From 315fbb415fbbf599433fe380af84e106518ff4b9 Mon Sep 17 00:00:00 2001 From: Selis <12716288+ItsSelis@users.noreply.github.com> Date: Sun, 28 Sep 2025 10:28:55 +0200 Subject: [PATCH] Load alien/job whitelists from database, if enabled (#17952) * Load alien/job whitelists from database, if enabled * SQL Template for Table * Fixes * Commands * . * . * fix * cannot be a list * . * . * embed * . * . * query test * query test * query test * . * fix --- SQL/feedback_schema.sql | 12 +- code/controllers/subsystems/dbcore.dm | 5 +- code/game/jobs/whitelist.dm | 212 ++++++++++++++++--- code/game/jobs/whitelist_vr.dm | 30 --- code/game/world.dm | 9 + code/modules/admin/holder2.dm | 1 + code/modules/tgs_commands/vorestation.dm | 167 ++++++++++++++- config/.gitignore | 2 - config/alienwhitelist.txt | 250 ----------------------- config/jobwhitelist.txt | 37 ---- tools/convert_whitelists_to_sql.py | 49 +++++ vorestation.dme | 1 - 12 files changed, 421 insertions(+), 354 deletions(-) delete mode 100644 code/game/jobs/whitelist_vr.dm delete mode 100644 config/alienwhitelist.txt delete mode 100644 config/jobwhitelist.txt create mode 100644 tools/convert_whitelists_to_sql.py diff --git a/SQL/feedback_schema.sql b/SQL/feedback_schema.sql index 6c8c4bfa1f..a0dbdd074f 100644 --- a/SQL/feedback_schema.sql +++ b/SQL/feedback_schema.sql @@ -295,7 +295,7 @@ LANGUAGE SQL NOT DETERMINISTIC CONTAINS SQL SQL SECURITY INVOKER -COMMENT 'Inserts a new row into \'chatlogs_rounds\' and deletes the oldest entry, if the ckey already has 10 round id\'s stored.' +COMMENT 'Inserts a new row into \'chatlogs_rounds\' and deletes the oldest entry, if the ckey already has 10 round ids stored.' BEGIN INSERT IGNORE INTO chatlogs_rounds(round_id, ckey) VALUES (p_round_id, p_ckey); @@ -306,3 +306,13 @@ END IF; END DELIMITER ; + +-- Table structure for table `whitelist` +CREATE TABLE `whitelist` ( + `id` INT(11) NOT NULL AUTO_INCREMENT, + `ckey` VARCHAR(45) NOT NULL COLLATE 'utf8mb4_uca1400_ai_ci', + `kind` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_uca1400_ai_ci', + `entry` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_uca1400_ai_ci', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `ckey_kind_entry` (`ckey`, `kind`, `entry`) USING BTREE +) ENGINE=InnoDB COLLATE='utf8mb4_uca1400_ai_ci'; diff --git a/code/controllers/subsystems/dbcore.dm b/code/controllers/subsystems/dbcore.dm index aaafbb0282..ec542a63d8 100644 --- a/code/controllers/subsystems/dbcore.dm +++ b/code/controllers/subsystems/dbcore.dm @@ -526,11 +526,10 @@ Ignore_errors instructes mysql to continue inserting rows if some of them have e Close() status = DB_QUERY_STARTED if(async) - /*if(!MC_RUNNING(SSdbcore.init_stage)) + if(!MC_RUNNING(SSdbcore.init_stage)) SSdbcore.run_query_sync(src) else - SSdbcore.queue_query(src)*/ - SSdbcore.run_query_sync(src) + SSdbcore.queue_query(src) sync() else var/job_result_str = rustg_sql_query_blocking(connection, sql, json_encode(arguments)) diff --git a/code/game/jobs/whitelist.dm b/code/game/jobs/whitelist.dm index 21b636021f..610c1febe4 100644 --- a/code/game/jobs/whitelist.dm +++ b/code/game/jobs/whitelist.dm @@ -1,11 +1,68 @@ #define WHITELISTFILE "data/whitelist.txt" GLOBAL_LIST_EMPTY(whitelist) +GLOBAL_LIST_EMPTY(job_whitelist) +GLOBAL_LIST_EMPTY(alien_whitelist) -/hook/startup/proc/loadWhitelist() - if(CONFIG_GET(flag/usewhitelist)) - load_whitelist() - return 1 +// Not yet implemented +//ADMIN_VERB(open_whitelist_editor, R_ADMIN, "Open Whitelist Editor", "Opens the editor for alien- and jobwhitelists.", ADMIN_CATEGORY_GAME) +// if(user.holder) +// user.holder.whitelist_editor = new /datum/whitelist_editor() +// user.holder.whitelist_editor.tgui_interact(user.mob) + +/datum/whitelist_editor + +/datum/whitelist_editor/tgui_state(mob/user) + return ADMIN_STATE(R_ADMIN) + +/datum/whitelist_editor/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "WhitelistEdit") + ui.open() + +/datum/whitelist_editor/tgui_data(mob/user) + var/list/data = list() + + data["alienwhitelist"] = GLOB.alien_whitelist + data["jobwhitelist"] = GLOB.job_whitelist + + return data + +/datum/whitelist_editor/tgui_static_data(mob/user) + var/list/data = list() + + data["species_requiring_whitelist"] = GLOB.whitelisted_species + + return data + +/datum/whitelist_editor/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + . = ..() + if(.) + return + + switch(action) + if("add_alienwhitelist") + if (!CONFIG_GET(flag/sql_enabled)) + to_chat(ui.user, "This action is not supported while the database is disabled. Please edit [global.config.directory]/alienwhitelist.txt.") + return + // TODO: Add to database + . = TRUE + + if("remove_alienwhitelist") + if (!CONFIG_GET(flag/sql_enabled)) + to_chat(ui.user, "This action is not supported while the database is disabled. Please edit [global.config.directory]/alienwhitelist.txt.") + return + // TODO: Remove from database + . = TRUE + + if("reload_alienwhitelist") + reload_alienwhitelist() + . = TRUE + + if("reload_jobwhitelist") + reload_jobwhitelist() + . = TRUE /proc/load_whitelist() GLOB.whitelist = world.file2list(WHITELISTFILE) @@ -16,33 +73,58 @@ GLOBAL_LIST_EMPTY(whitelist) return 0 return ("[M.ckey]" in GLOB.whitelist) -GLOBAL_LIST_EMPTY(alien_whitelist) +/proc/load_alienwhitelist(dbfail = FALSE) + if (CONFIG_GET(flag/sql_enabled) && !dbfail) + var/datum/db_query/query_load_alienwhistelist = SSdbcore.NewQuery("SELECT ckey, entry FROM [format_table_name("whitelist")] WHERE kind = 'species'") + if(!query_load_alienwhistelist.Execute()) + message_admins("Error loading alienwhitelist from database. Loading from [global.config.directory]/alienwhitelist.txt.") + log_sql("Error loading alienwhitelist from database. Loading from [global.config.directory]/alienwhitelist.txt.") + load_alienwhitelist(dbfail = TRUE) + return + else + while(query_load_alienwhistelist.NextRow()) + var/ckey = query_load_alienwhistelist.item[1] + var/entry = query_load_alienwhistelist.item[2] -/hook/startup/proc/loadAlienWhitelist() - if(CONFIG_GET(flag/usealienwhitelist)) - load_alienwhitelist() - return 1 - -/proc/load_alienwhitelist() - var/text = file2text("config/alienwhitelist.txt") - if (!text) - log_world("Failed to load config/alienwhitelist.txt") + var/list/our_whitelists = GLOB.alien_whitelist[ckey] + if(!our_whitelists) // Guess this is their first/only whitelist entry + our_whitelists = list() + GLOB.alien_whitelist[ckey] = our_whitelists + our_whitelists += entry + qdel(query_load_alienwhistelist) else - var/lines = splittext(text, "\n") // Now we've got a bunch of "ckey = something" strings in a list - for(var/line in lines) - var/list/left_and_right = splittext(line, " - ") // Split it on the dash into left and right - if(LAZYLEN(left_and_right) != 2) - WARNING("Alien whitelist entry is invalid: [line]") // If we didn't end up with a left and right, the line is bad - continue - var/key = left_and_right[1] - if(key != ckey(key)) - WARNING("Alien whitelist entry appears to have key, not ckey: [line]") // The key contains invalid ckey characters - continue - var/list/our_whitelists = GLOB.alien_whitelist[key] // Try to see if we have one already and add to it - if(!our_whitelists) // Guess this is their first/only whitelist entry - our_whitelists = list() - GLOB.alien_whitelist[key] = our_whitelists - our_whitelists += left_and_right[2] + var/text = file2text("[global.config.directory]/alienwhitelist.txt") + if (!text) + log_world("Failed to load [global.config.directory]/alienwhitelist.txt") + else + var/lines = splittext(text, "\n") // Now we've got a bunch of "ckey = something" strings in a list + for(var/line in lines) + var/list/left_and_right = splittext(line, " - ") // Split it on the dash into left and right + if(LAZYLEN(left_and_right) != 2) + WARNING("Alien whitelist entry is invalid: [line]") // If we didn't end up with a left and right, the line is bad + continue + var/key = left_and_right[1] + if(key != ckey(key)) + WARNING("Alien whitelist entry appears to have key, not ckey: [line]") // The key contains invalid ckey characters + continue + var/list/our_whitelists = GLOB.alien_whitelist[key] // Try to see if we have one already and add to it + if(!our_whitelists) // Guess this is their first/only whitelist entry + our_whitelists = list() + GLOB.alien_whitelist[key] = our_whitelists + our_whitelists += left_and_right[2] + + #ifdef TESTING + var/msg = "Alienwhitelist Built:\n" + for(var/key in GLOB.alien_whitelist) + msg += "\t[key]:\n" + for(var/value in GLOB.alien_whitelist[key]) + msg += "\t\t- [value]\n" + testing(msg) + #endif + +/proc/reload_alienwhitelist() + GLOB.alien_whitelist.Cut() + load_alienwhitelist() /proc/is_alien_whitelisted(client/C, var/datum/species/species) //They are admin or the whitelist isn't in use @@ -67,6 +149,78 @@ GLOBAL_LIST_EMPTY(alien_whitelist) // Go apply! return FALSE +/proc/load_jobwhitelist(dbfail = FALSE) + if (CONFIG_GET(flag/sql_enabled) && !dbfail) + var/datum/db_query/query_load_jobwhitelist = SSdbcore.NewQuery("SELECT ckey, entry FROM [format_table_name("whitelist")] WHERE kind = 'job'") + if(!query_load_jobwhitelist.Execute()) + message_admins("Error loading jobwhitelist from database. Loading from [global.config.directory]/jobwhitelist.txt.") + log_sql("Error loading jobwhitelist from database. Loading from [global.config.directory]/jobwhitelist.txt.") + load_jobwhitelist(dbfail = TRUE) + return + else + while(query_load_jobwhitelist.NextRow()) + var/ckey = query_load_jobwhitelist.item[1] + var/entry = query_load_jobwhitelist.item[2] + + var/list/our_whitelists = GLOB.job_whitelist[ckey] + if(!our_whitelists) // Guess this is their first/only whitelist entry + our_whitelists = list() + GLOB.job_whitelist[ckey] = our_whitelists + our_whitelists += entry + qdel(query_load_jobwhitelist) + else + var/text = file2text("[global.config.directory]/jobwhitelist.txt") + if (!text) + log_world("Failed to load [global.config.directory]/jobwhitelist.txt") + else + var/lines = splittext(text, "\n") // Now we've got a bunch of "ckey = something" strings in a list + for(var/line in lines) + var/list/left_and_right = splittext(line, " - ") // Split it on the dash into left and right + if(LAZYLEN(left_and_right) != 2) + warning("Alien whitelist entry is invalid: [line]") // If we didn't end up with a left and right, the line is bad + continue + var/key = left_and_right[1] + if(key != ckey(key)) + warning("Alien whitelist entry appears to have key, not ckey: [line]") // The key contains invalid ckey characters + continue + var/list/our_whitelists = GLOB.job_whitelist[key] // Try to see if we have one already and add to it + if(!our_whitelists) // Guess this is their first/only whitelist entry + our_whitelists = list() + GLOB.job_whitelist[key] = our_whitelists + our_whitelists += left_and_right[2] + +/proc/reload_jobwhitelist() + GLOB.job_whitelist.Cut() + load_jobwhitelist() + +/proc/is_job_whitelisted(mob/M, var/rank) + // Check if the job actually requires a whitelist + var/datum/job/job = job_master.GetJob(rank) + if(!job.whitelist_only) + return TRUE + + // Visitor not Assistant + if(rank == JOB_ALT_VISITOR) + return TRUE + + // Let R_ADMIN permission bypass the whitelist + if(check_rights(R_ADMIN, 0)) + return TRUE + + // Whitelist empty + if(!GLOB.job_whitelist) + return FALSE + + //Search the whitelist + if(M && M.client && rank) + var/list/our_whitelists = GLOB.job_whitelist[M.client.ckey] + if("All" in our_whitelists) + return TRUE + if(lowertext(rank) in our_whitelists) + return TRUE + + return FALSE + /proc/is_lang_whitelisted(mob/M, var/datum/language/language) //They are admin or the whitelist isn't in use if(whitelist_overrides(M)) diff --git a/code/game/jobs/whitelist_vr.dm b/code/game/jobs/whitelist_vr.dm deleted file mode 100644 index 3750eebaf6..0000000000 --- a/code/game/jobs/whitelist_vr.dm +++ /dev/null @@ -1,30 +0,0 @@ -GLOBAL_LIST_EMPTY(job_whitelist) - -/hook/startup/proc/loadJobWhitelist() - load_jobwhitelist() - return 1 - -/proc/load_jobwhitelist() - var/text = file2text("config/jobwhitelist.txt") - if (!text) - log_world("Failed to load config/jobwhitelist.txt") - else - GLOB.job_whitelist = splittext(text, "\n") - -/proc/is_job_whitelisted(mob/M, var/rank) - var/datum/job/job = job_master.GetJob(rank) - if(!job.whitelist_only) - return 1 - if(rank == JOB_ALT_VISITOR) //VOREStation Edit - Visitor not Assistant - return 1 - if(check_rights(R_ADMIN, 0)) - return 1 - if(!GLOB.job_whitelist) - return 0 - if(M && rank) - for (var/s in GLOB.job_whitelist) - if(findtext(s,"[lowertext(M.ckey)] - [lowertext(rank)]")) - return 1 - if(findtext(s,"[M.ckey] - All")) - return 1 - return 0 diff --git a/code/game/world.dm b/code/game/world.dm index 7887269163..bc6b39f4d3 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -155,6 +155,15 @@ GLOBAL_VAR(restart_counter) GLOB.timezoneOffset = get_timezone_offset() callHook("startup") + + // This should probably moved somewhere else + // Maybe even a comsig? + if(CONFIG_GET(flag/usewhitelist)) + load_whitelist() + if(CONFIG_GET(flag/usealienwhitelist)) + load_alienwhitelist() + load_jobwhitelist() + //Emergency Fix load_mods() //end-emergency fix diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index 8b090f86c4..b6a552e0a5 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -31,6 +31,7 @@ GLOBAL_PROTECT(href_token) var/datum/filter_editor/filteriffic var/datum/particle_editor/particle_test + var/datum/whitelist_editor/whitelist_editor /// A lazylist of tagged datums, for quick reference with the View Tags verb var/list/tagged_datums diff --git a/code/modules/tgs_commands/vorestation.dm b/code/modules/tgs_commands/vorestation.dm index 0abcecbf4c..eafcabf41a 100644 --- a/code/modules/tgs_commands/vorestation.dm +++ b/code/modules/tgs_commands/vorestation.dm @@ -30,7 +30,7 @@ admin_only = FALSE /datum/tgs_chat_command/parsetest/Run(datum/tgs_chat_user/sender, params) - return "```You passed:[params]```" + return new /datum/tgs_message_content("```You passed:[params]```") /datum/tgs_chat_command/staffwho name = "staffwho" @@ -378,3 +378,168 @@ GLOBAL_LIST_EMPTY(pending_discord_registrations) if("dust") real_target.dust() return "Smite [smite_name] sent!" + +#define VALID_ACTIONS list("add", "remove", "list") +#define VALID_KINDS list("job", "species") +#define VALID_USAGE "whitelist \[[list2text(VALID_ACTIONS, ", ")]\] \[[list2text(VALID_KINDS, ", ")]\] (role)" +/datum/tgs_chat_command/whitelist + name = "whitelist" + help_text = "allows the management of player whitelists. Usage: whitelist \[add, remove, list\] \[job, species\] (role)" + admin_only = TRUE + +/datum/tgs_chat_command/whitelist/Run(datum/tgs_chat_user/sender, params) + var/list/message_as_list = splittext(params, " ") + var/datum/tgs_message_content/message = new("Invalid return message.") + + // Check if the command is valid + if(!CONFIG_GET(flag/sql_enabled)) + message.text = "```A database is required to be set up for this feature.```" + return message + + if(!LAZYLEN(message_as_list)) + message.text = "```Invalid command usage: [VALID_USAGE]```" + return message + + var/action = message_as_list[1] + if(!(action in VALID_ACTIONS)) + message.text = "```First param must be a valid action.```" + return message + message_as_list.Cut(1, 2) + if(!LAZYLEN(message_as_list)) + message.text = "```Invalid command usage: [VALID_USAGE]```" + return message + + var/kind = message_as_list[1] + if(!(kind in VALID_KINDS)) + message.text = "```Second param must be a valid whitelist kind.```" + return message + message_as_list.Cut(1, 2) + if(!LAZYLEN(message_as_list)) + message.text = "```Invalid command usage: [VALID_USAGE]```" + return message + + var/ckey = message_as_list[1] + if(!istext(ckey)) + message.text = "```Third param must be a valid ckey.```" + return message + + // Role is not required for listing the roles of a ckey + var/role + if(action != "list") + message_as_list.Cut(1, 2) + if(!LAZYLEN(message_as_list)) + message.text = "```Invalid command usage: [VALID_USAGE]```" + return message + + role = message_as_list[1] + if(!istext(role)) + message.text = "```Fourth param must be a valid whitelist role.```" + return message + + // Resolve the action + switch(action) + if("add") + var/datum/db_query/command_add = SSdbcore.NewQuery( + "INSERT INTO [format_table_name("whitelist")] (ckey, kind, entry) VALUES (:ckey, :kind, :entry)", + list("ckey" = ckey, "kind" = kind, "entry" = role) + ) + if(!command_add.Execute()) + log_sql("Error while trying to add [ckey] to the [role] [kind] whitelist.") + message.text = "Error while trying to add [ckey] to the [role] [kind] whitelist. Please review SQL logs." + return message + qdel(command_add) + + var/list/our_whitelists + if(kind == "job") + our_whitelists = GLOB.job_whitelist[ckey] + if(!our_whitelists) + our_whitelists = list() + GLOB.job_whitelist[ckey] = our_whitelists + + if(kind == "species") + our_whitelists = GLOB.alien_whitelist[ckey] + if(!our_whitelists) + our_whitelists = list() + GLOB.alien_whitelist[ckey] = our_whitelists + + if(our_whitelists) + our_whitelists |= role + + if("remove") + var/datum/db_query/command_remove = SSdbcore.NewQuery( + "DELETE FROM [format_table_name("whitelist")] WHERE ckey = :ckey AND kind = :kind AND entry = :entry", + list("ckey" = ckey, "kind" = kind, "entry" = role) + ) + if(!command_remove.Execute()) + log_sql("Error while trying to remove [ckey] from the [role] [kind] whitelist.") + message.text = "Error while trying to remove [ckey] from the [role] [kind] whitelist. Please review SQL logs." + return message + qdel(command_remove) + + var/list/our_whitelists + if(kind == "job") + our_whitelists = GLOB.job_whitelist[ckey] + if(!our_whitelists) + our_whitelists = list() + GLOB.job_whitelist[ckey] = our_whitelists + + if(kind == "species") + our_whitelists = GLOB.alien_whitelist[ckey] + if(!our_whitelists) + our_whitelists = list() + GLOB.alien_whitelist[ckey] = our_whitelists + + if(our_whitelists && (role in our_whitelists)) + our_whitelists -= role + + // Listing all whitelists for a specific ckey + if("list") + var/datum/tgs_chat_embed/structure/embed = new() + var/found = FALSE + + message.text = "" + message.embed = embed + embed.title = "Whitelists for [ckey]" + + var/datum/db_query/query_list = SSdbcore.NewQuery( + "SELECT kind, entry FROM [format_table_name("whitelist")] WHERE ckey = :ckey", + list("ckey" = ckey) + ) + if(!query_list.Execute()) + log_sql("Error while trying to query whitelists for [ckey].") + embed.description = "Error while trying to query whitelists for [ckey]. Please review SQL logs." + embed.colour = "#FF0000" + return message + else + while(query_list.NextRow()) + var/kind_query_result = query_list.item[1] + var/entry_query_result = query_list.item[2] + + embed.description += "- [kind_query_result] - [entry_query_result]\n" + found = TRUE + qdel(query_list) + + if(!found) + embed.description += "No whitelist entries found for [ckey]" + + return message + + // Notify the player of the change + var/key_to_find = "[ckey(ckey)]" + if(length(key_to_find)) + var/client/user + for(var/client/C in GLOB.clients) + if(C.ckey == key_to_find) + user = C + break + to_chat(user, span_info("You have been [action][action == "remove" ? "d" : "ed"] to the [kind] whitelist of [role] by an administrator.")) + + // Notify the admins on discord that it was successful + message.text = "\[Whitelist Edit\] [ckey] has been [action][action == "remove" ? "d" : "ed"] to [kind] whitelist: [role]" + log_admin(message.text) + message_admins(message.text) + + return message +#undef VALID_USAGE +#undef VALID_KINDS +#undef VALID_ACTIONS diff --git a/config/.gitignore b/config/.gitignore index d406d61dcf..7fdf40f791 100644 --- a/config/.gitignore +++ b/config/.gitignore @@ -4,6 +4,4 @@ #Also don't ignore these things because editing them manually on the server is a pain in the fucking ass. !custom_items.txt !custom_sprites.txt -!alienwhitelist.txt -!jobwhitelist.txt !jukebox.json diff --git a/config/alienwhitelist.txt b/config/alienwhitelist.txt deleted file mode 100644 index c3a76b1056..0000000000 --- a/config/alienwhitelist.txt +++ /dev/null @@ -1,250 +0,0 @@ -1062aphelion - Protean -abyssalamphithere - Vox -admiraldragon - Vox -adriano20037 - Protean -adriano20037 - Xenochimera -aetherelemental - Daemon -afflatuskeeper - Xenochimera -alphaprime1 - Protean -amarewolf - Xenochimera -amshaegaar - Vox -arandomalien - Xenochimera -arminazenith - Protean -arokha - Protean -aruis - Diona -aruis - Protean -aruis - Xenochimera -ashburndracki - Protean -athena14 - Xenochimera -athena14 - Protean -auraribbon - Black-Eyed Shadekin -avianaviator - Protean -avianaviator - Hanner -azmodan412 - Xenochimera -beyondmylife - Protean -bonktrauma - Diona -bothnevarbackwards - Diona -bricker98 - Protean -bricker98 - Black-Eyed Shadekin -bricker98 - Hanner -bricker98 - Gamma Replicant -bubonicsweetie - Protean -burritojustice - Protean -camanis - Protean -cameron653 - Protean -cgr - Protean -chaosdoomsday - Black-Eyed Shadekin -chaosdoomsday - Protean -chargae - Protean -chemlight - Xenochimera -chillyfang - Black-Eyed Shadekin -chloeplayer - Protean -comradenitro - Protean -coolcrow420 - Black-Eyed Shadekin -crossexonar - Protean -cryohydra - Protean -ctrz - Protean -cubejackal - Black-Eyed Shadekin -detectivegoogle - Protean -digi5 - Protean -digi5 - Black-Eyed Shadekin -digitalsquirrel95 - Black-Eyed Shadekin -digitalsquirrel95 - Protean -digitalsquirrel95 - Hanner -draycu - Vox -draykenthedragon - Xenochimera -draykenthedragon - Protean -durandaal - Teppi -essbie - Black-Eyed Shadekin -eucliwood0 - Hanner -exgame - Vox -falloutdog3 - Black-Eyed Shadekin -flaktual - Vox -flurriee - Protean -foxfire53 - Xenochimera -foxglovepurpur - Diona -funnyman2003 - Xenochimera -fuzlet - Protean -grallstonefist - Black-Eyed Shadekin -greennyy - Protean -h0lysquirr3l - Protean -haloren - Black-Eyed Shadekin -hawkerthegreat - Vox -heroman3003 - Xenochimera -hexadood - Protean -hollifex - Diona -huenererschrecker - Xenochimera -hunterbirk - Protean -hunterbirk - Xenochimera -idcaboutaname - Protean -idcaboutaname - Black-Eyed Shadekin -inuzari - Diona -iivoracious - Black-Eyed Shadekin -irkallaepsilon - Protean -jademanique - Black-Eyed Shadekin -jademanique - Protean -jademanique - Teppi -jademanique - Xenochimera -joltze - Black-Eyed Shadekin -jparker890 - Vox -juney7 - Hanner -kered2 - Protean -khanivore - Protean -killjaden - Protean -kira72 - Xenochimera -kira72 - Protean -kiraalitruss - Teppi -kitchifox - Black-Eyed Shadekin -konner1055 - Black-Eyed Shadekin -konner1055 - Protean -ktccd - Diona -kyrendragon - Black-Eyed Shadekin -lavenderrs - Teppi -lazzar - Black-Eyed Shadekin -lazzar - Hanner -lewzharri - Hanner -lewzharri - Glamour Speak -lianvee - Black-Eyed Shadekin -lillianfyre - Xenochimera -liquidfirefly - Protean -lizehrd - Xenochimera -looptyloo - Protean -lordlag - Black-Eyed Shadekin -lorgenz - Protean -losstinspess - Protean -losstinspess - Xenochimera -lykojeyot - Black-Eyed Shadekin -negatist - Protean -madmulk9 - Protean -magpiemayhem - Vox -magpiemayhem - Xenochimera -makkinindorn - Protean -malfestio - Protean -malfestio - Xenochimera -marcobarko - Black-Eyed Shadekin -marcobarko - Protean -maxcaliber50 - Protean -maxine64 - Xenochimera -mewchild - Diona -mewchild - Vox -milu - Xenochimera -mrsebbi - Xenochimera -mullins111 - Black-Eyed Shadekin -murchant - Teppi -natje - Xenochimera -neodraconica - Hanner -nerdass - Protean -newyorks - Protean -obengrad - Diona -obengrad - Protean -obengrad - Xenochimera -omegamech - Black-Eyed Shadekin -oneofmanynames385 - Protean -ontejbjoav - Black-Eyed Shadekin -ontejbjoav - Diona -opheliathedreadful - Hanner -oreganovulgaris - Xenochimera -oscarholmes - Protean -oscarholmes - Gamma Replicant -owwy - Black-Eyed Shadekin -oxenfree - Protean -ozyton - Black-Eyed Shadekin -pandora029 - Protean -paradoxspace - Xenochimera -pastelprincedan - Black-Eyed Shadekin -pastelprincedan - Hanner -pastelprincedan - Protean -pearlprophet - Protean -pemdesos - Protean -phoenixx0 - Vox -pontifexminimus - Black-Eyed Shadekin -pontifexminimus - Protean -pontifexminimus - Xenochimera -pontifexminimus - Hanner -pugly43 - Protean -qrocakes - Black-Eyed Shadekin -radiantaurora - Protean -rainbyplays - Protean -ramomisama - Protean -residentcody - Black-Eyed Shadekin -residentcody - Protean -residentcody - Gamma Replicant -revolvereloise - Protean -rikaru19xjenkins - Xenochimera -rixunie - Diona -romanatcolgate - Hanner -rubyflamewing - Protean -rykkastormheart - Xenochimera -ryumi - Protean -ryumi - Xenochimera -ryumi - Black-Eyed Shadekin -ryumi - Hanner -satinisle - Black-Eyed Shadekin -satinisle - Protean -scoutisafolflol - Xenochimera -seagha - Vox -seiga - Vox -selter - Protean -sepulchre - Vox -sharplight - Protean -shilkon - Hanner -shirosenshi - Xenochimera -silvertalismen - Diona -silvertalismen - Vox -silvertalismen - Xenochimera -silvertalismen - Hanner -sirlionfur - Black-Eyed Shadekin -sixberry - Black-Eyed Shadekin -sixberry - Hanner -skylarks - Black-Eyed Shadekin -slovakiani - Black-Eyed Shadekin -slysilentclaw - Black-Eyed Shadekin -smdytb1 - Black-Eyed Shadekin -spirit1299 - Black-Eyed Shadekin -stackerrobot - Protean -storesund97 - Protean -syzygyrior - Black-Eyed Shadekin -tankthebirb - Black-Eyed Shadekin -tastypred - Black-Eyed Shadekin -tastypred - Protean -tastypred - Xenochimera -terrestris - Common Skrellian -terrestris - Vox -thedavestdave - Protean -theoun - Hanner -thexdkidoflol - Xenochimera -tigercat2000 - Protean -timidvi - Diona -titaania - Protean -tombomb90 - Protean -torquegstc - Protean -trifireblade - Protean -trikonei - Protean -umbraferros - Black-Eyed Shadekin -umbraferros - Protean -umbraferros - Xenochimera -umbraferros - Hanner -umbrenos - Black-Eyed Shadekin -unkindnaysayer - Hanner -varkaselyn - Protean -varonis - Protean -varonis - Xenochimera -verkister - Xenochimera -verysoft - Black-Eyed Shadekin -verysoft - Teppi -vitoras - Protean -voidalynx - Black-Eyed Shadekin -voidalynx - Protean -wickedtemp - Shadekin Empathy -wolfmeme - Protean -xioen - Diona -xioen - Protean -xioen - Xenochimera -xonkon - Protean -yecrowbarman - Protean -yeehawguvnah - Protean -yeehawguvnah - Xenochimera -zalvine - Shadekin Empathy -zammyman215 - Vox -zeracyfr - Xenochimera -zwadstheiguana - Diona diff --git a/config/jobwhitelist.txt b/config/jobwhitelist.txt deleted file mode 100644 index abc8de04b1..0000000000 --- a/config/jobwhitelist.txt +++ /dev/null @@ -1,37 +0,0 @@ -# Job whitelist in format ckey - jobname -# Like arokha - clown -akram - clown -amshaegaar - mime -auraribbon - clown -awkwarddryad - mime -CGR - mime -chargae - mime -coolcrow420 - clown -coolcrow420 - mime -donnysalmond - clown -h0lysquirr3l - clown -joey4298 - mime -lm40 - clown -losstinspess - mime -maxcaliber50 - mime -murchant - mime -pastelprincedan - mime -pastelprincedan - clown -radishfriend - clown -schrano - mime -seiga - mime -sgtryder - mime -sharplight - clown -siennaathens - clown -silvertalismen - clown -spirit1299 - clown -suicidalpickles - mime -tinybear16 - clown -tygertac - clown -umbraferros - mime -varonis - mime -verkister - clown -whiskyrose - clown -yecrowbarman - clown -yecrowbarman - mime -nullspaceindustries - mime diff --git a/tools/convert_whitelists_to_sql.py b/tools/convert_whitelists_to_sql.py new file mode 100644 index 0000000000..f707df2de9 --- /dev/null +++ b/tools/convert_whitelists_to_sql.py @@ -0,0 +1,49 @@ +input_file = 'config/alienwhitelist.txt' +output_file = 'whitelist.sql' +table_name = 'whitelist' + +with open(input_file, 'r', encoding='utf-8') as infile, \ + open(output_file, 'w', encoding='utf-8') as outfile: + for line in infile: + line = line.strip() + if not line: + continue + if "#" in line: + print(f"Skipping commented line: {line}") + continue + # Split on ' - ', expecting exactly two parts + parts = line.split(' - ') + if len(parts) != 2: + print(f"Skipping invalid line: {line}") + continue + username, entry = (p.replace("'", "''") for p in parts) # Escape single quotes + kind = "species" + sql = ( + f"INSERT INTO {table_name} (ckey, entry, kind) " + f"VALUES ('{username}', '{entry}', '{kind}');\n" + ) + outfile.write(sql) + +input_file = 'config/jobwhitelist.txt' + +with open(input_file, 'r', encoding='utf-8') as infile, \ + open(output_file, 'a', encoding='utf-8') as outfile: + for line in infile: + line = line.strip() + if not line: + continue + if "#" in line: + print(f"Skipping commented line: {line}") + continue + # Split on ' - ', expecting exactly two parts + parts = line.split(' - ') + if len(parts) != 2: + print(f"Skipping invalid line: {line}") + continue + username, entry = (p.replace("'", "''") for p in parts) # Escape single quotes + kind = "job" + sql = ( + f"INSERT INTO {table_name} (ckey, entry, kind) " + f"VALUES ('{username}', '{entry}', '{kind}');\n" + ) + outfile.write(sql) diff --git a/vorestation.dme b/vorestation.dme index 78de165c5d..6ad4eae210 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -1087,7 +1087,6 @@ #include "code\game\jobs\job_controller.dm" #include "code\game\jobs\jobs.dm" #include "code\game\jobs\whitelist.dm" -#include "code\game\jobs\whitelist_vr.dm" #include "code\game\jobs\job\_alt_title.dm" #include "code\game\jobs\job\assistant.dm" #include "code\game\jobs\job\captain.dm"