mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-12 07:33:34 +01:00
Merge branch 'master' into ghost-rad-hud
This commit is contained in:
@@ -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, "<span class='boldannounce'>Config reload blocked: Advanced ProcCall detected.</span>")
|
||||
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, "<span class='boldannounce'>SQL configuration reload blocked: Advanced ProcCall detected.</span>")
|
||||
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")
|
||||
@@ -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\
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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"])
|
||||
@@ -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"]
|
||||
@@ -0,0 +1,43 @@
|
||||
/// 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 = "paradise_gamedb"
|
||||
/// 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
|
||||
// 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_NUM(async_query_timeout, data["async_query_timeout"])
|
||||
CONFIG_LOAD_NUM(async_thread_limit, data["async_thread_limit"])
|
||||
#endif
|
||||
@@ -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"])
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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"])
|
||||
@@ -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"])
|
||||
@@ -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"])
|
||||
@@ -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"]
|
||||
@@ -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"])
|
||||
@@ -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"])
|
||||
@@ -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"])
|
||||
@@ -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"])
|
||||
@@ -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"])
|
||||
@@ -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"])
|
||||
@@ -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"])
|
||||
@@ -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"])
|
||||
@@ -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)
|
||||
|
||||
@@ -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, "<span class='danger'>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.</span>")
|
||||
warn(H, "<span class='danger'>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.</span>")
|
||||
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, "<span class='danger'>You have been despawned after being AFK for [mins_afk] minutes. You have been despawned instantly due to you being in a secure area.</span>")
|
||||
@@ -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, "<span class='danger'>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.</span>")
|
||||
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, "<span class='danger'>You have been despawned after being AFK for [mins_afk] minutes.</span>")
|
||||
toRemove += H.ckey
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SUBSYSTEM_DEF(alarm)
|
||||
name = "Alarm"
|
||||
flags = SS_NO_INIT | SS_NO_FIRE
|
||||
var/list/alarms = list("Motion" = list(), "Fire" = list(), "Atmosphere" = list(), "Power" = list(), "Camera" = list(), "Burglar" = list())
|
||||
var/list/alarms = list("Motion" = list(), "Fire" = list(), "Atmosphere" = list(), "Power" = list(), "Burglar" = list())
|
||||
|
||||
/datum/controller/subsystem/alarm/proc/triggerAlarm(class, area/A, list/O, obj/alarmsource)
|
||||
var/list/L = alarms[class]
|
||||
|
||||
@@ -65,7 +65,7 @@ SUBSYSTEM_DEF(blackbox)
|
||||
sqlversion = versions[FV.key]
|
||||
|
||||
var/datum/db_query/query_feedback_save = SSdbcore.NewQuery({"
|
||||
INSERT IGNORE INTO [format_table_name("feedback")] (datetime, round_id, key_name, key_type, version, json)
|
||||
INSERT IGNORE INTO feedback (datetime, round_id, key_name, key_type, version, json)
|
||||
VALUES (NOW(), :rid, :keyname, :keytype, :version, :json)"}, list(
|
||||
"rid" = text2num(GLOB.round_id),
|
||||
"keyname" = FV.key,
|
||||
@@ -287,7 +287,7 @@ SUBSYSTEM_DEF(blackbox)
|
||||
lakey = L.lastattackerckey
|
||||
|
||||
var/datum/db_query/deathquery = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord)
|
||||
INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord)
|
||||
VALUES (:name, :key, :job, :special, :pod, NOW(), :laname, :lakey, :gender, :bruteloss, :fireloss, :brainloss, :oxyloss, :coord)"},
|
||||
list(
|
||||
"name" = L.real_name,
|
||||
|
||||
@@ -24,7 +24,7 @@ SUBSYSTEM_DEF(changelog)
|
||||
if(!SSdbcore.IsConnected())
|
||||
return ..()
|
||||
|
||||
var/datum/db_query/latest_cl_date = SSdbcore.NewQuery("SELECT CAST(UNIX_TIMESTAMP(date_merged) AS CHAR) AS ut FROM [format_table_name("changelog")] ORDER BY date_merged DESC LIMIT 1")
|
||||
var/datum/db_query/latest_cl_date = SSdbcore.NewQuery("SELECT CAST(UNIX_TIMESTAMP(date_merged) AS CHAR) AS ut FROM changelog ORDER BY date_merged DESC LIMIT 1")
|
||||
if(!latest_cl_date.warn_execute())
|
||||
qdel(latest_cl_date)
|
||||
// Abort if we cant do this
|
||||
@@ -63,7 +63,7 @@ SUBSYSTEM_DEF(changelog)
|
||||
C.prefs.lastchangelog = current_cl_timestamp
|
||||
|
||||
var/datum/db_query/updatePlayerCLTime = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("player")] SET lastchangelog=:lastchangelog WHERE ckey=:ckey",
|
||||
"UPDATE player SET lastchangelog=:lastchangelog WHERE ckey=:ckey",
|
||||
list(
|
||||
"lastchangelog" = current_cl_timestamp,
|
||||
"ckey" = C.ckey
|
||||
@@ -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, "<span class='danger'>The GitHub URL is not set in the server configuration. PRs cannot be opened from changelog view. Please inform the server host.</span>")
|
||||
|
||||
@@ -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, "<span class='boldannounce'>Database schema ([sql_version]) doesn't match the latest schema version ([SQL_VERSION]). Roundstart has been delayed.</span>")
|
||||
to_chat(world, "<span class='boldannounce'>Database schema ([GLOB.configuration.database.version]) doesn't match the latest schema version ([SQL_VERSION]). Roundstart has been delayed.</span>")
|
||||
|
||||
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")
|
||||
@@ -142,7 +142,7 @@ SUBSYSTEM_DEF(dbcore)
|
||||
//This is as close as we can get to the true round end before Disconnect() without changing where it's called, defeating the reason this is a subsystem
|
||||
if(SSdbcore.Connect())
|
||||
var/datum/db_query/query_round_shutdown = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("round")] SET shutdown_datetime = Now(), end_state = :end_state WHERE id = :round_id",
|
||||
"UPDATE round SET shutdown_datetime = Now(), end_state = :end_state WHERE id = :round_id",
|
||||
list("end_state" = SSticker.end_state, "round_id" = GLOB.round_id)
|
||||
)
|
||||
query_round_shutdown.Execute()
|
||||
@@ -160,7 +160,7 @@ SUBSYSTEM_DEF(dbcore)
|
||||
if(!IsConnected())
|
||||
return
|
||||
var/datum/db_query/query_round_initialize = SSdbcore.NewQuery(
|
||||
"INSERT INTO [format_table_name("round")] (initialize_datetime, server_ip, server_port) VALUES (Now(), INET_ATON(:internet_address), :port)",
|
||||
"INSERT INTO round (initialize_datetime, server_ip, server_port) VALUES (Now(), INET_ATON(:internet_address), :port)",
|
||||
list("internet_address" = world.internet_address || "0", "port" = "[world.port]")
|
||||
)
|
||||
query_round_initialize.Execute(async = FALSE)
|
||||
@@ -177,7 +177,7 @@ SUBSYSTEM_DEF(dbcore)
|
||||
if(!IsConnected())
|
||||
return
|
||||
var/datum/db_query/query_round_start = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("round")] SET start_datetime=NOW(), commit_hash=:hash WHERE id=:round_id",
|
||||
"UPDATE round SET start_datetime=NOW(), commit_hash=:hash WHERE id=:round_id",
|
||||
list("hash" = GLOB.revision_info.commit_hash, "round_id" = GLOB.round_id)
|
||||
)
|
||||
query_round_start.Execute(async = FALSE) // This happens during a time of intense server lag, so should be non-async
|
||||
@@ -193,7 +193,7 @@ SUBSYSTEM_DEF(dbcore)
|
||||
if(!IsConnected())
|
||||
return
|
||||
var/datum/db_query/query_round_end = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("round")] SET end_datetime = Now(), game_mode_result = :game_mode_result WHERE id = :round_id",
|
||||
"UPDATE round SET end_datetime = Now(), game_mode_result = :game_mode_result WHERE id = :round_id",
|
||||
list("game_mode_result" = SSticker.mode_result, "station_name" = station_name(), "round_id" = GLOB.round_id)
|
||||
)
|
||||
query_round_end.Execute()
|
||||
@@ -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, "<span class='warning'>The Database is not enabled in the server configuration!</span>")
|
||||
return
|
||||
|
||||
|
||||
@@ -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 ""
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -3,13 +3,374 @@ SUBSYSTEM_DEF(ipintel)
|
||||
wait = 1
|
||||
flags = SS_NO_FIRE
|
||||
init_order = INIT_ORDER_XKEYSCORE // 10
|
||||
var/enabled = 0 //disable at round start to avoid checking reconnects
|
||||
// Are we enabled? Auto disable at world init to avoid checking reconnects
|
||||
var/enabled = FALSE
|
||||
var/throttle = 0
|
||||
var/errors = 0
|
||||
|
||||
var/list/cache = list()
|
||||
|
||||
/datum/controller/subsystem/ipintel/Initialize(timeofday, zlevel)
|
||||
enabled = 1
|
||||
. = ..()
|
||||
/datum/controller/subsystem/ipintel/Initialize(timeofday)
|
||||
enabled = TRUE
|
||||
return ..()
|
||||
|
||||
|
||||
// Represents an IP intel holder datum
|
||||
/datum/ipintel
|
||||
/// The IP being checked
|
||||
var/ip
|
||||
/// The current rating, 0-1 float.
|
||||
var/intel = 0
|
||||
/// Whether this was loaded from the cache or not
|
||||
var/cache = FALSE
|
||||
/// How many minutes ago it was cached
|
||||
var/cacheminutesago = 0
|
||||
/// The date it was cached
|
||||
var/cachedate = ""
|
||||
/// The real time it was cached
|
||||
var/cacherealtime = 0
|
||||
|
||||
/datum/ipintel/New()
|
||||
cachedate = SQLtime()
|
||||
cacherealtime = world.realtime
|
||||
|
||||
/datum/ipintel/proc/is_valid()
|
||||
. = FALSE
|
||||
if(intel < 0)
|
||||
return
|
||||
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 + (GLOB.configuration.ipintel.hours_save_bad HOURS))
|
||||
return TRUE
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get IP intel
|
||||
*
|
||||
* Performs a lookup of the rating for an IP provided
|
||||
*
|
||||
* Arguments:
|
||||
* * ip - The IP to lookup
|
||||
* * bypasscache - Do we want to bypass the DB cache?
|
||||
* * updatecache - Do we want to update the DB cache?
|
||||
*/
|
||||
/datum/controller/subsystem/ipintel/proc/get_ip_intel(ip, bypasscache = FALSE, updatecache = TRUE)
|
||||
var/datum/ipintel/res = new()
|
||||
res.ip = ip
|
||||
. = res
|
||||
if(!ip || !GLOB.configuration.ipintel.contact_email || !GLOB.configuration.ipintel.enabled || !enabled)
|
||||
return
|
||||
if(!bypasscache)
|
||||
var/datum/ipintel/cachedintel = cache[ip]
|
||||
if(cachedintel && cachedintel.is_valid())
|
||||
cachedintel.cache = TRUE
|
||||
return cachedintel
|
||||
|
||||
if(SSdbcore.IsConnected())
|
||||
var/datum/db_query/query_get_ip_intel = SSdbcore.NewQuery({"
|
||||
SELECT date, intel, TIMESTAMPDIFF(MINUTE,date,NOW())
|
||||
FROM ipintel
|
||||
WHERE
|
||||
ip = INET_ATON(:ip)
|
||||
AND ((
|
||||
intel < :rating_bad
|
||||
AND
|
||||
date + INTERVAL :save_good HOUR > NOW()
|
||||
) OR (
|
||||
intel >= :rating_bad
|
||||
AND
|
||||
date + INTERVAL :save_bad HOUR > NOW()
|
||||
))
|
||||
"}, list(
|
||||
"ip" = ip,
|
||||
"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)
|
||||
return
|
||||
if(query_get_ip_intel.NextRow())
|
||||
res.cache = TRUE
|
||||
res.cachedate = query_get_ip_intel.item[1]
|
||||
res.intel = text2num(query_get_ip_intel.item[2])
|
||||
res.cacheminutesago = text2num(query_get_ip_intel.item[3])
|
||||
res.cacherealtime = world.realtime - (text2num(query_get_ip_intel.item[3])*10*60)
|
||||
cache[ip] = res
|
||||
qdel(query_get_ip_intel)
|
||||
return
|
||||
qdel(query_get_ip_intel)
|
||||
res.intel = ip_intel_query(ip)
|
||||
if(updatecache && res.intel >= 0)
|
||||
cache[ip] = res
|
||||
if(SSdbcore.IsConnected())
|
||||
var/datum/db_query/query_add_ip_intel = SSdbcore.NewQuery({"
|
||||
INSERT INTO ipintel (ip, intel) VALUES (INET_ATON(:ip), :intel)
|
||||
ON DUPLICATE KEY UPDATE intel = VALUES(intel), date = NOW()"},
|
||||
list(
|
||||
"ip" = ip,
|
||||
"intel" = res.intel
|
||||
)
|
||||
)
|
||||
query_add_ip_intel.warn_execute()
|
||||
qdel(query_add_ip_intel)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Performs the remote IPintel lookup
|
||||
*
|
||||
*
|
||||
*
|
||||
* Arguments:
|
||||
* * ip - The IP to lookup
|
||||
* * retried - Was this attempt retried?
|
||||
*/
|
||||
/datum/controller/subsystem/ipintel/proc/ip_intel_query(ip, retried = FALSE)
|
||||
. = -1 //default
|
||||
if(!ip)
|
||||
return
|
||||
if(throttle > world.timeofday)
|
||||
return
|
||||
if(!enabled)
|
||||
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://[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"])
|
||||
|
||||
if(status == 200)
|
||||
var/response = json_decode(file2text(http["CONTENT"]))
|
||||
if(response)
|
||||
if(response["status"] == "success")
|
||||
var/intelnum = text2num(response["result"])
|
||||
if(isnum(intelnum))
|
||||
return text2num(response["result"])
|
||||
else
|
||||
ipintel_handle_error("Bad intel from server: [response["result"]].", ip, retried)
|
||||
if(!retried)
|
||||
sleep(25)
|
||||
return .(ip, 1)
|
||||
else
|
||||
ipintel_handle_error("Bad response from server: [response["status"]].", ip, retried)
|
||||
if(!retried)
|
||||
sleep(25)
|
||||
return .(ip, 1)
|
||||
|
||||
else if(status == 429)
|
||||
ipintel_handle_error("Error #429: We have exceeded the rate limit.", ip, 1)
|
||||
return
|
||||
else
|
||||
ipintel_handle_error("Unknown status code: [status].", ip, retried)
|
||||
if(!retried)
|
||||
sleep(25)
|
||||
return .(ip, 1)
|
||||
else
|
||||
ipintel_handle_error("Unable to connect to API.", ip, retried)
|
||||
if(!retried)
|
||||
sleep(25)
|
||||
return .(ip, 1)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Error handler
|
||||
*
|
||||
* Handles an IP intel error, also throttling the susbystem if required
|
||||
*
|
||||
* Arguments:
|
||||
* * error - The error description
|
||||
* * ip - The IP that was tried
|
||||
* * retried - Was this on a retried attempt
|
||||
*/
|
||||
/datum/controller/subsystem/ipintel/proc/ipintel_handle_error(error, ip, retried)
|
||||
if(retried)
|
||||
errors++
|
||||
error += " Could not check [ip]. Disabling IPINTEL for [errors] minute[(errors == 1 ? "" : "s")]"
|
||||
throttle = world.timeofday + (2 * errors MINUTES)
|
||||
else
|
||||
error += " Attempting retry on [ip]."
|
||||
log_ipintel(error)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Logs an IPintel error
|
||||
*
|
||||
* Pretty self explanatory. Logs errors regarding ipintel.
|
||||
*
|
||||
* Arguments:
|
||||
* * text - Argument 1
|
||||
*/
|
||||
/datum/controller/subsystem/ipintel/proc/log_ipintel(text)
|
||||
log_game("IPINTEL: [text]")
|
||||
log_debug("IPINTEL: [text]")
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* IPIntel Ban Checker
|
||||
*
|
||||
* Checks if a user is banned due to IPintel. It will check configuration, DB, whitelist checks, and more
|
||||
*
|
||||
* Arguments:
|
||||
* * t_ckey - The ckey to check
|
||||
* * t_ip - The IP to check
|
||||
*/
|
||||
/datum/controller/subsystem/ipintel/proc/ipintel_is_banned(t_ckey, t_ip)
|
||||
if(!GLOB.configuration.ipintel.contact_email)
|
||||
return FALSE
|
||||
if(!GLOB.configuration.ipintel.enabled)
|
||||
return FALSE
|
||||
if(!GLOB.configuration.ipintel.whitelist_mode)
|
||||
return FALSE
|
||||
if(!SSdbcore.IsConnected())
|
||||
return FALSE
|
||||
if(!ipintel_badip_check(t_ip))
|
||||
return FALSE
|
||||
if(vpn_whitelist_check(t_ckey))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* IP Rating Checker
|
||||
*
|
||||
* Checks if a provided IP passes the config threshold for denial
|
||||
*
|
||||
* Arguments:
|
||||
* * target_ip - The IP to check
|
||||
*/
|
||||
/datum/controller/subsystem/ipintel/proc/ipintel_badip_check(target_ip)
|
||||
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 = GLOB.configuration.ipintel.hours_save_bad
|
||||
if(!valid_hours)
|
||||
log_debug("ipintel_badip_check reports misconfigured ipintel_save_bad directive")
|
||||
return FALSE
|
||||
var/datum/db_query/query_get_ip_intel = SSdbcore.NewQuery({"
|
||||
SELECT * FROM ipintel WHERE ip = INET_ATON(:target_ip)
|
||||
AND intel >= :rating_bad AND (date + INTERVAL :valid_hours HOUR) > NOW()"},
|
||||
list(
|
||||
"target_ip" = target_ip,
|
||||
"rating_bad" = rating_bad,
|
||||
"valid_hours" = valid_hours
|
||||
)
|
||||
)
|
||||
if(!query_get_ip_intel.warn_execute())
|
||||
log_debug("ipintel_badip_check reports failed query execution")
|
||||
qdel(query_get_ip_intel)
|
||||
return FALSE
|
||||
if(!query_get_ip_intel.NextRow())
|
||||
qdel(query_get_ip_intel)
|
||||
return FALSE
|
||||
qdel(query_get_ip_intel)
|
||||
return TRUE
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* VPN whitelist checker
|
||||
*
|
||||
* Checks if a ckey is whitelisted to be using a VPN against the DB
|
||||
*
|
||||
* Arguments:
|
||||
* * target_ckey - The ckey to check
|
||||
*/
|
||||
/datum/controller/subsystem/ipintel/proc/vpn_whitelist_check(target_ckey)
|
||||
if(!GLOB.configuration.ipintel.whitelist_mode)
|
||||
return FALSE
|
||||
var/datum/db_query/query_whitelist_check = SSdbcore.NewQuery("SELECT * FROM vpn_whitelist WHERE ckey=:ckey", list(
|
||||
"ckey" = target_ckey
|
||||
))
|
||||
if(!query_whitelist_check.warn_execute())
|
||||
qdel(query_whitelist_check)
|
||||
return FALSE
|
||||
if(query_whitelist_check.NextRow())
|
||||
qdel(query_whitelist_check)
|
||||
return TRUE // At least one row in the whitelist names their ckey. That means they are whitelisted.
|
||||
qdel(query_whitelist_check)
|
||||
return FALSE
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* VPN whitelist adder
|
||||
*
|
||||
* Adds a ckey to the VPN whitelist. Asks the admin to also provide a link to their request.
|
||||
*
|
||||
* Arguments:
|
||||
* * target_ckey - The ckey to whitelist
|
||||
*/
|
||||
/datum/controller/subsystem/ipintel/proc/vpn_whitelist_add(target_ckey)
|
||||
var/reason_string = input(usr, "Enter link to the URL of their whitelist request on the forum.","Reason required") as message|null
|
||||
if(!reason_string)
|
||||
return FALSE
|
||||
var/datum/db_query/query_whitelist_add = SSdbcore.NewQuery("INSERT INTO vpn_whitelist (ckey,reason) VALUES (:targetckey, :reason)", list(
|
||||
"targetckey" = target_ckey,
|
||||
"reason" = reason_string
|
||||
))
|
||||
if(!query_whitelist_add.warn_execute())
|
||||
qdel(query_whitelist_add)
|
||||
return FALSE
|
||||
qdel(query_whitelist_add)
|
||||
return TRUE
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* VPN whitelist remover
|
||||
*
|
||||
* Removes a ckey from the VPN whitelist. Pretty simple.
|
||||
*
|
||||
* Arguments:
|
||||
* * target_ckey - The ckey to remove
|
||||
*/
|
||||
/datum/controller/subsystem/ipintel/proc/vpn_whitelist_remove(target_ckey)
|
||||
var/datum/db_query/query_whitelist_remove = SSdbcore.NewQuery("DELETE FROM vpn_whitelist WHERE ckey=:targetckey", list(
|
||||
"targetckey" = target_ckey
|
||||
))
|
||||
if(!query_whitelist_remove.warn_execute())
|
||||
qdel(query_whitelist_remove)
|
||||
return FALSE
|
||||
qdel(query_whitelist_remove)
|
||||
return TRUE
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* VPN whitelist panel
|
||||
*
|
||||
* Doesnt actually open a panel, this is just a verb to handle the rest of the whitelist operations
|
||||
*
|
||||
* Arguments:
|
||||
* * target_ckey - The ckey to add/remove
|
||||
*/
|
||||
/datum/controller/subsystem/ipintel/proc/vpn_whitelist_panel(target_ckey as text)
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
if(!target_ckey)
|
||||
return
|
||||
var/is_already_whitelisted = vpn_whitelist_check(target_ckey)
|
||||
if(is_already_whitelisted)
|
||||
var/confirm = alert("[target_ckey] is already whitelisted. Remove them?", "Confirm Removal", "No", "Yes")
|
||||
if(!confirm || confirm != "Yes")
|
||||
to_chat(usr, "VPN whitelist alteration cancelled.")
|
||||
return
|
||||
else if(vpn_whitelist_remove(target_ckey))
|
||||
to_chat(usr, "[target_ckey] was removed from the VPN whitelist.")
|
||||
else
|
||||
to_chat(usr, "VPN whitelist unchanged.")
|
||||
else
|
||||
if(vpn_whitelist_add(target_ckey))
|
||||
to_chat(usr, "[target_ckey] was added to the VPN whitelist.")
|
||||
else
|
||||
to_chat(usr, "VPN whitelist unchanged.")
|
||||
|
||||
@@ -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()
|
||||
@@ -750,7 +740,7 @@ SUBSYSTEM_DEF(jobs)
|
||||
continue // If a client logs out in the middle of this
|
||||
|
||||
var/datum/db_query/exp_read = SSdbcore.NewQuery(
|
||||
"SELECT exp FROM [format_table_name("player")] WHERE ckey=:ckey",
|
||||
"SELECT exp FROM player WHERE ckey=:ckey",
|
||||
list("ckey" = C.ckey)
|
||||
)
|
||||
|
||||
@@ -834,7 +824,7 @@ SUBSYSTEM_DEF(jobs)
|
||||
C.prefs.exp = new_exp
|
||||
|
||||
var/datum/db_query/update_query = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("player")] SET exp =:newexp, lastseen=NOW() WHERE ckey=:ckey",
|
||||
"UPDATE player SET exp =:newexp, lastseen=NOW() WHERE ckey=:ckey",
|
||||
list(
|
||||
"newexp" = new_exp,
|
||||
"ckey" = C.ckey
|
||||
@@ -844,7 +834,7 @@ SUBSYSTEM_DEF(jobs)
|
||||
player_update_queries += update_query
|
||||
|
||||
var/datum/db_query/update_query_history = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("playtime_history")] (ckey, date, time_living, time_ghost)
|
||||
INSERT INTO playtime_history (ckey, date, time_living, time_ghost)
|
||||
VALUES (:ckey, CURDATE(), :addedliving, :addedghost)
|
||||
ON DUPLICATE KEY UPDATE time_living=time_living + VALUES(time_living), time_ghost=time_ghost + VALUES(time_ghost)"},
|
||||
list(
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -6,6 +6,10 @@ SUBSYSTEM_DEF(mapping)
|
||||
var/datum/map/map_datum
|
||||
/// What map will be used next round
|
||||
var/datum/map/next_map
|
||||
/// List of all areas that can be accessed via IC means
|
||||
var/list/teleportlocs
|
||||
/// List of all areas that can be accessed via IC and OOC means
|
||||
var/list/ghostteleportlocs
|
||||
|
||||
// This has to be here because world/New() uses [station_name()], which looks this datum up
|
||||
/datum/controller/subsystem/mapping/PreInit()
|
||||
@@ -40,11 +44,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,35 +61,37 @@ 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
|
||||
teleportlocs = list()
|
||||
for(var/area/AR in world)
|
||||
if(AR.no_teleportlocs)
|
||||
continue
|
||||
if(GLOB.teleportlocs[AR.name])
|
||||
if(teleportlocs[AR.name])
|
||||
continue
|
||||
var/turf/picked = safepick(get_area_turfs(AR.type))
|
||||
if(picked && is_station_level(picked.z))
|
||||
GLOB.teleportlocs[AR.name] = AR
|
||||
teleportlocs[AR.name] = AR
|
||||
|
||||
GLOB.teleportlocs = sortAssoc(GLOB.teleportlocs)
|
||||
teleportlocs = sortAssoc(teleportlocs)
|
||||
|
||||
|
||||
ghostteleportlocs = list()
|
||||
for(var/area/AR in world)
|
||||
if(GLOB.ghostteleportlocs[AR.name])
|
||||
if(ghostteleportlocs[AR.name])
|
||||
continue
|
||||
var/list/turfs = get_area_turfs(AR.type)
|
||||
if(turfs.len)
|
||||
GLOB.ghostteleportlocs[AR.name] = AR
|
||||
ghostteleportlocs[AR.name] = AR
|
||||
|
||||
GLOB.ghostteleportlocs = sortAssoc(GLOB.ghostteleportlocs)
|
||||
ghostteleportlocs = sortAssoc(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 +102,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.")
|
||||
@@ -128,7 +134,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
if(!SSdbcore.IsConnected())
|
||||
return
|
||||
var/datum/db_query/query_set_map = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("round")] SET start_datetime=NOW(), map_name=:mapname, station_name=:stationname WHERE id=:round_id",
|
||||
"UPDATE round SET start_datetime=NOW(), map_name=:mapname, station_name=:stationname WHERE id=:round_id",
|
||||
list("mapname" = map_datum.technical_name, "stationname" = map_datum.fluff_name, "round_id" = GLOB.round_id)
|
||||
)
|
||||
query_set_map.Execute(async = FALSE) // This happens during a time of intense server lag, so should be non-async
|
||||
@@ -230,11 +236,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))
|
||||
|
||||
@@ -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]!")
|
||||
|
||||
@@ -9,6 +9,8 @@ SUBSYSTEM_DEF(mobs)
|
||||
var/static/list/clients_by_zlevel[][]
|
||||
var/static/list/dead_players_by_zlevel[][] = list(list()) // Needs to support zlevel 1 here, MaxZChanged only happens when CC is created and new_players can login before that.
|
||||
var/static/list/cubemonkeys = list()
|
||||
/// The amount of giant spiders that exist in the world. Used for mob capping.
|
||||
var/giant_spiders = 0
|
||||
|
||||
/datum/controller/subsystem/mobs/stat_entry()
|
||||
..("P:[GLOB.mob_living_list.len]")
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
@@ -18,7 +18,7 @@ SUBSYSTEM_DEF(statistics)
|
||||
return
|
||||
else
|
||||
var/datum/db_query/statquery = SSdbcore.NewQuery(
|
||||
"INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time) VALUES (:playercount, :admincount, NOW())",
|
||||
"INSERT INTO legacy_population (playercount, admincount, time) VALUES (:playercount, :admincount, NOW())",
|
||||
list(
|
||||
"playercount" = length(GLOB.clients),
|
||||
"admincount" = length(GLOB.admins)
|
||||
|
||||
@@ -7,10 +7,12 @@ SUBSYSTEM_DEF(ticker)
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME
|
||||
offline_implications = "The game is no longer aware of when the round ends. Immediate server restart recommended."
|
||||
|
||||
/// Time the world started, relative to world.time
|
||||
/// Time the game should start, relative to world.time
|
||||
var/round_start_time = 0
|
||||
/// Time that the round started
|
||||
var/time_game_started = 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 +81,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, "<B><span class='darkmblue'>Welcome to the pre-game lobby!</span></B>")
|
||||
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 +116,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 +131,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 +151,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, "<B>Unable to choose playable game mode.</B> Reverting to pre-game lobby.")
|
||||
force_start = FALSE
|
||||
@@ -155,9 +159,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 +169,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, "<B>Unable to start [mode.name].</B> Not enough players, [mode.required_players] players needed. Reverting to pre-game lobby.")
|
||||
@@ -264,10 +268,10 @@ SUBSYSTEM_DEF(ticker)
|
||||
|
||||
SSdiscord.send2discord_simple_noadmins("**\[Info]** Round has started")
|
||||
auto_toggle_ooc(FALSE) // Turn it off
|
||||
round_start_time = world.time
|
||||
time_game_started = 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 +283,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
|
||||
|
||||
@@ -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 <a href='[config.githuburl]'>Github page</a>. 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 <a href='[config.banappeals]'>[config.banappeals]</a>"
|
||||
)
|
||||
|
||||
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 <a href='[GLOB.configuration.url.banappeals_url]'>[GLOB.configuration.url.banappeals_url]</a>"
|
||||
|
||||
if(GLOB.configuration.url.github_url)
|
||||
response_phrases["Github Issue Report"] = "To report a bug, please go to our <a href='[GLOB.configuration.url.github_url]'>Github page</a>. 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
|
||||
|
||||
@@ -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, "<b>The OOC channel has been automatically enabled due to vote end.</b>")
|
||||
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, {"<font color='purple'><b>[text]</b>
|
||||
<a href='?src=[UID()];vote=open'>Click here or type vote to place your vote.</a>
|
||||
You have [config.vote_period/10] seconds to vote.</font>"})
|
||||
You have [GLOB.configuration.vote.vote_time / 10] seconds to vote.</font>"})
|
||||
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, "<font color='red'><b>Round start has been delayed.</b></font>")
|
||||
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, "<b>The OOC channel has been automatically disabled due to a crew transfer vote.</b>")
|
||||
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, "<b>The OOC channel has been automatically disabled due to the gamemode vote.</b>")
|
||||
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, "<b>The OOC channel has been automatically disabled due to a custom vote.</b>")
|
||||
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 += "<div id='vote_div'><h2>Start a vote:</h2><hr><ul><li>"
|
||||
//restart
|
||||
if(admin || config.allow_vote_restart)
|
||||
if(admin || GLOB.configuration.vote.allow_restart_votes)
|
||||
dat += "<a href='?src=[UID()];vote=restart'>Restart</a>"
|
||||
else
|
||||
dat += "<font color='grey'>Restart (Disallowed)</font>"
|
||||
dat += "</li><li>"
|
||||
if(admin || config.allow_vote_restart)
|
||||
if(admin || GLOB.configuration.vote.allow_restart_votes)
|
||||
dat += "<a href='?src=[UID()];vote=crew_transfer'>Crew Transfer</a>"
|
||||
else
|
||||
dat += "<font color='grey'>Crew Transfer (Disallowed)</font>"
|
||||
if(admin)
|
||||
dat += "\t(<a href='?src=[UID()];vote=toggle_restart'>[config.allow_vote_restart?"Allowed":"Disallowed"]</a>)"
|
||||
dat += "\t(<a href='?src=[UID()];vote=toggle_restart'>[GLOB.configuration.vote.allow_restart_votes ? "Allowed" : "Disallowed"]</a>)"
|
||||
dat += "</li><li>"
|
||||
//gamemode
|
||||
if(admin || config.allow_vote_mode)
|
||||
if(admin || GLOB.configuration.vote.allow_mode_votes)
|
||||
dat += "<a href='?src=[UID()];vote=gamemode'>GameMode</a>"
|
||||
else
|
||||
dat += "<font color='grey'>GameMode (Disallowed)</font>"
|
||||
if(admin)
|
||||
dat += "\t(<a href='?src=[UID()];vote=toggle_gamemode'>[config.allow_vote_mode?"Allowed":"Disallowed"]</a>)"
|
||||
dat += "\t(<a href='?src=[UID()];vote=toggle_gamemode'>[GLOB.configuration.vote.allow_mode_votes ? "Allowed" : "Disallowed"]</a>)"
|
||||
|
||||
dat += "</li><li>"
|
||||
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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user