diff --git a/SQL/aurora_schema.sql b/SQL/aurora_schema.sql index b88f9105..a30eeb7a 100644 --- a/SQL/aurora_schema.sql +++ b/SQL/aurora_schema.sql @@ -134,3 +134,26 @@ CREATE TABLE `ss13_connection_log` ( `computerid` VARCHAR(32) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +-- ------------------------------ +-- SQL based whitelist index +-- tgstation.ss13_whitelist_statuses +-- ------------------------------ +CREATE TABLE `ss13_whitelist_statuses` ( + `flag` INT(10) UNSIGNED NOT NULL, + `status_name` VARCHAR(32) NOT NULL, + PRIMARY KEY (`flag`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +-- ------------------------------ +-- SQL based whitelist modification log +-- tgstation.ss13_whitelist_log +-- ------------------------------ +CREATE TABLE `ss13_whitelist_log` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `datetime` DATETIME NOT NULL, + `user` VARCHAR(32) NOT NULL, + `action_method` VARCHAR(32) NOT NULL DEFAULT 'Game Server', + `action` VARCHAR(32) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; diff --git a/SQL/feedback_schema.sql b/SQL/feedback_schema.sql index bb2baf83..4208a579 100644 --- a/SQL/feedback_schema.sql +++ b/SQL/feedback_schema.sql @@ -61,6 +61,7 @@ CREATE TABLE `ss13_player` ( `ip` varchar(18) NOT NULL, `computerid` varchar(32) NOT NULL, `lastadminrank` varchar(32) NOT NULL DEFAULT 'Player', + `whitelist_status` INT(11) UNSIGNED NOT NULL DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `ckey` (`ckey`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ; @@ -117,4 +118,4 @@ CREATE TABLE `ss13_privacy` ( `ckey` varchar(32) NOT NULL, `option` varchar(128) NOT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ; \ No newline at end of file +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ; diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 4080c325..1a60f756 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -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]'") diff --git a/code/game/jobs/whitelist.dm b/code/game/jobs/whitelist.dm index f9bb469f..599517ce 100644 --- a/code/game/jobs/whitelist.dm +++ b/code/game/jobs/whitelist.dm @@ -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 diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm index cdd394f4..f026c743 100644 --- a/code/modules/client/client defines.dm +++ b/code/modules/client/client defines.dm @@ -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. diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index f461943b..135262c9 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -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