Merge pull request #811 from skull132/database-updates

Database updates
This commit is contained in:
skull132
2015-12-30 19:15:58 +02:00
5 changed files with 204 additions and 93 deletions
+5
View File
@@ -88,6 +88,8 @@
var/aurorawikiurl
var/githuburl
var/whitelists_on_sql = 0 //Changes how whitelists are handled. SQL connection required to run this!
//Alert level description
var/alert_desc_green = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced."
var/alert_desc_blue_upto = "The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible, random searches are permitted."
@@ -528,6 +530,9 @@
if("topic_safe_address")
topic_safe_address = value
if ("whitelists_on_sql")
config.whitelists_on_sql = 1
else
log_misc("Unknown setting in configuration: '[name]'")
+133 -63
View File
@@ -48,45 +48,45 @@ DBConnection
var/server = ""
var/port = 3306
DBConnection/New(dbi_handler,username,password_handler,cursor_handler)
src.dbi = dbi_handler
src.user = username
src.password = password_handler
src.default_cursor = cursor_handler
DBConnection/New(dbi_handler, username, password_handler, cursor_handler)
dbi = dbi_handler
user = username
password = password_handler
default_cursor = cursor_handler
_db_con = _dm_db_new_con()
DBConnection/proc/Connect(dbi_handler=src.dbi,user_handler=src.user,password_handler=src.password,cursor_handler)
if(!sqllogging)
DBConnection/proc/Connect(dbi_handler = dbi, user_handler = user, password_handler = password, cursor_handler)
if (!sqllogging)
return 0
if(!src) return 0
cursor_handler = src.default_cursor
if(!cursor_handler) cursor_handler = Default_Cursor
return _dm_db_connect(_db_con,dbi_handler,user_handler,password_handler,cursor_handler,null)
if (!src)
return 0
cursor_handler = default_cursor
if (!cursor_handler)
cursor_handler = Default_Cursor
return _dm_db_connect(_db_con,dbi_handler, user_handler, password_handler, cursor_handler, null)
DBConnection/proc/Disconnect() return _dm_db_close(_db_con)
DBConnection/proc/Disconnect()
return _dm_db_close(_db_con)
DBConnection/proc/IsConnected()
if(!sqllogging) return 0
if(!sqllogging)
return 0
var/success = _dm_db_is_connected(_db_con)
return success
DBConnection/proc/Quote(str) return _dm_db_quote(_db_con,str)
DBConnection/proc/Quote(str)
return _dm_db_quote(_db_con,str)
DBConnection/proc/ErrorMsg()
return _dm_db_error_msg(_db_con)
DBConnection/proc/ErrorMsg() return _dm_db_error_msg(_db_con)
DBConnection/proc/SelectDB(database_name,dbi)
if(IsConnected()) Disconnect()
//return Connect("[dbi?"[dbi]":"dbi:mysql:[database_name]:[DB_SERVER]:[DB_PORT]"]",user,password)
return Connect("[dbi?"[dbi]":"dbi:mysql:[database_name]:[sqladdress]:[sqlport]"]",user,password)
DBConnection/proc/NewQuery(sql_query,cursor_handler=src.default_cursor) return new/DBQuery(sql_query,src,cursor_handler)
DBQuery/New(sql_query,DBConnection/connection_handler,cursor_handler)
if(sql_query) src.sql = sql_query
if(connection_handler) src.db_connection = connection_handler
if(cursor_handler) src.default_cursor = cursor_handler
_db_query = _dm_db_new_query()
return ..()
return Connect("[dbi?"[dbi]":"dbi:mysql:[database_name]:[sqladdress]:[sqlport]"]", user, password)
DBConnection/proc/NewQuery(sql_query, cursor_handler = default_cursor)
return new/DBQuery(sql_query, src, cursor_handler)
DBQuery
var/sql // The sql query being executed.
@@ -98,34 +98,53 @@ DBQuery
var/DBConnection/db_connection
var/_db_query
DBQuery/proc/Connect(DBConnection/connection_handler) src.db_connection = connection_handler
DBQuery/New(var/sql_query, var/DBConnection/connection_handler, var/cursor_handler)
if (sql_query)
sql = sql_query
if (connection_handler)
db_connection = connection_handler
if (cursor_handler)
default_cursor = cursor_handler
_db_query = _dm_db_new_query()
return ..()
DBQuery/proc/Execute(sql_query=src.sql,cursor_handler=default_cursor)
DBQuery/proc/Connect(DBConnection/connection_handler)
db_connection = connection_handler
DBQuery/proc/Execute(var/list/argumentList = null, var/passNotFound = 0, sql_query = sql, cursor_handler = default_cursor)
Close()
return _dm_db_execute(_db_query,sql_query,db_connection._db_con,cursor_handler,null)
DBQuery/proc/NextRow() return _dm_db_next_row(_db_query,item,conversions)
if (argumentList)
parseArguments(argumentList, passNotFound)
DBQuery/proc/RowsAffected() return _dm_db_rows_affected(_db_query)
return _dm_db_execute(_db_query, sql_query, db_connection._db_con, cursor_handler, null)
DBQuery/proc/RowCount() return _dm_db_row_count(_db_query)
DBQuery/proc/NextRow()
return _dm_db_next_row(_db_query,item,conversions)
DBQuery/proc/ErrorMsg() return _dm_db_error_msg(_db_query)
DBQuery/proc/RowsAffected()
return _dm_db_rows_affected(_db_query)
DBQuery/proc/RowCount()
return _dm_db_row_count(_db_query)
DBQuery/proc/ErrorMsg()
return _dm_db_error_msg(_db_query)
DBQuery/proc/Columns()
if(!columns)
if (!columns)
columns = _dm_db_columns(_db_query,/DBColumn)
return columns
DBQuery/proc/GetRowData()
var/list/columns = Columns()
var/list/results
if(columns.len)
if (columns.len)
results = list()
for(var/C in columns)
results+=C
for (var/C in columns)
results += C
var/DBColumn/cur_col = columns[C]
results[C] = src.item[(cur_col.position+1)]
results[C] = item[(cur_col.position+1)]
return results
DBQuery/proc/Close()
@@ -138,11 +157,49 @@ DBQuery/proc/Quote(str)
return db_connection.Quote(str)
DBQuery/proc/SetConversion(column,conversion)
if(istext(column)) column = columns.Find(column)
if(!conversions) conversions = new/list(column)
else if(conversions.len < column) conversions.len = column
if (istext(column))
column = columns.Find(column)
if (!conversions)
conversions = new/list(column)
else if (conversions.len < column)
conversions.len = column
conversions[column] = conversion
/* Works similarly to the PDO object's Execute() method in PHP.
* Insert a list of keys/values, it searches the SQL syntax for the keys,
* and replaces them with sanitized versions of the values.
* Can be called independently, or through dbcon.Execute(), where the list would be the first argument.
* passNotFound controls whether or not is passes keys not found in the SQL query.
* Keys are /case-sensitive/, be careful!
* Returns FALSE upon failure, TRUE otherwise, so it can be used in checks and so on.
* - Skull132
*/
DBQuery/proc/parseArguments(var/list/argumentList, var/passNotFound = 0)
if (!sql || !argumentList || !argumentList.len)
return 0
for (var/placeholder in argumentList)
if (!findtextEx(sql, placeholder))
if (passNotFound)
continue
else
return 0
var/argument = argumentList[placeholder]
if (isnull(argument))
argument = "NULL"
else if (istext(argument))
argument = dbcon.Quote(argument)
else if (isnum(argument))
argument = "'[argument]'"
else
return 0
sql = replacetextEx(sql, placeholder, argument)
return 1
DBColumn
var/name
@@ -153,32 +210,45 @@ DBColumn
var/length
var/max_length
DBColumn/New(name_handler,table_handler,position_handler,type_handler,flag_handler,length_handler,max_length_handler)
src.name = name_handler
src.table = table_handler
src.position = position_handler
src.sql_type = type_handler
src.flags = flag_handler
src.length = length_handler
src.max_length = max_length_handler
DBColumn/New(name_handler, table_handler, position_handler, type_handler, flag_handler, length_handler, max_length_handler)
name = name_handler
table = table_handler
position = position_handler
sql_type = type_handler
flags = flag_handler
length = length_handler
max_length = max_length_handler
return ..()
DBColumn/proc/SqlTypeName(type_handler=src.sql_type)
switch(type_handler)
if(TINYINT) return "TINYINT"
if(SMALLINT) return "SMALLINT"
if(MEDIUMINT) return "MEDIUMINT"
if(INTEGER) return "INTEGER"
if(BIGINT) return "BIGINT"
if(FLOAT) return "FLOAT"
if(DOUBLE) return "DOUBLE"
if(DATE) return "DATE"
if(DATETIME) return "DATETIME"
if(TIMESTAMP) return "TIMESTAMP"
if(TIME) return "TIME"
if(STRING) return "STRING"
if(BLOB) return "BLOB"
DBColumn/proc/SqlTypeName(type_handler = sql_type)
switch (type_handler)
if (TINYINT)
return "TINYINT"
if (SMALLINT)
return "SMALLINT"
if (MEDIUMINT)
return "MEDIUMINT"
if (INTEGER)
return "INTEGER"
if (BIGINT)
return "BIGINT"
if (FLOAT)
return "FLOAT"
if (DOUBLE)
return "DOUBLE"
if (DATE)
return "DATE"
if (DATETIME)
return "DATETIME"
if (TIMESTAMP)
return "TIMESTAMP"
if (TIME)
return "TIME"
if (STRING)
return "STRING"
if (BLOB)
return "BLOB"
#undef Default_Cursor
+56 -15
View File
@@ -3,18 +3,36 @@
var/list/whitelist = list()
/hook/startup/proc/loadWhitelist()
if(config.usewhitelist)
if (config.usewhitelist)
load_whitelist()
return 1
/proc/load_whitelist()
whitelist = file2list(WHITELISTFILE)
if(!whitelist.len) whitelist = null
if (config.whitelists_on_sql)
establish_db_connection()
if (!dbcon.IsConnected())
//Continue with the old code if it fails. Stop and return if it succeeds.
log_misc("Database connection failed. Reverting to legacy system.")
config.whitelists_on_sql = 0
else
return
whitelist = file2list(WHITELISTFILE)
if (!whitelist.len)
whitelist = null
/proc/check_whitelist(mob/M)
if (config.whitelists_on_sql)
var/head_of_staff_whitelist = 1
if (M.client && M.client.whitelist_status)
return (M.client.whitelist_status & head_of_staff_whitelist)
/proc/check_whitelist(mob/M /*, var/rank*/)
if(!whitelist)
return 0
return ("[M.ckey]" in whitelist)
else
if (!whitelist)
return 0
return ("[M.ckey]" in whitelist)
/var/list/alien_whitelist = list()
@@ -24,6 +42,22 @@ var/list/whitelist = list()
return 1
/proc/load_alienwhitelist()
if (config.whitelists_on_sql)
establish_db_connection()
if (!dbcon.IsConnected())
log_misc("Database connection failed. Reverting to legacy system.")
config.whitelists_on_sql = 0
else
var/DBQuery/query = dbcon.NewQuery("SELECT status_name, flag FROM ss13_whitelist_statuses")
query.Execute()
for (query.NextRow())
if (query.item[1] in whitelisted_species)
whitelisted_species[query.item[1]] = text2num(query.item[2])
return
var/text = file2text("config/alienwhitelist.txt")
if (!text)
log_misc("Failed to load config/alienwhitelist.txt")
@@ -32,19 +66,26 @@ var/list/whitelist = list()
//todo: admin aliens
/proc/is_alien_whitelisted(mob/M, var/species)
if(!config.usealienwhitelist)
if (!config.usealienwhitelist)
return 1
if(species == "human" || species == "Human")
return 1
// if(check_rights(R_ADMIN, 0))
// return 1
if(!alien_whitelist)
if (!M || !species)
return 0
if(M && species)
if (species == "human" || species == "Human")
return 1
if (config.whitelists_on_sql)
if (M.client && M.client.whitelist_status)
return (M.client.whitelist_status & whitelisted_species[species])
else
if (!alien_whitelist)
return 0
for (var/s in alien_whitelist)
if(findtext(s,"[M.ckey] - [species]"))
if (findtext(s, "[M.ckey] - [species]"))
return 1
if(findtext(s,"[M.ckey] - All"))
if (findtext(s, "[M.ckey] - All"))
return 1
return 0
+1
View File
@@ -46,5 +46,6 @@
var/player_age = "Requires database" //So admins know why it isn't working - Used to determine how old the account is - in days.
var/related_accounts_ip = "Requires database" //So admins know why it isn't working - Used to determine what other accounts previously logged in from this ip
var/related_accounts_cid = "Requires database" //So admins know why it isn't working - Used to determine what other accounts previously logged in from this computer id
var/whitelist_status = 0 //Used to determine what whitelists the player has access to. Bitflag field.
preload_rsc = 0 // This is 0 so we can set it to an URL once the player logs in and have them download the resources from a different server.
+9 -15
View File
@@ -225,15 +225,14 @@
if(!dbcon.IsConnected())
return
var/sql_ckey = sql_sanitize_text(src.ckey)
var/DBQuery/query = dbcon.NewQuery("SELECT id, datediff(Now(),firstseen) as age FROM ss13_player WHERE ckey = '[sql_ckey]'")
query.Execute()
var/DBQuery/query = dbcon.NewQuery("SELECT id, datediff(Now(),firstseen) as age, whitelist_status FROM ss13_player WHERE ckey = :ckey")
query.Execute(list(":ckey" = ckey))
var/sql_id = 0
player_age = 0 // New players won't have an entry so knowing we have a connection we set this to zero to be updated if their is a record.
while(query.NextRow())
sql_id = query.item[1]
player_age = text2num(query.item[2])
whitelist_status = text2num(query.item[3])
break
var/DBQuery/query_ip = dbcon.NewQuery("SELECT ckey FROM ss13_player WHERE ip = '[address]'")
@@ -261,24 +260,19 @@
if(src.holder)
admin_rank = src.holder.rank
var/sql_ip = sql_sanitize_text(src.address)
var/sql_computerid = sql_sanitize_text(src.computer_id)
var/sql_admin_rank = sql_sanitize_text(admin_rank)
if(sql_id)
//Player already identified previously, we need to just update the 'lastseen', 'ip' and 'computer_id' variables
var/DBQuery/query_update = dbcon.NewQuery("UPDATE ss13_player SET lastseen = Now(), ip = '[sql_ip]', computerid = '[sql_computerid]', lastadminrank = '[sql_admin_rank]' WHERE id = [sql_id]")
query_update.Execute()
var/DBQuery/query_update = dbcon.NewQuery("UPDATE ss13_player SET lastseen = Now(), ip = :ip, computerid = :computer_id, lastadminrank = :admin_rank WHERE id = :id")
query_update.Execute(list(":ip" = address, ":computer_id" = computer_id, ":admin_rank" = admin_rank, ":id" = sql_id))
else
//New player!! Need to insert all the stuff
var/DBQuery/query_insert = dbcon.NewQuery("INSERT INTO ss13_player (id, ckey, firstseen, lastseen, ip, computerid, lastadminrank) VALUES (null, '[sql_ckey]', Now(), Now(), '[sql_ip]', '[sql_computerid]', '[sql_admin_rank]')")
query_insert.Execute()
var/DBQuery/query_insert = dbcon.NewQuery("INSERT INTO ss13_player (id, ckey, firstseen, lastseen, ip, computerid, lastadminrank) VALUES (null, :ckey, Now(), Now(), :ip, :computer_id, :admin_rank)")
query_insert.Execute(list(":ckey" = ckey, ":ip" = address, ":computer_id" = computer_id, ":admin_rank" = admin_rank))
//Logging player access
var/serverip = "[world.internet_address]:[world.port]"
var/DBQuery/query_accesslog = dbcon.NewQuery("INSERT INTO `ss13_connection_log`(`id`,`datetime`,`serverip`,`ckey`,`ip`,`computerid`) VALUES(null,Now(),'[serverip]','[sql_ckey]','[sql_ip]','[sql_computerid]');")
query_accesslog.Execute()
var/DBQuery/query_accesslog = dbcon.NewQuery("INSERT INTO `ss13_connection_log`(`id`, `datetime`, `serverip`, `ckey`, `ip`, `computerid`) VALUES(null, Now(), :server_ip, :ckey, :ip, :computer_id);")
query_accesslog.Execute(list(":server_ip" = serverip, ":ckey" = ckey, ":ip" = address, ":computer_id" = computer_id))
#undef TOPIC_SPAM_DELAY