diff --git a/.github/DOWNLOADING.md b/.github/DOWNLOADING.md
index eaad0dee7f9..27731066cae 100644
--- a/.github/DOWNLOADING.md
+++ b/.github/DOWNLOADING.md
@@ -41,15 +41,14 @@ something has gone wrong - possibly a corrupt download or the files extracted wr
or a code issue on the main repo. Feel free to ask on Discord.
Once that's done, open up the config folder.
-Firstly, you will want to copy everything from the example folder into the regular config folder.
-EG: Move `config/example/config.txt` to `config/config.txt`, and do the same for all the other files.
-You'll want to edit `config.txt` to set your server location,
+Firstly, you will want to copy `config.toml` from the example folder into the regular config folder.
+You'll want to edit the url configuration section of `config.toml` to set your server location,
so that all your players don't get disconnected at the end of each round.
It's recommended you don't turn on the gamemodes with probability 0,
as they have various issues and aren't currently being tested,
so they may have unknown and bizarre bugs.
-You'll also want to edit admins.txt to remove the default admins and add your own.
+You'll also want to edit the admin configuration of `config.toml` to remove the default admins and add your own.
If you are connecting from localhost to your own test server, you should automatically be admin.
"Host" is the highest level of access, and the other recommended admin levels for now are
"Game Admin" and "Moderator". The format is:
@@ -60,7 +59,7 @@ If you are connecting from localhost to your own test server, you should automat
where the BYOND key must be in lowercase and the admin rank must be properly capitalised.
There are a bunch more admin ranks, but these two should be enough for most servers,
-assuming you have trustworthy admins. You can define your own ranks in `admin_ranks.txt`
+assuming you have trustworthy admins. You can define your own ranks in the admin section of `config.toml`
Finally, to start the server,
run Dream Daemon and enter the path to your compiled paradise.dmb file.
diff --git a/_build_dependencies.sh b/_build_dependencies.sh
index be4b390a6d3..8cef5ce91b9 100644
--- a/_build_dependencies.sh
+++ b/_build_dependencies.sh
@@ -7,5 +7,3 @@ export NODE_VERSION=12
export BYOND_MAJOR=513
# Byond Minor
export BYOND_MINOR=1528
-# For the RUSTG library. Not actually installed by CI but kept as a reference
-export RUSTG_VERSION=2.1-P
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 3d38b8716b6..65777da80cb 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -309,7 +309,7 @@
#define ROUND_TIME (SSticker.round_start_time ? (world.time - SSticker.round_start_time) : 0)
// Macro that returns true if it's too early in a round to freely ghost out
-#define TOO_EARLY_TO_GHOST (config && (ROUND_TIME < (config.round_abandon_penalty_period)))
+#define TOO_EARLY_TO_GHOST (ROUND_TIME < GLOB.configuration.general.cryo_penalty_period)
// Used by radios to indicate that they have sent a message via something other than subspace
#define RADIO_CONNECTION_FAIL 0
diff --git a/code/__DEFINES/rust_g.dm b/code/__DEFINES/rust_g.dm
index fe4b644096b..6a331a6131f 100644
--- a/code/__DEFINES/rust_g.dm
+++ b/code/__DEFINES/rust_g.dm
@@ -18,14 +18,46 @@
// Noise related operations //
#define rustg_noise_get_at_coordinates(seed, x, y) call(RUST_G, "noise_get_at_coordinates")(seed, x, y)
+// File related operations //
+#define rustg_file_read(fname) call(RUST_G, "file_read")(fname)
+#define rustg_file_write(text, fname) call(RUST_G, "file_write")(text, fname)
+#define rustg_file_append(text, fname) call(RUST_G, "file_append")(text, fname)
+
+#ifdef RUSTG_OVERRIDE_BUILTINS
+#define file2text(fname) rustg_file_read(fname)
+#define text2file(text, fname) rustg_file_append(text, fname)
+#endif
+
// Git related operations //
#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)
+// Hash related operations //
+#define rustg_hash_string(algorithm, text) call(RUST_G, "hash_string")(algorithm, text)
+#define rustg_hash_file(algorithm, fname) call(RUST_G, "hash_file")(algorithm, fname)
+
+#define RUSTG_HASH_MD5 "md5"
+#define RUSTG_HASH_SHA1 "sha1"
+#define RUSTG_HASH_SHA256 "sha256"
+#define RUSTG_HASH_SHA512 "sha512"
+
+#ifdef RUSTG_OVERRIDE_BUILTINS
+#define md5(thing) (isfile(thing) ? rustg_hash_file(RUSTG_HASH_MD5, "[thing]") : rustg_hash_string(RUSTG_HASH_MD5, thing))
+#endif
+
// Logging stuff //
#define rustg_log_write(fname, text) call(RUST_G, "log_write")(fname, text)
/proc/rustg_log_close_all() return call(RUST_G, "log_close_all")()
+// URL encoding stuff
+#define rustg_url_encode(text) call(RUST_G, "url_encode")(text)
+#define rustg_url_decode(text) call(RUST_G, "url_decode")(text)
+
+#ifdef RUSTG_OVERRIDE_BUILTINS
+#define url_encode(text) rustg_url_encode(text)
+#define url_decode(text) rustg_url_decode(text)
+#endif
+
// HTTP library stuff //
#define RUSTG_HTTP_METHOD_GET "get"
#define RUSTG_HTTP_METHOD_PUT "put"
@@ -50,5 +82,8 @@
#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]")
+// toml2json stuff //
+#define rustg_toml2json(tomlfile) call(RUST_G, "toml2json")(tomlfile)
+
// RUSTG Version //
-#define RUST_G_VERSION "0.4.5-P2"
+#define RUST_G_VERSION "0.4.5-P3"
diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm
index fea2756f664..c61d8319d39 100644
--- a/code/__HELPERS/_logging.dm
+++ b/code/__HELPERS/_logging.dm
@@ -28,11 +28,12 @@ GLOBAL_PROTECT(log_end)
/proc/log_admin(text)
GLOB.admin_log.Add(text)
- if(config.log_admin)
+ if(GLOB.configuration.logging.admin_logging)
rustg_log_write(GLOB.world_game_log, "ADMIN: [text][GLOB.log_end]")
/proc/log_debug(text)
- if(config.log_debug)
+ // This has presence checks as this may be called before GLOB has loaded
+ if(GLOB?.configuration?.logging.debug_logging)
rustg_log_write(GLOB.world_game_log, "DEBUG: [text][GLOB.log_end]")
for(var/client/C in GLOB.admins)
@@ -40,80 +41,80 @@ GLOBAL_PROTECT(log_end)
to_chat(C, "DEBUG: [text]")
/proc/log_game(text)
- if(config.log_game)
+ if(GLOB.configuration.logging.game_logging)
rustg_log_write(GLOB.world_game_log, "GAME: [text][GLOB.log_end]")
/proc/log_vote(text)
- if(config.log_vote)
+ if(GLOB.configuration.logging.vote_logging)
rustg_log_write(GLOB.world_game_log, "VOTE: [text][GLOB.log_end]")
/proc/log_access_in(client/new_client)
- if(config.log_access)
+ if(GLOB.configuration.logging.access_logging)
var/message = "[key_name(new_client)] - IP:[new_client.address] - CID:[new_client.computer_id] - BYOND v[new_client.byond_version]"
rustg_log_write(GLOB.world_game_log, "ACCESS IN: [message][GLOB.log_end]")
/proc/log_access_out(mob/last_mob)
- if(config.log_access)
+ if(GLOB.configuration.logging.access_logging)
var/message = "[key_name(last_mob)] - IP:[last_mob.lastKnownIP] - CID:[last_mob.computer_id] - BYOND Logged Out"
rustg_log_write(GLOB.world_game_log, "ACCESS OUT: [message][GLOB.log_end]")
/proc/log_say(text, mob/speaker)
- if(config.log_say)
+ if(GLOB.configuration.logging.say_logging)
rustg_log_write(GLOB.world_game_log, "SAY: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_whisper(text, mob/speaker)
- if(config.log_whisper)
+ if(GLOB.configuration.logging.whisper_logging)
rustg_log_write(GLOB.world_game_log, "WHISPER: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_ooc(text, client/user)
- if(config.log_ooc)
+ if(GLOB.configuration.logging.ooc_logging)
rustg_log_write(GLOB.world_game_log, "OOC: [user.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_aooc(text, client/user)
- if(config.log_ooc)
+ if(GLOB.configuration.logging.ooc_logging)
rustg_log_write(GLOB.world_game_log, "AOOC: [user.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_looc(text, client/user)
- if(config.log_ooc)
+ if(GLOB.configuration.logging.ooc_logging)
rustg_log_write(GLOB.world_game_log, "LOOC: [user.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_emote(text, mob/speaker)
- if(config.log_emote)
+ if(GLOB.configuration.logging.emote_logging)
rustg_log_write(GLOB.world_game_log, "EMOTE: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_attack(attacker, defender, message)
- if(config.log_attack)
+ if(GLOB.configuration.logging.attack_logging)
rustg_log_write(GLOB.world_game_log, "ATTACK: [attacker] against [defender]: [message][GLOB.log_end]") //Seperate attack logs? Why?
/proc/log_adminsay(text, mob/speaker)
- if(config.log_adminchat)
+ if(GLOB.configuration.logging.adminchat_logging)
rustg_log_write(GLOB.world_game_log, "ADMINSAY: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_qdel(text)
rustg_log_write(GLOB.world_qdel_log, "QDEL: [text][GLOB.log_end]")
/proc/log_mentorsay(text, mob/speaker)
- if(config.log_adminchat)
+ if(GLOB.configuration.logging.adminchat_logging)
rustg_log_write(GLOB.world_game_log, "MENTORSAY: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_ghostsay(text, mob/speaker)
- if(config.log_say)
+ if(GLOB.configuration.logging.say_logging)
rustg_log_write(GLOB.world_game_log, "DEADCHAT: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_ghostemote(text, mob/speaker)
- if(config.log_emote)
+ if(GLOB.configuration.logging.emote_logging)
rustg_log_write(GLOB.world_game_log, "DEADEMOTE: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_adminwarn(text)
- if(config.log_adminwarn)
+ if(GLOB.configuration.logging.admin_warning_logging)
rustg_log_write(GLOB.world_game_log, "ADMINWARN: [html_decode(text)][GLOB.log_end]")
/proc/log_pda(text, mob/speaker)
- if(config.log_pda)
+ if(GLOB.configuration.logging.pda_logging)
rustg_log_write(GLOB.world_game_log, "PDA: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
/proc/log_chat(text, mob/speaker)
- if(config.log_pda)
+ if(GLOB.configuration.logging.pda_logging)
rustg_log_write(GLOB.world_game_log, "CHAT: [speaker.simple_info_line()] [html_decode(text)][GLOB.log_end]")
/proc/log_misc(text)
@@ -121,7 +122,8 @@ GLOBAL_PROTECT(log_end)
/proc/log_world(text)
SEND_TEXT(world.log, text)
- if(config && config.log_world_output)
+ // This has to be presence checked as log_world() is used before world/New().
+ if(GLOB?.configuration?.logging.world_logging)
rustg_log_write(GLOB.world_game_log, "WORLD: [html_decode(text)][GLOB.log_end]")
/proc/log_runtime_txt(text) // different from /tg/'s log_runtime because our error handler has a log_runtime proc already that does other stuff
diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm
index b8b47aa8656..3d7d14e59ce 100644
--- a/code/__HELPERS/names.dm
+++ b/code/__HELPERS/names.dm
@@ -15,7 +15,7 @@ GLOBAL_VAR(church_name)
return name
-// TODO: Remove this. Its always gonna be NAS Trurl
+// AA TODO: Remove this. Its always gonna be NAS Trurl
/proc/command_name()
return "NAS Trurl"
diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm
index 1d9b6550b84..437765a0a6f 100644
--- a/code/__HELPERS/text.dm
+++ b/code/__HELPERS/text.dm
@@ -10,7 +10,7 @@
/proc/format_table_name(table as text)
- return sqlfdbktableprefix + table
+ return GLOB.configuration.database.table_prefix + table
/*
* Text sanitization
@@ -720,9 +720,9 @@
/proc/client2rankcolour(client/C)
// First check if end user is an admin
if(C.holder)
- if(C.holder.rank in GLOB.rank_colour_map)
+ if(C.holder.rank in GLOB.configuration.admin.rank_colour_map)
// Return their rank colour if they are in here
- return GLOB.rank_colour_map[C.holder.rank]
+ return GLOB.configuration.admin.rank_colour_map[C.holder.rank]
// If they arent an admin, see if they are a patreon. Just accept any level
if(C.donator_level)
diff --git a/code/_globalvars/configuration.dm b/code/_globalvars/configuration.dm
index ea2cf1290fd..3b7d061ace3 100644
--- a/code/_globalvars/configuration.dm
+++ b/code/_globalvars/configuration.dm
@@ -1,44 +1,30 @@
-GLOBAL_REAL(config, /datum/configuration)
-
-GLOBAL_VAR(host)
+/// Join MOTD for the server
GLOBAL_VAR(join_motd)
+GLOBAL_PROTECT(join_motd) // Takes up a lot of space in VV
+/// Join TOS for the server
GLOBAL_VAR(join_tos)
-GLOBAL_VAR_INIT(game_version, "ParaCode")
+GLOBAL_PROTECT(join_tos) // Takes up a lot of space. Also dont touch this shit
+
+/// The current game year
GLOBAL_VAR_INIT(game_year, (text2num(time2text(world.realtime, "YYYY")) + 544))
-GLOBAL_VAR_INIT(aliens_allowed, 1)
-GLOBAL_VAR_INIT(traitor_scaling, 1)
-//GLOBAL_VAR_INIT(goonsay_allowed, 0)
-GLOBAL_VAR_INIT(dna_ident, 1)
-GLOBAL_VAR_INIT(abandon_allowed, 0)
-GLOBAL_VAR_INIT(enter_allowed, 1)
-GLOBAL_VAR_INIT(guests_allowed, 1)
-GLOBAL_VAR_INIT(shuttle_frozen, 0)
-GLOBAL_VAR_INIT(shuttle_left, 0)
-GLOBAL_VAR_INIT(tinted_weldhelh, 1)
-GLOBAL_VAR_INIT(mouse_respawn_time, 5) //Amount of time that must pass between a player dying as a mouse and repawning as a mouse. In minutes.
+/// Allow new players to enter the game?
+GLOBAL_VAR_INIT(enter_allowed, TRUE)
-// Debug is used exactly once (in living.dm) but is commented out in a lot of places. It is not set anywhere and only checked.
-// Debug2 is used in conjunction with a lot of admin verbs and therefore is actually legit.
-GLOBAL_VAR_INIT(debug, 0) // global debug switch
-GLOBAL_VAR_INIT(debug2, 1) // enables detailed job debug file in secrets
+/// Is OOC currently enabled?
+GLOBAL_VAR_INIT(ooc_enabled, TRUE)
-//This was a define, but I changed it to a variable so it can be changed in-game.(kept the all-caps definition because... code...) -Errorage
-GLOBAL_VAR_INIT(max_ex_devastation_range, 3)
-GLOBAL_VAR_INIT(max_ex_heavy_range, 7)
-GLOBAL_VAR_INIT(max_ex_light_range, 14)
-GLOBAL_VAR_INIT(max_ex_flash_range, 14)
-GLOBAL_VAR_INIT(max_ex_flame_range, 14)
+/// Is LOOC currently enabled?
+GLOBAL_VAR_INIT(looc_enabled, TRUE)
-//Random event stuff, apparently used
-GLOBAL_VAR_INIT(eventchance, 10) //% per 5 mins
-GLOBAL_VAR_INIT(event, 0)
-GLOBAL_VAR_INIT(hadevent, 0)
-GLOBAL_VAR_INIT(blobevent, 0)
+/// Is OOC currently enabled for dead people?
+GLOBAL_VAR_INIT(dooc_enabled, TRUE)
-// These vars are protected because changing them could pose a security risk, though they are fine to be read since they are just system paths
-GLOBAL_VAR(shutdown_shell_command) // Command to run if shutting down (SHUTDOWN_ON_REBOOT) instead of rebooting
-GLOBAL_PROTECT(shutdown_shell_command)
+/// Is deadchat currently enabled?
+GLOBAL_VAR_INIT(dsay_enabled, TRUE)
-GLOBAL_VAR(python_path) //Path to the python executable. Defaults to "python" on windows and "/usr/bin/env python2" on unix
-GLOBAL_PROTECT(python_path)
+/// Amount of time (in minutes) that must pass between a player dying as a mouse and repawning as a mouse
+GLOBAL_VAR_INIT(mouse_respawn_time, 5)
+
+/// Enable debugging of things such as job starts and other things
+GLOBAL_VAR_INIT(debug2, TRUE)
diff --git a/code/_globalvars/lists/misc.dm b/code/_globalvars/lists/misc.dm
index 2873a626590..5464ed64bb4 100644
--- a/code/_globalvars/lists/misc.dm
+++ b/code/_globalvars/lists/misc.dm
@@ -55,7 +55,4 @@ GLOBAL_LIST_INIT(cooking_recipes, list(RECIPE_MICROWAVE = list(), RECIPE_OVEN =
GLOBAL_LIST_INIT(cooking_ingredients, list(RECIPE_MICROWAVE = list(), RECIPE_OVEN = list(), RECIPE_GRILL = list(), RECIPE_CANDY = list()))
GLOBAL_LIST_INIT(cooking_reagents, list(RECIPE_MICROWAVE = list(), RECIPE_OVEN = list(), RECIPE_GRILL = list(), RECIPE_CANDY = list()))
-/// Associative list of admin rank to colour. Set in config/rank_colours.txt
-GLOBAL_LIST_EMPTY(rank_colour_map)
-
#define EGG_LAYING_MESSAGES list("lays an egg.", "squats down and croons.", "begins making a huge racket.", "begins clucking raucously.")
diff --git a/code/_globalvars/sensitive.dm b/code/_globalvars/sensitive.dm
deleted file mode 100644
index 4c04b2d480b..00000000000
--- a/code/_globalvars/sensitive.dm
+++ /dev/null
@@ -1,12 +0,0 @@
-// All global vars in this file require a different handler as we dont want their data to be exposed, not even to admins with permission to view globals
-// They write as native BYOND globals, which means they cant be edited at all, and also use a format
-// Please only throw absolutely crucial do-not-view shit in here please. -aa07
-
-// MySQL configuration
-GLOBAL_REAL_VAR(sqladdress) = "localhost"
-GLOBAL_REAL_VAR(sqlport) = "3306"
-GLOBAL_REAL_VAR(sqlfdbkdb) = "test"
-GLOBAL_REAL_VAR(sqlfdbklogin) = "root"
-GLOBAL_REAL_VAR(sqlfdbkpass) = ""
-GLOBAL_REAL_VAR(sqlfdbktableprefix) = "erro_"
-GLOBAL_REAL_VAR(sql_version) = 0
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
deleted file mode 100644
index 2c3d3202a31..00000000000
--- a/code/controllers/configuration.dm
+++ /dev/null
@@ -1,968 +0,0 @@
-/datum/configuration
- var/server_name = null // server name (for world name / status)
- var/server_tag_line = null // server tagline (for showing on hub entry)
- var/server_extra_features = null // server-specific extra features (for hub entry)
- var/server_suffix = 0 // generate numeric suffix based on server port
-
- var/minimum_client_build = 1421 // Build 1421 due to the middle mouse button exploit
-
- var/nudge_script_path = "nudge.py" // where the nudge.py script is located
-
- var/log_ooc = 0 // log OOC channel
- var/log_access = 0 // log login/logout
- var/log_say = 0 // log client say
- var/log_admin = 0 // log admin actions
- var/log_debug = 1 // log debug output
- var/log_game = 0 // log game events
- var/log_vote = 0 // log voting
- var/log_whisper = 0 // log client whisper
- var/log_emote = 0 // log emotes
- var/log_attack = 0 // log attack messages
- var/log_adminchat = 0 // log admin chat messages
- var/log_adminwarn = 0 // log warnings admins get about bomb construction and such
- var/log_pda = 0 // log pda messages
- var/log_world_output = 0 // log world.log << messages
- var/log_runtimes = 0 // logs world.log to a file
- var/log_hrefs = 0 // logs all links clicked in-game. Could be used for debugging and tracking down exploits
- var/sql_enabled = 0 // for sql switching
- var/allow_admin_ooccolor = 0 // Allows admins with relevant permissions to have their own ooc colour
- var/pregame_timestart = 240 // Time it takes for the server to start the game
- var/allow_vote_restart = 0 // allow votes to restart
- var/allow_vote_mode = 0 // allow votes to change mode
- var/vote_delay = 6000 // minimum time between voting sessions (deciseconds, 10 minute default)
- var/vote_period = 600 // length of voting period (deciseconds, default 1 minute)
- var/vote_autotransfer_initial = 72000 // Length of time before the first autotransfer vote is called
- var/vote_autotransfer_interval = 18000 // length of time before next sequential autotransfer vote
- var/vote_no_default = 0 // vote does not default to nochange/norestart (tbi)
- var/vote_no_dead = 0 // dead people can't vote (tbi)
-// var/enable_authentication = 0 // goon authentication
- var/del_new_on_log = 1 // qdel's new players if they log before they spawn in
- var/feature_object_spell_system = 0 //spawns a spellbook which gives object-type spells instead of verb-type spells for the wizard
- var/traitor_scaling = 0 //if amount of traitors scales based on amount of players
- var/protect_roles_from_antagonist = 0// If security and such can be tratior/cult/other
- var/continuous_rounds = 0 // Gamemodes which end instantly will instead keep on going until the round ends by escape shuttle or nuke.
- var/allow_Metadata = 0 // Metadata is supported.
- var/popup_admin_pm = 0 //adminPMs to non-admins show in a pop-up 'reply' window when set to 1.
- var/Ticklag = 0.5
- var/socket_talk = 0 // use socket_talk to communicate with other processes
- var/list/resource_urls = null
- var/antag_hud_allowed = 0 // Ghosts can turn on Antagovision to see a HUD of who is the bad guys this round.
- var/antag_hud_restricted = 0 // Ghosts that turn on Antagovision cannot rejoin the round.
- var/list/mode_names = list()
- var/list/modes = list() // allowed modes
- var/list/votable_modes = list() // votable modes
- var/list/probabilities = list() // relative probability of each mode
- var/humans_need_surnames = 0
- var/allow_random_events = 0 // enables random events mid-round when set to 1
- var/allow_ai = 1 // allow ai job
- var/respawn = 0
- var/guest_jobban = 1
- var/panic_bunker_threshold = 150 // above this player count threshold, never-before-seen players are blocked from connecting
- var/usewhitelist = 0
- var/mods_are_mentors = 0
- var/load_jobs_from_txt = 0
- var/automute_on = 0 //enables automuting/spam prevention
- var/jobs_have_minimal_access = 0 //determines whether jobs use minimal access or expanded access.
- var/round_abandon_penalty_period = 30 MINUTES // Time from round start during which ghosting out is penalized
- var/medal_hub_address = null
- var/medal_hub_password = null
-
- var/reactionary_explosions = 0 //If we use reactionary explosions, explosions that react to walls and doors
-
- var/assistantlimit = 0 //enables assistant limiting
- var/assistantratio = 2 //how many assistants to security members
-
- // The AFK subsystem will not be activated if any of the below config values are equal or less than 0
- var/warn_afk_minimum = 0 // How long till you get a warning while being AFK
- var/auto_cryo_afk = 0 // How long till you get put into cryo when you're AFK
- var/auto_despawn_afk = 0 // How long till you actually despawn in cryo when you're AFK (Not ssd so not automatic)
-
- var/auto_cryo_ssd_mins = 0
- var/ssd_warning = 0
-
- var/list_afk_minimum = 5 // How long people have to be AFK before it's listed on the "List AFK players" verb
-
- var/traitor_objectives_amount = 2
- var/shadowling_max_age = 0
-
- var/max_maint_drones = 5 //This many drones can spawn,
- var/allow_drone_spawn = 1 //assuming the admin allow them to.
- var/drone_build_time = 1200 //A drone will become available every X ticks since last drone spawn. Default is 2 minutes.
-
- var/usealienwhitelist = 0
- var/limitalienplayers = 0
- var/alien_to_human_ratio = 0.5
-
- var/server
- var/banappeals
- var/wikiurl = "http://example.org"
- var/forumurl = "http://example.org"
- var/rulesurl = "http://example.org"
- var/githuburl = "http://example.org"
- var/donationsurl = "http://example.org"
- var/repositoryurl = "http://example.org"
- var/discordurl = "http://example.org"
- var/discordforumurl = "http://example.org"
-
- var/overflow_server_url
- var/forbid_singulo_possession = 0
-
- var/check_randomizer = 0
-
- //game_options.txt configs
-
- var/bones_can_break = 1
-
- var/revival_pod_plants = 1
- var/revival_cloning = 1
- var/revival_brain_life = -1
-
- var/auto_toggle_ooc_during_round = 0
-
- var/shuttle_refuel_delay = 12000
-
- //Used for modifying movement speed for mobs.
- //Unversal modifiers
- var/run_speed = 0
- var/walk_speed = 0
-
- //Mob specific modifiers. NOTE: These will affect different mob types in different ways
- var/human_delay = 0
- var/robot_delay = 0
- var/monkey_delay = 0
- var/alien_delay = 0
- var/slime_delay = 0
- var/animal_delay = 0
-
- //IP Intel vars
- var/ipintel_email
- var/ipintel_rating_bad = 1
- var/ipintel_save_good = 12
- var/ipintel_save_bad = 1
- var/ipintel_domain = "check.getipintel.net"
- var/ipintel_maxplaytime = 0
- var/ipintel_whitelist = 0
- var/ipintel_detailsurl = "https://iphub.info/?ip="
-
- var/forum_link_url
- var/forum_playerinfo_url
-
- var/admin_legacy_system = 0 //Defines whether the server uses the legacy admin system with admins.txt or the SQL system. Config option in config.txt
- var/ban_legacy_system = 0 //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. Config option in config.txt
- var/use_age_restriction_for_jobs = 0 //Do jobs use account age restrictions? --requires database
- var/use_age_restriction_for_antags = 0 //Do antags use account age restrictions? --requires database
-
- var/use_exp_tracking = 0
- var/use_exp_restrictions = 0
- var/use_exp_restrictions_admin_bypass = 0
-
- var/simultaneous_pm_warning_timeout = 100
-
- var/assistant_maint = 0 //Do assistants get maint access?
- var/gateway_delay = 6000
- var/ghost_interaction = 0
-
- var/comms_password = ""
-
- var/default_laws = 0 //Controls what laws the AI spawns with.
-
- var/const/minutes_to_ticks = 60 * 10
- // Event settings
- var/expected_round_length = 60 * 2 * minutes_to_ticks // 2 hours
- // If the first delay has a custom start time
- // No custom time, no custom time, between 80 to 100 minutes respectively.
- var/list/event_first_run = list(EVENT_LEVEL_MUNDANE = null, EVENT_LEVEL_MODERATE = null, EVENT_LEVEL_MAJOR = list("lower" = 48000, "upper" = 60000))
- // The lowest delay until next event
- // 10, 30, 50 minutes respectively
- var/list/event_delay_lower = list(EVENT_LEVEL_MUNDANE = 6000, EVENT_LEVEL_MODERATE = 18000, EVENT_LEVEL_MAJOR = 30000)
- // The upper delay until next event
- // 15, 45, 70 minutes respectively
- var/list/event_delay_upper = list(EVENT_LEVEL_MUNDANE = 9000, EVENT_LEVEL_MODERATE = 27000, EVENT_LEVEL_MAJOR = 42000)
-
- var/starlight = 0 // Whether space turfs have ambient light or not
- var/allow_holidays = 0
- var/player_overflow_cap = 0 //number of players before the server starts rerouting
- var/list/overflow_whitelist = list() //whitelist for overflow
-
- var/disable_away_missions = 0 // disable away missions
- var/disable_space_ruins = 0 //disable space ruins
-
- var/extra_space_ruin_levels_min = 4
- var/extra_space_ruin_levels_max = 8
-
- var/ooc_allowed = 1
- var/looc_allowed = 1
- var/dooc_allowed = 1
- var/dsay_allowed = 1
-
- var/disable_lobby_music = 0 // Disables the lobby music
- var/disable_cid_warn_popup = 0 //disables the annoying "You have already logged in this round, disconnect or be banned" popup, because it annoys the shit out of me when testing.
-
- var/max_loadout_points = 5 // How many points can be spent on extra items in character setup
-
- var/disable_ooc_emoji = 0 // prevents people from using emoji in OOC
-
- var/shutdown_on_reboot = 0 // Whether to shut down the world instead of rebooting it
-
- var/disable_karma = 0 // Disable all karma functions and unlock karma jobs by default
-
- // StonedMC
- var/tick_limit_mc_init = TICK_LIMIT_MC_INIT_DEFAULT //SSinitialization throttling
-
- // Highpop tickrates
- var/base_mc_tick_rate = 1
- var/high_pop_mc_tick_rate = 1.1
-
- var/high_pop_mc_mode_amount = 65
- var/disable_high_pop_mc_mode_amount = 60
-
- // Nightshift
- var/randomize_shift_time = FALSE
- var/enable_night_shifts = FALSE
-
- // Developer
- var/developer_express_start = 0
-
- // Automatic localhost admin disable
- var/disable_localhost_admin = 0
-
- //Start now warning
- var/start_now_confirmation = 0
-
- // Lavaland
- var/lavaland_budget = 60
-
- //cube monkey limit
- var/cubemonkeycap = 20
-
- // Makes gamemodes respect player limits
- var/enable_gamemode_player_limit = 0
-
- /// BYOND account age limit for notifcations of new accounts (Any accounts older than this value will not send notifications on first join)
- var/byond_account_age_threshold = 7
-
- /// Are discord webhooks enabled?
- var/discord_webhooks_enabled = FALSE
-
- /// Role ID to be pinged for administrative events
- var/discord_admin_role_id = null // Intentional null usage
-
- /// Webhook URLs for the main public webhook
- var/list/discord_main_webhook_urls = list()
-
- /// Webhook URLs for the admin webhook
- var/list/discord_admin_webhook_urls = list()
-
- /// Webhook URLs for the mentor webhook
- var/list/discord_mentor_webhook_urls = list()
-
- /// Do we want to forward all adminhelps to the discord or just ahelps when admins are offline.
- /// (This does not mean all ahelps are pinged, only ahelps sent when staff are offline get the ping, regardless of this setting)
- var/discord_forward_all_ahelps = FALSE
-
- /// URL for the CentCom Ban DB API
- var/centcom_ban_db_url = null
-
- /// Timeout (seconds) for async SQL queries
- var/async_sql_query_timeout = 10 SECONDS
-
- /// Limit of how many SQL threads can run at once
- var/rust_sql_thread_limit = 50
-
- /// Max amount of CIDs that one ckey can have attached to them before they trip a warning
- var/max_client_cid_history = 3
-
- /// Enable auto profiler of rounds
- var/auto_profile = FALSE
-
- // Enable map voting
- var/map_voting_enabled = FALSE
-
- // 2FA auth host
- var/_2fa_auth_host = null
-
-/datum/configuration/New()
- for(var/T in subtypesof(/datum/game_mode))
- var/datum/game_mode/M = T
-
- if(initial(M.config_tag))
- if(!(initial(M.config_tag) in modes)) // ensure each mode is added only once
- src.modes += initial(M.config_tag)
- src.mode_names[initial(M.config_tag)] = initial(M.name)
- src.probabilities[initial(M.config_tag)] = initial(M.probability)
- if(initial(M.votable))
- src.votable_modes += initial(M.config_tag)
- src.votable_modes += "secret"
-
-/datum/configuration/proc/load(filename, type = "config") //the type can also be game_options, in which case it uses a different switch. not making it separate to not copypaste code - Urist
- if(IsAdminAdvancedProcCall())
- to_chat(usr, "Config reload blocked: Advanced ProcCall detected.")
- message_admins("[key_name(usr)] attempted to reload configuration via advanced proc-call")
- log_admin("[key_name(usr)] attempted to reload configuration via advanced proc-call")
- return
- var/list/Lines = file2list(filename)
-
- for(var/t in Lines)
- if(!t) continue
-
- t = trim(t)
- if(length(t) == 0)
- continue
- else if(copytext(t, 1, 2) == "#")
- continue
-
- var/pos = findtext(t, " ")
- var/name = null
- var/value = null
-
- if(pos)
- name = lowertext(copytext(t, 1, pos))
- value = copytext(t, pos + 1)
- else
- name = lowertext(t)
-
- if(!name)
- continue
-
- if(type == "config")
- switch(name)
- if("resource_urls")
- config.resource_urls = splittext(value, " ")
-
- if("admin_legacy_system")
- config.admin_legacy_system = 1
-
- if("ban_legacy_system")
- config.ban_legacy_system = 1
-
- if("use_age_restriction_for_jobs")
- config.use_age_restriction_for_jobs = 1
-
- if("use_age_restriction_for_antags")
- config.use_age_restriction_for_antags = 1
-
- if("use_exp_tracking")
- config.use_exp_tracking = 1
-
- if("use_exp_restrictions")
- config.use_exp_restrictions = 1
-
- if("use_exp_restrictions_admin_bypass")
- config.use_exp_restrictions_admin_bypass = 1
-
- if("jobs_have_minimal_access")
- config.jobs_have_minimal_access = 1
-
- if("shadowling_max_age")
- config.shadowling_max_age = text2num(value)
-
- if("warn_afk_minimum")
- config.warn_afk_minimum = text2num(value)
- if("auto_cryo_afk")
- config.auto_cryo_afk = text2num(value)
- if("auto_despawn_afk")
- config.auto_despawn_afk = text2num(value)
-
- if("auto_cryo_ssd_mins")
- config.auto_cryo_ssd_mins = text2num(value)
- if("ssd_warning")
- config.ssd_warning = 1
-
- if("list_afk_minimum")
- config.list_afk_minimum = text2num(value)
-
- if("ipintel_email")
- if(value != "ch@nge.me")
- config.ipintel_email = value
- if("ipintel_rating_bad")
- config.ipintel_rating_bad = text2num(value)
- if("ipintel_domain")
- config.ipintel_domain = value
- if("ipintel_save_good")
- config.ipintel_save_good = text2num(value)
- if("ipintel_save_bad")
- config.ipintel_save_bad = text2num(value)
- if("ipintel_maxplaytime")
- config.ipintel_maxplaytime = text2num(value)
- if("ipintel_whitelist")
- config.ipintel_whitelist = 1
- if("ipintel_detailsurl")
- config.ipintel_detailsurl = value
-
- if("forum_link_url")
- config.forum_link_url = value
-
- if("forum_playerinfo_url")
- config.forum_playerinfo_url = value
-
- if("log_ooc")
- config.log_ooc = 1
-
- if("log_access")
- config.log_access = 1
-
- if("log_say")
- config.log_say = 1
-
- if("log_admin")
- config.log_admin = 1
-
- if("log_debug")
- config.log_debug = 1
-
- if("log_game")
- config.log_game = 1
-
- if("log_vote")
- config.log_vote = 1
-
- if("log_whisper")
- config.log_whisper = 1
-
- if("log_attack")
- config.log_attack = 1
-
- if("log_emote")
- config.log_emote = 1
-
- if("log_adminchat")
- config.log_adminchat = 1
-
- if("log_adminwarn")
- config.log_adminwarn = 1
-
- if("log_pda")
- config.log_pda = 1
-
- if("log_world_output")
- config.log_world_output = 1
-
- if("log_hrefs")
- config.log_hrefs = 1
-
- if("log_runtime")
- config.log_runtimes = 1
-
- if("mentors")
- config.mods_are_mentors = 1
-
- if("allow_admin_ooccolor")
- config.allow_admin_ooccolor = 1
-
- if("pregame_timestart")
- config.pregame_timestart = text2num(value)
-
- if("allow_vote_restart")
- config.allow_vote_restart = 1
-
- if("allow_vote_mode")
- config.allow_vote_mode = 1
-
- if("no_dead_vote")
- config.vote_no_dead = 1
-
- if("vote_autotransfer_initial")
- config.vote_autotransfer_initial = text2num(value)
-
- if("vote_autotransfer_interval")
- config.vote_autotransfer_interval = text2num(value)
-
- if("default_no_vote")
- config.vote_no_default = 1
-
- if("vote_delay")
- config.vote_delay = text2num(value)
-
- if("vote_period")
- config.vote_period = text2num(value)
-
- if("allow_ai")
- config.allow_ai = 1
-
-// if("authentication")
-// config.enable_authentication = 1
-
- if("norespawn")
- config.respawn = 0
-
- if("servername")
- config.server_name = value
-
- if("server_tag_line")
- config.server_tag_line = value
-
- if("server_extra_features")
- config.server_extra_features = value
-
- if("serversuffix")
- config.server_suffix = 1
-
- if("minimum_client_build")
- config.minimum_client_build = text2num(value)
-
- if("nudge_script_path")
- config.nudge_script_path = value
-
- if("server")
- config.server = value
-
- if("banappeals")
- config.banappeals = value
-
- if("wikiurl")
- config.wikiurl = value
-
- if("forumurl")
- config.forumurl = value
-
- if("rulesurl")
- config.rulesurl = value
-
- if("githuburl")
- config.githuburl = value
-
- if("discordurl")
- config.discordurl = value
-
- if("discordforumurl")
- config.discordforumurl = value
-
- if("donationsurl")
- config.donationsurl = value
-
- if("repositoryurl")
- config.repositoryurl = value
-
- if("guest_jobban")
- config.guest_jobban = 1
-
- if("guest_ban")
- GLOB.guests_allowed = 0
-
- if("panic_bunker_threshold")
- config.panic_bunker_threshold = text2num(value)
-
- if("usewhitelist")
- config.usewhitelist = 1
-
- if("feature_object_spell_system")
- config.feature_object_spell_system = 1
-
- if("allow_metadata")
- config.allow_Metadata = 1
-
- if("traitor_scaling")
- config.traitor_scaling = 1
-
- if("protect_roles_from_antagonist")
- config.protect_roles_from_antagonist = 1
-
- if("probability")
- var/prob_pos = findtext(value, " ")
- var/prob_name = null
- var/prob_value = null
-
- if(prob_pos)
- prob_name = lowertext(copytext(value, 1, prob_pos))
- prob_value = copytext(value, prob_pos + 1)
- if(prob_name in config.modes)
- config.probabilities[prob_name] = text2num(prob_value)
- else
- log_config("Unknown game mode probability configuration definition: [prob_name].")
- else
- log_config("Incorrect probability configuration definition: [prob_name] [prob_value].")
-
- if("allow_random_events")
- config.allow_random_events = 1
-
- if("load_jobs_from_txt")
- load_jobs_from_txt = 1
-
- if("forbid_singulo_possession")
- forbid_singulo_possession = 1
-
- if("check_randomizer")
- check_randomizer = 1
-
- if("popup_admin_pm")
- config.popup_admin_pm = 1
-
- if("allow_holidays")
- config.allow_holidays = 1
-
- if("ticklag")
- Ticklag = text2num(value)
-
- if("socket_talk")
- socket_talk = text2num(value)
-
- if("allow_antag_hud")
- config.antag_hud_allowed = 1
-
- if("antag_hud_restricted")
- config.antag_hud_restricted = 1
-
- if("humans_need_surnames")
- humans_need_surnames = 1
-
- if("automute_on")
- automute_on = 1
-
- if("usealienwhitelist")
- usealienwhitelist = 1
-
- if("alien_player_ratio")
- limitalienplayers = 1
- alien_to_human_ratio = text2num(value)
-
- if("assistant_maint")
- config.assistant_maint = 1
-
- if("gateway_delay")
- config.gateway_delay = text2num(value)
-
- if("continuous_rounds")
- config.continuous_rounds = 1
-
- if("ghost_interaction")
- config.ghost_interaction = 1
-
- if("comms_password")
- config.comms_password = value
-
- if("python_path")
- if(value)
- GLOB.python_path = value
- else
- if(world.system_type == UNIX)
- GLOB.python_path = "/usr/bin/env python2"
- else //probably windows, if not this should work anyway
- GLOB.python_path = "pythonw"
-
- if("assistant_limit")
- config.assistantlimit = 1
-
- if("assistant_ratio")
- config.assistantratio = text2num(value)
-
- if("allow_drone_spawn")
- config.allow_drone_spawn = text2num(value)
-
- if("drone_build_time")
- config.drone_build_time = text2num(value)
-
- if("max_maint_drones")
- config.max_maint_drones = text2num(value)
-
- if("expected_round_length")
- config.expected_round_length = text2num(value) MINUTES
-
- if("event_custom_start_mundane")
- var/values = text2numlist(value, ";")
- config.event_first_run[EVENT_LEVEL_MUNDANE] = list("lower" = values[1] MINUTES, "upper" = values[2] MINUTES)
-
- if("event_custom_start_moderate")
- var/values = text2numlist(value, ";")
- config.event_first_run[EVENT_LEVEL_MODERATE] = list("lower" = values[1] MINUTES, "upper" = values[2] MINUTES)
-
- if("event_custom_start_major")
- var/values = text2numlist(value, ";")
- config.event_first_run[EVENT_LEVEL_MAJOR] = list("lower" = values[1] MINUTES, "upper" = values[2] MINUTES)
-
- if("event_delay_lower")
- var/values = text2numlist(value, ";")
- config.event_delay_lower[EVENT_LEVEL_MUNDANE] = values[1] MINUTES
- config.event_delay_lower[EVENT_LEVEL_MODERATE] = values[2] MINUTES
- config.event_delay_lower[EVENT_LEVEL_MAJOR] = values[3] MINUTES
-
- if("event_delay_upper")
- var/values = text2numlist(value, ";")
- config.event_delay_upper[EVENT_LEVEL_MUNDANE] = values[1] MINUTES
- config.event_delay_upper[EVENT_LEVEL_MODERATE] = values[2] MINUTES
- config.event_delay_upper[EVENT_LEVEL_MAJOR] = values[3] MINUTES
-
- if("starlight")
- config.starlight = 1
-
- if("player_reroute_cap")
- var/vvalue = text2num(value)
- config.player_overflow_cap = vvalue >= 0 ? vvalue : 0
-
- if("overflow_server_url")
- config.overflow_server_url = value
-
- if("disable_away_missions")
- config.disable_away_missions = 1
-
- if("disable_space_ruins")
- config.disable_space_ruins = 1
-
- if("disable_lobby_music")
- config.disable_lobby_music = 1
-
- if("disable_cid_warn_popup")
- config.disable_cid_warn_popup = 1
-
- if("extra_space_ruin_levels_min")
- var/vvalue = text2num(value)
- config.extra_space_ruin_levels_min = max(vvalue, 0)
-
- if("extra_space_ruin_levels_max")
- var/vvalue = text2num(value)
- config.extra_space_ruin_levels_max = max(vvalue, 0)
-
- if("max_loadout_points")
- config.max_loadout_points = text2num(value)
-
- if("round_abandon_penalty_period")
- config.round_abandon_penalty_period = text2num(value) MINUTES
-
- if("medal_hub_address")
- config.medal_hub_address = value
-
- if("medal_hub_password")
- config.medal_hub_password = value
-
- if("disable_ooc_emoji")
- config.disable_ooc_emoji = 1
-
- if("shutdown_on_reboot")
- config.shutdown_on_reboot = 1
-
- if("shutdown_shell_command")
- GLOB.shutdown_shell_command = value
-
- if("disable_karma")
- config.disable_karma = 1
-
- if("start_now_confirmation")
- config.start_now_confirmation = 1
-
- if("tick_limit_mc_init")
- config.tick_limit_mc_init = text2num(value)
- if("base_mc_tick_rate")
- config.base_mc_tick_rate = text2num(value)
- if("high_pop_mc_tick_rate")
- config.high_pop_mc_tick_rate = text2num(value)
- if("high_pop_mc_mode_amount")
- config.high_pop_mc_mode_amount = text2num(value)
- if("disable_high_pop_mc_mode_amount")
- config.disable_high_pop_mc_mode_amount = text2num(value)
- if("developer_express_start")
- config.developer_express_start = 1
- if("disable_localhost_admin")
- config.disable_localhost_admin = 1
- if("enable_gamemode_player_limit")
- config.enable_gamemode_player_limit = 1
- if("byond_account_age_threshold")
- config.byond_account_age_threshold = text2num(value)
- // Discord stuff
- if("enable_discord_webhooks")
- discord_webhooks_enabled = TRUE
- if("discord_webhooks_admin_role_id")
- discord_admin_role_id = "[value]" // This MUST be a string because BYOND doesnt like massive integers
- if("discord_webhooks_main_url")
- discord_main_webhook_urls = splittext(value, "|")
- if("discord_webhooks_admin_url")
- discord_admin_webhook_urls = splittext(value, "|")
- if("discord_webhooks_mentor_url")
- discord_mentor_webhook_urls = splittext(value, "|")
- if("discord_forward_all_ahelps")
- discord_forward_all_ahelps = TRUE
- // End discord stuff
- if("centcom_ban_db_url")
- centcom_ban_db_url = value
- if("max_client_cid_history")
- max_client_cid_history = text2num(value)
- if("enable_auto_profiler")
- auto_profile = TRUE
- if("enable_map_voting")
- map_voting_enabled = TRUE
- if("2fa_host")
- _2fa_auth_host = value
- else
- log_config("Unknown setting in configuration: '[name]'")
-
-
- else if(type == "game_options")
- value = text2num(value)
-
- switch(name)
- if("revival_pod_plants")
- config.revival_pod_plants = value
- if("revival_cloning")
- config.revival_cloning = value
- if("revival_brain_life")
- config.revival_brain_life = value
- if("auto_toggle_ooc_during_round")
- config.auto_toggle_ooc_during_round = 1
- if("run_speed")
- config.run_speed = value
- if("walk_speed")
- config.walk_speed = value
- if("human_delay")
- config.human_delay = value
- if("robot_delay")
- config.robot_delay = value
- if("monkey_delay")
- config.monkey_delay = value
- if("alien_delay")
- config.alien_delay = value
- if("slime_delay")
- config.slime_delay = value
- if("animal_delay")
- config.animal_delay = value
- if("bones_can_break")
- config.bones_can_break = value
- if("shuttle_refuel_delay")
- config.shuttle_refuel_delay = text2num(value)
- if("traitor_objectives_amount")
- config.traitor_objectives_amount = text2num(value)
- if("reactionary_explosions")
- config.reactionary_explosions = 1
- if("bombcap")
- var/BombCap = text2num(value)
- if(!BombCap)
- continue
- if(BombCap < 4)
- BombCap = 4
- if(BombCap > 128)
- BombCap = 128
-
- GLOB.max_ex_devastation_range = round(BombCap/4)
- GLOB.max_ex_heavy_range = round(BombCap/2)
- GLOB.max_ex_light_range = BombCap
- GLOB.max_ex_flash_range = BombCap
- GLOB.max_ex_flame_range = BombCap
- if("default_laws")
- config.default_laws = text2num(value)
- if("randomize_shift_time")
- config.randomize_shift_time = TRUE
- if("enable_night_shifts")
- config.enable_night_shifts = TRUE
- if("lavaland_budget")
- config.lavaland_budget = text2num(value)
- if("cubemonkey_cap")
- config.cubemonkeycap = text2num(value)
- else
- log_config("Unknown setting in configuration: '[name]'")
-
-/datum/configuration/proc/loadsql(filename) // -- TLE
- if(IsAdminAdvancedProcCall())
- to_chat(usr, "SQL configuration reload blocked: Advanced ProcCall detected.")
- message_admins("[key_name(usr)] attempted to reload SQL configuration via advanced proc-call")
- log_admin("[key_name(usr)] attempted to reload SQL configuration via advanced proc-call")
- return
- var/list/Lines = file2list(filename)
- for(var/t in Lines)
- if(!t) continue
-
- t = trim(t)
- if(length(t) == 0)
- continue
- else if(copytext(t, 1, 2) == "#")
- continue
-
- var/pos = findtext(t, " ")
- var/name = null
- var/value = null
-
- if(pos)
- name = lowertext(copytext(t, 1, pos))
- value = copytext(t, pos + 1)
- else
- name = lowertext(t)
-
- if(!name)
- continue
-
- switch(name)
- if("sql_enabled")
- config.sql_enabled = 1
- if("address")
- sqladdress = value
- if("port")
- sqlport = value
- if("feedback_database")
- sqlfdbkdb = value
- if("feedback_login")
- sqlfdbklogin = value
- if("feedback_password")
- sqlfdbkpass = value
- if("feedback_tableprefix")
- sqlfdbktableprefix = value
- if("db_version")
- sql_version = text2num(value)
- if("async_query_timeout")
- async_sql_query_timeout = text2num(value)
- if("rust_sql_thread_limit")
- config.rust_sql_thread_limit = text2num(value)
- else
- log_config("Unknown setting in configuration: '[name]'")
-
-/datum/configuration/proc/loadoverflowwhitelist(filename)
- var/list/Lines = file2list(filename)
- for(var/t in Lines)
- if(!t) continue
-
- t = trim(t)
- if(length(t) == 0)
- continue
- else if(copytext(t, 1, 2) == "#")
- continue
-
- config.overflow_whitelist += t
-
-/datum/configuration/proc/pick_mode(mode_name)
- for(var/T in subtypesof(/datum/game_mode))
- var/datum/game_mode/M = T
- if(initial(M.config_tag) && initial(M.config_tag) == mode_name)
- return new T()
- return new /datum/game_mode/extended()
-
-/datum/configuration/proc/get_runnable_modes()
- var/list/datum/game_mode/runnable_modes = new
- for(var/T in subtypesof(/datum/game_mode))
- var/datum/game_mode/M = new T()
-// to_chat(world, "DEBUG: [T], tag=[M.config_tag], prob=[probabilities[M.config_tag]]")
- if(!(M.config_tag in modes))
- qdel(M)
- continue
- if(probabilities[M.config_tag]<=0)
- qdel(M)
- continue
- if(M.can_start())
- runnable_modes[M] = probabilities[M.config_tag]
-// to_chat(world, "DEBUG: runnable_mode\[[runnable_modes.len]\] = [M.config_tag]")
- return runnable_modes
-
-/datum/configuration/proc/load_rank_colour_map()
- var/list/lines = file2list("config/rank_colours.txt")
-
- for(var/line in lines)
- // Skip newlines
- if(!length(line))
- continue
- // Skip comments
- if(line[1] == "#")
- continue
-
- //Split the line at every " - "
- var/list/split_holder = splittext(line, " - ")
- if(!length(split_holder))
- continue
-
- // Rank is before the " - "
- var/rank = split_holder[1]
- if(!rank)
- continue
-
- // Color is after the " - "
- var/colour = ""
- if(length(split_holder) >= 2)
- colour = split_holder[2]
-
- if(rank && colour)
- GLOB.rank_colour_map[rank] = colour
- else
- stack_trace("Invalid colour for rank '[rank]' in config/rank_colours.txt")
diff --git a/code/controllers/configuration/__config_defines.dm b/code/controllers/configuration/__config_defines.dm
new file mode 100644
index 00000000000..f5262401107
--- /dev/null
+++ b/code/controllers/configuration/__config_defines.dm
@@ -0,0 +1,40 @@
+// Config protection states
+#define PROTECTION_PRIVATE "PRIVATE"
+#define PROTECTION_READONLY "READONLY"
+#define PROTECTION_NONE "NONE"
+/// Wrapper to not overwrite a variable if a list key doesnt exist. Auto casts to bools.
+#define CONFIG_LOAD_BOOL(target, input) \
+ if(!isnull(input)) {\
+ target = ((input == 1) ? TRUE : FALSE)\
+ }
+
+/// Wrapper to not overwrite a variable if a list key doesnt exist. Auto casts to number.
+#define CONFIG_LOAD_NUM(target, input) \
+ if(!isnull(input)) {\
+ target = text2num(input)\
+ }
+
+/// Wrapper to not overwrite a variable if a list key doesnt exist. Auto casts to number, and accepts a macro argument for number maths (ds to min for example)
+#define CONFIG_LOAD_NUM_MULT(target, input, multiplier) \
+ if(!isnull(input)) {\
+ target = text2num(input) multiplier\
+ }
+
+/// Wrapper to not overwrite a variable if a list key doesnt exist. Auto casts to string.
+#define CONFIG_LOAD_STR(target, input) \
+ if(!isnull(input)) {\
+ target = "[input]"\
+ }
+
+/// Wrapper to not overwrite a variable if a list key doesnt exist. No casting done.
+#define CONFIG_LOAD_RAW(target, input) \
+ if(!isnull(input)) {\
+ target = input\
+ }
+
+/// Wrapper to not overwrite a variable if a list key doesnt exist. Ensures target is a list.
+#define CONFIG_LOAD_LIST(target, input) \
+ if(islist(input)) {\
+ target = input\
+ }
+
diff --git a/code/controllers/configuration/configuration_core.dm b/code/controllers/configuration/configuration_core.dm
new file mode 100644
index 00000000000..c4938d3efc6
--- /dev/null
+++ b/code/controllers/configuration/configuration_core.dm
@@ -0,0 +1,142 @@
+// Paradise SS13 Configuration System
+// Refactored to use config sections as part of a single TOML file, since thats much better to deal with
+
+/// Global configuration datum holder for all the config sections
+GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new())
+
+/// Represents a base configuration datum. Has everything else bundled into it
+/datum/server_configuration
+ /// Holder for the admin configuration datum
+ var/datum/configuration_section/admin_configuration/admin
+ /// Holder for the AFK configuration datum
+ var/datum/configuration_section/afk_configuration/afk
+ /// Holder for the custom sprites configuration datum
+ var/datum/configuration_section/custom_sprites_configuration/custom_sprites
+ /// Holder for the DB configuration datum
+ var/datum/configuration_section/database_configuration/database
+ /// Holder for the Discord configuration datum
+ var/datum/configuration_section/discord_configuration/discord
+ /// Holder for the Event configuration datum
+ var/datum/configuration_section/event_configuration/event
+ /// Holder for the gamemode configuration datum
+ var/datum/configuration_section/gamemode_configuration/gamemode
+ /// Holder for the gateway configuration datum
+ var/datum/configuration_section/gateway_configuration/gateway
+ /// Holder for the general configuration datum
+ var/datum/configuration_section/general_configuration/general
+ /// Holder for the IPIntel configuration datum
+ var/datum/configuration_section/ipintel_configuration/ipintel
+ /// Holder for the job configuration datum
+ var/datum/configuration_section/job_configuration/jobs
+ /// Holder for the logging configuration datum
+ var/datum/configuration_section/logging_configuration/logging
+ /// Holder for the MC configuration datum
+ var/datum/configuration_section/mc_configuration/mc
+ /// Holder for the MC configuration datum
+ var/datum/configuration_section/movement_configuration/movement
+ /// Holder for the overflow configuration datum
+ var/datum/configuration_section/overflow_configuration/overflow
+ /// Holder for the ruins configuration datum
+ var/datum/configuration_section/ruin_configuration/ruins
+ /// Holder for the system configuration datum
+ var/datum/configuration_section/system_configuration/system
+ /// Holder for the URL configuration datum
+ var/datum/configuration_section/url_configuration/url
+ /// Holder for the voting configuration datum
+ var/datum/configuration_section/vote_configuration/vote
+
+
+/datum/server_configuration/Destroy(force)
+ SHOULD_CALL_PARENT(FALSE)
+ // This is going to stay existing. I dont care.
+ return QDEL_HINT_LETMELIVE
+
+/datum/server_configuration/CanProcCall(procname)
+ return FALSE // No thanks
+
+/datum/server_configuration/proc/load_configuration()
+ var/start = start_watch() // Time tracking
+
+ // Initialize all our holders
+ admin = new()
+ afk = new()
+ custom_sprites = new()
+ database = new()
+ discord = new()
+ event = new()
+ gamemode = new()
+ gateway = new()
+ general = new()
+ ipintel = new()
+ jobs = new()
+ logging = new()
+ mc = new()
+ movement = new()
+ overflow = new()
+ ruins = new()
+ system = new()
+ url = new()
+ vote = new()
+
+ // Load our stuff up
+ var/config_file = "config/config.toml"
+ if(!fexists(config_file))
+ config_file = "config/example/config.toml" // Fallback to example if user hasnt setup config properly
+ var/raw_json = rustg_toml2json(config_file)
+ var/list/raw_config_data = json_decode(raw_json)
+
+ // Now pass through all our stuff
+ admin.load_data(raw_config_data["admin_configuration"])
+ afk.load_data(raw_config_data["afk_configuration"])
+ custom_sprites.load_data(raw_config_data["custom_sprites_configuration"])
+ database.load_data(raw_config_data["database_configuration"])
+ discord.load_data(raw_config_data["discord_configuration"])
+ event.load_data(raw_config_data["event_configuration"])
+ gamemode.load_data(raw_config_data["gamemode_configuration"])
+ gateway.load_data(raw_config_data["gateway_configuration"])
+ general.load_data(raw_config_data["general_configuration"])
+ ipintel.load_data(raw_config_data["ipintel_configuration"])
+ jobs.load_data(raw_config_data["job_configuration"])
+ logging.load_data(raw_config_data["logging_configuration"])
+ mc.load_data(raw_config_data["mc_configuration"])
+ movement.load_data(raw_config_data["movement_configuration"])
+ overflow.load_data(raw_config_data["overflow_configuration"])
+ ruins.load_data(raw_config_data["ruin_configuration"])
+ system.load_data(raw_config_data["system_configuration"])
+ url.load_data(raw_config_data["url_configuration"])
+ vote.load_data(raw_config_data["voting_configuration"])
+
+ // And report the load
+ DIRECT_OUTPUT(world.log, "Config loaded in [stop_watch(start)]s")
+
+
+/datum/configuration_section
+ /// See __config_defines.dm
+ var/protection_state = PROTECTION_NONE
+
+/datum/configuration_section/proc/load_data(list/data)
+ CRASH("load() not overriden for [type]!")
+
+// Maximum protection
+/datum/configuration_section/can_vv_get(var_name)
+ if(protection_state == PROTECTION_PRIVATE)
+ return FALSE
+ return ..()
+
+/datum/configuration_section/vv_edit_var(var_name, var_value)
+ if(protection_state in list(PROTECTION_PRIVATE, PROTECTION_READONLY))
+ return FALSE
+ return ..()
+
+/datum/configuration_section/vv_get_var(var_name)
+ if(protection_state == PROTECTION_PRIVATE)
+ return FALSE
+ return ..()
+
+/datum/configuration_section/Destroy(force)
+ SHOULD_CALL_PARENT(FALSE)
+ // This is going to stay existing. I dont care.
+ return QDEL_HINT_LETMELIVE
+
+/datum/configuration_section/CanProcCall(procname)
+ return FALSE // No thanks
diff --git a/code/controllers/configuration/sections/admin_configuration.dm b/code/controllers/configuration/sections/admin_configuration.dm
new file mode 100644
index 00000000000..42bcbff4bc1
--- /dev/null
+++ b/code/controllers/configuration/sections/admin_configuration.dm
@@ -0,0 +1,43 @@
+/// Config holder for all admin related things
+/datum/configuration_section/admin_configuration
+ protection_state = PROTECTION_READONLY // Dont even think about it
+ /// Do we want to load admins from the database?
+ var/use_database_admins = FALSE
+ /// Do we want to auto enable admin rights if you connect from localhost?
+ var/enable_localhost_autoadmin = TRUE
+ /// Do we want to allow admins to set their own OOC colour?
+ var/allow_admin_ooc_colour = TRUE
+ /// Assoc list of admin ranks and their stuff. key: rank name string | value: list of rights
+ var/list/rank_rights_map = list()
+ /// Assoc list of admin ckeys and their ranks. key: ckey | value: rank name
+ var/list/ckey_rank_map = list()
+ /// Assoc list of admin ranks and their colours. key: rank | value: rank colour
+ var/list/rank_colour_map = list()
+
+/datum/configuration_section/admin_configuration/load_data(list/data)
+ // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
+ CONFIG_LOAD_BOOL(use_database_admins, data["use_database_admins"])
+ CONFIG_LOAD_BOOL(enable_localhost_autoadmin, data["enable_localhost_autoadmin"])
+ CONFIG_LOAD_BOOL(allow_admin_ooc_colour, data["allow_admin_ooc_colour"])
+
+ // Load admin rank tokens
+ if(islist(data["admin_ranks"]))
+ rank_rights_map.Cut()
+ for(var/list/kvset in data["admin_ranks"])
+ rank_rights_map[kvset["name"]] = kvset["rights"]
+
+ // Load admin assignments
+ if(islist(data["admin_assignments"]))
+ ckey_rank_map.Cut()
+ for(var/list/kvset in data["admin_assignments"])
+ ckey_rank_map[kvset["ckey"]] = kvset["rank"]
+
+ // Load admin colours
+ if(islist(data["admin_rank_colour_map"]))
+ rank_colour_map.Cut()
+ for(var/list/kvset in data["admin_rank_colour_map"])
+ rank_colour_map[kvset["name"]] = kvset["colour"]
+
+ // For the person who asks "Why not put admin datum generation in this step?", well I will tell you why
+ // Admins can be reloaded at runtime when DB edits are made and such, and I dont want an entire config reload to be part of this
+ // Separation makes sense. That and in prod we use the DB anyways.
diff --git a/code/controllers/configuration/sections/afk_configuration.dm b/code/controllers/configuration/sections/afk_configuration.dm
new file mode 100644
index 00000000000..90e2c6b7c67
--- /dev/null
+++ b/code/controllers/configuration/sections/afk_configuration.dm
@@ -0,0 +1,17 @@
+/// Config holder for all AFK related things
+/datum/configuration_section/afk_configuration
+ /// Minutes before someone gets an AFK warning
+ var/warning_minutes = 0
+ /// Minutes before someone is auto moved to cryo
+ var/auto_cryo_minutes = 0
+ /// Minutes before someone is auto despawned
+ var/auto_despawn_minutes = 0
+ /// Time before SSD people are auto cryo'd
+ var/ssd_auto_cryo_minutes = 0
+
+/datum/configuration_section/afk_configuration/load_data(list/data)
+ // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
+ CONFIG_LOAD_NUM(warning_minutes, data["afk_warning_minutes"])
+ CONFIG_LOAD_NUM(auto_cryo_minutes, data["afk_auto_cryo_minutes"])
+ CONFIG_LOAD_NUM(auto_despawn_minutes, data["afk_auto_despawn_minutes"])
+ CONFIG_LOAD_NUM(ssd_auto_cryo_minutes, data["ssd_auto_cryo_minutes"])
diff --git a/code/controllers/configuration/sections/custom_sprites_configuration.dm b/code/controllers/configuration/sections/custom_sprites_configuration.dm
new file mode 100644
index 00000000000..3b1c18feb70
--- /dev/null
+++ b/code/controllers/configuration/sections/custom_sprites_configuration.dm
@@ -0,0 +1,25 @@
+/// Config holder for all things regarding custom sprites
+/datum/configuration_section/custom_sprites_configuration
+ /// List of ckeys that have custom cyborg skins
+ var/list/cyborg_ckeys = list()
+ /// List of ckeys that have custom AI core skins
+ var/list/ai_core_ckeys = list()
+ /// List of ckeys that have custom AI hologram skins
+ var/list/ai_hologram_ckeys = list()
+ /// List of ckeys that have custom pAI holoforms
+ var/list/pai_holoform_ckeys = list()
+ /// Assoc of ckeys that have custom pAI screens. Key: ckey | value: list of icon states
+ var/list/ipc_screen_map = list()
+
+/datum/configuration_section/custom_sprites_configuration/load_data(list/data)
+ // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
+ CONFIG_LOAD_LIST(cyborg_ckeys, data["cyborgs"])
+ CONFIG_LOAD_LIST(ai_core_ckeys, data["ai_core"])
+ CONFIG_LOAD_LIST(ai_hologram_ckeys, data["ai_hologram"])
+ CONFIG_LOAD_LIST(pai_holoform_ckeys, data["pai_holoform"])
+
+ // Load the ipc screens
+ if(islist(data["ipc_screens"]))
+ ipc_screen_map.Cut()
+ for(var/kvp in data["ipc_screens"])
+ ipc_screen_map[kvp["ckey"]] = kvp["screens"]
diff --git a/code/controllers/configuration/sections/database_configuration.dm b/code/controllers/configuration/sections/database_configuration.dm
new file mode 100644
index 00000000000..d95aedcf193
--- /dev/null
+++ b/code/controllers/configuration/sections/database_configuration.dm
@@ -0,0 +1,47 @@
+/// Config holder for all database related things
+/datum/configuration_section/database_configuration
+ protection_state = PROTECTION_PRIVATE // NO! BAD!
+ /// SQL enabled or not
+ var/enabled = FALSE
+ /// What SQL version are we on
+ var/version = 0
+ /// Address of the SQL server
+ var/address = "127.0.0.1"
+ /// Port of the SQL server
+ var/port = 3306
+ /// SQL usename
+ var/username = "root"
+ /// SQL password
+ var/password = "root" // Dont do this in prod. Please......
+ /// Database name
+ var/db = "feedback" // AA TODO: Rename to paradise_gamedb
+ /// Table prefix
+ var/table_prefix = "erro_" // AA TODO: Remove table prefixes
+ /// Time in seconds for async queries to time out
+ var/async_query_timeout = 10
+ /// Thread limit for async queries
+ var/async_thread_limit = 50
+
+/datum/configuration_section/database_configuration/load_data(list/data)
+ // UNIT TESTS ARE DEFINED - USE CUSTOM CI VALUES
+ #ifdef UNIT_TESTS
+
+ enabled = TRUE
+ table_prefix = ""
+ // This needs to happen in the CI environment to ensure the example SQL version gets updated.
+ CONFIG_LOAD_NUM(version, data["sql_version"])
+
+ #else
+ // Load the normal config. Were not in CI mode
+ // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
+ CONFIG_LOAD_BOOL(enabled, data["sql_enabled"])
+ CONFIG_LOAD_NUM(version, data["sql_version"])
+ CONFIG_LOAD_STR(address, data["sql_address"])
+ CONFIG_LOAD_NUM(port, data["sql_port"])
+ CONFIG_LOAD_STR(username, data["sql_username"])
+ CONFIG_LOAD_STR(password, data["sql_password"])
+ CONFIG_LOAD_STR(db, data["sql_database"])
+ CONFIG_LOAD_STR(table_prefix, data["sql_table_prefix"])
+ CONFIG_LOAD_NUM(async_query_timeout, data["async_query_timeout"])
+ CONFIG_LOAD_NUM(async_thread_limit, data["async_thread_limit"])
+ #endif
diff --git a/code/controllers/configuration/sections/discord_configuration.dm b/code/controllers/configuration/sections/discord_configuration.dm
new file mode 100644
index 00000000000..3d51c92aa42
--- /dev/null
+++ b/code/controllers/configuration/sections/discord_configuration.dm
@@ -0,0 +1,26 @@
+/// Config holder for all things relating to discord webhooks
+/datum/configuration_section/discord_configuration
+ protection_state = PROTECTION_PRIVATE // No hook reading
+ /// Are webhooks enabled at all
+ var/webhooks_enabled = FALSE
+ /// Do we want to forward all ahelps or just ones sent with no active admins
+ var/forward_all_ahelps = TRUE
+ /// Admin role to ping if no admins are online. Disables if empty string
+ var/admin_role_id = ""
+ /// List of all URLs for the main webhooks
+ var/list/main_webhook_urls = list()
+ /// List of all URLs for the admin webhooks
+ var/list/mentor_webhook_urls = list()
+ /// List of all URLs for the mentor webhooks
+ var/list/admin_webhook_urls = list()
+
+
+
+/datum/configuration_section/discord_configuration/load_data(list/data)
+ // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
+ CONFIG_LOAD_BOOL(webhooks_enabled, data["enable_discord_webhooks"])
+ CONFIG_LOAD_BOOL(forward_all_ahelps, data["forward_all_ahelps"])
+ CONFIG_LOAD_STR(admin_role_id, data["admin_role_id"])
+ CONFIG_LOAD_LIST(main_webhook_urls, data["main_webhook_urls"])
+ CONFIG_LOAD_LIST(mentor_webhook_urls, data["mentor_webhook_urls"])
+ CONFIG_LOAD_LIST(admin_webhook_urls, data["admin_webhook_urls"])
diff --git a/code/controllers/configuration/sections/event_configuration.dm b/code/controllers/configuration/sections/event_configuration.dm
new file mode 100644
index 00000000000..d169a92406d
--- /dev/null
+++ b/code/controllers/configuration/sections/event_configuration.dm
@@ -0,0 +1,61 @@
+/// Config holder for all stuff relating to ingame random events
+/datum/configuration_section/event_configuration
+ /// Do we want to enable random events at all
+ var/enable_random_events = TRUE
+ /// Assoc list of when the first event in a group can run. key: severity | value: assoc list with upper and low bounds (key: "upper"/"lower" | value: time in deciseconds)
+ var/list/first_run_times = list(
+ EVENT_LEVEL_MUNDANE = null,
+ EVENT_LEVEL_MODERATE = null,
+ EVENT_LEVEL_MAJOR = list("lower" = 40 MINUTES, "upper" = 50 MINUTES)
+ ) // <---- Whoever designed this needs to be shot
+
+ /// Assoc list of lower bounds of event delays. key: severity | value: delay (deciseconds)
+ var/list/delay_lower_bound = list(
+ EVENT_LEVEL_MUNDANE = 5 MINUTES,
+ EVENT_LEVEL_MODERATE = 15 MINUTES,
+ EVENT_LEVEL_MAJOR = 25 MINUTES
+ )
+ /// Assoc list of lower bounds of event delays. key: severity | value: delay (deciseconds)
+ var/list/delay_upper_bound = list(
+ EVENT_LEVEL_MUNDANE = 7.5 MINUTES,
+ EVENT_LEVEL_MODERATE = 22.5 MINUTES,
+ EVENT_LEVEL_MAJOR = 35 MINUTES
+ )
+ /// Expected time of a round in deciseconds
+ var/expected_round_length = 120 MINUTES // This macro is equivilent to 72,000 deciseconds
+
+/datum/configuration_section/event_configuration/load_data(list/data)
+ // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
+ CONFIG_LOAD_BOOL(enable_random_events, data["allow_random_events"])
+
+ // Wrapper cant be used here due to it being multiplied
+ if(isnum(data["expected_round_length"]))
+ expected_round_length = data["expected_round_length"] MINUTES // Convert from minutes to deciseconds
+
+ // Load event severities. This is quite awful but needs to be done so we can account for config mistakes. This event system is awful
+ if(islist(data["event_delay_lower_bounds"]))
+ CONFIG_LOAD_NUM_MULT(delay_lower_bound[EVENT_LEVEL_MUNDANE], data["event_delay_lower_bounds"]["mundane"], MINUTES)
+ CONFIG_LOAD_NUM_MULT(delay_lower_bound[EVENT_LEVEL_MODERATE], data["event_delay_lower_bounds"]["moderate"], MINUTES)
+ CONFIG_LOAD_NUM_MULT(delay_lower_bound[EVENT_LEVEL_MAJOR], data["event_delay_lower_bounds"]["major"], MINUTES)
+
+ // Same here. I hate this.
+ if(islist(data["event_delay_upper_bounds"]))
+ CONFIG_LOAD_NUM_MULT(delay_upper_bound[EVENT_LEVEL_MUNDANE], data["event_delay_upper_bounds"]["mundane"], MINUTES)
+ CONFIG_LOAD_NUM_MULT(delay_upper_bound[EVENT_LEVEL_MODERATE], data["event_delay_upper_bounds"]["moderate"], MINUTES)
+ CONFIG_LOAD_NUM_MULT(delay_upper_bound[EVENT_LEVEL_MAJOR], data["event_delay_upper_bounds"]["major"], MINUTES)
+
+ // And for the worst, the first run delays. I hate this so much -aa07
+ if(islist(data["event_initial_delays"]))
+ for(var/list/assoclist in data["event_initial_delays"])
+ var/target = null
+ switch(assoclist["severity"])
+ if("mundane")
+ target = EVENT_LEVEL_MUNDANE
+ if("moderate")
+ target = EVENT_LEVEL_MODERATE
+ if("major")
+ target = EVENT_LEVEL_MAJOR
+ ASSERT(target in list(EVENT_LEVEL_MUNDANE, EVENT_LEVEL_MODERATE, EVENT_LEVEL_MAJOR))
+ first_run_times[target] = list("lower" = assoclist["lower_bound"] MINUTES, "upper" = assoclist["upper_bound"] MINUTES)
+
+
diff --git a/code/controllers/configuration/sections/gamemode_configuration.dm b/code/controllers/configuration/sections/gamemode_configuration.dm
new file mode 100644
index 00000000000..d09e02b5c29
--- /dev/null
+++ b/code/controllers/configuration/sections/gamemode_configuration.dm
@@ -0,0 +1,96 @@
+/// Config holder for everything regarding gamemodes
+/datum/configuration_section/gamemode_configuration
+ /// List of all gamemodes (value: config-tag)
+ var/list/gamemodes = list()
+ /// Assoc list of gamemode names (key: config-tag | value: mode name)
+ var/list/gamemode_names = list()
+ /// Assoc list of gamemode probabilities (key: config-tag | value: probability)
+ var/list/probabilities = list()
+ /// List of all gamemodes that can be voted for (value: config-tag)
+ var/list/votable_modes = list()
+ /// Should antags be restricted based on account age?
+ var/antag_account_age_restriction = FALSE
+ /// Max age (in SSmobs cycles, [2 seconds]) before a shadowling starts to take damage if they have not hatched
+ var/shadowling_max_age = 600 // 20 mins
+ /// Scale amount of traitors with population
+ var/traitor_scaling = TRUE
+ /// Prevent mindshield roles getting antagonist status
+ var/prevent_mindshield_antags = TRUE
+ /// Rounds such as rev, wizard and malf end instantly when the antag has won. Enable the setting below to not do that.
+ var/disable_certain_round_early_end = FALSE
+ /// Amount of objectives traitors should get. Does not include escape or hijack.
+ var/traitor_objectives_amount = 2
+ /// Enable player limits on gamemodes? Disabling can be useful for testing
+ var/enable_gamemode_player_limit = TRUE
+
+// Dynamically setup a list of all gamemodes
+/datum/configuration_section/gamemode_configuration/New()
+ for(var/T in subtypesof(/datum/game_mode))
+ var/datum/game_mode/M = T
+
+ // Dont bother if theres no tag
+ if(!initial(M.config_tag))
+ continue
+ // Ensure each mode is added only once
+ if(initial(M.config_tag) in gamemodes)
+ continue
+
+ // Add it in
+ gamemodes += initial(M.config_tag)
+ gamemode_names[initial(M.config_tag)] = initial(M.name)
+ probabilities[initial(M.config_tag)] = initial(M.probability)
+
+ if(initial(M.votable))
+ votable_modes += initial(M.config_tag)
+
+ // Add secret to the votable pool
+ votable_modes += "secret"
+
+/datum/configuration_section/gamemode_configuration/load_data(list/data)
+ // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
+ CONFIG_LOAD_BOOL(antag_account_age_restriction, data["antag_account_age_restrictions"])
+ CONFIG_LOAD_BOOL(traitor_scaling, data["traitor_scaling"])
+ CONFIG_LOAD_BOOL(prevent_mindshield_antags, data["prevent_mindshield_antag"])
+ CONFIG_LOAD_BOOL(disable_certain_round_early_end, data["disable_certain_round_early_end"])
+ CONFIG_LOAD_BOOL(enable_gamemode_player_limit, data["enable_gamemode_player_limit"])
+
+ CONFIG_LOAD_NUM(traitor_objectives_amount, data["traitor_objective_amount"])
+ CONFIG_LOAD_NUM(shadowling_max_age, data["shadowling_max_age"])
+
+ // Load gamemode probabilities
+ if(islist(data["gamemode_probabilities"]))
+ for(var/list/assocset in data["gamemode_probabilities"])
+ // Make sure it exists
+ if(assocset["gamemode"] in gamemodes)
+ probabilities[assocset["gamemode"]] = assocset["probability"]
+ else
+ stack_trace("Gamemode [assocset["gamemode"]] has a probability in config, but does not exist!")
+
+/datum/configuration_section/gamemode_configuration/proc/pick_mode(mode_name)
+ for(var/T in subtypesof(/datum/game_mode))
+ var/datum/game_mode/M = T
+ // If the tag exists, and its the same as the mode
+ if(initial(M.config_tag) && (initial(M.config_tag) == mode_name))
+ return new T()
+
+ // Default to extended if it didnt work
+ stack_trace("Could not pick a gamemode. Defaulting to extended. (Attempted mode: [mode_name])")
+ return new /datum/game_mode/extended()
+
+/datum/configuration_section/gamemode_configuration/proc/get_runnable_modes()
+ var/list/datum/game_mode/runnable_modes = new
+ for(var/T in subtypesof(/datum/game_mode))
+ var/datum/game_mode/M = new T()
+
+ if(!(M.config_tag in gamemodes))
+ qdel(M)
+ continue
+
+ if(probabilities[M.config_tag] <= 0)
+ qdel(M)
+ continue
+
+ if(M.can_start())
+ runnable_modes[M] = probabilities[M.config_tag]
+
+ return runnable_modes
diff --git a/code/controllers/configuration/sections/gateway_configuration.dm b/code/controllers/configuration/sections/gateway_configuration.dm
new file mode 100644
index 00000000000..f9e64e5f3be
--- /dev/null
+++ b/code/controllers/configuration/sections/gateway_configuration.dm
@@ -0,0 +1,14 @@
+/// Config holder for all gateway related things
+/datum/configuration_section/gateway_configuration
+ /// Do we want to enable away missions or not
+ var/enable_away_mission = TRUE
+ /// Delay (in deciseconds) before the gateway is usable
+ var/away_mission_delay = 6000
+ /// List of all available away missions
+ var/list/enabled_away_missions = list()
+
+/datum/configuration_section/gateway_configuration/load_data(list/data)
+ // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
+ CONFIG_LOAD_BOOL(enable_away_mission, data["enable_away_mission"])
+ CONFIG_LOAD_NUM(away_mission_delay, data["away_mission_delay"])
+ CONFIG_LOAD_LIST(enabled_away_missions, data["enabled_away_missions"])
diff --git a/code/controllers/configuration/sections/general_configuration.dm b/code/controllers/configuration/sections/general_configuration.dm
new file mode 100644
index 00000000000..296304c28b7
--- /dev/null
+++ b/code/controllers/configuration/sections/general_configuration.dm
@@ -0,0 +1,137 @@
+/// Config holder for all general/misc things
+/datum/configuration_section/general_configuration
+ /// Server name for the BYOND hub
+ var/server_name = "Paradise Station"
+ /// Tagline for the hub entry
+ var/server_tag_line = "The perfect mix of RP & action"
+ /// Server features in a newline
+ var/server_features = "Medium RP, varied species/jobs"
+ /// Should bans be stored in the DB
+ var/use_database_bans = FALSE
+ /// Allow character OOC notes
+ var/allow_character_metadata = TRUE
+ /// Time in seconds for the pregame lobby
+ var/lobby_time = 240
+ /// Ban all Guest BYOND accounts
+ var/guest_ban = TRUE
+ /// Player threshold to automatically enable panic bunker
+ var/panic_bunker_threshold = 150
+ /// Allow players to use AntagHUD?
+ var/allow_antag_hud = TRUE
+ /// Forbid players from rejoining if they use AntagHUD?
+ var/restrict_antag_hud_rejoin = TRUE
+ /// Enable respanws by default?
+ var/respawn_enabled = FALSE
+ /// Enable karma? Disable to lockout awarding and unlock everything
+ var/enable_karma = TRUE
+ /// Enable CID randomiser buster?
+ var/enabled_cid_randomiser_buster = FALSE
+ /// Forbid admins from posessing and flying the singulo round
+ var/forbid_singulo_possession = FALSE
+ /// Force open a PM window when replied to? This is very annoying
+ var/popup_admin_pm = FALSE
+ /// Announce holidays (christmas, halloween, etc etc)
+ var/allow_holidays = TRUE
+ /// Enable auto muting in all chat channels
+ var/enable_auto_mute = FALSE
+ /// Show a warning to players to make them accept touching an SSD
+ var/ssd_warning = TRUE
+ /// Allow ghosts to spin chairs round
+ var/ghost_interaction = FALSE
+ /// Enable/disable starlight to light up space
+ var/starlight = TRUE
+ /// Disable lobby music?
+ var/disable_lobby_music = FALSE
+ /// Disable a popup if 2 users are on the same CID?
+ var/disable_cid_warning_popup = FALSE
+ /// Amount of loadout points non-donors should get
+ var/base_loadout_points = 5
+ /// Respawnability loss penalty for eary cryoing (minutes)
+ var/cryo_penalty_period = 30
+ /// Enable OOC emojis?
+ var/enable_ooc_emoji = TRUE
+ /// Auto start the game if on a local test server
+ var/developer_express_start = FALSE
+ /// Minimum client build. Keep above 1421 due to exploits
+ var/minimum_client_build = 1421
+ /// Give a confirm button for the "Start Now" verb
+ var/start_now_confirmation = TRUE
+ /// BYOND account age threshold for first join alerts
+ var/byond_account_age_threshold = 3
+ /// Max CIDs a client can have history of before a warning is thrown
+ var/max_client_cid_history = 20
+ /// Enable automatic profiling to profile.json
+ var/enable_auto_profiler = TRUE
+ /// Auto disable OOC on roundstart?
+ var/auto_disable_ooc = TRUE
+ /// Do we want to allow bones to break?
+ var/breakable_bones = TRUE
+ /// Enable/disable revival pod plants
+ var/enable_revival_pod_plants = TRUE
+ /// Enable/disable cloning
+ var/enable_cloning = TRUE
+ /// Randomise shift time instead of it always being 12:00?
+ var/randomise_shift_time = TRUE
+ /// Enable night-shift lighting?
+ var/enable_night_shifts = TRUE
+ /// Cap for monkey cube monkey spawns
+ var/monkey_cube_cap = 32
+ /// Enable to make explosions react to obstacles instead of ignoring them
+ var/reactionary_explosions = TRUE
+ /// Bomb cap (Devastation) Other values will be calculated around this
+ var/bomb_cap = 20
+ /// Time for a brain to keep its spark of life (deciseconds)
+ var/revival_brain_life = 10 MINUTES
+ /// Enable random AI lawsets from the default=TRUE pool
+ var/random_ai_lawset = TRUE
+
+/datum/configuration_section/general_configuration/load_data(list/data)
+ // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
+
+ // A lot of bools
+ CONFIG_LOAD_BOOL(use_database_bans, data["use_database_bans"])
+ CONFIG_LOAD_BOOL(allow_character_metadata, data["allow_character_metadata"])
+ CONFIG_LOAD_BOOL(guest_ban, data["guest_ban"])
+ CONFIG_LOAD_BOOL(allow_antag_hud, data["allow_antag_hud"])
+ CONFIG_LOAD_BOOL(restrict_antag_hud_rejoin, data["restrict_antag_hud_rejoin"])
+ CONFIG_LOAD_BOOL(respawn_enabled, data["respawn_enabled"])
+ CONFIG_LOAD_BOOL(enable_karma, data["enable_karma"])
+ CONFIG_LOAD_BOOL(enabled_cid_randomiser_buster, data["enable_cid_randomiser_buster"])
+ CONFIG_LOAD_BOOL(forbid_singulo_possession, data["prevent_admin_singlo_possession"])
+ CONFIG_LOAD_BOOL(popup_admin_pm, data["popup_admin_pm"])
+ CONFIG_LOAD_BOOL(allow_holidays, data["allow_holidays"])
+ CONFIG_LOAD_BOOL(enable_auto_mute, data["enable_auto_mute"])
+ CONFIG_LOAD_BOOL(ssd_warning, data["ssd_warning"])
+ CONFIG_LOAD_BOOL(ghost_interaction, data["ghost_interaction"])
+ CONFIG_LOAD_BOOL(starlight, data["starlight"])
+ CONFIG_LOAD_BOOL(disable_lobby_music, data["disable_lobby_music"])
+ CONFIG_LOAD_BOOL(disable_cid_warning_popup, data["disable_cid_warning_popup"])
+ CONFIG_LOAD_BOOL(enable_ooc_emoji, data["enable_ooc_emoji"])
+ CONFIG_LOAD_BOOL(developer_express_start, data["developer_express_start"])
+ CONFIG_LOAD_BOOL(start_now_confirmation, data["start_now_confirmation"])
+ CONFIG_LOAD_BOOL(enable_auto_profiler, data["enable_auto_profiler"])
+ CONFIG_LOAD_BOOL(auto_disable_ooc, data["auto_disable_ooc"])
+ CONFIG_LOAD_BOOL(breakable_bones, data["breakable_bones"])
+ CONFIG_LOAD_BOOL(enable_revival_pod_plants, data["enable_revival_pod_plants"])
+ CONFIG_LOAD_BOOL(enable_cloning, data["enable_cloning"])
+ CONFIG_LOAD_BOOL(randomise_shift_time, data["randomise_shift_time"])
+ CONFIG_LOAD_BOOL(enable_night_shifts, data["enable_night_shifts"])
+ CONFIG_LOAD_BOOL(reactionary_explosions, data["reactionary_explosions"])
+ CONFIG_LOAD_BOOL(random_ai_lawset, data["random_ai_lawset"])
+
+ // Numbers
+ CONFIG_LOAD_NUM(lobby_time, data["lobby_time"])
+ CONFIG_LOAD_NUM(panic_bunker_threshold, data["panic_bunker_threshold"])
+ CONFIG_LOAD_NUM(base_loadout_points, data["base_loadout_points"])
+ CONFIG_LOAD_NUM(cryo_penalty_period, data["cryo_penalty_period"])
+ CONFIG_LOAD_NUM(minimum_client_build, data["minimum_client_build"])
+ CONFIG_LOAD_NUM(byond_account_age_threshold, data["byond_account_age_threshold"])
+ CONFIG_LOAD_NUM(max_client_cid_history, data["max_client_cid_history"])
+ CONFIG_LOAD_NUM(monkey_cube_cap, data["monkey_cube_cap"])
+ CONFIG_LOAD_NUM(bomb_cap, data["bomb_cap"])
+ CONFIG_LOAD_NUM(revival_brain_life, data["revival_brain_life"])
+
+ // Strings
+ CONFIG_LOAD_STR(server_name, data["server_name"])
+ CONFIG_LOAD_STR(server_tag_line, data["server_tag_line"])
+ CONFIG_LOAD_STR(server_features, data["server_features"])
diff --git a/code/controllers/configuration/sections/ipintel_configuration.dm b/code/controllers/configuration/sections/ipintel_configuration.dm
new file mode 100644
index 00000000000..89fa23d5307
--- /dev/null
+++ b/code/controllers/configuration/sections/ipintel_configuration.dm
@@ -0,0 +1,34 @@
+/// Config holder for all things relating to IPIntel
+/datum/configuration_section/ipintel_configuration
+ /// Is IPIntel enabled
+ var/enabled = FALSE
+ /// Are we in whitelist mode (Auto-kick people who are on proxies/VPNs)
+ var/whitelist_mode = TRUE
+ /// 0-1 float for percentage threshold to kick people out
+ var/bad_rating = 0.9
+ /// IPIntel contact email. Required.
+ var/contact_email = null
+ /// How many hours to save good matches for. Cached due to rate limits
+ var/hours_save_good = 72
+ /// How many hours to save bad matches for. Cached due to rate limits
+ var/hours_save_bad = 24
+ /// IPIntel Domain. Do not prefix with a protocol
+ var/ipintel_domain = "check.getipintel.net"
+ /// Do not proxy-check players with more hours than the below threshold
+ var/playtime_ignore_threshold = 10
+ /// Details URL for more info on an IP, including ASN. IP is tacked straight on the end.
+ var/details_url = "https://iphub.info/?ip="
+
+/datum/configuration_section/ipintel_configuration/load_data(list/data)
+ // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
+ CONFIG_LOAD_BOOL(enabled, data["ipintel_enabled"])
+ CONFIG_LOAD_BOOL(whitelist_mode, data["whitelist_mode"])
+
+ CONFIG_LOAD_NUM(bad_rating, data["bad_rating"])
+ CONFIG_LOAD_NUM(hours_save_good, data["hours_save_good"])
+ CONFIG_LOAD_NUM(hours_save_bad, data["hours_save_bad"])
+ CONFIG_LOAD_NUM(playtime_ignore_threshold, data["playtime_ignore_threshold"])
+
+ CONFIG_LOAD_STR(contact_email, data["contact_email"])
+ CONFIG_LOAD_STR(ipintel_domain, data["ipintel_domain"])
+ CONFIG_LOAD_STR(details_url, data["details_url"])
diff --git a/code/controllers/configuration/sections/job_configuration.dm b/code/controllers/configuration/sections/job_configuration.dm
new file mode 100644
index 00000000000..d56faddfc74
--- /dev/null
+++ b/code/controllers/configuration/sections/job_configuration.dm
@@ -0,0 +1,55 @@
+/// Config holder for all job related things
+/datum/configuration_section/job_configuration
+ /// Do we want jobs to have minimal access or extra access (IE: Scientists having robotics access)
+ var/jobs_have_minimal_access = TRUE
+ /// Do we want to restrict jobs based on account age
+ var/restrict_jobs_on_account_age = FALSE
+ /// Allow admins to bypass age-based job restrictions
+ var/restrict_jobs_on_account_age_admin_bypass = TRUE
+ /// Enable EXP logging and tracking
+ var/enable_exp_tracking = FALSE
+ /// Lockout jobs based on EXP
+ var/enable_exp_restrictions = FALSE
+ /// Allow admins to bypass EXP restrictions
+ var/enable_exp_admin_bypass = TRUE
+ /// Allow non-admins to play as AI
+ var/allow_ai = TRUE
+ /// Prevent guests from playing high profile roles
+ var/guest_job_ban = TRUE
+ /// Grant assistants maint access
+ var/assistant_maint_access = TRUE
+ /// Limit amount of assistants?
+ var/assistant_limit = FALSE
+ /// If yes to above, ratio of assistants per security officer (IE: 4:1)
+ var/assistant_security_ratio = 2
+ /// Enable loading of job overrides from the config
+ var/enable_job_amount_overrides = TRUE
+ /// Map of job:amount for lowpop. key: Job | value: amount
+ var/list/lowpop_job_map = list()
+ /// Map of job:amount for highpop. key: Job | value: amount
+ var/list/highpop_job_map = list()
+
+/datum/configuration_section/job_configuration/load_data(list/data)
+ // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
+ CONFIG_LOAD_BOOL(jobs_have_minimal_access, data["jobs_have_minimal_access"])
+ CONFIG_LOAD_BOOL(restrict_jobs_on_account_age, data["restrict_jobs_on_account_age"])
+ CONFIG_LOAD_BOOL(restrict_jobs_on_account_age_admin_bypass, data["restrict_jobs_on_account_age_admin_bypass"])
+ CONFIG_LOAD_BOOL(enable_exp_tracking, data["enable_exp_tracking"])
+ CONFIG_LOAD_BOOL(enable_exp_restrictions, data["enable_exp_restrictions"])
+ CONFIG_LOAD_BOOL(enable_exp_admin_bypass, data["enable_exp_admin_bypass"])
+ CONFIG_LOAD_BOOL(allow_ai, data["allow_ai"])
+ CONFIG_LOAD_BOOL(guest_job_ban, data["guest_job_ban"])
+ CONFIG_LOAD_BOOL(assistant_maint_access, data["assistant_maint_access"])
+ CONFIG_LOAD_BOOL(assistant_limit, data["assistant_limit"])
+ CONFIG_LOAD_NUM(assistant_security_ratio, data["assistant_security_ratio"])
+ CONFIG_LOAD_BOOL(enable_job_amount_overrides, data["enable_job_amount_overrides"])
+
+ if(enable_job_amount_overrides && islist(data["job_slot_amounts"]))
+ lowpop_job_map.Cut()
+ highpop_job_map.Cut()
+ for(var/kvp in data["job_slot_amounts"])
+ if(!isnull(kvp["name"]))
+ if(!isnull(kvp["lowpop"]))
+ lowpop_job_map[kvp["name"]] = kvp["lowpop"]
+ if(!isnull(kvp["highpop"]))
+ highpop_job_map[kvp["name"]] = kvp["highpop"]
diff --git a/code/controllers/configuration/sections/logging_configuration.dm b/code/controllers/configuration/sections/logging_configuration.dm
new file mode 100644
index 00000000000..ea2cd492057
--- /dev/null
+++ b/code/controllers/configuration/sections/logging_configuration.dm
@@ -0,0 +1,53 @@
+/// Config holder for all things regarding logging
+/datum/configuration_section/logging_configuration
+ /// Log OOC messages
+ var/ooc_logging = TRUE
+ /// Log ingame say messages
+ var/say_logging = TRUE
+ /// Log admin actions
+ var/admin_logging = TRUE
+ /// Log client access (login/logout)
+ var/access_logging = TRUE
+ /// Log game events (roundstart, results, a lot of other things)
+ var/game_logging = TRUE
+ /// Enable logging of votes and their results
+ var/vote_logging = TRUE
+ /// Enable logging of whipers
+ var/whisper_logging = TRUE
+ /// Enable logging of emotes
+ var/emote_logging = TRUE
+ /// Enable logging of attacks between players
+ var/attack_logging = TRUE
+ /// Enable logging of PDA messages
+ var/pda_logging = TRUE
+ /// Enable runtime logging
+ var/runtime_logging = TRUE
+ /// Enable world.log output logging
+ var/world_logging = TRUE
+ /// Log hrefs
+ var/href_logging = TRUE
+ /// Log admin warning messages
+ var/admin_warning_logging = TRUE
+ /// Log asay messages
+ var/adminchat_logging = TRUE
+ /// Log debug messages
+ var/debug_logging = TRUE
+
+/datum/configuration_section/logging_configuration/load_data(list/data)
+ // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
+ CONFIG_LOAD_BOOL(ooc_logging, data["enable_ooc_logging"])
+ CONFIG_LOAD_BOOL(say_logging, data["enable_say_logging"])
+ CONFIG_LOAD_BOOL(admin_logging, data["enable_admin_logging"])
+ CONFIG_LOAD_BOOL(access_logging, data["enable_access_logging"])
+ CONFIG_LOAD_BOOL(game_logging, data["enable_game_logging"])
+ CONFIG_LOAD_BOOL(vote_logging, data["enable_vote_logging"])
+ CONFIG_LOAD_BOOL(whisper_logging, data["enable_whisper_logging"])
+ CONFIG_LOAD_BOOL(emote_logging, data["enable_emote_logging"])
+ CONFIG_LOAD_BOOL(attack_logging, data["enable_attack_logging"])
+ CONFIG_LOAD_BOOL(pda_logging, data["enable_pda_logging"])
+ CONFIG_LOAD_BOOL(runtime_logging, data["enable_runtime_logging"])
+ CONFIG_LOAD_BOOL(world_logging, data["enable_world_logging"])
+ CONFIG_LOAD_BOOL(href_logging, data["enable_href_logging"])
+ CONFIG_LOAD_BOOL(admin_warning_logging, data["enable_admin_warning_logging"])
+ CONFIG_LOAD_BOOL(adminchat_logging, data["enable_adminchat_logging"])
+ CONFIG_LOAD_BOOL(debug_logging, data["enable_debug_logging"])
diff --git a/code/controllers/configuration/sections/mc_configuration.dm b/code/controllers/configuration/sections/mc_configuration.dm
new file mode 100644
index 00000000000..0a047b6ac4d
--- /dev/null
+++ b/code/controllers/configuration/sections/mc_configuration.dm
@@ -0,0 +1,23 @@
+/// Config holder for all things regarding the MC
+/datum/configuration_section/mc_configuration
+ /// Server ticklag
+ var/ticklag = 0.5
+ /// Tick limit % during world Init
+ var/world_init_tick_limit = TICK_LIMIT_MC_INIT_DEFAULT
+ /// Base MC tick rate
+ var/base_tickrate = 1
+ /// Highpop MC tickrate
+ var/highpop_tickrate = 1.1
+ /// MC Highpop enable threshold
+ var/highpop_enable_threshold = 65
+ /// MC Highpop disable threshold
+ var/highpop_disable_threshold = 60
+
+/datum/configuration_section/mc_configuration/load_data(list/data)
+ // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
+ CONFIG_LOAD_NUM(ticklag, data["ticklag"])
+ CONFIG_LOAD_NUM(world_init_tick_limit, data["world_init_mc_tick_limit"])
+ CONFIG_LOAD_NUM(base_tickrate, data["base_mc_tick_rate"])
+ CONFIG_LOAD_NUM(highpop_tickrate, data["highpop_mc_tick_rate"])
+ CONFIG_LOAD_NUM(highpop_enable_threshold, data["mc_highpop_threshold_enable"])
+ CONFIG_LOAD_NUM(highpop_disable_threshold, data["mc_highpop_threshold_disable"])
diff --git a/code/controllers/configuration/sections/movement_configuration.dm b/code/controllers/configuration/sections/movement_configuration.dm
new file mode 100644
index 00000000000..1f647b94e8a
--- /dev/null
+++ b/code/controllers/configuration/sections/movement_configuration.dm
@@ -0,0 +1,26 @@
+/// Config holder for values relating to mob movement speeds
+/datum/configuration_section/movement_configuration
+ /// Base run speed before modifiers
+ var/base_run_speed = 1
+ /// Base walk speed before modifiers
+ var/base_walk_speed = 4
+ /// Move delay for humanoids
+ var/human_delay = 1.5
+ /// Move delay for cyborgs
+ var/robot_delay = 2.5
+ /// Move delay for xenomorphs
+ var/alien_delay = 1.5
+ /// Move delay for slimes (xenobio, not slimepeople)
+ var/slime_delay = 1.5
+ /// Move delay for other simple animals
+ var/animal_delay = 2.5
+
+/datum/configuration_section/movement_configuration/load_data(list/data)
+ // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
+ CONFIG_LOAD_NUM(base_run_speed, data["base_run_speed"])
+ CONFIG_LOAD_NUM(base_walk_speed, data["base_walk_speed"])
+ CONFIG_LOAD_NUM(human_delay, data["human_delay"])
+ CONFIG_LOAD_NUM(robot_delay, data["robot_delay"])
+ CONFIG_LOAD_NUM(alien_delay, data["alien_delay"])
+ CONFIG_LOAD_NUM(slime_delay, data["slime_delay"])
+ CONFIG_LOAD_NUM(animal_delay, data["animal_delay"])
diff --git a/code/controllers/configuration/sections/overflow_configuration.dm b/code/controllers/configuration/sections/overflow_configuration.dm
new file mode 100644
index 00000000000..37c083676c1
--- /dev/null
+++ b/code/controllers/configuration/sections/overflow_configuration.dm
@@ -0,0 +1,14 @@
+/// Config holder for all overflow-server related things
+/datum/configuration_section/overflow_configuration
+ /// Amount of players before reroute server is used. 0 to disable.
+ var/reroute_cap = 0
+ /// Location of the overflow server
+ var/overflow_server_location = null
+ /// List of ckeys who will never be routed to the overflow server
+ var/list/overflow_whitelist = list()
+
+/datum/configuration_section/overflow_configuration/load_data(list/data)
+ // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
+ CONFIG_LOAD_NUM(reroute_cap, data["player_reroute_cap"])
+ CONFIG_LOAD_STR(overflow_server_location, data["overflow_server"])
+ CONFIG_LOAD_LIST(overflow_whitelist, data["overflow_whitelist"])
diff --git a/code/controllers/configuration/sections/ruin_configuration.dm b/code/controllers/configuration/sections/ruin_configuration.dm
new file mode 100644
index 00000000000..2adc5570867
--- /dev/null
+++ b/code/controllers/configuration/sections/ruin_configuration.dm
@@ -0,0 +1,23 @@
+/// Config holder for all things regarding space ruins and lavaland ruins
+/datum/configuration_section/ruin_configuration
+ /// Enable or disable space ruins
+ var/enable_space_ruins = TRUE
+ /// Minimum number of extra zlevels to fill with ruins
+ var/extra_levels_min = 2
+ /// Maximum number of extra zlevels to fill with ruins
+ var/extra_levels_max = 4
+ /// List of all active space ruins
+ var/list/active_space_ruins = list()
+ /// List of all active lavaland ruins
+ var/list/active_lava_ruins = list()
+ /// Budget for lavaland ruins
+ var/lavaland_ruin_budget = 60
+
+/datum/configuration_section/ruin_configuration/load_data(list/data)
+ // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
+ CONFIG_LOAD_BOOL(enable_space_ruins, data["enable_space_ruins"])
+ CONFIG_LOAD_NUM(extra_levels_min, data["minimum_zlevels"])
+ CONFIG_LOAD_NUM(extra_levels_max, data["maximum_zlevels"])
+ CONFIG_LOAD_LIST(active_space_ruins, data["active_space_ruins"])
+ CONFIG_LOAD_LIST(active_lava_ruins, data["active_lava_ruins"])
+ CONFIG_LOAD_NUM(lavaland_ruin_budget, data["lavaland_ruin_budget"])
diff --git a/code/controllers/configuration/sections/system_configuration.dm b/code/controllers/configuration/sections/system_configuration.dm
new file mode 100644
index 00000000000..a0354bb2b77
--- /dev/null
+++ b/code/controllers/configuration/sections/system_configuration.dm
@@ -0,0 +1,26 @@
+/// Config holder for stuff relating to server backend management and secrets
+/datum/configuration_section/system_configuration
+ // NO EDITS OR READS TO THIS WHAT SOEVER
+ protection_state = PROTECTION_PRIVATE
+ /// Password for authorising world/Topic requests
+ var/topic_key = null
+ /// Medal hub address for lavaland stats
+ var/medal_hub_address = null
+ /// Medal hub password for lavaland stats
+ var/medal_hub_password = null
+ /// Do we want the server to kill on reboot instead of keeping the same DD session
+ var/shutdown_on_reboot = FALSE
+ /// If above is true, you can run a shell command
+ var/shutdown_shell_command = null
+ /// 2FA backend server host
+ var/_2fa_auth_host = null
+
+/datum/configuration_section/system_configuration/load_data(list/data)
+ // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
+ CONFIG_LOAD_BOOL(shutdown_on_reboot, data["shutdown_on_reboot"])
+
+ CONFIG_LOAD_STR(topic_key, data["communications_password"])
+ CONFIG_LOAD_STR(medal_hub_address, data["medal_hub_address"])
+ CONFIG_LOAD_STR(medal_hub_password, data["medal_hub_password"])
+ CONFIG_LOAD_STR(shutdown_shell_command, data["shutdown_shell_command"])
+ CONFIG_LOAD_STR(_2fa_auth_host, data["_2fa_auth_host"])
diff --git a/code/controllers/configuration/sections/url_configuration.dm b/code/controllers/configuration/sections/url_configuration.dm
new file mode 100644
index 00000000000..cfdf06a7b51
--- /dev/null
+++ b/code/controllers/configuration/sections/url_configuration.dm
@@ -0,0 +1,47 @@
+/// Config holder for all the server URLs
+/datum/configuration_section/url_configuration
+ // Dont tweak these. You can read them though.
+ protection_state = PROTECTION_READONLY
+ /// List of URLs for the server RSC data
+ var/list/rsc_urls = list()
+ /// Server URL for auto-reconnecting people at end round
+ var/server_url
+ /// URL for the server ban appeals forum
+ var/banappeals_url
+ /// URL for the server wiki
+ var/wiki_url
+ /// URL for the server forums
+ var/forum_url
+ /// URL for the server rules
+ var/rules_url
+ /// URL for the server github repository
+ var/github_url
+ /// URL for server donations
+ var/donations_url
+ /// URL for a direct discord invite
+ var/discord_url
+ /// URL for a discord invite going via the forums
+ var/discord_forum_url
+ /// URL for linking ingame accounts and forum accounts. Token is appended to end
+ var/forum_link_url
+ /// URL for pulling player info on webtools
+ var/forum_playerinfo_url
+ /// URL for the CentCom Ban DB API
+ var/centcom_ban_db_url
+
+/datum/configuration_section/url_configuration/load_data(list/data)
+ // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
+ CONFIG_LOAD_LIST(rsc_urls, data["rsc_urls"])
+
+ CONFIG_LOAD_STR(server_url, data["reboot_url"])
+ CONFIG_LOAD_STR(banappeals_url, data["ban_appeals_url"])
+ CONFIG_LOAD_STR(wiki_url, data["wiki_url"])
+ CONFIG_LOAD_STR(forum_url, data["forum_url"])
+ CONFIG_LOAD_STR(rules_url, data["rules_url"])
+ CONFIG_LOAD_STR(github_url, data["github_url"])
+ CONFIG_LOAD_STR(donations_url, data["donations_url"])
+ CONFIG_LOAD_STR(discord_url, data["discord_url"])
+ CONFIG_LOAD_STR(discord_forum_url, data["discord_forum_url"])
+ CONFIG_LOAD_STR(forum_link_url, data["forum_link_url"])
+ CONFIG_LOAD_STR(forum_playerinfo_url, data["forum_playerinfo_url"])
+ CONFIG_LOAD_STR(centcom_ban_db_url, data["centcomm_ban_db_url"])
diff --git a/code/controllers/configuration/sections/vote_configuration.dm b/code/controllers/configuration/sections/vote_configuration.dm
new file mode 100644
index 00000000000..5c280c579fb
--- /dev/null
+++ b/code/controllers/configuration/sections/vote_configuration.dm
@@ -0,0 +1,33 @@
+/// Config holder for stuff relating to the ingame vote system
+/datum/configuration_section/vote_configuration
+ /// Allow players to start restart votes?
+ var/allow_restart_votes = FALSE
+ /// Allow players to start gamemode votes?
+ var/allow_mode_votes = FALSE
+ /// Minimum delay between each vote (deciseconds)
+ var/vote_delay = 18000 // 30 mins
+ /// How long will a vote last for (deciseconds)
+ var/vote_time = 600 // 60 seconds
+ /// Time before the first shuttle vote (deciseconds)
+ var/autotransfer_initial_time = 72000 // 2 hours
+ /// Time between subsequent shuttle votes if the first one is not successful (deciseconds)
+ var/autotransfer_interval_time = 18000 // 30 mins
+ /// Prevent dead players from voting
+ var/prevent_dead_voting = FALSE
+ /// Default to players not voting
+ var/disable_default_vote = TRUE
+ /// Enable map voting?
+ var/enable_map_voting = FALSE
+
+/datum/configuration_section/vote_configuration/load_data(list/data)
+ // Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
+ CONFIG_LOAD_BOOL(allow_restart_votes, data["allow_vote_restart"])
+ CONFIG_LOAD_BOOL(allow_mode_votes, data["allow_vote_mode"])
+ CONFIG_LOAD_BOOL(prevent_dead_voting, data["prevent_dead_voting"])
+ CONFIG_LOAD_BOOL(disable_default_vote, data["disable_default_vote"])
+ CONFIG_LOAD_BOOL(enable_map_voting, data["enable_map_voting"])
+
+ CONFIG_LOAD_NUM(vote_delay, data["vote_delay"])
+ CONFIG_LOAD_NUM(vote_time, data["vote_time"])
+ CONFIG_LOAD_NUM(autotransfer_initial_time, data["autotransfer_initial_time"])
+ CONFIG_LOAD_NUM(autotransfer_interval_time, data["autotransfer_interval_time"])
diff --git a/code/controllers/master.dm b/code/controllers/master.dm
index 82e2517823a..d445cf6f3b6 100644
--- a/code/controllers/master.dm
+++ b/code/controllers/master.dm
@@ -194,7 +194,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
var/start_timeofday = REALTIMEOFDAY
// Initialize subsystems.
- current_ticklimit = config.tick_limit_mc_init
+ current_ticklimit = GLOB.configuration.mc.world_init_tick_limit
for(var/datum/controller/subsystem/SS in subsystems)
if(SS.flags & SS_NO_INIT)
continue
@@ -206,8 +206,8 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
log_startup_progress("Initializations complete within [time] second[time == 1 ? "" : "s"]!")
- if(config.developer_express_start & SSticker.current_state == GAME_STATE_PREGAME)
- SSticker.current_state = GAME_STATE_SETTING_UP
+ if(GLOB.configuration.general.developer_express_start)
+ SSticker.force_start = TRUE
if(!current_runlevel)
SetRunLevel(1)
@@ -216,7 +216,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
sortTim(subsystems, /proc/cmp_subsystem_display)
// Set world options.
// world.fps = CONFIG_GET(number/fps) // TIGER TODO
- world.tick_lag = config.Ticklag
+ world.tick_lag = GLOB.configuration.mc.ticklag
var/initialized_tod = REALTIMEOFDAY
if(sleep_offline_after_initializations)
@@ -626,10 +626,10 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
if(!processing)
return
var/client_count = length(GLOB.clients)
- if(client_count < config.disable_high_pop_mc_mode_amount)
- processing = config.base_mc_tick_rate
- else if(client_count > config.high_pop_mc_mode_amount)
- processing = config.high_pop_mc_tick_rate
+ if(client_count < GLOB.configuration.mc.highpop_disable_threshold)
+ processing = GLOB.configuration.mc.base_tickrate
+ else if(client_count > GLOB.configuration.mc.highpop_enable_threshold)
+ processing = GLOB.configuration.mc.highpop_tickrate
/datum/controller/master/proc/formatcpu()
switch(world.cpu)
diff --git a/code/controllers/subsystem/afk.dm b/code/controllers/subsystem/afk.dm
index 9b1d5f3fa26..c7042513e49 100644
--- a/code/controllers/subsystem/afk.dm
+++ b/code/controllers/subsystem/afk.dm
@@ -12,7 +12,8 @@ SUBSYSTEM_DEF(afk)
/datum/controller/subsystem/afk/Initialize()
- if(config.warn_afk_minimum <= 0 || config.auto_cryo_afk <= 0 || config.auto_despawn_afk <= 0)
+
+ if(GLOB.configuration.afk.warning_minutes <= 0 || GLOB.configuration.afk.auto_cryo_minutes <= 0 || GLOB.configuration.afk.auto_despawn_minutes <= 0)
flags |= SS_NO_FIRE
else
non_cryo_antags = list(SPECIAL_ROLE_ABDUCTOR_AGENT, SPECIAL_ROLE_ABDUCTOR_SCIENTIST, \
@@ -35,19 +36,20 @@ SUBSYSTEM_DEF(afk)
toRemove += H.ckey
continue
+
var/mins_afk = round(H.client.inactivity / 600)
- if(mins_afk < config.warn_afk_minimum)
+ if(mins_afk < GLOB.configuration.afk.warning_minutes)
if(afk_players[H.ckey])
toRemove += H.ckey
continue
if(!afk_players[H.ckey])
afk_players[H.ckey] = AFK_WARNED
- warn(H, "You are AFK for [mins_afk] minutes. You will be cryod after [config.auto_cryo_afk] total minutes and fully despawned after [config.auto_despawn_afk] total minutes. Please move or click in game if you want to avoid being despawned.")
+ warn(H, "You are AFK for [mins_afk] minutes. You will be cryod after [GLOB.configuration.afk.auto_cryo_minutes] total minutes and fully despawned after [GLOB.configuration.afk.auto_despawn_minutes] total minutes. Please move or click in game if you want to avoid being despawned.")
else
var/area/A = T.loc // Turfs loc is the area
if(afk_players[H.ckey] == AFK_WARNED)
- if(mins_afk >= config.auto_cryo_afk && A.can_get_auto_cryod)
+ if(mins_afk >= GLOB.configuration.afk.auto_cryo_minutes && A.can_get_auto_cryod)
if(A.fast_despawn)
toRemove += H.ckey
warn(H, "You have been despawned after being AFK for [mins_afk] minutes. You have been despawned instantly due to you being in a secure area.")
@@ -60,13 +62,13 @@ SUBSYSTEM_DEF(afk)
afk_players[H.ckey] = AFK_CRYOD
log_afk_action(H, mins_afk, T, "put into cryostorage")
warn(H, "You are AFK for [mins_afk] minutes and have been moved to cryostorage. \
- After being AFK for another [config.auto_despawn_afk] minutes you will be fully despawned. \
+ After being AFK for another [GLOB.configuration.afk.auto_despawn_minutes] minutes you will be fully despawned. \
Please eject yourself (right click, eject) out of the cryostorage if you want to avoid being despawned.")
else
message_admins("[key_name_admin(H)] at ([get_area(T).name] [ADMIN_JMP(T)]) is AFK for [mins_afk] and can't be automatically cryod due to it's antag status: ([H.mind.special_role]).")
afk_players[H.ckey] = AFK_ADMINS_WARNED
- else if(afk_players[H.ckey] != AFK_ADMINS_WARNED && mins_afk >= config.auto_despawn_afk)
+ else if(afk_players[H.ckey] != AFK_ADMINS_WARNED && mins_afk >= GLOB.configuration.afk.auto_despawn_minutes)
log_afk_action(H, mins_afk, T, "despawned")
warn(H, "You have been despawned after being AFK for [mins_afk] minutes.")
toRemove += H.ckey
diff --git a/code/controllers/subsystem/changelog.dm b/code/controllers/subsystem/changelog.dm
index 3a2e3513916..3a35488e562 100644
--- a/code/controllers/subsystem/changelog.dm
+++ b/code/controllers/subsystem/changelog.dm
@@ -266,11 +266,11 @@ SUBSYSTEM_DEF(changelog)
usr.client.github()
// Takes a PR number as argument
if(href_list["openPR"])
- if(config.githuburl)
+ if(GLOB.configuration.url.github_url)
if(alert("This will open PR #[href_list["openPR"]] in your browser. Are you sure?",,"Yes","No")=="No")
return
// If the github URL in the config has a trailing slash, it doesnt matter here, thankfully github accepts having a double slash: https://github.com/org/repo//pull/1
- var/url = "[config.githuburl]/pull/[href_list["openPR"]]"
+ var/url = "[GLOB.configuration.url.github_url]/pull/[href_list["openPR"]]"
usr << link(url)
else
to_chat(usr, "The GitHub URL is not set in the server configuration. PRs cannot be opened from changelog view. Please inform the server host.")
diff --git a/code/controllers/subsystem/dbcore.dm b/code/controllers/subsystem/dbcore.dm
index 4cfe06083e3..4a845c375ea 100644
--- a/code/controllers/subsystem/dbcore.dm
+++ b/code/controllers/subsystem/dbcore.dm
@@ -30,7 +30,7 @@ SUBSYSTEM_DEF(dbcore)
// This is in Initialize() so that its actually seen in chat
/datum/controller/subsystem/dbcore/Initialize()
if(!schema_valid)
- to_chat(world, "Database schema ([sql_version]) doesn't match the latest schema version ([SQL_VERSION]). Roundstart has been delayed.")
+ to_chat(world, "Database schema ([GLOB.configuration.database.version]) doesn't match the latest schema version ([SQL_VERSION]). Roundstart has been delayed.")
return ..()
@@ -66,7 +66,7 @@ SUBSYSTEM_DEF(dbcore)
if(IsConnected())
return TRUE
- if(!config.sql_enabled)
+ if(!GLOB.configuration.database.enabled)
return FALSE
if(failed_connection_timeout <= world.time) //it's been more than 5 seconds since we failed to connect, reset the counter
@@ -77,14 +77,14 @@ SUBSYSTEM_DEF(dbcore)
return FALSE
var/result = json_decode(rustg_sql_connect_pool(json_encode(list(
- "host" = sqladdress,
- "port" = text2num(sqlport),
- "user" = sqlfdbklogin,
- "pass" = sqlfdbkpass,
- "db_name" = sqlfdbkdb,
- "read_timeout" = config.async_sql_query_timeout,
- "write_timeout" = config.async_sql_query_timeout,
- "max_threads" = config.rust_sql_thread_limit,
+ "host" = GLOB.configuration.database.address,
+ "port" = GLOB.configuration.database.port,
+ "user" = GLOB.configuration.database.username,
+ "pass" = GLOB.configuration.database.password,
+ "db_name" = GLOB.configuration.database.db,
+ "read_timeout" = GLOB.configuration.database.async_query_timeout,
+ "write_timeout" = GLOB.configuration.database.async_query_timeout,
+ "max_threads" = GLOB.configuration.database.async_thread_limit,
))))
. = (result["status"] == "ok")
if(.)
@@ -102,11 +102,11 @@ SUBSYSTEM_DEF(dbcore)
* If it is a valid version, the DB will then connect.
*/
/datum/controller/subsystem/dbcore/proc/CheckSchemaVersion()
- if(config.sql_enabled)
+ if(GLOB.configuration.database.enabled)
// The unit tests have their own version of this check, which wont hold the server up infinitely, so this is disabled if we are running unit tests
#ifndef UNIT_TESTS
- if(config.sql_enabled && sql_version != SQL_VERSION)
- config.sql_enabled = FALSE
+ if(GLOB.configuration.database.enabled && GLOB.configuration.database.version != SQL_VERSION)
+ GLOB.configuration.database.enabled = FALSE
schema_valid = FALSE
SSticker.ticker_going = FALSE
SEND_TEXT(world.log, "Database connection failed: Invalid SQL Versions")
@@ -206,7 +206,7 @@ SUBSYSTEM_DEF(dbcore)
* Does a few sanity checks, then asks the DLL if we are properly connected
*/
/datum/controller/subsystem/dbcore/proc/IsConnected()
- if(!config.sql_enabled)
+ if(!GLOB.configuration.database.enabled)
return FALSE
if(!schema_valid)
return FALSE
@@ -222,7 +222,7 @@ SUBSYSTEM_DEF(dbcore)
* Will always report "Database disabled by configuration" if the DB is disabled.
*/
/datum/controller/subsystem/dbcore/proc/ErrorMsg()
- if(!config.sql_enabled)
+ if(!GLOB.configuration.database.enabled)
return "Database disabled by configuration"
return last_error
@@ -492,7 +492,7 @@ SUBSYSTEM_DEF(dbcore)
/client/proc/reestablish_db_connection()
set category = "Debug"
set name = "Reestablish DB Connection"
- if(!config.sql_enabled)
+ if(!GLOB.configuration.database.enabled)
to_chat(usr, "The Database is not enabled in the server configuration!")
return
diff --git a/code/controllers/subsystem/discord.dm b/code/controllers/subsystem/discord.dm
index a0f8c1a68fe..11a2a481073 100644
--- a/code/controllers/subsystem/discord.dm
+++ b/code/controllers/subsystem/discord.dm
@@ -7,7 +7,7 @@ SUBSYSTEM_DEF(discord)
var/last_administration_ping = 0
/datum/controller/subsystem/discord/Initialize(start_timeofday)
- if(config.discord_webhooks_enabled)
+ if(GLOB.configuration.discord.webhooks_enabled)
enabled = TRUE
return ..()
@@ -18,11 +18,11 @@ SUBSYSTEM_DEF(discord)
var/list/webhook_urls
switch(destination)
if(DISCORD_WEBHOOK_ADMIN)
- webhook_urls = config.discord_admin_webhook_urls
+ webhook_urls = GLOB.configuration.discord.admin_webhook_urls
if(DISCORD_WEBHOOK_PRIMARY)
- webhook_urls = config.discord_main_webhook_urls
+ webhook_urls = GLOB.configuration.discord.main_webhook_urls
if(DISCORD_WEBHOOK_MENTOR)
- webhook_urls = config.discord_mentor_webhook_urls
+ webhook_urls = GLOB.configuration.discord.mentor_webhook_urls
var/datum/discord_webhook_payload/dwp = new()
dwp.webhook_content = content
@@ -36,14 +36,18 @@ SUBSYSTEM_DEF(discord)
var/list/webhook_urls
switch(destination)
if(DISCORD_WEBHOOK_ADMIN)
- webhook_urls = config.discord_admin_webhook_urls
+ webhook_urls = GLOB.configuration.discord.admin_webhook_urls
if(DISCORD_WEBHOOK_PRIMARY)
- webhook_urls = config.discord_main_webhook_urls
+ webhook_urls = GLOB.configuration.discord.main_webhook_urls
+ if(DISCORD_WEBHOOK_MENTOR)
+ webhook_urls = GLOB.configuration.discord.mentor_webhook_urls
for(var/url in webhook_urls)
SShttp.create_async_request(RUSTG_HTTP_METHOD_POST, url, dwp.serialize2json(), list("content-type" = "application/json"))
// This one is for sending messages to the admin channel if no admins are active, complete with a ping to the game admins role
/datum/controller/subsystem/discord/proc/send2discord_simple_noadmins(content, check_send_always = FALSE)
+ if(!enabled)
+ return
// Setup some stuff
var/alerttext
var/list/admincounter = staff_countup(R_BAN)
@@ -57,7 +61,7 @@ SUBSYSTEM_DEF(discord)
else
alerttext = " | **NO ADMINS ONLINE**"
else
- if(check_send_always && config.discord_forward_all_ahelps)
+ if(check_send_always && GLOB.configuration.discord.forward_all_ahelps)
// If we are here, there are admins online. We want to forward everything, but obviously dont want to add a ping, so we do this
add_ping = FALSE
else
@@ -68,17 +72,17 @@ SUBSYSTEM_DEF(discord)
var/datum/discord_webhook_payload/dwp = new()
dwp.webhook_content = message
- for(var/url in config.discord_admin_webhook_urls)
+ for(var/url in GLOB.configuration.discord.admin_webhook_urls)
SShttp.create_async_request(RUSTG_HTTP_METHOD_POST, url, dwp.serialize2json(), list("content-type" = "application/json"))
// Helper to make administrator ping easier
/datum/controller/subsystem/discord/proc/handle_administrator_ping()
// Check if a role is even set
- if(config.discord_admin_role_id)
+ if(GLOB.configuration.discord.admin_role_id)
if(last_administration_ping > world.time)
return "*(Role pinged recently)*"
last_administration_ping = world.time + 60 SECONDS
- return "<@&[config.discord_admin_role_id]>"
+ return "<@&[GLOB.configuration.discord.admin_role_id]>"
return ""
diff --git a/code/controllers/subsystem/ghost_spawns.dm b/code/controllers/subsystem/ghost_spawns.dm
index 96ac8f09116..0490e764685 100644
--- a/code/controllers/subsystem/ghost_spawns.dm
+++ b/code/controllers/subsystem/ghost_spawns.dm
@@ -166,7 +166,7 @@ SUBSYSTEM_DEF(ghost_spawns)
if(role_text)
if(jobban_isbanned(M, role_text) || jobban_isbanned(M, ROLE_SYNDICATE))
return
- if(config.use_exp_restrictions && min_hours)
+ if(GLOB.configuration.jobs.enable_exp_restrictions && min_hours)
if(M.client.get_exp_type_num(EXP_TYPE_LIVING) < min_hours * 60)
return
if(check_antaghud && cannotPossess(M))
diff --git a/code/controllers/subsystem/holiday.dm b/code/controllers/subsystem/holiday.dm
index ddde9cd62be..e9b254b1269 100644
--- a/code/controllers/subsystem/holiday.dm
+++ b/code/controllers/subsystem/holiday.dm
@@ -5,7 +5,7 @@ SUBSYSTEM_DEF(holiday)
var/list/holidays
/datum/controller/subsystem/holiday/Initialize(start_timeofday)
- if(!config.allow_holidays)
+ if(!GLOB.configuration.general.allow_holidays)
return ..() //Holiday stuff was not enabled in the config!
var/YY = text2num(time2text(world.timeofday, "YY")) // get the current year
diff --git a/code/controllers/subsystem/jobs.dm b/code/controllers/subsystem/jobs.dm
index c7e18522392..415e04e8611 100644
--- a/code/controllers/subsystem/jobs.dm
+++ b/code/controllers/subsystem/jobs.dm
@@ -20,12 +20,12 @@ SUBSYSTEM_DEF(jobs)
/datum/controller/subsystem/jobs/Initialize(timeofday)
if(!occupations.len)
SetupOccupations()
- LoadJobs("config/jobs.txt")
+ LoadJobs(FALSE)
return ..()
// Only fires every 5 minutes
/datum/controller/subsystem/jobs/fire()
- if(!SSdbcore.IsConnected() || !config.use_exp_tracking)
+ if(!SSdbcore.IsConnected() || !GLOB.configuration.jobs.enable_exp_tracking)
return
batch_update_player_exp(announce = FALSE) // Set this to true if you ever want to inform players about their EXP gains
@@ -242,8 +242,8 @@ SUBSYSTEM_DEF(jobs)
/datum/controller/subsystem/jobs/proc/FillAIPosition()
- if(config && !config.allow_ai)
- return 0
+ if(!GLOB.configuration.jobs.allow_ai)
+ return FALSE
var/ai_selected = 0
var/datum/job/job = GetJob("AI")
@@ -514,39 +514,29 @@ SUBSYSTEM_DEF(jobs)
-/datum/controller/subsystem/jobs/proc/LoadJobs(jobsfile) //ran during round setup, reads info from jobs.txt -- Urist
- if(!config.load_jobs_from_txt)
- return 0
+/datum/controller/subsystem/jobs/proc/LoadJobs(highpop = FALSE) //ran during round setup, reads info from jobs list
+ if(!GLOB.configuration.jobs.enable_job_amount_overrides)
+ return FALSE
- var/list/jobEntries = file2list(jobsfile)
+ var/list/joblist = list()
- for(var/job in jobEntries)
- if(!job)
+ if(highpop)
+ joblist = GLOB.configuration.jobs.highpop_job_map.Copy()
+ else
+ joblist = GLOB.configuration.jobs.lowpop_job_map.Copy()
+
+ for(var/job in joblist)
+ // Key: name | Value: Amount
+ var/datum/job/J = GetJob(job)
+ if(!J)
continue
+ J.total_positions = text2num(joblist[job])
+ J.spawn_positions = text2num(joblist[job])
- job = trim(job)
- if(!length(job))
- continue
+ if(job == "AI" || job == "Cyborg") //I dont like this here but it will do for now
+ J.total_positions = 0
- var/pos = findtext(job, "=")
- var/name = null
- var/value = null
-
- if(pos)
- name = copytext(job, 1, pos)
- value = copytext(job, pos + 1)
- else
- continue
-
- if(name && value)
- var/datum/job/J = GetJob(name)
- if(!J) continue
- J.total_positions = text2num(value)
- J.spawn_positions = text2num(value)
- if(name == "AI" || name == "Cyborg")//I dont like this here but it will do for now
- J.total_positions = 0
-
- return 1
+ return TRUE
/datum/controller/subsystem/jobs/proc/HandleFeedbackGathering()
diff --git a/code/controllers/subsystem/lighting.dm b/code/controllers/subsystem/lighting.dm
index 6761e9647d9..e12c6be07df 100644
--- a/code/controllers/subsystem/lighting.dm
+++ b/code/controllers/subsystem/lighting.dm
@@ -13,7 +13,7 @@ SUBSYSTEM_DEF(lighting)
/datum/controller/subsystem/lighting/Initialize(timeofday)
if(!initialized)
- if(config.starlight)
+ if(GLOB.configuration.general.starlight)
for(var/I in GLOB.all_areas)
var/area/A = I
if(A.dynamic_lighting == DYNAMIC_LIGHTING_IFSTARLIGHT)
diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm
index 87846d051f0..a816c18d0c5 100644
--- a/code/controllers/subsystem/mapping.dm
+++ b/code/controllers/subsystem/mapping.dm
@@ -40,11 +40,11 @@ SUBSYSTEM_DEF(mapping)
loadLavaland()
// Pick a random away mission.
- if(!config.disable_away_missions)
+ if(GLOB.configuration.gateway.enable_away_mission)
load_away_mission()
// Seed space ruins
- if(!config.disable_space_ruins)
+ if(GLOB.configuration.ruins.enable_space_ruins)
handleRuins()
// Makes a blank space level for the sake of randomness
@@ -57,12 +57,12 @@ SUBSYSTEM_DEF(mapping)
// Spawn Lavaland ruins and rivers.
log_startup_progress("Populating lavaland...")
var/lavaland_setup_timer = start_watch()
- seedRuins(list(level_name_to_num(MINING)), config.lavaland_budget, /area/lavaland/surface/outdoors/unexplored, GLOB.lava_ruins_templates)
+ seedRuins(list(level_name_to_num(MINING)), GLOB.configuration.ruins.lavaland_ruin_budget, /area/lavaland/surface/outdoors/unexplored, GLOB.lava_ruins_templates)
spawn_rivers(list(level_name_to_num(MINING)))
log_startup_progress("Successfully populated lavaland in [stop_watch(lavaland_setup_timer)]s.")
// Now we make a list of areas for teleport locs
- // TOOD: Make these locs into lists on the SS itself, not globs
+ // AA TODO: Make these locs into lists on the SS itself, not globs
for(var/area/AR in world)
if(AR.no_teleportlocs)
continue
@@ -84,8 +84,8 @@ SUBSYSTEM_DEF(mapping)
GLOB.ghostteleportlocs = sortAssoc(GLOB.ghostteleportlocs)
// World name
- if(config && config.server_name)
- world.name = "[config.server_name]: [station_name()]"
+ if(GLOB.configuration.general.server_name)
+ world.name = "[GLOB.configuration.general.server_name]: [station_name()]"
else
world.name = station_name()
@@ -96,7 +96,7 @@ SUBSYSTEM_DEF(mapping)
// load in extra levels of space ruins
var/load_zlevels_timer = start_watch()
log_startup_progress("Creating random space levels...")
- var/num_extra_space = rand(config.extra_space_ruin_levels_min, config.extra_space_ruin_levels_max)
+ var/num_extra_space = rand(GLOB.configuration.ruins.extra_levels_min, GLOB.configuration.ruins.extra_levels_max)
for(var/i in 1 to num_extra_space)
GLOB.space_manager.add_new_zlevel("Ruin Area #[i]", linkage = CROSSLINKED, traits = list(REACHABLE, SPAWN_RUINS))
log_startup_progress("Loaded random space levels in [stop_watch(load_zlevels_timer)]s.")
@@ -230,11 +230,11 @@ SUBSYSTEM_DEF(mapping)
if(length(GLOB.awaydestinations))
return
- if(GLOB.potentialRandomZlevels && length(GLOB.potentialRandomZlevels))
+ if(length(GLOB.configuration.gateway.enabled_away_missions))
var/watch = start_watch()
log_startup_progress("Loading away mission...")
- var/map = pick(GLOB.potentialRandomZlevels)
+ var/map = pick(GLOB.configuration.gateway.enabled_away_missions)
var/file = file(map)
if(isfile(file))
var/zlev = GLOB.space_manager.add_new_zlevel(AWAY_MISSION, linkage = UNAFFECTED, traits = list(AWAY_LEVEL,BLOCK_TELEPORT))
diff --git a/code/controllers/subsystem/medals.dm b/code/controllers/subsystem/medals.dm
index 5de6cdeb27a..46023427643 100644
--- a/code/controllers/subsystem/medals.dm
+++ b/code/controllers/subsystem/medals.dm
@@ -4,15 +4,15 @@ SUBSYSTEM_DEF(medals)
var/hub_enabled = FALSE
/datum/controller/subsystem/medals/Initialize(timeofday)
- if(config.medal_hub_address && config.medal_hub_password)
+ if(GLOB.configuration.system.medal_hub_address && GLOB.configuration.system.medal_hub_password)
hub_enabled = TRUE
- ..()
+ return ..()
/datum/controller/subsystem/medals/proc/UnlockMedal(medal, client/player)
set waitfor = FALSE
if(!medal || !hub_enabled)
return
- if(isnull(world.SetMedal(medal, player, config.medal_hub_address, config.medal_hub_password)))
+ if(isnull(world.SetMedal(medal, player, GLOB.configuration.system.medal_hub_address, GLOB.configuration.system.medal_hub_password)))
hub_enabled = FALSE
log_game("MEDAL ERROR: Could not contact hub to award medal [medal] to player [player.ckey].")
message_admins("Error! Failed to contact hub to award [medal] medal to [player.ckey]!")
@@ -35,7 +35,7 @@ SUBSYSTEM_DEF(medals)
var/newscoreparam = list2params(oldscore)
- if(isnull(world.SetScores(player.ckey, newscoreparam, config.medal_hub_address, config.medal_hub_password)))
+ if(isnull(world.SetScores(player.ckey, newscoreparam, GLOB.configuration.system.medal_hub_address, GLOB.configuration.system.medal_hub_password)))
hub_enabled = FALSE
log_game("SCORE ERROR: Could not contact hub to set score. Score [score] for player [player.ckey].")
message_admins("Error! Failed to contact hub to set [score] score for [player.ckey]!")
@@ -44,7 +44,7 @@ SUBSYSTEM_DEF(medals)
if(!score || !hub_enabled)
return
- var/scoreget = world.GetScores(player.ckey, score, config.medal_hub_address, config.medal_hub_password)
+ var/scoreget = world.GetScores(player.ckey, score, GLOB.configuration.system.medal_hub_address, GLOB.configuration.system.medal_hub_password)
if(isnull(scoreget))
hub_enabled = FALSE
log_game("SCORE ERROR: Could not contact hub to get score. Score [score] for player [player.ckey].")
@@ -58,7 +58,7 @@ SUBSYSTEM_DEF(medals)
if(!medal || !hub_enabled)
return
- if(isnull(world.GetMedal(medal, player, config.medal_hub_address, config.medal_hub_password)))
+ if(isnull(world.GetMedal(medal, player, GLOB.configuration.system.medal_hub_address, GLOB.configuration.system.medal_hub_password)))
hub_enabled = FALSE
log_game("MEDAL ERROR: Could not contact hub to get medal [medal] for player [player.ckey]")
message_admins("Error! Failed to contact hub to get [medal] medal for [player.ckey]!")
@@ -68,7 +68,7 @@ SUBSYSTEM_DEF(medals)
/datum/controller/subsystem/medals/proc/LockMedal(medal, client/player)
if(!player || !medal || !hub_enabled)
return
- var/result = world.ClearMedal(medal, player, config.medal_hub_address, config.medal_hub_password)
+ var/result = world.ClearMedal(medal, player, GLOB.configuration.system.medal_hub_address, GLOB.configuration.system.medal_hub_password)
switch(result)
if(null)
hub_enabled = FALSE
@@ -81,6 +81,6 @@ SUBSYSTEM_DEF(medals)
/datum/controller/subsystem/medals/proc/ClearScore(client/player)
- if(isnull(world.SetScores(player.ckey, "", config.medal_hub_address, config.medal_hub_password)))
+ if(isnull(world.SetScores(player.ckey, "", GLOB.configuration.system.medal_hub_address, GLOB.configuration.system.medal_hub_password)))
log_game("MEDAL ERROR: Could not contact hub to clear scores for [player.ckey].")
message_admins("Error! Failed to contact hub to clear scores for [player.ckey]!")
diff --git a/code/controllers/subsystem/nightshift.dm b/code/controllers/subsystem/nightshift.dm
index deffcb6bddf..fe5d17dccd4 100644
--- a/code/controllers/subsystem/nightshift.dm
+++ b/code/controllers/subsystem/nightshift.dm
@@ -14,9 +14,9 @@ SUBSYSTEM_DEF(nightshift)
var/high_security_mode = FALSE
/datum/controller/subsystem/nightshift/Initialize()
- if(!config.enable_night_shifts)
+ if(!GLOB.configuration.general.enable_night_shifts)
can_fire = FALSE
- if(config.randomize_shift_time)
+ if(GLOB.configuration.general.randomise_shift_time)
GLOB.gametime_offset = rand(0, 23) HOURS
return ..()
diff --git a/code/controllers/subsystem/profiler.dm b/code/controllers/subsystem/profiler.dm
index 418af664d92..2d30360edb1 100644
--- a/code/controllers/subsystem/profiler.dm
+++ b/code/controllers/subsystem/profiler.dm
@@ -13,7 +13,7 @@ SUBSYSTEM_DEF(profiler)
..("F:[round(fetch_cost, 1)]ms | W:[round(write_cost, 1)]ms")
/datum/controller/subsystem/profiler/Initialize()
- if(!config.auto_profile)
+ if(!GLOB.configuration.general.enable_auto_profiler)
StopProfiling() //Stop the early start profiler if we dont want it on in the config
flags |= SS_NO_FIRE
return ..()
@@ -22,7 +22,7 @@ SUBSYSTEM_DEF(profiler)
DumpFile()
/datum/controller/subsystem/profiler/Shutdown()
- if(config.auto_profile)
+ if(GLOB.configuration.general.enable_auto_profiler)
DumpFile()
return ..()
diff --git a/code/controllers/subsystem/shuttles.dm b/code/controllers/subsystem/shuttles.dm
index 4eb3adc62da..85e9e5da52c 100644
--- a/code/controllers/subsystem/shuttles.dm
+++ b/code/controllers/subsystem/shuttles.dm
@@ -1,5 +1,4 @@
#define CALL_SHUTTLE_REASON_LENGTH 12
-
SUBSYSTEM_DEF(shuttle)
name = "Shuttle"
wait = 10
@@ -42,6 +41,8 @@ SUBSYSTEM_DEF(shuttle)
var/sold_atoms = ""
var/list/hidden_shuttle_turfs = list() //all turfs hidden from navigation computers associated with a list containing the image hiding them and the type of the turf they are pretending to be
var/list/hidden_shuttle_turf_images = list() //only the images from the above list
+ /// Default refuel delay
+ var/refuel_delay = 20 MINUTES
/datum/controller/subsystem/shuttle/Initialize(start_timeofday)
ordernum = rand(1,9000)
@@ -97,7 +98,7 @@ SUBSYSTEM_DEF(shuttle)
/datum/controller/subsystem/shuttle/proc/secondsToRefuel()
var/elapsed = world.time - SSticker.round_start_time
- var/remaining = round((config.shuttle_refuel_delay - elapsed) / 10)
+ var/remaining = round((refuel_delay - elapsed) / 10)
return remaining > 0 ? remaining : 0
/datum/controller/subsystem/shuttle/proc/requestEvac(mob/user, call_reason)
@@ -115,7 +116,7 @@ SUBSYSTEM_DEF(shuttle)
emergency = backup_shuttle
if(secondsToRefuel())
- to_chat(user, "The emergency shuttle is refueling. Please wait another [abs(round(((world.time - SSticker.round_start_time) - config.shuttle_refuel_delay)/600))] minutes before trying again.")
+ to_chat(user, "The emergency shuttle is refueling. Please wait another [abs(round(((world.time - SSticker.round_start_time) - refuel_delay)/600))] minutes before trying again.")
return
switch(emergency.mode)
diff --git a/code/controllers/subsystem/statistics.dm b/code/controllers/subsystem/statistics.dm
index bfc7d9655d5..375bb47486f 100644
--- a/code/controllers/subsystem/statistics.dm
+++ b/code/controllers/subsystem/statistics.dm
@@ -6,7 +6,7 @@ SUBSYSTEM_DEF(statistics)
/datum/controller/subsystem/statistics/Initialize(start_timeofday)
- if(!config.sql_enabled)
+ if(!SSdbcore.IsConnected())
flags |= SS_NO_FIRE // Disable firing if SQL is disabled
return ..()
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index c46301713e0..320f3671000 100644
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -10,7 +10,7 @@ SUBSYSTEM_DEF(ticker)
/// Time the world started, relative to world.time
var/round_start_time = 0
/// Default timeout for if world.Reboot() doesnt have a time specified
- var/const/restart_timeout = 600
+ var/const/restart_timeout = 75 SECONDS
/// Current status of the game. See code\__DEFINES\game.dm
var/current_state = GAME_STATE_STARTUP
/// Do we want to force-start as soon as we can
@@ -79,9 +79,9 @@ SUBSYSTEM_DEF(ticker)
switch(current_state)
if(GAME_STATE_STARTUP)
// This is ran as soon as the MC starts firing, and should only run ONCE, unless startup fails
- round_start_time = world.time + (config.pregame_timestart * 10)
+ round_start_time = world.time + (GLOB.configuration.general.lobby_time SECONDS)
to_chat(world, "Welcome to the pre-game lobby!")
- to_chat(world, "Please, setup your character and select ready. Game will start in [config.pregame_timestart] seconds")
+ to_chat(world, "Please, setup your character and select ready. Game will start in [GLOB.configuration.general.lobby_time] seconds")
current_state = GAME_STATE_PREGAME
fire() // TG says this is a good idea
for(var/mob/new_player/N in GLOB.player_list)
@@ -114,10 +114,10 @@ SUBSYSTEM_DEF(ticker)
if(world.time > next_autotransfer)
SSvote.autotransfer()
- next_autotransfer = world.time + config.vote_autotransfer_interval
+ next_autotransfer = world.time + GLOB.configuration.vote.autotransfer_interval_time
var/game_finished = SSshuttle.emergency.mode >= SHUTTLE_ENDGAME || mode.station_was_nuked
- if(config.continuous_rounds)
+ if(GLOB.configuration.gamemode.disable_certain_round_early_end)
mode.check_finished() // some modes contain var-changing code in here, so call even if we don't uses result
else
game_finished |= mode.check_finished()
@@ -129,6 +129,8 @@ SUBSYSTEM_DEF(ticker)
auto_toggle_ooc(TRUE) // Turn it on
declare_completion()
addtimer(CALLBACK(src, .proc/call_reboot), 5 SECONDS)
+ if(GLOB.configuration.vote.enable_map_voting)
+ SSvote.initiate_vote("map", "the server", TRUE) // Start a map vote. Timing is a little tight here but we should be good.
/datum/controller/subsystem/ticker/proc/call_reboot()
if(mode.station_was_nuked)
@@ -147,7 +149,7 @@ SUBSYSTEM_DEF(ticker)
var/list/datum/game_mode/runnable_modes
if(GLOB.master_mode == "random" || GLOB.master_mode == "secret")
- runnable_modes = config.get_runnable_modes()
+ runnable_modes = GLOB.configuration.gamemode.get_runnable_modes()
if(!length(runnable_modes))
to_chat(world, "Unable to choose playable game mode. Reverting to pre-game lobby.")
force_start = FALSE
@@ -155,9 +157,9 @@ SUBSYSTEM_DEF(ticker)
Master.SetRunLevel(RUNLEVEL_LOBBY)
return FALSE
if(GLOB.secret_force_mode != "secret")
- var/datum/game_mode/M = config.pick_mode(GLOB.secret_force_mode)
+ var/datum/game_mode/M = GLOB.configuration.gamemode.pick_mode(GLOB.secret_force_mode)
if(M.can_start())
- mode = config.pick_mode(GLOB.secret_force_mode)
+ mode = GLOB.configuration.gamemode.pick_mode(GLOB.secret_force_mode)
SSjobs.ResetOccupations()
if(!mode)
mode = pickweight(runnable_modes)
@@ -165,7 +167,7 @@ SUBSYSTEM_DEF(ticker)
var/mtype = mode.type
mode = new mtype
else
- mode = config.pick_mode(GLOB.master_mode)
+ mode = GLOB.configuration.gamemode.pick_mode(GLOB.master_mode)
if(!mode.can_start())
to_chat(world, "Unable to start [mode.name]. Not enough players, [mode.required_players] players needed. Reverting to pre-game lobby.")
@@ -267,7 +269,7 @@ SUBSYSTEM_DEF(ticker)
round_start_time = world.time
// Sets the auto shuttle vote to happen after the config duration
- next_autotransfer = world.time + config.vote_autotransfer_initial
+ next_autotransfer = world.time + GLOB.configuration.vote.autotransfer_initial_time
for(var/mob/new_player/N in GLOB.mob_list)
if(N.client)
@@ -279,10 +281,12 @@ SUBSYSTEM_DEF(ticker)
if(playercount >= highpop_trigger)
log_debug("Playercount: [playercount] versus trigger: [highpop_trigger] - loading highpop job config")
- SSjobs.LoadJobs("config/jobs_highpop.txt")
+ SSjobs.LoadJobs(TRUE)
else
log_debug("Playercount: [playercount] versus trigger: [highpop_trigger] - keeping standard job config")
+ SSnightshift.check_nightshift()
+
#ifdef UNIT_TESTS
RunUnitTests()
#endif
diff --git a/code/controllers/subsystem/tickets/tickets.dm b/code/controllers/subsystem/tickets/tickets.dm
index 24919f801f5..d5eb31117e2 100644
--- a/code/controllers/subsystem/tickets/tickets.dm
+++ b/code/controllers/subsystem/tickets/tickets.dm
@@ -214,14 +214,18 @@ SUBSYSTEM_DEF(tickets)
"Already Resolved" = "The problem has been resolved already.",
"Mentorhelp" = "Please redirect your question to Mentorhelp, as they are better experienced with these types of questions.",
"Happens Again" = "Thanks, let us know if it continues to happen.",
- "Github Issue Report" = "To report a bug, please go to our Github page. Then go to 'Issues'. Then 'New Issue'. Then fill out the report form. If the report would reveal current-round information, file it after the round ends.",
"Clear Cache" = "To fix a blank screen, go to the 'Special Verbs' tab and press 'Reload UI Resources'. If that fails, clear your BYOND cache (instructions provided with 'Reload UI Resources'). If that still fails, please adminhelp again, stating you have already done the following." ,
"IC Issue" = "This is an In Character (IC) issue and will not be handled by admins. You could speak to Security, Internal Affairs, a Departmental Head, Nanotrasen Representetive, or any other relevant authority currently on station.",
"Reject" = "Reject",
"Man Up" = "Man Up",
- "Appeal on the Forums" = "Appealing a ban must occur on the forums. Privately messaging, or adminhelping about your ban will not resolve it. To appeal your ban, please head to [config.banappeals]"
)
+ if(GLOB.configuration.url.banappeals_url)
+ response_phrases["Appeal on the Forums"] = "Appealing a ban must occur on the forums. Privately messaging, or adminhelping about your ban will not resolve it. To appeal your ban, please head to [GLOB.configuration.url.banappeals_url]"
+
+ if(GLOB.configuration.url.github_url)
+ response_phrases["Github Issue Report"] = "To report a bug, please go to our Github page. Then go to 'Issues'. Then 'New Issue'. Then fill out the report form. If the report would reveal current-round information, file it after the round ends."
+
var/sorted_responses = list()
for(var/key in response_phrases) //build a new list based on the short descriptive keys of the master list so we can send this as the input instead of the full paragraphs to the admin choosing which autoresponse
sorted_responses += key
diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm
index 743d14a3962..83963e99562 100644
--- a/code/controllers/subsystem/vote.dm
+++ b/code/controllers/subsystem/vote.dm
@@ -27,7 +27,7 @@ SUBSYSTEM_DEF(vote)
// Calculate how much time is remaining by comparing current time, to time of vote start,
// plus vote duration
- time_remaining = round((started_time + config.vote_period - world.time)/10)
+ time_remaining = round((started_time + GLOB.configuration.vote.vote_time - world.time)/10)
if(time_remaining < 0)
result()
@@ -53,9 +53,9 @@ SUBSYSTEM_DEF(vote)
voting.Cut()
current_votes.Cut()
- if(auto_muted && !config.ooc_allowed && !(config.auto_toggle_ooc_during_round && SSticker.current_state == GAME_STATE_PLAYING))
+ if(auto_muted && !GLOB.ooc_enabled && !(GLOB.configuration.general.auto_disable_ooc && SSticker.current_state == GAME_STATE_PLAYING))
auto_muted = 0
- config.ooc_allowed = !( config.ooc_allowed )
+ GLOB.ooc_enabled = TRUE
to_chat(world, "The OOC channel has been automatically enabled due to vote end.")
log_admin("OOC was toggled automatically due to vote end.")
message_admins("OOC has been toggled on automatically.")
@@ -83,7 +83,7 @@ SUBSYSTEM_DEF(vote)
choices -= sorted_highest
choices = sorted_choices
//default-vote for everyone who didn't vote
- if(!config.vote_no_default && choices.len)
+ if(!GLOB.configuration.vote.disable_default_vote && choices.len)
var/non_voters = (GLOB.clients.len - total_votes)
if(non_voters > 0)
if(mode == "restart")
@@ -196,7 +196,7 @@ SUBSYSTEM_DEF(vote)
/datum/controller/subsystem/vote/proc/submit_vote(ckey, vote)
if(mode)
- if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder)
+ if(GLOB.configuration.vote.prevent_dead_voting && usr.stat == DEAD && !usr.client.holder)
return 0
if(current_votes[ckey])
choices[choices[current_votes[ckey]]]--
@@ -210,7 +210,7 @@ SUBSYSTEM_DEF(vote)
/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key, code_invoked = FALSE)
if(!mode)
if(started_time != null && !check_rights(R_ADMIN))
- var/next_allowed_time = (started_time + config.vote_delay)
+ var/next_allowed_time = (started_time + GLOB.configuration.vote.vote_delay)
if(next_allowed_time > world.time)
return 0
@@ -221,7 +221,7 @@ SUBSYSTEM_DEF(vote)
if("gamemode")
if(SSticker.current_state >= 2)
return 0
- choices.Add(config.votable_modes)
+ choices.Add(GLOB.configuration.gamemode.votable_modes)
if("crew_transfer")
if(check_rights(R_ADMIN|R_MOD))
if(SSticker.current_state <= 2)
@@ -264,33 +264,33 @@ SUBSYSTEM_DEF(vote)
log_vote(text)
to_chat(world, {"[text]
Click here or type vote to place your vote.
- You have [config.vote_period/10] seconds to vote."})
+ You have [GLOB.configuration.vote.vote_time / 10] seconds to vote."})
switch(vote_type)
if("crew_transfer", "gamemode", "custom", "map")
SEND_SOUND(world, sound('sound/ambience/alarm4.ogg'))
if(mode == "gamemode" && SSticker.ticker_going)
SSticker.ticker_going = FALSE
to_chat(world, "Round start has been delayed.")
- if(mode == "crew_transfer" && config.ooc_allowed)
- auto_muted = 1
- config.ooc_allowed = !( config.ooc_allowed )
+ if(mode == "crew_transfer" && GLOB.ooc_enabled)
+ auto_muted = TRUE
+ GLOB.ooc_enabled = FALSE
to_chat(world, "The OOC channel has been automatically disabled due to a crew transfer vote.")
log_admin("OOC was toggled automatically due to crew_transfer vote.")
message_admins("OOC has been toggled off automatically.")
- if(mode == "gamemode" && config.ooc_allowed)
- auto_muted = 1
- config.ooc_allowed = !( config.ooc_allowed )
+ if(mode == "gamemode" && GLOB.ooc_enabled)
+ auto_muted = TRUE
+ GLOB.ooc_enabled = FALSE
to_chat(world, "The OOC channel has been automatically disabled due to the gamemode vote.")
log_admin("OOC was toggled automatically due to gamemode vote.")
message_admins("OOC has been toggled off automatically.")
- if(mode == "custom" && config.ooc_allowed)
- auto_muted = 1
- config.ooc_allowed = !( config.ooc_allowed )
+ if(mode == "custom" && GLOB.ooc_enabled)
+ auto_muted = TRUE
+ GLOB.ooc_enabled = FALSE
to_chat(world, "The OOC channel has been automatically disabled due to a custom vote.")
log_admin("OOC was toggled automatically due to custom vote.")
message_admins("OOC has been toggled off automatically.")
- time_remaining = round(config.vote_period/10)
+ time_remaining = round(GLOB.configuration.vote.vote_time / 10)
return 1
return 0
@@ -315,25 +315,25 @@ SUBSYSTEM_DEF(vote)
else
dat += "
Start a vote:
- "
//restart
- if(admin || config.allow_vote_restart)
+ if(admin || GLOB.configuration.vote.allow_restart_votes)
dat += "Restart"
else
dat += "Restart (Disallowed)"
dat += "
- "
- if(admin || config.allow_vote_restart)
+ if(admin || GLOB.configuration.vote.allow_restart_votes)
dat += "Crew Transfer"
else
dat += "Crew Transfer (Disallowed)"
if(admin)
- dat += "\t([config.allow_vote_restart?"Allowed":"Disallowed"])"
+ dat += "\t([GLOB.configuration.vote.allow_restart_votes ? "Allowed" : "Disallowed"])"
dat += "
- "
//gamemode
- if(admin || config.allow_vote_mode)
+ if(admin || GLOB.configuration.vote.allow_mode_votes)
dat += "GameMode"
else
dat += "GameMode (Disallowed)"
if(admin)
- dat += "\t([config.allow_vote_mode?"Allowed":"Disallowed"])"
+ dat += "\t([GLOB.configuration.vote.allow_mode_votes ? "Allowed" : "Disallowed"])"
dat += "
- "
if(admin)
@@ -391,21 +391,21 @@ SUBSYSTEM_DEF(vote)
reset()
if("toggle_restart")
if(admin)
- config.allow_vote_restart = !config.allow_vote_restart
+ GLOB.configuration.vote.allow_restart_votes = !GLOB.configuration.vote.allow_restart_votes
if("toggle_gamemode")
if(admin)
- config.allow_vote_mode = !config.allow_vote_mode
+ GLOB.configuration.vote.allow_mode_votes = !GLOB.configuration.vote.allow_mode_votes
if("restart")
- if(config.allow_vote_restart || admin)
+ if(GLOB.configuration.vote.allow_restart_votes || admin)
initiate_vote("restart",usr.key)
if("gamemode")
- if(config.allow_vote_mode || admin)
+ if(GLOB.configuration.vote.allow_mode_votes || admin)
initiate_vote("gamemode",usr.key)
if("map")
if(admin)
initiate_vote("map", usr.key)
if("crew_transfer")
- if(config.allow_vote_restart || admin)
+ if(GLOB.configuration.vote.allow_restart_votes || admin)
initiate_vote("crew_transfer",usr.key)
if("custom")
if(admin)
diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm
index 33183cacbf0..244b32125b0 100644
--- a/code/controllers/verbs.dm
+++ b/code/controllers/verbs.dm
@@ -28,7 +28,7 @@
return
switch(controller)
if("Configuration")
- debug_variables(config)
+ debug_variables(GLOB.configuration)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Debug Config")
if("pAI")
debug_variables(GLOB.paiController)
diff --git a/code/datums/helper_datums/map_template.dm b/code/datums/helper_datums/map_template.dm
index ee5a4df4f5b..3b942850108 100644
--- a/code/datums/helper_datums/map_template.dm
+++ b/code/datums/helper_datums/map_template.dm
@@ -5,6 +5,8 @@
var/mappath = null
var/mapfile = null
var/loaded = 0 // Times loaded this round
+ /// Do we exclude this from CI checks? If so, set this to the templates pathtype itself to avoid it getting passed down
+ var/ci_exclude = null // DO NOT SET THIS IF YOU DO NOT KNOW WHAT YOU ARE DOING
/datum/map_template/New(path = null, map = null, rename = null)
if(path)
@@ -110,19 +112,16 @@
var/datum/map_template/T = new(path = "[path][map]", rename = "[map]")
GLOB.map_templates[T.name] = T
- if(!config.disable_space_ruins) // so we don't unnecessarily clutter start-up
+ if(GLOB.configuration.ruins.enable_space_ruins) // so we don't unnecessarily clutter start-up
preloadRuinTemplates()
preloadShelterTemplates()
preloadShuttleTemplates()
/proc/preloadRuinTemplates()
- // Still supporting bans by filename
- var/list/banned
- if(fexists("config/spaceRuinBlacklist.txt"))
- banned = generateMapList("config/spaceRuinBlacklist.txt")
- else
- banned = generateMapList("config/example/spaceRuinBlacklist.txt")
- banned += generateMapList("config/lavaRuinBlacklist.txt")
+ // Merge the active lists together
+ var/list/space_ruins = GLOB.configuration.ruins.active_space_ruins.Copy()
+ var/list/lava_ruins = GLOB.configuration.ruins.active_lava_ruins.Copy()
+ var/list/all_ruins = space_ruins | lava_ruins
for(var/item in subtypesof(/datum/map_template/ruin))
var/datum/map_template/ruin/ruin_type = item
@@ -131,7 +130,8 @@
continue
var/datum/map_template/ruin/R = new ruin_type()
- if(banned.Find(R.mappath))
+ // If not in the active list, skip it
+ if(!(R.mappath in all_ruins))
continue
GLOB.map_templates[R.name] = R
diff --git a/code/datums/revision.dm b/code/datums/revision.dm
index d1cb3ff0619..10d5ee1d09d 100644
--- a/code/datums/revision.dm
+++ b/code/datums/revision.dm
@@ -93,10 +93,10 @@ GLOBAL_PROTECT(revision_info) // Dont mess with this
msg += "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]"
// Commit info
- if(GLOB.revision_info.commit_hash && GLOB.revision_info.commit_date)
- msg += "Server Commit: [GLOB.revision_info.commit_hash] (Date: [GLOB.revision_info.commit_date])"
+ if(GLOB.revision_info.commit_hash && GLOB.revision_info.commit_date && GLOB.configuration.url.github_url)
+ msg += "Server Commit: [GLOB.revision_info.commit_hash] (Date: [GLOB.revision_info.commit_date])"
if(GLOB.revision_info.origin_commit && (GLOB.revision_info.commit_hash != GLOB.revision_info.origin_commit))
- msg += "Origin Commit: [GLOB.revision_info.origin_commit]"
+ msg += "Origin Commit: [GLOB.revision_info.origin_commit]"
else
msg += "Server Commit: Unable to determine"
diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm
index 5110058674a..4dd2a53f64f 100644
--- a/code/datums/ruins/lavaland.dm
+++ b/code/datums/ruins/lavaland.dm
@@ -1,9 +1,11 @@
/datum/map_template/ruin/lavaland
prefix = "_maps/map_files/RandomRuins/LavaRuins/"
+ ci_exclude = /datum/map_template/ruin/lavaland
/datum/map_template/ruin/lavaland/biodome
cost = 5
allow_duplicates = FALSE
+ ci_exclude = /datum/map_template/ruin/lavaland/biodome // This is a parent holder, not a ruin itself
/datum/map_template/ruin/lavaland/biodome/beach
name = "Biodome Beach"
@@ -71,6 +73,7 @@
/datum/map_template/ruin/lavaland/sin
cost = 10
allow_duplicates = FALSE
+ ci_exclude = /datum/map_template/ruin/lavaland/sin // This is a parent holder, not a ruin itself
/datum/map_template/ruin/lavaland/sin/envy
name = "Ruin of Envy"
diff --git a/code/datums/ruins/space.dm b/code/datums/ruins/space.dm
index d05b932b5cc..2a4e43821ac 100644
--- a/code/datums/ruins/space.dm
+++ b/code/datums/ruins/space.dm
@@ -2,6 +2,7 @@
/datum/map_template/ruin/space
prefix = "_maps/map_files/RandomRuins/SpaceRuins/"
cost = 1
+ ci_exclude = /datum/map_template/ruin/space
/datum/map_template/ruin/space/zoo
id = "zoo"
diff --git a/code/datums/spells/lichdom.dm b/code/datums/spells/lichdom.dm
index 32f2cd7e520..b863738c4a0 100644
--- a/code/datums/spells/lichdom.dm
+++ b/code/datums/spells/lichdom.dm
@@ -25,13 +25,13 @@
if(istype(S,/obj/effect/proc_holder/spell/targeted/lichdom) && S != src)
return ..()
if(existence_stops_round_end)
- config.continuous_rounds = 0
+ GLOB.configuration.gamemode.disable_certain_round_early_end = FALSE
return ..()
/obj/effect/proc_holder/spell/targeted/lichdom/cast(list/targets, mob/user = usr)
- if(!config.continuous_rounds)
- existence_stops_round_end = 1
- config.continuous_rounds = 1
+ if(!GLOB.configuration.gamemode.disable_certain_round_early_end)
+ existence_stops_round_end = TRUE
+ GLOB.configuration.gamemode.disable_certain_round_early_end = TRUE
for(var/mob/M in targets)
var/list/hand_items = list()
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index e8e08609e82..b3ae451aa35 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -102,7 +102,7 @@
else if(dynamic_lighting != DYNAMIC_LIGHTING_IFSTARLIGHT)
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
if(dynamic_lighting == DYNAMIC_LIGHTING_IFSTARLIGHT)
- dynamic_lighting = config.starlight ? DYNAMIC_LIGHTING_ENABLED : DYNAMIC_LIGHTING_DISABLED
+ dynamic_lighting = GLOB.configuration.general.starlight ? DYNAMIC_LIGHTING_ENABLED : DYNAMIC_LIGHTING_DISABLED
. = ..()
diff --git a/code/game/gamemodes/autotraitor/autotraitor.dm b/code/game/gamemodes/autotraitor/autotraitor.dm
index f0dbb68ec15..908daffeb77 100644
--- a/code/game/gamemodes/autotraitor/autotraitor.dm
+++ b/code/game/gamemodes/autotraitor/autotraitor.dm
@@ -15,7 +15,7 @@
/datum/game_mode/traitor/autotraitor/pre_setup()
- if(config.protect_roles_from_antagonist)
+ if(GLOB.configuration.gamemode.prevent_mindshield_antags)
restricted_jobs += protected_jobs
possible_traitors = get_players_for_role(ROLE_TRAITOR)
@@ -35,7 +35,7 @@
if(!possible_traitors.len)
return 0
- if(config.traitor_scaling)
+ if(GLOB.configuration.gamemode.traitor_scaling)
num_traitors = max_traitors - 1 + prob(traitor_prob)
log_game("Number of traitors: [num_traitors]")
message_admins("Players counted: [num_players] Number of traitors chosen: [num_traitors]")
diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm
index 85d776ad662..f89cf5c2a7f 100644
--- a/code/game/gamemodes/blob/blob.dm
+++ b/code/game/gamemodes/blob/blob.dm
@@ -101,7 +101,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
to_chat(blob.current, "Find a good location to spawn the core and then take control and overwhelm the station!")
to_chat(blob.current, "When you have found a location, wait until you spawn; this will happen automatically and you cannot speed up the process.")
to_chat(blob.current, "If you go outside of the station level, or in space, then you will die; make sure your location has lots of ground to cover.")
- to_chat(blob.current, "For more information, check the wiki page: ([config.wikiurl]/index.php/Blob)")
+ to_chat(blob.current, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Blob)")
SEND_SOUND(blob.current, sound('sound/magic/mutate.ogg'))
return
diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index 01f87d3b758..03326235953 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -41,7 +41,7 @@ GLOBAL_LIST_INIT(possible_changeling_IDs, list("Alpha","Beta","Gamma","Delta","E
to_chat(world, "There are alien changelings on the station. Do not let the changelings succeed!")
/datum/game_mode/changeling/pre_setup()
- if(config.protect_roles_from_antagonist)
+ if(GLOB.configuration.gamemode.prevent_mindshield_antags)
restricted_jobs += protected_jobs
var/list/datum/mind/possible_changelings = get_players_for_role(ROLE_CHANGELING)
@@ -147,7 +147,7 @@ GLOBAL_LIST_INIT(possible_changeling_IDs, list("Alpha","Beta","Gamma","Delta","E
for(var/datum/objective/objective in changeling.objectives)
to_chat(changeling.current, "Objective #[obj_count]: [objective.explanation_text]")
obj_count++
- to_chat(changeling.current, "For more information, check the wiki page: ([config.wikiurl]/index.php/Changeling)")
+ to_chat(changeling.current, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Changeling)")
return
/datum/game_mode/proc/remove_changeling(datum/mind/changeling_mind)
diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm
index b7ff2c30e0d..f315d79eb99 100644
--- a/code/game/gamemodes/changeling/traitor_chan.dm
+++ b/code/game/gamemodes/changeling/traitor_chan.dm
@@ -16,7 +16,7 @@
/datum/game_mode/traitor/changeling/pre_setup()
- if(config.protect_roles_from_antagonist)
+ if(GLOB.configuration.gamemode.prevent_mindshield_antags)
restricted_jobs += protected_jobs
var/list/datum/mind/possible_changelings = get_players_for_role(ROLE_CHANGELING)
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index fb15a380c60..60ded97ac3f 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -62,7 +62,7 @@ GLOBAL_LIST_EMPTY(all_cults)
to_chat(world, "Some crewmembers are attempting to start a cult!
\nCultists - complete your objectives. Convert crewmembers to your cause by using the offer rune. Remember - there is no you, there is only the cult.
\nPersonnel - Do not let the cult succeed in its mission. Brainwashing them with holy water reverts them to whatever CentComm-allowed faith they had.")
/datum/game_mode/cult/pre_setup()
- if(config.protect_roles_from_antagonist)
+ if(GLOB.configuration.gamemode.prevent_mindshield_antags)
restricted_jobs += protected_jobs
var/list/cultists_possible = get_players_for_role(ROLE_CULTIST)
@@ -99,7 +99,7 @@ GLOBAL_LIST_EMPTY(all_cults)
add_cult_actions(cult_mind)
update_cult_icons_added(cult_mind)
cult_objs.study(cult_mind.current)
- to_chat(cult_mind.current, "For more information, check the wiki page: ([config.wikiurl]/index.php/Cultist)")
+ to_chat(cult_mind.current, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Cultist)")
cult_threshold_check()
addtimer(CALLBACK(src, .proc/cult_threshold_check), 2 MINUTES) // Check again in 2 minutes for latejoiners
..()
@@ -167,7 +167,7 @@ GLOBAL_LIST_EMPTY(all_cults)
ascend(cult_mind.current)
check_cult_size()
cult_objs.study(cult_mind.current)
- to_chat(cult_mind.current, "For more information, check the wiki page: ([config.wikiurl]/index.php/Cultist)")
+ to_chat(cult_mind.current, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Cultist)")
return TRUE
/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, show_message = TRUE, remove_gear = FALSE)
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 7fdf66c7a1f..2b0000d9c38 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -54,7 +54,7 @@
if((player.client)&&(player.ready))
playerC++
- if(!config.enable_gamemode_player_limit || (playerC >= required_players))
+ if(!GLOB.configuration.gamemode.enable_gamemode_player_limit || (playerC >= required_players))
return 1
return 0
diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm
index a579a90273c..e36411a506a 100644
--- a/code/game/gamemodes/heist/heist.dm
+++ b/code/game/gamemodes/heist/heist.dm
@@ -181,7 +181,7 @@ GLOBAL_LIST_EMPTY(cortical_stacks) //Stacks for 'leave nobody behind' objective.
to_chat(raider.current, "Vox are cowardly and will flee from larger groups, but corner one or find them en masse and they are vicious.")
to_chat(raider.current, "Use :V to voxtalk, :H to talk on your encrypted channel, and don't forget to turn on your nitrogen internals!")
to_chat(raider.current, "Choose to accomplish your objectives by either raiding the crew and taking what you need, or by attempting to trade with them.")
- to_chat(raider.current, "For more information, check the wiki page: ([config.wikiurl]/index.php/Vox_Raider)")
+ to_chat(raider.current, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Vox_Raider)")
spawn(25)
show_objectives(raider)
diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm
index 6587907cdbd..f3cc450f155 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction.dm
@@ -158,7 +158,7 @@
to_chat(abductor.current, "You are an agent of [team_name]!")
to_chat(abductor.current, "With the help of your teammate, kidnap and experiment on station crew members!")
to_chat(abductor.current, "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve.")
- to_chat(abductor.current, "For more information, check the wiki page: ([config.wikiurl]/index.php/Abductor)")
+ to_chat(abductor.current, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Abductor)")
abductor.announce_objectives()
@@ -171,7 +171,7 @@
to_chat(abductor.current, "You are a scientist of [team_name]!")
to_chat(abductor.current, "With the help of your teammate, kidnap and experiment on station crew members!")
to_chat(abductor.current, "Use your tool and ship consoles to support the agent and retrieve human specimens.")
- to_chat(abductor.current, "For more information, check the wiki page: ([config.wikiurl]/index.php/Abductor)")
+ to_chat(abductor.current, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Abductor)")
abductor.announce_objectives()
diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm
index ea62734f383..b2f07c7e4e6 100644
--- a/code/game/gamemodes/miniantags/borer/borer.dm
+++ b/code/game/gamemodes/miniantags/borer/borer.dm
@@ -837,7 +837,7 @@
to_chat(src, "You are a brain slug that worms its way into the head of its victim. Use stealth, persuasion and your powers of mind control to keep you, your host and your eventual spawn safe and warm.")
to_chat(src, "Sugar nullifies your abilities, avoid it at all costs!")
to_chat(src, "You can speak to your fellow borers by prefixing your messages with ':bo'. Check out your Borer tab to see your abilities.")
- to_chat(src, "For more information, check the wiki page: ([config.wikiurl]/index.php/Cortical_Borer)")
+ to_chat(src, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Cortical_Borer)")
/proc/create_borer_mind(key)
var/datum/mind/M = new /datum/mind(key)
diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
index e597da7864f..bc82815d7f5 100644
--- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
+++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
@@ -112,7 +112,7 @@
to_chat(src, "1. Consume resources and replicate until there are no more resources left.")
to_chat(src, "2. Ensure that the station is fit for invasion at a later date, do not perform actions that would render it dangerous or inhospitable.")
to_chat(src, "3. Biological and sentient resources will be harvested at a later date, do not harm them.")
- to_chat(src, "For more information, check the wiki page: ([config.wikiurl]/index.php/Swarmer)")
+ to_chat(src, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Swarmer)")
/mob/living/simple_animal/hostile/swarmer/New()
..()
diff --git a/code/game/gamemodes/miniantags/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm
index db33bc355a8..beea65ec465 100644
--- a/code/game/gamemodes/miniantags/guardian/guardian.dm
+++ b/code/game/gamemodes/miniantags/guardian/guardian.dm
@@ -343,7 +343,7 @@
to_chat(G, "You are capable of manifesting or recalling to your master with verbs in the Guardian tab. You will also find a verb to communicate with them privately there.")
to_chat(G, "While personally invincible, you will die if [user.real_name] does, and any damage dealt to you will have a portion passed on to them as you feed upon them to sustain yourself.")
to_chat(G, "[G.playstyle_string]")
- to_chat(G, "For more information, check the wiki page: ([config.wikiurl]/index.php/Guardian)")
+ to_chat(G, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Guardian)")
G.faction = user.faction
var/color = pick(color_list)
diff --git a/code/game/gamemodes/miniantags/morph/morph_event.dm b/code/game/gamemodes/miniantags/morph/morph_event.dm
index f24166b1381..ad42365947b 100644
--- a/code/game/gamemodes/miniantags/morph/morph_event.dm
+++ b/code/game/gamemodes/miniantags/morph/morph_event.dm
@@ -26,7 +26,7 @@
player_mind.special_role = SPECIAL_ROLE_MORPH
SSticker.mode.traitors |= player_mind
to_chat(S, S.playstyle_string)
- to_chat(S, "For more information, check the wiki page: ([config.wikiurl]/index.php/Morph)")
+ to_chat(S, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Morph)")
SEND_SOUND(S, sound('sound/magic/mutate.ogg'))
message_admins("[key_of_morph] has been made into morph by an event.")
log_game("[key_of_morph] was spawned as a morph by an event.")
diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm
index 9373861798e..fa5af6b12ff 100644
--- a/code/game/gamemodes/miniantags/revenant/revenant.dm
+++ b/code/game/gamemodes/miniantags/revenant/revenant.dm
@@ -168,7 +168,7 @@
to_chat(src, "You are invincible and invisible to everyone but other ghosts. Most abilities will reveal you, rendering you vulnerable.")
to_chat(src, "To function, you are to drain the life essence from humans. This essence is a resource, as well as your health, and will power all of your abilities.")
to_chat(src, "You do not remember anything of your past lives, nor will you remember anything about this one after your death.")
- to_chat(src, "For more information, check the wiki page: ([config.wikiurl]/index.php/Revenant)")
+ to_chat(src, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Revenant)")
var/datum/objective/revenant/objective = new
objective.owner = mind
mind.objectives += objective
diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm
index 88ce7fbff99..feeffc68c04 100644
--- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm
+++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm
@@ -92,7 +92,7 @@
mind.objectives += fluffObjective
to_chat(src, "Objective #[1]: [objective.explanation_text]")
to_chat(src, "Objective #[2]: [fluffObjective.explanation_text]")
- to_chat(src, "For more information, check the wiki page: ([config.wikiurl]/index.php/Slaughter_Demon)")
+ to_chat(src, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Slaughter_Demon)")
/obj/effect/decal/cleanable/blood/innards
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index fafa2c4e4a1..1ace6f6a836 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -250,7 +250,7 @@
for(var/datum/objective/objective in syndicate.objectives)
to_chat(syndicate.current, "Objective #[obj_count]: [objective.explanation_text]")
obj_count++
- to_chat(syndicate.current, "For more information, check the wiki page: ([config.wikiurl]/index.php/Nuclear_Agent)")
+ to_chat(syndicate.current, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Nuclear_Agent)")
return
diff --git a/code/game/gamemodes/nuclear/nuclear_challenge.dm b/code/game/gamemodes/nuclear/nuclear_challenge.dm
index be071fc80ad..c7a5f1d32bc 100644
--- a/code/game/gamemodes/nuclear/nuclear_challenge.dm
+++ b/code/game/gamemodes/nuclear/nuclear_challenge.dm
@@ -60,7 +60,7 @@
// No. of player - Min. Player to dec, divided by player per bonus, then multipled by TC per bonus. Rounded.
total_tc = CHALLENGE_TELECRYSTALS + round((((GLOB.player_list.len - CHALLENGE_MIN_PLAYERS)/CHALLENGE_SCALE_PLAYER) * CHALLENGE_SCALE_BONUS))
share_telecrystals()
- config.shuttle_refuel_delay = CHALLENGE_SHUTTLE_DELAY
+ SSshuttle.refuel_delay = CHALLENGE_SHUTTLE_DELAY
qdel(src)
/obj/item/nuclear_challenge/proc/share_telecrystals()
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index b4452295c31..93e385df6a9 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -38,7 +38,7 @@
/datum/game_mode/revolution/pre_setup()
possible_revolutionaries = get_players_for_role(ROLE_REV)
- if(config.protect_roles_from_antagonist)
+ if(GLOB.configuration.gamemode.prevent_mindshield_antags)
restricted_jobs += protected_jobs
@@ -110,7 +110,7 @@
to_chat(rev_mind.current, "Objective #[obj_count]: [objective.explanation_text]")
rev_mind.special_role = SPECIAL_ROLE_HEAD_REV
obj_count++
- to_chat(rev_mind.current, "For more information, check the wiki page: ([config.wikiurl]/index.php/Revolution)")
+ to_chat(rev_mind.current, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Revolution)")
/////////////////////////////////////////////////////////////////////////////////
//This are equips the rev heads with their gear, and makes the clown not clumsy//
@@ -214,7 +214,7 @@
//Checks if the round is over//
///////////////////////////////
/datum/game_mode/revolution/check_finished()
- if(config.continuous_rounds)
+ if(GLOB.configuration.gamemode.disable_certain_round_early_end)
if(finished != 0)
SSshuttle.emergencyNoEscape = 0
if(SSshuttle.emergency.mode == SHUTTLE_STRANDED)
diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm
index 67109419040..1cb4e6fbb35 100644
--- a/code/game/gamemodes/shadowling/shadowling.dm
+++ b/code/game/gamemodes/shadowling/shadowling.dm
@@ -81,7 +81,7 @@ Made by Xhuis
to_chat(world, "There are alien shadowlings on the station. Crew: Kill the shadowlings before they can eat or enthrall the crew. Shadowlings: Enthrall the crew while remaining in hiding.")
/datum/game_mode/shadowling/pre_setup()
- if(config.protect_roles_from_antagonist)
+ if(GLOB.configuration.gamemode.prevent_mindshield_antags)
restricted_jobs += protected_jobs
var/list/datum/mind/possible_shadowlings = get_players_for_role(ROLE_SHADOWLING)
@@ -126,7 +126,7 @@ Made by Xhuis
to_chat(shadow.current, "Currently, you are disguised as an employee aboard [world.name].")
to_chat(shadow.current, "In your limited state, you have two abilities: Hatch and Shadowling Hivemind (:8).")
to_chat(shadow.current, "Any other shadowlings are your allies. You must assist them as they shall assist you.")
- to_chat(shadow.current, "For more information, check the wiki page: ([config.wikiurl]/index.php/Shadowling)")
+ to_chat(shadow.current, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Shadowling)")
/datum/game_mode/proc/process_shadow_objectives(datum/mind/shadow_mind)
@@ -168,7 +168,7 @@ Made by Xhuis
to_chat(new_thrall_mind.current, "Your body has been irreversibly altered. The attentive can see this - you may conceal it by wearing a mask.")
to_chat(new_thrall_mind.current, "Though not nearly as powerful as your masters, you possess some weak powers. These can be found in the Thrall Abilities tab.")
to_chat(new_thrall_mind.current, "You may communicate with your allies by speaking in the Shadowling Hivemind (:8).")
- to_chat(new_thrall_mind.current, "For more information, check the wiki page: ([config.wikiurl]/index.php/Shadowling)")
+ to_chat(new_thrall_mind.current, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Shadowling)")
if(jobban_isbanned(new_thrall_mind.current, ROLE_SHADOWLING) || jobban_isbanned(new_thrall_mind.current, ROLE_SYNDICATE))
replace_jobbanned_player(new_thrall_mind.current, ROLE_SHADOWLING)
if(!victory_warning_announced && (length(shadowling_thralls) >= warning_threshold))//are the slings very close to winning?
@@ -216,13 +216,13 @@ Made by Xhuis
if(shadow.current.stat == DEAD)
continue
shadows_alive++
- if(shadow.special_role == SPECIAL_ROLE_SHADOWLING && config.shadowling_max_age)
+ if(shadow.special_role == SPECIAL_ROLE_SHADOWLING && GLOB.configuration.gamemode.shadowling_max_age)
if(ishuman(shadow.current))
var/mob/living/carbon/human/H = shadow.current
if(!isshadowling(H))
for(var/obj/effect/proc_holder/spell/targeted/shadowling_hatch/hatch_ability in shadow.spell_list)
hatch_ability.cycles_unused++
- if(!H.stunned && prob(20) && hatch_ability.cycles_unused > config.shadowling_max_age)
+ if(!H.stunned && prob(20) && hatch_ability.cycles_unused > GLOB.configuration.gamemode.shadowling_max_age)
var/shadow_nag_messages = list("You can barely hold yourself in this lesser form!", "The urge to become something greater is overwhelming!", "You feel a burning passion to hatch free of this shell and assume godhood!")
H.take_overall_damage(0, 3)
to_chat(H, "[pick(shadow_nag_messages)]")
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index f247f860400..6cbfeca3c10 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -28,7 +28,7 @@
/datum/game_mode/traitor/pre_setup()
- if(config.protect_roles_from_antagonist)
+ if(GLOB.configuration.gamemode.prevent_mindshield_antags)
restricted_jobs += protected_jobs
var/list/possible_traitors = get_players_for_role(ROLE_TRAITOR)
@@ -39,7 +39,7 @@
var/num_traitors = 1
- if(config.traitor_scaling)
+ if(GLOB.configuration.gamemode.traitor_scaling)
num_traitors = max(1, round((num_players())/(traitor_scaling_coeff)))
else
num_traitors = max(1, min(num_players(), traitors_possible))
diff --git a/code/game/gamemodes/vampire/traitor_vamp.dm b/code/game/gamemodes/vampire/traitor_vamp.dm
index 7fb1088214b..9ad66fdb976 100644
--- a/code/game/gamemodes/vampire/traitor_vamp.dm
+++ b/code/game/gamemodes/vampire/traitor_vamp.dm
@@ -17,7 +17,7 @@
/datum/game_mode/traitor/vampire/pre_setup()
- if(config.protect_roles_from_antagonist)
+ if(GLOB.configuration.gamemode.prevent_mindshield_antags)
restricted_jobs += protected_jobs
var/list/datum/mind/possible_vampires = get_players_for_role(ROLE_VAMPIRE)
diff --git a/code/game/gamemodes/vampire/vampire.dm b/code/game/gamemodes/vampire/vampire.dm
index ff3a6152da1..69972d2bea5 100644
--- a/code/game/gamemodes/vampire/vampire.dm
+++ b/code/game/gamemodes/vampire/vampire.dm
@@ -40,7 +40,7 @@
/datum/game_mode/vampire/pre_setup()
- if(config.protect_roles_from_antagonist)
+ if(GLOB.configuration.gamemode.prevent_mindshield_antags)
restricted_jobs += protected_jobs
var/list/datum/mind/possible_vampires = get_players_for_role(ROLE_VAMPIRE)
@@ -193,7 +193,7 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
for(var/datum/objective/objective in vampire.objectives)
to_chat(vampire.current, "Objective #[obj_count]: [objective.explanation_text]")
obj_count++
- to_chat(vampire.current, "For more information, check the wiki page: ([config.wikiurl]/index.php/Vampire)")
+ to_chat(vampire.current, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Vampire)")
return
/datum/vampire
var/bloodtotal = 0 // CHANGE TO ZERO WHEN PLAYTESTING HAPPENS
diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm
index 574042abc08..110bfec4a4e 100644
--- a/code/game/gamemodes/wizard/soulstone.dm
+++ b/code/game/gamemodes/wizard/soulstone.dm
@@ -328,7 +328,7 @@
var/mob/living/simple_animal/hostile/construct/C = new picked_class(shell.loc)
C.init_construct(shade, src, shell)
to_chat(C, C.playstyle_string)
- to_chat(C, "For more information, check the wiki page: ([config.wikiurl]/index.php/Construct)")
+ to_chat(C, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Construct)")
else
to_chat(user, "Creation failed!: The soul stone is empty! Go kill someone!")
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index d076afbaadb..d58a88d621e 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -108,19 +108,9 @@
for(var/datum/objective/objective in wizard.objectives)
to_chat(wizard.current, "Objective #[obj_count]: [objective.explanation_text]")
obj_count++
- to_chat(wizard.current, "For more information, check the wiki page: ([config.wikiurl]/index.php/Wizard)")
+ to_chat(wizard.current, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Wizard)")
return
-/*/datum/game_mode/proc/learn_basic_spells(mob/living/carbon/human/wizard_mob)
- if(!istype(wizard_mob))
- return
- if(!config.feature_object_spell_system)
- wizard_mob.verbs += /client/proc/jaunt
- wizard_mob.mind.special_verbs += /client/proc/jaunt
- else
- wizard_mob.spell_list += new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(usr)
-*/
-
/datum/game_mode/proc/equip_wizard(mob/living/carbon/human/wizard_mob)
if(!istype(wizard_mob))
return
diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm
index 6adc55a89f1..7dddfd6a8d7 100644
--- a/code/game/jobs/job/civilian.dm
+++ b/code/game/jobs/job/civilian.dm
@@ -13,7 +13,7 @@
outfit = /datum/outfit/job/assistant
/datum/job/civilian/get_access()
- if(config.assistant_maint)
+ if(GLOB.configuration.jobs.assistant_maint_access)
return list(ACCESS_MAINT_TUNNELS)
else
return list()
diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm
index 8f313c185dc..1c82df936bb 100644
--- a/code/game/jobs/job/job.dm
+++ b/code/game/jobs/job/job.dm
@@ -85,10 +85,11 @@
announce(H)
/datum/job/proc/get_access()
- if(!config) //Needed for robots.
+ if(!GLOB?.configuration?.jobs) //Needed for robots.
+ // AA TODO: Remove this once mulebots and stuff use Initialize()
return src.minimal_access.Copy()
- if(config.jobs_have_minimal_access)
+ if(GLOB.configuration.jobs.jobs_have_minimal_access)
return src.minimal_access.Copy()
else
return src.access.Copy()
@@ -103,7 +104,7 @@
/datum/job/proc/available_in_days(client/C)
if(!C)
return 0
- if(!config.use_age_restriction_for_jobs)
+ if(!GLOB.configuration.jobs.restrict_jobs_on_account_age)
return 0
if(!isnum(C.player_age))
return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced
diff --git a/code/game/jobs/job_exp.dm b/code/game/jobs/job_exp.dm
index b30fbac02c4..1c9ef7de79f 100644
--- a/code/game/jobs/job_exp.dm
+++ b/code/game/jobs/job_exp.dm
@@ -43,7 +43,7 @@ GLOBAL_LIST_INIT(role_playtime_requirements, list(
set category = "Special Verbs"
set name = "Check my playtime"
- if(!config.use_exp_tracking)
+ if(!GLOB.configuration.jobs.enable_exp_tracking)
to_chat(src, "Playtime tracking is not enabled.")
return
@@ -105,9 +105,9 @@ GLOBAL_LIST_INIT(role_playtime_requirements, list(
return 0
if(!role)
return 0
- if(!config.use_exp_restrictions)
+ if(!GLOB.configuration.jobs.enable_exp_restrictions)
return 0
- if(config.use_exp_restrictions_admin_bypass && check_rights(R_ADMIN, 0, C.mob))
+ if(GLOB.configuration.jobs.enable_exp_admin_bypass && check_rights(R_ADMIN, 0, C.mob))
return 0
var/list/play_records = params2list(C.prefs.exp)
var/isexempt = text2num(play_records[EXP_TYPE_EXEMPT])
@@ -128,9 +128,9 @@ GLOBAL_LIST_INIT(role_playtime_requirements, list(
return 0
if(!exp_requirements || !exp_type)
return 0
- if(!config.use_exp_restrictions)
+ if(!GLOB.configuration.jobs.enable_exp_restrictions)
return 0
- if(config.use_exp_restrictions_admin_bypass && check_rights(R_ADMIN, 0, C.mob))
+ if(GLOB.configuration.jobs.enable_exp_admin_bypass && check_rights(R_ADMIN, 0, C.mob))
return 0
var/list/play_records = params2list(C.prefs.exp)
var/isexempt = text2num(play_records[EXP_TYPE_EXEMPT])
@@ -156,7 +156,7 @@ GLOBAL_LIST_INIT(role_playtime_requirements, list(
return "[src] has no client."
/client/proc/get_exp_report()
- if(!config.use_exp_tracking)
+ if(!GLOB.configuration.jobs.enable_exp_tracking)
return "Tracking is disabled in the server configuration file."
var/list/play_records = params2list(prefs.exp)
if(!play_records.len)
@@ -174,10 +174,10 @@ GLOBAL_LIST_INIT(role_playtime_requirements, list(
return_text += " - Exempt (all jobs auto-unlocked)
"
else if(exp_data[EXP_TYPE_LIVING] > 0)
return_text += "- [dep]: [get_exp_format(exp_data[dep])]
"
- if(config.use_exp_restrictions_admin_bypass && check_rights(R_ADMIN, 0, mob))
+ if(GLOB.configuration.jobs.enable_exp_admin_bypass && check_rights(R_ADMIN, 0, mob))
return_text += "- Admin
"
return_text += "
"
- if(config.use_exp_restrictions)
+ if(GLOB.configuration.jobs.enable_exp_restrictions)
var/list/jobs_locked = list()
var/list/jobs_unlocked = list()
for(var/datum/job/job in SSjobs.occupations)
diff --git a/code/game/jobs/whitelist.dm b/code/game/jobs/whitelist.dm
index af80e7474a4..b327da6390f 100644
--- a/code/game/jobs/whitelist.dm
+++ b/code/game/jobs/whitelist.dm
@@ -1,29 +1,6 @@
-#define WHITELISTFILE "data/whitelist.txt"
-
-GLOBAL_LIST_EMPTY(whitelist)
-
-/proc/init_whitelists()
- if(config.usewhitelist)
- load_whitelist()
- if(config.usealienwhitelist)
- load_alienwhitelist()
-
-/proc/load_whitelist()
- GLOB.whitelist = file2list(WHITELISTFILE)
- if(!GLOB.whitelist.len)
- GLOB.whitelist = null
-/*
-/proc/check_whitelist(mob/M, rank)
- if(!whitelist)
- return 0
- return ("[M.ckey]" in whitelist)
-*/
-
/proc/is_job_whitelisted(mob/M, rank)
if(guest_jobbans(rank))
- if(!config.usewhitelist)
- return TRUE
- if(config.disable_karma)
+ if(!GLOB.configuration.general.enable_karma)
return TRUE
if(check_rights(R_ADMIN, 0, M))
return TRUE
@@ -55,30 +32,13 @@ GLOBAL_LIST_EMPTY(whitelist)
else
return TRUE
-
-
-
-GLOBAL_LIST_EMPTY(alien_whitelist)
-
-/proc/load_alienwhitelist()
- var/text = file2text("config/alienwhitelist.txt")
- if(!text)
- log_config("Failed to load config/alienwhitelist.txt\n")
- else
- GLOB.alien_whitelist = splittext(text, "\n")
-
-//todo: admin aliens
/proc/is_alien_whitelisted(mob/M, species)
- if(!config.usealienwhitelist)
- return TRUE
- if(config.disable_karma)
+ if(!GLOB.configuration.general.enable_karma)
return TRUE
if(species == "human" || species == "Human")
return TRUE
if(check_rights(R_ADMIN, 0))
return TRUE
- if(!GLOB.alien_whitelist)
- return FALSE
if(!SSdbcore.IsConnected())
return FALSE
else
@@ -104,14 +64,3 @@ GLOBAL_LIST_EMPTY(alien_whitelist)
break
qdel(species_read)
-/*
- if(M && species)
- for(var/s in alien_whitelist)
- if(findtext(s,"[M.ckey] - [species]"))
- return 1
- if(findtext(s,"[M.ckey] - All"))
- return 1
-*/
-
-
-#undef WHITELISTFILE
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index f2a76b15f58..77c78506676 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -338,7 +338,7 @@
set_temp("Error: Not enough biomass.", "danger")
else if(pod.mess)
set_temp("Error: The cloning pod is malfunctioning.", "danger")
- else if(!config.revival_cloning)
+ else if(!GLOB.configuration.general.enable_cloning)
set_temp("Error: Unable to initiate cloning cycle.", "danger")
else
cloneresult = pod.growclone(C)
diff --git a/code/game/objects/effects/effect_system/effects_other.dm b/code/game/objects/effects/effect_system/effects_other.dm
index d28367a1489..bb33bfe15fa 100644
--- a/code/game/objects/effects/effect_system/effects_other.dm
+++ b/code/game/objects/effects/effect_system/effects_other.dm
@@ -45,15 +45,15 @@
var/light = -1
var/flash = -1
- // Clamp all values to MAX_EXPLOSION_RANGE
+ // We dont need to clamp here. It gets clamped inside explosion()
if(round(amount/12) > 0)
- devastation = min (GLOB.max_ex_devastation_range, devastation + round(amount/12))
+ devastation += round(amount/12)
if(round(amount/6) > 0)
- heavy = min (GLOB.max_ex_heavy_range, heavy + round(amount/6))
+ heavy += round(amount/6)
if(round(amount/3) > 0)
- light = min (GLOB.max_ex_light_range, light + round(amount/3))
+ light += round(amount/3)
if(flashing && flashing_factor)
flash += (round(amount/4) * flashing_factor)
diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm
index 4e4eefbe9cb..8be822219c1 100644
--- a/code/game/objects/explosion.dm
+++ b/code/game/objects/explosion.dm
@@ -24,11 +24,11 @@
if(!ignorecap)
// Clamp all values to MAX_EXPLOSION_RANGE
- devastation_range = min (GLOB.max_ex_devastation_range, devastation_range)
- heavy_impact_range = min (GLOB.max_ex_heavy_range, heavy_impact_range)
- light_impact_range = min (GLOB.max_ex_light_range, light_impact_range)
- flash_range = min (GLOB.max_ex_flash_range, flash_range)
- flame_range = min (GLOB.max_ex_flame_range, flame_range)
+ devastation_range = min(GLOB.configuration.general.bomb_cap / 4, devastation_range)
+ heavy_impact_range = min(GLOB.configuration.general.bomb_cap / 2, heavy_impact_range)
+ light_impact_range = min(GLOB.configuration.general.bomb_cap, light_impact_range)
+ flash_range = min(GLOB.configuration.general.bomb_cap, flash_range)
+ flame_range = min(GLOB.configuration.general.bomb_cap, flame_range)
var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flame_range)
@@ -118,7 +118,7 @@
var/list/affected_turfs = spiral_range_turfs(max_range, epicenter)
- if(config.reactionary_explosions)
+ if(GLOB.configuration.general.reactionary_explosions)
for(var/A in affected_turfs) // we cache the explosion block rating of every turf in the explosion area
var/turf/T = A
cached_exp_block[T] = 0
@@ -136,7 +136,7 @@
continue
var/dist = HYPOTENUSE(T.x, T.y, x0, y0)
- if(config.reactionary_explosions)
+ if(GLOB.configuration.general.reactionary_explosions)
var/turf/Trajectory = T
while(Trajectory != epicenter)
Trajectory = get_step_towards(Trajectory, epicenter)
diff --git a/code/game/objects/items/weapons/dice.dm b/code/game/objects/items/weapons/dice.dm
index 6395b55a3b1..adda05615e6 100644
--- a/code/game/objects/items/weapons/dice.dm
+++ b/code/game/objects/items/weapons/dice.dm
@@ -179,12 +179,11 @@
addtimer(CALLBACK(src, .proc/boom, user, result), 4 SECONDS)
/obj/item/dice/d20/e20/proc/boom(mob/user, result)
- var/capped = FALSE
+ var/capped = TRUE
var/actual_result = result
- if(result != 20)
- capped = TRUE
- result = min(result, GLOB.max_ex_light_range) // Apply the bombcap
- else // Rolled a nat 20, screw the bombcap
+ // Rolled a nat 20, screw the bombcap
+ if(result == 20)
+ capped = FALSE
result = 24
var/turf/epicenter = get_turf(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm
index e94d0772f67..0345dca3b7f 100644
--- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm
+++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm
@@ -24,7 +24,7 @@
var/oldloc = loc
step(src, direction)
if(oldloc != loc)
- addtimer(CALLBACK(src, .proc/ResetMoveDelay), config.walk_speed)
+ addtimer(CALLBACK(src, .proc/ResetMoveDelay), GLOB.configuration.movement.base_walk_speed)
else
move_delay = FALSE
diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm
index c56f4cb2603..6efbb726cff 100644
--- a/code/game/objects/structures/mirror.dm
+++ b/code/game/objects/structures/mirror.dm
@@ -114,12 +114,9 @@
if("Body")
var/list/race_list = list("Human", "Tajaran", "Skrell", "Unathi", "Diona", "Vulpkanin")
- if(config.usealienwhitelist)
- for(var/Spec in GLOB.whitelisted_species)
- if(is_alien_whitelisted(H, Spec))
- race_list += Spec
- else
- race_list += GLOB.whitelisted_species
+ for(var/species in GLOB.whitelisted_species)
+ if(is_alien_whitelisted(H, species))
+ race_list += species
var/datum/ui_module/appearance_changer/AC = ui_users[user]
if(!AC)
diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
index d12dc172b0c..9b8eb06e216 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
@@ -116,7 +116,7 @@
set category = "Object"
set src in oview(1)
- if(config.ghost_interaction)
+ if(GLOB.configuration.general.ghost_interaction)
setDir(turn(dir, 90))
handle_rotation()
return
diff --git a/code/game/sound.dm b/code/game/sound.dm
index a836aba710f..5d438268775 100644
--- a/code/game/sound.dm
+++ b/code/game/sound.dm
@@ -178,7 +178,7 @@ falloff_distance - Distance at which falloff begins. Sound is at peak volume (in
SEND_SOUND(src, S)
/client/proc/playtitlemusic()
- if(!SSticker || !SSticker.login_music || config.disable_lobby_music)
+ if(!SSticker || !SSticker.login_music || GLOB.configuration.general.disable_lobby_music)
return
if(prefs.sound & SOUND_LOBBY)
SEND_SOUND(src, sound(SSticker.login_music, repeat = 0, wait = 0, volume = 85 * prefs.get_channel_volume(CHANNEL_LOBBYMUSIC), channel = CHANNEL_LOBBYMUSIC)) // MAD JAMS
diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm
index 66ce0bedcac..a107250f18d 100644
--- a/code/game/turfs/space/space.dm
+++ b/code/game/turfs/space/space.dm
@@ -54,7 +54,7 @@
S.apply_transition(src)
/turf/space/proc/update_starlight()
- if(config.starlight)
+ if(GLOB.configuration.general.starlight)
for(var/t in RANGE_TURFS(1,src)) //RANGE_TURFS is in code\__HELPERS\game.dm
if(isspaceturf(t))
//let's NOT update this that much pls
diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm
index d6698fecc25..458f06e9c19 100644
--- a/code/game/verbs/ooc.dm
+++ b/code/game/verbs/ooc.dm
@@ -19,10 +19,10 @@ GLOBAL_VAR_INIT(admin_ooc_colour, "#b82e00")
return
if(!check_rights(R_ADMIN|R_MOD, 0))
- if(!config.ooc_allowed)
+ if(!GLOB.ooc_enabled)
to_chat(src, "
OOC is globally muted.")
return
- if(!config.dooc_allowed && (mob.stat == DEAD))
+ if(!GLOB.dooc_enabled && (mob.stat == DEAD))
to_chat(usr, "
OOC for dead mobs has been turned off.")
return
if(prefs.muted & MUTE_OOC)
@@ -41,7 +41,7 @@ GLOBAL_VAR_INIT(admin_ooc_colour, "#b82e00")
return
if(!check_rights(R_ADMIN|R_MOD,0))
- if(!config.ooc_allowed)
+ if(!GLOB.ooc_enabled)
to_chat(src, "
OOC is globally muted.")
return
if(handle_spam_prevention(msg, MUTE_OOC, OOC_COOLDOWN))
@@ -61,7 +61,7 @@ GLOBAL_VAR_INIT(admin_ooc_colour, "#b82e00")
if(check_rights(R_MOD,0) && !check_rights(R_ADMIN,0))
display_colour = GLOB.moderator_ooc_colour
else if(check_rights(R_ADMIN,0))
- if(config.allow_admin_ooccolor)
+ if(GLOB.configuration.admin.allow_admin_ooc_colour)
display_colour = src.prefs.ooccolor
else
display_colour = GLOB.admin_ooc_colour
@@ -92,20 +92,20 @@ GLOBAL_VAR_INIT(admin_ooc_colour, "#b82e00")
else
display_name = holder.fakekey
- if(!config.disable_ooc_emoji)
+ if(GLOB.configuration.general.enable_ooc_emoji)
msg = "
[msg]"
to_chat(C, "
OOC: [display_name]: [msg]")
/proc/toggle_ooc()
- config.ooc_allowed = ( !config.ooc_allowed )
- if(config.ooc_allowed)
+ GLOB.ooc_enabled = (!GLOB.ooc_enabled)
+ if(GLOB.ooc_enabled)
to_chat(world, "
The OOC channel has been globally enabled!")
else
to_chat(world, "
The OOC channel has been globally disabled!")
/proc/auto_toggle_ooc(on)
- if(config.auto_toggle_ooc_during_round && config.ooc_allowed != on)
+ if(GLOB.configuration.general.auto_disable_ooc && GLOB.ooc_enabled != on)
toggle_ooc()
/client/proc/set_ooc(newColor as color)
@@ -175,10 +175,10 @@ GLOBAL_VAR_INIT(admin_ooc_colour, "#b82e00")
return
if(!check_rights(R_ADMIN|R_MOD,0))
- if(!config.looc_allowed)
+ if(!GLOB.looc_enabled)
to_chat(src, "
LOOC is globally muted.")
return
- if(!config.dooc_allowed && (mob.stat == DEAD))
+ if(!GLOB.dooc_enabled && (mob.stat == DEAD))
to_chat(usr, "
LOOC for dead mobs has been turned off.")
return
if(prefs.muted & MUTE_OOC)
diff --git a/code/game/world.dm b/code/game/world.dm
index b87e195f28c..cc567987617 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -8,9 +8,19 @@ GLOBAL_LIST_INIT(map_transition_config, list(CC_TRANSITION_CONFIG))
// Right off the bat
enable_auxtools_debugger()
+ // Do sanity checks to ensure RUST actually exists
+ if(!fexists(RUST_G))
+ DIRECT_OUTPUT(world.log, "ERROR: RUSTG was not found and is required for the game to function. Server will now exit.")
+ del(world)
+
+ var/rustg_version = rustg_get_version()
+ if(rustg_version != RUST_G_VERSION)
+ DIRECT_OUTPUT(world.log, "ERROR: RUSTG version mismatch. Library is [rustg_version], code wants [RUST_G_VERSION]. Server will now exit.")
+ del(world)
+
//temporary file used to record errors with loading config and the database, moved to log directory once logging is set up
GLOB.config_error_log = GLOB.world_game_log = GLOB.world_runtime_log = GLOB.sql_log = "data/logs/config_error.log"
- load_configuration()
+ GLOB.configuration.load_configuration()
// Right off the bat, load up the DB
SSdbcore.CheckSchemaVersion() // This doesnt just check the schema version, it also connects to the db! This needs to happen super early! I cannot stress this enough!
@@ -18,6 +28,7 @@ GLOBAL_LIST_INIT(map_transition_config, list(CC_TRANSITION_CONFIG))
// Setup all log paths and stamp them with startups, including round IDs
SetupLogs()
+ load_files() // Loads up the MOTD (Welcome message players see when joining the server), TOS and gamemode
// This needs to happen early, otherwise people can get a null species, nuking their character
makeDatumRefLists()
@@ -32,16 +43,9 @@ GLOBAL_LIST_INIT(map_transition_config, list(CC_TRANSITION_CONFIG))
log_world("Unit Tests Are Enabled!")
#endif
- if(!fexists("config/config.txt") || !fexists("config/game_options.txt"))
- stack_trace("The game config files have not been properly set! Please copy ALL files from '/config/example' into the parent folder, '/config'.")
-
if(byond_version < MIN_COMPILER_VERSION || byond_build < MIN_COMPILER_BUILD)
log_world("Your server's byond version does not meet the recommended requirements for this code. Please update BYOND")
- if(config && config.server_name != null && config.server_suffix && world.port > 0)
- // dumb and hardcoded but I don't care~
- config.server_name += " #[(world.port % 1000) / 100]"
-
GLOB.timezoneOffset = text2num(time2text(0, "hh")) * 36000
startup_procs() // Call procs that need to occur on startup (Generate lists, load MOTD, etc)
@@ -69,8 +73,6 @@ GLOBAL_LIST_INIT(map_transition_config, list(CC_TRANSITION_CONFIG))
/world/proc/startup_procs()
LoadBans() // Load up who is banned and who isnt. DONT PUT THIS IN A SUBSYSTEM IT WILL TAKE TOO LONG TO BE CALLED
jobban_loadbanfile() // Load up jobbans. Again, DO NOT PUT THIS IN A SUBSYSTEM IT WILL TAKE TOO LONG TO BE CALLED
- load_motd() // Loads up the MOTD (Welcome message players see when joining the server)
- load_mode() // Loads up the gamemode
investigate_reset() // This is part of the admin investigate system. PLEASE DONT SS THIS EITHER
/// List of all world topic spam prevention handlers. See code/modules/world_topic/_spam_prevention_handler.dm
@@ -122,10 +124,10 @@ GLOBAL_LIST_EMPTY(world_topic_handlers)
to_chat(world, "
Rebooting world immediately due to host request")
rustg_log_close_all() // Past this point, no logging procs can be used, at risk of data loss.
// Now handle a reboot
- if(config && config.shutdown_on_reboot)
+ if(GLOB.configuration.system.shutdown_on_reboot)
sleep(0)
- if(GLOB.shutdown_shell_command)
- shell(GLOB.shutdown_shell_command)
+ if(GLOB.configuration.system.shutdown_shell_command)
+ shell(GLOB.configuration.system.shutdown_shell_command)
del(world)
TgsEndProcess() // We want to shutdown on reboot. That means kill our TGS process "gracefully", instead of the watchdog crying
return
@@ -151,15 +153,15 @@ GLOBAL_LIST_EMPTY(world_topic_handlers)
// Send the reboot banner to all players
for(var/client/C in GLOB.clients)
C << output(list2params(list(secs_before_auto_reconnect)), "browseroutput:reboot")
- if(config.server) // If you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
- C << link("byond://[config.server]")
+ if(GLOB.configuration.url.server_url) // If you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
+ C << link("byond://[GLOB.configuration.url.server_url]")
// And begin the real shutdown
rustg_log_close_all() // Past this point, no logging procs can be used, at risk of data loss.
- if(config && config.shutdown_on_reboot)
+ if(GLOB.configuration.system.shutdown_on_reboot)
sleep(0)
- if(GLOB.shutdown_shell_command)
- shell(GLOB.shutdown_shell_command)
+ if(GLOB.configuration.system.shutdown_shell_command)
+ shell(GLOB.configuration.system.shutdown_shell_command)
rustg_log_close_all() // Past this point, no logging procs can be used, at risk of data loss.
del(world)
TgsEndProcess() // We want to shutdown on reboot. That means kill our TGS process "gracefully", instead of the watchdog crying
@@ -180,39 +182,26 @@ GLOBAL_LIST_EMPTY(world_topic_handlers)
fdel(F)
F << the_mode
-/world/proc/load_motd()
+/world/proc/load_files()
GLOB.join_motd = file2text("config/motd.txt")
GLOB.join_tos = file2text("config/tos.txt")
-
-/proc/load_configuration()
- config = new /datum/configuration()
- config.load("config/config.txt")
- config.load("config/game_options.txt","game_options")
- config.loadsql("config/dbconfig.txt")
- config.loadoverflowwhitelist("config/ofwhitelist.txt")
- config.load_rank_colour_map()
- // apply some settings from config..
+ load_mode()
/world/proc/update_status()
status = get_status_text()
-/proc/get_world_status_text()
- return world.get_status_text()
-
/world/proc/get_status_text()
var/s = ""
- if(config && config.server_name)
- s += "
[config.server_name] — "
+ if(GLOB.configuration.general.server_name)
+ s += "
[GLOB.configuration.general.server_name] — "
s += "
[station_name()] "
- if(config && config.githuburl)
- s+= "([GLOB.game_version])"
- if(config && config.server_tag_line)
- s += "
[config.server_tag_line]"
+ if(GLOB.configuration.general.server_tag_line)
+ s += "
[GLOB.configuration.general.server_tag_line]"
if(SSticker && ROUND_TIME > 0)
- s += "
[round(ROUND_TIME / 36000)]:[add_zero(num2text(ROUND_TIME / 600 % 60), 2)], " + capitalize(get_security_level())
+ s += "
[round(ROUND_TIME / 36000)]:[add_zero(num2text(ROUND_TIME / 600 % 60), 2)], [capitalize(get_security_level())]"
else
s += "
STARTING"
@@ -222,16 +211,16 @@ GLOBAL_LIST_EMPTY(world_topic_handlers)
if(!GLOB.enter_allowed)
features += "closed"
- if(config && config.server_extra_features)
- features += config.server_extra_features
+ if(GLOB.configuration.general.server_features)
+ features += GLOB.configuration.general.server_features
- if(config && config.allow_vote_mode)
+ if(GLOB.configuration.vote.allow_restart_votes)
features += "vote"
- if(config && config.wikiurl)
- features += "
Wiki"
+ if(GLOB.configuration.url.wiki_url)
+ features += "
Wiki"
- if(GLOB.abandon_allowed)
+ if(GLOB.configuration.general.respawn_enabled)
features += "respawn"
if(features)
diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm
index e70fa4acac8..5e5f8c07343 100644
--- a/code/modules/admin/IsBanned.dm
+++ b/code/modules/admin/IsBanned.dm
@@ -28,24 +28,24 @@
admin = 1
//Guest Checking
- if(!GLOB.guests_allowed && IsGuestKey(key))
+ if(GLOB.configuration.general.guest_ban && IsGuestKey(key))
log_adminwarn("Failed Login: [key] [computer_id] [address] - Guests not allowed")
// message_admins("
Failed Login: [key] - Guests not allowed")
INVOKE_ASYNC(GLOBAL_PROC, .proc/log_connection, ckey(key), address, computer_id, CONNECTION_TYPE_DROPPED_BANNED)
return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a BYOND account.")
//check if the IP address is a known proxy/vpn, and the user is not whitelisted
- if(check_ipintel && config.ipintel_email && config.ipintel_whitelist && ipintel_is_banned(key, address))
+ if(check_ipintel && GLOB.configuration.ipintel.contact_email && GLOB.configuration.ipintel.whitelist_mode && ipintel_is_banned(key, address))
log_adminwarn("Failed Login: [key] [computer_id] [address] - Proxy/VPN")
var/mistakemessage = ""
- if(config.banappeals)
- mistakemessage = "\nIf you have to use one, request whitelisting at: [config.banappeals]"
+ if(GLOB.configuration.url.banappeals_url)
+ mistakemessage = "\nIf you have to use one, request whitelisting at: [GLOB.configuration.url.banappeals_url]"
INVOKE_ASYNC(GLOBAL_PROC, .proc/log_connection, ckey(key), address, computer_id, CONNECTION_TYPE_DROPPED_IPINTEL)
return list("reason"="using proxy or vpn", "desc"="\nReason: Proxies/VPNs are not allowed here. [mistakemessage]")
// If 2FA is enabled, makes sure they were authed within the last minute
- if(check_2fa && config._2fa_auth_host)
+ if(check_2fa && GLOB.configuration.system._2fa_auth_host)
// First see if they exist at all
var/datum/db_query/check_query = SSdbcore.NewQuery("SELECT 2fa_status, ip FROM [format_table_name("player")] WHERE ckey=:ckey", list("ckey" = ckey(key)))
@@ -87,7 +87,7 @@
qdel(verify_query)
- if(config.ban_legacy_system)
+ if(!GLOB.configuration.general.use_database_bans)
//Ban Checking
. = CheckBan(ckey(key), computer_id, address)
if(.)
@@ -159,8 +159,8 @@
expires = " The ban is for [duration] minutes and expires on [expiration] (server time)."
else
var/appealmessage = ""
- if(config.banappeals)
- appealmessage = " You may appeal it at
[config.banappeals]."
+ if(GLOB.configuration.url.banappeals_url)
+ appealmessage = " You may appeal it at
[GLOB.configuration.url.banappeals_url]."
expires = " This ban does not expire automatically and must be appealed.[appealmessage]"
var/desc = "\nReason: You, or another user of this computer or connection ([pckey]) is banned from playing here. The ban reason is:\n[reason]\nThis ban was applied by [ackey] on [bantime][ban_round_id ? " (Round [ban_round_id])" : ""].[expires]"
diff --git a/code/modules/admin/NewBan.dm b/code/modules/admin/NewBan.dm
index c0233a4c544..65eff893de6 100644
--- a/code/modules/admin/NewBan.dm
+++ b/code/modules/admin/NewBan.dm
@@ -10,8 +10,8 @@ GLOBAL_PROTECT(banlist_savefile) // Obvious reasons
. = list()
var/appeal
- if(config && config.banappeals)
- appeal = "\nFor more information on your ban, or to appeal, head to
[config.banappeals]"
+ if(GLOB.configuration.url.banappeals_url)
+ appeal = "\nFor more information on your ban, or to appeal, head to
[GLOB.configuration.url.banappeals_url]"
GLOB.banlist_savefile.cd = "/base"
if( "[ckey][id]" in GLOB.banlist_savefile.dir )
GLOB.banlist_savefile.cd = "[ckey][id]"
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 2f7ef2e44c8..61e5570148e 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -91,8 +91,8 @@ GLOBAL_VAR_INIT(nologevent, 0)
else
body += "\[[M.client.holder ? M.client.holder.rank : "Player"]\] "
body += "\[
" + M.client.get_exp_type(EXP_TYPE_CREW) + " as [EXP_TYPE_CREW]\]"
- body += "
BYOND account registration date: [M.client.byondacc_date || "ERROR"] [M.client.byondacc_age <= config.byond_account_age_threshold ? "
" : ""]([M.client.byondacc_age] days old)[M.client.byondacc_age <= config.byond_account_age_threshold ? "" : ""]"
- body += "
Global Ban DB Lookup: [config.centcom_ban_db_url ? "
Lookup" : "
Disabled"]"
+ body += "
BYOND account registration date: [M.client.byondacc_date || "ERROR"] [M.client.byondacc_age <= GLOB.configuration.general.byond_account_age_threshold ? "
" : ""]([M.client.byondacc_age] days old)[M.client.byondacc_age <= GLOB.configuration.general.byond_account_age_threshold ? "" : ""]"
+ body += "
Global Ban DB Lookup: [GLOB.configuration.url.centcom_ban_db_url ? "
Lookup" : "
Disabled"]"
body += "
"
@@ -127,7 +127,7 @@ GLOBAL_VAR_INIT(nologevent, 0)
body += "
Appearance Ban | "
body += "
Notes | "
body += "
View Karma | "
- if(config.forum_playerinfo_url)
+ if(GLOB.configuration.url.forum_playerinfo_url)
body += "
WebInfo | "
if(M.client)
if(check_watchlist(M.client.ckey))
@@ -462,8 +462,8 @@ GLOBAL_VAR_INIT(nologevent, 0)
if(!check_rights(R_ADMIN))
return
- config.looc_allowed = !(config.looc_allowed)
- if(config.looc_allowed)
+ GLOB.looc_enabled = !(GLOB.looc_enabled)
+ if(GLOB.looc_enabled)
to_chat(world, "
The LOOC channel has been globally enabled!")
else
to_chat(world, "
The LOOC channel has been globally disabled!")
@@ -478,8 +478,8 @@ GLOBAL_VAR_INIT(nologevent, 0)
if(!check_rights(R_ADMIN))
return
- config.dsay_allowed = !(config.dsay_allowed)
- if(config.dsay_allowed)
+ GLOB.dsay_enabled = !(GLOB.dsay_enabled)
+ if(GLOB.dsay_enabled)
to_chat(world, "
Deadchat has been globally enabled!")
else
to_chat(world, "
Deadchat has been globally disabled!")
@@ -495,7 +495,7 @@ GLOBAL_VAR_INIT(nologevent, 0)
if(!check_rights(R_ADMIN))
return
- config.dooc_allowed = !( config.dooc_allowed )
+ GLOB.dooc_enabled = !(GLOB.dooc_enabled)
log_admin("[key_name(usr)] toggled Dead OOC.")
message_admins("[key_name_admin(usr)] toggled Dead OOC.", 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Dead OOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -508,7 +508,7 @@ GLOBAL_VAR_INIT(nologevent, 0)
if(!check_rights(R_ADMIN))
return
- config.disable_ooc_emoji = !(config.disable_ooc_emoji)
+ GLOB.configuration.general.enable_ooc_emoji = !(GLOB.configuration.general.enable_ooc_emoji)
log_admin("[key_name(usr)] toggled OOC Emoji.")
message_admins("[key_name_admin(usr)] toggled OOC Emoji.", 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle OOC Emoji")
@@ -525,7 +525,7 @@ GLOBAL_VAR_INIT(nologevent, 0)
alert("Unable to start the game as it is not set up.")
return
- if(config.start_now_confirmation)
+ if(GLOB.configuration.general.start_now_confirmation)
if(alert(usr, "This is a live server. Are you sure you want to start now?", "Start game", "Yes", "No") != "Yes")
return
@@ -568,8 +568,9 @@ GLOBAL_VAR_INIT(nologevent, 0)
if(!check_rights(R_EVENT))
return
- config.allow_ai = !( config.allow_ai )
- if(!( config.allow_ai ))
+
+ GLOB.configuration.jobs.allow_ai = !(GLOB.configuration.jobs.allow_ai)
+ if(!GLOB.configuration.jobs.allow_ai)
to_chat(world, "
The AI job is no longer chooseable.")
else
to_chat(world, "
The AI job is chooseable now.")
@@ -586,13 +587,13 @@ GLOBAL_VAR_INIT(nologevent, 0)
if(!check_rights(R_SERVER))
return
- GLOB.abandon_allowed = !( GLOB.abandon_allowed )
- if(GLOB.abandon_allowed)
+ GLOB.configuration.general.respawn_enabled = !(GLOB.configuration.general.respawn_enabled)
+ if(GLOB.configuration.general.respawn_enabled)
to_chat(world, "
You may now respawn.")
else
- to_chat(world, "
You may no longer respawn :(")
- message_admins("[key_name_admin(usr)] toggled respawn to [GLOB.abandon_allowed ? "On" : "Off"].", 1)
- log_admin("[key_name(usr)] toggled respawn to [GLOB.abandon_allowed ? "On" : "Off"].")
+ to_chat(world, "
You may no longer respawn")
+ message_admins("[key_name_admin(usr)] toggled respawn to [GLOB.configuration.general.respawn_enabled ? "On" : "Off"].", 1)
+ log_admin("[key_name(usr)] toggled respawn to [GLOB.configuration.general.respawn_enabled ? "On" : "Off"].")
world.update_status()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Respawn") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -724,13 +725,13 @@ GLOBAL_VAR_INIT(nologevent, 0)
if(!check_rights(R_SERVER))
return
- GLOB.guests_allowed = !( GLOB.guests_allowed )
- if(!( GLOB.guests_allowed ))
+ GLOB.configuration.general.guest_ban = !(GLOB.configuration.general.guest_ban)
+ if(GLOB.configuration.general.guest_ban)
to_chat(world, "
Guests may no longer enter the game.")
else
to_chat(world, "
Guests may now enter the game.")
- log_admin("[key_name(usr)] toggled guests game entering [GLOB.guests_allowed ? "" : "dis"]allowed.")
- message_admins("
[key_name_admin(usr)] toggled guests game entering [GLOB.guests_allowed ? "" : "dis"]allowed.", 1)
+ log_admin("[key_name(usr)] toggled guests game entering [GLOB.configuration?.general.guest_ban ? "dis" : ""]allowed.")
+ message_admins("
[key_name_admin(usr)] toggled guests game entering [GLOB.configuration?.general.guest_ban ? "dis" : ""]allowed.", 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Guests") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/output_ai_laws()
@@ -917,4 +918,3 @@ GLOBAL_VAR_INIT(gamma_ship_location, 1) // 0 = station , 1 = space
continue
result[1]++
return result
-
diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm
index 24ea8f95886..702dcf7cd03 100644
--- a/code/modules/admin/admin_investigate.dm
+++ b/code/modules/admin/admin_investigate.dm
@@ -43,7 +43,7 @@
watchlist_show()
if("hrefs") //persistant logs and stuff
- if(config && config.log_hrefs)
+ if(GLOB.configuration.logging.href_logging)
if(GLOB.world_href_log)
src << browse(file(GLOB.world_href_log), "window=investigate[subject];size=800x300")
else
diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm
index 72376027dc5..9f0f37df719 100644
--- a/code/modules/admin/admin_ranks.dm
+++ b/code/modules/admin/admin_ranks.dm
@@ -7,25 +7,15 @@ GLOBAL_PROTECT(admin_ranks) // this shit is being protected for obvious reasons
var/previous_rights = 0
- //load text from file
- var/list/Lines = file2list("config/admin_ranks.txt")
-
- //process each line seperately
- for(var/line in Lines)
- if(!length(line)) continue
- if(copytext(line,1,2) == "#") continue
-
- var/list/List = splittext(line,"+")
- if(!List.len) continue
-
- var/rank = ckeyEx(List[1])
- switch(rank)
- if(null,"") continue
- if("Removed") continue //Reserved
+ // Process each rank set seperately
+ // key: rank name | value: list of rights
+ for(var/rankname in GLOB.configuration.admin.rank_rights_map)
+ var/list/rank_right_tokens = GLOB.configuration.admin.rank_rights_map[rankname]
var/rights = 0
- for(var/i=2, i<=List.len, i++)
- switch(ckey(List[i]))
+ for(var/right_token in rank_right_tokens)
+ var/token = lowertext(splittext(right_token, "+")[2])
+ switch(token)
if("@","prev") rights |= previous_rights
if("buildmode","build") rights |= R_BUILDMODE
if("admin") rights |= R_ADMIN
@@ -46,7 +36,7 @@ GLOBAL_PROTECT(admin_ranks) // this shit is being protected for obvious reasons
if("proccall") rights |= R_PROCCALL
if("viewruntimes") rights |= R_VIEWRUNTIMES
- GLOB.admin_ranks[rank] = rights
+ GLOB.admin_ranks[rankname] = rights
previous_rights = rights
#ifdef TESTING
@@ -73,29 +63,13 @@ GLOBAL_PROTECT(admin_ranks) // this shit is being protected for obvious reasons
for(var/A in world.GetConfig("admin"))
world.SetConfig("APP/admin", A, null)
- if(config.admin_legacy_system)
+ if(!GLOB.configuration.admin.use_database_admins)
load_admin_ranks()
- //load text from file
- var/list/Lines = file2list("config/admins.txt")
-
//process each line seperately
- for(var/line in Lines)
- if(!length(line)) continue
- if(copytext(line,1,2) == "#") continue
-
- //Split the line at every "-"
- var/list/List = splittext(line, "-")
- if(!List.len) continue
-
- //ckey is before the first "-"
- var/ckey = ckey(List[1])
- if(!ckey) continue
-
- //rank follows the first "-"
- var/rank = ""
- if(List.len >= 2)
- rank = ckeyEx(List[2])
+ for(var/iterator_key in GLOB.configuration.admin.ckey_rank_map)
+ var/ckey = ckey(iterator_key) // Snip out formatting
+ var/rank = GLOB.configuration.admin.ckey_rank_map[iterator_key]
//load permissions associated with this rank
var/rights = GLOB.admin_ranks[rank]
@@ -113,7 +87,7 @@ GLOBAL_PROTECT(admin_ranks) // this shit is being protected for obvious reasons
//The current admin system uses SQL
if(!SSdbcore.IsConnected())
log_world("Failed to connect to database in load_admins(). Reverting to legacy system.")
- config.admin_legacy_system = 1
+ GLOB.configuration.admin.use_database_admins = FALSE
load_admins()
return
@@ -141,7 +115,7 @@ GLOBAL_PROTECT(admin_ranks) // this shit is being protected for obvious reasons
if(!GLOB.admin_datums)
log_world("The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system.")
- config.admin_legacy_system = 1
+ GLOB.configuration.admin.use_database_admins = FALSE
load_admins()
return
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index d9146f385e7..62b2a01e3eb 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -137,7 +137,6 @@ GLOBAL_LIST_INIT(admin_verbs_server, list(
/client/proc/toggle_antagHUD_restrictions,
/client/proc/set_ooc,
/client/proc/reset_ooc,
- /client/proc/toggledrones,
/client/proc/set_next_map
))
GLOBAL_LIST_INIT(admin_verbs_debug, list(
@@ -403,7 +402,7 @@ GLOBAL_LIST_INIT(admin_verbs_ticket, list(
if(!check_rights(R_BAN))
return
- if(config.ban_legacy_system)
+ if(!GLOB.configuration.general.use_database_bans)
holder.unbanpanel()
else
holder.DB_ban_panel()
@@ -679,21 +678,13 @@ GLOBAL_LIST_INIT(admin_verbs_ticket, list(
var/datum/admins/D = GLOB.admin_datums[ckey]
var/rank = null
- if(config.admin_legacy_system)
- //load text from file
- var/list/Lines = file2list("config/admins.txt")
- for(var/line in Lines)
- if(findtext(line, "#")) // Skip comments
+ if(!GLOB.configuration.admin.use_database_admins)
+ for(var/iterator_key in GLOB.configuration.admin.ckey_rank_map)
+ var/_ckey = ckey(iterator_key) // Snip out formatting
+ if(ckey != _ckey)
continue
-
- var/list/splitline = splittext(line, " - ")
- if(length(splitline) != 2) // Always 'ckey - rank'
- continue
- if(lowertext(splitline[1]) == ckey)
- rank = ckeyEx(splitline[2])
- break
- continue
-
+ rank = GLOB.configuration.admin.ckey_rank_map[iterator_key]
+ break
else
if(!SSdbcore.IsConnected())
to_chat(src, "Warning, MYSQL database is not connected.")
@@ -713,7 +704,7 @@ GLOBAL_LIST_INIT(admin_verbs_ticket, list(
qdel(rank_read)
if(!D)
- if(config.admin_legacy_system)
+ if(!GLOB.configuration.admin.use_database_admins)
if(GLOB.admin_ranks[rank] == null)
error("Error while re-adminning [src], admin rank ([rank]) does not exist.")
to_chat(src, "Error while re-adminning, admin rank ([rank]) does not exist.")
@@ -773,13 +764,13 @@ GLOBAL_LIST_INIT(admin_verbs_ticket, list(
if(!check_rights(R_SERVER))
return
- if(config)
- if(config.log_hrefs)
- config.log_hrefs = 0
- to_chat(src, "
Stopped logging hrefs")
- else
- config.log_hrefs = 1
- to_chat(src, "
Started logging hrefs")
+ // Why would we ever turn this off?
+ if(GLOB.configuration.logging.href_logging)
+ GLOB.configuration.logging.href_logging = FALSE
+ to_chat(src, "
Stopped logging hrefs")
+ else
+ GLOB.configuration.logging.href_logging = TRUE
+ to_chat(src, "
Started logging hrefs")
/client/proc/check_ai_laws()
set name = "Check AI Laws"
@@ -956,17 +947,6 @@ GLOBAL_LIST_INIT(admin_verbs_ticket, list(
else
to_chat(usr, "You now will get admin ticket messages.")
-/client/proc/toggledrones()
- set name = "Toggle Maintenance Drones"
- set category = "Server"
-
- if(!check_rights(R_SERVER))
- return
-
- config.allow_drone_spawn = !(config.allow_drone_spawn)
- log_admin("[key_name(usr)] has [config.allow_drone_spawn ? "enabled" : "disabled"] maintenance drones.")
- message_admins("[key_name_admin(usr)] has [config.allow_drone_spawn ? "enabled" : "disabled"] maintenance drones.")
-
/client/proc/toggledebuglogs()
set name = "Toggle Debug Log Messages"
set category = "Preferences"
diff --git a/code/modules/admin/banappearance.dm b/code/modules/admin/banappearance.dm
index 480eb841f78..75816c22c43 100644
--- a/code/modules/admin/banappearance.dm
+++ b/code/modules/admin/banappearance.dm
@@ -40,8 +40,9 @@ DEBUG
appearance_loadbanfile()
*/
// AA 2020-11-25: This entire proc isnt even called. What the actual fuck.
+// AA 2021-05-23: This entire proc STILL isnt even called. I am going to screan.
/proc/appearance_loadbanfile()
- if(config.ban_legacy_system)
+ if(!GLOB.configuration.general.use_database_bans)
var/savefile/S=new("data/appearance_full.ban")
S["keys[0]"] >> GLOB.appearance_keylist
log_admin("Loading appearance_rank")
@@ -53,7 +54,7 @@ DEBUG
else
if(!SSdbcore.IsConnected())
log_world("Database connection failed. Reverting to the legacy ban system.")
- config.ban_legacy_system = 1
+ GLOB.configuration.general.use_database_bans = FALSE
appearance_loadbanfile()
return
diff --git a/code/modules/admin/banjob.dm b/code/modules/admin/banjob.dm
index fe7c4196488..024b264fbb1 100644
--- a/code/modules/admin/banjob.dm
+++ b/code/modules/admin/banjob.dm
@@ -17,7 +17,7 @@ GLOBAL_DATUM_INIT(jobban_regex, /regex, regex("(\[\\S]+) - (\[^#]+\[^# ])(?: ##
return
GLOB.jobban_keylist.Add(text("[M.ckey] - [rank] ## [reason]"))
jobban_assoc_insert(M.ckey, rank, reason)
- if(config.ban_legacy_system)
+ if(!GLOB.configuration.general.use_database_bans)
jobban_savebanfile()
/proc/jobban_client_fullban(ckey, rank)
@@ -25,7 +25,7 @@ GLOBAL_DATUM_INIT(jobban_regex, /regex, regex("(\[\\S]+) - (\[^#]+\[^# ])(?: ##
return
GLOB.jobban_keylist.Add(text("[ckey] - [rank]"))
jobban_assoc_insert(ckey, rank)
- if(config.ban_legacy_system)
+ if(!GLOB.configuration.general.use_database_bans)
jobban_savebanfile()
//returns a reason if M is banned from rank, returns 0 otherwise
@@ -33,7 +33,7 @@ GLOBAL_DATUM_INIT(jobban_regex, /regex, regex("(\[\\S]+) - (\[^#]+\[^# ])(?: ##
if(!M || !rank)
return 0
- if(config.guest_jobban && guest_jobbans(rank))
+ if(GLOB.configuration.jobs.guest_job_ban && guest_jobbans(rank))
if(IsGuestKey(M.key))
return "Guest Job-ban"
@@ -46,7 +46,7 @@ GLOBAL_DATUM_INIT(jobban_regex, /regex, regex("(\[\\S]+) - (\[^#]+\[^# ])(?: ##
if(!ckey || !rank)
return null
- if(config.guest_jobban && guest_jobbans(rank))
+ if(GLOB.configuration.jobs.guest_job_ban && guest_jobbans(rank))
if(IsGuestKey(ckey))
return "Guest Job-ban"
@@ -56,7 +56,7 @@ GLOBAL_DATUM_INIT(jobban_regex, /regex, regex("(\[\\S]+) - (\[^#]+\[^# ])(?: ##
return null
/proc/jobban_loadbanfile()
- if(config.ban_legacy_system)
+ if(!GLOB.configuration.general.use_database_bans)
var/savefile/S=new("data/job_full.ban")
S["keys[0]"] >> GLOB.jobban_keylist
log_admin("Loading jobban_rank")
@@ -74,7 +74,7 @@ GLOBAL_DATUM_INIT(jobban_regex, /regex, regex("(\[\\S]+) - (\[^#]+\[^# ])(?: ##
else
if(!SSdbcore.IsConnected())
log_world("Database connection failed. Reverting to the legacy ban system.")
- config.ban_legacy_system = 1
+ GLOB.configuration.general.use_database_bans = FALSE
jobban_loadbanfile()
return
@@ -132,7 +132,7 @@ GLOBAL_DATUM_INIT(jobban_regex, /regex, regex("(\[\\S]+) - (\[^#]+\[^# ])(?: ##
else
log_runtime(EXCEPTION("Failed to remove malformed job ban from associative list: [X]"))
GLOB.jobban_keylist.Remove(GLOB.jobban_keylist[i])
- if(config.ban_legacy_system)
+ if(!GLOB.configuration.general.use_database_bans)
jobban_savebanfile()
return 1
return 0
@@ -144,7 +144,7 @@ GLOBAL_DATUM_INIT(jobban_regex, /regex, regex("(\[\\S]+) - (\[^#]+\[^# ])(?: ##
if(!client || !ckey)
return
- if(config.ban_legacy_system)
+ if(!GLOB.configuration.general.use_database_bans)
//using the legacy .txt ban system
to_chat(src, "The server is using the legacy ban system. Ask an administrator for help!")
@@ -182,7 +182,7 @@ GLOBAL_DATUM_INIT(jobban_regex, /regex, regex("(\[\\S]+) - (\[^#]+\[^# ])(?: ##
qdel(select_query)
if(is_actually_banned)
- if(config.banappeals)
- to_chat(src, "
You can appeal the bans at: [config.banappeals]")
+ if(GLOB.configuration.url.banappeals_url)
+ to_chat(src, "
You can appeal the bans at: [GLOB.configuration.url.banappeals_url]")
else
to_chat(src, "
You have no active jobbans!")
diff --git a/code/modules/admin/centcom_ban_db.dm b/code/modules/admin/centcom_ban_db.dm
index 6416a1a935b..83d8c192d88 100644
--- a/code/modules/admin/centcom_ban_db.dm
+++ b/code/modules/admin/centcom_ban_db.dm
@@ -14,7 +14,7 @@
*/
/datum/admins/proc/create_ccbdb_lookup(ckey)
// Bail if disabled
- if(!config.centcom_ban_db_url)
+ if(!GLOB.configuration.url.centcom_ban_db_url)
to_chat(usr, "
The CentCom Ban DB lookup is disabled. Please inform a maintainer or server host.")
return
// Bail if no ckey is supplied
@@ -22,7 +22,7 @@
return
var/datum/callback/cb = CALLBACK(src, /datum/admins/.proc/ccbdb_lookup_callback, usr, ckey)
- SShttp.create_async_request(RUSTG_HTTP_METHOD_GET, "[config.centcom_ban_db_url][ckey]", proc_callback=cb)
+ SShttp.create_async_request(RUSTG_HTTP_METHOD_GET, "[GLOB.configuration.url.centcom_ban_db_url][ckey]", proc_callback=cb)
/**
* CCBDB Lookup Callback
diff --git a/code/modules/admin/ipintel.dm b/code/modules/admin/ipintel.dm
index b0d411a2727..e9079d1d289 100644
--- a/code/modules/admin/ipintel.dm
+++ b/code/modules/admin/ipintel.dm
@@ -1,3 +1,4 @@
+// AA TODO: Make these procs part of SSipintel
/datum/ipintel
var/ip
var/intel = 0
@@ -14,18 +15,18 @@
. = FALSE
if(intel < 0)
return
- if(intel <= config.ipintel_rating_bad)
- if(world.realtime < cacherealtime + (config.ipintel_save_good HOURS))
+ if(intel <= GLOB.configuration.ipintel.bad_rating)
+ if(world.realtime < cacherealtime + (GLOB.configuration.ipintel.hours_save_good HOURS))
return TRUE
else
- if(world.realtime < cacherealtime + (config.ipintel_save_bad HOURS))
+ if(world.realtime < cacherealtime + (GLOB.configuration.ipintel.hours_save_bad HOURS))
return TRUE
/proc/get_ip_intel(ip, bypasscache = FALSE, updatecache = TRUE)
var/datum/ipintel/res = new()
res.ip = ip
. = res
- if(!ip || !config.ipintel_email || !SSipintel.enabled)
+ if(!ip || !GLOB.configuration.ipintel.contact_email || !GLOB.configuration.ipintel.enabled || !SSipintel.enabled)
return
if(!bypasscache)
var/datum/ipintel/cachedintel = SSipintel.cache[ip]
@@ -50,9 +51,9 @@
))
"}, list(
"ip" = ip,
- "rating_bad" = config.ipintel_rating_bad,
- "save_good" = config.ipintel_save_good,
- "save_bad" = config.ipintel_save_bad,
+ "rating_bad" = GLOB.configuration.ipintel.bad_rating,
+ "save_good" = GLOB.configuration.ipintel.hours_save_good,
+ "save_bad" = GLOB.configuration.ipintel.hours_save_bad,
))
if(!query_get_ip_intel.warn_execute())
qdel(query_get_ip_intel)
@@ -93,7 +94,7 @@
return
// Do not refactor this to use SShttp, because that requires the subsystem to be firing for requests to be made, and this will be triggered before the MC has finished loading
- var/list/http[] = world.Export("http://[config.ipintel_domain]/check.php?ip=[ip]&contact=[config.ipintel_email]&format=json&flags=b")
+ var/list/http[] = world.Export("http://[GLOB.configuration.ipintel.ipintel_domain]/check.php?ip=[ip]&contact=[GLOB.configuration.ipintel.contact_email]&format=json&flags=b")
if(http)
var/status = text2num(http["STATUS"])
@@ -146,9 +147,11 @@
/proc/ipintel_is_banned(t_ckey, t_ip)
- if(!config.ipintel_email)
+ if(!GLOB.configuration.ipintel.contact_email)
return FALSE
- if(!config.ipintel_whitelist)
+ if(!GLOB.configuration.ipintel.enabled)
+ return FALSE
+ if(!GLOB.configuration.ipintel.whitelist_mode)
return FALSE
if(!SSdbcore.IsConnected())
return FALSE
@@ -159,11 +162,11 @@
return TRUE
/proc/ipintel_badip_check(target_ip)
- var/rating_bad = config.ipintel_rating_bad
+ var/rating_bad = GLOB.configuration.ipintel.bad_rating
if(!rating_bad)
log_debug("ipintel_badip_check reports misconfigured rating_bad directive")
return FALSE
- var/valid_hours = config.ipintel_save_bad
+ var/valid_hours = GLOB.configuration.ipintel.hours_save_bad
if(!valid_hours)
log_debug("ipintel_badip_check reports misconfigured ipintel_save_bad directive")
return FALSE
@@ -187,7 +190,7 @@
return TRUE
/proc/vpn_whitelist_check(target_ckey)
- if(!config.ipintel_whitelist)
+ if(!GLOB.configuration.ipintel.whitelist_mode)
return FALSE
var/datum/db_query/query_whitelist_check = SSdbcore.NewQuery("SELECT * FROM [format_table_name("vpn_whitelist")] WHERE ckey=:ckey", list(
"ckey" = target_ckey
diff --git a/code/modules/admin/permissionverbs/permissionedit.dm b/code/modules/admin/permissionverbs/permissionedit.dm
index 0abbb877350..86491bce349 100644
--- a/code/modules/admin/permissionverbs/permissionedit.dm
+++ b/code/modules/admin/permissionverbs/permissionedit.dm
@@ -52,7 +52,8 @@
usr << browse(output,"window=editrights;size=600x500")
/datum/admins/proc/log_admin_rank_modification(adm_ckey, new_rank)
- if(config.admin_legacy_system) return
+ if(!GLOB.configuration.admin.use_database_admins)
+ return
if(!usr.client)
return
@@ -140,7 +141,7 @@
message_admins("[key_name(usr)] attempted to edit admin ranks via advanced proc-call")
log_admin("[key_name(usr)] attempted to edit admin ranks via advanced proc-call")
return
- if(config.admin_legacy_system)
+ if(!GLOB.configuration.admin.use_database_admins)
return
if(!usr.client)
diff --git a/code/modules/admin/sql_notes.dm b/code/modules/admin/sql_notes.dm
index 737efd1480d..4bbef9829ec 100644
--- a/code/modules/admin/sql_notes.dm
+++ b/code/modules/admin/sql_notes.dm
@@ -54,8 +54,8 @@
adminckey = ckey(adminckey)
if(!server)
- if(config && config.server_name)
- server = config.server_name
+ if(GLOB.configuration.general.server_name)
+ server = GLOB.configuration.general.server_name
// Force cast this to 1/0 incase someone tries to feed bad data
automated = !!automated
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 492d4b7831d..f0232622f8e 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -287,19 +287,19 @@
if(null,"") return
if("*New Rank*")
new_rank = input("Please input a new rank", "New custom rank", null, null) as null|text
- if(config.admin_legacy_system)
+ if(!GLOB.configuration.admin.use_database_admins)
new_rank = ckeyEx(new_rank)
if(!new_rank)
to_chat(usr, "
Error: Topic 'editrights': Invalid rank")
return
- if(config.admin_legacy_system)
+ if(!GLOB.configuration.admin.use_database_admins)
if(GLOB.admin_ranks.len)
if(new_rank in GLOB.admin_ranks)
rights = GLOB.admin_ranks[new_rank] //we typed a rank which already exists, use its rights
else
GLOB.admin_ranks[new_rank] = 0 //add the new rank to admin_ranks
else
- if(config.admin_legacy_system)
+ if(!GLOB.configuration.admin.use_database_admins)
new_rank = ckeyEx(new_rank)
rights = GLOB.admin_ranks[new_rank] //we input an existing rank, use its rights
@@ -538,8 +538,8 @@
to_chat(M, "
You have been appearance banned by [usr.client.ckey].")
to_chat(M, "
The reason is: [reason]")
to_chat(M, "
Appearance ban can be lifted only upon request.")
- if(config.banappeals)
- to_chat(M, "
To try to resolve this matter head to [config.banappeals]")
+ if(GLOB.configuration.url.banappeals_url)
+ to_chat(M, "
To try to resolve this matter head to [GLOB.configuration.url.banappeals_url]")
else
to_chat(M, "
No ban appeals URL has been set.")
if("No")
@@ -877,7 +877,7 @@
if(notbannedlist.len) //at least 1 unbanned job exists in joblist so we have stuff to ban.
switch(alert("Temporary Ban of [M.ckey]?",,"Yes","No", "Cancel"))
if("Yes")
- if(config.ban_legacy_system)
+ if(!GLOB.configuration.general.use_database_bans)
to_chat(usr, "
Your server is using the legacy banning system, which does not support temporary job bans. Consider upgrading. Aborting ban.")
return
var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null
@@ -928,7 +928,7 @@
//Unbanning joblist
//all jobs in joblist are banned already OR we didn't give a reason (implying they shouldn't be banned)
if(joblist.len) //at least 1 banned job exists in joblist so we have stuff to unban.
- if(!config.ban_legacy_system)
+ if(GLOB.configuration.general.use_database_bans)
to_chat(usr, "
Unfortunately, database based unbanning cannot be done through this panel")
DB_ban_panel(M.ckey)
return
@@ -1002,8 +1002,8 @@
else if(href_list["webtools"])
var/target_ckey = href_list["webtools"]
- if(config.forum_playerinfo_url)
- var/url_to_open = config.forum_playerinfo_url + target_ckey
+ if(GLOB.configuration.url.forum_playerinfo_url)
+ var/url_to_open = "[GLOB.configuration.url.forum_playerinfo_url][target_ckey]"
if(alert("Open [url_to_open]",,"Yes","No")=="Yes")
usr.client << link(url_to_open)
@@ -1067,8 +1067,8 @@
DB_ban_record(BANTYPE_TEMP, M, mins, reason)
if(M.client)
M.client.link_forum_account(TRUE)
- if(config.banappeals)
- to_chat(M, "
To try to resolve this matter head to [config.banappeals]")
+ if(GLOB.configuration.url.banappeals_url)
+ to_chat(M, "
To try to resolve this matter head to [GLOB.configuration.url.banappeals_url]")
else
to_chat(M, "
No ban appeals URL has been set.")
log_admin("[key_name(usr)] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.")
@@ -1084,8 +1084,8 @@
to_chat(M, "
This ban does not expire automatically and must be appealed.")
if(M.client)
M.client.link_forum_account(TRUE)
- if(config.banappeals)
- to_chat(M, "
To try to resolve this matter head to [config.banappeals]")
+ if(GLOB.configuration.url.banappeals_url)
+ to_chat(M, "
To try to resolve this matter head to [GLOB.configuration.url.banappeals_url]")
else
to_chat(M, "
No ban appeals URL has been set.")
log_admin("[key_name(usr)] has banned [M.ckey].\nReason: [reason]\nThis ban does not expire automatically and must be appealed.")
@@ -1163,8 +1163,8 @@
if(SSticker && SSticker.mode)
return alert(usr, "The game has already started.", null, null, null, null)
var/dat = {"
What mode do you wish to play?
"}
- for(var/mode in config.modes)
- dat += {"
[config.mode_names[mode]]"}
+ for(var/mode in GLOB.configuration.gamemode.gamemodes)
+ dat += {"
[GLOB.configuration.gamemode.gamemode_names[mode]]"}
dat += {"
Secret"}
dat += {"
Random"}
dat += {"Now: [GLOB.master_mode]"}
@@ -1178,8 +1178,8 @@
if(GLOB.master_mode != "secret")
return alert(usr, "The game mode has to be secret!", null, null, null, null)
var/dat = {"
What game mode do you want to force secret to be? Use this if you want to change the game mode, but want the players to believe it's secret. This will only work if the current game mode is secret.
"}
- for(var/mode in config.modes)
- dat += {"
[config.mode_names[mode]]"}
+ for(var/mode in GLOB.configuration.gamemode.gamemodes)
+ dat += {"
[GLOB.configuration.gamemode.gamemode_names[mode]]"}
dat += {"
Random (default)"}
dat += {"Now: [GLOB.secret_force_mode]"}
usr << browse(dat, "window=f_secret")
@@ -3008,21 +3008,16 @@
if("togglebombcap")
SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Bomb Cap")
- var/newBombCap = input(usr,"What would you like the new bomb cap to be. (entered as the light damage range (the 3rd number in common (1,2,3) notation)) Must be between 4 and 128)", "New Bomb Cap", GLOB.max_ex_light_range) as num|null
+ var/newBombCap = input(usr,"What would you like the new bomb cap to be. (entered as the light damage range (the 3rd number in common (1,2,3) notation)) Must be between 4 and 128)", "New Bomb Cap", GLOB.configuration.general.bomb_cap) as num|null
if(newBombCap < 4)
return
if(newBombCap > 128)
newBombCap = 128
- GLOB.max_ex_devastation_range = round(newBombCap/4)
- GLOB.max_ex_heavy_range = round(newBombCap/2)
- GLOB.max_ex_light_range = newBombCap
- //I don't know why these are their own variables, but fuck it, they are.
- GLOB.max_ex_flash_range = newBombCap
- GLOB.max_ex_flame_range = newBombCap
+ GLOB.configuration.general.bomb_cap = newBombCap
- message_admins("
[key_name_admin(usr)] changed the bomb cap to [GLOB.max_ex_devastation_range], [GLOB.max_ex_heavy_range], [GLOB.max_ex_light_range]")
- log_admin("[key_name(usr)] changed the bomb cap to [GLOB.max_ex_devastation_range], [GLOB.max_ex_heavy_range], [GLOB.max_ex_light_range]")
+ message_admins("
[key_name_admin(usr)] changed the bomb cap to [GLOB.configuration.general.bomb_cap / 4], [GLOB.configuration.general.bomb_cap / 2], [GLOB.configuration.general.bomb_cap]")
+ log_admin("[key_name(usr)] changed the bomb cap to [GLOB.configuration.general.bomb_cap / 4], [GLOB.configuration.general.bomb_cap / 2], [GLOB.configuration.general.bomb_cap]")
if("flicklights")
SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Flicker Lights")
@@ -3299,7 +3294,7 @@
var/val = alert(usr, "What do you want to set night shift to? This will override the automatic system until set to automatic again.", "Night Shift", "On", "Off", "Automatic")
switch(val)
if("Automatic")
- if(config.enable_night_shifts)
+ if(GLOB.configuration.general.enable_night_shifts)
SSnightshift.can_fire = TRUE
SSnightshift.fire()
else
diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm
index 87009e78b52..d03344da2a1 100644
--- a/code/modules/admin/verbs/adminpm.dm
+++ b/code/modules/admin/verbs/adminpm.dm
@@ -142,7 +142,7 @@
C.adminhelped = 0
//AdminPM popup for ApocStation and anybody else who wants to use it. Set it with POPUP_ADMIN_PM in config.txt ~Carn
- if(config.popup_admin_pm)
+ if(GLOB.configuration.general.popup_admin_pm)
spawn(0) //so we don't hold the caller proc up
var/sender = src
var/sendername = key
diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm
index 06f4086fe81..d92fc9ad235 100644
--- a/code/modules/admin/verbs/one_click_antag.dm
+++ b/code/modules/admin/verbs/one_click_antag.dm
@@ -45,7 +45,7 @@
/datum/admins/proc/makeTraitors()
var/datum/game_mode/traitor/temp = new
- if(config.protect_roles_from_antagonist)
+ if(GLOB.configuration.gamemode.prevent_mindshield_antags)
temp.restricted_jobs += temp.protected_jobs
var/list/mob/living/carbon/human/candidates = list()
@@ -76,7 +76,7 @@
/datum/admins/proc/makeChangelings()
var/datum/game_mode/changeling/temp = new
- if(config.protect_roles_from_antagonist)
+ if(GLOB.configuration.gamemode.prevent_mindshield_antags)
temp.restricted_jobs += temp.protected_jobs
var/list/mob/living/carbon/human/candidates = list()
@@ -106,7 +106,7 @@
/datum/admins/proc/makeRevs()
var/datum/game_mode/revolution/temp = new
- if(config.protect_roles_from_antagonist)
+ if(GLOB.configuration.gamemode.prevent_mindshield_antags)
temp.restricted_jobs += temp.protected_jobs
var/list/mob/living/carbon/human/candidates = list()
@@ -156,7 +156,7 @@
/datum/admins/proc/makeCult()
var/datum/game_mode/cult/temp = new
- if(config.protect_roles_from_antagonist)
+ if(GLOB.configuration.gamemode.prevent_mindshield_antags)
temp.restricted_jobs += temp.protected_jobs
var/list/mob/living/carbon/human/candidates = list()
@@ -517,7 +517,7 @@
/datum/admins/proc/makeVampires()
var/datum/game_mode/vampire/temp = new
- if(config.protect_roles_from_antagonist)
+ if(GLOB.configuration.gamemode.prevent_mindshield_antags)
temp.restricted_jobs += temp.protected_jobs
var/list/mob/living/carbon/human/candidates = list()
diff --git a/code/modules/admin/verbs/possess.dm b/code/modules/admin/verbs/possess.dm
index 76287e1da17..45e93ce8c47 100644
--- a/code/modules/admin/verbs/possess.dm
+++ b/code/modules/admin/verbs/possess.dm
@@ -6,7 +6,7 @@
return
if(istype(O,/obj/singularity))
- if(config.forbid_singulo_possession)
+ if(GLOB.configuration.general.forbid_singulo_possession) // I love how this needs to exist
to_chat(usr, "It is forbidden to possess singularities.")
return
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index 85b9fa20941..53615c3d2f7 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -203,7 +203,7 @@
/proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0)
if(automute)
- if(!config.automute_on)
+ if(!GLOB.configuration.general.enable_auto_mute)
return
else
if(!usr || !usr.client)
@@ -276,21 +276,21 @@
return
var/action=""
- if(config.antag_hud_allowed)
+ if(GLOB.configuration.general.allow_antag_hud)
for(var/mob/dead/observer/g in get_ghosts())
if(g.antagHUD)
g.antagHUD = FALSE // Disable it on those that have it enabled
g.has_enabled_antagHUD = FALSE // We'll allow them to respawn
- to_chat(g, "
The Administrator has disabled AntagHUD ")
- config.antag_hud_allowed = 0
+ to_chat(g, "
The Administrators have disabled AntagHUD ")
+ GLOB.configuration.general.allow_antag_hud = FALSE
to_chat(src, "
AntagHUD usage has been disabled")
action = "disabled"
else
for(var/mob/dead/observer/g in get_ghosts())
if(!g.client.holder) // Add the verb back for all non-admin ghosts
- to_chat(g, "
The Administrator has enabled AntagHUD ")// Notify all observers they can now use AntagHUD
+ to_chat(g, "
The Administrators have enabled AntagHUD ")// Notify all observers they can now use AntagHUD
- config.antag_hud_allowed = 1
+ GLOB.configuration.general.allow_antag_hud = TRUE
action = "enabled"
to_chat(src, "
AntagHUD usage has been enabled")
@@ -307,11 +307,11 @@
return
var/action=""
- if(config.antag_hud_restricted)
+ if(GLOB.configuration.general.restrict_antag_hud_rejoin)
for(var/mob/dead/observer/g in get_ghosts())
to_chat(g, "
The administrator has lifted restrictions on joining the round if you use AntagHUD")
action = "lifted restrictions"
- config.antag_hud_restricted = 0
+ GLOB.configuration.general.restrict_antag_hud_rejoin = FALSE
to_chat(src, "
AntagHUD restrictions have been lifted")
else
for(var/mob/dead/observer/g in get_ghosts())
@@ -320,7 +320,7 @@
g.antagHUD = FALSE
g.has_enabled_antagHUD = FALSE
action = "placed restrictions"
- config.antag_hud_restricted = 1
+ GLOB.configuration.general.restrict_antag_hud_rejoin = TRUE
to_chat(src, "
AntagHUD restrictions have been enabled")
log_admin("[key_name(usr)] has [action] on joining the round if they use AntagHUD")
@@ -941,14 +941,14 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(!check_rights(R_SERVER|R_EVENT))
return
- if(!config.allow_random_events)
- config.allow_random_events = 1
+ if(!GLOB.configuration.event.enable_random_events)
+ GLOB.configuration.event.enable_random_events = TRUE
to_chat(usr, "Random events enabled")
- message_admins("Admin [key_name_admin(usr)] has enabled random events.", 1)
+ message_admins("Admin [key_name_admin(usr)] has enabled random events.")
else
- config.allow_random_events = 0
+ GLOB.configuration.event.enable_random_events = FALSE
to_chat(usr, "Random events disabled")
- message_admins("Admin [key_name_admin(usr)] has disabled random events.", 1)
+ message_admins("Admin [key_name_admin(usr)] has disabled random events.")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Random Events") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/reset_all_tcs()
@@ -1031,7 +1031,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(H.client == null || H.stat == DEAD) // No clientless or dead
continue
mins_afk = round(H.client.inactivity / 600)
- if(mins_afk < config.list_afk_minimum)
+ if(mins_afk < 5)
continue
if(H.job)
job_string = H.job
diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm
index c1905917c9d..bca5249aa6d 100644
--- a/code/modules/antagonists/traitor/datum_traitor.dm
+++ b/code/modules/antagonists/traitor/datum_traitor.dm
@@ -117,7 +117,7 @@
objective_count += 1 //Exchange counts towards number of objectives
- var/objective_amount = config.traitor_objectives_amount
+ var/objective_amount = GLOB.configuration.gamemode.traitor_objectives_amount
if(is_hijacker && objective_count <= objective_amount) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount
if (!(locate(/datum/objective/hijack) in objectives))
@@ -154,7 +154,7 @@
objective_count += forge_single_objective()
- for(var/i = objective_count, i < config.traitor_objectives_amount)
+ for(var/i = objective_count, i < GLOB.configuration.gamemode.traitor_objectives_amount)
var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = owner
kill_objective.find_target()
@@ -248,7 +248,7 @@
owner.announce_objectives()
if(should_give_codewords)
give_codewords()
- to_chat(owner.current, "
For more information, check the wiki page: ([config.wikiurl]/index.php/Traitor)")
+ to_chat(owner.current, "
For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Traitor)")
/datum/antagonist/traitor/proc/update_traitor_icons_added(datum/mind/traitor_mind)
diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm
index ba78a3f9b02..96f86679590 100644
--- a/code/modules/awaymissions/gateway.dm
+++ b/code/modules/awaymissions/gateway.dm
@@ -47,7 +47,7 @@ GLOBAL_DATUM_INIT(the_gateway, /obj/machinery/gateway/centerstation, null)
/obj/machinery/gateway/centerstation/Initialize()
..()
update_icon()
- wait = world.time + config.gateway_delay
+ wait = world.time + GLOB.configuration.gateway.away_mission_delay
return INITIALIZE_HINT_LATELOAD
/obj/machinery/gateway/centerstation/LateInitialize()
diff --git a/code/modules/awaymissions/zlevel.dm b/code/modules/awaymissions/zlevel.dm
index 641b7e0815e..0c18062d189 100644
--- a/code/modules/awaymissions/zlevel.dm
+++ b/code/modules/awaymissions/zlevel.dm
@@ -1,5 +1,3 @@
-GLOBAL_LIST_INIT(potentialRandomZlevels, generateMapList(filename = "config/away_mission_config.txt"))
-
// Call this before you remove the last dirt on a z level - that way, all objects
// will have proper atmos and other important enviro things
/proc/late_setup_level(turfs, smoothTurfs)
@@ -38,39 +36,6 @@ GLOBAL_LIST_INIT(potentialRandomZlevels, generateMapList(filename = "config/away
qdel(otherthing)
T.ChangeTurf(T.baseturf)
-/proc/generateMapList(filename)
- var/list/potentialMaps = list()
- var/list/Lines = file2list(filename)
-
- if(!Lines.len)
- return
- for(var/t in Lines)
- if(!t)
- continue
-
- t = trim(t)
- if(length(t) == 0)
- continue
- else if(copytext(t, 1, 2) == "#")
- continue
-
- var/pos = findtext(t, " ")
- var/name = null
-
- if(pos)
- name = lowertext(copytext(t, 1, pos))
-
- else
- name = lowertext(t)
-
- if(!name)
- continue
-
- potentialMaps.Add(t)
-
- return potentialMaps
-
-
/datum/map_template/ruin/proc/try_to_place(z,allowed_areas)
var/sanity = PLACEMENT_TRIES
while(sanity > 0)
diff --git a/code/modules/client/2fa.dm b/code/modules/client/2fa.dm
index 9de8ef73476..d51d41e13d6 100644
--- a/code/modules/client/2fa.dm
+++ b/code/modules/client/2fa.dm
@@ -1,12 +1,12 @@
// This is in its own file as it has so much stuff to contend with
/client/proc/edit_2fa()
- if(!config._2fa_auth_host)
+ if(!GLOB.configuration.system._2fa_auth_host)
alert(usr, "This server does not have 2FA enabled.")
return
// Client does not have 2FA enabled. Set it up.
if(prefs._2fa_status == _2FA_DISABLED)
// Get us an auth token
- var/datum/http_response/qrcr = wrap_http_get("[config._2fa_auth_host]/generateQR?ckey=[ckey]")
+ var/datum/http_response/qrcr = wrap_http_get("[GLOB.configuration.system._2fa_auth_host]/generateQR?ckey=[ckey]")
// If this fails, shits gone bad
if(qrcr.errored)
alert(usr, "Something has gone VERY wrong ingame. Please inform the server host.\nError details: [qrcr.error]")
@@ -33,7 +33,7 @@
B.close()
return
- var/datum/http_response/vr = wrap_http_get("[config._2fa_auth_host]/validateCode?ckey=[ckey]&code=[entered_code]")
+ var/datum/http_response/vr = wrap_http_get("[GLOB.configuration.system._2fa_auth_host]/validateCode?ckey=[ckey]&code=[entered_code]")
// If this fails, shits gone bad
if(vr.errored)
alert(usr, "Something has gone VERY wrong ingame. Please inform the server host.\nError details: [vr.error]")
@@ -86,7 +86,7 @@
alert(usr, "2FA deactivation aborted!")
return
- var/datum/http_response/vr = wrap_http_get("[config._2fa_auth_host]/validateCode?ckey=[ckey]&code=[entered_code]")
+ var/datum/http_response/vr = wrap_http_get("[GLOB.configuration.system._2fa_auth_host]/validateCode?ckey=[ckey]&code=[entered_code]")
// If this fails, shits gone bad
if(vr.errored)
alert(usr, "Something has gone VERY wrong ingame. Please inform the server host.\nError details: [vr.error]")
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index 801bc69f383..5622cbc5b95 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -122,11 +122,12 @@
//Logs all hrefs
- if(config && config.log_hrefs)
+ if(GLOB.configuration.logging.href_logging)
log_href("[src] (usr:[usr]\[[COORD(usr)]\]) : [hsrc ? "[hsrc] " : ""][href]")
if(href_list["karmashop"])
- if(config.disable_karma)
+ if(!GLOB.configuration.general.enable_karma)
+ to_chat(src, "Karma is disabled on this server.")
return
switch(href_list["karmashop"])
@@ -218,7 +219,7 @@
to_chat(src, "
You are sending messages to quickly. Please wait [wait_time] [wait_time == 1 ? "second" : "seconds"] before sending another message.")
return 1
last_message_time = world.time
- if(config.automute_on && !check_rights(R_ADMIN, 0) && last_message == message)
+ if(GLOB.configuration.general.enable_auto_mute && !check_rights(R_ADMIN, 0) && last_message == message)
last_message_count++
if(last_message_count >= SPAM_TRIGGER_AUTOMUTE)
to_chat(src, "
You have exceeded the spam filter limit for identical messages. An auto-mute was applied.")
@@ -259,7 +260,7 @@
return null
if(byond_version < MIN_CLIENT_VERSION) // Too out of date to play at all. Unfortunately, we can't send them a message here.
version_blocked = TRUE
- if(byond_build < config.minimum_client_build)
+ if(byond_build < GLOB.configuration.general.minimum_client_build)
version_blocked = TRUE
var/show_update_prompt = FALSE
@@ -274,7 +275,7 @@
GLOB.directory[ckey] = src
//Admin Authorisation
// Automatically makes localhost connection an admin
- if(!config.disable_localhost_admin)
+ if(GLOB.configuration.admin.enable_localhost_autoadmin)
if(is_connecting_from_localhost())
new /datum/admins("!LOCALHOST!", R_HOST, ckey) // Makes localhost rank
holder = GLOB.admin_datums[ckey]
@@ -306,10 +307,6 @@
spawn() // Goonchat does some non-instant checks in start()
chatOutput.start()
- if( (world.address == address || !address) && !GLOB.host )
- GLOB.host = key
- world.update_status()
-
if(holder)
on_holder_add()
add_admin_verbs()
@@ -383,7 +380,7 @@
playercount += 1
// Update the state of the panic bunker based on current playercount
- var/threshold = config.panic_bunker_threshold
+ var/threshold = GLOB.configuration.general.panic_bunker_threshold
if((playercount > threshold) && (GLOB.panic_bunker_enabled == FALSE))
GLOB.panic_bunker_enabled = TRUE
@@ -466,7 +463,7 @@
/client/proc/donor_loadout_points()
if(donator_level > 0 && prefs)
- prefs.max_gear_slots = config.max_loadout_points + 5
+ prefs.max_gear_slots = GLOB.configuration.general.base_loadout_points + 5
/client/proc/log_client_to_db(connectiontopic)
set waitfor = FALSE // This needs to run async because any sleep() inside /client/New() breaks stuff badly
@@ -568,8 +565,9 @@
//New player!! Need to insert all the stuff
// Check new peeps for panic bunker
+ // AA TODO: Move this to world.IsBanned()
if(GLOB.panic_bunker_enabled)
- var/threshold = config.panic_bunker_threshold
+ var/threshold = GLOB.configuration.general.panic_bunker_threshold
src << "Server is not accepting connections from never-before-seen players until player count is less than [threshold]. Please try again later."
qdel(src)
return // Dont insert or they can just go in again
@@ -593,10 +591,10 @@
/client/proc/check_ip_intel()
set waitfor = 0 //we sleep when getting the intel, no need to hold up the client connection while we sleep
- if(config.ipintel_email)
- if(config.ipintel_maxplaytime && config.use_exp_tracking)
+ if(GLOB.configuration.ipintel.enabled)
+ if(GLOB.configuration.ipintel.playtime_ignore_threshold && GLOB.configuration.jobs.enable_exp_tracking)
var/living_hours = get_exp_type_num(EXP_TYPE_LIVING) / 60
- if(living_hours >= config.ipintel_maxplaytime)
+ if(living_hours >= GLOB.configuration.ipintel.playtime_ignore_threshold)
return
if(is_connecting_from_localhost())
@@ -612,14 +610,15 @@
verify_ip_intel()
/client/proc/verify_ip_intel()
- if(ip_intel >= config.ipintel_rating_bad)
- var/detailsurl = config.ipintel_detailsurl ? "(
IP Info)" : ""
- if(config.ipintel_whitelist)
+ if(ip_intel >= GLOB.configuration.ipintel.bad_rating)
+ var/detailsurl = GLOB.configuration.ipintel.details_url ? "(
IP Info)" : ""
+ if(GLOB.configuration.ipintel.whitelist_mode)
+ // AA TODO: move this check to world.IsBanned()
spawn(40) // This is necessary because without it, they won't see the message, and addtimer cannot be used because the timer system may not have initialized yet
message_admins("
IPIntel: [key_name_admin(src)] on IP [address] was rejected. [detailsurl]")
var/blockmsg = "
Error: proxy/VPN detected. Proxy/VPN use is not allowed here. Deactivate it before you reconnect."
- if(config.banappeals)
- blockmsg += "\nIf you are not actually using a proxy/VPN, or have no choice but to use one, request whitelisting at: [config.banappeals]"
+ if(GLOB.configuration.url.banappeals_url)
+ blockmsg += "\nIf you are not actually using a proxy/VPN, or have no choice but to use one, request whitelisting at: [GLOB.configuration.url.banappeals_url]"
to_chat(src, blockmsg)
qdel(src)
else
@@ -627,9 +626,9 @@
/client/proc/check_forum_link()
- if(!config.forum_link_url || !prefs || prefs.fuid)
+ if(!GLOB.configuration.url.forum_link_url || !prefs || prefs.fuid)
return
- if(config.use_exp_tracking)
+ if(GLOB.configuration.jobs.enable_exp_tracking)
var/living_hours = get_exp_type_num(EXP_TYPE_LIVING) / 60
if(living_hours < 20)
return
@@ -663,7 +662,7 @@
return tokenstr
/client/proc/link_forum_account(fromban)
- if(!config.forum_link_url)
+ if(!GLOB.configuration.url.forum_link_url)
return
if(IsGuestKey(key))
to_chat(src, "Guest keys cannot be linked.")
@@ -689,7 +688,7 @@
if(!tokenid)
to_chat(src, "link_forum_account: unable to create token")
return
- var/url = "[config.forum_link_url][tokenid]"
+ var/url = "[GLOB.configuration.url.forum_link_url][tokenid]"
if(fromban)
url += "&fwd=appeal"
to_chat(src, {"Now opening a window to verify your information with the forums, so that you can appeal your ban. If the window does not load, please copy/paste this link:
[url]"})
@@ -709,7 +708,7 @@
if(connection != "seeker") //Invalid connection type.
return null
topic = params2list(topic)
- if(!config.check_randomizer)
+ if(!GLOB.configuration.general.enabled_cid_randomiser_buster)
return
// Stash o' ckeys
var/static/cidcheck = list()
@@ -842,8 +841,8 @@
//Send resources to the client.
/client/proc/send_resources()
// Change the way they should download resources.
- if(config.resource_urls)
- preload_rsc = pick(config.resource_urls)
+ if(length(GLOB.configuration.url.rsc_urls))
+ preload_rsc = pick(GLOB.configuration.url.rsc_urls)
else
preload_rsc = 1 // If config.resource_urls is not set, preload like normal.
// Most assets are now handled through global_cache.dm
@@ -949,7 +948,7 @@
void.UpdateGreed(actualview[1],actualview[2])
/client/proc/send_ssd_warning(mob/M)
- if(!config.ssd_warning)
+ if(!GLOB.configuration.general.ssd_warning)
return FALSE
if(ssd_warning_acknowledged)
return FALSE
@@ -1102,7 +1101,7 @@
qdel(query_age)
// Notify admins on new clients connecting, if the byond account age is less than a config value
- if(notify && (byondacc_age < config.byond_account_age_threshold))
+ if(notify && (byondacc_age < GLOB.configuration.general.byond_account_age_threshold))
message_admins("[key] has just connected for the first time. BYOND account registered on [byondacc_date] ([byondacc_age] days old)")
/client/proc/show_update_notice()
@@ -1149,7 +1148,7 @@
*/
/client/proc/cid_count_check()
// If the config is 0, disable this
- if(config.max_client_cid_history == 0)
+ if(GLOB.configuration.general.max_client_cid_history == 0)
return
// If we have no DB, dont even bother
@@ -1169,7 +1168,7 @@
cidcount = query_cidcheck.item[1]
qdel(query_cidcheck)
- if(cidcount > config.max_client_cid_history)
+ if(cidcount > GLOB.configuration.general.max_client_cid_history)
// Check their notes for CID tracking in the past
var/has_note = FALSE
var/note_text = ""
diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm
index 60e973b8770..66fff042534 100644
--- a/code/modules/client/preference/preferences.dm
+++ b/code/modules/client/preference/preferences.dm
@@ -38,7 +38,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
return 0
if(!role)
return 0
- if(!config.use_age_restriction_for_antags)
+ if(!GLOB.configuration.gamemode.antag_account_age_restriction)
return 0
if(!isnum(C.player_age))
return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced
@@ -214,7 +214,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
parent = C
b_type = pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+")
- max_gear_slots = config.max_loadout_points
+ max_gear_slots = GLOB.configuration.general.base_loadout_points
var/loaded_preferences_successfully = FALSE
if(istype(C))
if(!IsGuestKey(C.key))
@@ -473,7 +473,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
dat += "
Ghost PDA: [(toggles & PREFTOGGLE_CHAT_GHOSTPDA) ? "All PDA Messages" : "No PDA Messages"]"
if(check_rights(R_ADMIN,0))
dat += "
OOC Color: Change"
- if(config.allow_Metadata)
+ if(GLOB.configuration.general.allow_character_metadata)
dat += "
OOC Notes: Edit"
dat += "
Parallax (Fancy Space): "
switch (parallax)
@@ -1102,9 +1102,9 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
ResetJobs()
SetChoices(user)
if("learnaboutselection")
- if(config.wikiurl)
+ if(GLOB.configuration.url.wiki_url)
if(alert("Would you like to open the Job selection info in your browser?", "Open Job Selection", "Yes", "No") == "Yes")
- user << link("[config.wikiurl]/index.php/Job_Selection_and_Assignment")
+ user << link("[GLOB.configuration.url.wiki_url]/index.php/Job_Selection_and_Assignment")
else
to_chat(user, "The Wiki URL is not set in the server configuration.")
if("random")
@@ -1321,17 +1321,10 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
if("species")
var/list/new_species = list("Human", "Tajaran", "Skrell", "Unathi", "Diona", "Vulpkanin")
var/prev_species = species
-// var/whitelisted = 0
- if(config.usealienwhitelist) //If we're using the whitelist, make sure to check it!
- for(var/Spec in GLOB.whitelisted_species)
- if(is_alien_whitelisted(user,Spec))
- new_species += Spec
-// whitelisted = 1
-// if(!whitelisted)
-// alert(user, "You cannot change your species as you need to be whitelisted. If you wish to be whitelisted contact an admin in-game, on the forums, or on IRC.")
- else //Not using the whitelist? Aliens for everyone!
- new_species += GLOB.whitelisted_species
+ for(var/species in GLOB.whitelisted_species)
+ if(is_alien_whitelisted(user, species))
+ new_species += species
species = input("Please select a species", "Character Generation", null) in sortTim(new_species, /proc/cmp_text_asc)
var/datum/species/NS = GLOB.all_species[species]
@@ -1414,18 +1407,6 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
if("language")
// var/languages_available
var/list/new_languages = list("None")
-/*
- if(config.usealienwhitelist)
- for(var/L in GLOB.all_languages)
- var/datum/language/lang = GLOB.all_languages[L]
- if((!(lang.flags & RESTRICTED)) && (is_alien_whitelisted(user, L)||(!( lang.flags & WHITELISTED ))))
- new_languages += lang
- languages_available = 1
-
- if(!(languages_available))
- alert(user, "There are not currently any available secondary languages.")
- else
-*/
for(var/L in GLOB.all_languages)
var/datum/language/lang = GLOB.all_languages[L]
if(!(lang.flags & RESTRICTED))
@@ -2029,8 +2010,8 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
if("afk_watch")
if(!(toggles2 & PREFTOGGLE_2_AFKWATCH))
- to_chat(user, "You will now get put into cryo dorms after [config.auto_cryo_afk] minutes. \
- Then after [config.auto_despawn_afk] minutes you will be fully despawned. You will receive a visual and auditory warning before you will be put into cryodorms.")
+ to_chat(user, "You will now get put into cryo dorms after [GLOB.configuration.afk.auto_cryo_minutes] minutes. \
+ Then after [GLOB.configuration.afk.auto_despawn_minutes] minutes you will be fully despawned. You will receive a visual and auditory warning before you will be put into cryodorms.")
else
to_chat(user, "Automatic cryoing turned off.")
toggles2 ^= PREFTOGGLE_2_AFKWATCH
@@ -2162,14 +2143,6 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
if(be_random_name)
real_name = random_name(gender,species)
- if(config.humans_need_surnames)
- var/firstspace = findtext(real_name, " ")
- var/name_length = length(real_name)
- if(!firstspace) //we need a surname
- real_name += " [pick(GLOB.last_names)]"
- else if(firstspace == name_length)
- real_name += "[pick(GLOB.last_names)]"
-
character.add_language(language)
diff --git a/code/modules/error_handler/error_viewer.dm b/code/modules/error_handler/error_viewer.dm
index 96a228a8bff..7c28ff890d0 100644
--- a/code/modules/error_handler/error_viewer.dm
+++ b/code/modules/error_handler/error_viewer.dm
@@ -115,8 +115,7 @@ GLOBAL_DATUM(error_cache, /datum/ErrorViewer/ErrorCache)
// Show the error to admins with debug messages turned on, but only if one
// from the same source hasn't been shown too recently
- // (Also, make sure config is initialized, or log_debug will runtime)
- if(config && error_source.next_message_at <= world.time)
+ if(error_source.next_message_at <= world.time)
var/const/viewtext = "\[view]" // Nesting these in other brackets went poorly
log_debug("Runtime in [e.file],[e.line]: [html_encode(e.name)] [error_entry.makeLink(viewtext)]")
error_source.next_message_at = world.time + ERROR_MSG_DELAY
diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm
index 8282cc11317..65d820ce43f 100644
--- a/code/modules/events/blob.dm
+++ b/code/modules/events/blob.dm
@@ -30,6 +30,6 @@
SSticker.mode.update_blob_icons_added(B.mind)
to_chat(B, "You are now a mouse, infected with blob spores. Find somewhere isolated... before you burst and become the blob! Use ventcrawl (alt-click on vents) to move around.")
- to_chat(B, "For more information, check the wiki page: ([config.wikiurl]/index.php/Blob)")
+ to_chat(B, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Blob)")
notify_ghosts("Infected Mouse has appeared in [get_area(B)].", source = B)
successSpawn = TRUE
diff --git a/code/modules/events/event.dm b/code/modules/events/event.dm
index 309f85a963c..b2d744b9e34 100644
--- a/code/modules/events/event.dm
+++ b/code/modules/events/event.dm
@@ -40,11 +40,6 @@
return clamp((weight + job_weight) * weight_mod, min_weight, max_weight)
-/datum/event_meta/alien/get_weight(list/active_with_role)
- if(GLOB.aliens_allowed)
- return ..(active_with_role)
- return 0
-
/*/datum/event_meta/ninja/get_weight(var/list/active_with_role)
if(toggle_space_ninja)
return ..(active_with_role)
diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm
index 47edf168a29..987a9cf7950 100644
--- a/code/modules/events/event_container.dm
+++ b/code/modules/events/event_container.dm
@@ -29,7 +29,8 @@ GLOBAL_LIST_EMPTY(event_last_fired)
if(delayed)
next_event_time += (world.time - last_world_time)
else if(world.time > next_event_time)
- start_event()
+ if(GLOB.configuration.event.enable_random_events)
+ start_event()
last_world_time = world.time
@@ -66,7 +67,7 @@ GLOBAL_LIST_EMPTY(event_last_fired)
for(var/event_meta in last_event_time) if(possible_events[event_meta])
var/time_passed = world.time - GLOB.event_last_fired[event_meta]
- var/weight_modifier = max(0, (config.expected_round_length - time_passed) / 300)
+ var/weight_modifier = max(0, (GLOB.configuration.event.expected_round_length - time_passed) / 300)
var/new_weight = max(possible_events[event_meta] - weight_modifier, 0)
if(new_weight)
@@ -84,9 +85,9 @@ GLOBAL_LIST_EMPTY(event_last_fired)
/datum/event_container/proc/set_event_delay()
// If the next event time has not yet been set and we have a custom first time start
- if(next_event_time == 0 && config.event_first_run[severity])
- var/lower = config.event_first_run[severity]["lower"]
- var/upper = config.event_first_run[severity]["upper"]
+ if(next_event_time == 0 && GLOB.configuration.event.first_run_times[severity])
+ var/lower = GLOB.configuration.event.first_run_times[severity]["lower"]
+ var/upper = GLOB.configuration.event.first_run_times[severity]["upper"]
var/event_delay = rand(lower, upper)
next_event_time = world.time + event_delay
// Otherwise, follow the standard setup process
@@ -110,7 +111,7 @@ GLOBAL_LIST_EMPTY(event_last_fired)
playercount_modifier = playercount_modifier * delay_modifier
- var/event_delay = rand(config.event_delay_lower[severity], config.event_delay_upper[severity]) * playercount_modifier
+ var/event_delay = rand(GLOB.configuration.event.delay_lower_bound[severity], GLOB.configuration.event.delay_upper_bound[severity]) * playercount_modifier
next_event_time = world.time + event_delay
log_debug("Next event of severity [GLOB.severity_to_string[severity]] in [(next_event_time - world.time)/600] minutes.")
diff --git a/code/modules/events/spider_terror.dm b/code/modules/events/spider_terror.dm
index 019ef568908..5f9a06a501b 100644
--- a/code/modules/events/spider_terror.dm
+++ b/code/modules/events/spider_terror.dm
@@ -56,7 +56,7 @@
var/mob/living/simple_animal/hostile/poison/terror_spider/S = new spider_type(vent.loc)
var/mob/M = pick_n_take(candidates)
S.key = M.key
- to_chat(S, "For more information, check the wiki page: ([config.wikiurl]/index.php/Terror_Spider)")
+ to_chat(S, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Terror_Spider)")
spawncount--
successSpawn = TRUE
diff --git a/code/modules/food_and_drinks/food/foods/meat.dm b/code/modules/food_and_drinks/food/foods/meat.dm
index a9f0ab3d684..31cdb6fd331 100644
--- a/code/modules/food_and_drinks/food/foods/meat.dm
+++ b/code/modules/food_and_drinks/food/foods/meat.dm
@@ -293,9 +293,9 @@
return 1
/obj/item/reagent_containers/food/snacks/monkeycube/proc/Expand()
- if(LAZYLEN(SSmobs.cubemonkeys) >= config.cubemonkeycap)
+ if(LAZYLEN(SSmobs.cubemonkeys) >= GLOB.configuration.general.monkey_cube_cap)
if(fingerprintslast)
- to_chat(get_mob_by_ckey(fingerprintslast), "Bluespace harmonics prevent the spawning of more than [config.cubemonkeycap] monkeys on the station at one time!")
+ to_chat(get_mob_by_ckey(fingerprintslast), "Bluespace harmonics prevent the spawning of more than [GLOB.configuration.general.monkey_cube_cap] monkeys on the station at one time!")
else
visible_message("[src] fails to expand!")
return
diff --git a/code/modules/hydroponics/grown/replicapod.dm b/code/modules/hydroponics/grown/replicapod.dm
index 75d091a7f52..e3592346271 100644
--- a/code/modules/hydroponics/grown/replicapod.dm
+++ b/code/modules/hydroponics/grown/replicapod.dm
@@ -58,7 +58,7 @@
var/obj/machinery/hydroponics/parent = loc
var/make_podman = 0
var/ckey_holder = null
- if(config.revival_pod_plants)
+ if(GLOB.configuration.general.enable_revival_pod_plants)
if(ckey)
for(var/mob/M in GLOB.player_list)
if(isobserver(M))
diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm
index 7c80166c46f..6c011da5b2f 100644
--- a/code/modules/karma/karma.dm
+++ b/code/modules/karma/karma.dm
@@ -78,7 +78,7 @@ GLOBAL_LIST_EMPTY(karma_spenders)
if(!client)
to_chat(src, "You can't award karma without being connected.")
return FALSE
- if(config.disable_karma)
+ if(!GLOB.configuration.general.enable_karma)
to_chat(src, "Karma is disabled.")
return FALSE
if(!SSticker || !GLOB.player_list.len || (SSticker.current_state == GAME_STATE_PREGAME))
@@ -152,7 +152,7 @@ GLOBAL_LIST_EMPTY(karma_spenders)
if(!M)
to_chat(usr, "Please right click a mob to award karma directly, or use the 'Award Karma' verb to select a player from the player listing.")
return
- if(config.disable_karma) // this is here because someone thought it was a good idea to add an alert box before checking if they can even give a mob karma
+ if(!GLOB.configuration.general.enable_karma) // this is here because someone thought it was a good idea to add an alert box before checking if they can even give a mob karma
to_chat(usr, "Karma is disabled.")
return
if(alert("Give [M.name] good karma?", "Karma", "Yes", "No") != "Yes")
@@ -173,6 +173,7 @@ GLOBAL_LIST_EMPTY(karma_spenders)
special_role = M.mind.special_role
if(M.mind.assigned_role)
assigned_role = M.mind.assigned_role
+ // AA TODO: Make this use proper RUSTG logging. Why is this a normal file write these are so expensive aaaaaaaaa
karma_diary << "[M.name] ([M.key]) [assigned_role]/[special_role]: [M.client.karma] - [time2text(world.timeofday, "hh:mm:ss")] given by [key]"
sql_report_karma(src, M)
@@ -182,7 +183,7 @@ GLOBAL_LIST_EMPTY(karma_spenders)
set desc = "Reports how much karma you have accrued."
set category = "Special Verbs"
- if(config.disable_karma)
+ if(!GLOB.configuration.general.enable_karma)
to_chat(src, "Karma is disabled.")
return
@@ -218,7 +219,7 @@ GLOBAL_LIST_EMPTY(karma_spenders)
set desc = "Spend your hard-earned karma here"
set hidden = TRUE
- if(config.disable_karma)
+ if(!GLOB.configuration.general.enable_karma)
to_chat(src, "Karma is disabled.")
return
karmashopmenu()
diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm
index 05d34a4e301..beb9564ef86 100644
--- a/code/modules/mob/emote.dm
+++ b/code/modules/mob/emote.dm
@@ -116,7 +116,7 @@
return
if(!src.client.holder)
- if(!config.dsay_allowed)
+ if(!GLOB.dsay_enabled)
to_chat(src, "Deadchat is globally muted")
return
diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm
index 63d2b012c41..0d94b7cdf4c 100644
--- a/code/modules/mob/living/carbon/alien/alien.dm
+++ b/code/modules/mob/living/carbon/alien/alien.dm
@@ -126,7 +126,7 @@
/mob/living/carbon/alien/movement_delay()
. = ..()
- . += move_delay_add + config.alien_delay //move_delay_add is used to slow aliens with stuns
+ . += move_delay_add + GLOB.configuration.movement.alien_delay //move_delay_add is used to slow aliens with stuns
/mob/living/carbon/alien/getDNA()
return null
diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
index d26f87d76c3..02a305ec0ec 100644
--- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
+++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
@@ -99,7 +99,7 @@
new_xeno.mind.assigned_role = SPECIAL_ROLE_XENOMORPH
new_xeno.mind.special_role = SPECIAL_ROLE_XENOMORPH
new_xeno << sound('sound/voice/hiss5.ogg',0,0,0,100)//To get the player's attention
- to_chat(new_xeno, "For more information, check the wiki page: ([config.wikiurl]/index.php/Xenomorph)")
+ to_chat(new_xeno, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Xenomorph)")
if(gib_on_success)
owner.gib()
diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm
index b188c7bac72..271524ad61d 100644
--- a/code/modules/mob/living/carbon/brain/life.dm
+++ b/code/modules/mob/living/carbon/brain/life.dm
@@ -13,7 +13,7 @@
/mob/living/carbon/brain/Life()
. = ..()
if(.)
- if(!container && (world.time - timeofhostdeath) > config.revival_brain_life)
+ if(!container && (world.time - timeofhostdeath) > GLOB.configuration.general.revival_brain_life)
death()
/mob/living/carbon/brain/breathe()
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 22562eb6633..160a9d55288 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -1130,8 +1130,6 @@ so that different stomachs can handle things in different ways VB*/
//to recalculate and update the mob's total tint from tinted equipment it's wearing.
/mob/living/carbon/proc/update_tint()
- if(!GLOB.tinted_weldhelh)
- return
var/tinttotal = get_total_tint()
if(tinttotal >= TINT_BLIND)
overlay_fullscreen("tint", /obj/screen/fullscreen/blind)
diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm
index c6d224975e8..80cfd86079b 100644
--- a/code/modules/mob/living/carbon/human/appearance.dm
+++ b/code/modules/mob/living/carbon/human/appearance.dm
@@ -320,7 +320,7 @@
for(var/current_species_name in GLOB.all_species)
var/datum/species/current_species = GLOB.all_species[current_species_name]
- if(check_whitelist && config.usealienwhitelist && !check_rights(R_ADMIN, 0, src)) //If we're using the whitelist, make sure to check it!
+ if(check_whitelist && !check_rights(R_ADMIN, 0, src)) //If we're using the whitelist, make sure to check it!
if(whitelist.len && !(current_species_name in whitelist))
continue
if(blacklist.len && (current_species_name in blacklist))
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 839efbb02cc..9c8635afa9e 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1942,3 +1942,16 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
runechat_msg_location = loc
else
runechat_msg_location = src
+
+/mob/living/carbon/human/verb/Examine_OOC()
+ set name = "Examine Meta-Info (OOC)"
+ set category = "OOC"
+ set src in view()
+
+ if(GLOB.configuration.general.allow_character_metadata)
+ if(client)
+ to_chat(usr, "[src]'s Metainfo:
[sanitize(client.prefs.metadata)]")
+ else
+ to_chat(usr, "[src] does not have any stored infomation!")
+ else
+ to_chat(usr, "OOC Metadata is not supported by this server!")
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index cd7f743fa8f..6c05cfcd0a2 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -1,7 +1,7 @@
/mob/living/carbon/human/movement_delay()
. = 0
. += ..()
- . += config.human_delay
+ . += GLOB.configuration.movement.human_delay
. += dna.species.movement_delay(src)
/mob/living/carbon/human/Process_Spacemove(movement_dir = 0)
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 6b1659c2b6f..f11313c11ba 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -61,7 +61,7 @@
player_logged++
if(istype(loc, /obj/machinery/cryopod))
return
- if(config.auto_cryo_ssd_mins && (player_logged >= (config.auto_cryo_ssd_mins * 30)) && player_logged % 30 == 0)
+ if(GLOB.configuration.afk.ssd_auto_cryo_minutes && (player_logged >= (GLOB.configuration.afk.ssd_auto_cryo_minutes * 30)) && player_logged % 30 == 0)
var/turf/T = get_turf(src)
if(!is_station_level(T.z))
return
diff --git a/code/modules/mob/living/carbon/human/species/machine.dm b/code/modules/mob/living/carbon/human/species/machine.dm
index e0df022eb79..963b878a758 100644
--- a/code/modules/mob/living/carbon/human/species/machine.dm
+++ b/code/modules/mob/living/carbon/human/species/machine.dm
@@ -129,17 +129,11 @@
if((head_organ.dna.species.name in tmp_hair.species_allowed) && (robohead.company in tmp_hair.models_allowed)) //Populate the list of available monitor styles only with styles that the monitor-head is allowed to use.
hair += i
- var/file = file2text("config/custom_sprites.txt") //Pulls up the custom_sprites list
- var/lines = splittext(file, "\n")
- for(var/line in lines) // Looks for lines set up as screen:ckey:screen_name
- var/list/Entry = splittext(line, ":") // split lines
- for(var/i = 1 to Entry.len)
- Entry[i] = trim(Entry[i]) // Cleans up lines
- if(Entry.len != 3 || Entry[1] != "screen") // Ignore entries that aren't for screens
- continue
- if(Entry[2] == H.ckey) // They're in the list? Custom sprite time, var and icon change required
- hair += Entry[3] // Adds custom screen to list
+ if(H.ckey in GLOB.configuration.custom_sprites.ipc_screen_map)
+ // key: ckey | value: list of icon states
+ for(var/style in GLOB.configuration.custom_sprites.ipc_screen_map[H.ckey])
+ hair += style
var/new_style = input(H, "Select a monitor display", "Monitor Display", head_organ.h_style) as null|anything in hair
var/new_color = input("Please select hair color.", "Monitor Color", head_organ.hair_colour) as null|color
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 23f4d829d43..0e56570abee 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -519,22 +519,6 @@
/mob/living/proc/UpdateDamageIcon()
return
-
-/mob/living/proc/Examine_OOC()
- set name = "Examine Meta-Info (OOC)"
- set category = "OOC"
- set src in view()
-
- if(config.allow_Metadata)
- if(client)
- to_chat(usr, "[src]'s Metainfo:
[client.prefs.metadata]")
- else
- to_chat(usr, "[src] does not have any stored infomation!")
- else
- to_chat(usr, "OOC Metadata is not supported by this server!")
-
- return
-
/mob/living/Move(atom/newloc, direct, movetime)
if(buckled && buckled.loc != newloc) //not updating position
if(!buckled.anchored)
@@ -928,15 +912,15 @@
if(forced_look)
. += 3
if(ignorewalk)
- . += config.run_speed
+ . += GLOB.configuration.movement.base_run_speed
else
switch(m_intent)
if(MOVE_INTENT_RUN)
if(drowsyness > 0)
. += 6
- . += config.run_speed
+ . += GLOB.configuration.movement.base_run_speed
if(MOVE_INTENT_WALK)
- . += config.walk_speed
+ . += GLOB.configuration.movement.base_walk_speed
/mob/living/proc/can_use_guns(obj/item/gun/G)
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index d0407aa271e..86c265fec02 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -365,20 +365,8 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
if(stat || aiRestorePowerRoutine)
return
if(!custom_sprite) //Check to see if custom sprite time, checking the appopriate file to change a var
- var/file = file2text("config/custom_sprites.txt")
- var/lines = splittext(file, "\n")
-
- for(var/line in lines)
- // split & clean up
- var/list/Entry = splittext(line, ":")
- for(var/i = 1 to Entry.len)
- Entry[i] = trim(Entry[i])
-
- if(Entry.len < 2 || Entry[1] != "ai") //ignore incorrectly formatted entries or entries that aren't marked for AI
- continue
-
- if(Entry[2] == ckey) //They're in the list? Custom sprite time, var and icon change required
- custom_sprite = 1
+ if(ckey in GLOB.configuration.custom_sprites.ai_core_ckeys)
+ custom_sprite = TRUE
var/display_choices = list(
"Monochrome",
@@ -963,21 +951,9 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
if(check_unable())
return
- if(!custom_hologram) //Check to see if custom sprite time, checking the appopriate file to change a var
- var/file = file2text("config/custom_sprites.txt")
- var/lines = splittext(file, "\n")
-
- for(var/line in lines)
- // split & clean up
- var/list/Entry = splittext(line, ":")
- for(var/i = 1 to Entry.len)
- Entry[i] = trim(Entry[i])
-
- if(Entry.len < 2 || Entry[1] != "hologram")
- continue
-
- if (Entry[2] == ckey) //Custom holograms
- custom_hologram = 1 // option is given in hologram menu
+ if(!custom_hologram)
+ if(ckey in GLOB.configuration.custom_sprites.ai_hologram_ckeys)
+ custom_hologram = TRUE
var/input
switch(alert("Would you like to select a hologram based on a crew member, an animal, or switch to a unique avatar?",,"Crew Member","Unique","Animal"))
@@ -1319,7 +1295,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
/mob/living/silicon/ai/proc/open_nearest_door(mob/living/target)
if(!istype(target))
return
-
+
if(check_unable(AI_CHECK_WIRELESS))
return
diff --git a/code/modules/mob/living/silicon/laws.dm b/code/modules/mob/living/silicon/laws.dm
index 038a121a042..046c215f969 100644
--- a/code/modules/mob/living/silicon/laws.dm
+++ b/code/modules/mob/living/silicon/laws.dm
@@ -125,11 +125,10 @@
laws.sort_laws()
/mob/living/silicon/proc/make_laws()
- switch(config.default_laws)
- if(0)
- laws = new /datum/ai_laws/crewsimov()
- else
- laws = get_random_lawset()
+ if(GLOB.configuration.general.random_ai_lawset)
+ laws = get_random_lawset()
+ else
+ laws = new /datum/ai_laws/crewsimov()
/mob/living/silicon/proc/get_random_lawset()
var/list/law_options[0]
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index a70b8034238..9ddbaf61a03 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -122,7 +122,7 @@
. = ..()
. += slowdown
. += 1 //A bit slower than humans, so they're easier to smash
- . += config.robot_delay
+ . += GLOB.configuration.movement.robot_delay
/mob/living/silicon/pai/update_icons()
if(stat == DEAD)
@@ -286,21 +286,9 @@
//check for custom_sprite
if(!custom_sprite)
- var/file = file2text("config/custom_sprites.txt")
- var/lines = splittext(file, "\n")
-
- for(var/line in lines)
- // split & clean up
- var/list/Entry = splittext(line, ":")
- for(var/i = 1 to Entry.len)
- Entry[i] = trim(Entry[i])
-
- if(Entry.len < 2 || Entry[1] != "pai") //ignore incorrectly formatted entries or entries that aren't marked for pAI
- continue
-
- if(Entry[2] == ckey) //They're in the list? Custom sprite time, var and icon change required
- custom_sprite = 1
- my_choices["Custom"] = "[ckey]-pai"
+ if(ckey in GLOB.configuration.custom_sprites.pai_holoform_ckeys)
+ custom_sprite = TRUE
+ my_choices["Custom"] = "[ckey]-pai"
my_choices = possible_chassis.Copy()
if(custom_sprite)
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm
index 58605d8d89f..96bd7ee572b 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm
@@ -49,35 +49,6 @@
else
..()
-/mob/living/silicon/robot/drone/verb/customize()
- set name = "Customize Chassis"
- set desc = "Reconfigure your chassis into a customized version."
- set category = "Drone"
-
- if(!custom_sprite) //Check to see if custom sprite time, checking the appopriate file to change a var
- var/file = file2text("config/custom_sprites.txt")
- var/lines = splittext(file, "\n")
-
- for(var/line in lines)
- // split & clean up
- var/list/Entry = splittext(line, ":")
- for(var/i = 1 to Entry.len)
- Entry[i] = trim(Entry[i])
-
- if(Entry.len < 2 || Entry[1] != "drone")
- continue
-
- if (Entry[2] == ckey) //Custom holograms
- custom_sprite = 1 // option is given in hologram menu
-
- if(!custom_sprite)
- to_chat(src, "Error 404: Custom chassis not found. Revoking customization option.")
- else
- icon = 'icons/mob/custom_synthetic/custom-synthetic.dmi'
- icon_state = "[ckey]-drone"
- to_chat(src, "You reconfigure your chassis and improve the station through your new aesthetics.")
- verbs -= /mob/living/silicon/robot/drone/verb/customize
-
/mob/living/silicon/robot/drone/get_scooped(mob/living/carbon/grabber)
var/obj/item/holder/H = ..()
if(!istype(H))
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
index 6baf208a377..0f599b6479b 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm
@@ -1,3 +1,6 @@
+#define DRONE_BUILD_TIME 2 MINUTES
+#define MAX_MAINT_DRONES 5
+
/obj/machinery/drone_fabricator
name = "drone fabricator"
desc = "A large automated factory for producing maintenance drones."
@@ -37,14 +40,14 @@
icon_state = "drone_fab_active"
var/elapsed = world.time - time_last_drone
- drone_progress = clamp(round((elapsed / config.drone_build_time) * 100), 0, 100)
+ drone_progress = clamp(round((elapsed / DRONE_BUILD_TIME) * 100), 0, 100)
if(drone_progress >= 100)
visible_message("[src] voices a strident beep, indicating a drone chassis is prepared.")
/obj/machinery/drone_fabricator/examine(mob/user)
. = ..()
- if(produce_drones && drone_progress >= 100 && isobserver(user) && config.allow_drone_spawn && count_drones() < config.max_maint_drones)
+ if(produce_drones && drone_progress >= 100 && isobserver(user) && count_drones() < MAX_MAINT_DRONES)
. += "
A drone is prepared. Select 'Join As Drone' from the Ghost tab to spawn as a maintenance drone."
/obj/machinery/drone_fabricator/proc/count_drones()
@@ -58,7 +61,7 @@
if(stat & NOPOWER)
return
- if(!produce_drones || !config.allow_drone_spawn || count_drones() >= config.max_maint_drones)
+ if(!produce_drones || count_drones() >= MAX_MAINT_DRONES)
return
if(!player || !isobserver(player.mob))
@@ -80,10 +83,6 @@
set name = "Join As Drone"
set desc = "If there is a powered, enabled fabricator in the game world with a prepared chassis, join as a maintenance drone."
- if(!(config.allow_drone_spawn))
- to_chat(src, "That verb is not currently permitted.")
- return
-
if(stat != DEAD)
return
@@ -99,7 +98,7 @@
return
var/player_age_check = check_client_age(usr.client, 14) // 14 days to play as a drone
- if(player_age_check && config.use_age_restriction_for_antags)
+ if(player_age_check && GLOB.configuration.gamemode.antag_account_age_restriction)
to_chat(usr, "This role is not yet available to you. You need to wait another [player_age_check] days.")
return
@@ -141,7 +140,7 @@
if(DF.stat & NOPOWER || !DF.produce_drones)
continue
- if(DF.count_drones() >= config.max_maint_drones)
+ if(DF.count_drones() >= MAX_MAINT_DRONES)
to_chat(src, "There are too many active drones in the world for you to spawn.")
return
@@ -150,3 +149,6 @@
return
to_chat(src, "There are no available drone spawn points, sorry.")
+
+#undef DRONE_BUILD_TIME
+#undef MAX_MAINT_DRONES
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 439c29f4490..8eee7810bb2 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -215,20 +215,8 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
//Check for custom sprite
if(!custom_sprite)
- var/file = file2text("config/custom_sprites.txt")
- var/lines = splittext(file, "\n")
-
- for(var/line in lines)
- // split & clean up
- var/list/Entry = splittext(line, ":")
- for(var/i = 1 to Entry.len)
- Entry[i] = trim(Entry[i])
-
- if(Entry.len < 2 || Entry[1] != "cyborg") //ignore incorrectly formatted entries or entries that aren't marked for cyborg
- continue
-
- if(Entry[2] == ckey) //They're in the list? Custom sprite time, var and icon change required
- custom_sprite = 1
+ if(ckey in GLOB.configuration.custom_sprites.cyborg_ckeys)
+ custom_sprite = TRUE
if(mmi && mmi.brainmob)
mmi.brainmob.name = newname
diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm
index f3a946a9d50..b5fd0a1b1c8 100644
--- a/code/modules/mob/living/silicon/robot/robot_movement.dm
+++ b/code/modules/mob/living/silicon/robot/robot_movement.dm
@@ -11,7 +11,7 @@
. += speed
if(module_active && istype(module_active,/obj/item/borg/destroyer/mobility))
. -= 3
- . += config.robot_delay
+ . += GLOB.configuration.movement.robot_delay
/mob/living/silicon/robot/mob_negates_gravity()
return magpulse
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index 06c62d569c3..aeb51e55d8c 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -139,12 +139,22 @@
update_controls()
/mob/living/simple_animal/bot/New()
+ /*
+ HEY! LISTEN!
+
+ I see you're poking the the bot/New() proc
+ Assuming you are converting this to Initialize() [yay], please see my note in
+ code\game\jobs\job\job.dm | /datum/job/proc/get_access()
+
+ Theres a useless check that bugs me but needs to exist because these things New()
+ -AA07
+ */
..()
GLOB.bots_list += src
icon_living = icon_state
icon_dead = icon_state
access_card = new /obj/item/card/id(src)
-//This access is so bots can be immediately set to patrol and leave Robotics, instead of having to be let out first.
+ //This access is so bots can be immediately set to patrol and leave Robotics, instead of having to be let out first.
access_card.access += ACCESS_ROBOTICS
set_custom_texts()
Radio = new/obj/item/radio/headset/bot(src)
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/ghost.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/ghost.dm
index 74c829200f8..5757913eb9f 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/ghost.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/ghost.dm
@@ -42,6 +42,6 @@
to_chat(user, "Someone else already took this spider.")
return
key = user.key
- to_chat(src, "For more information, check the wiki page: ([config.wikiurl]/index.php/Terror_Spider)")
+ to_chat(src, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Terror_Spider)")
for(var/mob/dead/observer/G in GLOB.player_list)
G.show_message("A ghost has taken control of [src]. ([ghost_follow_link(src, ghost=G)]).")
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 7a34f746728..f5c812e7d83 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -332,7 +332,7 @@
. = speed
if(forced_look)
. += 3
- . += config.animal_delay
+ . += GLOB.configuration.movement.animal_delay
/mob/living/simple_animal/Stat()
..()
diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm
index 9941e59373b..551a588247d 100644
--- a/code/modules/mob/living/simple_animal/slime/slime.dm
+++ b/code/modules/mob/living/simple_animal/slime/slime.dm
@@ -157,7 +157,7 @@
if(health <= 0) // if damaged, the slime moves twice as slow
. *= 2
- . += config.slime_delay
+ . += GLOB.configuration.movement.slime_delay
/mob/living/simple_animal/slime/update_health_hud()
if(hud_used)
diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm
index 81150ac3be5..493fbff4615 100644
--- a/code/modules/mob/login.dm
+++ b/code/modules/mob/login.dm
@@ -6,7 +6,7 @@
log_access_in(client)
create_attack_log("Logged in at [atom_loc_line(get_turf(src))]")
create_log(MISC_LOG, "Logged in")
- if(config.log_access)
+ if(GLOB.configuration.logging.access_logging)
for(var/mob/M in GLOB.player_list)
if(M == src) continue
if( M.key && (M.key != key) )
@@ -16,7 +16,7 @@
if( (M.computer_id == client.computer_id) )
if(matches) matches += " and "
matches += "ID ([client.computer_id])"
- if(!config.disable_cid_warn_popup)
+ if(!GLOB.configuration.general.disable_cid_warning_popup)
spawn() alert("You have logged in already with another key this round, please log out of this one NOW or risk being banned!")
if(matches)
if(M.client)
@@ -68,9 +68,5 @@
for(var/datum/alternate_appearance/AA in viewing_alternate_appearances)
AA.display_to(list(src))
- if(!fexists("config/config.txt") || !fexists("config/game_options.txt"))
- to_chat(src, "The game config files have not been properly set!\n Please copy ALL files from '/config/example' into the parent folder, '/config'.")
- log_world("The game config files have not been properly set! Please copy ALL files from /config/example into the parent folder, /config.")
-
update_client_colour(0)
update_morgue()
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 9d4a22b73cc..d9df2550ae9 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -749,7 +749,7 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
set name = "Respawn"
set category = "OOC"
- if(!GLOB.abandon_allowed)
+ if(!GLOB.configuration.general.respawn_enabled)
to_chat(usr, "Respawning is disabled.")
return
@@ -1007,7 +1007,7 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
// this function displays the station time in the status panel
/mob/proc/show_stat_station_time()
- stat(null, "Round Time: [worldtime2text()]")
+ stat(null, "Round Time: [worldtime2text()]") // AA TODO: Make this do "Game Time" and "Round Time" with the ROUND_TIME macro
stat(null, "Station Time: [station_time_timestamp()]")
// this function displays the shuttles ETA in the status panel if the shuttle has been called
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 00d7336e380..7e1c22aa237 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -79,7 +79,7 @@
/proc/cannotPossess(A)
var/mob/dead/observer/G = A
- if(G.has_enabled_antagHUD && config.antag_hud_restricted)
+ if(G.has_enabled_antagHUD && GLOB.configuration.general.restrict_antag_hud_rejoin)
return 1
return 0
diff --git a/code/modules/mob/new_player/login.dm b/code/modules/mob/new_player/login.dm
index 299f208444e..3bea05a89d3 100644
--- a/code/modules/mob/new_player/login.dm
+++ b/code/modules/mob/new_player/login.dm
@@ -32,11 +32,11 @@
if(client)
client.playtitlemusic()
- if(config.player_overflow_cap && config.overflow_server_url) //Overflow rerouting, if set, forces players to be moved to a different server once a player cap is reached. Less rough than a pure kick.
- if(src.client.holder) return //admins are immune to overflow rerouting
- if(config.overflow_whitelist.Find(lowertext(src.ckey))) return //Whitelisted people are immune to overflow rerouting.
- var/tally = 0
- for(var/client/C in GLOB.clients)
- tally++
- if(tally > config.player_overflow_cap)
- src << link(config.overflow_server_url)
+ //Overflow rerouting, if set, forces players to be moved to a different server once a player cap is reached. Less rough than a pure kick.
+ if(GLOB.configuration.overflow.reroute_cap && GLOB.configuration.overflow.overflow_server_location)
+ if(client.holder)
+ return //admins are immune to overflow rerouting
+ if(ckey in GLOB.configuration.overflow.overflow_whitelist)
+ return //Whitelisted people are immune to overflow rerouting.
+ if(length(GLOB.clients) > GLOB.configuration.overflow.reroute_cap)
+ src << link(GLOB.configuration.overflow.overflow_server_location)
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 27226bff98f..5d7d5caa919 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -214,7 +214,7 @@
return
if(client.prefs.species in GLOB.whitelisted_species)
- if(!is_alien_whitelisted(src, client.prefs.species) && config.usealienwhitelist)
+ if(!is_alien_whitelisted(src, client.prefs.species))
to_chat(src, alert("You are currently not whitelisted to play [client.prefs.species]."))
return FALSE
@@ -233,7 +233,7 @@
client.prefs.load_random_character_slot(client)
if(client.prefs.species in GLOB.whitelisted_species)
- if(!is_alien_whitelisted(src, client.prefs.species) && config.usealienwhitelist)
+ if(!is_alien_whitelisted(src, client.prefs.species))
to_chat(src, alert("You are currently not whitelisted to play [client.prefs.species]."))
return FALSE
@@ -257,14 +257,14 @@
if(job.available_in_playtime(client))
return 0
- if(config.assistantlimit)
+ if(GLOB.configuration.jobs.assistant_limit)
if(job.title == "Civilian")
var/count = 0
var/datum/job/officer = SSjobs.GetJob("Security Officer")
var/datum/job/warden = SSjobs.GetJob("Warden")
var/datum/job/hos = SSjobs.GetJob("Head of Security")
count += (officer.current_positions + warden.current_positions + hos.current_positions)
- if(job.current_positions > (config.assistantratio * count))
+ if(job.current_positions > (GLOB.configuration.jobs.assistant_security_ratio * count))
if(count >= 5) // if theres more than 5 security on the station just let assistants join regardless, they should be able to handle the tide
return 1
return 0
@@ -603,7 +603,7 @@
/mob/new_player/proc/is_species_whitelisted(datum/species/S)
if(!S) return 1
- return is_alien_whitelisted(src, S.name) || !config.usealienwhitelist || !(IS_WHITELISTED in S.species_traits)
+ return is_alien_whitelisted(src, S.name) || !(IS_WHITELISTED in S.species_traits)
/mob/new_player/get_gender()
if(!client || !client.prefs) ..()
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index 2ebf4708e83..e199e81eb69 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -47,7 +47,7 @@
/mob/proc/say_dead(message)
if(client)
if(!client.holder)
- if(!config.dsay_allowed)
+ if(!GLOB.dsay_enabled)
to_chat(src, "Deadchat is globally muted.")
return
diff --git a/code/modules/newscaster/obj/newspaper.dm b/code/modules/newscaster/obj/newspaper.dm
index b9d8e1dd857..aa7eb1bf2bf 100644
--- a/code/modules/newscaster/obj/newspaper.dm
+++ b/code/modules/newscaster/obj/newspaper.dm
@@ -115,7 +115,10 @@
dat+= "
"
else
// No trailing punctuation so that it's easy to copy and paste the address
- dat += "We're sorry to break your immersion, but there has been an error with the newscaster. Please report this error, along with any more information you have, to [config.githuburl]/issues/new?template=bug_report.md"
+ if(GLOB.configuration.url.github_url)
+ dat += "We're sorry to break your immersion, but there has been an error with the newscaster. Please report this error, along with any more information you have, to [GLOB.configuration.url.github_url]/issues/new?template=bug_report.md"
+ else
+ dat += "We're sorry to break your immersion, but there has been an error with the newscaster. Unfortunately there is no GitHub URL set in the config. This is really bad."
dat += "
[curr_page+1]
"
human_user << browse(dat, "window=newspaper_main;size=300x400")
diff --git a/code/modules/power/treadmill.dm b/code/modules/power/treadmill.dm
index c9ded5798f4..2ffc4f301f4 100644
--- a/code/modules/power/treadmill.dm
+++ b/code/modules/power/treadmill.dm
@@ -72,9 +72,9 @@
if(MOVE_INTENT_RUN)
if(M.drowsyness > 0)
mob_speed += 6
- mob_speed += config.run_speed - 1
+ mob_speed += GLOB.configuration.movement.base_run_speed - 1
if(MOVE_INTENT_WALK)
- mob_speed += config.walk_speed - 1
+ mob_speed += GLOB.configuration.movement.base_run_speed - 1
mob_speed = BASE_MOVE_DELAY / max(1, BASE_MOVE_DELAY + mob_speed)
speed = min(speed + inertia * mob_speed, mob_speed)
continue
diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm
index 8ed36875c63..2b6910f5523 100644
--- a/code/modules/research/xenobiology/xenobio_camera.dm
+++ b/code/modules/research/xenobiology/xenobio_camera.dm
@@ -235,8 +235,8 @@
var/obj/machinery/computer/camera_advanced/xenobio/X = target
if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
- if(LAZYLEN(SSmobs.cubemonkeys) >= config.cubemonkeycap)
- to_chat(owner, "Bluespace harmonics prevent the spawning of more than [config.cubemonkeycap] monkeys on the station at one time!")
+ if(LAZYLEN(SSmobs.cubemonkeys) >= GLOB.configuration.general.monkey_cube_cap)
+ to_chat(owner, "Bluespace harmonics prevent the spawning of more than [GLOB.configuration.general.monkey_cube_cap] monkeys on the station at one time!")
return
else if(X.monkeys >= 1)
var/mob/living/carbon/human/monkey/food = new /mob/living/carbon/human/monkey(remote_eye.loc)
diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm
index d6d7312adc6..964ea0cb754 100644
--- a/code/modules/research/xenobiology/xenobiology.dm
+++ b/code/modules/research/xenobiology/xenobiology.dm
@@ -375,7 +375,7 @@
if(istype(O, /obj/vehicle))
var/obj/vehicle/V = O
- var/vehicle_speed_mod = config.run_speed
+ var/vehicle_speed_mod = GLOB.configuration.movement.base_run_speed
if(V.vehicle_move_delay <= vehicle_speed_mod)
to_chat(user, "[V] can't be made any faster!")
return ..()
diff --git a/code/modules/response_team/ert.dm b/code/modules/response_team/ert.dm
index f709e0455f9..4909dbe89f8 100644
--- a/code/modules/response_team/ert.dm
+++ b/code/modules/response_team/ert.dm
@@ -47,7 +47,7 @@ GLOBAL_VAR_INIT(ert_request_answered, FALSE)
return 0
var/player_age_check = check_client_age(client, GLOB.responseteam_age)
- if(player_age_check && config.use_age_restriction_for_antags)
+ if(player_age_check && GLOB.configuration.gamemode.antag_account_age_restriction)
to_chat(src, "This role is not yet available to you. You need to wait another [player_age_check] days.")
return 0
diff --git a/code/modules/ruins/lavalandruin_code/ash_walker_den.dm b/code/modules/ruins/lavalandruin_code/ash_walker_den.dm
index c37fe1921e9..35cf2ae9fbb 100644
--- a/code/modules/ruins/lavalandruin_code/ash_walker_den.dm
+++ b/code/modules/ruins/lavalandruin_code/ash_walker_den.dm
@@ -78,7 +78,7 @@
new_spawn.rename_character(new_spawn.real_name, new_spawn.dna.species.get_random_name(new_spawn.gender))
to_chat(new_spawn, "Drag the corpses of men and beasts to your nest. It will absorb them to create more of your kind. Glory to the Necropolis!")
- to_chat(new_spawn, "For more information, check the wiki page: ([config.wikiurl]/index.php/Ash_Walker)")
+ to_chat(new_spawn, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Ash_Walker)")
/obj/effect/mob_spawn/human/ash_walker/New()
. = ..()
diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm
index 3be1df48458..8a5c2118794 100644
--- a/code/modules/shuttle/emergency.dm
+++ b/code/modules/shuttle/emergency.dm
@@ -269,8 +269,6 @@
for(var/mob/M in GLOB.player_list)
if(!isnewplayer(M) && !M.client.karma_spent && !(M.client.ckey in GLOB.karma_spenders) && !M.get_preference(PREFTOGGLE_DISABLE_KARMA_REMINDER))
to_chat(M, "You have not yet spent your karma for the round; was there a player worthy of receiving your reward? Look under Special Verbs tab, Award Karma.")
- if(config.map_voting_enabled)
- SSvote.initiate_vote("map", "the server", TRUE)
if(SHUTTLE_ESCAPE)
if(time_left <= 0)
diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm
index ee2ee4a6e76..1f6dde3146a 100644
--- a/code/modules/surgery/organs/organ_external.dm
+++ b/code/modules/surgery/organs/organ_external.dm
@@ -400,7 +400,7 @@ Note that amputating the affected organ does in fact remove the infection from t
//Updates brute_damn and burn_damn from wound damages. Updates BLEEDING status.
/obj/item/organ/external/proc/check_fracture(damage_inflicted)
- if(config.bones_can_break && brute_dam > min_broken_damage && !is_robotic())
+ if(GLOB.configuration.general.breakable_bones && brute_dam > min_broken_damage && !is_robotic())
if(prob(damage_inflicted))
fracture()
diff --git a/code/modules/tgui/modules/ghost_hud_panel.dm b/code/modules/tgui/modules/ghost_hud_panel.dm
index fe35872bc04..d7376d59ff4 100644
--- a/code/modules/tgui/modules/ghost_hud_panel.dm
+++ b/code/modules/tgui/modules/ghost_hud_panel.dm
@@ -47,14 +47,14 @@ GLOBAL_DATUM_INIT(ghost_hud_panel, /datum/ui_module/ghost_hud_panel, new)
ghost.remove_the_hud(hud_type)
if("ahud_on")
- if(!config.antag_hud_allowed && !ghost.client.holder)
+ if(!GLOB.configuration.general.allow_antag_hud && !ghost.client.holder)
to_chat(ghost, "Admins have disabled this for this round.")
return FALSE
if(jobban_isbanned(ghost, "AntagHUD"))
to_chat(ghost, "You have been banned from using this feature.")
return FALSE
// Check if this is the first time they're turning on Antag HUD.
- if(!check_rights(R_ADMIN | R_MOD, FALSE) && !ghost.has_enabled_antagHUD && config.antag_hud_restricted)
+ if(!check_rights(R_ADMIN | R_MOD, FALSE) && !ghost.has_enabled_antagHUD && GLOB.configuration.general.restrict_antag_hud_rejoin)
var/response = alert(ghost, "If you turn this on, you will not be able to take any part in the round.", "Are you sure you want to enable antag HUD?", "Yes", "No")
if(response == "No")
return FALSE
diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm
index 08297e97bc0..d929acd58ca 100644
--- a/code/modules/unit_tests/_unit_tests.dm
+++ b/code/modules/unit_tests/_unit_tests.dm
@@ -3,6 +3,7 @@
#ifdef UNIT_TESTS
#include "component_tests.dm"
+#include "config_sanity.dm"
#include "crafting_lists.dm"
#include "log_format.dm"
#include "map_templates.dm"
diff --git a/code/modules/unit_tests/config_sanity.dm b/code/modules/unit_tests/config_sanity.dm
new file mode 100644
index 00000000000..55f84fa98ca
--- /dev/null
+++ b/code/modules/unit_tests/config_sanity.dm
@@ -0,0 +1,60 @@
+// This one test does multiple config things
+/datum/unit_test/config_sanity/Run()
+ // First test the ruins. Space then lava.
+ var/list/config_space_ruins = GLOB.configuration.ruins.active_space_ruins.Copy() // Copy so we dont remove
+ var/list/datum/map_template/ruin/space/game_space_ruins = list()
+
+ // Yes I know this is inefficient. Sue me.
+ for(var/path in subtypesof(/datum/map_template/ruin/space))
+ var/datum/map_template/ruin/space/S = new path()
+ // istype() doesnt work here. Dont even try it.
+ if(S.ci_exclude == S.type)
+ continue
+ game_space_ruins.Add(S)
+
+ for(var/datum/map_template/ruin/space/S in game_space_ruins)
+ if(S.mappath in config_space_ruins)
+ // Remove both
+ game_space_ruins -= S
+ config_space_ruins -= S.mappath
+
+ // Do not confuse this with the map_templates unit test. They do different things!!!!!
+ if(length(game_space_ruins))
+ Fail("Space ruins exist in the game code that do not exist in the config file")
+ for(var/datum/map_template/ruin/space/S in game_space_ruins)
+ Fail("Ruin [S.type] does not have a valid map path ([S.mappath])")
+
+ if(length(config_space_ruins))
+ Fail("Space ruins exist in the game config that do not have associated datums")
+ for(var/path in config_space_ruins)
+ Fail("- [path]")
+
+
+ // Now for lava ruins
+ var/list/config_lava_ruins = GLOB.configuration.ruins.active_lava_ruins.Copy() // Copy so we dont remove
+ var/list/datum/map_template/ruin/space/game_lava_ruins = list()
+
+ // Yes I know this is inefficient. Sue me.
+ for(var/path in subtypesof(/datum/map_template/ruin/lavaland))
+ var/datum/map_template/ruin/lavaland/L = new path()
+ // istype() doesnt work here. Dont even try it.
+ if(L.ci_exclude == L.type)
+ continue
+ game_lava_ruins.Add(L)
+
+ for(var/datum/map_template/ruin/lavaland/L in game_lava_ruins)
+ if(L.mappath in config_lava_ruins)
+ // Remove both
+ game_lava_ruins -= L
+ config_lava_ruins -= L.mappath
+
+ // Do not confuse this with the map_templates unit test. They do different things!!!!!
+ if(length(game_lava_ruins))
+ Fail("Lava ruins exist in the game code that do not exist in the config file")
+ for(var/datum/map_template/ruin/lavaland/L in game_lava_ruins)
+ Fail("Ruin [L.type] does not have a valid map path ([L.mappath])")
+
+ if(length(config_lava_ruins))
+ Fail("Lava ruins exist in the game config that do not have associated datums")
+ for(var/path in config_lava_ruins)
+ Fail("- [path]")
diff --git a/code/modules/unit_tests/map_templates.dm b/code/modules/unit_tests/map_templates.dm
index b590526a46b..55834d8d171 100644
--- a/code/modules/unit_tests/map_templates.dm
+++ b/code/modules/unit_tests/map_templates.dm
@@ -2,6 +2,10 @@
var/list/datum/map_template/templates = subtypesof(/datum/map_template)
for(var/I in templates)
var/datum/map_template/MT = new I // The new is important here to ensure stuff gets set properly
+ if(MT.ci_exclude == MT.type)
+ continue
// Check if it even has a path and if so, does it exist
if(MT.mappath && !fexists(MT.mappath))
Fail("The map file for [MT.type] does not exist!")
+ if(MT.mappath && !findtext(MT.mappath, ".dmm"))
+ Fail("The map file for [MT.type] is not a map!")
diff --git a/code/modules/unit_tests/sql.dm b/code/modules/unit_tests/sql.dm
index 06287c881c8..8d46a2e6587 100644
--- a/code/modules/unit_tests/sql.dm
+++ b/code/modules/unit_tests/sql.dm
@@ -1,43 +1,8 @@
// Unit test to check SQL version has been updated properly.,
/datum/unit_test/sql_version/Run()
// Check if the SQL version set in the code is equal to the CI DB config
- if(config.sql_enabled && sql_version != SQL_VERSION)
- Fail("SQL version error: Game is running V[SQL_VERSION] but config is V[sql_version]. You may need to update tools/ci/dbconfig.txt")
- // Check if the CI DB config is up to date with the example dbconfig
- // This proc is a little unclean but it works
- var/example_db_version
- var/list/Lines = file2list("config/example/dbconfig.txt")
- for(var/t in Lines)
- if(!t) continue
-
- t = trim(t)
- if(length(t) == 0)
- continue
- else if(copytext(t, 1, 2) == "#")
- continue
-
- var/pos = findtext(t, " ")
- var/name = null
- var/value = null
-
- if(pos)
- name = lowertext(copytext(t, 1, pos))
- value = copytext(t, pos + 1)
- else
- name = lowertext(t)
-
- if(!name)
- continue
-
- switch(name)
- if("db_version")
- example_db_version = text2num(value)
-
- if(!example_db_version)
- Fail("SQL version error: File config/example/dbconfig.txt does not have a valid SQL version set!")
-
- if(example_db_version != SQL_VERSION)
- Fail("SQL version error: Game is running V[SQL_VERSION] but config/example/dbconfig.txt is V[example_db_version].")
+ if(GLOB.configuration.database.version != SQL_VERSION)
+ Fail("SQL version error: Game is running V[SQL_VERSION] but config is V[GLOB.configuration.database.version]. You may need to update the example config.")
if(SSdbcore.total_errors > 0)
Fail("SQL errors occured on startup. Please fix them.")
diff --git a/code/modules/vehicle/ambulance.dm b/code/modules/vehicle/ambulance.dm
index 702b8e97201..87323fc2042 100644
--- a/code/modules/vehicle/ambulance.dm
+++ b/code/modules/vehicle/ambulance.dm
@@ -92,7 +92,7 @@
bed = null
. = ..()
if(bed && get_dist(oldloc, loc) <= 2)
- bed.Move(oldloc, get_dir(bed, oldloc), (last_move_diagonal? 2 : 1) * (vehicle_move_delay + config.human_delay))
+ bed.Move(oldloc, get_dir(bed, oldloc), (last_move_diagonal? 2 : 1) * (vehicle_move_delay + GLOB.configuration.movement.human_delay))
bed.dir = Dir
if(bed.has_buckled_mobs())
for(var/m in bed.buckled_mobs)
diff --git a/code/modules/vehicle/vehicle.dm b/code/modules/vehicle/vehicle.dm
index 9ed335a6bc1..0d9d002496d 100644
--- a/code/modules/vehicle/vehicle.dm
+++ b/code/modules/vehicle/vehicle.dm
@@ -160,7 +160,7 @@
unbuckle_mob(user)
return
- var/delay = (last_move_diagonal? 2 : 1) * (vehicle_move_delay + config.human_delay)
+ var/delay = (last_move_diagonal? 2 : 1) * (vehicle_move_delay + GLOB.configuration.movement.human_delay)
if(world.time < last_vehicle_move + delay)
return
last_vehicle_move = world.time
diff --git a/code/modules/world_topic/_topic_base.dm b/code/modules/world_topic/_topic_base.dm
index ad67482afe7..34cb1329842 100644
--- a/code/modules/world_topic/_topic_base.dm
+++ b/code/modules/world_topic/_topic_base.dm
@@ -15,7 +15,7 @@
*/
/datum/world_topic_handler/proc/invoke(list/input)
SHOULD_NOT_OVERRIDE(TRUE)
- var/authorised = (config.comms_password && input["key"] == config.comms_password) // No password means no comms, not any password
+ var/authorised = (GLOB.configuration.system.topic_key && input["key"] == GLOB.configuration.system.topic_key) // No password means no comms, not any password
if(requires_commskey && !authorised)
// Try keep all returns in JSON unless absolutely necessary (?ping for example)
return(json_encode(list("error" = "Invalid Key")))
diff --git a/code/modules/world_topic/status.dm b/code/modules/world_topic/status.dm
index 0bd3b8d8da4..4f964eeeb3b 100644
--- a/code/modules/world_topic/status.dm
+++ b/code/modules/world_topic/status.dm
@@ -6,10 +6,10 @@
var/list/admins = list()
status_info["version"] = GLOB.revision_info.commit_hash
status_info["mode"] = GLOB.master_mode
- status_info["respawn"] = GLOB.abandon_allowed
+ status_info["respawn"] = GLOB.configuration.general.respawn_enabled
status_info["enter"] = GLOB.enter_allowed
- status_info["vote"] = config.allow_vote_mode
- status_info["ai"] = config.allow_ai
+ status_info["vote"] = GLOB.configuration.vote.allow_mode_votes
+ status_info["ai"] = GLOB.configuration.jobs.allow_ai
status_info["host"] = world.host ? world.host : null
status_info["players"] = list()
status_info["roundtime"] = worldtime2text()
diff --git a/config/example/admin_ranks.txt b/config/example/admin_ranks.txt
deleted file mode 100644
index 84b0036e2c8..00000000000
--- a/config/example/admin_ranks.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-########################################################################################
-# ADMIN RANK DEFINES #
-# The format of this is very simple. Rank name goes first. #
-# Rank is CASE-SENSITIVE, all punctuation will be stripped so spaces don't matter. #
-# Each rank is then followed by keywords with the prefix "+". #
-# These keywords represent groups of verbs and abilities which are given to that rank. #
-# +@ (or +prev) is a special shorthand which adds all the rights of the rank above it. #
-# Ranks with no keywords will just be given the most basic verbs and abilities #
-########################################################################################
-# KEYWORDS:
-# +MENTOR = Access only to the Question's Ahelp and has little way of metagaming the game.
-# +ADMIN = general admin tools, verbs etc
-# +FUN = events, other event-orientated actions. Access to the fun secrets in the secrets panel.
-# +BAN = the ability to ban, jobban and fullban
-# +STEALTH = the ability to stealthmin (make yourself appear with a fake name to everyone but other admins
-# +POSSESS = the ability to possess objects
-# +REJUV (or +REJUVINATE) = the ability to heal, respawn, modify damage and use godmode
-# +BUILD (or +BUILDMODE) = the ability to use buildmode
-# +SERVER = higher-risk admin verbs and abilities, such as those which affect the server configuration.
-# +DEBUG = debug tools used for diagnosing and fixing problems. It's useful to give this to coders so they can investigate problems on a live server.
-# +VAREDIT = everyone may view viewvars/debugvars/whatever you call it. This keyword allows you to actually EDIT those variables.
-# +RIGHTS (or +PERMISSIONS) = allows you to promote and/or demote people.
-# +SOUND (or +SOUNDS) = allows you to upload and play sounds
-# +SPAWN (or +CREATE) = mob transformations, spawning of most atoms including mobs (high-risk atoms, e.g. blackholes, will require the +FUN flag too)
-# +EVERYTHING (or +HOST or +ALL) = Simply gives you everything without having to type every flag
-# +VIEWRUNTIMES = Allows a player to view the runtimes of the server, but not use other debug verbs
-
-# Admin Ranks
-Admin Observer
-Mentor +MENTOR
-Trial Admin +ADMIN +BAN +STEALTH +REJUVINATE
-Game Admin +ADMIN +BAN +DEBUG +REJUVINATE +BUILDMODE +EVENT +SERVER +POSSESS +PROCCALL +STEALTH +VAREDIT +SOUND +SPAWN
-Head of Staff +EVERYTHING
-
-Hosting Provider +EVERYTHING
-
-# Coder Ranks
-Maintainers +EVERYTHING
\ No newline at end of file
diff --git a/config/example/admins.txt b/config/example/admins.txt
deleted file mode 100644
index c42f756a87d..00000000000
--- a/config/example/admins.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-######################################################################
-# Basically, ckey goes first. Rank goes after the "-" #
-# Case is not important for ckey. #
-# Case IS important for the rank. However punctuation/spaces are not #
-# Ranks can be anything defined in admin_ranks.txt #
-######################################################################
-
-# example - Hosting Provider
diff --git a/config/example/alienwhitelist.txt b/config/example/alienwhitelist.txt
deleted file mode 100644
index 01acc82de92..00000000000
--- a/config/example/alienwhitelist.txt
+++ /dev/null
@@ -1 +0,0 @@
-some~user - Species
\ No newline at end of file
diff --git a/config/example/away_mission_config.txt b/config/example/away_mission_config.txt
deleted file mode 100644
index bfbc792d821..00000000000
--- a/config/example/away_mission_config.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-#List the potential random Z-levels here.
-#Maps must be the full path to them
-#Maps should be 255x255 or smaller and be bounded. Falling off the edge of the map will result in undefined behavior.
-#SPECIFYING AN INVALID MAP WILL RESULT IN RUNTIMES ON GAME START
-
-#!!IMPORTANT NOTES FOR HOSTING AWAY MISSIONS!!:
-#Do NOT tick the maps during compile -- the game uses this list to decide which map to load. Ticking the maps will result in them ALL being loaded at once.
-#DO tick the associated code file for the away mission you are enabling. Otherwise, the map will be trying to reference objects which do not exist, which will cause runtime errors!
-
-#===================================#
-# BROKEN / INCOMPLETE AWAY MISSIONS #
-#===================================#
-#_maps/map_files/RandomZLevels/example.dmm
-#_maps/map_files/RandomZLevels/spacebattle.dmm
-#_maps/map_files/RandomZLevels/stationCollision.dmm
-#_maps/map_files/RandomZLevels/spacehotel.dmm
-#_maps/map_files/RandomZLevels/wildwest.dmm
-#_maps/map_files/RandomZLevels/academy.dmm
-
-#===================================#
-# USABLE AWAY MISSIONS #
-#===================================#
-_maps/map_files/RandomZLevels/moonoutpost19.dmm
-#_maps/map_files/RandomZLevels/undergroundoutpost45.dmm
-_maps/map_files/RandomZLevels/blackmarketpackers.dmm
-_maps/map_files/RandomZLevels/terrorspiders.dmm
-_maps/map_files/RandomZLevels/centcomAway.dmm
-_maps/map_files/RandomZLevels/beach.dmm
-
-
-#===================================#
-# SPECIAL AWAY MISSIONS #
-#===================================#
-#_maps/map_files/RandomZLevels/evil_santa.dmm
diff --git a/config/example/config.toml b/config/example/config.toml
new file mode 100644
index 00000000000..80e768d1d37
--- /dev/null
+++ b/config/example/config.toml
@@ -0,0 +1,776 @@
+##########
+# README #
+##########
+#
+# Paradise SS13 Config System
+# This used to be 10+ different text files, now its all condensed into one toml file with sections and proper values
+# This is serialized to json on world load by RUSTG, and then handled inside BYOND
+# Editing this in an IDE such as VSCode is highly recommended so you can lint for errors
+# Commenting out any value will make it use the game default (likely null)
+# If you add new sections, keep them alphabetical
+# Please be careful editing this, as you can break it all if youre not careful. -aa07
+#
+#
+# SECTION LIST (Ctrl+F to jump to these)
+# - admin_configuration
+# - afk_configuration
+# - custom_sprites_configuration
+# - database_configuration
+# - debug_configuration
+# - discord_configuration
+# - event_configuration
+# - gamemode_configuration
+# - gateway_configuration
+# - general_configuration
+# - ipintel_configuration
+# - job_configuration
+# - logging_configuration
+# - movement_configuration
+# - overflow_configuration
+# - ruin_configuration
+# - system_configuration
+# - url_configuration
+# - voting_configuration
+
+
+################################################################
+
+
+[admin_configuration]
+# This section contains all information regarding admin setup. This includes ranks, rights, and if you are using the database-backed admin system
+
+# Set this to true if you are using database-based admins, or false if you want to define them in this file
+# If the database fails, this file will be used as fallback
+use_database_admins = false
+# Auto authenticate localhost users as admin? Useful for test servers, disable in producation
+enable_localhost_autoadmin = false
+# List of admin rank assignments and their permissions
+# These names ARE CASE SENSITIVE
+# +BUILD (or +BUILDMODE) = the ability to use buildmode
+# +ADMIN = general admin tools, verbs etc
+# +BAN = the ability to ban, jobban and fullban
+# +EVENT = Access to event related verbs
+# +SERVER = higher-risk admin verbs and abilities, such as those which affect the server configuration.
+# +DEBUG = debug tools used for diagnosing and fixing problems. It's useful to give this to coders so they can investigate problems on a live server.
+# +PERMISSIONS (or +RIGHTS) = allows you to promote and/or demote people.
+# +POSSESS = the ability to possess objects
+# +STEALTH = the ability to stealthmin (make yourself appear with a fake name to everyone but other admins)
+# +REJUV (or +REJUVINATE) = the ability to heal, respawn, modify damage and use godmode
+# +VAREDIT = everyone may view viewvars/debugvars/whatever you call it. This keyword allows you to actually EDIT those variables.
+# +EVERYTHING (or +HOST or +ALL) = Simply gives you everything without having to type every flag
+# +SOUND (or +SOUNDS) = allows you to upload and play sounds
+# +SPAWN (or +CREATE) = mob transformations, spawning of most atoms including mobs
+# +MOD = Access to low level moderation tools. Not used in Paradise production
+# +MENTOR = Access only to the Question's Ahelp and has little way of metagaming the game.
+# +PROCCALL = Access to call procs on anything. Be careful who you grant this too!
+# +VIEWRUNTIMES = Allows a player to view the runtimes of the server, but not use other debug verbs
+admin_ranks = [
+ # Format: {name = "My Rank", rights = ["+LIST", "+OF", "+RIGHTS"]}
+ {name = "Mentor", rights = ["+MENTOR"]},
+ {name = "Trial Admin", rights = ["+ADMIN", "+BAN", "+STEALTH", "+REJUVINATE"]},
+ {name = "Game Admin", rights = ["+ADMIN", "+BAN", "+STEALTH", "+REJUVINATE", "+DEBUG", "+BUILDMODE", "+EVENT", "+SERVER", "+POSSESS", "+PROCCALL", "+VAREDIT", "+SOUND", "+SPAWN"]},
+ {name = "Head of Staff", rights = ["+EVERYTHING"]},
+ {name = "Hosting Provider", rights = ["+EVERYTHING"]},
+ {name = "Maintainers", rights = ["+EVERYTHING"]}
+]
+# List of people and the admin rank they are assigned to
+admin_assignments = [
+ #{ckey = "Your Name Here", rank = "Hosting Provider"}
+]
+# Allow admins to set their own OOC colour
+allow_admin_ooc_colour = true
+# Map of admin rank colours to their respective rank. Note you can use hex or colour name here.
+admin_rank_colour_map = [
+ {name = "Head of Staff", colour = "#e74c3c"},
+ {name = "Maintainer", colour = "#992d22"},
+ {name = "Server Dev", colour = "#1abc9c"},
+ {name = "Community Manager", colour = "#e91e63"},
+ {name = "Game Admin", colour = "#238afa"},
+ {name = "Trial Admin", colour = "#7fb6fc"},
+ {name = "PR Reviewer", colour = "#c27c0e"},
+ {name = "Mentor", colour = "#f1c40f"},
+]
+
+
+################################################################
+
+
+[afk_configuration]
+# This section contains options for the auto AFK cryo system
+
+# Amount of minutes that a person can be AFK for before they are warned
+afk_warning_minutes = 15
+# Amount of minutes that a person can be AFK for before they are auto cryo'd
+afk_auto_cryo_minutes = 20
+# Amount of minutes that a person can be AFK for before they are despawned
+afk_auto_despawn_minutes = 21
+# Amount of time before SSD people are auto cryo'd
+ssd_auto_cryo_minutes = 15
+
+
+################################################################
+
+
+[custom_sprites_configuration]
+# This section contains a list of information for people with custom sprites for mobs, if they donated
+# It is split by mob type, and screens have their own system
+# Make sure you use CKEYS not KEYS here (EG: affectedarc07 instead of AffectedArc07)
+
+# List of ckeys who have a custom cyborg skin
+cyborgs = ["ckeyhere"]
+# List of ckeys who have a custom AI core style
+ai_core = ["ckeyhere"]
+# List of ckeys who have a custom AI holopad hologram sprite
+ai_hologram = ["ckeyhere"]
+# List of ckeys who have a custom pAI holoform sprite
+pai_holoform = ["ckeyhere"]
+# List of dictionary entries for ckeys with a custom IPC screean
+ipc_screens = [
+ {ckey = "ckeyhere", screens = ["Icon State 1", "Icon State 2"]}
+]
+
+
+################################################################
+
+
+[database_configuration]
+# This section contains all the settings for the ingame database
+# If you are running in production, you will want to be using a database
+
+# Enable/disable the database on a whole
+sql_enabled = false
+# SQL version. If this is a mismatch, round start will be delayed
+sql_version = 24
+# SQL server address. Can be an IP or DNS name
+sql_address = "127.0.0.1"
+# SQL server port
+sql_port = 3306
+# SQL server database name
+sql_database = "feedback" # TODO: Convert into `paradise_db`
+# SQL server table prefix, if applicable. SET TO EMPTY STRING IF NOT.
+sql_table_prefix = "" # TODO: Deprecate table prefixes
+# SQL server username
+sql_username = "root"
+# SQL server password
+sql_password = "please use something secure in a prod environment"
+# Time in seconds for async queries to time out
+async_query_timeout = 10
+# How many threads is the async SQL engine allowed to open. 50 is normal. Trust me.
+async_thread_limit = 50
+
+
+################################################################
+
+
+[discord_configuration]
+# This section contains all the information related to Discord webhook sending from the code
+# If you are using webhooks, please fill out this section in full
+# All role IDs must be STRINGS as BYOND doesnt like ints that big
+enable_discord_webhooks = false
+# List of all webhooks for the primary feed (public channels)
+main_webhook_urls = [
+ "https://webhook.one",
+ "https://webhook.two"
+]
+# List of all webhook URLs for the mentor feed (mentorhelps relay)
+mentor_webhook_urls = [
+ "https://mentor.webhook.one",
+ "https://mentor.webhook.two"
+]
+# List of all webhook URLs for the admin feed (round alerts, ahelps, etc)
+admin_webhook_urls = [
+ "https://admin.webhook.one",
+ "https://admin.webhook.two"
+]
+# Role ID for the admin role on the discord. Set to "" to disable.
+# THIS MUST BE A STRING. BYOND DOESNT LIKE NUMBERS THIS BIG
+admin_role_id = ""
+# Forward all ahelps to the discord? If disabled, ahelps are only forwarded if admins are AFK/Offline
+forward_all_ahelps = true
+
+
+################################################################
+
+
+[event_configuration]
+# This section contains settings for ingame random events
+
+# Disable this to disable all random events
+allow_random_events = true
+# Map of lower bounds for event delays. In minutes.
+event_delay_lower_bounds = {mundane = 10, moderate = 30, major = 50}
+# Map of upper bounds for event delays. In minutes.
+event_delay_upper_bounds = {mundane = 15, moderate = 45, major = 70}
+# Expected round length in minutes. Changes event weights
+expected_round_length = 120
+# Initial delays for the first events firing off. If any of these are commented, a random value based on above thresholds is used.
+# You must specify an upper and lower bound, or the code cries a lot. The events system is so bad good god.
+# Values are in minutes
+event_initial_delays = [
+ #{severity = "mundane", lower_bound = 10, upper_bound = 15},
+ {severity = "moderate", lower_bound = 25, upper_bound = 40},
+ {severity = "major", lower_bound = 55, upper_bound = 75},
+]
+
+
+################################################################
+
+
+[gamemode_configuration]
+# This section contains setups for the gamemodes, as well as their probabilities
+
+# Should antags use account age restrictions?
+antag_account_age_restrictions = false
+# Gamemode probabilities map for if you are using secret or random
+gamemode_probabilities = [
+ {gamemode = "abduction", probability = 0},
+ {gamemode = "blob", probability = 1},
+ {gamemode = "changeling", probability = 3},
+ {gamemode = "cult", probability = 3},
+ {gamemode = "extend-a-traitormongous", probability = 2}, # Autotraitor
+ {gamemode = "extended", probability = 3},
+ {gamemode = "heist", probability = 0},
+ {gamemode = "meteor", probability = 0},
+ {gamemode = "nuclear", probability = 2},
+ {gamemode = "raginmages", probability = 0},
+ {gamemode = "revolution", probability = 0},
+ {gamemode = "shadowling", probability = 1},
+ {gamemode = "traitor", probability = 2},
+ {gamemode = "traitorchan", probability = 3},
+ {gamemode = "traitorvamp", probability = 3},
+ {gamemode = "vampire", probability = 3},
+ {gamemode = "wizard", probability = 2},
+]
+# Maximum cycles (2s) before a shadowling starts to take damage if they dont hatch
+shadowling_max_age = 600 # 20 minutes
+# Do we want the amount of traitors to scale with population?
+traitor_scaling = true
+# Protect mindshielded roles from being antagonists
+prevent_mindshield_antag = true
+# Rounds such as rev, wizard and malf end instantly when the antag has won. Enable the setting below to not do that.
+disable_certain_round_early_end = false
+# Amount of objectives for traitors to get (Does not include escape or hijack)
+traitor_objective_amount = 2
+# Enable player limits on gamemodes. Disable if testing
+enable_gamemode_player_limit = true
+
+
+################################################################
+
+
+[gateway_configuration]
+# This section contains everything relating to the ingame gateway (away mission) system.
+
+# Do we want to enable this at all? Disable for faster load times in testing
+enable_away_mission = true
+# Delay (in deciseconds) before the gateway is usable
+away_mission_delay = 0
+# List of all enabled away missions. Comment out an entry to disable it.
+enabled_away_missions = [
+ #"_maps/map_files/RandomZLevels/academy.dmm",
+ "_maps/map_files/RandomZLevels/beach.dmm",
+ "_maps/map_files/RandomZLevels/blackmarketpackers.dmm",
+ "_maps/map_files/RandomZLevels/centcomAway.dmm",
+ #"_maps/map_files/RandomZLevels/evil_santa.dmm", # Special christmas mission. Enable for festivities
+ #"_maps/map_files/RandomZLevels/example.dmm", # Example file. Do not enable.
+ "_maps/map_files/RandomZLevels/moonoutpost19.dmm",
+ #"_maps/map_files/RandomZLevels/spacebattle.dmm", # Broken/incomplete. Do not enable
+ #"_maps/map_files/RandomZLevels/stationCollision.dmm", # Broken/incomplete. Do not enable
+ "_maps/map_files/RandomZLevels/terrorspiders.dmm",
+ #"_maps/map_files/RandomZLevels/undergroundoutpost45.dmm",
+ #"_maps/map_files/RandomZLevels/wildwest.dmm",
+]
+
+
+################################################################
+
+
+[general_configuration]
+# General setup for the server (branding, options, etc)
+
+# Name for the server in the list
+server_name = "ParaCode Test"
+# Tag line for the server. This appears as supplementary text
+# EG: The perfect mix of RP & action
+server_tag_line = "ParaCode Testing Server"
+# Server features. Shows in a newline
+server_features = "Medium RP, varied species/jobs."
+# Store bans in the database? If you are in production, you want this on
+use_database_bans = false
+# Allow OOC character metadata notes
+allow_character_metadata = true
+# Lobby time before roundstart (Seconds)
+lobby_time = 240
+# Forbid people without a BYOND account joining the server
+guest_ban = true
+# Player threshold before the automatic panic bunker engages
+panic_bunker_threshold = 150
+# Allow players to use antagHUD?
+allow_antag_hud = true
+# Forbid players from rejoining if they use antag hud
+restrict_antag_hud_rejoin = true
+# Do we want to allow player respawns?
+respawn_enabled = false
+# Enable karma awarding and karma lockouts for jobs and species?
+enable_karma = true
+# Enable/disable the buster for the CID randomiser DLL
+enable_cid_randomiser_buster = false
+# Prevent admins from possessing the singularity
+prevent_admin_singlo_possession = false
+# Force open a reply window whenever someone is admin PM'd. Quite annoying.
+popup_admin_pm = false
+# Announce holidays ingame (such as halloween, christmas, happy [whatever] day)
+allow_holidays = true
+# Enable auto muting in all chat channels
+enable_auto_mute = false
+# Show a warning to players to make them accept a popup if they try to interact with SSD players
+ssd_warning = true
+# Allow ghosts to spin chairs
+ghost_interaction = false
+# Enable/disable starlight to make space without areas be lit up
+starlight = true
+# Disable lobby music on the server
+disable_lobby_music = false
+# Enable this if you want to disable the popup alert for people on the same CID
+disable_cid_warning_popup = false
+# Amount of loadout points people should get
+base_loadout_points = 5
+# Respawnability loss penalty if you cryo below this threshold (Minutes)
+cryo_penalty_period = 30
+# Enable twitter emojis in OOC?
+enable_ooc_emoji = true
+# Auto start the game if running a local test server
+developer_express_start = false
+# Minimum client build for playing the server. Keep above 1421 due to exploits
+minimum_client_build = 1421
+# Give a confirmation when pressing "Start Now". Useful for avoiding starting the live server early
+start_now_confirmation = false
+# BYOND accounts younger than this threshold (days) will cause alerts on first login
+byond_account_age_threshold = 3
+# Maximum CIDs a client can have attached to them before they trip a warning
+max_client_cid_history = 20
+# Enable automatic profiling of rounds to profile.json
+enable_auto_profiler = true
+# Auto disable OOC when round starts?
+auto_disable_ooc = true
+# Enable/disable the breaking of bones
+breakable_bones = true
+# Enable/disable revival pod plants
+enable_revival_pod_plants = true
+# Enable/disable cloning
+enable_cloning = true
+# Randomise shift time instead of it always being 12:00
+randomise_shift_time = true
+# Enable night shift for night lighting
+enable_night_shifts = true
+# Cap for monkeys spawned from monkey cubes
+monkey_cube_cap = 32
+# Make explosions react to obstacles (walls+doors) instead of ignoring them
+reactionary_explosions = true
+# Bomb cap for explosions (Outer devastation. Other values calculate from this)
+bomb_cap = 20
+# Amount of time (deciseconds) for a brain to keep its "spark of life". Set to -1 to disable.
+revival_brain_life = 6000 # 10 minutes
+# Enable random silicon lawset (If said lawset has default = TRUE in the code). Disable for always crewsimov
+random_ai_lawset = true
+
+
+################################################################
+
+
+[ipintel_configuration]
+# This section contains all the information for IPIntel (The Anti VPN system)
+
+# Enable or disable IPIntel entirely
+ipintel_enabled = false
+# Whitelist mode. If true, people on proxies/VPNs will need whitelisting if they arent past the threshold below. If false, admins are merely warned with no automatic action
+whitelist_mode = true
+# Threshold to kick people out (0-1 percentage float)
+bad_rating = 0.98
+# Contact email (required, leaving blank disables this)
+contact_email = "ch@nge.me"
+# How many hours to save good matches for (IPIntel has rate limits)
+hours_save_good = 72
+# How many hours to save bad matches for (IPIntel has rate limits)
+hours_save_bad = 24
+# IPIntel Domain. Do not put http:// in front of it
+ipintel_domain = "check.getipintel.net"
+# Ignore checking IPs with more hours than the threshold below. Requires EXP tracking to be enabled
+playtime_ignore_threshold = 10
+# Details URL for more info on an IP (such as ASN). IP is tacked on the end.
+details_url = "https://iphub.info/?ip="
+
+
+################################################################
+
+
+[job_configuration]
+# This section contains information on job configuartion, as well as the jon amounts
+
+# Disable this if you are in a lowpop environment
+jobs_have_minimal_access = true
+# Require account agre restrictions for job? Requires the database
+restrict_jobs_on_account_age = false
+# Allow admins to bypass all job age restrictions
+restrict_jobs_on_account_age_admin_bypass = true
+# Enable job EXP tracking (playtime)? Requires the database
+enable_exp_tracking = false
+# Enable job EXP-based restrictions (EG: require X hours as officer before warden)? Requires the database
+enable_exp_restrictions = false
+# Allow admins to bypass all EXP restrictions
+enable_exp_admin_bypass = true
+# Allow non-admins to play the AI job
+allow_ai = true
+# Prevent guests (people without BYOND accounts) from playing following positions
+# Captain, HoS, HoP, CE, RD, CMO, Warden, Security, Detective, AI
+guest_job_ban = true
+# Should assistants have maint access?
+assistant_maint_access = true
+# Should the amount of assistants be limited?
+assistant_limit = false
+# If they above setting is enabled, specify a ratio of how many assistants can be allowed per security officers onboard
+assistant_security_ratio = 2
+# Enable to use the custom job amounts here, disable to use the code ones
+enable_job_amount_overrides = true
+# Job slot amount map. These are overrides. If you dont specify a value here, the code will be used as default. -1 is infinite
+job_slot_amounts = [
+ # Commmand
+ {name = "Captain", lowpop = 1, highpop = 1},
+ {name = "Head of Personnel", lowpop = 1, highpop = 1},
+ {name = "Head of Security", lowpop = 1, highpop = 1},
+ {name = "Chief Engineer", lowpop = 1, highpop = 1},
+ {name = "Research Director", lowpop = 1, highpop = 1},
+ {name = "Chief Medical Officer", lowpop = 1, highpop = 1},
+ # Engineering
+ {name = "Atmospheric Technician", lowpop = 3, highpop = 4},
+ {name = "Station Engineer", lowpop = 5, highpop = 6},
+ # Medical
+ {name = "Chemist", lowpop = 2, highpop = 2},
+ {name = "Geneticist", lowpop = 2, highpop = 2},
+ {name = "Medical Doctor", lowpop = 5, highpop = 6},
+ {name = "Virologist", lowpop = 1, highpop = 1},
+ # Science
+ {name = "Robotocist", lowpop = 2, highpop = 2},
+ {name = "Scientist", lowpop = 6, highpop = 7},
+ # Security
+ {name = "Detective", lowpop = 1, highpop = 1},
+ {name = "Security Officer", lowpop = 7, highpop = 8},
+ {name = "Warden", lowpop = 1, highpop = 1},
+ # Service
+ {name = "Bartender", lowpop = 1, highpop = 1},
+ {name = "Botanist", lowpop = 2, highpop = 2},
+ {name = "Chaplain", lowpop = 1, highpop = 1},
+ {name = "Chef", lowpop = 1, highpop = 1},
+ {name = "Janitor", lowpop = 1, highpop = 2},
+ {name = "Lawyer", lowpop = 2, highpop = 2},
+ {name = "Librarian", lowpop = 1, highpop = 1},
+ # Cargo/Supply
+ {name = "Quartermaster", lowpop = 1, highpop = 1},
+ {name = "Shaft Miner", lowpop = 6, highpop = 6},
+ {name = "Cargo Technician", lowpop = 3, highpop = 4},
+ # Silicon
+ {name = "AI", lowpop = 1, highpop = 1},
+ {name = "Cyborg", lowpop = 1, highpop = 1},
+ # Misc
+ {name = "Assistant", lowpop = -1, highpop = -1},
+]
+
+
+################################################################
+
+
+[logging_configuration]
+# Configuration for all things related to logging data to disk
+# If you are in production you will want most of these on
+
+# Log OOC messages
+enable_ooc_logging = true
+# Log ingame say messages
+enable_say_logging = true
+# Log admin actions
+enable_admin_logging = true
+# Log client access (login/logout)
+enable_access_logging = true
+# Log game events (roundstart, results, a lot of other things)
+enable_game_logging = true
+# Enable logging of votes and their results
+enable_vote_logging = true
+# Enable logging of whipers
+enable_whisper_logging = true
+# Enable logging of emotes
+enable_emote_logging = true
+# Enable logging of attacks between players
+enable_attack_logging = true
+# Enable logging of PDA messages
+enable_pda_logging = true
+# Enable runtime logging
+enable_runtime_logging = true
+# Enable world.log output logging
+enable_world_logging = false
+# Log hrefs
+enable_href_logging = true
+# Log admin warning messages
+enable_admin_warning_logging = true
+# Log asay messages
+enable_adminchat_logging = true
+# Log debug messages
+enable_debug_logging = true
+
+
+################################################################
+
+
+[mc_configuration]
+# This section is settings for the MC
+# Dont change these unless you know what you are doing
+
+# Defines world tick lag. 0.5 is default for 20 TPS/FPS (10 * ticklag = TPS/FPS)
+ticklag = 0.5
+# Tick usage percentage limit for the MC during initialization.
+world_init_mc_tick_limit = 500
+# Base MC tick rate. 1 = once per BYOND tick
+base_mc_tick_rate = 1
+# Highpop MC tick rate. Increased to account for lag
+highpop_mc_tick_rate = 1.1
+# Threshold to enable MC highpop mode
+mc_highpop_threshold_enable = 65
+# Threshold to disable MC highpop mode
+mc_highpop_threshold_disable = 60
+
+
+################################################################
+
+
+[movement_configuration]
+# This section contains values for all mob movement stuff.
+# We suggest VVing ingame till you get values you like.
+# In context of this, speed = delay. Lower number = higher speed.
+
+# Base run speed before modifiers
+base_run_speed = 1
+# Base walk speed before modifiers
+base_walk_speed = 4
+# Move delay for humanoids
+human_delay = 1.5
+# Move delay for cyborgs
+robot_delay = 2.5
+# Move delay for xenomorphs
+alien_delay = 1.5
+# Move delay for slimes (xenobio, not slimepeople)
+slime_delay = 1.5
+# Move delay for other simple animals
+animal_delay = 2.5
+
+
+################################################################
+
+
+[overflow_configuration]
+# This contains information for re-routing players to an overflow server
+# We dont use this in production, but you may find it useful
+
+# Cap of players before we start to re-route to the overflow server. 0 to disable
+player_reroute_cap = 0
+# Overflow server location
+overflow_server = "byond://yourdomain.com:1111"
+# List of ckeys who will not get rerouted to the overflow server
+overflow_whitelist = ["keyhere", "anotherhere"]
+
+
+################################################################
+
+
+[ruin_configuration]
+# This section contains configuration for all space ruins and lava ruins
+
+# Globally enable and disable placing of space ruins. Lava ruins will still place.
+enable_space_ruins = true
+# Minimum number of extra zlevels to generate and fill with ruins
+minimum_zlevels = 2
+# Maximum number of extra zlevels to generate and fill with ruins
+maximum_zlevels = 4
+# List of all space ruins that can generate in the world
+# Commenting something out in here DISABLES IT FROM SPAWNING
+active_space_ruins = [
+ "_maps/map_files/RandomRuins/SpaceRuins/way_home.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/asteroid1.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/asteroid2.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/asteroid3.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/asteroid4.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/asteroid5.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/derelict1.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/derelict2.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/derelict3.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/derelict4.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/derelict5.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/spacebar.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/deepstorage.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/emptyshell.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/gasthelizards.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/intactemptyship.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/mechtransport.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/turretedoutpost.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/debris1.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/debris2.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/debris3.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/listeningpost.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/onehalf.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/syndiecakesfactory.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm",
+
+ ### The following ruins are based from past pre-spawned Zlevel content ###
+ "_maps/map_files/RandomRuins/SpaceRuins/abandonedtele.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/blowntcommsat.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/clownmime.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/dj.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/druglab.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/syndiedepot.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/syndie_space_base.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/ussp_tele.dmm",
+ "_maps/map_files/RandomRuins/SpaceRuins/ussp.dmm",
+
+
+ # The following is the white ship ruin. Its force-spawned and is required to stop SSshuttle runtiming on startup
+ # Its also important incase a white-ship console is ever built midround
+ # DO NOT DISABLE THIS UNLESS YOU HAVE A GOOD REASON
+ "_maps/map_files/RandomRuins/SpaceRuins/whiteship.dmm",
+
+ # The following is a force-spawned ruin consisting mostly of empty space with a shuttle docking port for the free golem shuttle
+ # Disabling it will lead to the free golem shuttle sometimes being stuck on lavaland.
+ "_maps/map_files/RandomRuins/SpaceRuins/golemtarget.dmm",
+]
+# List of all ruins that can generate on lavaland
+# Commenting something out in here DISABLES IT FROM SPAWNING
+active_lava_ruins = [
+ ##BIODOMES
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_winter.dmm",
+ ##RESPAWN
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm",
+ ##SIN
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_envy.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_gluttony.dmm",
+ # Greed blacklisted on production because its reward (dice) has a 1/20 chance of making you a wizard
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_greed.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_pride.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_sloth.dmm",
+ ##MEGAFAUNA
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk1.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk2.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk3.dmm",
+ # Re-removed 7/24/2020, I ran a month-long test of hierophant Jun-Jul and the staff was still too strong. https://github.com/ParadiseSS13/Paradise/pull/13542
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_hierophant.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_swarmer_crash.dmm",
+
+ ##MISC
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm",
+ # Cube blacklisted on production because it contains a wishgranter that gives you hijack on use
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_cube.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_dead_ratvar.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_fountain_hall.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_puzzle.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_ufo_crash.dmm",
+ "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.dmm",
+]
+# Budget for lavaland ruins. A higher number means more will spawn
+lavaland_ruin_budget = 60
+
+
+################################################################
+
+
+[system_configuration]
+# This contains stuff that the host should fill out, relating to backend stuff
+
+# Communications password for authorising world/Topic requests. Comment out to disable
+#communications_password = "generateSomeLongRandomStringHere"
+# Medal hub for tracking lavaland stats
+#medal_hub_address = "hubmakerckey.hubname"
+# Medal hub password for tracking lavaland stats
+#medal_hub_password = "putYourPasswordHere"
+# Do we want to kill the world on reboot instead of restarting it?
+shutdown_on_reboot = false
+# If true to above, an optional shell command can be ran. Defaults to killing DD on windows
+#shutdown_shell_command = "taskkill /im dreamdaemon.exe /f"
+# URL for the 2FA backend HTTP host. Do not use https:// or a trailing slash. Comment out to disable
+#_2fa_auth_host = "http://127.0.0.1:8080"
+
+
+################################################################
+
+
+[url_configuration]
+# Configuration for all the URLs used by the server
+# If you are in production you will want to tweak these to your servers
+# If you comment any of these out, they will be null ingame
+
+# Location of server resources. Used to offload sending the paradise.rsc from DD to a webserver
+# NOTE: This wants paradise.rsc inside a zip file, and it is HTTP ONLY. NO HTTPS
+#rsc_urls = ["http://www.paradisestation.org/windows/paradise.rsc.zip"]
+# Link URL to link forum accounts to ckeys. If set to an empty string, no link option will be offered
+# Token is appended right on the end, so set parameters as needed
+#forum_link_url = "https://example.com/link.php?token="
+# URL for accessing player info from admin webtools
+# Ckey is appended right on the end, so set parameters as needed
+#forum_playerinfo_url = "https://example.com/info.php?ckey="
+# Server location for world reboot. Don't include the byond://, just give the address and port.
+#reboot_url = "byond.paradisestation.org:6666"
+# Forum address
+forum_url = "https://www.paradisestation.org/forum/"
+# Wiki address
+wiki_url = "https://www.paradisestation.org/wiki"
+# Rules address
+rules_url = "https://www.paradisestation.org/rules"
+# Github address
+github_url = "https://github.com/ParadiseSS13/Paradise"
+# Discord address
+#discord_url = "http://example.org"
+# Discord address (forum-based invite)
+discord_forum_url = "https://www.paradisestation.org/forum/discord/invite/general/"
+# Donations address
+donations_url = "https://www.patreon.com/ParadiseStation"
+# Ban appeals URL - usually for a forum or wherever people should go to contact your admins
+ban_appeals_url = "https://www.paradisestation.org/forum/55-unban-requests/"
+# URL for the CentComm ban DB. Doesnt change much. Ckey is slapped on the end
+centcomm_ban_db_url = "https://centcom.melonmesa.com/ban/search/"
+
+
+################################################################
+
+
+[voting_configuration]
+# This section contains all settings relating to the ingame voting system
+
+# Allow players to vote for a round restart?
+allow_vote_restart = false
+# Allow players to vote for a gamemode in lobby?
+allow_vote_mode = false
+# Minimum delay between each vote (deciseconds)
+vote_delay = 18000
+# Time that a vote will last for (deciseconds)
+vote_time = 600
+# Time before the first auto crew transfer vote (deciseconds)
+autotransfer_initial_time = 72000
+# Interval after the first auto transfer vote for the next to be called (deciseconds)
+autotransfer_interval_time = 18000
+# Prevent dead players from voting or starting votes
+prevent_dead_voting = false
+# Default to players not voting by default
+disable_default_vote = true
+# Enable voting for a map on end round
+enable_map_voting = false
+
+
+################################################################
+
+# Congratulations. You reached the end. heres a cookie.
diff --git a/config/example/config.txt b/config/example/config.txt
deleted file mode 100644
index 27fe31e980e..00000000000
--- a/config/example/config.txt
+++ /dev/null
@@ -1,479 +0,0 @@
-## Server name: This identifies your server in the server list. It may also be used as the title of the game window.
-SERVERNAME ParaCode Test
-
-## Server tagline: This appears on the hub entry.
-SERVER_TAG_LINE ParaCode Test
-
-## Server extra features: This appears in the feature list on the hub entry.
-SERVER_EXTRA_FEATURES Medium RP, varied species/jobs.
-
-## Download the RSC from the web - this needs to be regenerated every time the code is changed.
-#RESOURCE_URLS http://www.paradisestation.org/windows/paradise.rsc.zip
-
-## Add a # infront of this if you want to use the SQL based admin system, the legacy system uses admins.txt. You need to set up your database to use the SQL based system.
-ADMIN_LEGACY_SYSTEM
-
-## Add a # infront of this if you want to use the SQL based banning system. The legacy systems use the files in the data folder. You need to set up your database to use the SQL based system.
-BAN_LEGACY_SYSTEM
-
-## Add a # here if you wish to use the setup where jobs have more access. This is intended for servers with low populations - where there are not enough players to fill all roles, so players need to do more than just one job. Also for servers where they don't want people to hide in their own departments.
-JOBS_HAVE_MINIMAL_ACCESS
-
-## Unhash this entry to have certain jobs require your account to be at least a certain number of days old to select. You can configure the exact age requirement for different jobs by editing
-## the minimal_player_age variable in the files in folder /code/game/jobs/job/.. for the job you want to edit. Set minimal_player_age to 0 to disable age requirement for that job.
-## REQUIRES the database set up to work. Keep it hashed if you don't have a database set up.
-## NOTE: If you have just set-up the database keep this DISABLED, as player age is determined from the first time they connect to the server with the database up. If you just set it up, it means
-## you have noone older than 0 days, since noone has been logged yet. Only turn this on once you have had the database up for 30 days.
-#USE_AGE_RESTRICTION_FOR_JOBS
-
-##Unhash this to track player playtime in the database. Requires database to be enabled.
-#USE_EXP_TRACKING
-##Unhash this to enable playtime requirements for jobs that have them defined.
-#USE_EXP_RESTRICTIONS
-##Allows admins to bypass job playtime requirements.
-USE_EXP_RESTRICTIONS_ADMIN_BYPASS
-
-## Unhash this entry to have certain antagonist roles require your account to be at least a certain number of days old to select. You can configure the exact age requirement for different antag roles by editing special_role_times in /code/modules/client/preferences.dm.
-## See USE_AGE_RESTRICTION_FOR_JOBS for more information
-#USE_AGE_RESTRICTION_FOR_ANTAGS
-
-## log OOC channel
-LOG_OOC
-
-## log client Say
-LOG_SAY
-
-## log admin actions
-LOG_ADMIN
-
-## log client access (logon/logoff)
-LOG_ACCESS
-
-## log game actions (start of round, results, etc.)
-LOG_GAME
-
-## log player votes
-LOG_VOTE
-
-## log client Whisper
-LOG_WHISPER
-
-## log emotes
-LOG_EMOTE
-
-## log attack messages
-LOG_ATTACK
-
-## log pda messages
-LOG_PDA
-
-## log world.log and runtime errors to a file
-LOG_RUNTIME
-
-## log world.log messages
-# LOG_WORLD_OUTPUT
-
-## log all Topic() calls (for use by coders in tracking down Topic issues)
-LOG_HREFS
-
-## log admin warning messages - may result in some message duplication
-LOG_ADMINWARN
-
-## Log admin chat
-LOG_ADMINCHAT
-
-## Amount of minutes that a person has to be AFK before he will be warned by the AFK subsystem. Leave this 0 to prevent the subsystem from activating
-WARN_AFK_MINIMUM 15
-
-## Amount of minutes that a person has to be AFK before he will be cryod by the AFK subsystem. Leave this 0 to prevent the subsystem from activating
-AUTO_CRYO_AFK 20
-
-## Amount of minutes that a person has to be AFK before he will be despawned by the AFK subsystem. Leave this 0 to prevent the subsystem from activating
-AUTO_DESPAWN_AFK 21
-
-## probablities for game modes chosen in "secret" and "random" modes
-##
-## default probablity is 1, increase to make that mode more likely to be picked
-## set to 0 to disable that mode
-PROBABILITY ABDUCTION 0
-PROBABILITY BLOB 1
-PROBABILITY CHANGELING 3
-PROBABILITY CULT 3
-PROBABILITY EXTEND-A-TRAITORMONGOUS 2
-PROBABILITY EXTENDED 3
-PROBABILITY HEIST 0
-PROBABILITY METEOR 0
-PROBABILITY NUCLEAR 2
-PROBABILITY RAGINMAGES 0
-PROBABILITY REVOLUTION 0
-PROBABILITY SHADOWLING 1
-PROBABILITY TRAITOR 2
-PROBABILITY TRAITORCHAN 3
-PROBABILITY TRAITORVAMP 3
-PROBABILITY VAMPIRE 3
-PROBABILITY WIZARD 2
-
-## Uncomment to allow free golems on all roundtypes. Otherwise, disabled on cult, wiz, raging mages, blob, and nuclear.
-#UNRESTRICTED_FREE_GOLEMS
-
-## MAXIMUM SECONDS SHADOWLINGS CAN REMAIN UNHATCHED BEFORE THEY TAKE DAMAGE
-SHADOWLING_MAX_AGE 600
-
-## Hash out to disable random events during the round.
-ALLOW_RANDOM_EVENTS
-
-## if amount of traitors scales or not
-TRAITOR_SCALING
-
-## If security is prohibited from being most antagonists
-PROTECT_ROLES_FROM_ANTAGONIST
-
-## Comment this out to stop admins being able to choose their personal ooccolor
-ALLOW_ADMIN_OOCCOLOR
-
-## If metadata is supported
-ALLOW_METADATA
-
-## The time it takes for a round to start in seconds
-PREGAME_TIMESTART 240
-
-## allow players to initiate a restart vote
-#ALLOW_VOTE_RESTART
-
-## allow players to initate a mode-change start
-#ALLOW_VOTE_MODE
-
-## min delay (deciseconds) between voting sessions (default 10 minutes)
-VOTE_DELAY 18000
-
-## time period (deciseconds) which voting session will last (default 1 minute)
-VOTE_PERIOD 600
-
-## autovote initial delay (deciseconds) before first automatic transfer vote call (default 180 minutes)
-VOTE_AUTOTRANSFER_INITIAL 72000
-
-##autovote delay (deciseconds) before sequential automatic transfer votes are called (default 60 minutes)
-VOTE_AUTOTRANSFER_INTERVAL 18000
-
-## prevents dead players from voting or starting votes
-#NO_DEAD_VOTE
-
-## players' votes default to "No vote" (otherwise, default to "No change")
-DEFAULT_NO_VOTE
-
-## allow AI job
-ALLOW_AI
-
-## Allow ghosts to see antagonist through AntagHUD
-ALLOW_ANTAG_HUD
-
-## If ghosts use antagHUD they are no longer allowed to join the round.
-ANTAG_HUD_RESTRICTED
-
-## disable abandon mob
-NORESPAWN
-
-## disables calling qdel(src) on newmobs if they logout before spawnin in
-# DONT_DEL_NEWMOB
-
-## Set to jobban "Guest-" accounts from Captain, HoS, HoP, CE, RD, CMO, Warden, Security, Detective, and AI positions.
-## Set to 1 to jobban them from those positions, set to 0 to allow them.
-GUEST_JOBBAN
-
-## Uncomment this to stop people connecting to your server without a registered ckey. (i.e. guest-* are all blocked from connecting)
-GUEST_BAN
-
-## above this player count threshold, never-before-seen players are blocked from connecting
-PANIC_BUNKER_THRESHOLD 150
-
-### IPINTEL:
-### This allows you to detect likely proxies by checking ips against getipintel.net
-## Rating to warn at: (0.90 is good, 1 is 100% likely to be a spammer/proxy, 0.8 is 80%, etc) anything equal to or higher then this number triggers an admin warning
-#IPINTEL_RATING_BAD 0.98
-## Contact email, (required to use the service, leaving blank or default disables IPINTEL)
-#IPINTEL_EMAIL ch@nge.me
-## How long to save good matches (ipintel rate limits to 15 per minute and 500 per day. so this shouldn't be too low, getipintel.net suggests 6 hours, time is in hours) (Your ip will get banned if you go over 500 a day too many times)
-#IPINTEL_SAVE_GOOD 72
-## How long to save bad matches (these numbers can change as ips change hands, best not to save these for too long in case somebody gets a new ip used by a spammer/proxy before.)
-#IPINTEL_SAVE_BAD 24
-## Domain name to query (leave commented out for the default, only needed if you pay getipintel.net for more querys)
-#IPINTEL_DOMAIN check.getipintel.net
-## Ignore players with this many hours of playtime. Requires USE_EXP_TRACKING
-#IPINTEL_MAXPLAYTIME 10
-## Require players (except the previous ones with playtime, if enabled) to be whitelisted to use proxies/VPNs.
-#IPINTEL_WHITELIST
-## URL to show to admins to provide more information about an IP address. Leave undefined for default.
-#IPINTEL_DETAILSURL https://iphub.info/?ip=
-
-## URL to use to link forum accounts. If not set, no link option will be offered.
-#FORUM_LINK_URL https://example.com/link.php?token=
-
-## URL to use for admins accessing the web-based tools menu
-#FORUM_PLAYERINFO_URL https://example.com/info.php?ckey=
-
-## Comment to disable checking for the cid randomizer dll. (disabled if database isn't enabled or connected)
-#CHECK_RANDOMIZER
-
-## the whitelist
-USEWHITELIST
-
-## set a server location for world reboot. Don't include the byond://, just give the address and port.
-# SERVER server.net:port
-
-## Forum address
-FORUMURL https://www.paradisestation.org/forum/
-
-## Wiki address
-WIKIURL https://www.paradisestation.org/wiki
-
-## Rules address
-RULESURL https://www.paradisestation.org/rules
-
-## Github address
-GITHUBURL https://github.com/ParadiseSS13/Paradise
-
-## Discord address
-#DISCORDURL http://example.org
-
-## Discord address (forum-based invite)
-DISCORDFORUMURL https://www.paradisestation.org/forum/discord/invite/general/
-
-## Donations address
-DONATIONSURL https://www.patreon.com/ParadiseStation
-
-## Repository address
-REPOSITORYURL https://github.com/ParadiseSS13/Paradise
-
-## Ban appeals URL - usually for a forum or wherever people should go to contact your admins
-BANAPPEALS https://www.paradisestation.org/forum/55-unban-requests/
-
-## In-game features
-## spawns a spellbook which gives object-type spells instead of verb-type spells for the wizard
-# FEATURE_OBJECT_SPELL_SYSTEM
-
-## Toggle for having jobs load up from the .txt
-LOAD_JOBS_FROM_TXT
-
-## Remove the # mark infront of this to forbid admins from posssessing the singularity.
-#FORBID_SINGULO_POSSESSION
-
-## Remove the # to show a popup 'reply to' window to every non-admin that recieves an adminPM.
-## The intention is to make adminPMs more visible. (although I fnd popups annoying so this defaults to off)
-#POPUP_ADMIN_PM
-
-## Remove the # to allow special 'Easter-egg' events on special holidays such as seasonal holidays and stuff like 'Talk Like a Pirate Day' :3 YAARRR
-ALLOW_HOLIDAYS
-
-##Defines the ticklag for the world. 0.9 is the normal one, 0.5 is smoother.
-TICKLAG 0.5
-
-## Whether the server will talk to other processes through socket_talk
-SOCKET_TALK 0
-
-## Comment this out to disable automuting
-#AUTOMUTE_ON
-
-## How long the delay is before the Away Mission gate opens. Default is half an hour.
-GATEWAY_DELAY 10
-
-## Remove the # to give assistants maint access.
-ASSISTANT_MAINT
-
-## Remove the # to enable assistant limiting.
-#ASSISTANT_LIMIT
-
-# Mins before SSD crew are cryoed.
-AUTO_CRYO_SSD_MINS 15
-
-# If enabled, prevents people interacting with SSD players unless they acknowledge they have read the server rules.
-SSD_WARNING
-
-## If you enabled assistant limiting set the ratio of assistants to security members default is 2 assistants to 1 officer
-ASSISTANT_RATIO 2
-
-## Remove the # to make rounds which end instantly (Rev, Wizard, Malf) to continue until the shuttle is called or the station is nuked.
-## Malf and Rev will let the shuttle be called when the antags/protags are dead.
-#CONTINUOUS_ROUNDS
-
-## Uncomment to restrict non-admins from using humanoid alien races
-USEALIENWHITELIST
-
-## Comment this to unrestrict the number of alien players allowed in the round. The number represents the number of alien players for every human player.
-ALIEN_PLAYER_RATIO 0.2
-
-##Remove the # to let ghosts spin chairs
-#GHOST_INTERACTION
-
-## Password used for authorizing external tools via world/Topic.
-#COMMS_PASSWORD
-
-## Expected round length in minutes
-EXPECTED_ROUND_LENGTH 120
-
-## The lower delay between events in minutes.
-## Affect mundane, moderate, and major events respectively
-EVENT_DELAY_LOWER 10;30;50
-
-## The upper delay between events in minutes.
-## Affect mundane, moderate, and major events respectively
-EVENT_DELAY_UPPER 15;45;70
-
-## The delay until the first time an event of the given severity runs in minutes.
-## Unset setting use the EVENT_DELAY_LOWER and EVENT_DELAY_UPPER values instead.
-#EVENT_CUSTOM_START_MINOR 10;15
-EVENT_CUSTOM_START_MODERATE 25;40
-EVENT_CUSTOM_START_MAJOR 55;75
-
-## Starlight for exterior walls and breaches. Uncomment for starlight!
-## This is disabled by default to make testing quicker, should be enabled on production servers or testing servers messing with lighting
-STARLIGHT
-
-## Player rerouting stuff
-## If not 0, players can be rerouted to an overflow server after a certain cap is reached
-
-## Cap before players start being rerouted
-PLAYER_REROUTE_CAP 0
-
-## Server to reroute to
-#OVERFLOW_SERVER_URL byond://example.org:1111
-
-## Disable the loading of away missions
-#DISABLE_AWAY_MISSIONS
-
-## Disable the loading of space ruins
-#DISABLE_SPACE_RUINS
-
-## Minimum number of space ruins levels to generate
-EXTRA_SPACE_RUIN_LEVELS_MIN 2
-
-## Maximum number of space ruins levels to generate
-EXTRA_SPACE_RUIN_LEVELS_MAX 4
-
-## Uncomment to disable the OOC/LOOC channel by default.
-#DISABLE_OOC
-
-## Uncomment to disable the dead OOC channel by default.
-#DISABLE_DEAD_OOC
-
-## Uncomment to disable ghost chat by default.
-#DISABLE_DSAY
-
-## Uncomment this if you want to disable the lobby music
-#DISABLE_LOBBY_MUSIC
-
-## Uncomment this if you want to disable the popup alert for people on the same CID
-#DISABLE_CID_WARN_POPUP
-
-## How many loadout points players may spend in character setup
-#MAX_LOADOUT_POINTS 5
-
-# How many minutes players must wait, from round start, before they can ghost out
-# and still qualify for re-entering the round. Defaults to 30.
-# Setting this to 0 will disable the penalty period
-#ROUND_ABANDON_PENALTY_PERIOD 30
-
-## Hub address for tracking stats
-## example: Hubmakerckey.Hubname
-#MEDAL_HUB_ADDRESS
-
-## Password for the hub page
-#MEDAL_HUB_PASSWORD
-
-## Uncomment this if you want to disable usage of emoji in OOC
-#DISABLE_OOC_EMOJI
-
-## Uncomment this to shut down the world any time it would normally reboot
-#SHUTDOWN_ON_REBOOT
-## A command to run prior to the world shutting down, only used if the above option is enabled
-## This default value will kill Dream Daemon on Windows machines.
-#SHUTDOWN_SHELL_COMMAND taskkill /f /im dreamdaemon.exe
-
-## Uncomment this to disable karma and unlock all karma purchases for players by default
-#DISABLE_KARMA
-
-## Defines the ticklimit for subsystem initialization (In percents of a byond tick). Lower makes world start smoother. Higher makes it faster.
-##This is currently a testing optimized setting. A good value for production would be 98.
-TICK_LIMIT_MC_INIT 500
-
-###Master Controller High Pop Mode###
-
-##The Master Controller(MC) is the primary system controlling timed tasks and events in SS13 (lobby timer, game checks, lighting updates, atmos, etc)
-##Default base MC tick rate (1 = process every "byond tick" (see: tick_lag/fps config settings), 2 = process every 2 byond ticks, etc)
-## Setting this to 0 will prevent the Master Controller from ticking
-BASE_MC_TICK_RATE 1
-
-##High population MC tick rate
-## Byond rounds timer values UP, but the tick rate is modified with heuristics during lag spites so setting this to something like 2
-## will make it run every 2 byond ticks, but will also double the effect of anti-lag heuristics. You can instead set it to something like
-## 1.1 to make it run every 2 byond ticks, but only increase the effect of anti-lag heuristics by 10%. or 1.5 for 50%.
-## (As an aside, you could in theory also reduce the effect of anti-lag heuristics in the base tick rate by setting it to something like 0.5)
-HIGH_POP_MC_TICK_RATE 1.1
-
-##Engage high pop mode if player count raises above this (Player in this context means any connected user. Lobby, ghost or in-game all count)
-HIGH_POP_MC_MODE_AMOUNT 65
-
-##Disengage high pop mode if player count drops below this
-DISABLE_HIGH_POP_MC_MODE_AMOUNT 60
-
-##Uncomment to enable developer start. Auto starts the server after initialization
-#DEVELOPER_EXPRESS_START
-
-## Uncomment to disable automatic admin for localhost
-#DISABLE_LOCALHOST_ADMIN
-
-## Add a # infront of this to unlimit the builds used to play. Advised is to keep it atleast 1421 due to the middle mouse button locking exploit
-MINIMUM_CLIENT_BUILD 1421
-
-## Uncomment to give a confirmation before hitting start now
-#START_NOW_CONFIRMATION
-
-## If uncommented, all gamemodes will respect the number of required players. Defaults to no.
-ENABLE_GAMEMODE_PLAYER_LIMIT
-
-## BYOND accounts younger than the value below will alert admins when they connect for the first time,
-## as well as making the BYOND account age in player panel bold
-BYOND_ACCOUNT_AGE_THRESHOLD 3
-
-##### DISCORD STUFF #####
-
-## If you are going to enable discord webhooks, fill out EVERYTHING in this section
-
-## Uncomment the line below to enable Discord webhooks
-#ENABLE_DISCORD_WEBHOOKS
-
-## Role ID to be pinged with administrative events. If unset, all pings to this role will be disabled
-## IF YOU ARE DISABLING THIS COMMENT IT OUT ENTIRELY, DONT LEAVE IT BLANK
-#DISCORD_WEBHOOKS_ADMIN_ROLE_ID 111111111111
-
-## Webhook URLs for the main discord webhook. Separate multiple URLs with a | (EG: https://url1|https://url2)
-#DISCORD_WEBHOOKS_MAIN_URL
-
-## Webhook URLs for the admin discord webhook. Separate multiple URLs with a | (EG: https://url1|https://url2)
-#DISCORD_WEBHOOKS_ADMIN_URL
-
-## Webhook URLs for the mentor discord webhook. Separate multiple URLs with a | (EG: https://url1|https://url2)
-#DISCORD_WEBHOOKS_MENTOR_URL
-
-## Uncomment to send all ahelps to discord. If the line is commented, only ahelps made when no admins are online will be forwarded
-## Ahelps forwarded when staff are online will never have the role ping, regardless of the setting above
-#DISCORD_FORWARD_ALL_AHELPS
-
-##### END DISCORD STUFF #####
-
-## URL For CentCom global ban DB
-## This is a config option should you want to disable this system, or if the primary URL changes
-## THE TRAILING SLASH ON THE END IS IMPORTANT SINCE IT JUST APPENDS THE CKEY TO THE END IN RAW
-## Add a hash before the line below to disable the system
-CENTCOM_BAN_DB_URL https://centcom.melonmesa.com/ban/search/
-
-## Max amount of CIDs that one ckey can have attached to them before they trip a warning. Set to 0 to disable.
-MAX_CLIENT_CID_HISTORY 20
-
-## Uncomment to enable automatic performance profiling of rounds
-ENABLE_AUTO_PROFILER
-
-## Uncomment to enable map voting
-#ENABLE_MAP_VOTING
-
-## Host for a custom 2FA server. Comment to disable. Do not use a trailing slash or https.
-#2FA_HOST http://127.0.0.1:8080
diff --git a/config/example/custom_sprites.txt b/config/example/custom_sprites.txt
deleted file mode 100644
index 45d1d66058b..00000000000
--- a/config/example/custom_sprites.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-Each entry should be composed of 2 parts, divided by a colon (:) with no spaces, in order to work. Failure to do so will result in that entry being disregarded by the code.
-- The first part should be either "cyborg", "ai", "hologram", "pai", "drone", or "screen". This tells the code what type of custom sprite this entry is for. The "ai" option is for AI core displays, while "hologram" is for AI hologram projections.
-- The second part should be the ckey of the player this entry is for. This tells the code who it works for and also is used to retrieve the proper sprite for them to use.
-- If the entry is a custom screen, it will need a 3rd part which is the screen name. This tells the code which screen to use, as well allows for someone to have more then one custom screen.
-
-
-example:example
\ No newline at end of file
diff --git a/config/example/dbconfig.txt b/config/example/dbconfig.txt
deleted file mode 100644
index ffceb33e7de..00000000000
--- a/config/example/dbconfig.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-## MySQL Connection Configuration
-## This is used for stats, feedback gathering,
-## administration, and the in game library.
-
-## Should SQL be enabled? Uncomment to enable.
-#SQL_ENABLED
-
-## Server the MySQL database can be found at.
-# Examples: localhost, 200.135.5.43, www.mysqldb.com, etc.
-ADDRESS 127.0.0.1
-
-## MySQL server port (default is 3306).
-PORT 3306
-
-## Database for all SQL functions, not just feedback.
-FEEDBACK_DATABASE feedback
-
-## This value must be set to the version of the paradise schema in use.
-## If this value does not match, the SQL database will not be loaded and an error will be generated.
-## Roundstart will be delayed.
-DB_VERSION 24
-
-## Prefix to be added to the name of every table, older databases will require this be set to erro_
-## If left out defaults to erro_ for legacy reasons, if you want no table prefix, give a blank prefix rather then comment out
-## Note, this does not change the table names in the database, you will have to do that yourself.
-## IE:
-## FEEDBACK_TABLEPREFIX erro_
-## FEEDBACK_TABLEPREFIX
-## FEEDBACK_TABLEPREFIX SS13_
-##
-## Leave as is if you are using the standard schema file.
-FEEDBACK_TABLEPREFIX
-
-## Username/Login used to access the database.
-FEEDBACK_LOGIN username
-
-## Password used to access the database.
-FEEDBACK_PASSWORD password
-
-## Time in seconds for asynchronous queries to timeout
-## Set to 0 for infinite
-ASYNC_QUERY_TIMEOUT 10
-
-## The maximum number of additional threads Rust SQL is allowed to run at once
-RUST_SQL_THREAD_LIMIT 50
diff --git a/config/example/game_options.txt b/config/example/game_options.txt
deleted file mode 100644
index 0d81a9402c8..00000000000
--- a/config/example/game_options.txt
+++ /dev/null
@@ -1,79 +0,0 @@
-### HEALTH ###
-## Determines whether bones can be broken through excessive damage to the organ
-## 0 means bones can't break, 1 means they can
-BONES_CAN_BREAK 1
-
-### REVIVAL ###
-## Whether pod plants work or not
-REVIVAL_POD_PLANTS 1
-
-## Whether cloning tubes work or not
-REVIVAL_CLONING 1
-
-## Amount of time (in hundredths of seconds) for which a brain retains the "spark of life" after the person's death (set to -1 for infinite)
-REVIVAL_BRAIN_LIFE 60000
-
-### AUTO TOGGLE OOC DURING ROUND ###
-#Uncomment this if you want OOC to be automatically disabled during the round, it will be enabled during the lobby and after the round end results.
-AUTO_TOGGLE_OOC_DURING_ROUND
-
-### MOB MOVEMENT ###
-## We suggest editing these variabled in-game to find a good speed for your server. To do this you must be a high level admin. Open the 'debug' tab ingame. Select "Debug Controller" and then, in the popup, select "Configuration". These variables should have the same name.
-## These values get directly added to values and totals in-game. To speed things up make the number negative, to slow things down, make the number positive.
-
-## These modify the run/walk speed of all mobs before the mob-specific modifiers are applied.
-RUN_SPEED 1
-WALK_SPEED 4
-
-## The variables below affect the movement of specific mob types.
-HUMAN_DELAY 1.5
-ROBOT_DELAY 2.5
-MONKEY_DELAY 1.5
-ALIEN_DELAY 1.5
-SLIME_DELAY 1.5
-ANIMAL_DELAY 2.5
-
-## Comment for "normal" explosions, which ignore obstacles
-## Uncomment for explosions that react to doors and walls
-REACTIONARY_EXPLOSIONS
-
-# The number of objectives traitors get.
-# Not including escaping/hijacking.
-TRAITOR_OBJECTIVES_AMOUNT 2
-
-### Configure the bomb cap
-## This caps all explosions to the specified range. Used for both balance reasons and to prevent overloading the server and lagging the game out.
-## This is given as the 3rd number(light damage) in the standard (1,2,3) explosion notation. The other numbers are derived by dividing by 2 and 4.
-## eg: If you give the number 20. The bomb cap will be 5,10,20.
-## Can be any number between 4 and 128, some examples are provided below.
-
-## Default (3,7,14)
-#BOMBCAP 14
-## One 'step' up (5,10,20) (recommended if you enable REACTIONARY_EXPLOSIONS above)
-BOMBCAP 20
-## LagHell (7,14,28)
-#BOMBCAP 28
-
-### ROUNDSTART SILICON LAWS ###
-## This controls what the AI's laws are at the start of the round.
-## Set to 0/commented for "off", silicons will just start with Crewsimov.
-## Set to 1 for "random", silicons will start with a random lawset picked from (at the time of writing): Nanotrasen Default, P.A.L.A.D.I.N., Corporate, Robop and Crewsimov. More can be added by changing the law datum "default" variable in ai_laws.dm.
-
-DEFAULT_LAWS 1
-
-## Randomize roundstart time (anywhere from 00:00 to 23:00 instead of always starting at 12:00)
-RANDOMIZE_SHIFT_TIME
-
-## Enable Nightshift - Causes the station to go into "night mode" from 19:30 to 07:30. Best used with RANDOMIZED_SHIFT_TIME.
-ENABLE_NIGHT_SHIFTS
-
-## Lavaland "Budget"
-# Lavaland ruin spawning has an imaginary budget to spend on ruins, where
-# a less lootfilled or smaller or less round effecting ruin costs less to
-# spawn, while the converse is true. Alter this number to affect the amount
-# of ruins.
-LAVALAND_BUDGET 60
-
-## Cube monkey limit
-# Amount of cube monkeys that can be spawned before the game limits them
-CUBEMONKEY_CAP 32
\ No newline at end of file
diff --git a/config/example/jobs.txt b/config/example/jobs.txt
deleted file mode 100644
index 6a73ab5f517..00000000000
--- a/config/example/jobs.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-Captain=1
-Head of Personnel=1
-Head of Security=1
-Chief Engineer=1
-Research Director=1
-Chief Medical Officer=1
-
-Station Engineer=5
-Roboticist=2
-
-Medical Doctor=5
-Geneticist=2
-Virologist=1
-
-Scientist=6
-Chemist=2
-
-Bartender=1
-Botanist=2
-Chef=1
-Janitor=1
-Quartermaster=1
-Shaft Miner=6
-
-Warden=1
-Detective=1
-Security Officer=7
-
-Assistant=-1
-Atmospheric Technician=3
-Cargo Technician=3
-Chaplain=1
-Lawyer=2
-Librarian=1
-
-AI=1
-Cyborg=1
diff --git a/config/example/jobs_highpop.txt b/config/example/jobs_highpop.txt
deleted file mode 100644
index eaaa50d55a9..00000000000
--- a/config/example/jobs_highpop.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-Captain=1
-Head of Personnel=1
-Head of Security=1
-Chief Engineer=1
-Research Director=1
-Chief Medical Officer=1
-
-Station Engineer=6
-Roboticist=2
-
-Medical Doctor=6
-Geneticist=2
-Virologist=1
-
-Scientist=7
-Chemist=2
-
-Bartender=1
-Botanist=2
-Chef=1
-Janitor=2
-Quartermaster=1
-Shaft Miner=6
-
-Warden=1
-Detective=1
-Security Officer=8
-
-Assistant=-1
-Atmospheric Technician=4
-Cargo Technician=4
-Chaplain=1
-Lawyer=2
-Librarian=1
-
-AI=1
-Cyborg=1
diff --git a/config/example/lavaRuinBlacklist.txt b/config/example/lavaRuinBlacklist.txt
deleted file mode 100644
index 49b70b5e682..00000000000
--- a/config/example/lavaRuinBlacklist.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-#Listing maps here will blacklist them from generating in lavaland.
-#Maps must be the full path to them
-#A list of maps valid to blacklist can be found in _maps\RandomRuins\LavaRuins
-#SPECIFYING AN INVALID MAP WILL RESULT IN RUNTIMES ON GAME START
-
-##BIODOMES
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_winter.dmm
-
-##RESPAWN
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm
-
-##SIN
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_envy.dmm
-# Gluttony was blacklisted because its reward is 'become morph'. Unblacklisted as it doesn't seem to generate complaints or be abused - but watch it.
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_gluttony.dmm
-# Greed blacklisted because its reward (dice) has a 1/20 chance of making you a wizard
-_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_greed.dmm
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_pride.dmm
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_sloth.dmm
-
-##MEGAFAUNA
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk1.dmm
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk2.dmm
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk3.dmm
-#re-removed 7/24/2020, I ran a month-long test of hierophant Jun-Jul and the staff was still too strong. https://github.com/ParadiseSS13/Paradise/pull/13542
-_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_hierophant.dmm
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_swarmer_crash.dmm
-
-##MISC
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_animal_hospital.dmm
-# Cube blacklisted because it contains a wishgranter that gives you hijack on use
-_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_cube.dmm
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_dead_ratvar.dmm
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_fountain_hell.dmm"
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_pizza_party.dmm
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_puzzle.dmm
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_ufo_crash.dmm"
-#_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.dmm"
\ No newline at end of file
diff --git a/config/example/ofwhitelist.txt b/config/example/ofwhitelist.txt
deleted file mode 100644
index 7588d3b698e..00000000000
--- a/config/example/ofwhitelist.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-#Any ckeys in this file will be ignored by the overflow system.
-example142
\ No newline at end of file
diff --git a/config/example/rank_colours.txt b/config/example/rank_colours.txt
deleted file mode 100644
index b35641c39f4..00000000000
--- a/config/example/rank_colours.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-# Use this file to denote colours for ingame admin ranks, using the following format
-# Rankname - #12A5F4
-# Colours dont have to be in hex, since this colour string is thrown into the style -aa
-Head of Staff - #e74c3c
-Maintainer - #992d22
-Server Dev - #1abc9c
-Community Manager - #e91e63
-Game Admin - #238afa
-Trial Admin - #7fb6fc
-PR Reviewer - #c27c0e
-Mentor - #f1c40f
diff --git a/config/example/spaceRuinBlacklist.txt b/config/example/spaceRuinBlacklist.txt
deleted file mode 100644
index 7ca7abb4b3a..00000000000
--- a/config/example/spaceRuinBlacklist.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-#Listing maps here will blacklist them from generating in space.
-#Maps must be the full path to them
-#Maps valid to be blacklisted can be found in _maps/map_files/RandomRuins/SpaceRuins
-#SPECIFYING AN INVALID MAP WILL RESULT IN RUNTIMES ON GAME START
-
-#_maps/map_files/RandomRuins/SpaceRuins/way_home.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/asteroid1.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/asteroid2.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/asteroid3.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/asteroid4.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/asteroid5.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/derelict1.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/derelict2.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/derelict3.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/derelict4.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/derelict5.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/spacebar.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/deepstorage.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/emptyshell.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/gasthelizards.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/intactemptyship.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/mechtransport.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/turretedoutpost.dmm
-
-### The following ruins are based from past pre-spawned Zlevel content ###
-
-#_maps/map_files/RandomRuins/SpaceRuins/abandonedtele.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/blowntcommsat.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/clownmime.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/dj.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/druglab.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/syndiedepot.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/syndie_space_base.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/ussp_tele.dmm
-#_maps/map_files/RandomRuins/SpaceRuins/ussp.dmm
-
-
-# The following is the white ship ruin. Its force-spawned and is required to stop SSshuttle runtiming on startup
-# Its also important incase a white-ship console is ever built midround
-# DO NOT DISABLE THIS UNLESS YOU HAVE A GOOD REASON
-#_maps/map_files/RandomRuins/SpaceRuins/whiteship.dmm
-
-# The following is a force-spawned ruin consisting mostly of empty space with a shuttle docking port for the free golem shuttle
-# Disabling it will lead to the free golem shuttle sometimes being stuck on lavaland.
-#_maps/map_files/RandomRuins/SpaceRuins/golemtarget.dmm
\ No newline at end of file
diff --git a/interface/interface.dm b/interface/interface.dm
index 6038bd4af7b..ebb73e820a9 100644
--- a/interface/interface.dm
+++ b/interface/interface.dm
@@ -3,12 +3,12 @@
set name = "wiki"
set desc = "Type what you want to know about. This will open the wiki in your web browser."
set hidden = 1
- if(config.wikiurl)
+ if(GLOB.configuration.url.wiki_url)
var/query = stripped_input(src, "Enter Search:", "Wiki Search", "Homepage")
if(query == "Homepage")
- src << link(config.wikiurl)
+ src << link(GLOB.configuration.url.wiki_url)
else if(query)
- var/output = config.wikiurl + "/index.php?title=Special%3ASearch&profile=default&search=" + query
+ var/output = "[GLOB.configuration.url.wiki_url]/index.php?title=Special%3ASearch&profile=default&search=[query]"
src << link(output)
else
to_chat(src, "The wiki URL is not set in the server configuration.")
@@ -18,11 +18,11 @@
set name = "forum"
set desc = "Visit the forum."
set hidden = 1
- if(config.forumurl)
+ if(GLOB.configuration.url.forum_url)
if(alert("Open the forum in your browser?", null, "Yes", "No") == "Yes")
- if(config.forum_link_url && prefs && !prefs.fuid)
+ if(GLOB.configuration.url.forum_link_url && prefs && !prefs.fuid)
link_forum_account()
- src << link(config.forumurl)
+ src << link(GLOB.configuration.url.forum_url)
else
to_chat(src, "The forum URL is not set in the server configuration.")
@@ -30,10 +30,10 @@
set name = "Rules"
set desc = "View the server rules."
set hidden = 1
- if(config.rulesurl)
+ if(GLOB.configuration.url.rules_url)
if(alert("This will open the rules in your browser. Are you sure?", null, "Yes", "No") == "No")
return
- src << link(config.rulesurl)
+ src << link(GLOB.configuration.url.rules_url)
else
to_chat(src, "The rules URL is not set in the server configuration.")
@@ -41,10 +41,10 @@
set name = "GitHub"
set desc = "Visit the GitHub page."
set hidden = 1
- if(config.githuburl)
+ if(GLOB.configuration.url.github_url)
if(alert("This will open our GitHub repository in your browser. Are you sure?", null, "Yes", "No") == "No")
return
- src << link(config.githuburl)
+ src << link(GLOB.configuration.url.github_url)
else
to_chat(src, "The GitHub URL is not set in the server configuration.")
@@ -53,9 +53,15 @@
set desc = "Join our Discord server."
set hidden = 1
- var/durl = config.discordurl
- if(config.forum_link_url && prefs && prefs.fuid && config.discordforumurl)
- durl = config.discordforumurl
+ var/durl
+ // Use normal URL
+ if(GLOB.configuration.url.discord_url)
+ durl = GLOB.configuration.url.discord_url
+
+ // Use forums URL if set
+ if(GLOB.configuration.url.forum_link_url && GLOB.configuration?.url.discord_forum_url && prefs?.fuid)
+ durl = GLOB.configuration.url.discord_forum_url
+
if(!durl)
to_chat(src, "The Discord URL is not set in the server configuration.")
return
@@ -67,10 +73,10 @@
set name = "Donate"
set desc = "Donate to help with hosting costs."
set hidden = 1
- if(config.donationsurl)
+ if(GLOB.configuration.url.donations_url)
if(alert("This will open the donation page in your browser. Are you sure?", null, "Yes", "No") == "No")
return
- src << link(config.donationsurl)
+ src << link(GLOB.configuration.url.donations_url)
else
to_chat(src, "The rules URL is not set in the server configuration.")
diff --git a/librust_g.so b/librust_g.so
index 6587d39c0a2..1f059e0b2ce 100644
Binary files a/librust_g.so and b/librust_g.so differ
diff --git a/paradise.dme b/paradise.dme
index 7fc54e9024f..02f5c19c020 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -132,7 +132,6 @@
#include "code\_globalvars\logging.dm"
#include "code\_globalvars\mapping.dm"
#include "code\_globalvars\misc.dm"
-#include "code\_globalvars\sensitive.dm"
#include "code\_globalvars\traits.dm"
#include "code\_globalvars\lists\flavor_misc.dm"
#include "code\_globalvars\lists\fortunes.dm"
@@ -178,13 +177,33 @@
#include "code\_onclick\hud\screen_objects.dm"
#include "code\_onclick\hud\slime.dm"
#include "code\_onclick\hud\swarmer.dm"
-#include "code\controllers\configuration.dm"
#include "code\controllers\controller.dm"
#include "code\controllers\failsafe.dm"
#include "code\controllers\globals.dm"
#include "code\controllers\master.dm"
#include "code\controllers\subsystem.dm"
#include "code\controllers\verbs.dm"
+#include "code\controllers\configuration\__config_defines.dm"
+#include "code\controllers\configuration\configuration_core.dm"
+#include "code\controllers\configuration\sections\admin_configuration.dm"
+#include "code\controllers\configuration\sections\afk_configuration.dm"
+#include "code\controllers\configuration\sections\custom_sprites_configuration.dm"
+#include "code\controllers\configuration\sections\database_configuration.dm"
+#include "code\controllers\configuration\sections\discord_configuration.dm"
+#include "code\controllers\configuration\sections\event_configuration.dm"
+#include "code\controllers\configuration\sections\gamemode_configuration.dm"
+#include "code\controllers\configuration\sections\gateway_configuration.dm"
+#include "code\controllers\configuration\sections\general_configuration.dm"
+#include "code\controllers\configuration\sections\ipintel_configuration.dm"
+#include "code\controllers\configuration\sections\job_configuration.dm"
+#include "code\controllers\configuration\sections\logging_configuration.dm"
+#include "code\controllers\configuration\sections\mc_configuration.dm"
+#include "code\controllers\configuration\sections\movement_configuration.dm"
+#include "code\controllers\configuration\sections\overflow_configuration.dm"
+#include "code\controllers\configuration\sections\ruin_configuration.dm"
+#include "code\controllers\configuration\sections\system_configuration.dm"
+#include "code\controllers\configuration\sections\url_configuration.dm"
+#include "code\controllers\configuration\sections\vote_configuration.dm"
#include "code\controllers\subsystem\acid.dm"
#include "code\controllers\subsystem\afk.dm"
#include "code\controllers\subsystem\air.dm"
diff --git a/rust_g.dll b/rust_g.dll
index bb414674e2e..ed4ac5bc38b 100644
Binary files a/rust_g.dll and b/rust_g.dll differ
diff --git a/tools/ci/dbconfig.txt b/tools/ci/dbconfig.txt
deleted file mode 100644
index f3a4b587962..00000000000
--- a/tools/ci/dbconfig.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-# This exists solely as a DBconfig file for CI testing
-# Dont use it ingame
-# Remember to update this when you increase the SQL version! -aa
-SQL_ENABLED
-DB_VERSION 24
-ADDRESS 127.0.0.1
-PORT 3306
-FEEDBACK_DATABASE feedback
-FEEDBACK_TABLEPREFIX
-FEEDBACK_LOGIN root
-FEEDBACK_PASSWORD root
-ASYNC_QUERY_TIMEOUT 10
-RUST_SQL_THREAD_LIMIT 50
diff --git a/tools/ci/run_server.sh b/tools/ci/run_server.sh
index c03809363c1..bb32d85f940 100755
--- a/tools/ci/run_server.sh
+++ b/tools/ci/run_server.sh
@@ -1,13 +1,7 @@
#!/bin/bash
set -euo pipefail
-cp config/example/* config/
-
-#Apply test DB config for SQL connectivity
-rm config/dbconfig.txt
-cp tools/ci/dbconfig.txt config
-
-# Now run the server and the unit tests
+# Run the server and the unit tests
DreamDaemon paradise.dmb -close -trusted -verbose
# Check if the unit tests actually suceeded
diff --git a/tools/ci/validate_rustg_windows.py b/tools/ci/validate_rustg_windows.py
index 3d4535484ed..787bafb9a60 100644
--- a/tools/ci/validate_rustg_windows.py
+++ b/tools/ci/validate_rustg_windows.py
@@ -3,13 +3,14 @@
# This script is invoked by GitHub actions as part of CI to validate that the windows DLL for RUSTG works and creates proper formats
# Imports
-import os, sys
+import os, json
from ctypes import *
from datetime import datetime, timedelta
# Initial vars
ci_log_file = "ci_log.log"
ci_testing_text = "This is a test message"
+ci_toml_file_location = "config/example/config.toml"
# Helpers
def success(msg):
@@ -88,4 +89,19 @@ if logline in valid_results:
else:
fail("Log timestamp is not valid 8601. Got {}".format(logline))
+# Make sure we can parse TOML
+string_array = c_char_p * 1
+sa = string_array(bytes(ci_toml_file_location, "ascii"))
+rustg_dll.toml2json.argtypes = [c_int, c_char_p * 1]
+# Set args for JSON retrieval
+rustg_dll.toml2json.restype = c_char_p
+
+try:
+ # Run it
+ output_json = rustg_dll.toml2json(1, sa).decode()
+ json.loads(output_json)
+ success("toml2json conversion successful")
+except Exception:
+ fail("Failed to convert toml2json")
+
exit(0) # Success