mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-27 14:07:51 +01:00
Small MC refactor (#20017)
* Small MC refactor * Order fix * Nabs tgstation/tgstation#27324 * Oops * gnarg
This commit is contained in:
@@ -4,10 +4,6 @@
|
||||
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
|
||||
/// Is this server a production server (Has higher security and requires 2FA)
|
||||
@@ -41,8 +37,6 @@
|
||||
CONFIG_LOAD_BOOL(enable_multi_instance_support, data["enable_multi_instance_support"])
|
||||
|
||||
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(api_host, data["api_host"])
|
||||
CONFIG_LOAD_STR(api_key, data["api_key"])
|
||||
|
||||
@@ -19,7 +19,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
name = "Master"
|
||||
|
||||
/// Are we processing (higher values increase the processing delay by n ticks)
|
||||
var/processing = TRUE
|
||||
var/processing = 1
|
||||
/// How many times have we ran
|
||||
var/iteration = 0
|
||||
|
||||
@@ -210,7 +210,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
if(init_sss)
|
||||
init_subtypes(/datum/controller/subsystem, subsystems)
|
||||
|
||||
to_chat(world, "<span class='boldannounce'>Initializing subsystems...</span>")
|
||||
log_startup_progress("Initializing subsystems...")
|
||||
|
||||
// Sort subsystems by init_order, so they initialize in the correct order.
|
||||
sortTim(subsystems, /proc/cmp_subsystem_init)
|
||||
@@ -221,8 +221,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
for(var/datum/controller/subsystem/SS in subsystems)
|
||||
if(SS.flags & SS_NO_INIT)
|
||||
continue
|
||||
SS.log_startup_progress("Initializing...")
|
||||
SS.Initialize(REALTIMEOFDAY)
|
||||
SS.call_init(REALTIMEOFDAY)
|
||||
CHECK_TICK
|
||||
current_ticklimit = TICK_LIMIT_RUNNING
|
||||
var/time = (REALTIMEOFDAY - start_timeofday) / 10
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
/// What are the implications of this SS being offlined?
|
||||
var/offline_implications = "None. No immediate action is needed."
|
||||
|
||||
/// Tab to display in under the MC subtabs
|
||||
var/cpu_display = SS_CPUDISPLAY_DEFAULT
|
||||
|
||||
/// Order of initialization. Higher numbers are initialized first, lower numbers later. Use or create defines such as [INIT_ORDER_DEFAULT] so we can see the order in one file.
|
||||
var/init_order = INIT_ORDER_DEFAULT
|
||||
|
||||
@@ -91,6 +94,9 @@
|
||||
/// Priority at the time the subsystem entered the queue. Needed to avoid changes in priority (by admins and the like) from breaking things.
|
||||
var/queued_priority
|
||||
|
||||
/// Amount of times the subsystem has slept during fire()
|
||||
var/fire_sleep_count = 0
|
||||
|
||||
/// How many times we suspect a subsystem type has crashed the MC, 3 strikes and you're out!
|
||||
var/static/list/failure_strikes
|
||||
|
||||
@@ -125,8 +131,10 @@
|
||||
fire(resumed)
|
||||
. = state
|
||||
if(state == SS_SLEEPING)
|
||||
fire_sleep_count++
|
||||
state = SS_IDLE
|
||||
if(state == SS_PAUSING)
|
||||
fire_sleep_count++
|
||||
var/QT = queued_time
|
||||
enqueue()
|
||||
state = SS_PAUSED
|
||||
@@ -260,11 +268,16 @@
|
||||
return
|
||||
|
||||
//used to initialize the subsystem AFTER the map has loaded
|
||||
/datum/controller/subsystem/Initialize(start_timeofday)
|
||||
/datum/controller/subsystem/proc/call_init(start_timeofday)
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
log_startup_progress("Initializing...")
|
||||
Initialize()
|
||||
initialized = TRUE
|
||||
var/time = (REALTIMEOFDAY - start_timeofday) / 10
|
||||
log_startup_progress("Initialized within [time] second[time == 1 ? "" : "s"]!")
|
||||
return time
|
||||
|
||||
/datum/controller/subsystem/Initialize()
|
||||
CRASH("Initialize() not overriden for [type]! Make the subsystem Initialize or add SS_NO_INIT to the flags")
|
||||
|
||||
//hook for printing stats to the "MC" statuspanel for admins to see performance and related stats etc.
|
||||
/datum/controller/subsystem/stat_entry(msg)
|
||||
@@ -297,7 +310,7 @@
|
||||
if(SS_SLEEPING)
|
||||
. = "S"
|
||||
if(SS_IDLE)
|
||||
. = " "
|
||||
. = " "
|
||||
|
||||
/datum/controller/subsystem/proc/state_colour()
|
||||
switch(state)
|
||||
@@ -342,5 +355,6 @@
|
||||
var/list/out = list()
|
||||
out["cost"] = cost
|
||||
out["tick_usage"] = tick_usage
|
||||
out["sleep_count"] = fire_sleep_count
|
||||
out["custom"] = list() // Override as needed on child
|
||||
return out
|
||||
|
||||
@@ -3,6 +3,7 @@ SUBSYSTEM_DEF(acid)
|
||||
priority = FIRE_PRIORITY_ACID
|
||||
flags = SS_NO_INIT|SS_BACKGROUND
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
offline_implications = "Objects will no longer react to acid. No immediate action is needed."
|
||||
|
||||
var/list/currentrun = list()
|
||||
|
||||
@@ -6,18 +6,17 @@ SUBSYSTEM_DEF(afk)
|
||||
name = "AFK Watcher"
|
||||
wait = 300
|
||||
flags = SS_BACKGROUND
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
offline_implications = "Players will no longer be marked as AFK. No immediate action is needed."
|
||||
var/list/afk_players = list() // Associative list. ckey as key and AFK state as value
|
||||
var/list/non_cryo_antags
|
||||
|
||||
|
||||
/datum/controller/subsystem/afk/Initialize()
|
||||
|
||||
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, SPECIAL_ROLE_WIZARD, SPECIAL_ROLE_WIZARD_APPRENTICE, SPECIAL_ROLE_NUKEOPS)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/afk/fire()
|
||||
var/list/toRemove = list()
|
||||
|
||||
@@ -15,6 +15,7 @@ SUBSYSTEM_DEF(air)
|
||||
flags = SS_BACKGROUND
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
offline_implications = "Turfs will no longer process atmos, and all atmospheric machines (including cryotubes) will no longer function. Shuttle call recommended."
|
||||
cpu_display = SS_CPUDISPLAY_HIGH
|
||||
var/cost_turfs = 0
|
||||
var/cost_groups = 0
|
||||
var/cost_highpressure = 0
|
||||
@@ -74,7 +75,7 @@ SUBSYSTEM_DEF(air)
|
||||
cust["hotspots"] = length(hotspots)
|
||||
.["custom"] = cust
|
||||
|
||||
/datum/controller/subsystem/air/Initialize(timeofday)
|
||||
/datum/controller/subsystem/air/Initialize()
|
||||
setup_overlays() // Assign icons and such for gas-turf-overlays
|
||||
icon_manager = new() // Sets up icon manager for pipes
|
||||
if(length(active_turfs))
|
||||
@@ -84,7 +85,6 @@ SUBSYSTEM_DEF(air)
|
||||
setup_pipenets(GLOB.machines)
|
||||
for(var/obj/machinery/atmospherics/A in machinery_to_construct)
|
||||
A.initialize_atmos_network()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/air/fire(resumed = 0)
|
||||
var/timer = TICK_USAGE_REAL
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
// why is this an SS if it has no fire or init
|
||||
// this should be a global datum for piss sake
|
||||
// AND YES I KNOW AN SS IS A GLOBAL DATUM, THATS NOT THE POINT
|
||||
SUBSYSTEM_DEF(alarm)
|
||||
name = "Alarm"
|
||||
flags = SS_NO_INIT | SS_NO_FIRE
|
||||
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]
|
||||
for(var/I in L)
|
||||
if(I == A.name)
|
||||
var/list/alarm = L[I]
|
||||
var/list/sources = alarm[3]
|
||||
if(!(alarmsource.UID() in sources))
|
||||
sources += alarmsource.UID()
|
||||
return TRUE
|
||||
L[A.name] = list(get_area_name(A, TRUE), O, list(alarmsource.UID()))
|
||||
SEND_SIGNAL(SSalarm, COMSIG_TRIGGERED_ALARM, class, A, O, alarmsource)
|
||||
return TRUE
|
||||
|
||||
/datum/controller/subsystem/alarm/proc/cancelAlarm(class, area/A, obj/origin)
|
||||
var/list/L = alarms[class]
|
||||
var/cleared = FALSE
|
||||
for(var/I in L)
|
||||
if(I == A.name)
|
||||
var/list/alarm = L[I]
|
||||
var/list/srcs = alarm[3]
|
||||
srcs -= origin.UID()
|
||||
if(!length(srcs))
|
||||
cleared = TRUE
|
||||
L -= I
|
||||
|
||||
SEND_SIGNAL(SSalarm, COMSIG_CANCELLED_ALARM, class, A, origin, cleared)
|
||||
@@ -5,6 +5,7 @@ SUBSYSTEM_DEF(ambience)
|
||||
priority = FIRE_PRIORITY_AMBIENCE
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
wait = 1 SECONDS
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
///Assoc list of listening client - next ambience time
|
||||
var/list/ambience_listening_clients = list()
|
||||
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
|
||||
SUBSYSTEM_DEF(blackbox)
|
||||
name = "Blackbox"
|
||||
flags = SS_NO_FIRE | SS_NO_INIT
|
||||
// Even though we dont initialize, we need this init_order
|
||||
// On Master.Shutdown(), it shuts down subsystems in the REVERSE order
|
||||
// The database SS has INIT_ORDER_DBCORE=20, and this SS has INIT_ORDER_BLACKBOX=19
|
||||
// So putting this ensures it shuts down in the right order
|
||||
init_order = INIT_ORDER_BLACKBOX
|
||||
wait = 10 MINUTES
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
offline_implications = "Player count and admin count statistics will no longer be logged to the database. No immediate action is needed."
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
|
||||
/// List of all recorded feedback
|
||||
var/list/datum/feedback_variable/feedback = list()
|
||||
@@ -18,6 +20,26 @@ SUBSYSTEM_DEF(blackbox)
|
||||
/// Associative list of any feedback variables that have had their format changed since creation and their current version, remember to update this
|
||||
var/list/versions = list()
|
||||
|
||||
/datum/controller/subsystem/blackbox/Initialize()
|
||||
if(!SSdbcore.IsConnected())
|
||||
flags |= SS_NO_FIRE // Disable firing if SQL is disabled
|
||||
|
||||
/datum/controller/subsystem/blackbox/fire(resumed = 0)
|
||||
sql_poll_players()
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/sql_poll_players()
|
||||
var/datum/db_query/statquery = SSdbcore.NewQuery(
|
||||
"INSERT INTO legacy_population (playercount, admincount, time, server_id) VALUES (:playercount, :admincount, NOW(), :server_id)",
|
||||
list(
|
||||
"playercount" = length(GLOB.clients),
|
||||
"admincount" = length(GLOB.admins),
|
||||
"server_id" = GLOB.configuration.system.instance_id
|
||||
)
|
||||
)
|
||||
statquery.warn_execute()
|
||||
qdel(statquery)
|
||||
|
||||
|
||||
/datum/controller/subsystem/blackbox/Recover()
|
||||
feedback = SSblackbox.feedback
|
||||
sealed = SSblackbox.sealed
|
||||
|
||||
@@ -3,6 +3,7 @@ SUBSYSTEM_DEF(chat_pings)
|
||||
flags = SS_NO_INIT
|
||||
runlevels = RUNLEVEL_INIT | RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME // ALL OF THEM
|
||||
wait = 30 SECONDS // Chat pings every 30 seconds
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
/// List of all held chat datums
|
||||
var/list/datum/chatOutput/chat_datums = list() // Do NOT put this in Initialize(). You will cause issues.
|
||||
|
||||
|
||||
@@ -18,10 +18,11 @@ SUBSYSTEM_DEF(cleanup)
|
||||
init_order = INIT_ORDER_CLEANUP
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
offline_implications = "Certain global lists will no longer be cleared of nulls, which may result in runtimes. No immediate action is needed."
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
/// A list of global lists we want the subsystem to clean.
|
||||
var/list/lists_to_clean
|
||||
|
||||
/datum/controller/subsystem/cleanup/Initialize(start_timeofday)
|
||||
/datum/controller/subsystem/cleanup/Initialize()
|
||||
// If you want this subsystem to clean out nulls from a specific list, add it here.
|
||||
lists_to_clean = list(
|
||||
GLOB.clients = "clients",
|
||||
@@ -32,7 +33,6 @@ SUBSYSTEM_DEF(cleanup)
|
||||
GLOB.human_list = "human_list",
|
||||
GLOB.carbon_list = "carbon_list"
|
||||
)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/cleanup/fire(resumed)
|
||||
for(var/L in lists_to_clean)
|
||||
|
||||
@@ -3,6 +3,7 @@ SUBSYSTEM_DEF(dbcore)
|
||||
flags = SS_BACKGROUND
|
||||
wait = 1 MINUTES
|
||||
init_order = INIT_ORDER_DBCORE
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
|
||||
/// Is the DB schema valid
|
||||
var/schema_valid = TRUE
|
||||
@@ -30,9 +31,8 @@ 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 ([GLOB.configuration.database.version]) doesn't match the latest schema version ([SQL_VERSION]). Roundstart has been delayed.</span>")
|
||||
log_startup_progress("Database schema ([GLOB.configuration.database.version]) doesn't match the latest schema version ([SQL_VERSION]). Roundstart has been delayed.")
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/dbcore/fire()
|
||||
for(var/I in active_queries)
|
||||
|
||||
@@ -3,6 +3,7 @@ SUBSYSTEM_DEF(debugview)
|
||||
wait = 1 // SS_TICKER subsystem, so wait is in ticks
|
||||
flags = SS_TICKER|SS_NO_INIT
|
||||
offline_implications = "Shift+F3 will no longer show a debug view. No immediate action is needed."
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
/// List of clients currently processing
|
||||
var/list/client/processing = list()
|
||||
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
SUBSYSTEM_DEF(discord)
|
||||
name = "Discord"
|
||||
flags = SS_NO_FIRE
|
||||
/// Is the SS enabled
|
||||
var/enabled = FALSE
|
||||
/// Last time the administrator ping was dropped. This ensures administrators cannot be mass pinged if a large chunk of ahelps go off at once (IE: tesloose)
|
||||
var/last_administration_ping = 0
|
||||
/// Last time the mentor ping was dropped. This ensures mentors cannot be mass pinged if a large chunk of mhelps go off at once.
|
||||
var/last_mentor_ping = 0
|
||||
|
||||
/datum/controller/subsystem/discord/Initialize(start_timeofday)
|
||||
if(GLOB.configuration.discord.webhooks_enabled)
|
||||
enabled = TRUE
|
||||
return ..()
|
||||
|
||||
// This is designed for ease of simplicity for sending quick messages from parts of the code
|
||||
/datum/controller/subsystem/discord/proc/send2discord_simple(destination, content)
|
||||
if(!enabled)
|
||||
return
|
||||
var/list/webhook_urls
|
||||
switch(destination)
|
||||
if(DISCORD_WEBHOOK_ADMIN)
|
||||
webhook_urls = GLOB.configuration.discord.admin_webhook_urls
|
||||
if(DISCORD_WEBHOOK_PRIMARY)
|
||||
webhook_urls = GLOB.configuration.discord.main_webhook_urls
|
||||
if(DISCORD_WEBHOOK_MENTOR)
|
||||
webhook_urls = GLOB.configuration.discord.mentor_webhook_urls
|
||||
|
||||
var/datum/discord_webhook_payload/dwp = new()
|
||||
dwp.webhook_content = "**\[[GLOB.configuration.system.instance_id]]** [content]"
|
||||
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 designed to take in a [/datum/discord_webhook_payload] which was prepared beforehand
|
||||
/datum/controller/subsystem/discord/proc/send2discord_complex(destination, datum/discord_webhook_payload/dwp)
|
||||
if(!enabled)
|
||||
return
|
||||
var/list/webhook_urls
|
||||
switch(destination)
|
||||
if(DISCORD_WEBHOOK_ADMIN)
|
||||
webhook_urls = GLOB.configuration.discord.admin_webhook_urls
|
||||
if(DISCORD_WEBHOOK_PRIMARY)
|
||||
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)
|
||||
var/active_admins = admincounter[1]
|
||||
var/inactive_admins = admincounter[3]
|
||||
var/add_ping = TRUE
|
||||
|
||||
if(active_admins <= 0)
|
||||
if(inactive_admins > 0)
|
||||
alerttext = " | **ALL ADMINS AFK**"
|
||||
else
|
||||
alerttext = " | **NO ADMINS ONLINE**"
|
||||
else
|
||||
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
|
||||
// We have active admins, we dont care about the rest of this proc
|
||||
return
|
||||
|
||||
var/message = "[content] [alerttext] [add_ping ? handle_administrator_ping() : ""]"
|
||||
|
||||
var/datum/discord_webhook_payload/dwp = new()
|
||||
dwp.webhook_content = "**\[[GLOB.configuration.system.instance_id]]** [message]"
|
||||
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"))
|
||||
|
||||
/datum/controller/subsystem/discord/proc/send2discord_simple_mentor(content)
|
||||
var/alerttext
|
||||
var/list/mentorcounter = staff_countup(R_MENTOR)
|
||||
var/active_mentors = mentorcounter[1]
|
||||
var/inactive_mentors = mentorcounter[3]
|
||||
var/add_ping = FALSE
|
||||
|
||||
if(active_mentors <= 0)
|
||||
add_ping = TRUE
|
||||
if(inactive_mentors)
|
||||
alerttext = "| **ALL MENTORS AFK**"
|
||||
else
|
||||
alerttext = "| **NO MENTORS ONLINE**"
|
||||
|
||||
var/message = "[content] [alerttext][add_ping ? handle_mentor_ping() : ""]"
|
||||
|
||||
var/datum/discord_webhook_payload/dwp = new()
|
||||
dwp.webhook_content = "**\[[GLOB.configuration.system.instance_id]]** [message]"
|
||||
for(var/url in GLOB.configuration.discord.mentor_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(GLOB.configuration.discord.admin_role_id)
|
||||
if(last_administration_ping > world.time)
|
||||
return "*(Role pinged recently)*"
|
||||
|
||||
last_administration_ping = world.time + 60 SECONDS
|
||||
return "<@&[GLOB.configuration.discord.admin_role_id]>"
|
||||
|
||||
return ""
|
||||
|
||||
/datum/controller/subsystem/discord/proc/handle_mentor_ping()
|
||||
if(GLOB.configuration.discord.mentor_role_id)
|
||||
if(last_mentor_ping > world.time)
|
||||
return " *(Role pinged recently)*"
|
||||
|
||||
last_mentor_ping = world.time + 60 SECONDS
|
||||
return " <@&[GLOB.configuration.discord.mentor_role_id]>"
|
||||
|
||||
return ""
|
||||
@@ -5,6 +5,7 @@ SUBSYSTEM_DEF(economy)
|
||||
wait = 30 SECONDS
|
||||
runlevels = RUNLEVEL_GAME
|
||||
offline_implications = "Crew wont get their paychecks. No immediate action is needed." // money go down
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
///List of all money account databases existing in the round
|
||||
var/list/money_account_databases = list()
|
||||
///Total amount of account created during the round, neccesary for generating unique account ids
|
||||
@@ -133,7 +134,6 @@ SUBSYSTEM_DEF(economy)
|
||||
centcom_message = "<center>---[station_time_timestamp()]---</center><br>Remember to stamp and send back the supply manifests.<hr>"
|
||||
|
||||
next_paycheck_delay = 30 MINUTES + world.time
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/economy/fire()
|
||||
if(next_paycheck_delay <= world.time)
|
||||
|
||||
@@ -4,6 +4,7 @@ SUBSYSTEM_DEF(events)
|
||||
runlevels = RUNLEVEL_GAME
|
||||
flags = SS_KEEP_TIMING
|
||||
offline_implications = "Random events will no longer happen. No immediate action is needed."
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
// Report events at the end of the rouund
|
||||
var/report_at_round_end = 0
|
||||
|
||||
@@ -31,7 +32,6 @@ SUBSYSTEM_DEF(events)
|
||||
|
||||
/datum/controller/subsystem/events/Initialize()
|
||||
allEvents = subtypesof(/datum/event)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/events/fire()
|
||||
for(var/datum/event/E in active_events)
|
||||
|
||||
@@ -3,6 +3,7 @@ SUBSYSTEM_DEF(fires)
|
||||
priority = FIRE_PRIORITY_BURNING
|
||||
flags = SS_NO_INIT|SS_BACKGROUND
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
cpu_display = SS_CPUDISPLAY_LOW // Trust me, this isnt atmos fires, this is paper and stuff being lit with lighters and stuff
|
||||
offline_implications = "Objects will no longer react to fires. No immediate action is needed."
|
||||
|
||||
var/list/currentrun = list()
|
||||
|
||||
@@ -4,8 +4,9 @@ SUBSYSTEM_DEF(garbage)
|
||||
wait = 2 SECONDS
|
||||
flags = SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT
|
||||
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
|
||||
init_order = INIT_ORDER_GARBAGE // Why does this have an init order if it has SS_NO_INIT?
|
||||
init_order = INIT_ORDER_GARBAGE // AA 2020: Why does this have an init order if it has SS_NO_INIT? | AA 2022: Its used for shutdown
|
||||
offline_implications = "Garbage collection is no longer functional, and objects will not be qdel'd. Immediate server restart recommended."
|
||||
cpu_display = SS_CPUDISPLAY_HIGH
|
||||
|
||||
var/list/collection_timeout = list(2 MINUTES, 10 SECONDS) // deciseconds to wait before moving something up in the queue to the next level
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
SUBSYSTEM_DEF(ghost_spawns)
|
||||
name = "Ghost Spawns"
|
||||
init_order = INIT_ORDER_EVENTS
|
||||
flags = SS_BACKGROUND
|
||||
flags = SS_BACKGROUND | SS_NO_INIT
|
||||
wait = 1 SECONDS
|
||||
runlevels = RUNLEVEL_GAME
|
||||
offline_implications = "Ghosts will no longer be able to respawn as event mobs (Blob, etc..). Shuttle call recommended."
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
|
||||
/// List of polls currently ongoing, to be checked on next fire()
|
||||
var/list/datum/candidate_poll/currently_polling
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
SUBSYSTEM_DEF(http)
|
||||
name = "HTTP"
|
||||
flags = SS_TICKER | SS_BACKGROUND // Measure in ticks, but also only run if we have the spare CPU. We also dont init.
|
||||
flags = SS_TICKER | SS_BACKGROUND // Measure in ticks, but also only run if we have the spare CPU.
|
||||
wait = 1
|
||||
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY // All the time
|
||||
// Assuming for the worst, since only discord is hooked into this for now, but that may change
|
||||
offline_implications = "The server is no longer capable of making async HTTP requests. Shuttle call recommended."
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
/// List of all async HTTP requests in the processing chain
|
||||
var/list/datum/http_request/active_async_requests
|
||||
/// Variable to define if logging is enabled or not. Disabled by default since we know the requests the server is making. Enable with VV if you need to debug requests
|
||||
@@ -16,9 +17,8 @@ SUBSYSTEM_DEF(http)
|
||||
. = ..()
|
||||
rustg_create_async_http_client() // Open the door
|
||||
|
||||
/datum/controller/subsystem/http/Initialize(start_timeofday)
|
||||
/datum/controller/subsystem/http/Initialize()
|
||||
active_async_requests = list()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/http/get_stat_details()
|
||||
return "P: [length(active_async_requests)] | T: [total_requests]"
|
||||
|
||||
@@ -5,6 +5,7 @@ SUBSYSTEM_DEF(icon_smooth)
|
||||
priority = FIRE_PRIORITY_SMOOTHING
|
||||
flags = SS_TICKER
|
||||
offline_implications = "Objects will no longer smooth together properly. No immediate action is needed."
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
|
||||
var/list/smooth_queue = list()
|
||||
|
||||
@@ -40,7 +41,6 @@ SUBSYSTEM_DEF(icon_smooth)
|
||||
A.smooth_icon()
|
||||
CHECK_TICK
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/icon_smooth/proc/add_to_queue(atom/thing)
|
||||
if(thing.smoothing_flags & SMOOTH_QUEUED)
|
||||
|
||||
@@ -4,6 +4,7 @@ SUBSYSTEM_DEF(idlenpcpool)
|
||||
priority = FIRE_PRIORITY_IDLE_NPC
|
||||
wait = 60
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
init_order = INIT_ORDER_IDLENPCS // MUST be after SSmapping since it tracks max Zs
|
||||
offline_implications = "Idle simple animals will no longer process. Shuttle call recommended."
|
||||
|
||||
var/list/currentrun = list()
|
||||
@@ -12,9 +13,8 @@ SUBSYSTEM_DEF(idlenpcpool)
|
||||
/datum/controller/subsystem/idlenpcpool/get_stat_details()
|
||||
return "IdleNPCS:[length(GLOB.simple_animals[AI_IDLE])]|Z:[length(GLOB.simple_animals[AI_Z_OFF])]"
|
||||
|
||||
/datum/controller/subsystem/idlenpcpool/Initialize(start_timeofday)
|
||||
idle_mobs_by_zlevel = new /list(world.maxz,0)
|
||||
return ..()
|
||||
/datum/controller/subsystem/idlenpcpool/Initialize()
|
||||
idle_mobs_by_zlevel = new /list(world.maxz, 0)
|
||||
|
||||
/datum/controller/subsystem/idlenpcpool/fire(resumed = FALSE)
|
||||
if(!resumed)
|
||||
|
||||
@@ -10,14 +10,13 @@ SUBSYSTEM_DEF(input)
|
||||
priority = FIRE_PRIORITY_INPUT
|
||||
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
|
||||
offline_implications = "Player input will no longer be recognised. Immediate server restart recommended."
|
||||
cpu_display = SS_CPUDISPLAY_HIGH
|
||||
|
||||
/// List of clients whose input to process in loop.
|
||||
var/list/client/processing = list()
|
||||
|
||||
/datum/controller/subsystem/input/Initialize()
|
||||
initialized = TRUE
|
||||
refresh_client_macro_sets()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/input/get_stat_details()
|
||||
return "P: [length(processing)]"
|
||||
|
||||
@@ -3,12 +3,13 @@ SUBSYSTEM_DEF(instancing)
|
||||
runlevels = RUNLEVEL_INIT | RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
wait = 30 SECONDS
|
||||
flags = SS_KEEP_TIMING
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
// This SS has the default init value since it needs to happen after the DB & redis
|
||||
|
||||
/// Associative list of registered commands. K = command name | V = command datum
|
||||
var/list/datum/server_command/registered_commands = list()
|
||||
|
||||
/datum/controller/subsystem/instancing/Initialize(start_timeofday)
|
||||
/datum/controller/subsystem/instancing/Initialize()
|
||||
// Make sure no one broke things. This check will trip up CI
|
||||
if(init_order >= SSredis.init_order)
|
||||
CRASH("SSinstancing was set to init before SSredis. Who broke it?")
|
||||
@@ -16,7 +17,7 @@ SUBSYSTEM_DEF(instancing)
|
||||
// Dont even bother if we arent connected to redis or the DB
|
||||
if(!SSdbcore.IsConnected() || !SSredis.connected || !GLOB.configuration.system.enable_multi_instance_support)
|
||||
flags |= SS_NO_FIRE
|
||||
return ..()
|
||||
return
|
||||
|
||||
// Setup our commands
|
||||
for(var/sct in subtypesof(/datum/server_command))
|
||||
@@ -36,7 +37,6 @@ SUBSYSTEM_DEF(instancing)
|
||||
// Announce startup to peers
|
||||
var/datum/server_command/new_round_announce/NRA = registered_commands["new_round_announce"]
|
||||
NRA.custom_dispatch(GLOB.configuration.general.server_name, SSmapping.map_datum.fluff_name, SSmapping.map_datum.technical_name)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/instancing/fire(resumed)
|
||||
update_heartbeat()
|
||||
|
||||
@@ -1,376 +0,0 @@
|
||||
SUBSYSTEM_DEF(ipintel)
|
||||
name = "XKeyScore"
|
||||
wait = 1
|
||||
flags = SS_NO_FIRE
|
||||
init_order = INIT_ORDER_XKEYSCORE // 10
|
||||
// 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)
|
||||
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[] = HTTPGet("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(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.")
|
||||
@@ -4,6 +4,7 @@ SUBSYSTEM_DEF(jobs)
|
||||
wait = 5 MINUTES // Dont ever make this a super low value since EXP updates are calculated from this value
|
||||
runlevels = RUNLEVEL_GAME
|
||||
offline_implications = "Job playtime hours will no longer be logged. No immediate action is needed."
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
|
||||
//List of all jobs
|
||||
var/list/occupations = list()
|
||||
@@ -20,13 +21,12 @@ SUBSYSTEM_DEF(jobs)
|
||||
///list of station departments and their associated roles and economy payments
|
||||
var/list/station_departments = list()
|
||||
|
||||
/datum/controller/subsystem/jobs/Initialize(timeofday)
|
||||
if(!occupations.len)
|
||||
/datum/controller/subsystem/jobs/Initialize()
|
||||
if(!length(occupations))
|
||||
SetupOccupations()
|
||||
for(var/department_type in subtypesof(/datum/station_department))
|
||||
station_departments += new department_type()
|
||||
LoadJobs(FALSE)
|
||||
return ..()
|
||||
|
||||
// Only fires every 5 minutes
|
||||
/datum/controller/subsystem/jobs/fire()
|
||||
|
||||
@@ -4,6 +4,7 @@ SUBSYSTEM_DEF(lighting)
|
||||
init_order = INIT_ORDER_LIGHTING
|
||||
flags = SS_TICKER
|
||||
offline_implications = "Lighting will no longer update. Shuttle call recommended."
|
||||
cpu_display = SS_CPUDISPLAY_HIGH
|
||||
var/static/list/sources_queue = list() // List of lighting sources queued for update.
|
||||
var/static/list/corners_queue = list() // List of lighting corners queued for update.
|
||||
var/static/list/objects_queue = list() // List of lighting objects queued for update.
|
||||
@@ -19,7 +20,7 @@ SUBSYSTEM_DEF(lighting)
|
||||
cust["objects_queue"] = length(objects_queue)
|
||||
.["custom"] = cust
|
||||
|
||||
/datum/controller/subsystem/lighting/Initialize(timeofday)
|
||||
/datum/controller/subsystem/lighting/Initialize()
|
||||
if(!initialized)
|
||||
if(GLOB.configuration.general.starlight)
|
||||
for(var/I in GLOB.all_areas)
|
||||
@@ -28,12 +29,9 @@ SUBSYSTEM_DEF(lighting)
|
||||
A.luminosity = 0
|
||||
|
||||
create_all_lighting_objects()
|
||||
initialized = TRUE
|
||||
|
||||
fire(FALSE, TRUE)
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/lighting/fire(resumed, init_tick_checks)
|
||||
MC_SPLIT_TICK_INIT(3)
|
||||
if(!init_tick_checks)
|
||||
|
||||
@@ -7,6 +7,7 @@ SUBSYSTEM_DEF(machines)
|
||||
init_order = INIT_ORDER_MACHINES
|
||||
flags = SS_KEEP_TIMING
|
||||
offline_implications = "Machinery will no longer process. Shuttle call recommended."
|
||||
cpu_display = SS_CPUDISPLAY_HIGH
|
||||
|
||||
var/list/processing = list()
|
||||
var/list/currentrun = list()
|
||||
@@ -18,7 +19,6 @@ SUBSYSTEM_DEF(machines)
|
||||
/datum/controller/subsystem/machines/Initialize()
|
||||
makepowernets()
|
||||
fire()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/machines/get_metrics()
|
||||
. = ..()
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
SUBSYSTEM_DEF(medals)
|
||||
name = "Medals"
|
||||
flags = SS_NO_FIRE
|
||||
var/hub_enabled = FALSE
|
||||
|
||||
/datum/controller/subsystem/medals/Initialize(timeofday)
|
||||
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, 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]!")
|
||||
return
|
||||
to_chat(player, "<span class='greenannounce'><B>Achievement unlocked: [medal]!</B></span>")
|
||||
|
||||
/datum/controller/subsystem/medals/proc/SetScore(score, client/player, increment, force)
|
||||
set waitfor = FALSE
|
||||
if(!score || !hub_enabled)
|
||||
return
|
||||
|
||||
var/list/oldscore = GetScore(score, player, TRUE)
|
||||
if(increment)
|
||||
if(!oldscore[score])
|
||||
oldscore[score] = 1
|
||||
else
|
||||
oldscore[score] = (text2num(oldscore[score]) + 1)
|
||||
else
|
||||
oldscore[score] = force
|
||||
|
||||
var/newscoreparam = list2params(oldscore)
|
||||
|
||||
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]!")
|
||||
|
||||
/datum/controller/subsystem/medals/proc/GetScore(score, client/player, returnlist)
|
||||
if(!score || !hub_enabled)
|
||||
return
|
||||
|
||||
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].")
|
||||
message_admins("Error! Failed to contact hub to get score [score] for [player.ckey]!")
|
||||
return
|
||||
. = params2list(scoreget)
|
||||
if(!returnlist)
|
||||
return .[score]
|
||||
|
||||
/datum/controller/subsystem/medals/proc/CheckMedal(medal, client/player)
|
||||
if(!medal || !hub_enabled)
|
||||
return
|
||||
|
||||
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]!")
|
||||
return
|
||||
to_chat(player, "[medal] is unlocked")
|
||||
|
||||
/datum/controller/subsystem/medals/proc/LockMedal(medal, client/player)
|
||||
if(!player || !medal || !hub_enabled)
|
||||
return
|
||||
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
|
||||
log_game("MEDAL ERROR: Could not contact hub to clear medal [medal] for player [player.ckey].")
|
||||
message_admins("Error! Failed to contact hub to clear [medal] medal for [player.ckey]!")
|
||||
if(TRUE)
|
||||
message_admins("Medal: [medal] removed for [player.ckey]")
|
||||
if(FALSE)
|
||||
message_admins("Medal: [medal] was not found for [player.ckey]. Unable to clear.")
|
||||
|
||||
|
||||
/datum/controller/subsystem/medals/proc/ClearScore(client/player)
|
||||
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]!")
|
||||
@@ -4,13 +4,13 @@ SUBSYSTEM_DEF(metrics)
|
||||
offline_implications = "Server metrics will no longer be ingested into monitoring systems. No immediate action is needed."
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME // ALL THE LEVELS
|
||||
flags = SS_KEEP_TIMING // This needs to ingest every 30 IRL seconds, not ingame seconds.
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
/// The real time of day the server started. Used to calculate time drift
|
||||
var/world_init_time = 0 // Not set in here. Set in world/New()
|
||||
|
||||
/datum/controller/subsystem/metrics/Initialize(start_timeofday)
|
||||
/datum/controller/subsystem/metrics/Initialize()
|
||||
if(!GLOB.configuration.metrics.enable_metrics)
|
||||
flags |= SS_NO_FIRE // Disable firing to save CPU
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/metrics/fire(resumed)
|
||||
|
||||
@@ -3,7 +3,9 @@ SUBSYSTEM_DEF(mobs)
|
||||
priority = FIRE_PRIORITY_MOBS
|
||||
flags = SS_KEEP_TIMING
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
init_order = INIT_ORDER_MOBS
|
||||
offline_implications = "Mobs will no longer process. Immediate server restart recommended."
|
||||
cpu_display = SS_CPUDISPLAY_HIGH
|
||||
|
||||
var/list/currentrun = list()
|
||||
var/static/list/clients_by_zlevel[][]
|
||||
@@ -21,10 +23,9 @@ SUBSYSTEM_DEF(mobs)
|
||||
/datum/controller/subsystem/mobs/get_stat_details()
|
||||
return "P:[length(GLOB.mob_living_list)]"
|
||||
|
||||
/datum/controller/subsystem/mobs/Initialize(start_timeofday)
|
||||
clients_by_zlevel = new /list(world.maxz,0)
|
||||
dead_players_by_zlevel = new /list(world.maxz,0)
|
||||
return ..()
|
||||
/datum/controller/subsystem/mobs/Initialize()
|
||||
clients_by_zlevel = new /list(world.maxz, 0)
|
||||
dead_players_by_zlevel = new /list(world.maxz, 0)
|
||||
|
||||
/datum/controller/subsystem/mobs/fire(resumed = 0)
|
||||
var/seconds = wait * 0.1
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
SUBSYSTEM_DEF(mob_hunt)
|
||||
name = "Nano-Mob Hunter GO Server"
|
||||
init_order = INIT_ORDER_NANOMOB
|
||||
priority = FIRE_PRIORITY_NANOMOB // Low priority, no need for MC_TICK_CHECK due to extremely low performance impact.
|
||||
flags = SS_NO_INIT
|
||||
offline_implications = "Nano-Mob Hunter will no longer spawn mobs. No immediate action is needed."
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
var/max_normal_spawns = 15 //change this to adjust the number of normal spawns that can exist at one time. trapped spawns (from traitors) don't count towards this
|
||||
var/list/normal_spawns = list()
|
||||
var/max_trap_spawns = 15 //change this to adjust the number of trap spawns that can exist at one time. traps spawned beyond this point clear the oldest traps
|
||||
|
||||
@@ -5,6 +5,7 @@ SUBSYSTEM_DEF(nightshift)
|
||||
wait = 600
|
||||
flags = SS_NO_TICK_CHECK
|
||||
offline_implications = "The game will no longer shift between day and night lighting. No immediate action is needed."
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
|
||||
var/nightshift_active = FALSE
|
||||
var/nightshift_start_time = 702000 //7:30 PM, station time
|
||||
@@ -15,10 +16,9 @@ SUBSYSTEM_DEF(nightshift)
|
||||
|
||||
/datum/controller/subsystem/nightshift/Initialize()
|
||||
if(!GLOB.configuration.general.enable_night_shifts)
|
||||
can_fire = FALSE
|
||||
flags |= SS_NO_FIRE
|
||||
if(GLOB.configuration.general.randomise_shift_time)
|
||||
GLOB.gametime_offset = rand(0, 23) HOURS
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/nightshift/fire(resumed = FALSE)
|
||||
if(world.time - SSticker.round_start_time < nightshift_first_check)
|
||||
|
||||
+1
-2
@@ -5,7 +5,7 @@ SUBSYSTEM_DEF(assets)
|
||||
var/list/cache = list()
|
||||
var/list/preload = list()
|
||||
|
||||
/datum/controller/subsystem/assets/Initialize(timeofday)
|
||||
/datum/controller/subsystem/assets/Initialize()
|
||||
for(var/type in typesof(/datum/asset) - list(/datum/asset, /datum/asset/simple))
|
||||
var/datum/asset/A = new type()
|
||||
A.register()
|
||||
@@ -14,4 +14,3 @@ SUBSYSTEM_DEF(assets)
|
||||
|
||||
for(var/client/C in GLOB.clients)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(getFilesSlow), C, preload, FALSE), 10)
|
||||
return ..()
|
||||
+1
-4
@@ -15,13 +15,10 @@ SUBSYSTEM_DEF(atoms)
|
||||
var/list/BadInitializeCalls = list()
|
||||
|
||||
|
||||
/datum/controller/subsystem/atoms/Initialize(timeofday)
|
||||
/datum/controller/subsystem/atoms/Initialize()
|
||||
setupgenetics()
|
||||
initialized = INITIALIZATION_INNEW_MAPLOAD
|
||||
InitializeAtoms()
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms, noisy = TRUE)
|
||||
if(initialized == INITIALIZATION_INSSATOMS)
|
||||
+2
-4
@@ -21,13 +21,13 @@ SUBSYSTEM_DEF(changelog)
|
||||
/datum/controller/subsystem/changelog/Initialize()
|
||||
// This entire subsystem relies on SQL being here.
|
||||
if(!SSdbcore.IsConnected())
|
||||
return ..()
|
||||
return
|
||||
|
||||
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
|
||||
return ..()
|
||||
return
|
||||
|
||||
while(latest_cl_date.NextRow())
|
||||
current_cl_timestamp = latest_cl_date.item[1]
|
||||
@@ -48,8 +48,6 @@ SUBSYSTEM_DEF(changelog)
|
||||
for(var/client/C as anything in startup_clients_open)
|
||||
OpenChangelog(C)
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/changelog/proc/UpdatePlayerChangelogDate(client/C)
|
||||
if(!ss_ready)
|
||||
+2
-4
@@ -4,9 +4,9 @@ SUBSYSTEM_DEF(holiday)
|
||||
flags = SS_NO_FIRE
|
||||
var/list/holidays
|
||||
|
||||
/datum/controller/subsystem/holiday/Initialize(start_timeofday)
|
||||
/datum/controller/subsystem/holiday/Initialize()
|
||||
if(!GLOB.configuration.general.allow_holidays)
|
||||
return ..() //Holiday stuff was not enabled in the config!
|
||||
return //Holiday stuff was not enabled in the config!
|
||||
|
||||
var/YY = text2num(time2text(world.timeofday, "YY")) // get the current year
|
||||
var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month
|
||||
@@ -27,5 +27,3 @@ SUBSYSTEM_DEF(holiday)
|
||||
if(H.eventChance)
|
||||
if(prob(H.eventChance))
|
||||
H.handle_event()
|
||||
|
||||
return ..()
|
||||
+1
-2
@@ -9,10 +9,9 @@ SUBSYSTEM_DEF(late_mapping)
|
||||
/// List of all maze generators to process
|
||||
var/list/obj/effect/mazegen/generator/maze_generators = list()
|
||||
|
||||
/datum/controller/subsystem/late_mapping/Initialize(start_timeofday)
|
||||
/datum/controller/subsystem/late_mapping/Initialize()
|
||||
if(length(maze_generators))
|
||||
log_startup_progress("Generating mazes...")
|
||||
for(var/i in maze_generators)
|
||||
var/obj/effect/mazegen/generator/MG = i
|
||||
MG.run_generator()
|
||||
return ..()
|
||||
+1
-3
@@ -35,7 +35,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
var/F = file("data/next_map.txt")
|
||||
F << next_map.type
|
||||
|
||||
/datum/controller/subsystem/mapping/Initialize(timeofday)
|
||||
/datum/controller/subsystem/mapping/Initialize()
|
||||
// Load all Z level templates
|
||||
preloadTemplates()
|
||||
|
||||
@@ -111,8 +111,6 @@ SUBSYSTEM_DEF(mapping)
|
||||
else
|
||||
world.name = station_name()
|
||||
|
||||
return ..()
|
||||
|
||||
// Do not confuse with seedRuins()
|
||||
/datum/controller/subsystem/mapping/proc/handleRuins()
|
||||
// load in extra levels of space ruins
|
||||
+4
-6
@@ -12,9 +12,9 @@ SUBSYSTEM_DEF(maprotate)
|
||||
|
||||
. = ..()
|
||||
|
||||
/datum/controller/subsystem/maprotate/Initialize(start_timeofday)
|
||||
/datum/controller/subsystem/maprotate/Initialize()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return ..()
|
||||
return
|
||||
|
||||
// Make a quick list for number to date lookups
|
||||
var/list/days = list("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")
|
||||
@@ -37,7 +37,7 @@ SUBSYSTEM_DEF(maprotate)
|
||||
var/datum/db_query/dbq = SSdbcore.NewQuery("SELECT WEEKDAY(NOW()) AS d")
|
||||
if(!dbq.warn_execute())
|
||||
log_startup_progress("Somehow, we failed to extract a numerical day from the DB. ?????????????")
|
||||
return ..()
|
||||
return
|
||||
|
||||
var/day_index = 0
|
||||
|
||||
@@ -50,7 +50,7 @@ SUBSYSTEM_DEF(maprotate)
|
||||
|
||||
if(!day_index)
|
||||
log_startup_progress("Somehow, we failed to extract a valid numerical day from the DB. ?????????????")
|
||||
return ..()
|
||||
return
|
||||
|
||||
|
||||
// String interpolation is faster than num2text() for some reason
|
||||
@@ -74,5 +74,3 @@ SUBSYSTEM_DEF(maprotate)
|
||||
log_startup_progress("There is no special rotation defined for this day")
|
||||
|
||||
|
||||
return ..()
|
||||
|
||||
-1
@@ -8,7 +8,6 @@ SUBSYSTEM_DEF(pathfinder)
|
||||
/datum/controller/subsystem/pathfinder/Initialize()
|
||||
space_type_cache = typecacheof(/turf/space)
|
||||
mobs = new(10)
|
||||
return ..()
|
||||
|
||||
/datum/flowcache
|
||||
var/lcount
|
||||
-1
@@ -18,7 +18,6 @@ SUBSYSTEM_DEF(persistent_data)
|
||||
// Load all the data of registered atoms
|
||||
for(var/atom/A in registered_atoms)
|
||||
A.persistent_load()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/persistent_data/Shutdown()
|
||||
// Save all the data of registered atoms
|
||||
+5
-1
@@ -1,6 +1,6 @@
|
||||
SUBSYSTEM_DEF(radio)
|
||||
name = "Radio"
|
||||
flags = SS_NO_INIT | SS_NO_FIRE
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
var/list/radiochannels = list(
|
||||
"Common" = PUB_FREQ,
|
||||
@@ -25,6 +25,10 @@ SUBSYSTEM_DEF(radio)
|
||||
var/list/DEPT_FREQS = list(AI_FREQ, COMM_FREQ, ENG_FREQ, MED_FREQ, SEC_FREQ, SCI_FREQ, SRV_FREQ, SUP_FREQ, PROC_FREQ)
|
||||
var/list/datum/radio_frequency/frequencies = list()
|
||||
|
||||
// This is a disgusting hack to stop this tripping CI when this thing needs to FUCKING DIE
|
||||
/datum/controller/subsystem/radio/Initialize()
|
||||
return
|
||||
|
||||
// This is fucking disgusting and needs to die
|
||||
/datum/controller/subsystem/radio/proc/frequency_span_class(frequency)
|
||||
// Antags!
|
||||
+1
-2
@@ -19,7 +19,7 @@ SUBSYSTEM_DEF(queue)
|
||||
/// Last world.time we let a ckey in. 3 second delay between each letin to avoid a mass bubble
|
||||
var/last_letin_time = 0
|
||||
|
||||
/datum/controller/subsystem/queue/Initialize(start_timeofday)
|
||||
/datum/controller/subsystem/queue/Initialize()
|
||||
if(fexists(QUEUE_DATA_FILE))
|
||||
try
|
||||
var/F = file2text(QUEUE_DATA_FILE)
|
||||
@@ -30,7 +30,6 @@ SUBSYSTEM_DEF(queue)
|
||||
catch
|
||||
stack_trace("Failed to load [QUEUE_DATA_FILE] from disk due to malformed JSON. You may need to setup the queue again.")
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/queue/Shutdown()
|
||||
// Save if persistent
|
||||
@@ -26,7 +26,6 @@ SUBSYSTEM_DEF(sounds)
|
||||
|
||||
/datum/controller/subsystem/sounds/Initialize()
|
||||
setup_available_channels()
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Sets up all available sound channels
|
||||
-2
@@ -32,5 +32,3 @@ SUBSYSTEM_DEF(title)
|
||||
|
||||
for(var/turf/simulated/wall/indestructible/splashscreen/splash in world)
|
||||
splash.icon = icon
|
||||
|
||||
return ..()
|
||||
@@ -18,10 +18,7 @@ SUBSYSTEM_DEF(overlays)
|
||||
stats = list()
|
||||
|
||||
/datum/controller/subsystem/overlays/Initialize()
|
||||
initialized = TRUE
|
||||
fire(mc_check = FALSE)
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/overlays/get_stat_details()
|
||||
return "Ov:[length(queue)]"
|
||||
|
||||
@@ -5,6 +5,7 @@ SUBSYSTEM_DEF(parallax)
|
||||
priority = FIRE_PRIORITY_PARALLAX
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
offline_implications = "Space parallax will no longer move around. No immediate action is needed."
|
||||
cpu_display = SS_CPUDISPLAY_HIGH
|
||||
var/list/currentrun
|
||||
var/planet_x_offset = 128
|
||||
var/planet_y_offset = 128
|
||||
|
||||
@@ -25,7 +25,6 @@ PROCESSING_SUBSYSTEM_DEF(instruments)
|
||||
/datum/controller/subsystem/processing/instruments/Initialize()
|
||||
initialize_instrument_data()
|
||||
synthesizer_instrument_ids = get_allowed_instrument_ids()
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Initializes all instrument datums
|
||||
|
||||
@@ -3,6 +3,7 @@ PROCESSING_SUBSYSTEM_DEF(projectiles)
|
||||
wait = 1
|
||||
flags = SS_NO_INIT|SS_TICKER
|
||||
offline_implications = "Projectiles will no longer move. Shuttle call recommended."
|
||||
cpu_display = SS_CPUDISPLAY_HIGH
|
||||
|
||||
/// Maximum moves a projectile can make per tick.
|
||||
var/global_max_tick_moves = 10
|
||||
|
||||
@@ -4,6 +4,7 @@ SUBSYSTEM_DEF(profiler)
|
||||
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
|
||||
wait = 5 MINUTES
|
||||
flags = SS_NO_TICK_CHECK
|
||||
cpu_display = SS_CPUDISPLAY_LOW // its usage itself is high but its every 5 mins so
|
||||
/// Time it took to fetch normal profile data (ms)
|
||||
var/nfetch_cost = 0
|
||||
/// Time it took to write the normal file (ms)
|
||||
@@ -24,7 +25,6 @@ SUBSYSTEM_DEF(profiler)
|
||||
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 ..()
|
||||
|
||||
/datum/controller/subsystem/profiler/fire()
|
||||
DumpFile()
|
||||
|
||||
@@ -3,6 +3,7 @@ PROCESSING_SUBSYSTEM_DEF(radiation)
|
||||
flags = SS_BACKGROUND | SS_NO_INIT
|
||||
wait = 1 SECONDS
|
||||
offline_implications = "Radiation will no longer function; power generation may not happen. A restart may or may not be required, depending on the situation."
|
||||
cpu_display = SS_CPUDISPLAY_HIGH
|
||||
var/list/warned_atoms = list()
|
||||
// Cache radiation levels for each turf so it doesn't need to be done iteratively
|
||||
// turf_rad_cache is the state in the current loop, and may not be 100% representative
|
||||
|
||||
@@ -11,6 +11,7 @@ SUBSYSTEM_DEF(redis)
|
||||
/// Message queue (If messages are sent before the SS has init'd)
|
||||
var/list/datum/redis_message/queue = list()
|
||||
offline_implications = "The server will no longer be able to send or receive redis messages. Shuttle call recommended (Potential server crash inbound)."
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
|
||||
// SS meta procs
|
||||
/datum/controller/subsystem/redis/get_stat_details()
|
||||
@@ -41,7 +42,6 @@ SUBSYSTEM_DEF(redis)
|
||||
var/amount_registered = length(subbed_channels)
|
||||
log_startup_progress("Registered [amount_registered] callback[amount_registered == 1 ? "" : "s"].")
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/redis/fire()
|
||||
check_messages()
|
||||
|
||||
@@ -27,6 +27,7 @@ SUBSYSTEM_DEF(runechat)
|
||||
wait = 1
|
||||
priority = FIRE_PRIORITY_RUNECHAT
|
||||
offline_implications = "Runechat messages will no longer clear. Shuttle call recommended."
|
||||
cpu_display = SS_CPUDISPLAY_HIGH
|
||||
|
||||
/// world.time of the first entry in the bucket list, effectively the 'start time' of the current buckets
|
||||
var/head_offset = 0
|
||||
|
||||
@@ -6,6 +6,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
flags = SS_KEEP_TIMING|SS_NO_TICK_CHECK
|
||||
runlevels = RUNLEVEL_SETUP | RUNLEVEL_GAME
|
||||
offline_implications = "Shuttles will no longer function. Immediate server restart recommended."
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
var/list/mobile = list()
|
||||
var/list/stationary = list()
|
||||
var/list/transit = list()
|
||||
@@ -28,7 +29,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
/// Default refuel delay
|
||||
var/refuel_delay = 20 MINUTES
|
||||
|
||||
/datum/controller/subsystem/shuttle/Initialize(start_timeofday)
|
||||
/datum/controller/subsystem/shuttle/Initialize()
|
||||
if(!emergency)
|
||||
WARNING("No /obj/docking_port/mobile/emergency placed on the map!")
|
||||
if(!backup_shuttle)
|
||||
@@ -39,8 +40,6 @@ SUBSYSTEM_DEF(shuttle)
|
||||
initial_load()
|
||||
initial_move()
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/shuttle/get_stat_details()
|
||||
return "M:[length(mobile)] S:[length(stationary)] T:[length(transit)]"
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ SUBSYSTEM_DEF(spacedrift)
|
||||
flags = SS_NO_INIT|SS_KEEP_TIMING
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
offline_implications = "Mobs will no longer respect a lack of gravity. No immediate action is needed."
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
|
||||
var/list/currentrun = list()
|
||||
var/list/processing = list()
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
SUBSYSTEM_DEF(statistics)
|
||||
name = "Statistics"
|
||||
wait = 6000 // 10 minute delay between fires
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME // Only count time actually ingame to avoid logging pre-round dips
|
||||
offline_implications = "Player count and admin count statistics will no longer be logged to the database. No immediate action is needed."
|
||||
|
||||
|
||||
/datum/controller/subsystem/statistics/Initialize(start_timeofday)
|
||||
if(!SSdbcore.IsConnected())
|
||||
flags |= SS_NO_FIRE // Disable firing if SQL is disabled
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/statistics/fire(resumed = 0)
|
||||
sql_poll_players()
|
||||
|
||||
/datum/controller/subsystem/statistics/proc/sql_poll_players()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return
|
||||
else
|
||||
var/datum/db_query/statquery = SSdbcore.NewQuery(
|
||||
"INSERT INTO legacy_population (playercount, admincount, time, server_id) VALUES (:playercount, :admincount, NOW(), :server_id)",
|
||||
list(
|
||||
"playercount" = length(GLOB.clients),
|
||||
"admincount" = length(GLOB.admins),
|
||||
"server_id" = GLOB.configuration.system.instance_id
|
||||
)
|
||||
)
|
||||
statquery.warn_execute()
|
||||
qdel(statquery)
|
||||
@@ -4,6 +4,7 @@ SUBSYSTEM_DEF(sun)
|
||||
flags = SS_NO_TICK_CHECK
|
||||
init_order = INIT_ORDER_SUN
|
||||
offline_implications = "Solar panels will no longer rotate. No immediate action is needed."
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
var/angle
|
||||
var/dx
|
||||
var/dy
|
||||
@@ -11,7 +12,7 @@ SUBSYSTEM_DEF(sun)
|
||||
var/list/solars = list()
|
||||
var/solar_gen_rate = 1500
|
||||
|
||||
/datum/controller/subsystem/sun/Initialize(start_timeofday)
|
||||
/datum/controller/subsystem/sun/Initialize()
|
||||
// Lets work out an angle for the "sun" to rotate around the station
|
||||
angle = rand (0,360) // the station position to the sun is randomised at round start
|
||||
rate = rand(50,200)/100 // 50% - 200% of standard rotation
|
||||
@@ -22,8 +23,6 @@ SUBSYSTEM_DEF(sun)
|
||||
for(var/obj/machinery/power/solar_control/SC in solars)
|
||||
SC.setup()
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/sun/get_stat_details()
|
||||
return "P:[length(solars)]"
|
||||
|
||||
@@ -8,6 +8,7 @@ SUBSYSTEM_DEF(throwing)
|
||||
flags = SS_NO_INIT|SS_KEEP_TIMING|SS_TICKER
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
offline_implications = "Thrown objects may not react properly. Shuttle call recommended."
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
|
||||
var/list/currentrun
|
||||
var/list/processing = list()
|
||||
|
||||
@@ -6,6 +6,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
flags = SS_KEEP_TIMING
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME
|
||||
offline_implications = "The game is no longer aware of when the round ends. Immediate server restart recommended."
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
|
||||
/// Time the game should start, relative to world.time
|
||||
var/round_start_time = 0
|
||||
@@ -76,8 +77,6 @@ SUBSYSTEM_DEF(ticker)
|
||||
'sound/music/title2.ogg',\
|
||||
'sound/music/title3.ogg',)
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/ticker/fire()
|
||||
switch(current_state)
|
||||
@@ -307,7 +306,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
var/datum/holiday/holiday = SSholiday.holidays[holidayname]
|
||||
to_chat(world, "<h4>[holiday.greet()]</h4>")
|
||||
|
||||
SSdiscord.send2discord_simple_noadmins("**\[Info]** Round has started")
|
||||
GLOB.discord_manager.send2discord_simple_noadmins("**\[Info]** Round has started")
|
||||
auto_toggle_ooc(FALSE) // Turn it off
|
||||
time_game_started = world.time
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@ GLOBAL_REAL(SSmentor_tickets, /datum/controller/subsystem/tickets/mentor_tickets
|
||||
db_save_id = "MENTOR"
|
||||
|
||||
/datum/controller/subsystem/tickets/mentor_tickets/Initialize()
|
||||
..()
|
||||
close_messages = list("<font color='red' size='3'><b>- [ticket_name] Closed -</b></font>",
|
||||
"<span class='boldmessage'>Please try to be as descriptive as possible in mentor helps. Mentors do not know the full situation you're in and need more information to give you a helpful response.</span>",
|
||||
"<span class='[span_class]'>Your [ticket_name] has now been closed.</span>")
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/tickets/mentor_tickets/message_staff(msg, prefix_type = NONE, important = FALSE)
|
||||
message_mentorTicket(msg, important)
|
||||
|
||||
@@ -51,11 +51,9 @@ SUBSYSTEM_DEF(tickets)
|
||||
.["custom"] = cust
|
||||
|
||||
/datum/controller/subsystem/tickets/Initialize()
|
||||
if(!close_messages)
|
||||
close_messages = list("<font color='red' size='4'><b>- [ticket_name] Rejected! -</b></font>",
|
||||
"<span class='boldmessage'>Please try to be calm, clear, and descriptive in admin helps, do not assume the staff member has seen any related events, and clearly state the names of anybody you are reporting. If you asked a question, please ensure it was clear what you were asking.</span>",
|
||||
"<span class='[span_class]'>Your [ticket_name] has now been closed.</span>")
|
||||
return ..()
|
||||
close_messages = list("<font color='red' size='4'><b>- [ticket_name] Rejected! -</b></font>",
|
||||
"<span class='boldmessage'>Please try to be calm, clear, and descriptive in admin helps, do not assume the staff member has seen any related events, and clearly state the names of anybody you are reporting. If you asked a question, please ensure it was clear what you were asking.</span>",
|
||||
"<span class='[span_class]'>Your [ticket_name] has now been closed.</span>")
|
||||
|
||||
/datum/controller/subsystem/tickets/fire()
|
||||
var/stales = checkStaleness()
|
||||
|
||||
@@ -14,6 +14,7 @@ SUBSYSTEM_DEF(time_track)
|
||||
var/last_tick_realtime = 0
|
||||
var/last_tick_byond_time = 0
|
||||
var/last_tick_tickcount = 0
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
|
||||
/datum/controller/subsystem/time_track/fire()
|
||||
var/current_realtime = REALTIMEOFDAY
|
||||
|
||||
@@ -23,6 +23,7 @@ SUBSYSTEM_DEF(timer)
|
||||
|
||||
flags = SS_TICKER|SS_NO_INIT
|
||||
offline_implications = "The game will no longer process timers. Immediate server restart recommended."
|
||||
cpu_display = SS_CPUDISPLAY_HIGH
|
||||
|
||||
/// Queue used for storing timers that do not fit into the current buckets
|
||||
var/list/datum/timedevent/second_queue = list()
|
||||
|
||||
@@ -4,6 +4,7 @@ SUBSYSTEM_DEF(vote)
|
||||
flags = SS_KEEP_TIMING|SS_NO_INIT
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
offline_implications = "Votes (Endround shuttle) will no longer function. Shuttle call recommended."
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
|
||||
/// Active vote, if any
|
||||
var/datum/vote/active_vote
|
||||
|
||||
@@ -13,6 +13,7 @@ SUBSYSTEM_DEF(weather)
|
||||
var/list/processing = list()
|
||||
var/list/eligible_zlevels = list()
|
||||
var/list/next_hit_by_zlevel = list() //Used by barometers to know when the next storm is coming
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
|
||||
/datum/controller/subsystem/weather/get_metrics()
|
||||
. = ..()
|
||||
@@ -41,7 +42,7 @@ SUBSYSTEM_DEF(weather)
|
||||
addtimer(CALLBACK(src, PROC_REF(make_eligible), z, possible_weather), randTime + initial(W.weather_duration_upper), TIMER_UNIQUE) //Around 5-10 minutes between weathers
|
||||
next_hit_by_zlevel["[z]"] = world.time + randTime + initial(W.telegraph_duration)
|
||||
|
||||
/datum/controller/subsystem/weather/Initialize(start_timeofday)
|
||||
/datum/controller/subsystem/weather/Initialize()
|
||||
for(var/V in subtypesof(/datum/weather))
|
||||
var/datum/weather/W = V
|
||||
var/probability = initial(W.probability)
|
||||
@@ -52,7 +53,6 @@ SUBSYSTEM_DEF(weather)
|
||||
for(var/z in levels_by_trait(target_trait))
|
||||
LAZYINITLIST(eligible_zlevels["[z]"])
|
||||
eligible_zlevels["[z]"][W] = probability
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/weather/proc/run_weather(datum/weather/weather_datum_type, z_levels)
|
||||
if(istext(weather_datum_type))
|
||||
|
||||
Reference in New Issue
Block a user