Whitespace Standardization [MDB IGNORE] (#15748)

* Update settings

* Whitespace changes

* Comment out merger hooks in gitattributes

Corrupt maps would have to be resolved in repo before hooks could be updated

* Revert "Whitespace changes"

This reverts commit afbdd1d844.

* Whitespace again minus example

* Gitignore example changelog

* Restore changelog merge setting

* Keep older dmi hook attribute until hooks can be updated

* update vscode settings too

* Renormalize remaining

* Revert "Gitignore example changelog"

This reverts commit de22ad375d.

* Attempt to normalize example.yml (and another file I guess)

* Try again
This commit is contained in:
Drathek
2024-02-20 11:28:51 +01:00
committed by GitHub
parent 3b61f677b3
commit 7c8bb85de3
1175 changed files with 818171 additions and 818145 deletions
+53 -53
View File
@@ -1,54 +1,54 @@
/decl/xgm_gas/oxygen
id = "oxygen"
name = "Oxygen"
specific_heat = 20 // J/(mol*K)
molar_mass = 0.032 // kg/mol
flags = XGM_GAS_OXIDIZER
/decl/xgm_gas/nitrogen
id = "nitrogen"
name = "Nitrogen"
specific_heat = 20 // J/(mol*K)
molar_mass = 0.028 // kg/mol
/decl/xgm_gas/carbon_dioxide
id = "carbon_dioxide"
name = "Carbon Dioxide"
specific_heat = 30 // J/(mol*K)
molar_mass = 0.044 // kg/mol
/decl/xgm_gas/phoron
id = "phoron"
name = "Phoron"
//Note that this has a significant impact on TTV yield.
//Because it is so high, any leftover phoron soaks up a lot of heat and drops the yield pressure.
specific_heat = 200 // J/(mol*K)
//Hypothetical group 14 (same as carbon), period 8 element.
//Using multiplicity rule, it's atomic number is 162
//and following a N/Z ratio of 1.5, the molar mass of a monatomic gas is:
molar_mass = 0.405 // kg/mol
tile_overlay = "phoron"
overlay_limit = 0.7
flags = XGM_GAS_FUEL | XGM_GAS_CONTAMINANT | XGM_GAS_FUSION_FUEL //R-UST port, adding XGM_GAS_FUSION_FUEL flag.
/decl/xgm_gas/volatile_fuel
id = "volatile_fuel"
name = "Volatile Fuel"
specific_heat = 253 // J/(mol*K) C8H18 gasoline. Isobaric, but good enough.
molar_mass = 0.114 // kg/mol. same.
flags = XGM_GAS_FUEL
/decl/xgm_gas/nitrous_oxide
id = "nitrous_oxide"
name = "Nitrous Oxide"
specific_heat = 40 // J/(mol*K)
molar_mass = 0.044 // kg/mol. N2O
tile_overlay = "nitrous_oxide"
overlay_limit = 1
/decl/xgm_gas/oxygen
id = "oxygen"
name = "Oxygen"
specific_heat = 20 // J/(mol*K)
molar_mass = 0.032 // kg/mol
flags = XGM_GAS_OXIDIZER
/decl/xgm_gas/nitrogen
id = "nitrogen"
name = "Nitrogen"
specific_heat = 20 // J/(mol*K)
molar_mass = 0.028 // kg/mol
/decl/xgm_gas/carbon_dioxide
id = "carbon_dioxide"
name = "Carbon Dioxide"
specific_heat = 30 // J/(mol*K)
molar_mass = 0.044 // kg/mol
/decl/xgm_gas/phoron
id = "phoron"
name = "Phoron"
//Note that this has a significant impact on TTV yield.
//Because it is so high, any leftover phoron soaks up a lot of heat and drops the yield pressure.
specific_heat = 200 // J/(mol*K)
//Hypothetical group 14 (same as carbon), period 8 element.
//Using multiplicity rule, it's atomic number is 162
//and following a N/Z ratio of 1.5, the molar mass of a monatomic gas is:
molar_mass = 0.405 // kg/mol
tile_overlay = "phoron"
overlay_limit = 0.7
flags = XGM_GAS_FUEL | XGM_GAS_CONTAMINANT | XGM_GAS_FUSION_FUEL //R-UST port, adding XGM_GAS_FUSION_FUEL flag.
/decl/xgm_gas/volatile_fuel
id = "volatile_fuel"
name = "Volatile Fuel"
specific_heat = 253 // J/(mol*K) C8H18 gasoline. Isobaric, but good enough.
molar_mass = 0.114 // kg/mol. same.
flags = XGM_GAS_FUEL
/decl/xgm_gas/nitrous_oxide
id = "nitrous_oxide"
name = "Nitrous Oxide"
specific_heat = 40 // J/(mol*K)
molar_mass = 0.044 // kg/mol. N2O
tile_overlay = "nitrous_oxide"
overlay_limit = 1
flags = XGM_GAS_OXIDIZER
+120 -120
View File
@@ -1,120 +1,120 @@
/obj/structure/signpost
icon = 'icons/obj/stationobjs.dmi'
icon_state = "signpost"
anchored = TRUE
density = TRUE
/obj/structure/signpost/attackby(obj/item/weapon/W as obj, mob/user as mob)
return attack_hand(user)
/obj/structure/signpost/attack_hand(mob/user as mob)
if(tgui_alert(user, "Travel back to ss13?","Return?",list("Yes","No")) == "Yes")
if(user.z != src.z) return
user.forceMove(pick(latejoin))
/obj/effect/mark
var/mark = ""
icon = 'icons/misc/mark.dmi'
icon_state = "blank"
anchored = TRUE
layer = 99
mouse_opacity = 0
unacidable = TRUE//Just to be sure.
/obj/effect/beam
name = "beam"
density = FALSE
unacidable = TRUE//Just to be sure.
var/def_zone
pass_flags = PASSTABLE
/obj/effect/begin
name = "begin"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "begin"
anchored = TRUE
unacidable = TRUE
/*
* This item is completely unused, but removing it will break something in R&D and Radio code causing PDA and Ninja code to fail on compile
*/
/var/list/acting_rank_prefixes = list("acting", "temporary", "interim", "provisional")
/proc/make_list_rank(rank)
for(var/prefix in acting_rank_prefixes)
if(findtext(rank, "[prefix] ", 1, 2+length(prefix)))
return copytext(rank, 2+length(prefix))
return rank
/obj/effect/laser
name = "laser"
desc = "IT BURNS!!!"
icon = 'icons/obj/projectiles.dmi'
var/damage = 0.0
var/range = 10.0
/obj/effect/projection
name = "Projection"
desc = "This looks like a projection of something."
anchored = TRUE
/obj/effect/shut_controller
name = "shut controller"
var/moving = null
var/list/parts = list( )
/obj/structure/showcase
name = "Showcase"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "showcase_1"
desc = "A stand with the empty body of a cyborg bolted to it."
density = TRUE
anchored = TRUE
unacidable = TRUE//temporary until I decide whether the borg can be removed. -veyveyr
/obj/structure/showcase/sign
name = "WARNING: WILDERNESS"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "wilderness1"
desc = "This appears to be a sign warning people that the other side is dangerous. It also says that NanoTrasen cannot guarantee your safety beyond this point."
/obj/item/mouse_drag_pointer = MOUSE_ACTIVE_POINTER
/obj/item/weapon/beach_ball
icon = 'icons/misc/beach.dmi'
icon_state = "beachball"
name = "beach ball"
density = FALSE
anchored = FALSE
w_class = ITEMSIZE_LARGE
force = 0.0
throwforce = 0.0
throw_speed = 1
throw_range = 20
drop_sound = 'sound/items/drop/rubber.ogg'
pickup_sound = 'sound/items/pickup/rubber.ogg'
/obj/item/weapon/beach_ball/afterattack(atom/target as mob|obj|turf|area, mob/user as mob)
user.drop_item()
src.throw_at(target, throw_range, throw_speed, user)
/obj/item/weapon/beach_ball/dodgeball
icon = 'icons/obj/balls_vr.dmi'
icon_state = "dodgeball"
item_state = "dodgeball"
item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_balls_vr.dmi', slot_r_hand_str = 'icons/mob/items/righthand_balls_vr.dmi')
name = "dodgeball"
desc = "Think fast, chucklenuts!"
w_class = ITEMSIZE_LARGE //Stops people from hiding it in their bags/pockets
force = 0.1
throwforce = 0.1
throw_speed = 5
throw_range = 15
drop_sound = 'sound/items/drop/rubber.ogg'
pickup_sound = 'sound/items/pickup/rubber.ogg'
hitsound = 'sound/weapons/dodgeball.ogg'
/obj/effect/spawner
name = "object spawner"
/obj/structure/signpost
icon = 'icons/obj/stationobjs.dmi'
icon_state = "signpost"
anchored = TRUE
density = TRUE
/obj/structure/signpost/attackby(obj/item/weapon/W as obj, mob/user as mob)
return attack_hand(user)
/obj/structure/signpost/attack_hand(mob/user as mob)
if(tgui_alert(user, "Travel back to ss13?","Return?",list("Yes","No")) == "Yes")
if(user.z != src.z) return
user.forceMove(pick(latejoin))
/obj/effect/mark
var/mark = ""
icon = 'icons/misc/mark.dmi'
icon_state = "blank"
anchored = TRUE
layer = 99
mouse_opacity = 0
unacidable = TRUE//Just to be sure.
/obj/effect/beam
name = "beam"
density = FALSE
unacidable = TRUE//Just to be sure.
var/def_zone
pass_flags = PASSTABLE
/obj/effect/begin
name = "begin"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "begin"
anchored = TRUE
unacidable = TRUE
/*
* This item is completely unused, but removing it will break something in R&D and Radio code causing PDA and Ninja code to fail on compile
*/
/var/list/acting_rank_prefixes = list("acting", "temporary", "interim", "provisional")
/proc/make_list_rank(rank)
for(var/prefix in acting_rank_prefixes)
if(findtext(rank, "[prefix] ", 1, 2+length(prefix)))
return copytext(rank, 2+length(prefix))
return rank
/obj/effect/laser
name = "laser"
desc = "IT BURNS!!!"
icon = 'icons/obj/projectiles.dmi'
var/damage = 0.0
var/range = 10.0
/obj/effect/projection
name = "Projection"
desc = "This looks like a projection of something."
anchored = TRUE
/obj/effect/shut_controller
name = "shut controller"
var/moving = null
var/list/parts = list( )
/obj/structure/showcase
name = "Showcase"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "showcase_1"
desc = "A stand with the empty body of a cyborg bolted to it."
density = TRUE
anchored = TRUE
unacidable = TRUE//temporary until I decide whether the borg can be removed. -veyveyr
/obj/structure/showcase/sign
name = "WARNING: WILDERNESS"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "wilderness1"
desc = "This appears to be a sign warning people that the other side is dangerous. It also says that NanoTrasen cannot guarantee your safety beyond this point."
/obj/item/mouse_drag_pointer = MOUSE_ACTIVE_POINTER
/obj/item/weapon/beach_ball
icon = 'icons/misc/beach.dmi'
icon_state = "beachball"
name = "beach ball"
density = FALSE
anchored = FALSE
w_class = ITEMSIZE_LARGE
force = 0.0
throwforce = 0.0
throw_speed = 1
throw_range = 20
drop_sound = 'sound/items/drop/rubber.ogg'
pickup_sound = 'sound/items/pickup/rubber.ogg'
/obj/item/weapon/beach_ball/afterattack(atom/target as mob|obj|turf|area, mob/user as mob)
user.drop_item()
src.throw_at(target, throw_range, throw_speed, user)
/obj/item/weapon/beach_ball/dodgeball
icon = 'icons/obj/balls_vr.dmi'
icon_state = "dodgeball"
item_state = "dodgeball"
item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_balls_vr.dmi', slot_r_hand_str = 'icons/mob/items/righthand_balls_vr.dmi')
name = "dodgeball"
desc = "Think fast, chucklenuts!"
w_class = ITEMSIZE_LARGE //Stops people from hiding it in their bags/pockets
force = 0.1
throwforce = 0.1
throw_speed = 5
throw_range = 15
drop_sound = 'sound/items/drop/rubber.ogg'
pickup_sound = 'sound/items/pickup/rubber.ogg'
hitsound = 'sound/weapons/dodgeball.ogg'
/obj/effect/spawner
name = "object spawner"
+890 -890
View File
File diff suppressed because it is too large Load Diff
+181 -181
View File
@@ -1,181 +1,181 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
/*
A Star pathfinding algorithm
Returns a list of tiles forming a path from A to B, taking dense objects as well as walls, and the orientation of
windows along the route into account.
Use:
your_list = AStar(start location, end location, adjacent turf proc, distance proc)
For the adjacent turf proc i wrote:
/turf/proc/AdjacentTurfs
And for the distance one i wrote:
/turf/proc/Distance
So an example use might be:
src.path_list = AStar(src.loc, target.loc, /turf/proc/AdjacentTurfs, /turf/proc/Distance)
Note: The path is returned starting at the END node, so i wrote reverselist to reverse it for ease of use.
src.path_list = reverselist(src.pathlist)
Then to start on the path, all you need to do it:
Step_to(src, src.path_list[1])
src.path_list -= src.path_list[1] or equivilent to remove that node from the list.
Optional extras to add on (in order):
MaxNodes: The maximum number of nodes the returned path can be (0 = infinite)
Maxnodedepth: The maximum number of nodes to search (default: 30, 0 = infinite)
Mintargetdist: Minimum distance to the target before path returns, could be used to get
near a target, but not right to it - for an AI mob with a gun, for example.
Minnodedist: Minimum number of nodes to return in the path, could be used to give a path a minimum
length to avoid portals or something i guess?? Not that they're counted right now but w/e.
*/
// Modified to provide ID argument - supplied to 'adjacent' proc, defaults to null
// Used for checking if route exists through a door which can be opened
// Also added 'exclude' turf to avoid travelling over; defaults to null
/PriorityQueue
var/list/queue
var/comparison_function
/PriorityQueue/New(compare)
queue = list()
comparison_function = compare
/PriorityQueue/proc/IsEmpty()
return !queue.len
/PriorityQueue/proc/Enqueue(var/data)
queue.Add(data)
var/index = queue.len
//From what I can tell, this automagically sorts the added data into the correct location.
while(index > 2 && call(comparison_function)(queue[index / 2], queue[index]) > 0)
queue.Swap(index, index / 2)
index /= 2
/PriorityQueue/proc/Dequeue()
if(!queue.len)
return 0
return Remove(1)
/PriorityQueue/proc/Remove(var/index)
if(index > queue.len)
return 0
var/thing = queue[index]
queue.Swap(index, queue.len)
queue.Cut(queue.len)
if(index < queue.len)
FixQueue(index)
return thing
/PriorityQueue/proc/FixQueue(var/index)
var/child = 2 * index
var/item = queue[index]
while(child <= queue.len)
if(child < queue.len && call(comparison_function)(queue[child], queue[child + 1]) > 0)
child++
if(call(comparison_function)(item, queue[child]) > 0)
queue[index] = queue[child]
index = child
else
break
child = 2 * index
queue[index] = item
/PriorityQueue/proc/List()
return queue.Copy()
/PriorityQueue/proc/Length()
return queue.len
/PriorityQueue/proc/RemoveItem(data)
var/index = queue.Find(data)
if(index)
return Remove(index)
/PathNode
var/datum/position
var/PathNode/previous_node
var/best_estimated_cost
var/estimated_cost
var/known_cost
var/cost
var/nodes_traversed
/PathNode/New(_position, _previous_node, _known_cost, _cost, _nodes_traversed)
position = _position
previous_node = _previous_node
known_cost = _known_cost
cost = _cost
estimated_cost = cost + known_cost
best_estimated_cost = estimated_cost
nodes_traversed = _nodes_traversed
/proc/PathWeightCompare(PathNode/a, PathNode/b)
return a.estimated_cost - b.estimated_cost
/proc/AStar(var/start, var/end, var/adjacent, var/dist, var/max_nodes, var/max_node_depth = 30, var/min_target_dist = 0, var/min_node_dist, var/id, var/datum/exclude)
var/PriorityQueue/open = new /PriorityQueue(/proc/PathWeightCompare)
var/list/closed = list()
var/list/path
var/list/path_node_by_position = list()
start = get_turf(start)
if(!start)
return 0
open.Enqueue(new /PathNode(start, null, 0, call(start, dist)(end), 0))
while(!open.IsEmpty() && !path)
var/PathNode/current = open.Dequeue()
closed.Add(current.position)
if(current.position == end || call(current.position, dist)(end) <= min_target_dist)
path = new /list(current.nodes_traversed + 1)
path[path.len] = current.position
var/index = path.len - 1
while(current.previous_node)
current = current.previous_node
path[index--] = current.position
break
if(min_node_dist && max_node_depth)
if(call(current.position, min_node_dist)(end) + current.nodes_traversed >= max_node_depth)
continue
if(max_node_depth)
if(current.nodes_traversed >= max_node_depth)
continue
for(var/datum/datum in call(current.position, adjacent)(id))
if(datum == exclude)
continue
var/best_estimated_cost = current.estimated_cost + call(current.position, dist)(datum)
//handle removal of sub-par positions
if(datum in path_node_by_position)
var/PathNode/target = path_node_by_position[datum]
if(target.best_estimated_cost)
if(best_estimated_cost + call(datum, dist)(end) < target.best_estimated_cost)
open.RemoveItem(target)
else
continue
var/PathNode/next_node = new (datum, current, best_estimated_cost, call(datum, dist)(end), current.nodes_traversed + 1)
path_node_by_position[datum] = next_node
open.Enqueue(next_node)
if(max_nodes && open.Length() > max_nodes)
open.Remove(open.Length())
return path
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
/*
A Star pathfinding algorithm
Returns a list of tiles forming a path from A to B, taking dense objects as well as walls, and the orientation of
windows along the route into account.
Use:
your_list = AStar(start location, end location, adjacent turf proc, distance proc)
For the adjacent turf proc i wrote:
/turf/proc/AdjacentTurfs
And for the distance one i wrote:
/turf/proc/Distance
So an example use might be:
src.path_list = AStar(src.loc, target.loc, /turf/proc/AdjacentTurfs, /turf/proc/Distance)
Note: The path is returned starting at the END node, so i wrote reverselist to reverse it for ease of use.
src.path_list = reverselist(src.pathlist)
Then to start on the path, all you need to do it:
Step_to(src, src.path_list[1])
src.path_list -= src.path_list[1] or equivilent to remove that node from the list.
Optional extras to add on (in order):
MaxNodes: The maximum number of nodes the returned path can be (0 = infinite)
Maxnodedepth: The maximum number of nodes to search (default: 30, 0 = infinite)
Mintargetdist: Minimum distance to the target before path returns, could be used to get
near a target, but not right to it - for an AI mob with a gun, for example.
Minnodedist: Minimum number of nodes to return in the path, could be used to give a path a minimum
length to avoid portals or something i guess?? Not that they're counted right now but w/e.
*/
// Modified to provide ID argument - supplied to 'adjacent' proc, defaults to null
// Used for checking if route exists through a door which can be opened
// Also added 'exclude' turf to avoid travelling over; defaults to null
/PriorityQueue
var/list/queue
var/comparison_function
/PriorityQueue/New(compare)
queue = list()
comparison_function = compare
/PriorityQueue/proc/IsEmpty()
return !queue.len
/PriorityQueue/proc/Enqueue(var/data)
queue.Add(data)
var/index = queue.len
//From what I can tell, this automagically sorts the added data into the correct location.
while(index > 2 && call(comparison_function)(queue[index / 2], queue[index]) > 0)
queue.Swap(index, index / 2)
index /= 2
/PriorityQueue/proc/Dequeue()
if(!queue.len)
return 0
return Remove(1)
/PriorityQueue/proc/Remove(var/index)
if(index > queue.len)
return 0
var/thing = queue[index]
queue.Swap(index, queue.len)
queue.Cut(queue.len)
if(index < queue.len)
FixQueue(index)
return thing
/PriorityQueue/proc/FixQueue(var/index)
var/child = 2 * index
var/item = queue[index]
while(child <= queue.len)
if(child < queue.len && call(comparison_function)(queue[child], queue[child + 1]) > 0)
child++
if(call(comparison_function)(item, queue[child]) > 0)
queue[index] = queue[child]
index = child
else
break
child = 2 * index
queue[index] = item
/PriorityQueue/proc/List()
return queue.Copy()
/PriorityQueue/proc/Length()
return queue.len
/PriorityQueue/proc/RemoveItem(data)
var/index = queue.Find(data)
if(index)
return Remove(index)
/PathNode
var/datum/position
var/PathNode/previous_node
var/best_estimated_cost
var/estimated_cost
var/known_cost
var/cost
var/nodes_traversed
/PathNode/New(_position, _previous_node, _known_cost, _cost, _nodes_traversed)
position = _position
previous_node = _previous_node
known_cost = _known_cost
cost = _cost
estimated_cost = cost + known_cost
best_estimated_cost = estimated_cost
nodes_traversed = _nodes_traversed
/proc/PathWeightCompare(PathNode/a, PathNode/b)
return a.estimated_cost - b.estimated_cost
/proc/AStar(var/start, var/end, var/adjacent, var/dist, var/max_nodes, var/max_node_depth = 30, var/min_target_dist = 0, var/min_node_dist, var/id, var/datum/exclude)
var/PriorityQueue/open = new /PriorityQueue(/proc/PathWeightCompare)
var/list/closed = list()
var/list/path
var/list/path_node_by_position = list()
start = get_turf(start)
if(!start)
return 0
open.Enqueue(new /PathNode(start, null, 0, call(start, dist)(end), 0))
while(!open.IsEmpty() && !path)
var/PathNode/current = open.Dequeue()
closed.Add(current.position)
if(current.position == end || call(current.position, dist)(end) <= min_target_dist)
path = new /list(current.nodes_traversed + 1)
path[path.len] = current.position
var/index = path.len - 1
while(current.previous_node)
current = current.previous_node
path[index--] = current.position
break
if(min_node_dist && max_node_depth)
if(call(current.position, min_node_dist)(end) + current.nodes_traversed >= max_node_depth)
continue
if(max_node_depth)
if(current.nodes_traversed >= max_node_depth)
continue
for(var/datum/datum in call(current.position, adjacent)(id))
if(datum == exclude)
continue
var/best_estimated_cost = current.estimated_cost + call(current.position, dist)(datum)
//handle removal of sub-par positions
if(datum in path_node_by_position)
var/PathNode/target = path_node_by_position[datum]
if(target.best_estimated_cost)
if(best_estimated_cost + call(datum, dist)(end) < target.best_estimated_cost)
open.RemoveItem(target)
else
continue
var/PathNode/next_node = new (datum, current, best_estimated_cost, call(datum, dist)(end), current.nodes_traversed + 1)
path_node_by_position[datum] = next_node
open.Enqueue(next_node)
if(max_nodes && open.Length() > max_nodes)
open.Remove(open.Length())
return path
+208 -208
View File
@@ -1,208 +1,208 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
//cursors
#define Default_Cursor 0
#define Client_Cursor 1
#define Server_Cursor 2
//conversions
#define TEXT_CONV 1
#define RSC_FILE_CONV 2
#define NUMBER_CONV 3
//column flag values:
#define IS_NUMERIC 1
#define IS_BINARY 2
#define IS_NOT_NULL 4
#define IS_PRIMARY_KEY 8
#define IS_UNSIGNED 16
//types
#define TINYINT 1
#define SMALLINT 2
#define MEDIUMINT 3
#define INTEGER 4
#define BIGINT 5
#define DECIMAL 6
#define FLOAT 7
#define DOUBLE 8
#define DATE 9
#define DATETIME 10
#define TIMESTAMP 11
#define TIME 12
#define STRING 13
#define BLOB 14
// TODO: Investigate more recent type additions and see if I can handle them. - Nadrew
// Deprecated! See global.dm for new configuration vars
/*
var/DB_SERVER = "" // This is the location of your MySQL server (localhost is USUALLY fine)
var/DB_PORT = 3306 // This is the port your MySQL server is running on (3306 is the default)
*/
/DBConnection
var/_db_con // This variable contains a reference to the actual database connection.
var/dbi // This variable is a string containing the DBI MySQL requires.
var/user // This variable contains the username data.
var/password // This variable contains the password data.
var/default_cursor // This contains the default database cursor data.
//
var/server = ""
var/port = 3306
/DBConnection/New(dbi_handler,username,password_handler,cursor_handler)
src.dbi = dbi_handler
src.user = username
src.password = password_handler
src.default_cursor = cursor_handler
_db_con = _dm_db_new_con()
/DBConnection/proc/Connect(dbi_handler=src.dbi,user_handler=src.user,password_handler=src.password,cursor_handler)
if(!config.sql_enabled)
return 0
if(!src) return 0
cursor_handler = src.default_cursor
if(!cursor_handler) cursor_handler = Default_Cursor
return _dm_db_connect(_db_con,dbi_handler,user_handler,password_handler,cursor_handler,null)
/DBConnection/proc/Disconnect() return _dm_db_close(_db_con)
/DBConnection/proc/IsConnected()
if(!config.sql_enabled) return 0
var/success = _dm_db_is_connected(_db_con)
return success
/DBConnection/proc/Quote(str) return _dm_db_quote(_db_con,str)
/DBConnection/proc/ErrorMsg() return _dm_db_error_msg(_db_con)
/DBConnection/proc/SelectDB(database_name,dbi)
if(IsConnected()) Disconnect()
//return Connect("[dbi?"[dbi]":"dbi:mysql:[database_name]:[DB_SERVER]:[DB_PORT]"]",user,password)
return Connect("[dbi?"[dbi]":"dbi:mysql:[database_name]:[sqladdress]:[sqlport]"]",user,password)
/DBConnection/proc/NewQuery(sql_query,cursor_handler=src.default_cursor) return new/DBQuery(sql_query,src,cursor_handler)
/DBQuery/New(sql_query,DBConnection/connection_handler,cursor_handler)
if(sql_query) src.sql = sql_query
if(connection_handler) src.db_connection = connection_handler
if(cursor_handler) src.default_cursor = cursor_handler
_db_query = _dm_db_new_query()
return ..()
/DBQuery
var/sql // The sql query being executed.
var/default_cursor
var/list/columns //list of DB Columns populated by Columns()
var/list/conversions
var/list/item[0] //list of data values populated by NextRow()
var/DBConnection/db_connection
var/_db_query
/DBQuery/proc/Connect(DBConnection/connection_handler) src.db_connection = connection_handler
/DBQuery/proc/Execute(sql_query=src.sql,cursor_handler=default_cursor)
Close()
return _dm_db_execute(_db_query,sql_query,db_connection._db_con,cursor_handler,null)
/DBQuery/proc/NextRow() return _dm_db_next_row(_db_query,item,conversions)
/DBQuery/proc/RowsAffected() return _dm_db_rows_affected(_db_query)
/DBQuery/proc/RowCount() return _dm_db_row_count(_db_query)
/DBQuery/proc/ErrorMsg() return _dm_db_error_msg(_db_query)
/DBQuery/proc/Columns()
if(!columns)
columns = _dm_db_columns(_db_query,/DBColumn)
return columns
/DBQuery/proc/GetRowData()
var/list/columns = Columns()
var/list/results
if(columns.len)
results = list()
for(var/C in columns)
results+=C
var/DBColumn/cur_col = columns[C]
results[C] = src.item[(cur_col.position+1)]
return results
/DBQuery/proc/Close()
item.len = 0
columns = null
conversions = null
return _dm_db_close(_db_query)
/DBQuery/proc/Quote(str)
return db_connection.Quote(str)
/DBQuery/proc/SetConversion(column,conversion)
if(istext(column)) column = columns.Find(column)
if(!conversions) conversions = new/list(column)
else if(conversions.len < column) conversions.len = column
conversions[column] = conversion
/DBColumn
var/name
var/table
var/position //1-based index into item data
var/sql_type
var/flags
var/length
var/max_length
/DBColumn/New(name_handler,table_handler,position_handler,type_handler,flag_handler,length_handler,max_length_handler)
src.name = name_handler
src.table = table_handler
src.position = position_handler
src.sql_type = type_handler
src.flags = flag_handler
src.length = length_handler
src.max_length = max_length_handler
return ..()
/DBColumn/proc/SqlTypeName(type_handler=src.sql_type)
switch(type_handler)
if(TINYINT) return "TINYINT"
if(SMALLINT) return "SMALLINT"
if(MEDIUMINT) return "MEDIUMINT"
if(INTEGER) return "INTEGER"
if(BIGINT) return "BIGINT"
if(FLOAT) return "FLOAT"
if(DOUBLE) return "DOUBLE"
if(DATE) return "DATE"
if(DATETIME) return "DATETIME"
if(TIMESTAMP) return "TIMESTAMP"
if(TIME) return "TIME"
if(STRING) return "STRING"
if(BLOB) return "BLOB"
#undef Default_Cursor
#undef Client_Cursor
#undef Server_Cursor
#undef TEXT_CONV
#undef RSC_FILE_CONV
#undef NUMBER_CONV
#undef IS_NUMERIC
#undef IS_BINARY
#undef IS_NOT_NULL
#undef IS_PRIMARY_KEY
#undef IS_UNSIGNED
#undef TINYINT
#undef SMALLINT
#undef MEDIUMINT
#undef INTEGER
#undef BIGINT
#undef DECIMAL
#undef FLOAT
#undef DOUBLE
#undef DATE
#undef DATETIME
#undef TIMESTAMP
#undef TIME
#undef STRING
#undef BLOB
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
//cursors
#define Default_Cursor 0
#define Client_Cursor 1
#define Server_Cursor 2
//conversions
#define TEXT_CONV 1
#define RSC_FILE_CONV 2
#define NUMBER_CONV 3
//column flag values:
#define IS_NUMERIC 1
#define IS_BINARY 2
#define IS_NOT_NULL 4
#define IS_PRIMARY_KEY 8
#define IS_UNSIGNED 16
//types
#define TINYINT 1
#define SMALLINT 2
#define MEDIUMINT 3
#define INTEGER 4
#define BIGINT 5
#define DECIMAL 6
#define FLOAT 7
#define DOUBLE 8
#define DATE 9
#define DATETIME 10
#define TIMESTAMP 11
#define TIME 12
#define STRING 13
#define BLOB 14
// TODO: Investigate more recent type additions and see if I can handle them. - Nadrew
// Deprecated! See global.dm for new configuration vars
/*
var/DB_SERVER = "" // This is the location of your MySQL server (localhost is USUALLY fine)
var/DB_PORT = 3306 // This is the port your MySQL server is running on (3306 is the default)
*/
/DBConnection
var/_db_con // This variable contains a reference to the actual database connection.
var/dbi // This variable is a string containing the DBI MySQL requires.
var/user // This variable contains the username data.
var/password // This variable contains the password data.
var/default_cursor // This contains the default database cursor data.
//
var/server = ""
var/port = 3306
/DBConnection/New(dbi_handler,username,password_handler,cursor_handler)
src.dbi = dbi_handler
src.user = username
src.password = password_handler
src.default_cursor = cursor_handler
_db_con = _dm_db_new_con()
/DBConnection/proc/Connect(dbi_handler=src.dbi,user_handler=src.user,password_handler=src.password,cursor_handler)
if(!config.sql_enabled)
return 0
if(!src) return 0
cursor_handler = src.default_cursor
if(!cursor_handler) cursor_handler = Default_Cursor
return _dm_db_connect(_db_con,dbi_handler,user_handler,password_handler,cursor_handler,null)
/DBConnection/proc/Disconnect() return _dm_db_close(_db_con)
/DBConnection/proc/IsConnected()
if(!config.sql_enabled) return 0
var/success = _dm_db_is_connected(_db_con)
return success
/DBConnection/proc/Quote(str) return _dm_db_quote(_db_con,str)
/DBConnection/proc/ErrorMsg() return _dm_db_error_msg(_db_con)
/DBConnection/proc/SelectDB(database_name,dbi)
if(IsConnected()) Disconnect()
//return Connect("[dbi?"[dbi]":"dbi:mysql:[database_name]:[DB_SERVER]:[DB_PORT]"]",user,password)
return Connect("[dbi?"[dbi]":"dbi:mysql:[database_name]:[sqladdress]:[sqlport]"]",user,password)
/DBConnection/proc/NewQuery(sql_query,cursor_handler=src.default_cursor) return new/DBQuery(sql_query,src,cursor_handler)
/DBQuery/New(sql_query,DBConnection/connection_handler,cursor_handler)
if(sql_query) src.sql = sql_query
if(connection_handler) src.db_connection = connection_handler
if(cursor_handler) src.default_cursor = cursor_handler
_db_query = _dm_db_new_query()
return ..()
/DBQuery
var/sql // The sql query being executed.
var/default_cursor
var/list/columns //list of DB Columns populated by Columns()
var/list/conversions
var/list/item[0] //list of data values populated by NextRow()
var/DBConnection/db_connection
var/_db_query
/DBQuery/proc/Connect(DBConnection/connection_handler) src.db_connection = connection_handler
/DBQuery/proc/Execute(sql_query=src.sql,cursor_handler=default_cursor)
Close()
return _dm_db_execute(_db_query,sql_query,db_connection._db_con,cursor_handler,null)
/DBQuery/proc/NextRow() return _dm_db_next_row(_db_query,item,conversions)
/DBQuery/proc/RowsAffected() return _dm_db_rows_affected(_db_query)
/DBQuery/proc/RowCount() return _dm_db_row_count(_db_query)
/DBQuery/proc/ErrorMsg() return _dm_db_error_msg(_db_query)
/DBQuery/proc/Columns()
if(!columns)
columns = _dm_db_columns(_db_query,/DBColumn)
return columns
/DBQuery/proc/GetRowData()
var/list/columns = Columns()
var/list/results
if(columns.len)
results = list()
for(var/C in columns)
results+=C
var/DBColumn/cur_col = columns[C]
results[C] = src.item[(cur_col.position+1)]
return results
/DBQuery/proc/Close()
item.len = 0
columns = null
conversions = null
return _dm_db_close(_db_query)
/DBQuery/proc/Quote(str)
return db_connection.Quote(str)
/DBQuery/proc/SetConversion(column,conversion)
if(istext(column)) column = columns.Find(column)
if(!conversions) conversions = new/list(column)
else if(conversions.len < column) conversions.len = column
conversions[column] = conversion
/DBColumn
var/name
var/table
var/position //1-based index into item data
var/sql_type
var/flags
var/length
var/max_length
/DBColumn/New(name_handler,table_handler,position_handler,type_handler,flag_handler,length_handler,max_length_handler)
src.name = name_handler
src.table = table_handler
src.position = position_handler
src.sql_type = type_handler
src.flags = flag_handler
src.length = length_handler
src.max_length = max_length_handler
return ..()
/DBColumn/proc/SqlTypeName(type_handler=src.sql_type)
switch(type_handler)
if(TINYINT) return "TINYINT"
if(SMALLINT) return "SMALLINT"
if(MEDIUMINT) return "MEDIUMINT"
if(INTEGER) return "INTEGER"
if(BIGINT) return "BIGINT"
if(FLOAT) return "FLOAT"
if(DOUBLE) return "DOUBLE"
if(DATE) return "DATE"
if(DATETIME) return "DATETIME"
if(TIMESTAMP) return "TIMESTAMP"
if(TIME) return "TIME"
if(STRING) return "STRING"
if(BLOB) return "BLOB"
#undef Default_Cursor
#undef Client_Cursor
#undef Server_Cursor
#undef TEXT_CONV
#undef RSC_FILE_CONV
#undef NUMBER_CONV
#undef IS_NUMERIC
#undef IS_BINARY
#undef IS_NOT_NULL
#undef IS_PRIMARY_KEY
#undef IS_UNSIGNED
#undef TINYINT
#undef SMALLINT
#undef MEDIUMINT
#undef INTEGER
#undef BIGINT
#undef DECIMAL
#undef FLOAT
#undef DOUBLE
#undef DATE
#undef DATETIME
#undef TIMESTAMP
#undef TIME
#undef STRING
#undef BLOB
+145 -145
View File
@@ -1,145 +1,145 @@
/proc/sql_poll_population()
if(!sqllogging)
return
var/admincount = GLOB.admins.len
var/playercount = 0
for(var/mob/M in player_list)
if(M.client)
playercount += 1
establish_db_connection()
if(!dbcon.IsConnected())
log_game("SQL ERROR during population polling. Failed to connect.")
else
var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
var/DBQuery/query = dbcon_old.NewQuery("INSERT INTO `tgstation`.`population` (`playercount`, `admincount`, `time`) VALUES ([playercount], [admincount], '[sqltime]')")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during population polling. Error : \[[err]\]\n")
/proc/sql_report_round_start()
// TODO
if(!sqllogging)
return
/proc/sql_report_round_end()
// TODO
if(!sqllogging)
return
/proc/sql_report_death(var/mob/living/carbon/human/H)
if(!sqllogging)
return
if(!H)
return
if(!H.key || !H.mind)
return
var/area/placeofdeath = get_area(H)
var/podname = placeofdeath ? placeofdeath.name : "Unknown area"
var/sqlname = sanitizeSQL(H.real_name)
var/sqlkey = sanitizeSQL(H.key)
var/sqlpod = sanitizeSQL(podname)
var/sqlspecial = sanitizeSQL(H.mind.special_role)
var/sqljob = sanitizeSQL(H.mind.assigned_role)
var/laname
var/lakey
if(H.lastattacker)
laname = sanitizeSQL(H.lastattacker:real_name)
lakey = sanitizeSQL(H.lastattacker:key)
var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
var/coord = "[H.x], [H.y], [H.z]"
//to_world("INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.bruteloss], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()])")
establish_db_connection()
if(!dbcon.IsConnected())
log_game("SQL ERROR during death reporting. Failed to connect.")
else
var/DBQuery/query = dbcon.NewQuery("INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.getBruteLoss()], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()], '[coord]')")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during death reporting. Error : \[[err]\]\n")
/proc/sql_report_cyborg_death(var/mob/living/silicon/robot/H)
if(!sqllogging)
return
if(!H)
return
if(!H.key || !H.mind)
return
var/area/placeofdeath = get_area(H)
var/podname = placeofdeath ? placeofdeath.name : "Unknown area"
var/sqlname = sanitizeSQL(H.real_name)
var/sqlkey = sanitizeSQL(H.key)
var/sqlpod = sanitizeSQL(podname)
var/sqlspecial = sanitizeSQL(H.mind.special_role)
var/sqljob = sanitizeSQL(H.mind.assigned_role)
var/laname
var/lakey
if(H.lastattacker)
laname = sanitizeSQL(H.lastattacker:real_name)
lakey = sanitizeSQL(H.lastattacker:key)
var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
var/coord = "[H.x], [H.y], [H.z]"
//to_world("INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.bruteloss], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()])")
establish_db_connection()
if(!dbcon.IsConnected())
log_game("SQL ERROR during death reporting. Failed to connect.")
else
var/DBQuery/query = dbcon.NewQuery("INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.getBruteLoss()], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()], '[coord]')")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during death reporting. Error : \[[err]\]\n")
/proc/statistic_cycle()
set waitfor = 0
if(!sqllogging)
return
while(1)
sql_poll_population()
sleep(6000)
//This proc is used for feedback. It is executed at round end.
/proc/sql_commit_feedback()
if(!blackbox)
log_game("Round ended without a blackbox recorder. No feedback was sent to the database.")
return
//content is a list of lists. Each item in the list is a list with two fields, a variable name and a value. Items MUST only have these two values.
var/list/datum/feedback_variable/content = blackbox.get_round_feedback()
if(!content)
log_game("Round ended without any feedback being generated. No feedback was sent to the database.")
return
establish_db_connection()
if(!dbcon.IsConnected())
log_game("SQL ERROR during feedback reporting. Failed to connect.")
else
var/DBQuery/max_query = dbcon.NewQuery("SELECT MAX(roundid) AS max_round_id FROM erro_feedback")
max_query.Execute()
var/newroundid
while(max_query.NextRow())
newroundid = max_query.item[1]
if(!(isnum(newroundid)))
newroundid = text2num(newroundid)
if(isnum(newroundid))
newroundid++
else
newroundid = 1
for(var/datum/feedback_variable/item in content)
var/variable = item.get_variable()
var/value = item.get_value()
var/DBQuery/query = dbcon.NewQuery("INSERT INTO erro_feedback (id, roundid, time, variable, value) VALUES (null, [newroundid], Now(), '[variable]', '[value]')")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during death reporting. Error : \[[err]\]\n")
/proc/sql_poll_population()
if(!sqllogging)
return
var/admincount = GLOB.admins.len
var/playercount = 0
for(var/mob/M in player_list)
if(M.client)
playercount += 1
establish_db_connection()
if(!dbcon.IsConnected())
log_game("SQL ERROR during population polling. Failed to connect.")
else
var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
var/DBQuery/query = dbcon_old.NewQuery("INSERT INTO `tgstation`.`population` (`playercount`, `admincount`, `time`) VALUES ([playercount], [admincount], '[sqltime]')")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during population polling. Error : \[[err]\]\n")
/proc/sql_report_round_start()
// TODO
if(!sqllogging)
return
/proc/sql_report_round_end()
// TODO
if(!sqllogging)
return
/proc/sql_report_death(var/mob/living/carbon/human/H)
if(!sqllogging)
return
if(!H)
return
if(!H.key || !H.mind)
return
var/area/placeofdeath = get_area(H)
var/podname = placeofdeath ? placeofdeath.name : "Unknown area"
var/sqlname = sanitizeSQL(H.real_name)
var/sqlkey = sanitizeSQL(H.key)
var/sqlpod = sanitizeSQL(podname)
var/sqlspecial = sanitizeSQL(H.mind.special_role)
var/sqljob = sanitizeSQL(H.mind.assigned_role)
var/laname
var/lakey
if(H.lastattacker)
laname = sanitizeSQL(H.lastattacker:real_name)
lakey = sanitizeSQL(H.lastattacker:key)
var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
var/coord = "[H.x], [H.y], [H.z]"
//to_world("INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.bruteloss], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()])")
establish_db_connection()
if(!dbcon.IsConnected())
log_game("SQL ERROR during death reporting. Failed to connect.")
else
var/DBQuery/query = dbcon.NewQuery("INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.getBruteLoss()], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()], '[coord]')")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during death reporting. Error : \[[err]\]\n")
/proc/sql_report_cyborg_death(var/mob/living/silicon/robot/H)
if(!sqllogging)
return
if(!H)
return
if(!H.key || !H.mind)
return
var/area/placeofdeath = get_area(H)
var/podname = placeofdeath ? placeofdeath.name : "Unknown area"
var/sqlname = sanitizeSQL(H.real_name)
var/sqlkey = sanitizeSQL(H.key)
var/sqlpod = sanitizeSQL(podname)
var/sqlspecial = sanitizeSQL(H.mind.special_role)
var/sqljob = sanitizeSQL(H.mind.assigned_role)
var/laname
var/lakey
if(H.lastattacker)
laname = sanitizeSQL(H.lastattacker:real_name)
lakey = sanitizeSQL(H.lastattacker:key)
var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
var/coord = "[H.x], [H.y], [H.z]"
//to_world("INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.bruteloss], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()])")
establish_db_connection()
if(!dbcon.IsConnected())
log_game("SQL ERROR during death reporting. Failed to connect.")
else
var/DBQuery/query = dbcon.NewQuery("INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.getBruteLoss()], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()], '[coord]')")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during death reporting. Error : \[[err]\]\n")
/proc/statistic_cycle()
set waitfor = 0
if(!sqllogging)
return
while(1)
sql_poll_population()
sleep(6000)
//This proc is used for feedback. It is executed at round end.
/proc/sql_commit_feedback()
if(!blackbox)
log_game("Round ended without a blackbox recorder. No feedback was sent to the database.")
return
//content is a list of lists. Each item in the list is a list with two fields, a variable name and a value. Items MUST only have these two values.
var/list/datum/feedback_variable/content = blackbox.get_round_feedback()
if(!content)
log_game("Round ended without any feedback being generated. No feedback was sent to the database.")
return
establish_db_connection()
if(!dbcon.IsConnected())
log_game("SQL ERROR during feedback reporting. Failed to connect.")
else
var/DBQuery/max_query = dbcon.NewQuery("SELECT MAX(roundid) AS max_round_id FROM erro_feedback")
max_query.Execute()
var/newroundid
while(max_query.NextRow())
newroundid = max_query.item[1]
if(!(isnum(newroundid)))
newroundid = text2num(newroundid)
if(isnum(newroundid))
newroundid++
else
newroundid = 1
for(var/datum/feedback_variable/item in content)
var/variable = item.get_variable()
var/value = item.get_value()
var/DBQuery/query = dbcon.NewQuery("INSERT INTO erro_feedback (id, roundid, time, variable, value) VALUES (null, [newroundid], Now(), '[variable]', '[value]')")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during death reporting. Error : \[[err]\]\n")