Removes BSQL, implements RUST SQL

This commit is contained in:
Shifty/Anthomansland
2020-07-16 20:36:27 +02:00
parent a19aff7a75
commit 01c868bdfb
36 changed files with 473 additions and 650 deletions

BIN
BSQL.dll

Binary file not shown.

View File

@@ -1,126 +0,0 @@
//BSQL - DMAPI
#define BSQL_VERSION "v1.3.0.0"
//types of connections
#define BSQL_CONNECTION_TYPE_MARIADB "MySql"
#define BSQL_CONNECTION_TYPE_SQLSERVER "SqlServer"
#define BSQL_DEFAULT_TIMEOUT 5
#define BSQL_DEFAULT_THREAD_LIMIT 50
//Call this before rebooting or shutting down your world to clean up gracefully. This invalidates all active connection and operation datums
/world/proc/BSQL_Shutdown()
return
/*
Called whenever a library call is made with verbose information, override and do with as you please
message: English debug message
*/
/world/proc/BSQL_Debug(msg)
return
/*
Create a new database connection, does not perform the actual connect
connection_type: The BSQL connection_type to use
asyncTimeout: The timeout to use for normal operations, 0 for infinite, defaults to BSQL_DEFAULT_TIMEOUT
blockingTimeout: The timeout to use for blocking operations, must be less than or equal to asyncTimeout, 0 for infinite, defaults to asyncTimeout
threadLimit: The limit of additional threads BSQL will run simultaneously, defaults to BSQL_DEFAULT_THREAD_LIMIT
*/
/datum/BSQL_Connection/New(connection_type, asyncTimeout, blockingTimeout, threadLimit)
return ..()
/*
Starts an operation to connect to a database. Should only have 1 successful call
ipaddress: The ip/hostname of the target server
port: The port of the target server
username: The username to login to the target server
password: The password for the target server
database: Optional database to connect to. Must be used when trying to do database operations, `USE x` is not sufficient
Returns: A /datum/BSQL_Operation representing the connection or null if an error occurred
*/
/datum/BSQL_Connection/proc/BeginConnect(ipaddress, port, username, password, database)
return
/*
Properly quotes a string for use by the database. The connection must be open for this proc to succeed
str: The string to quote
Returns: The string quoted on success, null on error
*/
/datum/BSQL_Connection/proc/Quote(str)
return
/*
Starts an operation for a query
query: The text of the query. Only one query allowed per invocation, no semicolons
Returns: A /datum/BSQL_Operation/Query representing the running query and subsequent result set or null if an error occurred
Note for MariaDB: The underlying connection is pooled. In order to use connection state based properties (i.e. LAST_INSERT_ID()) you can guarantee multiple queries will use the same connection by running BSQL_DEL_CALL(query) on the finished /datum/BSQL_Operation/Query and then creating the next one with another call to BeginQuery() with no sleeps in between
*/
/datum/BSQL_Connection/proc/BeginQuery(query)
return
/*
Checks if the operation is complete. This, in some cases must be called multiple times with false return before a result is present regardless of timespan. For best performance check it once per tick
Returns: TRUE if the operation is complete, FALSE if it's not, null on error
*/
/datum/BSQL_Operation/proc/IsComplete()
return
/*
Blocks the entire game until the given operation completes. IsComplete should not be checked after calling this to avoid potential side effects.
Returns: TRUE on success, FALSE if the operation wait time exceeded the connection's blockingTimeout setting
*/
/datum/BSQL_Operation/proc/WaitForCompletion()
return
/*
Get the error message associated with an operation. Should not be used while IsComplete() returns FALSE
Returns: The error message, if any. null otherwise
*/
/datum/BSQL_Operation/proc/GetError()
return
/*
Get the error code associated with an operation. Should not be used while IsComplete() returns FALSE
Returns: The error code, if any. null otherwise
*/
/datum/BSQL_Operation/proc/GetErrorCode()
return
/*
Gets an associated list of column name -> value representation of the most recent row in the query. Only valid if IsComplete() returns TRUE. If this returns null and no errors are present there are no more results in the query. Important to note that once IsComplete() returns TRUE it must not be called again without checking this or the row values may be lost
Returns: An associated list of column name -> value for the row. Values will always be either strings or null
*/
/datum/BSQL_Operation/Query/proc/CurrentRow()
return
/*
Code configuration options below
Define this to avoid modifying this file but the following defines must be declared somewhere else before BSQL/includes.dm is included
*/
#ifndef BSQL_EXTERNAL_CONFIGURATION
//Modify this if you disagree with byond's GC schemes. Ensure this is called for all connections and operations when they are deleted or they will leak native resources until /world/proc/BSQL_Shutdown() is called
#define BSQL_DEL_PROC(path) ##path/Del()
//The equivalent of calling del() in your codebase
// Must not be changed to "qdel()".
#define BSQL_DEL_CALL(obj) del(##obj)
//Returns TRUE if an object is delete
#define BSQL_IS_DELETED(obj) (obj == null)
//Modify this to add protections to the connection and query datums
#define BSQL_PROTECT_DATUM(path)
//Modify this to change up error handling for the library
#define BSQL_ERROR(message) CRASH("BSQL: [##message]")
#endif
/*
Copyright 2018 Jordan Brown
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

View File

@@ -196,7 +196,7 @@ var/datum/nanomanager/nanomanager = new()
// MySQL configuration
var/sqladdress = "localhost"
var/sqlport = "3306"
var/sqlport = 3306
var/sqldb = "tgstation"
var/sqllogin = "root"
var/sqlpass = ""

73
__DEFINES/rust_g.dm Normal file
View File

@@ -0,0 +1,73 @@
// -- Borrowed from various authors from TGStation - https://github.com/tgstation/tgstation
// rust_g.dm - DM API for rust_g extension library
//
// To configure, create a `rust_g.config.dm` and set what you care about from
// the following options:
//
// #define RUST_G "path/to/rust_g"
// Override the .dll/.so detection logic with a fixed path or with detection
// logic of your own.
//
// #define RUSTG_OVERRIDE_BUILTINS
// Enable replacement rust-g functions for certain builtins. Off by default.
#ifndef RUST_G
// Default automatic RUST_G detection.
// On Windows, looks in the standard places for `rust_g.dll`.
// On Linux, looks in `.`, `$LD_LIBRARY_PATH`, and `~/.byond/bin` for either of
// `librust_g.so` (preferred) or `rust_g` (old).
/* This comment bypasses grep checks */ /var/__rust_g
/proc/__detect_rust_g()
if (world.system_type == UNIX)
if (fexists("./librust_g.so"))
// No need for LD_LIBRARY_PATH badness.
return __rust_g = "./librust_g.so"
else if (fexists("./rust_g"))
// Old dumb filename.
return __rust_g = "./rust_g"
else if (fexists("[world.GetConfig("env", "HOME")]/.byond/bin/rust_g"))
// Old dumb filename in `~/.byond/bin`.
return __rust_g = "rust_g"
else
// It's not in the current directory, so try others
return __rust_g = "librust_g.so"
else
return __rust_g = "rust_g"
#define RUST_G (__rust_g || __detect_rust_g())
#endif
#define RUSTG_JOB_NO_RESULTS_YET "NO RESULTS YET"
#define RUSTG_JOB_NO_SUCH_JOB "NO SUCH JOB"
#define RUSTG_JOB_ERROR "JOB PANICKED"
#define rustg_dmi_strip_metadata(fname) call(RUST_G, "dmi_strip_metadata")(fname)
#define rustg_dmi_create_png(path, width, height, data) call(RUST_G, "dmi_create_png")(path, width, height, data)
#define rustg_noise_get_at_coordinates(seed, x, y) call(RUST_G, "noise_get_at_coordinates")(seed, x, y)
#define rustg_git_revparse(rev) call(RUST_G, "rg_git_revparse")(rev)
#define rustg_git_commit_date(rev) call(RUST_G, "rg_git_commit_date")(rev)
#define rustg_log_write(fname, text, format) call(RUST_G, "log_write")(fname, text, format)
/proc/rustg_log_close_all() return call(RUST_G, "log_close_all")()
#define RUSTG_HTTP_METHOD_GET "get"
#define RUSTG_HTTP_METHOD_PUT "put"
#define RUSTG_HTTP_METHOD_DELETE "delete"
#define RUSTG_HTTP_METHOD_PATCH "patch"
#define RUSTG_HTTP_METHOD_HEAD "head"
#define RUSTG_HTTP_METHOD_POST "post"
#define rustg_http_request_blocking(method, url, body, headers) call(RUST_G, "http_request_blocking")(method, url, body, headers)
#define rustg_http_request_async(method, url, body, headers) call(RUST_G, "http_request_async")(method, url, body, headers)
#define rustg_http_check_request(req_id) call(RUST_G, "http_check_request")(req_id)
#define rustg_sql_connect_pool(options) call(RUST_G, "sql_connect_pool")(options)
#define rustg_sql_query_async(handle, query, params) call(RUST_G, "sql_query_async")(handle, query, params)
#define rustg_sql_query_blocking(handle, query, params) call(RUST_G, "sql_query_blocking")(handle, query, params)
#define rustg_sql_connected(handle) call(RUST_G, "sql_connected")(handle)
#define rustg_sql_disconnect_pool(handle) call(RUST_G, "sql_disconnect_pool")(handle)
#define rustg_sql_check_query(job_id) call(RUST_G, "sql_check_query")("[job_id]")

View File

@@ -55,6 +55,7 @@
to_chat(C, "DEBUG: [text]")
/proc/log_sql(text)
world.log << text
if (!config || (config && config.log_sql))
diary << html_decode("\[[time_stamp()]]SQL: [text]")

View File

@@ -4,32 +4,12 @@
/*
* Holds procs designed to help with filtering text
* Contains groups:
* SQL sanitization
* Text sanitization
* Text searches
* Text modification
* Misc
*/
/*
* SQL sanitization
*/
// Run all strings to be used in an SQL query through this proc first to properly escape out injection attempts.
/proc/sanitizeSQL(var/t as text)
//var/sanitized_text = replacetext(t, "'", "\\'")
var/sqltext = SSdbcore.Quote(t)
sqltext = replacetext(sqltext, "'", "\'")
//to_chat(world, "sanitizeSQL(): BEFORE Quote(): [t]")
//to_chat(world, "sanitizeSQL(): AFTER Quote(): [sqltext]")
return sqltext
/*
/mob/verb/SanitizeTest(var/t as text)
to_chat(src, "IN: [t]")
to_chat(src, "OUT: [sanitizeSQL(t)]")
*/
/*
* Text sanitization
*/

View File

@@ -707,7 +707,7 @@
if ("address")
sqladdress = value
if ("port")
sqlport = value
sqlport = text2num(value)
if ("database")
sqldb = value
if ("login")

View File

@@ -22,8 +22,7 @@ var/datum/subsystem/dbcore/SSdbcore
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/subsystem/dbcore/New()
NEW_SS_GLOBAL(SSdbcore)
@@ -70,7 +69,6 @@ var/datum/subsystem/dbcore/SSdbcore
/datum/subsystem/dbcore/Recover()
connection = SSdbcore.connection
connectOperation = SSdbcore.connectOperation
/datum/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
@@ -78,7 +76,6 @@ var/datum/subsystem/dbcore/SSdbcore
ShutdownQuery()
if(IsConnected())
Disconnect()
world.BSQL_Shutdown()
/datum/subsystem/dbcore/proc/Connect()
if(initialized && IsConnected())
@@ -101,40 +98,42 @@ var/datum/subsystem/dbcore/SSdbcore
var/db = ids["db"]
var/address = ids["address"]
var/port = ids["port"]
var/timeout = max(config.async_query_timeout, config.blocking_query_timeout)
var/thread_limit = config.bsql_thread_limit
connection = new /datum/BSQL_Connection(BSQL_CONNECTION_TYPE_MARIADB, config.async_query_timeout, config.blocking_query_timeout, config.bsql_thread_limit)
var/error
if(!connection || connection.gcDestroyed)
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,
"max_threads" = 5,
"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)
// This is a bit of a hack. It sets initialized to be true BEFORE 'UNTIL', which sleeps. All the code done before is done synchronously.
// This ensures that the server establishes a connection and a connection operation before any call to IsBanned(), for instance, is made.
// Now IsBanned() calls will patiently wait on a DB connection to exist to be resolved, preventing queries to be queued up before an actual connection is made.
initialized = TRUE
if(SSdbcore.last_error)
CRASH(SSdbcore.last_error)
UNTIL(connectOperation.IsComplete())
error = connectOperation.GetError()
. = !error
if (!.)
last_error = error
log_sql("Connect() failed | [error]")
++failed_connections
BSQL_DEL_CALL(connection)
BSQL_DEL_CALL(connectOperation)
initialized = 0
connection = null
connectOperation = null
last_error = result["data"]
log_sql("Connect() failed | [last_error]")
++failed_connections
/datum/subsystem/dbcore/proc/Disconnect()
failed_connections = 0
if (connection)
rustg_sql_disconnect_pool(connection)
connection = null
/datum/subsystem/dbcore/proc/CheckSchemaVersion()
if(config.sql_enabled)
if(Connect())
log_world("Database connection established.")
/*
var/datum/DBQuery/query_db_version = NewQuery("SELECT major, minor FROM schema_revision ORDER BY date DESC LIMIT 1")
var/datum/DBQuery/query_db_version = NewQuery(/**xx**/"SELECT major, minor FROM 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])
@@ -168,10 +167,10 @@ var/datum/subsystem/dbcore/SSdbcore
/datum/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]')")
var/datum/DBQuery/query_round_initialize = SSdbcore.NewQuery(/**xx**/"")
query_round_initialize.Execute(async = FALSE)
qdel(query_round_initialize)
var/datum/DBQuery/query_round_last_id = SSdbcore.NewQuery("SELECT LAST_INSERT_ID()")
var/datum/DBQuery/query_round_last_id = SSdbcore.NewQuery(/**xx**/"SELECT LAST_INSERT_ID()")
query_round_last_id.Execute(async = FALSE)
if(query_round_last_id.NextRow(async = FALSE))
GLOB.round_id = query_round_last_id.item[1]
@@ -180,52 +179,29 @@ var/datum/subsystem/dbcore/SSdbcore
/datum/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/DBQuery/query_round_start = SSdbcore.NewQuery()
query_round_start.Execute()
qdel(query_round_start)
/datum/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/DBQuery/query_round_end = SSdbcore.NewQuery()
query_round_end.Execute()
qdel(query_round_end)
/datum/subsystem/dbcore/proc/ShutdownQuery()
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/DBQuery/query_round_shutdown = SSdbcore.NewQuery()
query_round_shutdown.Execute()
qdel(query_round_shutdown)
*/
/datum/subsystem/dbcore/proc/Disconnect()
initialized = 0
failed_connections = 0
BSQL_DEL_CALL(connectOperation)
BSQL_DEL_CALL(connection)
connectOperation = null
connection = null
/datum/subsystem/dbcore/proc/IsConnected()
if(!config.sql_enabled)
return FALSE
//block until any connect operations finish
var/datum/BSQL_Connection/_connection = connection
var/datum/BSQL_Operation/op = connectOperation
var/ticker = 0
while ( (!_connection || _connection.gcDestroyed) || !op.IsComplete() ) // Waiting we have a real connection and that it's complete
stoplag()
ticker++
if (ticker > 100 && (!connection || !connectOperation || connection.gcDestroyed))
message_admins("Error getting connection status. Attempting to reconnect.")
Disconnect()
Connect()
return
return connection && !(connection.gcDestroyed && !op.GetError()) // Connect
/datum/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/subsystem/dbcore/proc/ErrorMsg()
if(!config.sql_enabled)
@@ -236,8 +212,8 @@ var/datum/subsystem/dbcore/SSdbcore
last_error = error
//
/datum/subsystem/dbcore/proc/NewQuery(sql_query)
return new /datum/DBQuery(sql_query, connection)
/datum/subsystem/dbcore/proc/NewQuery(sql_query, arguments)
return new /datum/DBQuery(connection, sql_query, arguments)
/datum/subsystem/dbcore/proc/QuerySelect(list/querys, warn = FALSE, qdel = FALSE)
if (!islist(querys))
@@ -270,55 +246,60 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
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/subsystem/dbcore/proc/MassInsert(table, list/rows, duplicate_key = FALSE, ignore_errors = FALSE, delayed = FALSE, warn = FALSE, async = TRUE)
/datum/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/DBQuery/Query = NewQuery(query_parts.Join(), arguments)
if (warn)
. = Query.warn_execute(async)
else
@@ -326,25 +307,32 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
qdel(Query)
/datum/DBQuery
var/sql // The sql query being executed.
var/list/item //list of data values populated by NextRow()
// 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)
log_query_debug("new query with SQL : {[sql_query]} \n on [SSdbcore.name]")
var/list/item //list of data values populated by NextRow()
/datum/DBQuery/New(connection, sql, arguments)
SSdbcore.active_queries[src] = TRUE
Activity("Created")
item = list()
src.connection = connection
sql = sql_query
src.sql = sql
src.arguments = arguments
/datum/DBQuery/Destroy()
log_query_debug("query with [sql] being qdeleted. Will die any second now.")
@@ -356,12 +344,6 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
log_query_debug("query with [sql] died.")
return ..()
/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)
last_activity = activity
last_activity_time = world.time
@@ -376,30 +358,18 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
if(in_progress)
CRASH("Attempted to start a new query while waiting on the old one")
if(!connection || connection.gcDestroyed)
if(!SSdbcore.IsConnected())
last_error = "No connection!"
return FALSE
var/start_time
var/timed_out
if(!async)
start_time = REALTIMEOFDAY
Close()
timed_out = run_query(async)
if(query.GetErrorCode() == 2006) //2006 is the return code for "MySQL server has gone away" time-out error, meaning the connection has been lost to the server (if it's still alive)
log_sql("Executing query encountered returned a lost database connection (2006).")
SSdbcore.Disconnect()
if(SSdbcore.Connect()) //connection was restablished, reattempt the query
log_sql("Connection restablished")
timed_out = run_query(async)
else
log_sql("Executing query failed to restablish database connection.")
skip_next_is_complete = TRUE
var/error = (!query || query.gcDestroyed) ? "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]")
if(!async && timed_out)
log_query_debug("Query execution started at [start_time]")
log_query_debug("Query execution ended at [REALTIMEOFDAY]")
@@ -408,53 +378,50 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
slow_query_check()
/datum/DBQuery/proc/run_query(async)
query = connection.BeginQuery(sql)
if(!async)
. = !query.WaitForCompletion()
else
var/job_result_str
if (async)
var/job_id = rustg_sql_query_async(connection, sql, json_encode(arguments))
in_progress = TRUE
UNTIL(query.IsComplete())
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/DBQuery/proc/slow_query_check()
message_admins("HEY! A database query timed out. Tell coders or Pomf what happened, please.")
/datum/DBQuery/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
last_error = query.GetError()
var/list/results = query.CurrentRow()
. = results != null
item.Cut()
//populate item array
for(var/I in results)
item += results[I]
return FALSE
/datum/DBQuery/proc/ErrorMsg()
return last_error
/datum/DBQuery/proc/Close()
item.Cut()
qdel(query)
query = null
/world/BSQL_Debug(message)
if(!config.bsql_debug)
return
//strip sensitive stuff
if(findtext(message, ": OpenConnection("))
message = "OpenConnection CENSORED"
log_sql("BSQL_DEBUG: [message]")
rows = null
item = null

View File

@@ -79,7 +79,7 @@ var/datum/blackbox/blackbox = new
var/nqueries = 0
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT MAX(round_id) AS round_id FROM erro_feedback")
var/datum/DBQuery/query = SSdbcore.NewQuery(/**xx**/"SELECT MAX(round_id) AS round_id FROM erro_feedback")
if(!query.Execute())
log_sql("Error: [query.ErrorMsg()]")
qdel(query)

View File

@@ -1,4 +1,4 @@
proc/sql_poll_players()
/proc/sql_poll_players()
if(!sqllogging)
return
var/playercount = 0
@@ -9,13 +9,17 @@ proc/sql_poll_players()
log_game("SQL ERROR during player polling. Failed to connect.")
else
var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
var/datum/DBQuery/query = SSdbcore.NewQuery("INSERT INTO population (playercount, time) VALUES ([playercount], '[sqltime]')")
var/datum/DBQuery/query = SSdbcore.NewQuery("INSERT INTO population (playercount, time) VALUES (:playercount, :time)",
list(
"playercount" = playercount,
"time" = sqltime,
))
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during player polling. Error : \[[err]\]\n")
qdel(query)
proc/sql_poll_admins()
/proc/sql_poll_admins()
if(!sqllogging)
return
var/admincount = admins.len
@@ -23,22 +27,17 @@ proc/sql_poll_admins()
log_game("SQL ERROR during admin polling. Failed to connect.")
else
var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
var/datum/DBQuery/query = SSdbcore.NewQuery("INSERT INTO population (admincount, time) VALUES ([admincount], '[sqltime]')")
var/datum/DBQuery/query = SSdbcore.NewQuery("INSERT INTO population (admincount, time) VALUES (:admincount, :time)",
list(
"admincount" = admincount,
"time" = sqltime,
))
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during admin polling. Error : \[[err]\]\n")
qdel(query)
proc/sql_report_round_start()
// TODO
if(!sqllogging)
return
proc/sql_report_round_end()
// TODO
if(!sqllogging)
return
proc/sql_report_death(var/mob/living/carbon/human/H)
/proc/sql_report_death(var/mob/living/carbon/human/H)
if(!sqllogging)
return
if(!H)
@@ -49,30 +48,25 @@ proc/sql_report_death(var/mob/living/carbon/human/H)
var/turf/T = H.loc
var/area/placeofdeath = get_area(T.loc)
var/podname = placeofdeath.name
var/sqlname = sanitizeSQL(H.real_name)
var/sqlkey = sanitizeSQL(H.key)
var/sqlpod = sanitizeSQL(podname)
var/sqlspecial = sanitizeSQL(H.mind.special_role)
var/sqljob = sanitizeSQL(H.mind.assigned_role)
var/laname
var/lakey
if(H.lastattacker)
laname = sanitizeSQL(H.lastattacker:real_name)
lakey = sanitizeSQL(H.lastattacker:key)
laname = H.lastattacker:real_name
lakey = H.lastattacker:key
var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
var/coord = "[H.x], [H.y], [H.z]"
// to_chat(world, "INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.bruteloss], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()])")
if(!SSdbcore.Connect())
log_game("SQL ERROR during death reporting. Failed to connect.")
else
var/datum/DBQuery/query = SSdbcore.NewQuery("INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.getBruteLoss()], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()], '[coord]')")
var/datum/DBQuery/query = SSdbcore.NewQuery("INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES (:name, :key, :job, :special, :pod, :time, :laname, :lakey, :gender, :bruteloss, :fireloss, :brainloss, :oxyloss, :coord)",
list("name" = H.name, "key" = H.key, "special" = H.mind.assigned_role, "pod" = podname, "time" = sqltime, "laname" = laname, "lakey" = lakey, "gender" = "[H.gender]", "bruteloss" = "[H.getBruteLoss()]", "fireloss" = "[H.getFireLoss()]", "brainloss" = "[H.brainloss]", "oxyloss" = "[H.getOxyLoss()]", "coord" = "[coord]"))
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during death reporting. Error : \[[err]\]\n")
qdel(query)
proc/sql_report_cyborg_death(var/mob/living/silicon/robot/H)
/proc/sql_report_cyborg_death(var/mob/living/silicon/robot/H)
if(!sqllogging)
return
if(!H)
@@ -84,22 +78,19 @@ proc/sql_report_cyborg_death(var/mob/living/silicon/robot/H)
var/area/placeofdeath = get_area(T.loc)
var/podname = placeofdeath.name
var/sqlname = sanitizeSQL(H.real_name)
var/sqlkey = sanitizeSQL(H.key)
var/sqlpod = sanitizeSQL(podname)
var/sqlspecial = sanitizeSQL(H.mind.special_role)
var/sqljob = sanitizeSQL(H.mind.assigned_role)
var/laname
var/lakey
if(H.lastattacker)
laname = sanitizeSQL(H.lastattacker:real_name)
lakey = sanitizeSQL(H.lastattacker:key)
laname = H.lastattacker:real_name
lakey = H.lastattacker:key
var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
var/coord = "[H.x], [H.y], [H.z]"
if(!SSdbcore.Connect())
log_game("SQL ERROR during death reporting. Failed to connect.")
else
var/datum/DBQuery/query = SSdbcore.NewQuery("INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.getBruteLoss()], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()], '[coord]')")
var/datum/DBQuery/query = SSdbcore.NewQuery("INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES (:name, :key, :job, :special, :pod, :time, :laname, :lakey, :gender, :bruteloss, :fireloss, :brainloss, :oxyloss, :coord)",
list("name" = H.name, "key" = H.key, "special" = H.mind.assigned_role, "pod" = podname, "time" = sqltime, "laname" = laname, "lakey" = lakey, "gender" = "[H.gender]", "bruteloss" = "[H.getBruteLoss()]", "fireloss" = "[H.getFireLoss()]", "brainloss" = "[H.brainloss]", "oxyloss" = "[H.getOxyLoss()]", "coord" = "[coord]")
)
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during death reporting. Error : \[[err]\]\n")
@@ -126,7 +117,7 @@ proc/sql_commit_feedback()
if(!content)
log_game("Round ended without any feedback being generated. No feedback was sent to the database.")
return
if(!SSdbcore.Connect())
log_game("SQL ERROR during feedback reporting. Failed to connect.")
else
@@ -153,7 +144,13 @@ proc/sql_commit_feedback()
var/variable = item.get_variable()
var/value = item.get_value()
var/datum/DBQuery/query = SSdbcore.NewQuery("INSERT INTO erro_feedback (id, roundid, time, variable, value) VALUES (null, [newroundid], Now(), '[variable]', '[value]')")
var/datum/DBQuery/query = SSdbcore.NewQuery("INSERT INTO erro_feedback (id, roundid, time, variable, value) VALUES (:id, :newroundid, Now(), :variable, :value)",
list(
"id" = null,
"newroundid" = newroundid,
"variable" = variable,
"value" = value,
))
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during death reporting. Error : \[[err]\]\n")

View File

@@ -1,7 +0,0 @@
Copyright 2018 Jordan Brown
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,63 +0,0 @@
/datum/BSQL_Connection
var/id
var/connection_type
BSQL_PROTECT_DATUM(/datum/BSQL_Connection)
/datum/BSQL_Connection/New(connection_type, asyncTimeout, blockingTimeout, threadLimit)
if(asyncTimeout == null)
asyncTimeout = BSQL_DEFAULT_TIMEOUT
if(blockingTimeout == null)
blockingTimeout = asyncTimeout
if(threadLimit == null)
threadLimit = BSQL_DEFAULT_THREAD_LIMIT
src.connection_type = connection_type
world._BSQL_InitCheck(src)
var/error = world._BSQL_Internal_Call("CreateConnection", connection_type, "[asyncTimeout]", "[blockingTimeout]", "[threadLimit]")
if(error)
BSQL_ERROR(error)
id = world._BSQL_Internal_Call("GetConnection")
if(!id)
BSQL_ERROR("BSQL library failed to provide connect operation for connection id [id]([connection_type])!")
BSQL_DEL_PROC(/datum/BSQL_Connection)
var/error
if(id)
error = world._BSQL_Internal_Call("ReleaseConnection", id)
. = ..()
if(error)
BSQL_ERROR(error)
/datum/BSQL_Connection/BeginConnect(ipaddress, port, username, password, database)
var/error = world._BSQL_Internal_Call("OpenConnection", id, ipaddress, "[port]", username, password, database)
if(error)
BSQL_ERROR(error)
var/op_id = world._BSQL_Internal_Call("GetOperation")
if(!op_id)
BSQL_ERROR("Library failed to provide connect operation for connection id [id]([connection_type])!")
return new /datum/BSQL_Operation(src, op_id)
/datum/BSQL_Connection/BeginQuery(query)
var/error = world._BSQL_Internal_Call("NewQuery", id, query)
if(error)
BSQL_ERROR(error)
var/op_id = world._BSQL_Internal_Call("GetOperation")
if(!op_id)
BSQL_ERROR("Library failed to provide query operation for connection id [id]([connection_type])!")
return new /datum/BSQL_Operation/Query(src, op_id)
/datum/BSQL_Connection/Quote(str)
if(!str)
return null;
. = world._BSQL_Internal_Call("QuoteString", id, "[str]")
if(!.)
BSQL_ERROR("Library failed to provide quote for [str]!")

View File

@@ -1,40 +0,0 @@
/world/proc/_BSQL_Internal_Call(func, ...)
var/list/call_args = args.Copy(2)
BSQL_Debug("_BSQL_Internal_Call: [args[1]]([call_args.Join(", ")])")
. = call(_BSQL_Library_Path(), func)(arglist(call_args))
BSQL_Debug("Result: [. == null ? "NULL" : "\"[.]\""]")
/world/proc/_BSQL_Library_Path()
return system_type == MS_WINDOWS ? "BSQL.dll" : "libBSQL.so"
/world/proc/_BSQL_InitCheck(datum/BSQL_Connection/caller)
var/static/library_initialized = FALSE
if(_BSQL_Initialized())
return
var/libPath = _BSQL_Library_Path()
if(!fexists(libPath))
BSQL_DEL_CALL(caller)
BSQL_ERROR("Could not find [libPath]!")
var/version = _BSQL_Internal_Call("Version")
if(version != BSQL_VERSION)
BSQL_DEL_CALL(caller)
BSQL_ERROR("BSQL DMAPI version mismatch! Expected [BSQL_VERSION], got [version == null ? "NULL" : version]!")
var/result = _BSQL_Internal_Call("Initialize")
if(result)
BSQL_DEL_CALL(caller)
BSQL_ERROR(result)
_BSQL_Initialized(TRUE)
/world/proc/_BSQL_Initialized(new_val)
var/static/bsql_library_initialized = FALSE
if(new_val != null)
bsql_library_initialized = new_val
return bsql_library_initialized
/world/BSQL_Shutdown()
if(!_BSQL_Initialized())
return
_BSQL_Internal_Call("Shutdown")
_BSQL_Initialized(FALSE)

View File

@@ -1,45 +0,0 @@
/datum/BSQL_Operation
var/datum/BSQL_Connection/connection
var/id
BSQL_PROTECT_DATUM(/datum/BSQL_Operation)
/datum/BSQL_Operation/New(datum/BSQL_Connection/connection, id)
src.connection = connection
src.id = id
BSQL_DEL_PROC(/datum/BSQL_Operation)
var/error
if(!BSQL_IS_DELETED(connection))
error = world._BSQL_Internal_Call("ReleaseOperation", connection.id, id)
. = ..()
if(error)
BSQL_ERROR(error)
/datum/BSQL_Operation/IsComplete()
if(BSQL_IS_DELETED(connection))
return TRUE
var/result = world._BSQL_Internal_Call("OpComplete", connection.id, id)
if(!result)
BSQL_ERROR("Error fetching operation [id] for connection [connection.id]!")
return result == "DONE"
/datum/BSQL_Operation/GetError()
if(BSQL_IS_DELETED(connection))
return "Connection deleted!"
return world._BSQL_Internal_Call("GetError", connection.id, id)
/datum/BSQL_Operation/GetErrorCode()
if(BSQL_IS_DELETED(connection))
return -2
return text2num(world._BSQL_Internal_Call("GetErrorCode", connection.id, id))
/datum/BSQL_Operation/WaitForCompletion()
if(BSQL_IS_DELETED(connection))
return
var/error = world._BSQL_Internal_Call("BlockOnOperation", connection.id, id)
if(error)
if(error == "Operation timed out!") //match this with the implementation
return FALSE
BSQL_ERROR("Error waiting for operation [id] for connection [connection.id]! [error]")
return TRUE

View File

@@ -1,35 +0,0 @@
/datum/BSQL_Operation/Query
var/last_result_json
var/list/last_result
BSQL_PROTECT_DATUM(/datum/BSQL_Operation/Query)
/datum/BSQL_Operation/Query/CurrentRow()
return last_result
/datum/BSQL_Operation/Query/IsComplete()
//whole different ballgame here
if(BSQL_IS_DELETED(connection))
return TRUE
var/result = world._BSQL_Internal_Call("ReadyRow", connection.id, id)
switch(result)
if("DONE")
//load the data
LoadQueryResult()
return TRUE
if("NOTDONE")
return FALSE
else
BSQL_ERROR(result)
/datum/BSQL_Operation/Query/WaitForCompletion()
. = ..()
if(.)
LoadQueryResult()
/datum/BSQL_Operation/Query/proc/LoadQueryResult()
last_result_json = world._BSQL_Internal_Call("GetRow", connection.id, id)
if(last_result_json)
last_result = json_decode(last_result_json)
else
last_result = null

View File

@@ -1,4 +0,0 @@
#include "core\connection.dm"
#include "core\library.dm"
#include "core\operation.dm"
#include "core\query.dm"

View File

@@ -55,7 +55,7 @@
else if(banckey)
ckey = ckey(banckey)
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT id FROM erro_player WHERE ckey = '[ckey]'")
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT id FROM erro_player WHERE ckey = :ckey", list("ckey" = "[ckey]"))
if(!query.Execute())
message_admins("Error: [query.ErrorMsg()]")
log_sql("Error: [query.ErrorMsg()]")
@@ -202,7 +202,7 @@ datum/admins/proc/DB_ban_edit(var/banid = null, var/param = null)
to_chat(usr, "Cancelled")
return
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT ckey, duration, reason FROM erro_ban WHERE id = [banid]")
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT ckey, duration, reason FROM erro_ban WHERE id = :banid", list("banid" = banid))
if(!query.Execute())
message_admins("Error: [query.ErrorMsg()]")
log_sql("Error: [query.ErrorMsg()]")
@@ -235,7 +235,12 @@ datum/admins/proc/DB_ban_edit(var/banid = null, var/param = null)
to_chat(usr, "Cancelled")
return
var/datum/DBQuery/update_query = SSdbcore.NewQuery("UPDATE erro_ban SET reason = '[value]', edits = CONCAT(edits,'- [eckey] changed ban reason from <cite><b>\\\"[reason]\\\"</b></cite> to <cite><b>\\\"[value]\\\"</b></cite><BR>') WHERE id = [banid]")
var/datum/DBQuery/update_query = SSdbcore.NewQuery("UPDATE erro_ban SET reason = , edits = CONCAT(edits,:edits) WHERE id = :banid",
list(
"value" = "[value]",
"edits" = "- [eckey] changed ban reason from <cite><b>\\\"[reason]\\\"</b></cite> to <cite><b>\\\"[value]\\\"</b></cite><BR>",
"banid" = banid
))
if(!update_query.Execute())
message_admins("Error: [update_query.ErrorMsg()]")
log_sql("Error: [update_query.ErrorMsg()]")
@@ -250,7 +255,12 @@ datum/admins/proc/DB_ban_edit(var/banid = null, var/param = null)
to_chat(usr, "Cancelled")
return
var/datum/DBQuery/update_query = SSdbcore.NewQuery("UPDATE erro_ban SET duration = [value], edits = CONCAT(edits,'- [eckey] changed ban duration from [duration] to [value]<br>'), expiration_time = DATE_ADD(bantime, INTERVAL [value] MINUTE) WHERE id = [banid]")
var/datum/DBQuery/update_query = SSdbcore.NewQuery("UPDATE erro_ban SET duration = :value, edits = CONCAT(edits,:edits), expiration_time = DATE_ADD(bantime, INTERVAL :value MINUTE) WHERE id = :banid",
list(
"value" = "[value]",
"edits" = "- [eckey] changed ban duration from [duration] to [value]<br>",
"banid" = banid,
))
message_admins("[key_name_admin(usr)] has edited a ban for [pckey]'s duration from [duration] to [value]",1)
if(!update_query.Execute())
message_admins("Error: [update_query.ErrorMsg()]")
@@ -413,11 +423,15 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
var/adminsearch = ""
var/playersearch = ""
if(adminckey)
adminsearch = "AND a_ckey = '[adminckey]' "
adminsearch = "AND a_ckey = :adminckey "
if(playerckey)
playersearch = "AND ckey = '[playerckey]' "
playersearch = "AND ckey = :playerckey "
var/datum/DBQuery/select_query = SSdbcore.NewQuery("SELECT id, bantime, bantype, reason, job, duration, expiration_time, ckey, a_ckey, unbanned, unbanned_ckey, unbanned_datetime, edits FROM erro_ban WHERE 1 [playersearch] [adminsearch] ORDER BY bantime DESC")
var/datum/DBQuery/select_query = SSdbcore.NewQuery("SELECT id, bantime, bantype, reason, job, duration, expiration_time, ckey, a_ckey, unbanned, unbanned_ckey, unbanned_datetime, edits FROM erro_ban WHERE 1 [playersearch] [adminsearch] ORDER BY bantime DESC",
list(
"adminckey" = adminckey,
"playerckey" = playerckey,
))
if(!select_query.Execute())
qdel(select_query)
message_admins("Error: [select_query.ErrorMsg()]")

View File

@@ -59,17 +59,18 @@
var/failedcid = 1
var/failedip = 1
var/ipquery = ""
var/cidquery = ""
if(address)
failedip = 0
ipquery = " OR ip = '[address]' "
if(computer_id)
failedcid = 0
cidquery = " OR computerid = '[computer_id]' "
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM erro_ban WHERE (ckey = '[ckeytext]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM erro_ban WHERE (ckey = :ckey [address ? "OR ip = :address" : ""] [computer_id ? "OR computerid = :computer_id" : ""]) AND (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)",
list(
"ckey" = "[ckeytext]",
"address" = "[address]",
"computer_id" = "[computer_id]"
))
if(!query.Execute())
message_admins("Error: [query.ErrorMsg()]")

View File

@@ -933,8 +933,7 @@ var/list/admin_verbs_mod = list(
to_chat(src, "You are already an admin.")
verbs -= /client/proc/readmin
return
var/sql_ckey = sanitizeSQL(ckey(ckey))
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT ckey, rank, level, flags FROM erro_admin WHERE ckey = '[sql_ckey]'")
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT ckey, rank, level, flags FROM erro_admin WHERE ckey = :ckey", list("ckey" = ckey))
if(!query.Execute())
log_sql("Error: [query.ErrorMsg()]")
qdel(query)

View File

@@ -62,7 +62,10 @@ DEBUG
return
//appearance bans
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT ckey FROM erro_ban WHERE bantype = 'APPEARANCE_PERMABAN' AND isnull(unbanned)")
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT ckey FROM erro_ban WHERE bantype = :bantype AND isnull(unbanned)",
list(
"bantype" = "APPEARANCE_PERMABAN",
))
if(!query.Execute())
log_sql("Error: [query.ErrorMsg()]")
qdel(query)

View File

@@ -70,7 +70,10 @@ DEBUG
return
//Job permabans
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT ckey, job FROM erro_ban WHERE bantype = 'JOB_PERMABAN' AND isnull(unbanned)")
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT ckey, job FROM erro_ban WHERE bantype = :bantype AND isnull(unbanned)",
list(
"bantype" = "JOB_PERMABAN"
))
if(!query.Execute())
message_admins("Error: [query.ErrorMsg()]")
log_sql("Error: [query.ErrorMsg()]")
@@ -84,7 +87,10 @@ DEBUG
jobban_keylist.Add("[ckey] - [job]")
qdel(query)
//Job tempbans
var/datum/DBQuery/query1 = SSdbcore.NewQuery("SELECT ckey, job FROM erro_ban WHERE bantype = 'JOB_TEMPBAN' AND isnull(unbanned) AND expiration_time > Now()")
var/datum/DBQuery/query1 = SSdbcore.NewQuery("SELECT ckey, job FROM erro_ban WHERE bantype = :bantype AND isnull(unbanned) AND expiration_time > Now()",
list(
"bantype" = "JOB_TEMPBAN",
))
if(!query1.Execute())
log_sql("Error: [query1.ErrorMsg()]")
qdel(query1)

View File

@@ -17,7 +17,11 @@ var/oocban_keylist[0]
return
//OOC permabans
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT ckey FROM erro_ban WHERE (bantype = 'OOC_PERMABAN' OR (bantype = 'OOC_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT ckey FROM erro_ban WHERE (bantype = :ooc_perma OR (bantype = :ooc_temp AND expiration_time > Now())) AND isnull(unbanned)",
list(
"ooc_perma" = "OOC_PERMABAN",
"ooc_temp" = "OOC_TEMPBAN",
))
if(!query.Execute())
message_admins("Error: [query.ErrorMsg()]")
log_sql("Error: [query.ErrorMsg()]")

View File

@@ -23,8 +23,7 @@
if(!endtime)
to_chat(usr, "<span class='warning'>endtime is null!</span>")
return
endtime = sanitizeSQL(endtime)
var/datum/DBQuery/query_validate_time = SSdbcore.NewQuery("SELECT STR_TO_DATE('[endtime]','%Y-%c-%d %T')")
var/datum/DBQuery/query_validate_time = SSdbcore.NewQuery("SELECT STR_TO_DATE(:endtime,'%Y-%c-%d %T')", list("endtime" = endtime))
if(!query_validate_time.Execute())
var/err = query_validate_time.ErrorMsg()
log_sql("SQL ERROR validating endtime. Error : \[[err]\]\n")
@@ -36,7 +35,7 @@
to_chat(src, "Datetime entered is invalid.")
return
qdel(query_validate_time)
var/datum/DBQuery/query_time_later = SSdbcore.NewQuery("SELECT DATE('[endtime]') < NOW()")
var/datum/DBQuery/query_time_later = SSdbcore.NewQuery("SELECT DATE(:endtime) < NOW()", list("endtime" = endtime))
if(!query_time_later.Execute())
var/err = query_time_later.ErrorMsg()
log_sql("SQL ERROR comparing endtime to NOW(). Error : \[[err]\]\n")
@@ -56,12 +55,20 @@
adminonly = 0
else
return
var/sql_ckey = sanitizeSQL(ckey)
var/question = input("Write your question","Question") as message
if(!question)
return
question = sanitizeSQL(question)
var/datum/DBQuery/query_polladd_question = SSdbcore.NewQuery("INSERT INTO erro_poll_question (polltype, starttime, endtime, question, adminonly, multiplechoiceoptions, createdby_ckey, createdby_ip) VALUES ('[polltype]', '[starttime]', '[endtime]', '[question]', '[adminonly]', '[choice_amount]', '[sql_ckey]', '[address]')")
var/datum/DBQuery/query_polladd_question = SSdbcore.NewQuery("INSERT INTO erro_poll_question (polltype, starttime, endtime, question, adminonly, multiplechoiceoptions, createdby_ckey, createdby_ip) VALUES (:polltype, :starttime, :endtime, :question, :adminonly, :choice_amount, :ckey, :address)",
list(
"polltype" = polltype,
"starttime" = starttime,
"endtime" = endtime,
"question" = question,
"adminonly" = adminonly,
"choice_amount" = choice_amount,
"ckey" = ckey,
"address" = address,
))
if(!query_polladd_question.Execute())
var/err = query_polladd_question.ErrorMsg()
qdel(query_polladd_question)
@@ -69,7 +76,14 @@
return
qdel(query_polladd_question)
var/pollid = 0
var/datum/DBQuery/query_get_id = SSdbcore.NewQuery("SELECT id FROM erro_poll_question WHERE question = '[question]' AND starttime = '[starttime]' AND endtime = '[endtime]' AND createdby_ckey = '[sql_ckey]' AND createdby_ip = '[address]'")
var/datum/DBQuery/query_get_id = SSdbcore.NewQuery("SELECT id FROM erro_poll_question WHERE question = :question AND starttime = :starttime AND endtime = :endtime AND createdby_ckey = :ckey AND createdby_ip = :address",
list(
"question" = question,
"starttime" = starttime,
"endtime" = endtime,
"ckey" = ckey,
"address" = address,
))
if(!query_get_id.Execute())
var/err = query_get_id.ErrorMsg()
qdel(query_get_id)
@@ -88,7 +102,6 @@
var/option = input("Write your option","Option") as message
if(!option)
return
option = sanitizeSQL(option)
var/percentagecalc
switch(alert("Calculate option results as percentage?",,"Yes","No","Cancel"))
if("Yes")
@@ -113,15 +126,19 @@
src << "Minimum rating value can't be more than maximum rating value"
return
descmin = input("Optional: Set description for minimum rating","Minimum rating description") as message
if(descmin)
descmin = sanitizeSQL(descmin)
descmid = input("Optional: Set description for median rating","Median rating description") as message
if(descmid)
descmid = sanitizeSQL(descmid)
descmax = input("Optional: Set description for maximum rating","Maximum rating description") as message
if(descmax)
descmax = sanitizeSQL(descmax)
var/datum/DBQuery/query_polladd_option = SSdbcore.NewQuery("INSERT INTO erro_poll_option (pollid, text, percentagecalc, minval, maxval, descmin, descmid, descmax) VALUES ('[pollid]', '[option]', '[percentagecalc]', '[minval]', '[maxval]', '[descmin]', '[descmid]', '[descmax]')")
var/datum/DBQuery/query_polladd_option = SSdbcore.NewQuery("INSERT INTO erro_poll_option (pollid, text, percentagecalc, minval, maxval, descmin, descmid, descmax) VALUES (:pollid, :option, :percentagecacl, :minval, :maxval, :descmin, :descmid, :descmax)",
list(
"pollid" = pollid,
"option" = option,
"percentagecalc" = percentagecalc,
"minval" = minval,
"maxval" = maxval,
"descmin" = descmin,
"descmid" = descmid,
"descmax" = descmax,
))
if(!query_polladd_option.Execute())
var/err = query_polladd_option.ErrorMsg()
log_sql("SQL ERROR adding new poll option to table. Error : \[[err]\]\n")

View File

@@ -80,7 +80,7 @@
if(!istext(adm_ckey) || !istext(new_rank))
return
var/datum/DBQuery/select_query = SSdbcore.NewQuery("SELECT id FROM erro_admin WHERE ckey = '[adm_ckey]'")
var/datum/DBQuery/select_query = SSdbcore.NewQuery("SELECT id FROM erro_admin WHERE ckey = :adm_ckey", list("adm_ckey" = "[adm_ckey]"))
if(!select_query.Execute())
message_admins("Error: [select_query.ErrorMsg()]")
log_sql("Error: [select_query.ErrorMsg()]")
@@ -94,14 +94,23 @@
admin_id = text2num(select_query.item[1])
qdel(select_query)
if(new_admin)
var/datum/DBQuery/insert_query = SSdbcore.NewQuery("INSERT INTO `erro_admin` (`id`, `ckey`, `rank`, `level`, `flags`) VALUES (null, '[adm_ckey]', '[new_rank]', -1, 0)")
var/datum/DBQuery/insert_query = SSdbcore.NewQuery("INSERT INTO `erro_admin` (`id`, `ckey`, `rank`, `level`, `flags`) VALUES (null, :adm_ckey, :new_rank, -1, 0)",
list(
"adm_ckey" = "[adm_ckey]",
"new_rank" = "[new_rank]",
))
if(!insert_query.Execute())
message_admins("Error: [insert_query.ErrorMsg()]")
log_sql("Error: [insert_query.ErrorMsg()]")
qdel(insert_query)
return
qdel(insert_query)
var/datum/DBQuery/log_query = SSdbcore.NewQuery("INSERT INTO [sqlfdbkdb].`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added new admin [adm_ckey] to rank [new_rank]');") // FIXME: [sqlfdbkdb] is the default name of the feedback DB.
var/datum/DBQuery/log_query = SSdbcore.NewQuery("INSERT INTO [sqlfdbkdb].`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , :ckey, :address, :text);",
list(
"ckey" = "[usr.ckey]",
"address" = "[usr.client.address]",
"text" = "Added new admin [adm_ckey] to rank [new_rank]",
)) // FIXME: [sqlfdbkdb] is the default name of the feedback DB.
if(!log_query.Execute())
message_admins("Error: [log_query.ErrorMsg()]")
log_sql("Error: [log_query.ErrorMsg()]")
@@ -111,14 +120,23 @@
to_chat(usr, "<span class='notice'>New admin added.</span>")
else
if(!isnull(admin_id) && isnum(admin_id))
var/datum/DBQuery/insert_query = SSdbcore.NewQuery("UPDATE `erro_admin` SET rank = '[new_rank]' WHERE id = [admin_id]")
var/datum/DBQuery/insert_query = SSdbcore.NewQuery("UPDATE `erro_admin` SET rank = :new_rank WHERE id = :admin_id",
list(
"new_rank" = "[new_rank]",
"admin_id" = "[admin_id]",
))
if(!insert_query.Execute())
message_admins("Error: [insert_query.ErrorMsg()]")
log_sql("Error: [insert_query.ErrorMsg()]")
qdel(insert_query)
return
qdel(insert_query)
var/datum/DBQuery/log_query = SSdbcore.NewQuery("INSERT INTO [sqlfdbkdb].`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Edited the rank of [adm_ckey] to [new_rank]');") // FIXME: [sqlfdbkdb] is the default name of the feedback DB.
var/datum/DBQuery/log_query = SSdbcore.NewQuery("INSERT INTO [sqlfdbkdb].`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , :ckey, :address, :text);",
list(
"ckey" = "[usr.ckey]",
"address" = "[usr.client.address]",
"text" = "Edited the rank of [adm_ckey] to [new_rank]"
)) // FIXME: [sqlfdbkdb] is the default name of the feedback DB.
if(!log_query.Execute())
message_admins("Error: [log_query.ErrorMsg()]")
log_sql("Error: [log_query.ErrorMsg()]")
@@ -156,7 +174,7 @@
if(!istext(adm_ckey) || !isnum(new_permission))
return
var/datum/DBQuery/select_query = SSdbcore.NewQuery("SELECT id, flags FROM erro_admin WHERE ckey = '[adm_ckey]'")
var/datum/DBQuery/select_query = SSdbcore.NewQuery("SELECT id, flags FROM erro_admin WHERE ckey = :adm_ckey", list("adm_ckey" = "[adm_ckey]"))
if(!select_query.Execute())
message_admins("Error: [select_query.ErrorMsg()]")
log_sql("Error: [select_query.ErrorMsg()]")
@@ -173,14 +191,23 @@
return
if(admin_rights & new_permission) //This admin already has this permission, so we are removing it.
var/datum/DBQuery/insert_query = SSdbcore.NewQuery("UPDATE `erro_admin` SET flags = [admin_rights & ~new_permission] WHERE id = [admin_id]")
var/datum/DBQuery/insert_query = SSdbcore.NewQuery("UPDATE `erro_admin` SET flags = :flags WHERE id = :admin_id",
list(
"flags" = (admin_rights & ~new_permission),
"admin_id" = admin_id
))
if(!insert_query.Execute())
message_admins("Error: [insert_query.ErrorMsg()]")
log_sql("Error: [insert_query.ErrorMsg()]")
qdel(insert_query)
return
qdel(insert_query)
var/datum/DBQuery/log_query = SSdbcore.NewQuery("INSERT INTO [sqlfdbkdb].`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Removed permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]');")
var/datum/DBQuery/log_query = SSdbcore.NewQuery("INSERT INTO [sqlfdbkdb].`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , :ckey', :address, :text);",
list(
"ckey" = "[usr.ckey]",
"address" = "[usr.client.address]",
"text" = "Removed permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]",
))
if(!log_query.Execute())
message_admins("Error: [log_query.ErrorMsg()]")
log_sql("Error: [log_query.ErrorMsg()]")
@@ -189,14 +216,23 @@
qdel(log_query)
to_chat(usr, "<span class='notice'>Permission removed.</span>")
else //This admin doesn't have this permission, so we are adding it.
var/datum/DBQuery/insert_query = SSdbcore.NewQuery("UPDATE `erro_admin` SET flags = '[admin_rights | new_permission]' WHERE id = [admin_id]")
var/datum/DBQuery/insert_query = SSdbcore.NewQuery("UPDATE `erro_admin` SET flags = :flags WHERE id = :admin_id",
list(
"flags" = (admin_rights | new_permission),
"admin_id" = admin_id,
))
if(!insert_query.Execute())
message_admins("Error: [insert_query.ErrorMsg()]")
log_sql("Error: [insert_query.ErrorMsg()]")
qdel(insert_query)
return
qdel(insert_query)
var/datum/DBQuery/log_query = SSdbcore.NewQuery("INSERT INTO [sqlfdbkdb].`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]')")
var/datum/DBQuery/log_query = SSdbcore.NewQuery("INSERT INTO [sqlfdbkdb].`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , :ckey, :address, :text)",
list(
"ckey" = "[usr.ckey]",
"address" = "[usr.client.address]",
"text" = "Added permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]",
))
if(!log_query.Execute())
message_admins("Error: [log_query.ErrorMsg()]")
log_sql("Error: [log_query.ErrorMsg()]")

View File

@@ -73,7 +73,7 @@ var/inactive_keys = "None<br>"
//if there are ckeys left over, check whether they have a database entry at all
if(ckeys_with_customitems.len)
for(var/cur_ckey in ckeys_with_customitems)
var/datum/DBQuery/query_inactive = SSdbcore.NewQuery("SELECT ckey FROM erro_player WHERE ckey = '[cur_ckey]'")
var/datum/DBQuery/query_inactive = SSdbcore.NewQuery("SELECT ckey FROM erro_player WHERE ckey = :ckey", list("ckey" = "[cur_ckey]"))
query_inactive.Execute()
if(!query_inactive.Execute())
log_sql("Error: [query_inactive.ErrorMsg()]")

View File

@@ -1,15 +1,10 @@
var/list/forbidden_varedit_object_types = list(
/datum/admins, //Admins editing their own admin-power object? Yup, sounds like a good idea.
/datum/blackbox, //Prevents people messing with feedback gathering
/datum/blackbox, //Prevents people messing with feedback gathering
/datum/feedback_variable, //Prevents people messing with feedback gathering
/datum/subsystem/dbcore/, // No messing with the database.
)
var/list/unviewable_varedit_object_types = list(
/datum/BSQL_Connection/,
/datum/BSQL_Operation/,
)
//Interface for editing a variable. It returns its new value. If edited_datum, it automatically changes the edited datum's value
//If called with just [user] argument, it allows you to create a value such as a string, a number, an empty list, a nearby object, etc...
//If called with [edited_datum] and [edited_variable], you gain the ability to get the variable's initial value.
@@ -29,9 +24,6 @@ var/list/unviewable_varedit_object_types = list(
if(!C.can_edit_var(edited_variable, edited_datum?.type))
return
if (is_type_in_list(edited_datum, unviewable_varedit_object_types) || BSQL_DEBUG_CONNECTION)
return
//Special case for "appearance", because appearance values can't be stored anywhere.
//It's impossible for this proc to return an appearance value, so just set it directly here
if((isimage(edited_datum) || isatom(edited_datum)) && edited_variable == "appearance")

View File

@@ -263,10 +263,8 @@
Joined = copytext(String, JoinPos, JoinPos+10) // Get the date in the YYYY-MM-DD format
account_joined = Joined
var/sql_ckey = sanitizeSQL(ckey)
var/age
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT id, datediff(Now(),firstseen) as age, datediff(Now(),accountjoined) as age2 FROM erro_player WHERE ckey = '[sql_ckey]'")
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT id, datediff(Now(),firstseen) as age, datediff(Now(),accountjoined) as age2 FROM erro_player WHERE ckey = :ckey", list("ckey" = ckey))
if(!query.Execute())
message_admins("Error: [query.ErrorMsg()]")
log_sql("Error: [query.ErrorMsg()]")
@@ -280,9 +278,7 @@
break
qdel(query)
var/sql_address = sanitizeSQL(address)
var/datum/DBQuery/query_ip = SSdbcore.NewQuery("SELECT distinct ckey FROM erro_connection_log WHERE ip = '[sql_address]'")
var/datum/DBQuery/query_ip = SSdbcore.NewQuery("SELECT distinct ckey FROM erro_connection_log WHERE ip = :address", list("address" = address))
if(!query_ip.Execute())
log_sql("Error: [query_ip.ErrorMsg()]")
qdel(query_ip)
@@ -292,9 +288,7 @@
related_accounts_ip += "[query_ip.item[1]], "
qdel(query_ip)
var/sql_computerid = sanitizeSQL(computer_id)
var/datum/DBQuery/query_cid = SSdbcore.NewQuery("SELECT distinct ckey FROM erro_connection_log WHERE computerid = '[sql_computerid]'")
var/datum/DBQuery/query_cid = SSdbcore.NewQuery("SELECT distinct ckey FROM erro_connection_log WHERE computerid = :computer_id", list("computer_id" = computer_id))
if(!query_cid.Execute())
log_sql("Error: [query_cid.ErrorMsg()]")
qdel(query_cid)
@@ -316,28 +310,46 @@
if(istype(holder))
admin_rank = holder.rank
var/sql_admin_rank = sanitizeSQL(admin_rank)
if(sql_id)
//Player already identified previously, we need to just update the 'lastseen', 'ip' and 'computer_id' variables
var/datum/DBQuery/query_update
if(isnum(age))
query_update = SSdbcore.NewQuery("UPDATE erro_player SET lastseen = Now(), ip = '[sql_address]', computerid = '[sql_computerid]', lastadminrank = '[sql_admin_rank]' WHERE id = [sql_id]")
query_update = SSdbcore.NewQuery("UPDATE erro_player SET lastseen = Now(), ip = :address, computerid = :computer_id, lastadminrank = :admin_rank WHERE id = :id",
list(
"address" = address,
"computer_id" = computer_id,
"admin_rank" = admin_rank,
"id" = sql_id,
))
else
query_update = SSdbcore.NewQuery("UPDATE erro_player SET lastseen = Now(), ip = '[sql_address]', computerid = '[sql_computerid]', lastadminrank = '[sql_admin_rank]', accountjoined = '[Joined]' WHERE id = [sql_id]")
query_update = SSdbcore.NewQuery("UPDATE erro_player SET lastseen = Now(),ip = :address, computerid = :computer_id, lastadminrank = :admin_rank, accountjoined = :joined WHERE id = :id",
list(
"address" = address,
"computer_id" = computer_id,
"admin_rank" = admin_rank,
"joined" = Joined,
"id" = sql_id,
))
query_update.Execute()
if(query_update.ErrorMsg())
WARNING("FINGERPRINT: [query_update.ErrorMsg()]")
qdel(query_update)
else
//New player!! Need to insert all the stuff
var/datum/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_player (id, ckey, firstseen, lastseen, ip, computerid, lastadminrank, accountjoined) VALUES (null, '[sql_ckey]', Now(), Now(), '[sql_address]', '[sql_computerid]', '[sql_admin_rank]', '[Joined]')")
var/datum/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_player (id, ckey, firstseen, lastseen, ip, computerid, lastadminrank, accountjoined) VALUES (null, :ckey, Now(), Now(), :address, :computer_id, :admin_rank, :joined)",
list(
"ckey" = ckey,
"address" = address,
"computer_id" = computer_id,
"admin_rank" = admin_rank,
"joined" = Joined,
))
query_insert.Execute()
if(query_insert.ErrorMsg())
WARNING("FINGERPRINT: [query_insert.ErrorMsg()]")
qdel(query_insert)
if(!isnum(age))
var/datum/DBQuery/query_age = SSdbcore.NewQuery("SELECT datediff(Now(),accountjoined) as age2 FROM erro_player WHERE ckey = '[sql_ckey]'")
var/datum/DBQuery/query_age = SSdbcore.NewQuery("SELECT datediff(Now(),accountjoined) as age2 FROM erro_player WHERE ckey = :ckey", list("ckey" = ckey))
if(!query_age.Execute())
WARNING("FINGERPRINT: [query_age.ErrorMsg()]")
while(query_age.NextRow())
@@ -353,8 +365,13 @@
// logging player access
var/server_address_port = "[world.internet_address]:[world.port]"
var/sql_server_address_port = sanitizeSQL(server_address_port)
var/datum/DBQuery/query_connection_log = SSdbcore.NewQuery("INSERT INTO `erro_connection_log`(`id`,`datetime`,`serverip`,`ckey`,`ip`,`computerid`) VALUES(null,Now(),'[sql_server_address_port]','[sql_ckey]','[sql_address]','[sql_computerid]');")
var/datum/DBQuery/query_connection_log = SSdbcore.NewQuery("INSERT INTO `erro_connection_log`(`id`,`datetime`,`serverip`,`ckey`,`ip`,`computerid`) VALUES(null,Now(),:server_address_port,:ckey,:address,:computer_id);",
list(
"ckey" = ckey,
"address" = address,
"computer_id" = computer_id,
"server_address_port" = server_address_port,
))
query_connection_log.Execute()
if(query_connection_log.ErrorMsg())

View File

@@ -20,7 +20,11 @@
*/
// Grab the info we want.
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT cuiPath, cuiPropAdjust, cuiJobMask FROM customitems WHERE cuiCKey='[sanitizeSQL(M.ckey)]' AND (cuiRealName='[sanitizeSQL(M.real_name)]' OR cuiRealName='*')")
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT cuiPath, cuiPropAdjust, cuiJobMask FROM customitems WHERE cuiCKey=:ckey AND (cuiRealName=:real_name OR cuiRealName='*')",
list(
"ckey" = "[M.ckey]",
"real_name" = "[M.real_name]"
))
if(!query.Execute())
message_admins("Error: [query.ErrorMsg()]")
log_sql("Error: [query.ErrorMsg()]")

View File

@@ -267,7 +267,7 @@
var/datum/cachedbook/target = getBookByID(href_list["del"]) // Sanitized in getBookByID
var/ans = alert(usr, "Are you sure you wish to delete \"[target.title]\", by [target.author]? This cannot be undone.", "Library System", "Yes", "No")
if(ans=="Yes")
var/datum/DBQuery/query = SSdbcore.NewQuery("DELETE FROM library WHERE id=[target.id]")
var/datum/DBQuery/query = SSdbcore.NewQuery("DELETE FROM library WHERE id=:id", list("id" = "[target.id]"))
var/response = query.Execute()
if(!response)
to_chat(usr, query.ErrorMsg())
@@ -286,7 +286,7 @@
var/tckey = ckey(href_list["delbyckey"])
var/ans = alert(usr,"Are you sure you wish to delete all books by [tckey]? This cannot be undone.", "Library System", "Yes", "No")
if(ans=="Yes")
var/datum/DBQuery/query = SSdbcore.NewQuery("DELETE FROM library WHERE ckey='[sanitizeSQL(tckey)]'")
var/datum/DBQuery/query = SSdbcore.NewQuery("DELETE FROM library WHERE ckey=:tckey", list("tckey" = tckey))
var/datum/DBQuery/response = query.Execute()
if(!response)
to_chat(usr, query.ErrorMsg())
@@ -397,11 +397,18 @@
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/datum/DBQuery/query = SSdbcore.NewQuery("INSERT INTO library (author, title, content, category, ckey) VALUES ('[sqlauthor]', '[sqltitle]', '[sqlcontent]', '[sqlcategory]', '[ckey(usr.key)]')")
var/sqltitle = scanner.cache.name
var/sqlauthor = scanner.cache.author
var/sqlcontent = scanner.cache.dat
var/sqlcategory = upload_category
var/datum/DBQuery/query = SSdbcore.NewQuery("INSERT INTO library (author, title, content, category, ckey) VALUES (:author, :title, :content, :category, :ckey)",
list(
"author" = sqlauthor,
"title" = sqltitle,
"content" = sqlcontent,
"category" = sqlcategory,
"ckey" = "[ckey(usr.key)]"
))
var/response = query.Execute()
if(!response)
to_chat(usr, query.ErrorMsg())

View File

@@ -54,11 +54,11 @@
var/list/where = list()
if(author || title || category)
if(author)
where.Add("author LIKE '%[sanitizeSQL(author)]%'")
where.Add("author LIKE '%[author]%'")
if(category)
where.Add("category = '[sanitizeSQL(category)]'")
where.Add("category = '[category]'")
if(title)
where.Add("title LIKE '%[sanitizeSQL(title)]%'")
where.Add("title LIKE '%[title]%'")
return " WHERE "+jointext(where," AND ")
return ""
@@ -91,7 +91,7 @@
var/sqlid = text2num(id)
if(!sqlid)
return
var/datum/DBQuery/query = SSdbcore.NewQuery("DELETE FROM library WHERE id=[sqlid]")
var/datum/DBQuery/query = SSdbcore.NewQuery("DELETE FROM library WHERE id=:id", list("id" = sqlid))
if(!query.Execute())
message_admins("Error: [query.ErrorMsg()]")
log_sql("Error: [query.ErrorMsg()]")
@@ -104,7 +104,7 @@
var/sqlid = text2num(id)
if(!sqlid)
return
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT id, author, title, category, ckey FROM library WHERE id=[sqlid]")
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT id, author, title, category, ckey FROM library WHERE :id", list("id" = sqlid))
if(!query.Execute())
message_admins("Error: [query.ErrorMsg()]")
log_sql("Error: [query.ErrorMsg()]")

View File

@@ -44,7 +44,7 @@
var/isadmin = 0
if(src.client && src.client.holder)
isadmin = 1
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT id FROM erro_poll_question WHERE [(isadmin ? "" : "adminonly = false AND")] hidden IS NULL AND Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM erro_poll_vote WHERE ckey = \"[ckey]\") AND id NOT IN (SELECT pollid FROM erro_poll_textreply WHERE ckey = \"[ckey]\")")
var/datum/DBQuery/query = SSdbcore.NewQuery("SELECT id FROM erro_poll_question WHERE [(isadmin ? "" : "adminonly = false AND")] hidden IS NULL AND Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM erro_poll_vote WHERE ckey = \":ckey\") AND id NOT IN (SELECT pollid FROM erro_poll_textreply WHERE ckey = :ckey)", list("ckey" = "\"[ckey]\""))
if(!query.Execute())
log_sql("Error fetching poll question: [query.ErrorMsg()]")
qdel(query)

View File

@@ -43,7 +43,7 @@
return
if(SSdbcore.Connect())
var/datum/DBQuery/select_query = SSdbcore.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM erro_poll_question WHERE id = [pollid]")
var/datum/DBQuery/select_query = SSdbcore.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM erro_poll_question WHERE id = :id", list("id" = pollid))
if(!select_query.Execute())
message_admins("Error: [select_query.ErrorMsg()]")
log_sql("Error: [select_query.ErrorMsg()]")
@@ -73,7 +73,7 @@
switch(polltype)
//Polls that have enumerated options
if("OPTION")
var/datum/DBQuery/voted_query = SSdbcore.NewQuery("SELECT optionid FROM erro_poll_vote WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
var/datum/DBQuery/voted_query = SSdbcore.NewQuery("SELECT optionid FROM erro_poll_vote WHERE pollid = :id AND ckey = :ckey", list("id" = pollid, "ckey" = "[usr.ckey]"))
if(!voted_query.Execute())
message_admins("Error: [voted_query.ErrorMsg()]")
log_sql("Error: [voted_query.ErrorMsg()]")
@@ -89,7 +89,7 @@
qdel(voted_query)
var/list/datum/polloption/options = list()
var/datum/DBQuery/options_query = SSdbcore.NewQuery("SELECT id, text FROM erro_poll_option WHERE pollid = [pollid]")
var/datum/DBQuery/options_query = SSdbcore.NewQuery("SELECT id, text FROM erro_poll_option WHERE pollid = :id", list("id" = pollid))
if(!options_query.Execute())
message_admins("Error: [options_query.ErrorMsg()]")
log_sql("Error: [options_query.ErrorMsg()]")
@@ -137,7 +137,7 @@
//Polls with a text input
if("TEXT")
var/datum/DBQuery/voted_query = SSdbcore.NewQuery("SELECT replytext FROM erro_poll_textreply WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
var/datum/DBQuery/voted_query = SSdbcore.NewQuery("SELECT replytext FROM erro_poll_textreply WHERE pollid = :id AND ckey = :ckey", list("id" = pollid, "ckey" = "[usr.ckey]"))
if(!voted_query.Execute())
message_admins("Error: [voted_query.ErrorMsg()]")
log_sql("Error: [voted_query.ErrorMsg()]")
@@ -183,7 +183,7 @@
//Polls with a text input
if("NUMVAL")
var/datum/DBQuery/voted_query = SSdbcore.NewQuery("SELECT o.text, v.rating FROM erro_poll_option o, erro_poll_vote v WHERE o.pollid = [pollid] AND v.ckey = '[usr.ckey]' AND o.id = v.optionid")
var/datum/DBQuery/voted_query = SSdbcore.NewQuery("SELECT o.text, v.rating FROM erro_poll_option o, erro_poll_vote v WHERE o.pollid = :id AND v.ckey = :ckey AND o.id = v.optionid", , list("id" = pollid, "ckey" = "[usr.ckey]"))
if(!voted_query.Execute())
message_admins("Error: [voted_query.ErrorMsg()]")
log_sql("Error: [voted_query.ErrorMsg()]")
@@ -216,7 +216,7 @@
var/minid = 999999
var/maxid = 0
var/datum/DBQuery/option_query = SSdbcore.NewQuery("SELECT id, text, minval, maxval, descmin, descmid, descmax FROM erro_poll_option WHERE pollid = [pollid]")
var/datum/DBQuery/option_query = SSdbcore.NewQuery("SELECT id, text, minval, maxval, descmin, descmid, descmax FROM erro_poll_option WHERE pollid = :id", list("id" = pollid))
if(!option_query.Execute())
message_admins("Error: [option_query.ErrorMsg()]")
log_sql("Error: [option_query.ErrorMsg()]")
@@ -265,7 +265,7 @@
qdel(option_query)
src << browse(output,"window=playerpoll;size=500x500")
if("MULTICHOICE")
var/datum/DBQuery/voted_query = SSdbcore.NewQuery("SELECT optionid FROM erro_poll_vote WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
var/datum/DBQuery/voted_query = SSdbcore.NewQuery("SELECT optionid FROM erro_poll_vote WHERE WHERE pollid = :id AND ckey = :ckey", list("id" = pollid, "ckey" = "[usr.ckey]"))
if(!voted_query.Execute())
message_admins("Error: [voted_query.ErrorMsg()]")
log_sql("Error: [voted_query.ErrorMsg()]")
@@ -283,7 +283,7 @@
var/maxoptionid = 0
var/minoptionid = 0
var/datum/DBQuery/options_query = SSdbcore.NewQuery("SELECT id, text FROM erro_poll_option WHERE pollid = [pollid]")
var/datum/DBQuery/options_query = SSdbcore.NewQuery("SELECT id, text FROM erro_poll_option WHERE pollid = :id", list("id" = pollid))
if(!options_query.Execute())
message_admins("Error: [options_query.ErrorMsg()]")
log_sql("Error: [options_query.ErrorMsg()]")
@@ -348,7 +348,7 @@
return
if(SSdbcore.Connect())
var/datum/DBQuery/select_query = SSdbcore.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM erro_poll_question WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime")
var/datum/DBQuery/select_query = SSdbcore.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM erro_poll_question WHERE id = :id AND Now() BETWEEN starttime AND endtime", list("id" = pollid))
if(!select_query.Execute())
message_admins("Error: [select_query.ErrorMsg()]")
log_sql("Error: [select_query.ErrorMsg()]")
@@ -371,7 +371,7 @@
to_chat(usr, "<span class='warning'>Poll is not valid.</span>")
return
var/datum/DBQuery/select_query2 = SSdbcore.NewQuery("SELECT id FROM erro_poll_option WHERE id = [optionid] AND pollid = [pollid]")
var/datum/DBQuery/select_query2 = SSdbcore.NewQuery("SELECT id FROM erro_poll_option WHERE id = :optionid AND pollid = :pollid", list("optionid" = optionid, "pollid" = pollid))
if(!select_query2.Execute())
message_admins("Error: [select_query.ErrorMsg()]")
log_sql("Error: [select_query.ErrorMsg()]")
@@ -391,7 +391,7 @@
var/alreadyvoted = 0
var/datum/DBQuery/voted_query = SSdbcore.NewQuery("SELECT id FROM erro_poll_vote WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
var/datum/DBQuery/voted_query = SSdbcore.NewQuery("SELECT id FROM erro_poll_vote WHERE pollid = :id AND ckey = :ckey", list("id" = pollid, "ckey" = "[usr.ckey]"))
if(!voted_query.Execute())
message_admins("Error: [voted_query.ErrorMsg()]")
log_sql("Error: [voted_query.ErrorMsg()]")
@@ -415,7 +415,14 @@
adminrank = usr.client.holder.rank
var/datum/DBQuery/insert_query = SSdbcore.NewQuery("INSERT INTO erro_poll_vote (id ,datetime ,pollid ,optionid ,ckey ,ip ,adminrank) VALUES (null, Now(), [pollid], [optionid], '[usr.ckey]', '[usr.client.address]', '[adminrank]')")
var/datum/DBQuery/insert_query = SSdbcore.NewQuery("INSERT INTO erro_poll_vote (id ,datetime ,pollid ,optionid ,ckey ,ip ,adminrank) VALUES (null, Now(), :pollid, :optionid, :ckey, :address, :rank)",
list(
"pollid" = pollid,
"optionid" = optionid,
"ckey" = "[usr.ckey]",
"address" = "[usr.client.address]",
"rank" = adminrank,
))
if(!insert_query.Execute())
message_admins("Error: [insert_query.ErrorMsg()]")
log_sql("Error: [insert_query.ErrorMsg()]")
@@ -435,7 +442,7 @@
return
if(SSdbcore.Connect())
var/datum/DBQuery/select_query = SSdbcore.NewQuery("SELECT starttime, endtime, question, polltype FROM erro_poll_question WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime")
var/datum/DBQuery/select_query = SSdbcore.NewQuery("SELECT starttime, endtime, question, polltype FROM erro_poll_question WHERE id = :id AND Now() BETWEEN starttime AND endtime", list("id" = pollid))
if(!select_query.Execute())
message_admins("Error: [select_query.ErrorMsg()]")
log_sql("Error: [select_query.ErrorMsg()]")
@@ -458,7 +465,7 @@
var/alreadyvoted = 0
var/datum/DBQuery/voted_query = SSdbcore.NewQuery("SELECT id FROM erro_poll_textreply WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
var/datum/DBQuery/voted_query = SSdbcore.NewQuery("SELECT id FROM erro_poll_textreply WHERE pollid = :id AND ckey = :ckey", list("id" = pollid, "ckey" = "[usr.ckey]"))
if(!voted_query.Execute())
message_admins("Error: [voted_query.ErrorMsg()]")
log_sql("Error: [voted_query.ErrorMsg()]")
@@ -483,13 +490,19 @@
replytext = replacetext(replytext, "\n", "%BR%")
var/text_pass = reject_bad_text(replytext,8000)
replytext = replacetext(replytext, "%BR%", "<BR>")
replytext = sanitizeSQL(replytext)
if(!text_pass)
to_chat(usr, "The text you entered was blank, contained illegal characters or was too long. Please correct the text and submit again.")
return
var/datum/DBQuery/insert_query = SSdbcore.NewQuery("INSERT INTO erro_poll_textreply (id ,datetime ,pollid ,ckey ,ip ,replytext ,adminrank) VALUES (null, Now(), [pollid], '[usr.ckey]', '[usr.client.address]', '[replytext]', '[adminrank]')")
var/datum/DBQuery/insert_query = SSdbcore.NewQuery("INSERT INTO erro_poll_textreply (id ,datetime ,pollid ,ckey ,ip ,replytext ,adminrank) VALUES (null, Now(), :pollid, :ckey, :address, :replytext, :rank)",
list(
"pollid" = pollid,
"ckey" = "[usr.ckey]",
"address" = "[usr.client.address]",
"replytext" = replytext,
"rank" = adminrank,
))
if(!insert_query.Execute())
message_admins("Error: [insert_query.ErrorMsg()]")
log_sql("Error: [insert_query.ErrorMsg()]")
@@ -510,7 +523,7 @@
SSdbcore.Connect()
if(SSdbcore.IsConnected())
var/datum/DBQuery/select_query = SSdbcore.NewQuery("SELECT starttime, endtime, question, polltype FROM erro_poll_question WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime")
var/datum/DBQuery/select_query = SSdbcore.NewQuery("SELECT starttime, endtime, question, polltype FROM erro_poll_question WHERE id = :id AND Now() BETWEEN starttime AND endtime", list("id" = pollid))
if(!select_query.Execute())
message_admins("Error: [select_query.ErrorMsg()]")
log_sql("Error: [select_query.ErrorMsg()]")
@@ -531,7 +544,7 @@
to_chat(usr, "<span class='warning'>Poll is not valid.</span>")
return
var/datum/DBQuery/select_query2 = SSdbcore.NewQuery("SELECT id FROM erro_poll_option WHERE id = [optionid] AND pollid = [pollid]")
var/datum/DBQuery/select_query2 = SSdbcore.NewQuery("SELECT id FROM erro_poll_option WHERE id = :optionid AND pollid = :pollid", list("optionid" = optionid, "pollid" = pollid))
if(!select_query2.Execute())
message_admins("Error: [select_query.ErrorMsg()]")
log_sql("Error: [select_query.ErrorMsg()]")
@@ -551,7 +564,7 @@
var/alreadyvoted = 0
var/datum/DBQuery/voted_query = SSdbcore.NewQuery("SELECT id FROM erro_poll_vote WHERE optionid = [optionid] AND ckey = '[usr.ckey]'")
var/datum/DBQuery/voted_query = SSdbcore.NewQuery("SELECT id FROM erro_poll_vote WHERE optionid = :optionid AND ckey = :ckey", list("optionid" = optionid, "ckey" = "[usr.ckey]"))
if(!voted_query.Execute())
message_admins("Error: [voted_query.ErrorMsg()]")
log_sql("Error: [voted_query.ErrorMsg()]")
@@ -573,7 +586,15 @@
adminrank = usr.client.holder.rank
var/datum/DBQuery/insert_query = SSdbcore.NewQuery("INSERT INTO erro_poll_vote (id ,datetime ,pollid ,optionid ,ckey ,ip ,adminrank, rating) VALUES (null, Now(), [pollid], [optionid], '[usr.ckey]', '[usr.client.address]', '[adminrank]', [(isnull(rating)) ? "null" : rating])")
var/datum/DBQuery/insert_query = SSdbcore.NewQuery("INSERT INTO erro_poll_vote (id ,datetime ,pollid ,optionid ,ckey ,ip ,adminrank, rating) VALUES (null, Now(), :pollid, :optionid, :ckey, :address, :rank, :rating)",
list(
"pollid" = pollid,
"optionid" = optionid,
"ckey" = "[usr.ckey]",
"address" = "[usr.client.address]",
"rank" = adminrank,
"rating" = " [(isnull(rating)) ? "null" : rating]"
))
if(!insert_query.Execute())
message_admins("Error: [insert_query.ErrorMsg()]")
log_sql("Error: [insert_query.ErrorMsg()]")

5
data/ban_unban_log.txt Normal file
View File

@@ -0,0 +1,5 @@
Shifty_rail/(Shifty_rail) temp-jobbanned AnonSpess/(AnonSpess) from Captain for 1440 minutes. reason: AAAAAh
Shifty_rail/(Shifty_rail) temp-jobbanned AnonSpess/(AnonSpess) from Head of Security for 1440 minutes. reason: AAAAAh
Shifty_rail/(Shifty_rail) temp-jobbanned AnonSpess/(AnonSpess) from Chief Engineer for 1440 minutes. reason: AAAAAh
Shifty_rail/(Shifty_rail) temp-jobbanned AnonSpess/(AnonSpess) from Research Director for 1440 minutes. reason: AAAAAh
Shifty_rail/(Shifty_rail) temp-jobbanned AnonSpess/(AnonSpess) from Chief Medical Officer for 1440 minutes. reason: AAAAAh

Binary file not shown.

BIN
rust_g.dll Normal file

Binary file not shown.

View File

@@ -21,7 +21,6 @@
#include "__DEFINES\atom_locking_and_control.dm"
#include "__DEFINES\atoms.dm"
#include "__DEFINES\bots.dm"
#include "__DEFINES\BSQL.dm"
#include "__DEFINES\cameranet.dm"
#include "__DEFINES\carbon_defines.dm"
#include "__DEFINES\clothing.dm"
@@ -58,6 +57,7 @@
#include "__DEFINES\reagents.dm"
#include "__DEFINES\research_levels.dm"
#include "__DEFINES\role_datums_defines.dm"
#include "__DEFINES\rust_g.dm"
#include "__DEFINES\security.dm"
#include "__DEFINES\setup.dm"
#include "__DEFINES\silicon.dm"
@@ -1220,7 +1220,6 @@
#include "code\game\verbs\who.dm"
#include "code\js\byjax.dm"
#include "code\js\menus.dm"
#include "code\libs\BSQL\includes.dm"
#include "code\libs\Get Flat Icon\Get Flat Icon.dm"
#include "code\libs\IconProcs\IconProcs.dm"
#include "code\libs\s_html\hexadecimal.dm"