From 56789c5924abf1a4321a13ff434b0dafd2417b5d Mon Sep 17 00:00:00 2001
From: Letter N <24603524+LetterN@users.noreply.github.com>
Date: Thu, 31 Dec 2020 16:46:40 +0800
Subject: [PATCH] firsthit-lib_machines
---
code/__HELPERS/roundend.dm | 17 +-
code/controllers/subsystem/blackbox.dm | 98 ++++---
code/controllers/subsystem/dbcore.dm | 350 ++++++++++++-----------
code/controllers/subsystem/mapping.dm | 4 +-
code/game/gamemodes/game_mode.dm | 33 ++-
code/modules/admin/DB_ban/functions.dm | 22 +-
code/modules/admin/IsBanned.dm | 2 +-
code/modules/admin/admin_ranks.dm | 24 +-
code/modules/admin/banjob.dm | 6 +-
code/modules/admin/create_poll.dm | 6 +-
code/modules/admin/ipintel.dm | 28 +-
code/modules/admin/permissionedit.dm | 170 +++++++----
code/modules/admin/sql_message_system.dm | 252 +++++++++++-----
code/modules/admin/topic.dm | 19 +-
code/modules/client/client_procs.dm | 151 ++++++----
code/modules/client/preferences.dm | 2 +-
code/modules/jobs/job_exp.dm | 16 +-
code/modules/library/lib_machines.dm | 260 +++++++++--------
18 files changed, 871 insertions(+), 589 deletions(-)
diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm
index e4a2e6521a..e1c1e3df07 100644
--- a/code/__HELPERS/roundend.dm
+++ b/code/__HELPERS/roundend.dm
@@ -586,11 +586,9 @@
var/list/sql_admins = list()
for(var/i in GLOB.protected_admins)
var/datum/admins/A = GLOB.protected_admins[i]
- var/sql_ckey = sanitizeSQL(A.target)
- var/sql_rank = sanitizeSQL(A.rank.name)
- sql_admins += list(list("ckey" = "'[sql_ckey]'", "rank" = "'[sql_rank]'"))
+ sql_admins += list(list("ckey" = A.target, "rank" = A.rank.name))
SSdbcore.MassInsert(format_table_name("admin"), sql_admins, duplicate_key = TRUE)
- var/datum/DBQuery/query_admin_rank_update = SSdbcore.NewQuery("UPDATE [format_table_name("player")] p INNER JOIN [format_table_name("admin")] a ON p.ckey = a.ckey SET p.lastadminrank = a.rank")
+ var/datum/db_query/query_admin_rank_update = SSdbcore.NewQuery("UPDATE [format_table_name("player")] p INNER JOIN [format_table_name("admin")] a ON p.ckey = a.ckey SET p.lastadminrank = a.rank")
query_admin_rank_update.Execute()
qdel(query_admin_rank_update)
@@ -623,15 +621,20 @@
flags += "can_edit_flags"
if(!flags.len)
continue
- var/sql_rank = sanitizeSQL(R.name)
var/flags_to_check = flags.Join(" != [R_EVERYTHING] AND ") + " != [R_EVERYTHING]"
- var/datum/DBQuery/query_check_everything_ranks = SSdbcore.NewQuery("SELECT flags, exclude_flags, can_edit_flags FROM [format_table_name("admin_ranks")] WHERE rank = '[sql_rank]' AND ([flags_to_check])")
+ var/datum/db_query/query_check_everything_ranks = SSdbcore.NewQuery(
+ "SELECT flags, exclude_flags, can_edit_flags FROM [format_table_name("admin_ranks")] WHERE rank = :rank AND ([flags_to_check])",
+ list("rank" = R.name)
+ )
if(!query_check_everything_ranks.Execute())
qdel(query_check_everything_ranks)
return
if(query_check_everything_ranks.NextRow()) //no row is returned if the rank already has the correct flag value
var/flags_to_update = flags.Join(" = [R_EVERYTHING], ") + " = [R_EVERYTHING]"
- var/datum/DBQuery/query_update_everything_ranks = SSdbcore.NewQuery("UPDATE [format_table_name("admin_ranks")] SET [flags_to_update] WHERE rank = '[sql_rank]'")
+ var/datum/db_query/query_update_everything_ranks = SSdbcore.NewQuery(
+ "UPDATE [format_table_name("admin_ranks")] SET [flags_to_update] WHERE rank = :rank",
+ list("rank" = R.name)
+ )
if(!query_update_everything_ranks.Execute())
qdel(query_update_everything_ranks)
return
diff --git a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm
index dc1f246e3d..455ccb8d14 100644
--- a/code/controllers/subsystem/blackbox.dm
+++ b/code/controllers/subsystem/blackbox.dm
@@ -39,12 +39,19 @@ SUBSYSTEM_DEF(blackbox)
if(!SSdbcore.Connect())
return
- var/playercount = 0
- for(var/mob/M in GLOB.player_list)
- if(M.client)
- playercount += 1
+ var/playercount = LAZYLEN(GLOB.player_list)
var/admincount = GLOB.admins.len
- var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port, round_id) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]')")
+ var/datum/db_query/query_record_playercount = SSdbcore.NewQuery({"
+ INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port, round_id)
+ VALUES (:playercount, :admincount, :time, INET_ATON(:server_ip), :server_port, :round_id)
+ "}, list(
+ "playercount" = playercount,
+ "admincount" = admincount,
+ "time" = SQLtime(),
+ "server_ip" = world.internet_address || "0",
+ "server_port" = "[world.port]",
+ "round_id" = GLOB.round_id,
+ ))
query_record_playercount.Execute()
qdel(query_record_playercount)
@@ -271,6 +278,17 @@ Versioning
key = new_key
key_type = new_key_type
+/datum/controller/subsystem/blackbox/proc/LogAhelp(ticket, action, message, recipient, sender)
+ if(!SSdbcore.Connect())
+ return
+
+ var/datum/db_query/query_log_ahelp = SSdbcore.NewQuery({"
+ INSERT INTO [format_table_name("ticket")] (ticket, action, message, recipient, sender, server_ip, server_port, round_id, timestamp)
+ VALUES (:ticket, :action, :message, :recipient, :sender, INET_ATON(:server_ip), :server_port, :round_id, :time)
+ "}, list("ticket" = ticket, "action" = action, "message" = message, "recipient" = recipient, "sender" = sender, "server_ip" = world.internet_address || "0", "server_port" = world.port, "round_id" = GLOB.round_id, "time" = SQLtime()))
+ query_log_ahelp.Execute()
+ qdel(query_log_ahelp)
+
/datum/controller/subsystem/blackbox/proc/ReportDeath(mob/living/L)
set waitfor = FALSE
if(sealed)
@@ -285,51 +303,39 @@ Versioning
first_death["area"] = "[AREACOORD(L)]"
first_death["damage"] = "[L.getBruteLoss()]/[L.getFireLoss()]/[L.getToxLoss()]/[L.getOxyLoss()]/[L.getCloneLoss()]"
first_death["last_words"] = L.last_words
- var/sqlname = L.real_name
- var/sqlkey = L.ckey
- var/sqljob = L.mind.assigned_role
- var/sqlspecial = L.mind.special_role
- var/sqlpod = get_area_name(L, TRUE)
- var/laname = L.lastattacker
- var/lakey = L.lastattackerckey
- var/sqlbrute = L.getBruteLoss()
- var/sqlfire = L.getFireLoss()
- var/sqlbrain = L.getOrganLoss(ORGAN_SLOT_BRAIN)
- var/sqloxy = L.getOxyLoss()
- var/sqltox = L.getToxLoss()
- var/sqlclone = L.getCloneLoss()
- var/sqlstamina = L.getStaminaLoss()
- var/x_coord = L.x
- var/y_coord = L.y
- var/z_coord = L.z
- var/last_words = L.last_words
- var/suicide = L.suiciding
- var/map = SSmapping.config.map_name
if(!SSdbcore.Connect())
return
- sqlname = sanitizeSQL(sqlname)
- sqlkey = sanitizeSQL(sqlkey)
- sqljob = sanitizeSQL(sqljob)
- sqlspecial = sanitizeSQL(sqlspecial)
- sqlpod = sanitizeSQL(sqlpod)
- laname = sanitizeSQL(laname)
- lakey = sanitizeSQL(lakey)
- sqlbrute = sanitizeSQL(sqlbrute)
- sqlfire = sanitizeSQL(sqlfire)
- sqlbrain = sanitizeSQL(sqlbrain)
- sqloxy = sanitizeSQL(sqloxy)
- sqltox = sanitizeSQL(sqltox)
- sqlclone = sanitizeSQL(sqlclone)
- sqlstamina = sanitizeSQL(sqlstamina)
- x_coord = sanitizeSQL(x_coord)
- y_coord = sanitizeSQL(y_coord)
- z_coord = sanitizeSQL(z_coord)
- last_words = sanitizeSQL(last_words)
- suicide = sanitizeSQL(suicide)
- map = sanitizeSQL(map)
- var/datum/DBQuery/query_report_death = SSdbcore.NewQuery("INSERT INTO [format_table_name("death")] (pod, x_coord, y_coord, z_coord, mapname, server_ip, server_port, round_id, tod, job, special, name, byondkey, laname, lakey, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss, last_words, suicide) VALUES ('[sqlpod]', '[x_coord]', '[y_coord]', '[z_coord]', '[map]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', [GLOB.round_id], '[SQLtime()]', '[sqljob]', '[sqlspecial]', '[sqlname]', '[sqlkey]', '[laname]', '[lakey]', [sqlbrute], [sqlfire], [sqlbrain], [sqloxy], [sqltox], [sqlclone], [sqlstamina], '[last_words]', [suicide])")
+ var/datum/db_query/query_report_death = SSdbcore.NewQuery({"
+ INSERT INTO [format_table_name("death")] (pod, x_coord, y_coord, z_coord, mapname, server_ip, server_port, round_id, tod, job, special, name, byondkey, laname, lakey, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss, last_words, suicide)
+ VALUES (:pod, :x_coord, :y_coord, :z_coord, :map, INET_ATON(:internet_address), :port, :round_id, :time, :job, :special, :name, :key, :laname, :lakey, :brute, :fire, :brain, :oxy, :tox, :clone, :stamina, :last_words, :suicide)
+ "}, list(
+ "name" = L.real_name,
+ "key" = L.ckey,
+ "job" = L.mind.assigned_role,
+ "special" = L.mind.special_role,
+ "pod" = get_area_name(L, TRUE),
+ "laname" = L.lastattacker,
+ "lakey" = L.lastattackerckey,
+ "brute" = L.getBruteLoss(),
+ "fire" = L.getFireLoss(),
+ "brain" = L.getOrganLoss(ORGAN_SLOT_BRAIN) || BRAIN_DAMAGE_DEATH, //getOrganLoss returns null without a brain but a value is required for this column
+ "oxy" = L.getOxyLoss(),
+ "tox" = L.getToxLoss(),
+ "clone" = L.getCloneLoss(),
+ "stamina" = L.getStaminaLoss(),
+ "x_coord" = L.x,
+ "y_coord" = L.y,
+ "z_coord" = L.z,
+ "last_words" = L.last_words,
+ "suicide" = L.suiciding,
+ "map" = SSmapping.config.map_name,
+ "internet_address" = world.internet_address || "0",
+ "port" = "[world.port]",
+ "round_id" = GLOB.round_id,
+ "time" = SQLtime(),
+ ))
if(query_report_death)
query_report_death.Execute(async = TRUE)
qdel(query_report_death)
diff --git a/code/controllers/subsystem/dbcore.dm b/code/controllers/subsystem/dbcore.dm
index 4eff4fbf1d..b6b750fbf4 100644
--- a/code/controllers/subsystem/dbcore.dm
+++ b/code/controllers/subsystem/dbcore.dm
@@ -3,7 +3,7 @@ SUBSYSTEM_DEF(dbcore)
flags = SS_BACKGROUND
wait = 1 MINUTES
init_order = INIT_ORDER_DBCORE
- var/const/FAILED_DB_CONNECTION_CUTOFF = 5
+ var/failed_connection_timeout = 0
var/schema_mismatch = 0
var/db_minor = 0
@@ -13,8 +13,7 @@ SUBSYSTEM_DEF(dbcore)
var/last_error
var/list/active_queries = list()
- var/datum/BSQL_Connection/connection
- var/datum/BSQL_Operation/connectOperation
+ var/connection // Arbitrary handle returned from rust_g.
/datum/controller/subsystem/dbcore/Initialize()
//We send warnings to the admins during subsystem init, as the clients will be New'd and messages
@@ -29,7 +28,7 @@ SUBSYSTEM_DEF(dbcore)
/datum/controller/subsystem/dbcore/fire()
for(var/I in active_queries)
- var/datum/DBQuery/Q = I
+ var/datum/db_query/Q = I
if(world.time - Q.last_activity_time > (5 MINUTES))
message_admins("Found undeleted query, please check the server logs and notify coders.")
log_sql("Undeleted query: \"[Q.sql]\" LA: [Q.last_activity] LAT: [Q.last_activity_time]")
@@ -39,24 +38,25 @@ SUBSYSTEM_DEF(dbcore)
/datum/controller/subsystem/dbcore/Recover()
connection = SSdbcore.connection
- connectOperation = SSdbcore.connectOperation
/datum/controller/subsystem/dbcore/Shutdown()
//This is as close as we can get to the true round end before Disconnect() without changing where it's called, defeating the reason this is a subsystem
if(SSdbcore.Connect())
- var/datum/DBQuery/query_round_shutdown = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET shutdown_datetime = Now(), end_state = '[sanitizeSQL(SSticker.end_state)]' WHERE id = [GLOB.round_id]")
+ var/datum/db_query/query_round_shutdown = SSdbcore.NewQuery(
+ "UPDATE [format_table_name("round")] SET shutdown_datetime = Now(), end_state = :end_state WHERE id = :round_id",
+ list("end_state" = SSticker.end_state, "round_id" = GLOB.round_id)
+ )
query_round_shutdown.Execute()
qdel(query_round_shutdown)
if(IsConnected())
Disconnect()
- world.BSQL_Shutdown()
//nu
/datum/controller/subsystem/dbcore/can_vv_get(var_name)
- return var_name != NAMEOF(src, connection) && var_name != NAMEOF(src, active_queries) && var_name != NAMEOF(src, connectOperation) && ..()
+ return var_name != NAMEOF(src, connection) && var_name != NAMEOF(src, active_queries) && ..()
/datum/controller/subsystem/dbcore/vv_edit_var(var_name, var_value)
- if(var_name == NAMEOF(src, connection) || var_name == NAMEOF(src, connectOperation))
+ if(var_name == NAMEOF(src, connection))
return FALSE
return ..()
@@ -64,7 +64,11 @@ SUBSYSTEM_DEF(dbcore)
if(IsConnected())
return TRUE
- if(failed_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to connect anymore.
+ if(failed_connection_timeout <= world.time) //it's been more than 5 seconds since we failed to connect, reset the counter
+ failed_connections = 0
+
+ if(failed_connections > 5) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to connect for 5 seconds.
+ failed_connection_timeout = world.time + 50
return FALSE
if(!CONFIG_GET(flag/sql_enabled))
@@ -75,32 +79,33 @@ SUBSYSTEM_DEF(dbcore)
var/db = CONFIG_GET(string/feedback_database)
var/address = CONFIG_GET(string/address)
var/port = CONFIG_GET(number/port)
+ var/timeout = max(CONFIG_GET(number/async_query_timeout), CONFIG_GET(number/blocking_query_timeout))
+ var/thread_limit = CONFIG_GET(number/bsql_thread_limit)
- connection = new /datum/BSQL_Connection(BSQL_CONNECTION_TYPE_MARIADB, CONFIG_GET(number/async_query_timeout), CONFIG_GET(number/blocking_query_timeout), CONFIG_GET(number/bsql_thread_limit))
- var/error
- if(QDELETED(connection))
- connection = null
- error = last_error
+ var/result = json_decode(rustg_sql_connect_pool(json_encode(list(
+ "host" = address,
+ "port" = port,
+ "user" = user,
+ "pass" = pass,
+ "db_name" = db,
+ "read_timeout" = timeout,
+ "write_timeout" = timeout,
+ "max_threads" = thread_limit,
+ ))))
+ . = (result["status"] == "ok")
+ if (.)
+ connection = result["handle"]
else
- SSdbcore.last_error = null
- connectOperation = connection.BeginConnect(address, port, user, pass, db)
- if(SSdbcore.last_error)
- CRASH(SSdbcore.last_error)
- UNTIL(connectOperation.IsComplete())
- error = connectOperation.GetError()
- . = !error
- if (!.)
- last_error = error
- log_sql("Connect() failed | [error]")
+ connection = null
+ last_error = result["data"]
+ log_sql("Connect() failed | [last_error]")
++failed_connections
- QDEL_NULL(connection)
- QDEL_NULL(connectOperation)
/datum/controller/subsystem/dbcore/proc/CheckSchemaVersion()
if(CONFIG_GET(flag/sql_enabled))
if(Connect())
log_world("Database connection established.")
- var/datum/DBQuery/query_db_version = NewQuery("SELECT major, minor FROM [format_table_name("schema_revision")] ORDER BY date DESC LIMIT 1")
+ var/datum/db_query/query_db_version = NewQuery("SELECT major, minor FROM [format_table_name("schema_revision")] ORDER BY date DESC LIMIT 1")
query_db_version.Execute()
if(query_db_version.NextRow())
db_major = text2num(query_db_version.item[1])
@@ -120,47 +125,46 @@ SUBSYSTEM_DEF(dbcore)
/datum/controller/subsystem/dbcore/proc/SetRoundID()
if(!Connect())
return
- var/datum/DBQuery/query_round_initialize = SSdbcore.NewQuery("INSERT INTO [format_table_name("round")] (initialize_datetime, server_ip, server_port) VALUES (Now(), INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]')")
- query_round_initialize.Execute()
+ var/datum/db_query/query_round_initialize = SSdbcore.NewQuery(
+ "INSERT INTO [format_table_name("round")] (initialize_datetime, server_ip, server_port) VALUES (Now(), INET_ATON(:internet_address), :port)",
+ list("internet_address" = world.internet_address || "0", "port" = "[world.port]")
+ )
+ query_round_initialize.Execute(async = FALSE)
+ GLOB.round_id = "[query_round_initialize.last_insert_id]"
qdel(query_round_initialize)
- var/datum/DBQuery/query_round_last_id = SSdbcore.NewQuery("SELECT LAST_INSERT_ID()")
- query_round_last_id.Execute()
- if(query_round_last_id.NextRow())
- GLOB.round_id = query_round_last_id.item[1]
- qdel(query_round_last_id)
/datum/controller/subsystem/dbcore/proc/SetRoundStart()
if(!Connect())
return
- var/datum/DBQuery/query_round_start = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET start_datetime = Now() WHERE id = [GLOB.round_id]")
+ var/datum/db_query/query_round_start = SSdbcore.NewQuery(
+ "UPDATE [format_table_name("round")] SET start_datetime = Now() WHERE id = :round_id",
+ list("round_id" = GLOB.round_id)
+ )
query_round_start.Execute()
qdel(query_round_start)
/datum/controller/subsystem/dbcore/proc/SetRoundEnd()
if(!Connect())
return
- var/sql_station_name = sanitizeSQL(station_name())
- var/datum/DBQuery/query_round_end = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET end_datetime = Now(), game_mode_result = '[sanitizeSQL(SSticker.mode_result)]', station_name = '[sql_station_name]' WHERE id = [GLOB.round_id]")
+ var/datum/db_query/query_round_end = SSdbcore.NewQuery(
+ "UPDATE [format_table_name("round")] SET end_datetime = Now(), game_mode_result = :game_mode_result, station_name = :station_name WHERE id = :round_id",
+ list("game_mode_result" = SSticker.mode_result, "station_name" = station_name(), "round_id" = GLOB.round_id)
+ )
query_round_end.Execute()
qdel(query_round_end)
/datum/controller/subsystem/dbcore/proc/Disconnect()
failed_connections = 0
- QDEL_NULL(connectOperation)
- QDEL_NULL(connection)
+ if (connection)
+ rustg_sql_disconnect_pool(connection)
+ connection = null
/datum/controller/subsystem/dbcore/proc/IsConnected()
- if(!CONFIG_GET(flag/sql_enabled))
+ if (!CONFIG_GET(flag/sql_enabled))
return FALSE
- //block until any connect operations finish
- var/datum/BSQL_Connection/_connection = connection
- var/datum/BSQL_Operation/op = connectOperation
- UNTIL(QDELETED(_connection) || op.IsComplete())
- return !QDELETED(connection) && !op.GetError()
-
-/datum/controller/subsystem/dbcore/proc/Quote(str)
- if(connection)
- return connection.Quote(str)
+ if (!connection)
+ return FALSE
+ return json_decode(rustg_sql_connected(connection))["status"] == "online"
/datum/controller/subsystem/dbcore/proc/ErrorMsg()
if(!CONFIG_GET(flag/sql_enabled))
@@ -170,12 +174,33 @@ SUBSYSTEM_DEF(dbcore)
/datum/controller/subsystem/dbcore/proc/ReportError(error)
last_error = error
-/datum/controller/subsystem/dbcore/proc/NewQuery(sql_query)
+/datum/controller/subsystem/dbcore/proc/NewQuery(sql_query, arguments)
if(IsAdminAdvancedProcCall())
log_admin_private("ERROR: Advanced admin proc call led to sql query: [sql_query]. Query has been blocked")
message_admins("ERROR: Advanced admin proc call led to sql query. Query has been blocked")
return FALSE
- return new /datum/DBQuery(sql_query, connection)
+ return new /datum/db_query(connection, sql_query, arguments)
+
+/datum/controller/subsystem/dbcore/proc/QuerySelect(list/querys, warn = FALSE, qdel = FALSE)
+ if (!islist(querys))
+ if (!istype(querys, /datum/db_query))
+ CRASH("Invalid query passed to QuerySelect: [querys]")
+ querys = list(querys)
+
+ for (var/thing in querys)
+ var/datum/db_query/query = thing
+ if (warn)
+ INVOKE_ASYNC(query, /datum/db_query.proc/warn_execute)
+ else
+ INVOKE_ASYNC(query, /datum/db_query.proc/Execute)
+
+ for (var/thing in querys)
+ var/datum/db_query/query = thing
+ UNTIL(!query.in_progress)
+ if (qdel)
+ qdel(query)
+
+
/*
Takes a list of rows (each row being an associated list of column => value) and inserts them via a single mass query.
@@ -184,137 +209,135 @@ You are expected to do your own escaping of the data, and expected to provide yo
The duplicate_key arg can be true to automatically generate this part of the query
or set to a string that is appended to the end of the query
Ignore_errors instructes mysql to continue inserting rows if some of them have errors.
- the erroneous row(s) aren't inserted and there isn't really any way to know why or why errored
+ the erroneous row(s) aren't inserted and there isn't really any way to know why or why errored
Delayed insert mode was removed in mysql 7 and only works with MyISAM type tables,
It was included because it is still supported in mariadb.
It does not work with duplicate_key and the mysql server ignores it in those cases
*/
-/datum/controller/subsystem/dbcore/proc/MassInsert(table, list/rows, duplicate_key = FALSE, ignore_errors = FALSE, delayed = FALSE, warn = FALSE, async = TRUE)
+/datum/controller/subsystem/dbcore/proc/MassInsert(table, list/rows, duplicate_key = FALSE, ignore_errors = FALSE, delayed = FALSE, warn = FALSE, async = TRUE, special_columns = null)
if (!table || !rows || !istype(rows))
return
+
+ // Prepare column list
var/list/columns = list()
- var/list/sorted_rows = list()
-
+ var/list/has_question_mark = list()
for (var/list/row in rows)
- var/list/sorted_row = list()
- sorted_row.len = columns.len
for (var/column in row)
- var/idx = columns[column]
- if (!idx)
- idx = columns.len + 1
- columns[column] = idx
- sorted_row.len = columns.len
+ columns[column] = "?"
+ has_question_mark[column] = TRUE
+ for (var/column in special_columns)
+ columns[column] = special_columns[column]
+ has_question_mark[column] = findtext(special_columns[column], "?")
- sorted_row[idx] = row[column]
- sorted_rows[++sorted_rows.len] = sorted_row
+ // Prepare SQL query full of placeholders
+ var/list/query_parts = list("INSERT")
+ if (delayed)
+ query_parts += " DELAYED"
+ if (ignore_errors)
+ query_parts += " IGNORE"
+ query_parts += " INTO "
+ query_parts += table
+ query_parts += "\n([columns.Join(", ")])\nVALUES"
+
+ var/list/arguments = list()
+ var/has_row = FALSE
+ for (var/list/row in rows)
+ if (has_row)
+ query_parts += ","
+ query_parts += "\n ("
+ var/has_col = FALSE
+ for (var/column in columns)
+ if (has_col)
+ query_parts += ", "
+ if (has_question_mark[column])
+ var/name = "p[arguments.len]"
+ query_parts += replacetext(columns[column], "?", ":[name]")
+ arguments[name] = row[column]
+ else
+ query_parts += columns[column]
+ has_col = TRUE
+ query_parts += ")"
+ has_row = TRUE
if (duplicate_key == TRUE)
var/list/column_list = list()
for (var/column in columns)
column_list += "[column] = VALUES([column])"
- duplicate_key = "ON DUPLICATE KEY UPDATE [column_list.Join(", ")]\n"
- else if (duplicate_key == FALSE)
- duplicate_key = null
+ query_parts += "\nON DUPLICATE KEY UPDATE [column_list.Join(", ")]"
+ else if (duplicate_key != FALSE)
+ query_parts += duplicate_key
- if (ignore_errors)
- ignore_errors = " IGNORE"
- else
- ignore_errors = null
-
- if (delayed)
- delayed = " DELAYED"
- else
- delayed = null
-
- var/list/sqlrowlist = list()
- var/len = columns.len
- for (var/list/row in sorted_rows)
- if (length(row) != len)
- row.len = len
- for (var/value in row)
- if (value == null)
- value = "NULL"
- sqlrowlist += "([row.Join(", ")])"
-
- sqlrowlist = " [sqlrowlist.Join(",\n ")]"
- var/datum/DBQuery/Query = NewQuery("INSERT[delayed][ignore_errors] INTO [table]\n([columns.Join(", ")])\nVALUES\n[sqlrowlist]\n[duplicate_key]")
+ var/datum/db_query/Query = NewQuery(query_parts.Join(), arguments)
if (warn)
. = Query.warn_execute(async)
else
. = Query.Execute(async)
qdel(Query)
-/datum/DBQuery
- var/sql // The sql query being executed.
- var/list/item //list of data values populated by NextRow()
+/datum/db_query
+ // Inputs
+ var/connection
+ var/sql
+ var/arguments
+ // Status information
+ var/in_progress
+ var/last_error
var/last_activity
var/last_activity_time
- var/last_error
- var/skip_next_is_complete
- var/in_progress
- var/datum/BSQL_Connection/connection
- var/datum/BSQL_Operation/Query/query
+ // Output
+ var/list/list/rows
+ var/next_row_to_take = 1
+ var/affected
+ var/last_insert_id
-/datum/DBQuery/New(sql_query, datum/BSQL_Connection/connection)
+ var/list/item //list of data values populated by NextRow()
+
+/datum/db_query/New(connection, sql, arguments)
SSdbcore.active_queries[src] = TRUE
Activity("Created")
item = list()
- src.connection = connection
- sql = sql_query
-/datum/DBQuery/Destroy()
+ src.connection = connection
+ src.sql = sql
+ src.arguments = arguments
+
+/datum/db_query/Destroy()
Close()
SSdbcore.active_queries -= src
return ..()
-/datum/DBQuery/CanProcCall(proc_name)
+/datum/db_query/CanProcCall(proc_name)
//fuck off kevinz
return FALSE
-/datum/DBQuery/proc/SetQuery(new_sql)
- if(in_progress)
- CRASH("Attempted to set new sql while waiting on active query")
- Close()
- sql = new_sql
-
-/datum/DBQuery/proc/Activity(activity)
+/datum/db_query/proc/Activity(activity)
last_activity = activity
last_activity_time = world.time
-/datum/DBQuery/proc/warn_execute(async = FALSE)
+/datum/db_query/proc/warn_execute(async = TRUE)
. = Execute(async)
if(!.)
to_chat(usr, "A SQL error occurred during this operation, check the server logs.")
-/datum/DBQuery/proc/Execute(async = FALSE, log_error = TRUE)
+/datum/db_query/proc/Execute(async = TRUE, log_error = TRUE)
Activity("Execute")
if(in_progress)
CRASH("Attempted to start a new query while waiting on the old one")
- if(QDELETED(connection))
+ if(!SSdbcore.IsConnected())
last_error = "No connection!"
return FALSE
var/start_time
- var/timed_out
if(!async)
start_time = REALTIMEOFDAY
Close()
- query = connection.BeginQuery(sql)
- if(!async)
- timed_out = !query.WaitForCompletion()
- else
- in_progress = TRUE
- UNTIL(query.IsComplete())
- in_progress = FALSE
- skip_next_is_complete = TRUE
- var/error = QDELETED(query) ? "Query object deleted!" : query.GetError()
- last_error = error
- . = !error
+ . = run_query(async)
+ var/timed_out = !. && findtext(last_error, "Operation timed out")
if(!. && log_error)
- log_sql("[error] | Query used: [sql]")
+ log_sql("[last_error] | Query used: [sql] | Arguments: [json_encode(arguments)]")
if(!async && timed_out)
log_query_debug("Query execution started at [start_time]")
log_query_debug("Query execution ended at [REALTIMEOFDAY]")
@@ -322,44 +345,51 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
log_query_debug("Query used: [sql]")
slow_query_check()
-/datum/DBQuery/proc/slow_query_check()
+/datum/db_query/proc/run_query(async)
+ var/job_result_str
+
+ if (async)
+ var/job_id = rustg_sql_query_async(connection, sql, json_encode(arguments))
+ in_progress = TRUE
+ UNTIL((job_result_str = rustg_sql_check_query(job_id)) != RUSTG_JOB_NO_RESULTS_YET)
+ in_progress = FALSE
+
+ if (job_result_str == RUSTG_JOB_ERROR)
+ last_error = job_result_str
+ return FALSE
+ else
+ job_result_str = rustg_sql_query_blocking(connection, sql, json_encode(arguments))
+
+ var/result = json_decode(job_result_str)
+ switch (result["status"])
+ if ("ok")
+ rows = result["rows"]
+ affected = result["affected"]
+ last_insert_id = result["last_insert_id"]
+ return TRUE
+ if ("err")
+ last_error = result["data"]
+ return FALSE
+ if ("offline")
+ last_error = "offline"
+ return FALSE
+
+/datum/db_query/proc/slow_query_check()
message_admins("HEY! A database query timed out. Did the server just hang? \[YES\]|\[NO\]")
-/datum/DBQuery/proc/NextRow(async)
+/datum/db_query/proc/NextRow(async = TRUE)
Activity("NextRow")
- UNTIL(!in_progress)
- if(!skip_next_is_complete)
- if(!async)
- query.WaitForCompletion()
- else
- in_progress = TRUE
- UNTIL(query.IsComplete())
- in_progress = FALSE
+
+ if (rows && next_row_to_take <= rows.len)
+ item = rows[next_row_to_take]
+ next_row_to_take++
+ return !!item
else
- skip_next_is_complete = FALSE
+ return FALSE
- last_error = query.GetError()
- var/list/results = query.CurrentRow()
- . = results != null
-
- item.Cut()
- //populate item array
- for(var/I in results)
- item += results[I]
-
-/datum/DBQuery/proc/ErrorMsg()
+/datum/db_query/proc/ErrorMsg()
return last_error
-/datum/DBQuery/proc/Close()
- item.Cut()
- QDEL_NULL(query)
-
-/world/BSQL_Debug(message)
- if(!CONFIG_GET(flag/bsql_debug))
- return
-
- //strip sensitive stuff
- if(findtext(message, ": CreateConnection("))
- message = "CreateConnection CENSORED"
-
- log_sql("BSQL_DEBUG: [message]")
+/datum/db_query/proc/Close()
+ rows = null
+ item = null
diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm
index 2ea3b29c91..36347c9a43 100644
--- a/code/controllers/subsystem/mapping.dm
+++ b/code/controllers/subsystem/mapping.dm
@@ -272,7 +272,9 @@ SUBSYSTEM_DEF(mapping)
LoadGroup(FailedZs, "Station", config.map_path, config.map_file, config.traits, ZTRAITS_STATION, FALSE, config.orientation)
if(SSdbcore.Connect())
- var/datum/DBQuery/query_round_map_name = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET map_name = '[config.map_name]' WHERE id = [GLOB.round_id]")
+ var/datum/db_query/query_round_map_name = SSdbcore.NewQuery({"
+ UPDATE [format_table_name("round")] SET map_name = :map_name WHERE id = :round_id
+ "}, list("map_name" = config.map_name, "round_id" = GLOB.round_id))
query_round_map_name.Execute()
qdel(query_round_map_name)
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 3d7eeb7a8a..8bef236c5e 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -81,30 +81,43 @@
///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things
/datum/game_mode/proc/post_setup(report) //Gamemodes can override the intercept report. Passing TRUE as the argument will force a report.
- //finalize_monster_hunters() Disabled for now
if(!report)
report = !CONFIG_GET(flag/no_intercept_report)
addtimer(CALLBACK(GLOBAL_PROC, .proc/display_roundstart_logout_report), ROUNDSTART_LOGOUT_REPORT_TIME)
- if(prob(20)) //CIT CHANGE - adds a 20% chance for the security level to be the opposite of what it normally is
+ if(prob(20)) //cit-change
flipseclevel = TRUE
+
+ // if(CONFIG_GET(flag/reopen_roundstart_suicide_roles))
+ // var/delay = CONFIG_GET(number/reopen_roundstart_suicide_roles_delay)
+ // if(delay)
+ // delay = (delay SECONDS)
+ // else
+ // delay = (4 MINUTES) //default to 4 minutes if the delay isn't defined.
+ // addtimer(CALLBACK(GLOBAL_PROC, .proc/reopen_roundstart_suicide_roles), delay)
+
if(SSdbcore.Connect())
- var/sql
+ var/list/to_set = list()
+ var/arguments = list()
if(SSticker.mode)
- sql += "game_mode = '[SSticker.mode]'"
+ to_set += "game_mode = :game_mode"
+ arguments["game_mode"] = SSticker.mode
if(GLOB.revdata.originmastercommit)
- if(sql)
- sql += ", "
- sql += "commit_hash = '[GLOB.revdata.originmastercommit]'"
- if(sql)
- var/datum/DBQuery/query_round_game_mode = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET [sql] WHERE id = [GLOB.round_id]")
+ to_set += "commit_hash = :commit_hash"
+ arguments["commit_hash"] = GLOB.revdata.originmastercommit
+ if(to_set.len)
+ arguments["round_id"] = GLOB.round_id
+ var/datum/db_query/query_round_game_mode = SSdbcore.NewQuery(
+ "UPDATE [format_table_name("round")] SET [to_set.Join(", ")] WHERE id = :round_id",
+ arguments
+ )
query_round_game_mode.Execute()
qdel(query_round_game_mode)
if(report)
addtimer(CALLBACK(src, .proc/send_intercept, 0), rand(waittime_l, waittime_h))
generate_station_goals()
gamemode_ready = TRUE
- return 1
+ return TRUE
///Handles late-join antag assignments
diff --git a/code/modules/admin/DB_ban/functions.dm b/code/modules/admin/DB_ban/functions.dm
index 39c4d2d939..1f62b487fa 100644
--- a/code/modules/admin/DB_ban/functions.dm
+++ b/code/modules/admin/DB_ban/functions.dm
@@ -81,7 +81,7 @@
var/banned_mob_guest_key = had_banned_mob && IsGuestKey(banned_mob.key)
banned_mob = null
var/sql_ckey = sanitizeSQL(ckey)
- var/datum/DBQuery/query_add_ban_get_ckey = SSdbcore.NewQuery("SELECT 1 FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'")
+ var/datum/db_query/query_add_ban_get_ckey = SSdbcore.NewQuery("SELECT 1 FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'")
if(!query_add_ban_get_ckey.warn_execute())
qdel(query_add_ban_get_ckey)
return
@@ -125,7 +125,7 @@
reason = sanitizeSQL(reason)
var/sql_a_ckey = sanitizeSQL(a_ckey)
if(maxadminbancheck)
- var/datum/DBQuery/query_check_adminban_amt = SSdbcore.NewQuery("SELECT count(id) AS num FROM [format_table_name("ban")] WHERE (a_ckey = '[sql_a_ckey]') AND (bantype = 'ADMIN_PERMABAN' OR (bantype = 'ADMIN_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
+ var/datum/db_query/query_check_adminban_amt = SSdbcore.NewQuery("SELECT count(id) AS num FROM [format_table_name("ban")] WHERE (a_ckey = '[sql_a_ckey]') AND (bantype = 'ADMIN_PERMABAN' OR (bantype = 'ADMIN_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
if(!query_check_adminban_amt.warn_execute())
qdel(query_check_adminban_amt)
return
@@ -149,7 +149,7 @@
var/sql_a_computerid = sanitizeSQL(a_computerid)
var/sql_a_ip = sanitizeSQL(a_ip)
var/sql = "INSERT INTO [format_table_name("ban")] (`bantime`,`server_ip`,`server_port`,`round_id`,`bantype`,`reason`,`job`,`duration`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`) VALUES (Now(), INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]', '[bantype_str]', '[reason]', '[sql_job]', [(duration)?"[duration]":"0"], Now() + INTERVAL [(duration>0) ? duration : 0] MINUTE, '[sql_ckey]', '[sql_computerid]', INET_ATON('[sql_ip]'), '[sql_a_ckey]', '[sql_a_computerid]', INET_ATON('[sql_a_ip]'), '[who]', '[adminwho]')"
- var/datum/DBQuery/query_add_ban = SSdbcore.NewQuery(sql)
+ var/datum/db_query/query_add_ban = SSdbcore.NewQuery(sql)
if(!query_add_ban.warn_execute())
qdel(query_add_ban)
return
@@ -224,7 +224,7 @@
var/ban_id
var/ban_number = 0 //failsafe
- var/datum/DBQuery/query_unban_get_id = SSdbcore.NewQuery(sql)
+ var/datum/db_query/query_unban_get_id = SSdbcore.NewQuery(sql)
if(!query_unban_get_id.warn_execute())
qdel(query_unban_get_id)
return
@@ -258,7 +258,7 @@
to_chat(usr, "Cancelled")
return
- var/datum/DBQuery/query_edit_ban_get_details = SSdbcore.NewQuery("SELECT IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), ckey), duration, reason FROM [format_table_name("ban")] WHERE id = [banid]")
+ var/datum/db_query/query_edit_ban_get_details = SSdbcore.NewQuery("SELECT IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), ckey), duration, reason FROM [format_table_name("ban")] WHERE id = [banid]")
if(!query_edit_ban_get_details.warn_execute())
qdel(query_edit_ban_get_details)
return
@@ -290,7 +290,7 @@
to_chat(usr, "Cancelled")
return
- var/datum/DBQuery/query_edit_ban_reason = SSdbcore.NewQuery("UPDATE [format_table_name("ban")] SET reason = '[value]', edits = CONCAT(edits,'- [e_key] changed ban reason from \\\"[reason]\\\" to \\\"[value]\\\"
') WHERE id = [banid]")
+ var/datum/db_query/query_edit_ban_reason = SSdbcore.NewQuery("UPDATE [format_table_name("ban")] SET reason = '[value]', edits = CONCAT(edits,'- [e_key] changed ban reason from \\\"[reason]\\\" to \\\"[value]\\\"
') WHERE id = [banid]")
if(!query_edit_ban_reason.warn_execute())
qdel(query_edit_ban_reason)
return
@@ -303,7 +303,7 @@
to_chat(usr, "Cancelled")
return
- var/datum/DBQuery/query_edit_ban_duration = SSdbcore.NewQuery("UPDATE [format_table_name("ban")] SET duration = [value], edits = CONCAT(edits,'- [e_key] changed ban duration from [duration] to [value]
'), expiration_time = DATE_ADD(bantime, INTERVAL [value] MINUTE) WHERE id = [banid]")
+ var/datum/db_query/query_edit_ban_duration = SSdbcore.NewQuery("UPDATE [format_table_name("ban")] SET duration = [value], edits = CONCAT(edits,'- [e_key] changed ban duration from [duration] to [value]
'), expiration_time = DATE_ADD(bantime, INTERVAL [value] MINUTE) WHERE id = [banid]")
if(!query_edit_ban_duration.warn_execute())
qdel(query_edit_ban_duration)
return
@@ -333,7 +333,7 @@
var/ban_number = 0 //failsafe
var/p_key
- var/datum/DBQuery/query_unban_get_ckey = SSdbcore.NewQuery(sql)
+ var/datum/db_query/query_unban_get_ckey = SSdbcore.NewQuery(sql)
if(!query_unban_get_ckey.warn_execute())
qdel(query_unban_get_ckey)
return
@@ -358,7 +358,7 @@
var/unban_ip = owner.address
var/sql_update = "UPDATE [format_table_name("ban")] SET unbanned = 1, unbanned_datetime = Now(), unbanned_ckey = '[unban_ckey]', unbanned_computerid = '[unban_computerid]', unbanned_ip = INET_ATON('[unban_ip]') WHERE id = [id]"
- var/datum/DBQuery/query_unban = SSdbcore.NewQuery(sql_update)
+ var/datum/db_query/query_unban = SSdbcore.NewQuery(sql_update)
if(!query_unban.warn_execute())
qdel(query_unban)
return
@@ -461,7 +461,7 @@
var/bansperpage = 15
var/pagecount = 0
page = text2num(page)
- var/datum/DBQuery/query_count_bans = SSdbcore.NewQuery("SELECT COUNT(id) FROM [format_table_name("ban")] WHERE [search]")
+ var/datum/db_query/query_count_bans = SSdbcore.NewQuery("SELECT COUNT(id) FROM [format_table_name("ban")] WHERE [search]")
if(!query_count_bans.warn_execute())
qdel(query_count_bans)
return
@@ -489,7 +489,7 @@
output += "
OPTIONS | "
output += ""
var/limit = " LIMIT [bansperpage * page], [bansperpage]"
- var/datum/DBQuery/query_search_bans = SSdbcore.NewQuery("SELECT id, bantime, bantype, reason, job, duration, expiration_time, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), ckey), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].a_ckey), a_ckey), unbanned, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].unbanned_ckey), unbanned_ckey), unbanned_datetime, edits, round_id FROM [format_table_name("ban")] WHERE [search] ORDER BY bantime DESC[limit]")
+ var/datum/db_query/query_search_bans = SSdbcore.NewQuery("SELECT id, bantime, bantype, reason, job, duration, expiration_time, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), ckey), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].a_ckey), a_ckey), unbanned, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].unbanned_ckey), unbanned_ckey), unbanned_datetime, edits, round_id FROM [format_table_name("ban")] WHERE [search] ORDER BY bantime DESC[limit]")
if(!query_search_bans.warn_execute())
qdel(query_search_bans)
return
diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm
index 4ddb92ab19..a9a85e160d 100644
--- a/code/modules/admin/IsBanned.dm
+++ b/code/modules/admin/IsBanned.dm
@@ -100,7 +100,7 @@
if(computer_id)
cidquery = " OR computerid = '[computer_id]' "
- var/datum/DBQuery/query_ban_check = SSdbcore.NewQuery("SELECT IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), ckey), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].a_ckey), a_ckey), reason, expiration_time, duration, bantime, bantype, id, round_id FROM [format_table_name("ban")] WHERE (ckey = '[ckey]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR bantype = 'ADMIN_PERMABAN' OR ((bantype = 'TEMPBAN' OR bantype = 'ADMIN_TEMPBAN') AND expiration_time > Now())) AND isnull(unbanned)")
+ var/datum/db_query/query_ban_check = SSdbcore.NewQuery("SELECT IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), ckey), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].a_ckey), a_ckey), reason, expiration_time, duration, bantime, bantype, id, round_id FROM [format_table_name("ban")] WHERE (ckey = '[ckey]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR bantype = 'ADMIN_PERMABAN' OR ((bantype = 'TEMPBAN' OR bantype = 'ADMIN_TEMPBAN') AND expiration_time > Now())) AND isnull(unbanned)")
if(!query_ban_check.Execute(async = TRUE))
qdel(query_ban_check)
key_cache[key] = 0
diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm
index 39053b8e15..dbc98fb0d7 100644
--- a/code/modules/admin/admin_ranks.dm
+++ b/code/modules/admin/admin_ranks.dm
@@ -160,7 +160,7 @@ GLOBAL_PROTECT(protected_ranks)
if(!no_update)
sync_ranks_with_db()
else
- var/datum/DBQuery/query_load_admin_ranks = SSdbcore.NewQuery("SELECT rank, flags, exclude_flags, can_edit_flags FROM [format_table_name("admin_ranks")]")
+ var/datum/db_query/query_load_admin_ranks = SSdbcore.NewQuery("SELECT `rank`, flags, exclude_flags, can_edit_flags FROM [format_table_name("admin_ranks")]")
if(!query_load_admin_ranks.Execute())
message_admins("Error loading admin ranks from database. Loading from backup.")
log_sql("Error loading admin ranks from database. Loading from backup.")
@@ -168,7 +168,7 @@ GLOBAL_PROTECT(protected_ranks)
else
while(query_load_admin_ranks.NextRow())
var/skip
- var/rank_name = ckeyEx(query_load_admin_ranks.item[1])
+ var/rank_name = query_load_admin_ranks.item[1]
for(var/datum/admin_rank/R in GLOB.admin_ranks)
if(R.name == rank_name) //this rank was already loaded from txt override
skip = 1
@@ -234,20 +234,12 @@ GLOBAL_PROTECT(protected_ranks)
for(var/datum/admin_rank/R in GLOB.admin_ranks)
rank_names[R.name] = R
//ckeys listed in admins.txt are always made admins before sql loading is attempted
- var/list/lines = world.file2list("[global.config.directory]/admins.txt")
- for(var/line in lines)
- if(!length(line) || findtextEx(line, "#", 1, 2))
- continue
- var/list/entry = splittext(line, "=")
- if(entry.len < 2)
- continue
- var/ckey = ckey(entry[1])
- var/rank = ckeyEx(entry[2])
- if(!ckey || !rank)
- continue
- new /datum/admins(rank_names[rank], ckey, 0, 1)
+ var/admins_text = file2text("[global.config.directory]/admins.txt")
+ var/regex/admins_regex = new(@"^(?!#)(.+?)\s+=\s+(.+)", "gm")
+ while(admins_regex.Find(admins_text))
+ new /datum/admins(rank_names[admins_regex.group[2]], ckey(admins_regex.group[1]), FALSE, TRUE)
if(!CONFIG_GET(flag/admin_legacy_system) || dbfail)
- var/datum/DBQuery/query_load_admins = SSdbcore.NewQuery("SELECT ckey, rank FROM [format_table_name("admin")] ORDER BY rank")
+ var/datum/db_query/query_load_admins = SSdbcore.NewQuery("SELECT ckey, `rank` FROM [format_table_name("admin")] ORDER BY `rank`")
if(!query_load_admins.Execute())
message_admins("Error loading admins from database. Loading from backup.")
log_sql("Error loading admins from database. Loading from backup.")
@@ -255,7 +247,7 @@ GLOBAL_PROTECT(protected_ranks)
else
while(query_load_admins.NextRow())
var/admin_ckey = ckey(query_load_admins.item[1])
- var/admin_rank = ckeyEx(query_load_admins.item[2])
+ var/admin_rank = query_load_admins.item[2]
var/skip
if(rank_names[admin_rank] == null)
message_admins("[admin_ckey] loaded with invalid admin rank [admin_rank].")
diff --git a/code/modules/admin/banjob.dm b/code/modules/admin/banjob.dm
index cae1c6b22e..c6d8e9a5b0 100644
--- a/code/modules/admin/banjob.dm
+++ b/code/modules/admin/banjob.dm
@@ -3,8 +3,8 @@
if(!M || !istype(M) || !M.ckey)
return FALSE
- if(!M.client) //no cache. fallback to a datum/DBQuery
- var/datum/DBQuery/query_jobban_check_ban = SSdbcore.NewQuery("SELECT reason FROM [format_table_name("ban")] WHERE ckey = '[sanitizeSQL(M.ckey)]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned) AND job = '[sanitizeSQL(rank)]'")
+ if(!M.client) //no cache. fallback to a datum/db_query
+ var/datum/db_query/query_jobban_check_ban = SSdbcore.NewQuery("SELECT reason FROM [format_table_name("ban")] WHERE ckey = '[sanitizeSQL(M.ckey)]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned) AND job = '[sanitizeSQL(rank)]'")
if(!query_jobban_check_ban.warn_execute())
qdel(query_jobban_check_ban)
return
@@ -28,7 +28,7 @@
return
if(C && istype(C))
C.jobbancache = list()
- var/datum/DBQuery/query_jobban_build_cache = SSdbcore.NewQuery("SELECT job, reason FROM [format_table_name("ban")] WHERE ckey = '[sanitizeSQL(C.ckey)]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
+ var/datum/db_query/query_jobban_build_cache = SSdbcore.NewQuery("SELECT job, reason FROM [format_table_name("ban")] WHERE ckey = '[sanitizeSQL(C.ckey)]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
if(!query_jobban_build_cache.warn_execute())
qdel(query_jobban_build_cache)
return
diff --git a/code/modules/admin/create_poll.dm b/code/modules/admin/create_poll.dm
index 9f002f92e0..a6797ceb5f 100644
--- a/code/modules/admin/create_poll.dm
+++ b/code/modules/admin/create_poll.dm
@@ -35,7 +35,7 @@
if(!endtime)
return
endtime = sanitizeSQL(endtime)
- var/datum/DBQuery/query_validate_time = SSdbcore.NewQuery("SELECT IF(STR_TO_DATE('[endtime]','%Y-%c-%d %T') > NOW(), STR_TO_DATE('[endtime]','%Y-%c-%d %T'), 0)")
+ var/datum/db_query/query_validate_time = SSdbcore.NewQuery("SELECT IF(STR_TO_DATE('[endtime]','%Y-%c-%d %T') > NOW(), STR_TO_DATE('[endtime]','%Y-%c-%d %T'), 0)")
if(!query_validate_time.warn_execute() || QDELETED(usr) || !src)
qdel(query_validate_time)
return
@@ -129,14 +129,14 @@
return 0
var/m1 = "[key_name(usr)] has created a new server poll. Poll type: [polltype] - Admin Only: [adminonly ? "Yes" : "No"] - Question: [question]"
var/m2 = "[key_name_admin(usr)] has created a new server poll. Poll type: [polltype] - Admin Only: [adminonly ? "Yes" : "No"]
Question: [question]"
- var/datum/DBQuery/query_polladd_question = SSdbcore.NewQuery("INSERT INTO [format_table_name("poll_question")] (polltype, starttime, endtime, question, adminonly, multiplechoiceoptions, createdby_ckey, createdby_ip, dontshow) VALUES ('[polltype]', '[starttime]', '[endtime]', '[question]', '[adminonly]', '[choice_amount]', '[sql_ckey]', INET_ATON('[address]'), '[dontshow]')")
+ var/datum/db_query/query_polladd_question = SSdbcore.NewQuery("INSERT INTO [format_table_name("poll_question")] (polltype, starttime, endtime, question, adminonly, multiplechoiceoptions, createdby_ckey, createdby_ip, dontshow) VALUES ('[polltype]', '[starttime]', '[endtime]', '[question]', '[adminonly]', '[choice_amount]', '[sql_ckey]', INET_ATON('[address]'), '[dontshow]')")
if(!query_polladd_question.warn_execute())
qdel(query_polladd_question)
return
qdel(query_polladd_question)
if(polltype != POLLTYPE_TEXT)
var/pollid = 0
- var/datum/DBQuery/query_get_id = SSdbcore.NewQuery("SELECT LAST_INSERT_ID()")
+ var/datum/db_query/query_get_id = SSdbcore.NewQuery("SELECT LAST_INSERT_ID()")
if(!query_get_id.warn_execute())
qdel(query_get_id)
return
diff --git a/code/modules/admin/ipintel.dm b/code/modules/admin/ipintel.dm
index e0056b3e40..71c9a11acd 100644
--- a/code/modules/admin/ipintel.dm
+++ b/code/modules/admin/ipintel.dm
@@ -29,27 +29,27 @@
return
if (!bypasscache)
var/datum/ipintel/cachedintel = SSipintel.cache[ip]
- if (cachedintel && cachedintel.is_valid())
+ if (cachedintel?.is_valid())
cachedintel.cache = TRUE
return cachedintel
if(SSdbcore.Connect())
var/rating_bad = CONFIG_GET(number/ipintel_rating_bad)
- var/datum/DBQuery/query_get_ip_intel = SSdbcore.NewQuery({"
+ var/datum/db_query/query_get_ip_intel = SSdbcore.NewQuery({"
SELECT date, intel, TIMESTAMPDIFF(MINUTE,date,NOW())
FROM [format_table_name("ipintel")]
WHERE
- ip = INET_ATON('[ip]')
+ ip = INET_ATON(':ip')
AND ((
- intel < [rating_bad]
+ intel < :rating_bad
AND
- date + INTERVAL [CONFIG_GET(number/ipintel_save_good)] HOUR > NOW()
+ date + INTERVAL :save_good HOUR > NOW()
) OR (
- intel >= [rating_bad]
+ intel >= :rating_bad
AND
- date + INTERVAL [CONFIG_GET(number/ipintel_save_bad)] HOUR > NOW()
+ date + INTERVAL :save_bad HOUR > NOW()
))
- "})
+ "}, list("ip" = ip, "rating_bad" = rating_bad, "save_good" = CONFIG_GET(number/ipintel_save_good), "save_bad" = CONFIG_GET(number/ipintel_save_bad)))
if(!query_get_ip_intel.Execute())
qdel(query_get_ip_intel)
return
@@ -67,12 +67,15 @@
if (updatecache && res.intel >= 0)
SSipintel.cache[ip] = res
if(SSdbcore.Connect())
- var/datum/DBQuery/query_add_ip_intel = SSdbcore.NewQuery("INSERT INTO [format_table_name("ipintel")] (ip, intel) VALUES (INET_ATON('[ip]'), [res.intel]) ON DUPLICATE KEY UPDATE intel = VALUES(intel), date = NOW()")
+ var/datum/db_query/query_add_ip_intel = SSdbcore.NewQuery(
+ "INSERT INTO [format_table_name("ipintel")] (ip, intel) VALUES (INET_ATON(:ip), :intel) ON DUPLICATE KEY UPDATE intel = VALUES(intel), date = NOW()",
+ list("ip" = ip, "intel" = res.intel)
+ )
query_add_ip_intel.Execute()
qdel(query_add_ip_intel)
-/proc/ip_intel_query(ip, var/retryed=0)
+/proc/ip_intel_query(ip, retryed=0)
. = -1 //default
if (!ip)
return
@@ -131,8 +134,3 @@
/proc/log_ipintel(text)
log_game("IPINTEL: [text]")
debug_admins("IPINTEL: [text]")
-
-
-
-
-
diff --git a/code/modules/admin/permissionedit.dm b/code/modules/admin/permissionedit.dm
index 05f7465b03..9f5dc00a48 100644
--- a/code/modules/admin/permissionedit.dm
+++ b/code/modules/admin/permissionedit.dm
@@ -15,21 +15,14 @@
else
output += "
\[Log\]
\[Management\]"
if(action == 1)
- var/list/searchlist = list(" WHERE ")
- if(target)
- searchlist += "ckey = '[sanitizeSQL(target)]'"
- if(operation)
- if(target)
- searchlist += " AND "
- searchlist += "operation = '[sanitizeSQL(operation)]'"
- var/search
- if(searchlist.len > 1)
- search = searchlist.Join("")
var/logcount = 0
var/logssperpage = 20
var/pagecount = 0
page = text2num(page)
- var/datum/DBQuery/query_count_admin_logs = SSdbcore.NewQuery("SELECT COUNT(id) FROM [format_table_name("admin_log")][search]")
+ var/datum/db_query/query_count_admin_logs = SSdbcore.NewQuery(
+ "SELECT COUNT(id) FROM [format_table_name("admin_log")] WHERE (:target IS NULL OR adminckey = :target) AND (:operation IS NULL OR operation = :operation)",
+ list("target" = target, "operation" = operation)
+ )
if(!query_count_admin_logs.warn_execute())
qdel(query_count_admin_logs)
return
@@ -43,8 +36,20 @@
logcount -= logssperpage
pagecount++
output += "|"
- var/limit = " LIMIT [logssperpage * page], [logssperpage]"
- var/datum/DBQuery/query_search_admin_logs = SSdbcore.NewQuery("SELECT datetime, round_id, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), adminckey), operation, IF(ckey IS NULL, target, byond_key), log FROM [format_table_name("admin_log")] LEFT JOIN [format_table_name("player")] ON target = ckey[search] ORDER BY datetime DESC[limit]")
+ var/datum/db_query/query_search_admin_logs = SSdbcore.NewQuery({"
+ SELECT
+ datetime,
+ round_id,
+ IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), adminckey),
+ operation,
+ IF(ckey IS NULL, target, byond_key),
+ log
+ FROM [format_table_name("admin_log")]
+ LEFT JOIN [format_table_name("player")] ON target = ckey
+ WHERE (:target IS NULL OR ckey = :target) AND (:operation IS NULL OR operation = :operation)
+ ORDER BY datetime DESC
+ LIMIT :skip, :take
+ "}, list("target" = target, "operation" = operation, "skip" = logssperpage * page, "take" = logssperpage))
if(!query_search_admin_logs.warn_execute())
qdel(query_search_admin_logs)
return
@@ -59,7 +64,7 @@
qdel(query_search_admin_logs)
if(action == 2)
output += "Admin ckeys with invalid ranks
"
- var/datum/DBQuery/query_check_admin_errors = SSdbcore.NewQuery("SELECT IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("admin")].ckey), ckey), [format_table_name("admin")].rank FROM [format_table_name("admin")] LEFT JOIN [format_table_name("admin_ranks")] ON [format_table_name("admin_ranks")].rank = [format_table_name("admin")].rank WHERE [format_table_name("admin_ranks")].rank IS NULL")
+ var/datum/db_query/query_check_admin_errors = SSdbcore.NewQuery("SELECT IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("admin")].ckey), ckey), [format_table_name("admin")].`rank` FROM [format_table_name("admin")] LEFT JOIN [format_table_name("admin_ranks")] ON [format_table_name("admin_ranks")].`rank` = [format_table_name("admin")].`rank` WHERE [format_table_name("admin_ranks")].`rank` IS NULL")
if(!query_check_admin_errors.warn_execute())
qdel(query_check_admin_errors)
return
@@ -70,7 +75,7 @@
output += "
"
qdel(query_check_admin_errors)
output += "Unused ranks
"
- var/datum/DBQuery/query_check_unused_rank = SSdbcore.NewQuery("SELECT [format_table_name("admin_ranks")].rank, flags, exclude_flags, can_edit_flags FROM [format_table_name("admin_ranks")] LEFT JOIN [format_table_name("admin")] ON [format_table_name("admin")].rank = [format_table_name("admin_ranks")].rank WHERE [format_table_name("admin")].rank IS NULL")
+ var/datum/db_query/query_check_unused_rank = SSdbcore.NewQuery("SELECT [format_table_name("admin_ranks")].`rank`, flags, exclude_flags, can_edit_flags FROM [format_table_name("admin_ranks")] LEFT JOIN [format_table_name("admin")] ON [format_table_name("admin")].`rank` = [format_table_name("admin_ranks")].`rank` WHERE [format_table_name("admin")].`rank` IS NULL")
if(!query_check_unused_rank.warn_execute())
qdel(query_check_unused_rank)
return
@@ -130,7 +135,7 @@
log_admin("[key_name(usr)] attempted to edit admin permissions without sufficient rights.")
return
if(IsAdminAdvancedProcCall())
- to_chat(usr, "Admin Edit blocked: Advanced ProcCall detected.")
+ to_chat(usr, "Admin Edit blocked: Advanced ProcCall detected.", confidential = TRUE)
return
var/datum/asset/permissions_assets = get_asset_datum(/datum/asset/simple/permissions)
permissions_assets.send(src)
@@ -145,19 +150,19 @@
skip = TRUE
if(!CONFIG_GET(flag/admin_legacy_system) && CONFIG_GET(flag/protect_legacy_admins) && task == "rank")
if(admin_ckey in GLOB.protected_admins)
- to_chat(usr, "Editing the rank of this admin is blocked by server configuration.")
+ to_chat(usr, "Editing the rank of this admin is blocked by server configuration.", confidential = TRUE)
return
if(!CONFIG_GET(flag/admin_legacy_system) && CONFIG_GET(flag/protect_legacy_ranks) && task == "permissions")
if(D.rank in GLOB.protected_ranks)
- to_chat(usr, "Editing the flags of this rank is blocked by server configuration.")
+ to_chat(usr, "Editing the flags of this rank is blocked by server configuration.", confidential = TRUE)
return
if(CONFIG_GET(flag/load_legacy_ranks_only) && (task == "add" || task == "rank" || task == "permissions"))
- to_chat(usr, "Database rank loading is disabled, only temporary changes can be made to a rank's permissions and permanently creating a new rank is blocked.")
+ to_chat(usr, "Database rank loading is disabled, only temporary changes can be made to a rank's permissions and permanently creating a new rank is blocked.", confidential = TRUE)
legacy_only = TRUE
if(check_rights(R_DBRANKS, FALSE))
if(!skip)
if(!SSdbcore.Connect())
- to_chat(usr, "Unable to connect to database, changes are temporary only.")
+ to_chat(usr, "Unable to connect to database, changes are temporary only.", confidential = TRUE)
use_db = FALSE
else
use_db = alert("Permanent changes are saved to the database for future rounds, temporary changes will affect only the current round", "Permanent or Temporary?", "Permanent", "Temporary", "Cancel")
@@ -165,7 +170,6 @@
return
if(use_db == "Permanent")
use_db = TRUE
- admin_ckey = sanitizeSQL(admin_ckey)
else
use_db = FALSE
if(QDELETED(usr))
@@ -209,26 +213,34 @@
if(!.)
return FALSE
if(!admin_ckey && (. in GLOB.admin_datums+GLOB.deadmins))
- to_chat(usr, "[admin_key] is already an admin.")
+ to_chat(usr, "[admin_key] is already an admin.", confidential = TRUE)
return FALSE
if(use_db)
- . = sanitizeSQL(.)
//if an admin exists without a datum they won't be caught by the above
- var/datum/DBQuery/query_admin_in_db = SSdbcore.NewQuery("SELECT 1 FROM [format_table_name("admin")] WHERE ckey = '[.]'")
+ var/datum/db_query/query_admin_in_db = SSdbcore.NewQuery(
+ "SELECT 1 FROM [format_table_name("admin")] WHERE ckey = :ckey",
+ list("ckey" = .)
+ )
if(!query_admin_in_db.warn_execute())
qdel(query_admin_in_db)
return FALSE
if(query_admin_in_db.NextRow())
qdel(query_admin_in_db)
- to_chat(usr, "[admin_key] already listed in admin database. Check the Management tab if they don't appear in the list of admins.")
+ to_chat(usr, "[admin_key] already listed in admin database. Check the Management tab if they don't appear in the list of admins.", confidential = TRUE)
return FALSE
qdel(query_admin_in_db)
- var/datum/DBQuery/query_add_admin = SSdbcore.NewQuery("INSERT INTO [format_table_name("admin")] (ckey, rank) VALUES ('[.]', 'NEW ADMIN')")
+ var/datum/db_query/query_add_admin = SSdbcore.NewQuery(
+ "INSERT INTO [format_table_name("admin")] (ckey, `rank`) VALUES (:ckey, 'NEW ADMIN')",
+ list("ckey" = .)
+ )
if(!query_add_admin.warn_execute())
qdel(query_add_admin)
return FALSE
qdel(query_add_admin)
- var/datum/DBQuery/query_add_admin_log = SSdbcore.NewQuery("INSERT INTO [format_table_name("admin_log")] (datetime, round_id, adminckey, adminip, operation, target, log) VALUES ('[SQLtime()]', '[GLOB.round_id]', '[sanitizeSQL(usr.ckey)]', INET_ATON('[sanitizeSQL(usr.client.address)]'), 'add admin', '[.]', 'New admin added: [.]')")
+ var/datum/db_query/query_add_admin_log = SSdbcore.NewQuery({"
+ INSERT INTO [format_table_name("admin_log")] (datetime, round_id, adminckey, adminip, operation, target, log)
+ VALUES (:time, :round_id, :adminckey, INET_ATON(:adminip), 'add admin', :target, CONCAT('New admin added: ', :target))
+ "}, list("time" = SQLtime(), "round_id" = "[GLOB.round_id]", "adminckey" = usr.ckey, "adminip" = usr.client.address, "target" = .))
if(!query_add_admin_log.warn_execute())
qdel(query_add_admin_log)
return FALSE
@@ -243,12 +255,18 @@
var/m1 = "[key_name_admin(usr)] removed [admin_key] from the admins list [use_db ? "permanently" : "temporarily"]"
var/m2 = "[key_name(usr)] removed [admin_key] from the admins list [use_db ? "permanently" : "temporarily"]"
if(use_db)
- var/datum/DBQuery/query_add_rank = SSdbcore.NewQuery("DELETE FROM [format_table_name("admin")] WHERE ckey = '[admin_ckey]'")
+ var/datum/db_query/query_add_rank = SSdbcore.NewQuery(
+ "DELETE FROM [format_table_name("admin")] WHERE ckey = :ckey",
+ list("ckey" = admin_ckey)
+ )
if(!query_add_rank.warn_execute())
qdel(query_add_rank)
return
qdel(query_add_rank)
- var/datum/DBQuery/query_add_rank_log = SSdbcore.NewQuery("INSERT INTO [format_table_name("admin_log")] (datetime, round_id, adminckey, adminip, operation, target, log) VALUES ('[SQLtime()]', '[GLOB.round_id]', '[sanitizeSQL(usr.ckey)]', INET_ATON('[sanitizeSQL(usr.client.address)]'), 'remove admin', '[admin_ckey]', 'Admin removed: [admin_ckey]')")
+ var/datum/db_query/query_add_rank_log = SSdbcore.NewQuery({"
+ INSERT INTO [format_table_name("admin_log")] (datetime, round_id, adminckey, adminip, operation, target, log)
+ VALUES (:time, :round_id, :adminckey, INET_ATON(:adminip), 'remove admin', :admin_ckey, CONCAT('Admin removed: ', :admin_ckey))
+ "}, list("time" = SQLtime(), "round_id" = "[GLOB.round_id]", "adminckey" = usr.ckey, "adminip" = usr.client.address, "admin_ckey" = admin_ckey))
if(!query_add_rank_log.warn_execute())
qdel(query_add_rank_log)
return
@@ -271,6 +289,14 @@
log_admin("[key_name(usr)] forcefully deadmined [admin_key]")
D.deactivate() //after logs so the deadmined admin can see the message.
+/datum/admins/proc/auto_deadmin()
+ to_chat(owner, "You are now a normal player.", confidential = TRUE)
+ var/old_owner = owner
+ deactivate()
+ message_admins("[old_owner] deadmined via auto-deadmin config.")
+ log_admin("[old_owner] deadmined via auto-deadmin config.")
+ return TRUE
+
/datum/admins/proc/change_admin_rank(admin_ckey, admin_key, use_db, datum/admins/D, legacy_only)
var/datum/admin_rank/R
var/list/rank_names = list()
@@ -281,7 +307,7 @@
rank_names[R.name] = R
var/new_rank = input("Please select a rank", "New rank") as null|anything in rank_names
if(new_rank == "*New Rank*")
- new_rank = ckeyEx(input("Please input a new rank", "New custom rank") as text|null)
+ new_rank = input("Please input a new rank", "New custom rank") as text|null
if(!new_rank)
return
R = rank_names[new_rank]
@@ -294,10 +320,12 @@
var/m1 = "[key_name_admin(usr)] edited the admin rank of [admin_key] to [new_rank] [use_db ? "permanently" : "temporarily"]"
var/m2 = "[key_name(usr)] edited the admin rank of [admin_key] to [new_rank] [use_db ? "permanently" : "temporarily"]"
if(use_db)
- new_rank = sanitizeSQL(new_rank)
//if a player was tempminned before having a permanent change made to their rank they won't yet be in the db
var/old_rank
- var/datum/DBQuery/query_admin_in_db = SSdbcore.NewQuery("SELECT rank FROM [format_table_name("admin")] WHERE ckey = '[admin_ckey]'")
+ var/datum/db_query/query_admin_in_db = SSdbcore.NewQuery(
+ "SELECT `rank` FROM [format_table_name("admin")] WHERE ckey = :admin_ckey",
+ list("admin_ckey" = admin_ckey)
+ )
if(!query_admin_in_db.warn_execute())
qdel(query_admin_in_db)
return
@@ -308,29 +336,44 @@
old_rank = query_admin_in_db.item[1]
qdel(query_admin_in_db)
//similarly if a temp rank is created it won't be in the db if someone is permanently changed to it
- var/datum/DBQuery/query_rank_in_db = SSdbcore.NewQuery("SELECT 1 FROM [format_table_name("admin_ranks")] WHERE rank = '[new_rank]'")
+ var/datum/db_query/query_rank_in_db = SSdbcore.NewQuery(
+ "SELECT 1 FROM [format_table_name("admin_ranks")] WHERE `rank` = :new_rank",
+ list("new_rank" = new_rank)
+ )
if(!query_rank_in_db.warn_execute())
qdel(query_rank_in_db)
return
if(!query_rank_in_db.NextRow())
QDEL_NULL(query_rank_in_db)
- var/datum/DBQuery/query_add_rank = SSdbcore.NewQuery("INSERT INTO [format_table_name("admin_ranks")] (rank, flags, exclude_flags, can_edit_flags) VALUES ('[new_rank]', '0', '0', '0')")
+ var/datum/db_query/query_add_rank = SSdbcore.NewQuery({"
+ INSERT INTO [format_table_name("admin_ranks")] (`rank`, flags, exclude_flags, can_edit_flags)
+ VALUES (:new_rank, '0', '0', '0')
+ "}, list("new_rank" = new_rank))
if(!query_add_rank.warn_execute())
qdel(query_add_rank)
return
qdel(query_add_rank)
- var/datum/DBQuery/query_add_rank_log = SSdbcore.NewQuery("INSERT INTO [format_table_name("admin_log")] (datetime, round_id, adminckey, adminip, operation, target, log) VALUES ('[SQLtime()]', '[GLOB.round_id]', '[sanitizeSQL(usr.ckey)]', INET_ATON('[sanitizeSQL(usr.client.address)]'), 'add rank', '[new_rank]', 'New rank added: [new_rank]')")
+ var/datum/db_query/query_add_rank_log = SSdbcore.NewQuery({"
+ INSERT INTO [format_table_name("admin_log")] (datetime, round_id, adminckey, adminip, operation, target, log)
+ VALUES (:time, :round_id, :adminckey, INET_ATON(:adminip), 'add rank', :new_rank, CONCAT('New rank added: ', :new_rank))
+ "}, list("time" = SQLtime(), "round_id" = "[GLOB.round_id]", "adminckey" = usr.ckey, "adminip" = usr.client.address, "new_rank" = new_rank))
if(!query_add_rank_log.warn_execute())
qdel(query_add_rank_log)
return
qdel(query_add_rank_log)
qdel(query_rank_in_db)
- var/datum/DBQuery/query_change_rank = SSdbcore.NewQuery("UPDATE [format_table_name("admin")] SET rank = '[new_rank]' WHERE ckey = '[admin_ckey]'")
+ var/datum/db_query/query_change_rank = SSdbcore.NewQuery(
+ "UPDATE [format_table_name("admin")] SET `rank` = :new_rank WHERE ckey = :admin_ckey",
+ list("new_rank" = new_rank, "admin_ckey" = admin_ckey)
+ )
if(!query_change_rank.warn_execute())
qdel(query_change_rank)
return
qdel(query_change_rank)
- var/datum/DBQuery/query_change_rank_log = SSdbcore.NewQuery("INSERT INTO [format_table_name("admin_log")] (datetime, round_id, adminckey, adminip, operation, target, log) VALUES ('[SQLtime()]', '[GLOB.round_id]', '[sanitizeSQL(usr.ckey)]', INET_ATON('[sanitizeSQL(usr.client.address)]'), 'change admin rank', '[admin_ckey]', 'Rank of [admin_ckey] changed from [old_rank] to [new_rank]')")
+ var/datum/db_query/query_change_rank_log = SSdbcore.NewQuery({"
+ INSERT INTO [format_table_name("admin_log")] (datetime, round_id, adminckey, adminip, operation, target, log)
+ VALUES (:time, :round_id, :adminckey, INET_ATON(:adminip), 'change admin rank', :target, CONCAT('Rank of ', :target, ' changed from ', :old_rank, ' to ', :new_rank))
+ "}, list("time" = SQLtime(), "round_id" = "[GLOB.round_id]", "adminckey" = usr.ckey, "adminip" = usr.client.address, "target" = admin_ckey, "old_rank" = old_rank, "new_rank" = new_rank))
if(!query_change_rank_log.warn_execute())
qdel(query_change_rank_log)
return
@@ -357,11 +400,15 @@
return
var/m1 = "[key_name_admin(usr)] edited the permissions of [use_db ? " rank [D.rank.name] permanently" : "[admin_key] temporarily"]"
var/m2 = "[key_name(usr)] edited the permissions of [use_db ? " rank [D.rank.name] permanently" : "[admin_key] temporarily"]"
- if(use_db || legacy_only)
+ if(use_db && !legacy_only)
+ var/rank_name = D.rank.name
var/old_flags
var/old_exclude_flags
var/old_can_edit_flags
- var/datum/DBQuery/query_get_rank_flags = SSdbcore.NewQuery("SELECT flags, exclude_flags, can_edit_flags FROM [format_table_name("admin_ranks")] WHERE rank = '[D.rank.name]'")
+ var/datum/db_query/query_get_rank_flags = SSdbcore.NewQuery(
+ "SELECT flags, exclude_flags, can_edit_flags FROM [format_table_name("admin_ranks")] WHERE `rank` = :rank_name",
+ list("rank_name" = rank_name)
+ )
if(!query_get_rank_flags.warn_execute())
qdel(query_get_rank_flags)
return
@@ -370,12 +417,19 @@
old_exclude_flags = text2num(query_get_rank_flags.item[2])
old_can_edit_flags = text2num(query_get_rank_flags.item[3])
qdel(query_get_rank_flags)
- var/datum/DBQuery/query_change_rank_flags = SSdbcore.NewQuery("UPDATE [format_table_name("admin_ranks")] SET flags = '[new_flags]', exclude_flags = '[new_exclude_flags]', can_edit_flags = '[new_can_edit_flags]' WHERE rank = '[D.rank.name]'")
+ var/datum/db_query/query_change_rank_flags = SSdbcore.NewQuery(
+ "UPDATE [format_table_name("admin_ranks")] SET flags = :new_flags, exclude_flags = :new_exclude_flags, can_edit_flags = :new_can_edit_flags WHERE `rank` = :rank_name",
+ list("new_flags" = new_flags, "new_exclude_flags" = new_exclude_flags, "new_can_edit_flags" = new_can_edit_flags, "rank_name" = rank_name)
+ )
if(!query_change_rank_flags.warn_execute())
qdel(query_change_rank_flags)
return
qdel(query_change_rank_flags)
- var/datum/DBQuery/query_change_rank_flags_log = SSdbcore.NewQuery("INSERT INTO [format_table_name("admin_log")] (datetime, round_id, adminckey, adminip, operation, target, log) VALUES ('[SQLtime()]', '[GLOB.round_id]', '[sanitizeSQL(usr.ckey)]', INET_ATON('[sanitizeSQL(usr.client.address)]'), 'change rank flags', '[D.rank.name]', 'Permissions of [D.rank.name] changed from[rights2text(old_flags," ")][rights2text(old_exclude_flags," ", "-")][rights2text(old_can_edit_flags," ", "*")] to[rights2text(new_flags," ")][rights2text(new_exclude_flags," ", "-")][rights2text(new_can_edit_flags," ", "*")]')")
+ var/log_message = "Permissions of [rank_name] changed from[rights2text(old_flags," ")][rights2text(old_exclude_flags," ", "-")][rights2text(old_can_edit_flags," ", "*")] to[rights2text(new_flags," ")][rights2text(new_exclude_flags," ", "-")][rights2text(new_can_edit_flags," ", "*")]"
+ var/datum/db_query/query_change_rank_flags_log = SSdbcore.NewQuery({"
+ INSERT INTO [format_table_name("admin_log")] (datetime, round_id, adminckey, adminip, operation, target, log)
+ VALUES (:time, :round_id, :adminckey, INET_ATON(:adminip), 'change rank flags', :rank_name, :log)
+ "}, list("time" = SQLtime(), "round_id" = "[GLOB.round_id]", "adminckey" = usr.ckey, "adminip" = usr.client.address, "rank_name" = rank_name, "log" = log_message))
if(!query_change_rank_flags_log.warn_execute())
qdel(query_change_rank_flags_log)
return
@@ -418,33 +472,41 @@
return
for(var/datum/admin_rank/R in GLOB.admin_ranks)
if(R.name == admin_rank && (!(R.rights & usr.client.holder.rank.can_edit_rights) == R.rights))
- to_chat(usr, "You don't have edit rights to all the rights this rank has, rank deletion not permitted.")
+ to_chat(usr, "You don't have edit rights to all the rights this rank has, rank deletion not permitted.", confidential = TRUE)
return
if(!CONFIG_GET(flag/admin_legacy_system) && CONFIG_GET(flag/protect_legacy_ranks) && (admin_rank in GLOB.protected_ranks))
- to_chat(usr, "Deletion of protected ranks is not permitted, it must be removed from admin_ranks.txt.")
+ to_chat(usr, "Deletion of protected ranks is not permitted, it must be removed from admin_ranks.txt.", confidential = TRUE)
return
if(CONFIG_GET(flag/load_legacy_ranks_only))
- to_chat(usr, "Rank deletion not permitted while database rank loading is disabled.")
+ to_chat(usr, "Rank deletion not permitted while database rank loading is disabled.", confidential = TRUE)
return
- admin_rank = sanitizeSQL(admin_rank)
- var/datum/DBQuery/query_admins_with_rank = SSdbcore.NewQuery("SELECT 1 FROM [format_table_name("admin")] WHERE rank = '[admin_rank]'")
+ var/datum/db_query/query_admins_with_rank = SSdbcore.NewQuery(
+ "SELECT 1 FROM [format_table_name("admin")] WHERE `rank` = :admin_rank",
+ list("admin_rank" = admin_rank)
+ )
if(!query_admins_with_rank.warn_execute())
qdel(query_admins_with_rank)
return
if(query_admins_with_rank.NextRow())
qdel(query_admins_with_rank)
- to_chat(usr, "Error: Rank deletion attempted while rank still used; Tell a coder, this shouldn't happen.")
+ to_chat(usr, "Error: Rank deletion attempted while rank still used; Tell a coder, this shouldn't happen.", confidential = TRUE)
return
qdel(query_admins_with_rank)
if(alert("Are you sure you want to remove [admin_rank]?","Confirm Removal","Do it","Cancel") == "Do it")
var/m1 = "[key_name_admin(usr)] removed rank [admin_rank] permanently"
var/m2 = "[key_name(usr)] removed rank [admin_rank] permanently"
- var/datum/DBQuery/query_add_rank = SSdbcore.NewQuery("DELETE FROM [format_table_name("admin_ranks")] WHERE rank = '[admin_rank]'")
+ var/datum/db_query/query_add_rank = SSdbcore.NewQuery(
+ "DELETE FROM [format_table_name("admin_ranks")] WHERE `rank` = :admin_rank",
+ list("admin_rank" = admin_rank)
+ )
if(!query_add_rank.warn_execute())
qdel(query_add_rank)
return
qdel(query_add_rank)
- var/datum/DBQuery/query_add_rank_log = SSdbcore.NewQuery("INSERT INTO [format_table_name("admin_log")] (datetime, round_id, adminckey, adminip, operation, target, log) VALUES ('[SQLtime()]', '[GLOB.round_id]', '[sanitizeSQL(usr.ckey)]', INET_ATON('[sanitizeSQL(usr.client.address)]'), 'remove rank', '[admin_rank]', 'Rank removed: [admin_rank]')")
+ var/datum/db_query/query_add_rank_log = SSdbcore.NewQuery({"
+ INSERT INTO [format_table_name("admin_log")] (datetime, round_id, adminckey, adminip, operation, target, log)
+ VALUES (:time, :round_id, :adminckey, INET_ATON(:adminip), 'remove rank', :admin_rank, CONCAT('Rank removed: ', :admin_rank))
+ "}, list("time" = SQLtime(), "round_id" = "[GLOB.round_id]", "adminckey" = usr.ckey, "adminip" = usr.client.address, "admin_rank" = admin_rank))
if(!query_add_rank_log.warn_execute())
qdel(query_add_rank_log)
return
@@ -455,11 +517,13 @@
/datum/admins/proc/sync_lastadminrank(admin_ckey, admin_key, datum/admins/D)
var/sqlrank = "Player"
if (D)
- sqlrank = sanitizeSQL(D.rank.name)
- admin_ckey = sanitizeSQL(admin_ckey)
- var/datum/DBQuery/query_sync_lastadminrank = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET lastadminrank = '[sqlrank]' WHERE ckey = '[admin_ckey]'")
+ sqlrank = D.rank.name
+ var/datum/db_query/query_sync_lastadminrank = SSdbcore.NewQuery(
+ "UPDATE [format_table_name("player")] SET lastadminrank = :rank WHERE ckey = :ckey",
+ list("rank" = sqlrank, "ckey" = admin_ckey)
+ )
if(!query_sync_lastadminrank.warn_execute())
qdel(query_sync_lastadminrank)
return
qdel(query_sync_lastadminrank)
- to_chat(usr, "Sync of [admin_key] successful.")
+ to_chat(usr, "Sync of [admin_key] successful.", confidential = TRUE)
diff --git a/code/modules/admin/sql_message_system.dm b/code/modules/admin/sql_message_system.dm
index 4218d4238f..3ba309bc24 100644
--- a/code/modules/admin/sql_message_system.dm
+++ b/code/modules/admin/sql_message_system.dm
@@ -1,6 +1,6 @@
/proc/create_message(type, target_key, admin_ckey, text, timestamp, server, secret, logged = 1, browse, expiry, note_severity)
if(!SSdbcore.Connect())
- to_chat(usr, "Failed to establish database connection.")
+ to_chat(usr, "Failed to establish database connection.", confidential = TRUE)
return
if(!type)
return
@@ -9,8 +9,11 @@
var/new_key = input(usr,"Who would you like to create a [type] for?","Enter a key or ckey",null) as null|text
if(!new_key)
return
- var/new_ckey = sanitizeSQL(ckey(new_key))
- var/datum/DBQuery/query_find_ckey = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey = '[new_ckey]'")
+ var/new_ckey = ckey(new_key)
+ var/datum/db_query/query_find_ckey = SSdbcore.NewQuery(
+ "SELECT ckey FROM [format_table_name("player")] WHERE ckey = :ckey",
+ list("ckey" = new_ckey)
+ )
if(!query_find_ckey.warn_execute())
qdel(query_find_ckey)
return
@@ -23,29 +26,24 @@
target_key = new_key
if(QDELETED(usr))
return
- if(target_ckey)
- target_ckey = sanitizeSQL(target_ckey)
if(!target_key)
target_key = target_ckey
if(!admin_ckey)
admin_ckey = usr.ckey
if(!admin_ckey)
return
- admin_ckey = sanitizeSQL(admin_ckey)
if(!target_ckey)
target_ckey = admin_ckey
if(!text)
text = input(usr,"Write your [type]","Create [type]") as null|message
if(!text)
return
- text = sanitizeSQL(text)
if(!timestamp)
timestamp = SQLtime()
if(!server)
var/ssqlname = CONFIG_GET(string/serversqlname)
if (ssqlname)
server = ssqlname
- server = sanitizeSQL(server)
if(isnull(secret))
switch(alert("Hide note from being viewed by players?", "Secret note?","Yes","No","Cancel"))
if("Yes")
@@ -59,15 +57,17 @@
var/expire_time = input("Set expiry time for [type] as format YYYY-MM-DD HH:MM:SS. All times in server time. HH:MM:SS is optional and 24-hour. Must be later than current time for obvious reasons.", "Set expiry time", SQLtime()) as null|text
if(!expire_time)
return
- expire_time = sanitizeSQL(expire_time)
- var/datum/DBQuery/query_validate_expire_time = SSdbcore.NewQuery("SELECT IF(STR_TO_DATE('[expire_time]','%Y-%c-%d %T') > NOW(), STR_TO_DATE('[expire_time]','%Y-%c-%d %T'), 0)")
+ var/datum/db_query/query_validate_expire_time = SSdbcore.NewQuery(
+ "SELECT IF(STR_TO_DATE(:expire_time,'%Y-%c-%d %T') > NOW(), STR_TO_DATE(:expire_time,'%Y-%c-%d %T'), 0)",
+ list("expire_time" = expire_time)
+ )
if(!query_validate_expire_time.warn_execute())
qdel(query_validate_expire_time)
return
if(query_validate_expire_time.NextRow())
var/checktime = text2num(query_validate_expire_time.item[1])
if(!checktime)
- to_chat(usr, "Datetime entered is improperly formatted or not later than current server time.")
+ to_chat(usr, "Datetime entered is improperly formatted or not later than current server time.", confidential = TRUE)
qdel(query_validate_expire_time)
return
expiry = query_validate_expire_time.item[1]
@@ -76,8 +76,23 @@
note_severity = input("Set the severity of the note.", "Severity", null, null) as null|anything in list("High", "Medium", "Minor", "None")
if(!note_severity)
return
- note_severity = sanitizeSQL(note_severity)
- var/datum/DBQuery/query_create_message = SSdbcore.NewQuery("INSERT INTO [format_table_name("messages")] (type, targetckey, adminckey, text, timestamp, server, server_ip, server_port, round_id, secret, expire_timestamp, severity) VALUES ('[type]', '[target_ckey]', '[admin_ckey]', '[text]', '[timestamp]', '[server]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]','[secret]', [expiry ? "'[expiry]'" : "NULL"], [note_severity ? "'[note_severity]'" : "NULL"])")
+ var/datum/db_query/query_create_message = SSdbcore.NewQuery({"
+ INSERT INTO [format_table_name("messages")] (type, targetckey, adminckey, text, timestamp, server, server_ip, server_port, round_id, secret, expire_timestamp, severity)
+ VALUES (:type, :target_ckey, :admin_ckey, :text, :timestamp, :server, INET_ATON(:internet_address), :port, :round_id, :secret, :expiry, :note_severity)
+ "}, list(
+ "type" = type,
+ "target_ckey" = target_ckey,
+ "admin_ckey" = admin_ckey,
+ "text" = text,
+ "timestamp" = timestamp,
+ "server" = server,
+ "internet_address" = world.internet_address || "0",
+ "port" = "[world.port]",
+ "round_id" = GLOB.round_id,
+ "secret" = secret,
+ "expiry" = expiry || null,
+ "note_severity" = note_severity,
+ ))
var/pm = "[key_name(usr)] has created a [type][(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_key]" : ""]: [text]"
var/header = "[key_name_admin(usr)] has created a [type][(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_key]" : ""]"
if(!query_create_message.warn_execute())
@@ -96,7 +111,7 @@
/proc/delete_message(message_id, logged = 1, browse)
if(!SSdbcore.Connect())
- to_chat(usr, "Failed to establish database connection.")
+ to_chat(usr, "Failed to establish database connection.", confidential = TRUE)
return
message_id = text2num(message_id)
if(!message_id)
@@ -106,7 +121,11 @@
var/text
var/user_key_name = key_name(usr)
var/user_name_admin = key_name_admin(usr)
- var/datum/DBQuery/query_find_del_message = SSdbcore.NewQuery("SELECT type, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey), text FROM [format_table_name("messages")] WHERE id = [message_id] AND deleted = 0")
+ var/deleted_by_ckey = usr.ckey
+ var/datum/db_query/query_find_del_message = SSdbcore.NewQuery(
+ "SELECT type, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey), text FROM [format_table_name("messages")] WHERE id = :id AND deleted = 0",
+ list("id" = message_id)
+ )
if(!query_find_del_message.warn_execute())
qdel(query_find_del_message)
return
@@ -115,7 +134,10 @@
target_key = query_find_del_message.item[2]
text = query_find_del_message.item[3]
qdel(query_find_del_message)
- var/datum/DBQuery/query_del_message = SSdbcore.NewQuery("UPDATE [format_table_name("messages")] SET deleted = 1 WHERE id = [message_id]")
+ var/datum/db_query/query_del_message = SSdbcore.NewQuery(
+ "UPDATE [format_table_name("messages")] SET deleted = 1, deleted_ckey = :deleted_ckey WHERE id = :id",
+ list("deleted_ckey" = deleted_by_ckey, "id" = message_id)
+ )
if(!query_del_message.warn_execute())
qdel(query_del_message)
return
@@ -132,16 +154,24 @@
/proc/edit_message(message_id, browse)
if(!SSdbcore.Connect())
- to_chat(usr, "Failed to establish database connection.")
+ to_chat(usr, "Failed to establish database connection.", confidential = TRUE)
return
message_id = text2num(message_id)
if(!message_id)
return
- var/editor_ckey = sanitizeSQL(usr.ckey)
- var/editor_key = sanitizeSQL(usr.key)
+ var/editor_ckey = usr.ckey
+ var/editor_key = usr.key
var/kn = key_name(usr)
var/kna = key_name_admin(usr)
- var/datum/DBQuery/query_find_edit_message = SSdbcore.NewQuery("SELECT type, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), targetckey), text FROM [format_table_name("messages")] WHERE id = [message_id] AND deleted = 0")
+ var/datum/db_query/query_find_edit_message = SSdbcore.NewQuery({"
+ SELECT
+ type,
+ IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey),
+ IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), targetckey),
+ text
+ FROM [format_table_name("messages")]
+ WHERE id = :id AND deleted = 0
+ "}, list("id" = message_id))
if(!query_find_edit_message.warn_execute())
qdel(query_find_edit_message)
return
@@ -154,9 +184,12 @@
if(!new_text)
qdel(query_find_edit_message)
return
- new_text = sanitizeSQL(new_text)
- var/edit_text = sanitizeSQL("Edited by [editor_key] on [SQLtime()] from
[old_text]
to
[new_text]
")
- var/datum/DBQuery/query_edit_message = SSdbcore.NewQuery("UPDATE [format_table_name("messages")] SET text = '[new_text]', lasteditor = '[editor_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [message_id] AND deleted = 0")
+ var/edit_text = "Edited by [editor_key] on [SQLtime()] from
[old_text]
to
[new_text]
"
+ var/datum/db_query/query_edit_message = SSdbcore.NewQuery({"
+ UPDATE [format_table_name("messages")]
+ SET text = :text, lasteditor = :lasteditor, edits = CONCAT(IFNULL(edits,''),:edit_text)
+ WHERE id = :id AND deleted = 0
+ "}, list("text" = new_text, "lasteditor" = editor_ckey, "edit_text" = edit_text, "id" = message_id))
if(!query_edit_message.warn_execute())
qdel(query_edit_message)
return
@@ -171,16 +204,24 @@
/proc/edit_message_expiry(message_id, browse)
if(!SSdbcore.Connect())
- to_chat(usr, "Failed to establish database connection.")
+ to_chat(usr, "Failed to establish database connection.", confidential = TRUE)
return
message_id = text2num(message_id)
if(!message_id)
return
- var/editor_ckey = sanitizeSQL(usr.ckey)
- var/editor_key = sanitizeSQL(usr.key)
+ var/editor_ckey = usr.ckey
+ var/editor_key = usr.key
var/kn = key_name(usr)
var/kna = key_name_admin(usr)
- var/datum/DBQuery/query_find_edit_expiry_message = SSdbcore.NewQuery("SELECT type, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), adminckey), expire_timestamp FROM [format_table_name("messages")] WHERE id = [message_id] AND deleted = 0")
+ var/datum/db_query/query_find_edit_expiry_message = SSdbcore.NewQuery({"
+ SELECT
+ type,
+ IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey),
+ IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), adminckey),
+ expire_timestamp
+ FROM [format_table_name("messages")]
+ WHERE id = :id AND deleted = 0
+ "}, list("id" = message_id))
if(!query_find_edit_expiry_message.warn_execute())
qdel(query_find_edit_expiry_message)
return
@@ -197,8 +238,9 @@
if(expire_time == "-1")
new_expiry = "non-expiring"
else
- expire_time = sanitizeSQL(expire_time)
- var/datum/DBQuery/query_validate_expire_time_edit = SSdbcore.NewQuery("SELECT IF(STR_TO_DATE('[expire_time]','%Y-%c-%d %T') > NOW(), STR_TO_DATE('[expire_time]','%Y-%c-%d %T'), 0)")
+ var/datum/db_query/query_validate_expire_time_edit = SSdbcore.NewQuery({"
+ SELECT IF(STR_TO_DATE(:expire_time,'%Y-%c-%d %T') > NOW(), STR_TO_DATE(:expire_time,'%Y-%c-%d %T'), 0)
+ "}, list("expire_time" = expire_time))
if(!query_validate_expire_time_edit.warn_execute())
qdel(query_validate_expire_time_edit)
qdel(query_find_edit_expiry_message)
@@ -206,14 +248,18 @@
if(query_validate_expire_time_edit.NextRow())
var/checktime = text2num(query_validate_expire_time_edit.item[1])
if(!checktime)
- to_chat(usr, "Datetime entered is improperly formatted or not later than current server time.")
+ to_chat(usr, "Datetime entered is improperly formatted or not later than current server time.", confidential = TRUE)
qdel(query_validate_expire_time_edit)
qdel(query_find_edit_expiry_message)
return
new_expiry = query_validate_expire_time_edit.item[1]
qdel(query_validate_expire_time_edit)
- var/edit_text = sanitizeSQL("Expiration time edited by [editor_key] on [SQLtime()] from [old_expiry] to [new_expiry]
")
- var/datum/DBQuery/query_edit_message_expiry = SSdbcore.NewQuery("UPDATE [format_table_name("messages")] SET expire_timestamp = [expire_time == "-1" ? "NULL" : "'[new_expiry]'"], lasteditor = '[editor_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [message_id] AND deleted = 0")
+ var/edit_text = "Expiration time edited by [editor_key] on [SQLtime()] from [old_expiry] to [new_expiry]
"
+ var/datum/db_query/query_edit_message_expiry = SSdbcore.NewQuery({"
+ UPDATE [format_table_name("messages")]
+ SET expire_timestamp = :expire_time, lasteditor = :lasteditor, edits = CONCAT(IFNULL(edits,''),:edit_text)
+ WHERE id = :id AND deleted = 0
+ "}, list("expire_time" = (expire_time == "-1" ? null : new_expiry), "lasteditor" = editor_ckey, "edit_text" = edit_text, "id" = message_id))
if(!query_edit_message_expiry.warn_execute())
qdel(query_edit_message_expiry)
qdel(query_find_edit_expiry_message)
@@ -229,14 +275,22 @@
/proc/edit_message_severity(message_id)
if(!SSdbcore.Connect())
- to_chat(usr, "Failed to establish database connection.")
+ to_chat(usr, "Failed to establish database connection.", confidential = TRUE)
return
message_id = text2num(message_id)
if(!message_id)
return
var/kn = key_name(usr)
var/kna = key_name_admin(usr)
- var/datum/DBQuery/query_find_edit_note_severity = SSdbcore.NewQuery("SELECT type, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), adminckey), severity FROM [format_table_name("messages")] WHERE id = [message_id] AND deleted = 0")
+ var/datum/db_query/query_find_edit_note_severity = SSdbcore.NewQuery({"
+ SELECT
+ type,
+ IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey),
+ IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), adminckey),
+ severity
+ FROM [format_table_name("messages")]
+ WHERE id = :id AND deleted = 0
+ "}, list("id" = message_id))
if(!query_find_edit_note_severity.warn_execute())
qdel(query_find_edit_note_severity)
return
@@ -247,15 +301,19 @@
var/old_severity = query_find_edit_note_severity.item[4]
if(!old_severity)
old_severity = "NA"
- var/editor_key = sanitizeSQL(usr.key)
- var/editor_ckey = sanitizeSQL(usr.ckey)
+ var/editor_key = usr.key
+ var/editor_ckey = usr.ckey
var/new_severity = input("Set the severity of the note.", "Severity", null, null) as null|anything in list("high", "medium", "minor", "none") //lowercase for edit log consistency
if(!new_severity)
qdel(query_find_edit_note_severity)
return
- new_severity = sanitizeSQL(new_severity)
- var/edit_text = sanitizeSQL("Note severity edited by [editor_key] on [SQLtime()] from [old_severity] to [new_severity]
")
- var/datum/DBQuery/query_edit_note_severity = SSdbcore.NewQuery("UPDATE [format_table_name("messages")] SET severity = '[new_severity]', lasteditor = '[editor_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [message_id] AND deleted = 0")
+ new_severity = new_severity
+ var/edit_text = "Note severity edited by [editor_key] on [SQLtime()] from [old_severity] to [new_severity]
"
+ var/datum/db_query/query_edit_note_severity = SSdbcore.NewQuery({"
+ UPDATE [format_table_name("messages")]
+ SET severity = :severity, lasteditor = :lasteditor, edits = CONCAT(IFNULL(edits,''),:edit_text)
+ WHERE id = :id AND deleted = 0
+ "}, list("severity" = new_severity, "lasteditor" = editor_ckey, "edit_text" = edit_text, "id" = message_id))
if(!query_edit_note_severity.warn_execute(async = TRUE))
qdel(query_edit_note_severity)
qdel(qdel(query_find_edit_note_severity))
@@ -268,16 +326,24 @@
/proc/toggle_message_secrecy(message_id)
if(!SSdbcore.Connect())
- to_chat(usr, "Failed to establish database connection.")
+ to_chat(usr, "Failed to establish database connection.", confidential = TRUE)
return
message_id = text2num(message_id)
if(!message_id)
return
- var/editor_ckey = sanitizeSQL(usr.ckey)
- var/editor_key = sanitizeSQL(usr.key)
+ var/editor_ckey = usr.ckey
+ var/editor_key = usr.key
var/kn = key_name(usr)
var/kna = key_name_admin(usr)
- var/datum/DBQuery/query_find_message_secret = SSdbcore.NewQuery("SELECT type, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), targetckey), secret FROM [format_table_name("messages")] WHERE id = [message_id] AND deleted = 0")
+ var/datum/db_query/query_find_message_secret = SSdbcore.NewQuery({"
+ SELECT
+ type,
+ IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey),
+ IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), targetckey),
+ secret
+ FROM [format_table_name("messages")]
+ WHERE id = :id AND deleted = 0
+ "}, list("id" = message_id))
if(!query_find_message_secret.warn_execute())
qdel(query_find_message_secret)
return
@@ -287,7 +353,11 @@
var/admin_key = query_find_message_secret.item[3]
var/secret = text2num(query_find_message_secret.item[4])
var/edit_text = "Made [secret ? "not secret" : "secret"] by [editor_key] on [SQLtime()]
"
- var/datum/DBQuery/query_message_secret = SSdbcore.NewQuery("UPDATE [format_table_name("messages")] SET secret = NOT secret, lasteditor = '[editor_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [message_id]")
+ var/datum/db_query/query_message_secret = SSdbcore.NewQuery({"
+ UPDATE [format_table_name("messages")]
+ SET secret = NOT secret, lasteditor = :lasteditor, edits = CONCAT(IFNULL(edits,''),:edit_text)
+ WHERE id = :id
+ "}, list("lasteditor" = editor_ckey, "edit_text" = edit_text, "id" = message_id))
if(!query_message_secret.warn_execute())
qdel(query_find_message_secret)
qdel(query_message_secret)
@@ -298,11 +368,9 @@
browse_messages(target_ckey = ckey(target_key), agegate = TRUE)
qdel(query_find_message_secret)
-/proc/browse_messages(type, target_ckey, index, linkless = FALSE, filter, agegate = FALSE, override = FALSE)
- if((!override || IsAdminAdvancedProcCall()) && !check_rights(R_SENSITIVE))
- return
+/proc/browse_messages(type, target_ckey, index, linkless = FALSE, filter, agegate = FALSE)
if(!SSdbcore.Connect())
- to_chat(usr, "Failed to establish database connection.")
+ to_chat(usr, "Failed to establish database connection.", confidential = TRUE)
return
var/list/output = list()
var/ruler = "
"
@@ -329,7 +397,20 @@
else
output += "Filter offline clients"
output += ruler
- var/datum/DBQuery/query_get_type_messages = SSdbcore.NewQuery("SELECT id, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey), targetckey, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), adminckey), text, timestamp, server, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = lasteditor), lasteditor), expire_timestamp FROM [format_table_name("messages")] WHERE type = '[type]' AND deleted = 0 AND (expire_timestamp > NOW() OR expire_timestamp IS NULL)")
+ var/datum/db_query/query_get_type_messages = SSdbcore.NewQuery({"
+ SELECT
+ id,
+ IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey),
+ targetckey,
+ IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), adminckey),
+ text,
+ timestamp,
+ server,
+ IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = lasteditor), lasteditor),
+ expire_timestamp
+ FROM [format_table_name("messages")]
+ WHERE type = :type AND deleted = 0 AND (expire_timestamp > NOW() OR expire_timestamp IS NULL)
+ "}, list("type" = type))
if(!query_get_type_messages.warn_execute())
qdel(query_get_type_messages)
return
@@ -362,9 +443,24 @@
output += "
[text]
"
qdel(query_get_type_messages)
if(target_ckey)
- target_ckey = sanitizeSQL(target_ckey)
var/target_key
- var/datum/DBQuery/query_get_messages = SSdbcore.NewQuery("SELECT type, secret, id, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), adminckey), text, timestamp, server, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = lasteditor), lasteditor), DATEDIFF(NOW(), timestamp), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey), expire_timestamp, severity FROM [format_table_name("messages")] WHERE type <> 'memo' AND targetckey = '[target_ckey]' AND deleted = 0 AND (expire_timestamp > NOW() OR expire_timestamp IS NULL) ORDER BY timestamp DESC")
+ var/datum/db_query/query_get_messages = SSdbcore.NewQuery({"
+ SELECT
+ type,
+ secret,
+ id,
+ IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), adminckey),
+ text,
+ timestamp,
+ server,
+ IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = lasteditor), lasteditor),
+ DATEDIFF(NOW(), timestamp),
+ IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey),
+ expire_timestamp, severity
+ FROM [format_table_name("messages")]
+ WHERE type <> 'memo' AND targetckey = :targetckey AND deleted = 0 AND (expire_timestamp > NOW() OR expire_timestamp IS NULL)
+ ORDER BY timestamp DESC
+ "}, list("targetckey" = target_ckey))
if(!query_get_messages.warn_execute())
qdel(query_get_messages)
return
@@ -442,7 +538,9 @@
notedata += data
qdel(query_get_messages)
if(!target_key)
- var/datum/DBQuery/query_get_message_key = SSdbcore.NewQuery("SELECT byond_key FROM [format_table_name("player")] WHERE ckey = '[target_ckey]'")
+ var/datum/db_query/query_get_message_key = SSdbcore.NewQuery({"
+ SELECT byond_key FROM [format_table_name("player")] WHERE ckey = :ckey
+ "}, list("ckey" = target_ckey))
if(!query_get_message_key.warn_execute())
qdel(query_get_message_key)
return
@@ -479,8 +577,6 @@
var/search
output += "Add messageAdd watchlist entryAdd note"
output += ruler
- if(!isnum(index))
- index = sanitizeSQL(index)
switch(index)
if(1)
search = "^."
@@ -488,7 +584,17 @@
search = "^\[^\[:alpha:\]\]"
else
search = "^[index]"
- var/datum/DBQuery/query_list_messages = SSdbcore.NewQuery("SELECT DISTINCT targetckey, (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey) FROM [format_table_name("messages")] WHERE type <> 'memo' AND targetckey REGEXP '[search]' AND deleted = 0 AND (expire_timestamp > NOW() OR expire_timestamp IS NULL) ORDER BY targetckey")
+ var/datum/db_query/query_list_messages = SSdbcore.NewQuery({"
+ SELECT DISTINCT
+ targetckey,
+ (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey)
+ FROM [format_table_name("messages")]
+ WHERE type <> 'memo'
+ AND targetckey REGEXP :search
+ AND deleted = 0
+ AND (expire_timestamp > NOW() OR expire_timestamp IS NULL)
+ ORDER BY targetckey
+ "}, list("search" = search))
if(!query_list_messages.warn_execute())
qdel(query_list_messages)
return
@@ -512,17 +618,24 @@
/proc/get_message_output(type, target_ckey)
if(!SSdbcore.Connect())
- to_chat(usr, "Failed to establish database connection.")
+ to_chat(usr, "Failed to establish database connection.", confidential = TRUE)
return
if(!type)
return
var/output
- if(target_ckey)
- target_ckey = sanitizeSQL(target_ckey)
- var/query = "SELECT id, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), adminckey), text, timestamp, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = lasteditor), lasteditor) FROM [format_table_name("messages")] WHERE type = '[type]' AND deleted = 0 AND (expire_timestamp > NOW() OR expire_timestamp IS NULL)"
- if(type == "message" || type == "watchlist entry")
- query += " AND targetckey = '[target_ckey]'"
- var/datum/DBQuery/query_get_message_output = SSdbcore.NewQuery(query)
+ var/datum/db_query/query_get_message_output = SSdbcore.NewQuery({"
+ SELECT
+ id,
+ IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), adminckey),
+ text,
+ timestamp,
+ IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = lasteditor), lasteditor)
+ FROM [format_table_name("messages")]
+ WHERE type = :type
+ AND deleted = 0
+ AND (expire_timestamp > NOW() OR expire_timestamp IS NULL)
+ AND ((type != 'message' AND type != 'watchlist entry') OR targetckey = :targetckey)
+ "}, list("targetckey" = target_ckey, "type" = type))
if(!query_get_message_output.warn_execute())
qdel(query_get_message_output)
return
@@ -536,7 +649,10 @@
if("message")
output += "Admin message left by [admin_key] on [timestamp]"
output += "
[text]
"
- var/datum/DBQuery/query_message_read = SSdbcore.NewQuery("UPDATE [format_table_name("messages")] SET type = 'message sent' WHERE id = [message_id]")
+ var/datum/db_query/query_message_read = SSdbcore.NewQuery(
+ "UPDATE [format_table_name("messages")] SET type = 'message sent' WHERE id = :id",
+ list("id" = message_id)
+ )
if(!query_message_read.warn_execute())
qdel(query_get_message_output)
qdel(query_message_read)
@@ -544,7 +660,7 @@
qdel(query_message_read)
if("watchlist entry")
message_admins("Notice: [key_name_admin(target_ckey)] has been on the watchlist since [timestamp] and has just connected - Reason: [text]")
- send2irc_adminless_only("Watchlist", "[key_name(target_ckey)] is on the watchlist and has just connected - Reason: [text]")
+ send2tgs_adminless_only("Watchlist", "[key_name(target_ckey)] is on the watchlist and has just connected - Reason: [text]")
if("memo")
output += "Memo by [admin_key] on [timestamp]"
if(editor_key)
@@ -576,7 +692,7 @@
var/timestamp = note.group[1]
notetext = note.group[2]
var/admin_ckey = note.group[3]
- var/datum/DBQuery/query_convert_time = SSdbcore.NewQuery("SELECT ADDTIME(STR_TO_DATE('[timestamp]','%d-%b-%Y'), '0')")
+ var/datum/db_query/query_convert_time = SSdbcore.NewQuery("SELECT ADDTIME(STR_TO_DATE(:timestamp,'%d-%b-%Y'), '0')", list("timestamp" = timestamp))
if(!query_convert_time.Execute())
qdel(query_convert_time)
return
@@ -591,7 +707,7 @@
/*alternatively this proc can be run once to pass through every note and attempt to convert it before deleting the file, if done then AUTOCONVERT_NOTES should be turned off
this proc can take several minutes to execute fully if converting and cause DD to hang if converting a lot of notes; it's not advised to do so while a server is live
/proc/mass_convert_notes()
- to_chat(world, "Beginning mass note conversion")
+ to_chat(world, "Beginning mass note conversion", confidential = TRUE)
var/savefile/notesfile = new(NOTESFILE)
if(!notesfile)
log_game("Error: Cannot access [NOTESFILE]")
@@ -599,7 +715,7 @@ this proc can take several minutes to execute fully if converting and cause DD t
notesfile.cd = "/"
for(var/ckey in notesfile.dir)
convert_notes_sql(ckey)
- to_chat(world, "Deleting NOTESFILE")
+ to_chat(world, "Deleting NOTESFILE", confidential = TRUE)
fdel(NOTESFILE)
- to_chat(world, "Finished mass note conversion, remember to turn off AUTOCONVERT_NOTES")*/
+ to_chat(world, "Finished mass note conversion, remember to turn off AUTOCONVERT_NOTES", confidential = TRUE)*/
#undef NOTESFILE
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index e0434a6fea..b341f4bbfb 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -1270,8 +1270,10 @@
else if(href_list["messageedits"])
if(!check_rights(R_ADMIN))
return
- var/message_id = sanitizeSQL("[href_list["messageedits"]]")
- var/datum/DBQuery/query_get_message_edits = SSdbcore.NewQuery("SELECT edits FROM [format_table_name("messages")] WHERE id = '[message_id]'")
+ var/datum/db_query/query_get_message_edits = SSdbcore.NewQuery(
+ "SELECT edits FROM [format_table_name("messages")] WHERE id = :message_id",
+ list("message_id" = href_list["messageedits"])
+ )
if(!query_get_message_edits.warn_execute())
qdel(query_get_message_edits)
return
@@ -2971,16 +2973,19 @@
to_chat(usr, "The client chosen is an admin! Cannot mentorize.")
return
if(SSdbcore.Connect())
- var/datum/DBQuery/query_get_mentor = SSdbcore.NewQuery("SELECT id FROM [format_table_name("mentor")] WHERE ckey = '[ckey]'")
+ var/datum/db_query/query_get_mentor = SSdbcore.NewQuery(
+ "SELECT id FROM [format_table_name("mentor")] WHERE ckey = :ckey",
+ list("ckey" = ckey)
+ )
if(!query_get_mentor.warn_execute())
return
if(query_get_mentor.NextRow())
to_chat(usr, "[ckey] is already a mentor.")
return
- var/datum/DBQuery/query_add_mentor = SSdbcore.NewQuery("INSERT INTO `[format_table_name("mentor")]` (`id`, `ckey`) VALUES (null, '[ckey]')")
+ var/datum/db_query/query_add_mentor = SSdbcore.NewQuery("INSERT INTO `[format_table_name("mentor")]` (`id`, `ckey`) VALUES (null, '[ckey]')")
if(!query_add_mentor.warn_execute())
return
- var/datum/DBQuery/query_add_admin_log = SSdbcore.NewQuery("INSERT INTO `[format_table_name("admin_log")]` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added new mentor [ckey]');")
+ var/datum/db_query/query_add_admin_log = SSdbcore.NewQuery("INSERT INTO `[format_table_name("admin_log")]` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added new mentor [ckey]');")
if(!query_add_admin_log.warn_execute())
return
else
@@ -3004,10 +3009,10 @@
C.mentor_datum = null
GLOB.mentors -= C
if(SSdbcore.Connect())
- var/datum/DBQuery/query_remove_mentor = SSdbcore.NewQuery("DELETE FROM [format_table_name("mentor")] WHERE ckey = '[ckey]'")
+ var/datum/db_query/query_remove_mentor = SSdbcore.NewQuery("DELETE FROM [format_table_name("mentor")] WHERE ckey = '[ckey]'")
if(!query_remove_mentor.warn_execute())
return
- var/datum/DBQuery/query_add_admin_log = SSdbcore.NewQuery("INSERT INTO `[format_table_name("admin_log")]` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Removed mentor [ckey]');")
+ var/datum/db_query/query_add_admin_log = SSdbcore.NewQuery("INSERT INTO `[format_table_name("admin_log")]` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Removed mentor [ckey]');")
if(!query_add_admin_log.warn_execute())
return
else
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index 617d4a1d72..faa202ee53 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -534,14 +534,21 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
return
if(!SSdbcore.Connect())
return
- var/sql_ckey = sanitizeSQL(src.ckey)
- var/datum/DBQuery/query_get_related_ip = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ip = INET_ATON('[address]') AND ckey != '[sql_ckey]'")
- query_get_related_ip.Execute()
+ var/datum/db_query/query_get_related_ip = SSdbcore.NewQuery(
+ "SELECT ckey FROM [format_table_name("player")] WHERE ip = INET_ATON(:address) AND ckey != :ckey",
+ list("address" = address, "ckey" = ckey)
+ )
+ if(!query_get_related_ip.Execute())
+ qdel(query_get_related_ip)
+ return
related_accounts_ip = ""
while(query_get_related_ip.NextRow())
related_accounts_ip += "[query_get_related_ip.item[1]], "
qdel(query_get_related_ip)
- var/datum/DBQuery/query_get_related_cid = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE computerid = '[computer_id]' AND ckey != '[sql_ckey]'")
+ var/datum/db_query/query_get_related_cid = SSdbcore.NewQuery(
+ "SELECT ckey FROM [format_table_name("player")] WHERE computerid = :computerid AND ckey != :ckey",
+ list("computerid" = computer_id, "ckey" = ckey)
+ )
if(!query_get_related_cid.Execute())
qdel(query_get_related_cid)
return
@@ -555,45 +562,40 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
else
if (!GLOB.deadmins[ckey] && check_randomizer(connectiontopic))
return
- var/sql_ip = sanitizeSQL(address)
- var/sql_computerid = sanitizeSQL(computer_id)
- var/sql_admin_rank = sanitizeSQL(admin_rank)
var/new_player
- var/datum/DBQuery/query_client_in_db = SSdbcore.NewQuery("SELECT 1 FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'")
+ var/datum/db_query/query_client_in_db = SSdbcore.NewQuery(
+ "SELECT 1 FROM [format_table_name("player")] WHERE ckey = :ckey",
+ list("ckey" = ckey)
+ )
if(!query_client_in_db.Execute())
qdel(query_client_in_db)
return
- if(!query_client_in_db.NextRow()) //new user detected
- if(!holder && !GLOB.deadmins[ckey])
- if(CONFIG_GET(flag/panic_bunker) && !(ckey in GLOB.bunker_passthrough))
- log_access("Failed Login: [key] - New account attempting to connect during panic bunker")
- message_admins("Failed Login: [key] - New account attempting to connect during panic bunker")
- to_chat(src, "You must first join the Discord to verify your account before joining this server.
To do so, read the rules and post a request in the #station-access-requests channel under the \"Main server\" category in the Discord server linked here: https://discord.gg/E6SQuhz
If you have already done so, wait a few minutes then try again; sometimes the server needs to fully load before you can join.") //CIT CHANGE - makes the panic bunker disconnect message point to the discord
- var/list/connectiontopic_a = params2list(connectiontopic)
- var/list/panic_addr = CONFIG_GET(string/panic_server_address)
- if(panic_addr && !connectiontopic_a["redirect"])
- var/panic_name = CONFIG_GET(string/panic_server_name)
- to_chat(src, "Sending you to [panic_name ? panic_name : panic_addr].")
- winset(src, null, "command=.options")
- src << link("[panic_addr]?redirect=1")
- qdel(query_client_in_db)
- qdel(src)
- return
- new_player = 1
- account_join_date = sanitizeSQL(findJoinDate())
- var/sql_key = sanitizeSQL(key)
- var/datum/DBQuery/query_add_player = SSdbcore.NewQuery("INSERT INTO [format_table_name("player")] (`ckey`, `byond_key`, `firstseen`, `firstseen_round_id`, `lastseen`, `lastseen_round_id`, `ip`, `computerid`, `lastadminrank`, `accountjoindate`) VALUES ('[sql_ckey]', '[sql_key]', Now(), '[GLOB.round_id]', Now(), '[GLOB.round_id]', INET_ATON('[sql_ip]'), '[sql_computerid]', '[sql_admin_rank]', [account_join_date ? "'[account_join_date]'" : "NULL"])")
- if(!query_add_player.Execute())
- qdel(query_client_in_db)
- qdel(query_add_player)
- return
- qdel(query_add_player)
- if(!account_join_date)
- account_join_date = "Error"
- account_age = -1
- else if(ckey in GLOB.bunker_passthrough)
- GLOB.bunker_passthrough -= ckey
+ //If we aren't an admin, and the flag is set
+ if(CONFIG_GET(flag/panic_bunker) && !holder && !GLOB.deadmins[ckey] && !(ckey in GLOB.bunker_passthrough))
+ var/living_recs = CONFIG_GET(number/panic_bunker_living)
+ //Relies on pref existing, but this proc is only called after that occurs, so we're fine.
+ var/minutes = get_exp_living(pure_numeric = TRUE)
+ if(minutes <= living_recs && !CONFIG_GET(flag/panic_bunker_interview))
+ var/reject_message = "Failed Login: [key] - Account attempting to connect during panic bunker, but they do not have the required living time [minutes]/[living_recs]"
+ log_access(reject_message)
+ message_admins("[reject_message]")
+ var/message = CONFIG_GET(string/panic_bunker_message)
+ message = replacetext(message, "%minutes%", living_recs)
+ to_chat(src, message)
+ var/list/connectiontopic_a = params2list(connectiontopic)
+ var/list/panic_addr = CONFIG_GET(string/panic_server_address)
+ if(panic_addr && !connectiontopic_a["redirect"])
+ var/panic_name = CONFIG_GET(string/panic_server_name)
+ to_chat(src, "Sending you to [panic_name ? panic_name : panic_addr].")
+ winset(src, null, "command=.options")
+ src << link("[panic_addr]?redirect=1")
+ qdel(query_client_in_db)
+ qdel(src)
+ return
+
+ if(!query_client_in_db.NextRow())
+ new_player = 1
if(CONFIG_GET(flag/age_verification)) //setup age verification
if(!set_db_player_flags())
message_admins(usr, "ERROR: Unable to read player flags from database. Please check logs.")
@@ -605,9 +607,24 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
update_flag_db(DB_FLAG_AGE_CONFIRMATION_COMPLETE, TRUE)
else
update_flag_db(DB_FLAG_AGE_CONFIRMATION_INCOMPLETE, TRUE)
-
+ account_join_date = findJoinDate()
+ var/datum/db_query/query_add_player = SSdbcore.NewQuery({"
+ INSERT INTO [format_table_name("player")] (`ckey`, `byond_key`, `firstseen`, `firstseen_round_id`, `lastseen`, `lastseen_round_id`, `ip`, `computerid`, `lastadminrank`, `accountjoindate`)
+ VALUES (:ckey, :key, Now(), :round_id, Now(), :round_id, INET_ATON(:ip), :computerid, :adminrank, :account_join_date)
+ "}, list("ckey" = ckey, "key" = key, "round_id" = GLOB.round_id, "ip" = address, "computerid" = computer_id, "adminrank" = admin_rank, "account_join_date" = account_join_date || null))
+ if(!query_add_player.Execute())
+ qdel(query_client_in_db)
+ qdel(query_add_player)
+ return
+ qdel(query_add_player)
+ if(!account_join_date)
+ account_join_date = "Error"
+ account_age = -1
qdel(query_client_in_db)
- var/datum/DBQuery/query_get_client_age = SSdbcore.NewQuery("SELECT firstseen, DATEDIFF(Now(),firstseen), accountjoindate, DATEDIFF(Now(),accountjoindate) FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'")
+ var/datum/db_query/query_get_client_age = SSdbcore.NewQuery(
+ "SELECT firstseen, DATEDIFF(Now(),firstseen), accountjoindate, DATEDIFF(Now(),accountjoindate) FROM [format_table_name("player")] WHERE ckey = :ckey",
+ list("ckey" = ckey)
+ )
if(!query_get_client_age.Execute())
qdel(query_get_client_age)
return
@@ -618,11 +635,14 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
account_join_date = query_get_client_age.item[3]
account_age = text2num(query_get_client_age.item[4])
if(!account_age)
- account_join_date = sanitizeSQL(findJoinDate())
+ account_join_date = findJoinDate()
if(!account_join_date)
account_age = -1
else
- var/datum/DBQuery/query_datediff = SSdbcore.NewQuery("SELECT DATEDIFF(Now(),'[account_join_date]')")
+ var/datum/db_query/query_datediff = SSdbcore.NewQuery(
+ "SELECT DATEDIFF(Now(), :account_join_date)",
+ list("account_join_date" = account_join_date)
+ )
if(!query_datediff.Execute())
qdel(query_datediff)
return
@@ -631,14 +651,20 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
qdel(query_datediff)
qdel(query_get_client_age)
if(!new_player)
- var/datum/DBQuery/query_log_player = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET lastseen = Now(), lastseen_round_id = '[GLOB.round_id]', ip = INET_ATON('[sql_ip]'), computerid = '[sql_computerid]', lastadminrank = '[sql_admin_rank]', accountjoindate = [account_join_date ? "'[account_join_date]'" : "NULL"] WHERE ckey = '[sql_ckey]'")
+ var/datum/db_query/query_log_player = SSdbcore.NewQuery(
+ "UPDATE [format_table_name("player")] SET lastseen = Now(), lastseen_round_id = :round_id, ip = INET_ATON(:ip), computerid = :computerid, lastadminrank = :admin_rank, accountjoindate = :account_join_date WHERE ckey = :ckey",
+ list("round_id" = GLOB.round_id, "ip" = address, "computerid" = computer_id, "admin_rank" = admin_rank, "account_join_date" = account_join_date || null, "ckey" = ckey)
+ )
if(!query_log_player.Execute())
qdel(query_log_player)
return
qdel(query_log_player)
if(!account_join_date)
account_join_date = "Error"
- var/datum/DBQuery/query_log_connection = SSdbcore.NewQuery("INSERT INTO `[format_table_name("connection_log")]` (`id`,`datetime`,`server_ip`,`server_port`,`round_id`,`ckey`,`ip`,`computerid`) VALUES(null,Now(),INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')),'[world.port]','[GLOB.round_id]','[sql_ckey]',INET_ATON('[sql_ip]'),'[sql_computerid]')")
+ var/datum/db_query/query_log_connection = SSdbcore.NewQuery({"
+ INSERT INTO `[format_table_name("connection_log")]` (`id`,`datetime`,`server_ip`,`server_port`,`round_id`,`ckey`,`ip`,`computerid`)
+ VALUES(null,Now(),INET_ATON(:internet_address),:port,:round_id,:ckey,INET_ATON(:ip),:computerid)
+ "}, list("internet_address" = world.internet_address || "0", "port" = world.port, "round_id" = GLOB.round_id, "ckey" = ckey, "ip" = address, "computerid" = computer_id))
query_log_connection.Execute()
qdel(query_log_connection)
@@ -662,9 +688,11 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
CRASH("Age check regex failed for [src.ckey]")
/client/proc/validate_key_in_db()
- var/sql_ckey = sanitizeSQL(ckey)
var/sql_key
- var/datum/DBQuery/query_check_byond_key = SSdbcore.NewQuery("SELECT byond_key FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'")
+ var/datum/db_query/query_check_byond_key = SSdbcore.NewQuery(
+ "SELECT byond_key FROM [format_table_name("player")] WHERE ckey = :ckey",
+ list("ckey" = ckey)
+ )
if(!query_check_byond_key.Execute())
qdel(query_check_byond_key)
return
@@ -680,8 +708,11 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
if(F)
var/regex/R = regex("\\tkey = \"(.+)\"")
if(R.Find(F))
- var/web_key = sanitizeSQL(R.group[1])
- var/datum/DBQuery/query_update_byond_key = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET byond_key = '[web_key]' WHERE ckey = '[sql_ckey]'")
+ var/web_key = R.group[1]
+ var/datum/db_query/query_update_byond_key = SSdbcore.NewQuery(
+ "UPDATE [format_table_name("player")] SET byond_key = :byond_key WHERE ckey = :ckey",
+ list("byond_key" = web_key, "ckey" = ckey)
+ )
query_update_byond_key.Execute()
qdel(query_update_byond_key)
else
@@ -698,8 +729,10 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
var/static/tokens = list()
var/static/cidcheck_failedckeys = list() //to avoid spamming the admins if the same guy keeps trying.
var/static/cidcheck_spoofckeys = list()
- var/sql_ckey = sanitizeSQL(ckey)
- var/datum/DBQuery/query_cidcheck = SSdbcore.NewQuery("SELECT computerid FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'")
+ var/datum/db_query/query_cidcheck = SSdbcore.NewQuery(
+ "SELECT computerid FROM [format_table_name("player")] WHERE ckey = :ckey",
+ list("ckey" = ckey)
+ )
query_cidcheck.Execute()
var/lastcid
@@ -718,7 +751,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
sleep(15 SECONDS) //Longer sleep here since this would trigger if a client tries to reconnect manually because the inital reconnect failed
- //we sleep after telling the client to reconnect, so if we still exist something is up
+ //we sleep after telling the client to reconnect, so if we still exist something is up
log_access("Forced disconnect: [key] [computer_id] [address] - CID randomizer check")
qdel(src)
@@ -732,7 +765,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
if (!cidcheck_failedckeys[ckey])
message_admins("[key_name(src)] has been detected as using a cid randomizer. Connection rejected.")
- send2irc_adminless_only("CidRandomizer", "[key_name(src)] has been detected as using a cid randomizer. Connection rejected.")
+ send2tgs_adminless_only("CidRandomizer", "[key_name(src)] has been detected as using a cid randomizer. Connection rejected.")
cidcheck_failedckeys[ckey] = TRUE
note_randomizer_user()
@@ -743,7 +776,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
else
if (cidcheck_failedckeys[ckey])
message_admins("[key_name_admin(src)] has been allowed to connect after showing they removed their cid randomizer")
- send2irc_adminless_only("CidRandomizer", "[key_name(src)] has been allowed to connect after showing they removed their cid randomizer.")
+ send2tgs_adminless_only("CidRandomizer", "[key_name(src)] has been allowed to connect after showing they removed their cid randomizer.")
cidcheck_failedckeys -= ckey
if (cidcheck_spoofckeys[ckey])
message_admins("[key_name_admin(src)] has been allowed to connect after appearing to have attempted to spoof a cid randomizer check because it appears they aren't spoofing one this time")
@@ -774,10 +807,11 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
add_system_note("CID-Error", "Detected as using a cid randomizer.")
/client/proc/add_system_note(system_ckey, message)
- var/sql_system_ckey = sanitizeSQL(system_ckey)
- var/sql_ckey = sanitizeSQL(ckey)
//check to see if we noted them in the last day.
- var/datum/DBQuery/query_get_notes = SSdbcore.NewQuery("SELECT id FROM [format_table_name("messages")] WHERE type = 'note' AND targetckey = '[sql_ckey]' AND adminckey = '[sql_system_ckey]' AND timestamp + INTERVAL 1 DAY < NOW() AND deleted = 0 AND expire_timestamp > NOW()")
+ var/datum/db_query/query_get_notes = SSdbcore.NewQuery(
+ "SELECT id FROM [format_table_name("messages")] WHERE type = 'note' AND targetckey = :targetckey AND adminckey = :adminckey AND timestamp + INTERVAL 1 DAY < NOW() AND deleted = 0 AND (expire_timestamp > NOW() OR expire_timestamp IS NULL)",
+ list("targetckey" = ckey, "adminckey" = system_ckey)
+ )
if(!query_get_notes.Execute())
qdel(query_get_notes)
return
@@ -786,7 +820,10 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
return
qdel(query_get_notes)
//regardless of above, make sure their last note is not from us, as no point in repeating the same note over and over.
- query_get_notes = SSdbcore.NewQuery("SELECT adminckey FROM [format_table_name("messages")] WHERE targetckey = '[sql_ckey]' AND deleted = 0 AND expire_timestamp > NOW() ORDER BY timestamp DESC LIMIT 1")
+ query_get_notes = SSdbcore.NewQuery(
+ "SELECT adminckey FROM [format_table_name("messages")] WHERE targetckey = :targetckey AND deleted = 0 AND (expire_timestamp > NOW() OR expire_timestamp IS NULL) ORDER BY timestamp DESC LIMIT 1",
+ list("targetckey" = ckey)
+ )
if(!query_get_notes.Execute())
qdel(query_get_notes)
return
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index e97f6dc3f4..0e7fda80b1 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -1333,7 +1333,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(href_list["jobbancheck"])
var/job = sanitizeSQL(href_list["jobbancheck"])
var/sql_ckey = sanitizeSQL(user.ckey)
- var/datum/DBQuery/query_get_jobban = SSdbcore.NewQuery("SELECT reason, bantime, duration, expiration_time, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].a_ckey), a_ckey) FROM [format_table_name("ban")] WHERE ckey = '[sql_ckey]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned) AND job = '[job]'")
+ var/datum/db_query/query_get_jobban = SSdbcore.NewQuery("SELECT reason, bantime, duration, expiration_time, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].a_ckey), a_ckey) FROM [format_table_name("ban")] WHERE ckey = '[sql_ckey]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned) AND job = '[job]'")
if(!query_get_jobban.warn_execute())
qdel(query_get_jobban)
return
diff --git a/code/modules/jobs/job_exp.dm b/code/modules/jobs/job_exp.dm
index 5ff791c5f3..f982d7e96e 100644
--- a/code/modules/jobs/job_exp.dm
+++ b/code/modules/jobs/job_exp.dm
@@ -156,7 +156,10 @@ GLOBAL_PROTECT(exp_to_update)
return -1
if(!SSdbcore.Connect())
return -1
- var/datum/DBQuery/exp_read = SSdbcore.NewQuery("SELECT job, minutes FROM [format_table_name("role_time")] WHERE ckey = '[sanitizeSQL(ckey)]'")
+ var/datum/db_query/exp_read = SSdbcore.NewQuery(
+ "SELECT job, minutes FROM [format_table_name("role_time")] WHERE ckey = :ckey",
+ list("ckey" = ckey)
+ )
if(!exp_read.Execute(async = TRUE))
qdel(exp_read)
return -1
@@ -188,7 +191,10 @@ GLOBAL_PROTECT(exp_to_update)
else
prefs.db_flags |= newflag
- var/datum/DBQuery/flag_update = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET flags = '[prefs.db_flags]' WHERE ckey='[sanitizeSQL(ckey)]'")
+ var/datum/db_query/flag_update = SSdbcore.NewQuery(
+ "UPDATE [format_table_name("player")] SET flags=:flags WHERE ckey=:ckey",
+ list("flags" = "[prefs.db_flags]", "ckey" = ckey)
+ )
if(!flag_update.Execute())
qdel(flag_update)
@@ -268,7 +274,10 @@ GLOBAL_PROTECT(exp_to_update)
if(!SSdbcore.Connect())
return FALSE
- var/datum/DBQuery/flags_read = SSdbcore.NewQuery("SELECT flags FROM [format_table_name("player")] WHERE ckey='[ckey]'")
+ var/datum/db_query/flags_read = SSdbcore.NewQuery(
+ "SELECT flags FROM [format_table_name("player")] WHERE ckey=:ckey",
+ list("ckey" = ckey)
+ )
if(!flags_read.Execute(async = TRUE))
qdel(flags_read)
@@ -280,3 +289,4 @@ GLOBAL_PROTECT(exp_to_update)
prefs.db_flags = 0 //This PROBABLY won't happen, but better safe than sorry.
qdel(flags_read)
return TRUE
+
diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm
index 3953f5e28c..e751861d6b 100644
--- a/code/modules/library/lib_machines.dm
+++ b/code/modules/library/lib_machines.dm
@@ -25,12 +25,13 @@
var/title
var/category = "Any"
var/author
- var/SQLquery
- clockwork = TRUE //it'd look weird
-
+ var/search_page = 0
+ COOLDOWN_DECLARE(library_visitor_topic_cooldown)
+ clockwork = TRUE
+
/obj/machinery/computer/libraryconsole/ui_interact(mob/user)
. = ..()
- var/dat = "" //
+ var/list/dat = list() //
switch(screenstate)
if(0)
dat += "Search Settings
"
@@ -43,13 +44,48 @@
dat += "ERROR: Unable to contact External Archive. Please contact your system administrator for assistance.
"
else if(QDELETED(user))
return
- else if(!SQLquery)
- dat += "ERROR: Malformed search request. Please contact your system administrator for assistance.
"
else
dat += ""
dat += "| AUTHOR | TITLE | CATEGORY | SS13BN |
"
-
- var/datum/DBQuery/query_library_list_books = SSdbcore.NewQuery(SQLquery)
+ var/SQLsearch = "isnull(deleted) AND "
+ if(category == "Any")
+ SQLsearch += "author LIKE '%[author]%' AND title LIKE '%[title]%'"
+ else
+ SQLsearch += "author LIKE '%[author]%' AND title LIKE '%[title]%' AND category='[category]'"
+ var/bookcount = 0
+ var/booksperpage = 20
+ var/datum/db_query/query_library_count_books = SSdbcore.NewQuery({"
+ SELECT COUNT(id) FROM [format_table_name("library")]
+ WHERE isnull(deleted)
+ AND author LIKE CONCAT('%',:author,'%')
+ AND title LIKE CONCAT('%',:title,'%')
+ AND (:category = 'Any' OR category = :category)
+ "}, list("author" = author, "title" = title, "category" = category))
+ if(!query_library_count_books.warn_execute())
+ qdel(query_library_count_books)
+ return
+ if(query_library_count_books.NextRow())
+ bookcount = text2num(query_library_count_books.item[1])
+ qdel(query_library_count_books)
+ if(bookcount > booksperpage)
+ dat += "Page: "
+ var/pagecount = 1
+ var/list/pagelist = list()
+ while(bookcount > 0)
+ pagelist += "[pagecount == search_page + 1 ? "\[[pagecount]\]" : "\[[pagecount]\]"]"
+ bookcount -= booksperpage
+ pagecount++
+ dat += pagelist.Join(" | ")
+ search_page = text2num(search_page)
+ var/datum/db_query/query_library_list_books = SSdbcore.NewQuery({"
+ SELECT author, title, category, id
+ FROM [format_table_name("library")]
+ WHERE isnull(deleted)
+ AND author LIKE CONCAT('%',:author,'%')
+ AND title LIKE CONCAT('%',:title,'%')
+ AND (:category = 'Any' OR category = :category)
+ LIMIT :skip, :take
+ "}, list("author" = author, "title" = title, "category" = category, "skip" = booksperpage * search_page, "take" = booksperpage))
if(!query_library_list_books.Execute())
dat += "ERROR: Unable to retrieve book listings. Please contact your system administrator for assistance.
"
else
@@ -65,12 +101,15 @@
dat += "
"
dat += "\[Go Back\]
"
var/datum/browser/popup = new(user, "publiclibrary", name, 600, 400)
- popup.set_content(dat)
+ popup.set_content(jointext(dat, ""))
popup.open()
/obj/machinery/computer/libraryconsole/Topic(href, href_list)
+ if(!COOLDOWN_FINISHED(src, library_visitor_topic_cooldown))
+ return
+ COOLDOWN_START(src, library_visitor_topic_cooldown, 1 SECONDS)
. = ..()
- if(..())
+ if(.)
usr << browse(null, "window=publiclibrary")
onclose(usr, "publiclibrary")
return
@@ -81,29 +120,24 @@
title = sanitize(newtitle)
else
title = null
- title = sanitizeSQL(title)
if(href_list["setcategory"])
var/newcategory = input("Choose a category to search for:") in list("Any", "Fiction", "Non-Fiction", "Adult", "Reference", "Religion")
if(newcategory)
category = sanitize(newcategory)
else
category = "Any"
- category = sanitizeSQL(category)
if(href_list["setauthor"])
var/newauthor = input("Enter an author to search for:") as text|null
if(newauthor)
author = sanitize(newauthor)
else
author = null
- author = sanitizeSQL(author)
if(href_list["search"])
- SQLquery = "SELECT author, title, category, id FROM [format_table_name("library")] WHERE isnull(deleted) AND "
- if(category == "Any")
- SQLquery += "author LIKE '%[author]%' AND title LIKE '%[title]%'"
- else
- SQLquery += "author LIKE '%[author]%' AND title LIKE '%[title]%' AND category='[category]'"
screenstate = 1
+ if(href_list["bookpagecount"])
+ search_page = text2num(href_list["bookpagecount"])
+
if(href_list["back"])
screenstate = 0
@@ -120,39 +154,6 @@
var/getdate
var/duedate
-/*
- * Cachedbook datum
- */
-/datum/cachedbook // Datum used to cache the SQL DB books locally in order to achieve a performance gain.
- var/id
- var/title
- var/author
- var/category
-
-GLOBAL_LIST(cachedbooks) // List of our cached book datums
-
-
-/proc/load_library_db_to_cache()
- if(GLOB.cachedbooks)
- return
- if(!SSdbcore.Connect())
- return
- GLOB.cachedbooks = list()
- var/datum/DBQuery/query_library_cache = SSdbcore.NewQuery("SELECT id, author, title, category FROM [format_table_name("library")] WHERE isnull(deleted)")
- if(!query_library_cache.Execute())
- qdel(query_library_cache)
- return
- while(query_library_cache.NextRow())
- var/datum/cachedbook/newbook = new()
- newbook.id = query_library_cache.item[1]
- newbook.author = query_library_cache.item[2]
- newbook.title = query_library_cache.item[3]
- newbook.category = query_library_cache.item[4]
- GLOB.cachedbooks += newbook
- qdel(query_library_cache)
-
-
-
#define PRINTER_COOLDOWN 60
/*
@@ -165,11 +166,15 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
/obj/machinery/computer/libraryconsole/bookmanagement
name = "book inventory management console"
desc = "Librarian's command station."
- screenstate = 0 // 0 - Main Menu, 1 - Inventory, 2 - Checked Out, 3 - Check Out a Book
verb_say = "beeps"
verb_ask = "beeps"
verb_exclaim = "beeps"
pass_flags = PASSTABLE
+
+ circuit = /obj/item/circuitboard/computer/libraryconsole
+
+ var/screenstate = 0 // 0 - Main Menu, 1 - Inventory, 2 - Checked Out, 3 - Check Out a Book
+
var/arcanecheckout = 0
var/buffer_book
var/buffer_mob
@@ -178,33 +183,17 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
var/list/inventory = list()
var/checkoutperiod = 5 // In minutes
var/obj/machinery/libraryscanner/scanner // Book scanner that will be used when uploading books to the Archive
- var/list/libcomp_menu
var/page = 1 //current page of the external archives
- var/cooldown = 0
+ var/printer_cooldown = 0
+ COOLDOWN_DECLARE(library_console_topic_cooldown)
-/obj/machinery/computer/libraryconsole/bookmanagement/proc/build_library_menu()
- if(libcomp_menu)
- return
- load_library_db_to_cache()
- if(!GLOB.cachedbooks)
- return
- libcomp_menu = list("")
-
- for(var/i in 1 to GLOB.cachedbooks.len)
- var/datum/cachedbook/C = GLOB.cachedbooks[i]
- var/page = round(i/250)+1
- if (libcomp_menu.len < page)
- libcomp_menu.len = page
- libcomp_menu[page] = ""
- libcomp_menu[page] += "| [C.author] | [C.title] | [C.category] | \[Order\] |
\n"
-
-/obj/machinery/computer/libraryconsole/bookmanagement/Initialize()
+/obj/machinery/computer/bookmanagement/Initialize()
. = ..()
if(circuit)
circuit.name = "Book Inventory Management Console (Machine Board)"
- circuit.build_path = /obj/machinery/computer/libraryconsole/bookmanagement
+ circuit.build_path = /obj/machinery/computer/bookmanagement
-/obj/machinery/computer/libraryconsole/bookmanagement/ui_interact(mob/user)
+/obj/machinery/computer/bookmanagement/ui_interact(mob/user)
. = ..()
var/dat = "" //
switch(screenstate)
@@ -258,17 +247,37 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
dat += "(Return to main menu)
"
if(4)
dat += "External Archive
"
- build_library_menu()
-
- if(!GLOB.cachedbooks)
+ if(!SSdbcore.Connect())
dat += "ERROR: Unable to contact External Archive. Please contact your system administrator for assistance."
else
+ var/booksperpage = 50
+ var/pagecount
+ var/datum/db_query/query_library_count_books = SSdbcore.NewQuery("SELECT COUNT(id) FROM [format_table_name("library")] WHERE isnull(deleted)")
+ if(!query_library_count_books.Execute())
+ qdel(query_library_count_books)
+ return
+ if(query_library_count_books.NextRow())
+ pagecount = CEILING(text2num(query_library_count_books.item[1]) / booksperpage, 1)
+ qdel(query_library_count_books)
+ var/list/booklist = list()
+ var/datum/db_query/query_library_get_books = SSdbcore.NewQuery({"
+ SELECT id, author, title, category
+ FROM [format_table_name("library")]
+ WHERE isnull(deleted)
+ LIMIT :skip, :take
+ "}, list("skip" = booksperpage * (page - 1), "take" = booksperpage))
+ if(!query_library_get_books.Execute())
+ qdel(query_library_get_books)
+ return
+ while(query_library_get_books.NextRow())
+ booklist += "| [query_library_get_books.item[2]] | [query_library_get_books.item[3]] | [query_library_get_books.item[4]] | \[Order\] |
\n"
dat += "(Order book by SS13BN)
"
dat += ""
dat += "| AUTHOR | TITLE | CATEGORY | |
"
- dat += libcomp_menu[clamp(page,1,libcomp_menu.len)]
- dat += "| <<<< | | | >>>> |
"
+ dat += jointext(booklist, "")
+ dat += "| <<<< | | | >>>> |
"
dat += "
"
+ qdel(query_library_get_books)
dat += "
(Return to main menu)
"
if(5)
dat += "Upload a New Title
"
@@ -315,39 +324,33 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
popup.set_content(dat)
popup.open()
-/obj/machinery/computer/libraryconsole/bookmanagement/proc/findscanner(viewrange)
+/obj/machinery/computer/bookmanagement/proc/findscanner(viewrange)
for(var/obj/machinery/libraryscanner/S in range(viewrange, get_turf(src)))
return S
return null
-/obj/machinery/computer/libraryconsole/bookmanagement/proc/print_forbidden_lore(mob/user)
- var/spook = pick("blood", "brass")
- var/turf/T = get_turf(src)
- if(spook == "blood")
- new /obj/item/melee/cultblade/dagger(T)
- else
- new /obj/item/clockwork/slab(T)
+/obj/machinery/computer/bookmanagement/proc/print_forbidden_lore(mob/user)
+ new /obj/item/melee/cultblade/dagger(get_turf(src))
+ to_chat(user, "Your sanity barely endures the seconds spent in the vault's browsing window. The only thing to remind you of this when you stop browsing is a sinister dagger sitting on the desk. You don't even remember where it came from...")
+ user.visible_message("[user] stares at the blank screen for a few moments, [user.p_their()] expression frozen in fear. When [user.p_they()] finally awaken[user.p_s()] from it, [user.p_they()] look[user.p_s()] a lot older.", 2)
- to_chat(user, "Your sanity barely endures the seconds spent in the vault's browsing window. The only thing to remind you of this when you stop browsing is a [spook == "blood" ? "sinister dagger" : "strange metal tablet"] sitting on the desk. You don't even remember where it came from...")
- user.visible_message("[user] stares at the blank screen for a few moments, [user.p_their()] expression frozen in fear. When [user.p_they()] finally awaken[user.p_s()] from it, [user.p_they()] look[user.p_s()] a lot older.", 2)
-
-/obj/machinery/computer/libraryconsole/bookmanagement/attackby(obj/item/W, mob/user, params)
+/obj/machinery/computer/bookmanagement/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/barcodescanner))
var/obj/item/barcodescanner/scanner = W
scanner.computer = src
- to_chat(user, "[scanner]'s associated machine has been set to [src].")
- audible_message("[src] lets out a low, short blip.")
+ to_chat(user, "[scanner]'s associated machine has been set to [src].")
+ audible_message("[src] lets out a low, short blip.")
else
return ..()
-/obj/machinery/computer/libraryconsole/bookmanagement/emag_act(mob/user)
- . = ..()
- if(!density || obj_flags & EMAGGED)
- return
- obj_flags |= EMAGGED
- return TRUE
+/obj/machinery/computer/bookmanagement/emag_act(mob/user)
+ if(density && !(obj_flags & EMAGGED))
+ obj_flags |= EMAGGED
-/obj/machinery/computer/libraryconsole/bookmanagement/Topic(href, href_list)
+/obj/machinery/computer/bookmanagement/Topic(href, href_list)
+ if(!COOLDOWN_FINISHED(src, library_console_topic_cooldown))
+ return
+ COOLDOWN_START(src, library_console_topic_cooldown, 1 SECONDS)
if(..())
usr << browse(null, "window=library")
onclose(usr, "library")
@@ -385,7 +388,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
if(checkoutperiod < 1)
checkoutperiod = 1
if(href_list["editbook"])
- buffer_book = stripped_input(usr, "Enter the book's title:")
+ buffer_book = stripped_input(usr, "Enter the book's title:", max_length = 45)
if(href_list["editmob"])
buffer_mob = stripped_input(usr, "Enter the recipient's name:", max_length = MAX_NAME_LEN)
if(href_list["checkout"])
@@ -404,7 +407,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
if(b && istype(b))
inventory.Remove(b)
if(href_list["setauthor"])
- var/newauthor = stripped_input(usr, "Enter the author's name: ")
+ var/newauthor = stripped_input(usr, "Enter the author's name: ", max_length = 45)
if(newauthor)
scanner.cache.author = newauthor
if(href_list["setcategory"])
@@ -419,14 +422,11 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
if (!SSdbcore.Connect())
alert("Connection to Archive has been severed. Aborting.")
else
-
- var/sqltitle = sanitizeSQL(scanner.cache.name)
- var/sqlauthor = sanitizeSQL(scanner.cache.author)
- var/sqlcontent = sanitizeSQL(scanner.cache.dat)
- var/sqlcategory = sanitizeSQL(upload_category)
- var/sqlckey = sanitizeSQL(usr.ckey)
var/msg = "[key_name(usr)] has uploaded the book titled [scanner.cache.name], [length(scanner.cache.dat)] signs"
- var/datum/DBQuery/query_library_upload = SSdbcore.NewQuery("INSERT INTO [format_table_name("library")] (author, title, content, category, ckey, datetime, round_id_created) VALUES ('[sqlauthor]', '[sqltitle]', '[sqlcontent]', '[sqlcategory]', '[sqlckey]', Now(), '[GLOB.round_id]')")
+ var/datum/db_query/query_library_upload = SSdbcore.NewQuery({"
+ INSERT INTO [format_table_name("library")] (author, title, content, category, ckey, datetime, round_id_created)
+ VALUES (:author, :title, :content, :category, :ckey, Now(), :round_id)
+ "}, list("title" = scanner.cache.name, "author" = scanner.cache.author, "content" = scanner.cache.dat, "category" = upload_category, "ckey" = usr.ckey, "round_id" = GLOB.round_id))
if(!query_library_upload.Execute())
qdel(query_library_upload)
alert("Database error encountered uploading to Archive")
@@ -439,7 +439,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
if(!GLOB.news_network)
alert("No news network found on station. Aborting.")
var/channelexists = 0
- for(var/datum/news/feed_channel/FC in GLOB.news_network.network_channels)
+ for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels)
if(FC.channel_name == "Nanotrasen Book Club")
channelexists = 1
break
@@ -448,7 +448,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
GLOB.news_network.SubmitArticle(scanner.cache.dat, "[scanner.cache.name]", "Nanotrasen Book Club", null)
alert("Upload complete. Your uploaded title is now available on station newscasters.")
if(href_list["orderbyid"])
- if(cooldown > world.time)
+ if(printer_cooldown > world.time)
say("Printer unavailable. Please allow a short time before attempting to print.")
else
var/orderid = input("Enter your order:") as num|null
@@ -457,14 +457,17 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
href_list["targetid"] = num2text(orderid)
if(href_list["targetid"])
- var/sqlid = sanitizeSQL(href_list["targetid"])
+ var/id = href_list["targetid"]
if (!SSdbcore.Connect())
alert("Connection to Archive has been severed. Aborting.")
- if(cooldown > world.time)
+ if(printer_cooldown > world.time)
say("Printer unavailable. Please allow a short time before attempting to print.")
else
- cooldown = world.time + PRINTER_COOLDOWN
- var/datum/DBQuery/query_library_print = SSdbcore.NewQuery("SELECT * FROM [format_table_name("library")] WHERE id=[sqlid] AND isnull(deleted)")
+ printer_cooldown = world.time + PRINTER_COOLDOWN
+ var/datum/db_query/query_library_print = SSdbcore.NewQuery(
+ "SELECT * FROM [format_table_name("library")] WHERE id=:id AND isnull(deleted)",
+ list("id" = id)
+ )
if(!query_library_print.Execute())
qdel(query_library_print)
say("PRINTER ERROR! Failed to print document (0x0000000F)")
@@ -480,24 +483,24 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
B.author = author
B.dat = content
B.icon_state = "book[rand(1,8)]"
- visible_message("[src]'s printer hums as it produces a completely bound book. How did it do that?")
+ visible_message("[src]'s printer hums as it produces a completely bound book. How did it do that?")
break
qdel(query_library_print)
if(href_list["printbible"])
- if(cooldown < world.time)
+ if(printer_cooldown < world.time)
var/obj/item/storage/book/bible/B = new /obj/item/storage/book/bible(src.loc)
- if(GLOB.bible_icon_state && GLOB.bible_item_state)
+ if(GLOB.bible_icon_state && GLOB.bible_inhand_icon_state)
B.icon_state = GLOB.bible_icon_state
- B.item_state = GLOB.bible_item_state
+ B.inhand_icon_state = GLOB.bible_inhand_icon_state
B.name = GLOB.bible_name
B.deity_name = GLOB.deity
- cooldown = world.time + PRINTER_COOLDOWN
+ printer_cooldown = world.time + PRINTER_COOLDOWN
else
say("Printer currently unavailable, please wait a moment.")
if(href_list["printposter"])
- if(cooldown < world.time)
+ if(printer_cooldown < world.time)
new /obj/item/poster/random_official(src.loc)
- cooldown = world.time + PRINTER_COOLDOWN
+ printer_cooldown = world.time + PRINTER_COOLDOWN
else
say("Printer currently unavailable, please wait a moment.")
add_fingerprint(usr)
@@ -521,7 +524,10 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
else
return ..()
-/obj/machinery/libraryscanner/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
+/obj/machinery/libraryscanner/attack_hand(mob/user)
+ . = ..()
+ if(.)
+ return
usr.set_machine(src)
var/dat = "" //
if(cache)
@@ -577,21 +583,21 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
return ..()
/obj/machinery/bookbinder/proc/bind_book(mob/user, obj/item/paper/P)
- if(stat)
+ if(machine_stat)
return
if(busy)
to_chat(user, "The book binder is busy. Please wait for completion of previous operation.")
return
if(!user.transferItemToLoc(P, src))
return
- user.visible_message("[user] loads some paper into [src].", "You load some paper into [src].")
- audible_message("[src] begins to hum as it warms up its printing drums.")
+ user.visible_message("[user] loads some paper into [src].", "You load some paper into [src].")
+ audible_message("[src] begins to hum as it warms up its printing drums.")
busy = TRUE
sleep(rand(200,400))
busy = FALSE
if(P)
- if(!stat)
- visible_message("[src] whirs as it prints and binds a new book.")
+ if(!machine_stat)
+ visible_message("[src] whirs as it prints and binds a new book.")
var/obj/item/book/B = new(src.loc)
B.dat = P.info
B.name = "Print Job #" + "[rand(100, 999)]"