Files
WaterpigandMajkl-J bb70889f6e TG Upstream Part 1
3591 individual conflicts

Update build.js

Update install_node.sh

Update byond.js

oh my fucking god

hat

slow

huh

holy shit

we all fall down

2 more I missed

2900 individual conflicts

2700 Individual conflicts

replaces yarn file with tg version, bumping us down to 2200-ish

Down to 2000 individual conflicts

140 down

mmm

aaaaaaaaaaaaaaaaaaa

not yt

575

soon

900 individual conflicts

600 individual conflicts, 121 file conflicts

im not okay

160 across 19 files

29 in 4 files

0 conflicts, compiletime fix time

some minor incap stuff

missed ticks

weird dupe definition stuff

missed ticks 2

incap fixes

undefs and pie fix

Radio update and some extra minor stuff

returns a single override

no more dupe definitions, 175 compiletime errors

Unticked file fix

sound and emote stuff

honk and more radio stuff
2024-10-19 08:04:33 -07:00

516 lines
17 KiB
Plaintext

#define RESTART_COUNTER_PATH "data/round_counter.txt"
/// Load byond-tracy. If USE_BYOND_TRACY is defined, then this is ignored and byond-tracy is always loaded.
#define USE_TRACY_PARAMETER "tracy"
/// Force the log directory to be something specific in the data/logs folder
#define OVERRIDE_LOG_DIRECTORY_PARAMETER "log-directory"
/// Prevent the master controller from starting automatically
#define NO_INIT_PARAMETER "no-init"
GLOBAL_VAR(restart_counter)
GLOBAL_VAR(tracy_log)
/**
* WORLD INITIALIZATION
* THIS IS THE INIT ORDER:
*
* BYOND =>
* - (secret init native) =>
* - world.Genesis() =>
* - world.init_byond_tracy()
* - (Start native profiling)
* - world.init_debugger()
* - Master =>
* - config *unloaded
* - (all subsystems) PreInit()
* - GLOB =>
* - make_datum_reference_lists()
* - (/static variable inits, reverse declaration order)
* - (all pre-mapped atoms) /atom/New()
* - world.New() =>
* - config.Load()
* - world.InitTgs() =>
* - TgsNew() *may sleep
* - GLOB.rev_data.load_tgs_info()
* - world.ConfigLoaded() =>
* - SSdbcore.InitializeRound()
* - world.SetupLogs()
* - load_admins()
* - ...
* - Master.Initialize() =>
* - (all subsystems) Initialize()
* - Master.StartProcessing() =>
* - Master.Loop() =>
* - Failsafe
* - world.RunUnattendedFunctions()
*
* Now listen up because I want to make something clear:
* If something is not in this list it should almost definitely be handled by a subsystem Initialize()ing
* If whatever it is that needs doing doesn't fit in a subsystem you probably aren't trying hard enough tbhfam
*
* GOT IT MEMORIZED?
* - Dominion/Cyberboss
*
* Where to put init shit quick guide:
* If you need it to happen before the mc is created: world/Genesis.
* If you need it to happen last: world/New(),
* Otherwise, in a subsystem preinit or init. Subsystems can set an init priority.
*/
/**
* THIS !!!SINGLE!!! PROC IS WHERE ANY FORM OF INIITIALIZATION THAT CAN'T BE PERFORMED IN SUBSYSTEMS OR WORLD/NEW IS DONE
* NOWHERE THE FUCK ELSE
* I DON'T CARE HOW MANY LAYERS OF DEBUG/PROFILE/TRACE WE HAVE, YOU JUST HAVE TO DEAL WITH THIS PROC EXISTING
* I'M NOT EVEN GOING TO TELL YOU WHERE IT'S CALLED FROM BECAUSE I'M DECLARING THAT FORBIDDEN KNOWLEDGE
* SO HELP ME GOD IF I FIND ABSTRACTION LAYERS OVER THIS!
*/
/world/proc/Genesis(tracy_initialized = FALSE)
RETURN_TYPE(/datum/controller/master)
#ifdef USE_BYOND_TRACY
#warn USE_BYOND_TRACY is enabled
if(!tracy_initialized)
#else
if(!tracy_initialized && (USE_TRACY_PARAMETER in params))
#endif
GLOB.tracy_log = init_byond_tracy()
Genesis(tracy_initialized = TRUE)
return
Profile(PROFILE_RESTART)
Profile(PROFILE_RESTART, type = "sendmaps")
// Write everything to this log file until we get to SetupLogs() later
_initialize_log_files("data/logs/config_error.[GUID()].log")
// Init the debugger first so we can debug Master
init_debugger()
// Create the logger
logger = new
// THAT'S IT, WE'RE DONE, THE. FUCKING. END.
Master = new
/**
* World creation
*
* Here is where a round itself is actually begun and setup.
* * db connection setup
* * config loaded from files
* * loads admins
* * Sets up the dynamic menu system
* * and most importantly, calls initialize on the master subsystem, starting the game loop that causes the rest of the game to begin processing and setting up
*
*
* Nothing happens until something moves. ~Albert Einstein
*
* For clarity, this proc gets triggered later in the initialization pipeline, it is not the first thing to happen, as it might seem.
*
* Initialization Pipeline:
* Global vars are new()'ed, (including config, glob, and the master controller will also new and preinit all subsystems when it gets new()ed)
* Compiled in maps are loaded (mainly centcom). all areas/turfs/objs/mobs(ATOMs) in these maps will be new()ed
* world/New() (You are here)
* Once world/New() returns, client's can connect.
* 1 second sleep
* Master Controller initialization.
* Subsystem initialization.
* Non-compiled-in maps are maploaded, all atoms are new()ed
* All atoms in both compiled and uncompiled maps are initialized()
*/
/world/New()
log_world("World loaded at [time_stamp()]!")
// From a really fucking old commit (91d7150)
// I wanted to move it but I think this needs to be after /world/New is called but before any sleeps?
// - Dominion/Cyberboss
GLOB.timezoneOffset = world.timezone * 36000
// First possible sleep()
InitTgs()
config.Load(params[OVERRIDE_CONFIG_DIRECTORY_PARAMETER])
ConfigLoaded()
if(NO_INIT_PARAMETER in params)
return
Master.Initialize(10, FALSE, TRUE)
RunUnattendedFunctions()
/// Initializes TGS and loads the returned revising info into GLOB.revdata
/world/proc/InitTgs()
TgsNew(new /datum/tgs_event_handler/impl, TGS_SECURITY_TRUSTED)
GLOB.revdata.load_tgs_info()
/// Runs after config is loaded but before Master is initialized
/world/proc/ConfigLoaded()
// Everything in here is prioritized in a very specific way.
// If you need to add to it, ask yourself hard if what your adding is in the right spot
// (i.e. basically nothing should be added before load_admins() in here)
// Try to set round ID
SSdbcore.InitializeRound()
SetupLogs()
load_admins()
load_poll_data()
LoadVerbs(/datum/verbs/menu)
if(fexists(RESTART_COUNTER_PATH))
GLOB.restart_counter = text2num(trim(file2text(RESTART_COUNTER_PATH)))
fdel(RESTART_COUNTER_PATH)
/// Runs after the call to Master.Initialize, but before the delay kicks in. Used to turn the world execution into some single function then exit
/world/proc/RunUnattendedFunctions()
#ifdef UNIT_TESTS
HandleTestRun()
#endif
#ifdef AUTOWIKI
setup_autowiki()
#endif
/world/proc/HandleTestRun()
//trigger things to run the whole process
Master.sleep_offline_after_initializations = FALSE
SSticker.start_immediately = TRUE
CONFIG_SET(number/round_end_countdown, 0)
var/datum/callback/cb
#ifdef UNIT_TESTS
cb = CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(RunUnitTests))
#else
cb = VARSET_CALLBACK(SSticker, force_ending, ADMIN_FORCE_END_ROUND)
#endif
SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(_addtimer), cb, 10 SECONDS))
/// Returns a list of data about the world state, don't clutter
/world/proc/get_world_state_for_logging()
var/data = list()
data["tick_usage"] = world.tick_usage
data["tick_lag"] = world.tick_lag
data["time"] = world.time
data["timestamp"] = rustg_unix_timestamp()
return data
/world/proc/SetupLogs()
var/override_dir = params[OVERRIDE_LOG_DIRECTORY_PARAMETER]
if(!override_dir)
var/realtime = world.realtime
var/texttime = time2text(realtime, "YYYY/MM/DD")
GLOB.log_directory = "data/logs/[texttime]/round-"
GLOB.picture_logging_prefix = "L_[time2text(realtime, "YYYYMMDD")]_"
GLOB.picture_log_directory = "data/picture_logs/[texttime]/round-"
if(GLOB.round_id)
GLOB.log_directory += "[GLOB.round_id]"
GLOB.picture_logging_prefix += "R_[GLOB.round_id]_"
GLOB.picture_log_directory += "[GLOB.round_id]"
else
var/timestamp = replacetext(time_stamp(), ":", ".")
GLOB.log_directory += "[timestamp]"
GLOB.picture_log_directory += "[timestamp]"
GLOB.picture_logging_prefix += "T_[timestamp]_"
else
GLOB.log_directory = "data/logs/[override_dir]"
GLOB.picture_logging_prefix = "O_[override_dir]_"
GLOB.picture_log_directory = "data/picture_logs/[override_dir]"
logger.init_logging()
if(GLOB.tracy_log)
rustg_file_write("[GLOB.tracy_log]", "[GLOB.log_directory]/tracy.loc")
var/latest_changelog = file("[global.config.directory]/../html/changelogs/archive/" + time2text(world.timeofday, "YYYY-MM") + ".yml")
GLOB.changelog_hash = fexists(latest_changelog) ? md5(latest_changelog) : 0 //for telling if the changelog has changed recently
if(GLOB.round_id)
log_game("Round ID: [GLOB.round_id]")
// This was printed early in startup to the world log and config_error.log,
// but those are both private, so let's put the commit info in the runtime
// log which is ultimately public.
log_runtime(GLOB.revdata.get_log_message())
#ifndef USE_CUSTOM_ERROR_HANDLER
world.log = file("[GLOB.log_directory]/dd.log")
#else
if (TgsAvailable()) // why
world.log = file("[GLOB.log_directory]/dd.log") //not all runtimes trigger world/Error, so this is the only way to ensure we can see all of them.
#endif
/world/Topic(T, addr, master, key)
TGS_TOPIC //redirect to server tools if necessary
var/static/list/topic_handlers = TopicHandlers()
var/list/input = params2list(T)
var/datum/world_topic/handler
for(var/I in topic_handlers)
if(I in input)
handler = topic_handlers[I]
break
if((!handler || initial(handler.log)) && config && CONFIG_GET(flag/log_world_topic))
log_topic("\"[T]\", from:[addr], master:[master], key:[key]")
if(!handler)
return
handler = new handler()
return handler.TryRun(input)
/world/proc/AnnouncePR(announcement, list/payload)
var/static/list/PRcounts = list() //PR id -> number of times announced this round
var/id = "[payload["pull_request"]["id"]]"
if(!PRcounts[id])
PRcounts[id] = 1
else
++PRcounts[id]
if(PRcounts[id] > CONFIG_GET(number/pr_announcements_per_round))
return
var/final_composed = span_announce("PR: [announcement]")
for(var/client/C in GLOB.clients)
C.AnnouncePR(final_composed)
/world/proc/FinishTestRun()
set waitfor = FALSE
var/list/fail_reasons
if(GLOB)
if(GLOB.total_runtimes != 0)
fail_reasons = list("Total runtimes: [GLOB.total_runtimes]")
#ifdef UNIT_TESTS
if(GLOB.failed_any_test)
LAZYADD(fail_reasons, "Unit Tests failed!")
#endif
if(!GLOB.log_directory)
LAZYADD(fail_reasons, "Missing GLOB.log_directory!")
else
fail_reasons = list("Missing GLOB!")
if(!fail_reasons)
text2file("Success!", "[GLOB.log_directory]/clean_run.lk")
else
log_world("Test run failed!\n[fail_reasons.Join("\n")]")
sleep(0) //yes, 0, this'll let Reboot finish and prevent byond memes
qdel(src) //shut it down
/world/Reboot(reason = 0, fast_track = FALSE)
if (reason || fast_track) //special reboot, do none of the normal stuff
if (usr)
log_admin("[key_name(usr)] Has requested an immediate world restart via client side debugging tools")
message_admins("[key_name_admin(usr)] Has requested an immediate world restart via client side debugging tools")
to_chat(world, span_boldannounce("Rebooting World immediately due to host request."))
else
to_chat(world, span_boldannounce("Rebooting world..."))
Master.Shutdown() //run SS shutdowns
#ifdef UNIT_TESTS
FinishTestRun()
return
#else
if(TgsAvailable())
var/do_hard_reboot
// check the hard reboot counter
var/ruhr = CONFIG_GET(number/rounds_until_hard_restart)
switch(ruhr)
if(-1)
do_hard_reboot = FALSE
if(0)
do_hard_reboot = TRUE
else
if(GLOB.restart_counter >= ruhr)
do_hard_reboot = TRUE
else
text2file("[++GLOB.restart_counter]", RESTART_COUNTER_PATH)
do_hard_reboot = FALSE
if(do_hard_reboot)
log_world("World hard rebooted at [time_stamp()]")
shutdown_logging() // See comment below.
auxcleanup()
TgsEndProcess()
return ..()
log_world("World rebooted at [time_stamp()]")
shutdown_logging() // Past this point, no logging procs can be used, at risk of data loss.
auxcleanup()
TgsReboot() // TGS can decide to kill us right here, so it's important to do it last
..()
#endif
/world/proc/auxcleanup()
var/debug_server = world.GetConfig("env", "AUXTOOLS_DEBUG_DLL")
if (debug_server)
call_ext(debug_server, "auxtools_shutdown")()
/world/Del()
auxcleanup()
. = ..()
/* SKYRAT EDIT REMOVAL - OVERRIDEN
/world/proc/update_status()
var/list/features = list()
if(LAZYACCESS(SSlag_switch.measures, DISABLE_NON_OBSJOBS))
features += "closed"
var/new_status = ""
var/hostedby
if(config)
var/server_name = CONFIG_GET(string/servername)
if (server_name)
new_status += "<b>[server_name]</b> "
if(CONFIG_GET(flag/allow_respawn))
features += "respawn" // show "respawn" regardless of "respawn as char" or "free respawn"
if(!CONFIG_GET(flag/allow_ai))
features += "AI disabled"
hostedby = CONFIG_GET(string/hostedby)
if (CONFIG_GET(flag/station_name_in_hub_entry))
new_status += " &#8212; <b>[station_name()]</b>"
var/players = GLOB.clients.len
game_state = (CONFIG_GET(number/extreme_popcap) && players >= CONFIG_GET(number/extreme_popcap)) //tells the hub if we are full
if (!host && hostedby)
features += "hosted by <b>[hostedby]</b>"
if(length(features))
new_status += ": [jointext(features, ", ")]"
if(!SSticker || SSticker?.current_state == GAME_STATE_STARTUP)
new_status += "<br><b>STARTING</b>"
else if(SSticker)
if(SSticker.current_state == GAME_STATE_PREGAME && SSticker.GetTimeLeft() > 0)
new_status += "<br>Starting: <b>[round((SSticker.GetTimeLeft())/10)]</b>"
else if(SSticker.current_state == GAME_STATE_SETTING_UP)
new_status += "<br>Starting: <b>Now</b>"
else if(SSticker.IsRoundInProgress())
new_status += "<br>Time: <b>[time2text(STATION_TIME_PASSED(), "hh:mm", 0)]</b>"
if(SSshuttle?.emergency && SSshuttle?.emergency?.mode != (SHUTTLE_IDLE || SHUTTLE_ENDGAME))
new_status += " | Shuttle: <b>[SSshuttle.emergency.getModeStr()] [SSshuttle.emergency.getTimerStr()]</b>"
else if(SSticker.current_state == GAME_STATE_FINISHED)
new_status += "<br><b>RESTARTING</b>"
if(SSmapping.config)
new_status += "<br>Map: <b>[SSmapping.config.map_path == CUSTOM_MAP_PATH ? "Uncharted Territory" : SSmapping.config.map_name]</b>"
if(SSmapping.next_map_config)
new_status += "[SSmapping.config ? " | " : "<br>"]Next: <b>[SSmapping.next_map_config.map_path == CUSTOM_MAP_PATH ? "Uncharted Territory" : SSmapping.next_map_config.map_name]</b>"
status = new_status
*/
/world/proc/update_hub_visibility(new_visibility)
if(new_visibility == GLOB.hub_visibility)
return
GLOB.hub_visibility = new_visibility
if(GLOB.hub_visibility)
hub_password = "kMZy3U5jJHSiBQjr"
else
hub_password = "SORRYNOPASSWORD"
/**
* Handles increasing the world's maxx var and initializing the new turfs and assigning them to the global area.
* If map_load_z_cutoff is passed in, it will only load turfs up to that z level, inclusive.
* This is because maploading will handle the turfs it loads itself.
*/
/world/proc/increase_max_x(new_maxx, map_load_z_cutoff = maxz)
if(new_maxx <= maxx)
return
var/old_max = world.maxx
maxx = new_maxx
if(!map_load_z_cutoff)
return
var/area/global_area = GLOB.areas_by_type[world.area] // We're guaranteed to be touching the global area, so we'll just do this
LISTASSERTLEN(global_area.turfs_by_zlevel, map_load_z_cutoff, list())
for (var/zlevel in 1 to map_load_z_cutoff)
var/list/to_add = block(
locate(old_max + 1, 1, zlevel),
locate(maxx, maxy, zlevel))
global_area.turfs_by_zlevel[zlevel] += to_add
/world/proc/increase_max_y(new_maxy, map_load_z_cutoff = maxz)
if(new_maxy <= maxy)
return
var/old_maxy = maxy
maxy = new_maxy
if(!map_load_z_cutoff)
return
var/area/global_area = GLOB.areas_by_type[world.area] // We're guaranteed to be touching the global area, so we'll just do this
LISTASSERTLEN(global_area.turfs_by_zlevel, map_load_z_cutoff, list())
for (var/zlevel in 1 to map_load_z_cutoff)
var/list/to_add = block(
locate(1, old_maxy + 1, 1),
locate(maxx, maxy, map_load_z_cutoff))
global_area.turfs_by_zlevel[zlevel] += to_add
/world/proc/incrementMaxZ()
maxz++
SSmobs.MaxZChanged()
SSai_controllers.on_max_z_changed()
/world/proc/change_fps(new_value = 20)
if(new_value <= 0)
CRASH("change_fps() called with [new_value] new_value.")
if(fps == new_value)
return //No change required.
fps = new_value
on_tickrate_change()
/world/proc/change_tick_lag(new_value = 0.5)
if(new_value <= 0)
CRASH("change_tick_lag() called with [new_value] new_value.")
if(tick_lag == new_value)
return //No change required.
tick_lag = new_value
on_tickrate_change()
/world/proc/on_tickrate_change()
SStimer?.reset_buckets()
DREAMLUAU_SET_EXECUTION_LIMIT_MILLIS(tick_lag * 100)
/world/proc/init_byond_tracy()
var/library
switch (system_type)
if (MS_WINDOWS)
library = "prof.dll"
if (UNIX)
library = "libprof.so"
else
CRASH("Unsupported platform: [system_type]")
var/init_result = call_ext(library, "init")("block")
if(length(init_result) != 0 && init_result[1] == ".") // if first character is ., then it returned the output filename
return init_result
else if(init_result != "0")
CRASH("Error initializing byond-tracy: [init_result]")
/world/proc/init_debugger()
var/dll = GetConfig("env", "AUXTOOLS_DEBUG_DLL")
if (dll)
call_ext(dll, "auxtools_init")()
enable_debugging()
/world/Profile(command, type, format)
if((command & PROFILE_STOP) || !global.config?.loaded || !CONFIG_GET(flag/forbid_all_profiling))
. = ..()
#undef NO_INIT_PARAMETER
#undef OVERRIDE_LOG_DIRECTORY_PARAMETER
#undef USE_TRACY_PARAMETER
#undef RESTART_COUNTER_PATH