Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
SatinIsle committed Dec 17, 2023
2 parents 9a3c6df + 1d7d5e1 commit 6d58d8a
Show file tree
Hide file tree
Showing 499 changed files with 43,148 additions and 5,018 deletions.
9 changes: 9 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## Enforce text mode and LF line breaks
*.cjs text eol=lf
*.css text eol=lf
*.js text eol=lf
*.jsx text eol=lf
*.scss text eol=lf
*.ts text eol=lf
*.tsx text eol=lf

## Enforce binary mode
*.dll binary
*.exe binary
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/autochangelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Ensure +x on CI directory
run: |
chmod -R +x ./tools/ci
- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: '3.7'
- name: Generate Changelog
Expand Down
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ vchat.db*
*.before
*.pyc
*.pid
data
data/
cfg/

#Ignore everything in datafolder and subdirectories
/data/**/*
/tmp/**/*

#Visual studio stuff
*.vscode/*
!/.vscode/launch.json
Expand Down
8 changes: 8 additions & 0 deletions code/__defines/admin_vr.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,11 @@
#define SMITE_AD_SPAM "Ad Spam"
#define SMITE_AUTOSAVE "10 Second Autosave"
#define SMITE_AUTOSAVE_WIDE "10 Second Autosave (AoE)"
#define MODIFIY_ROBOT_MODULE_ADD "Add a Module"
#define MODIFIY_ROBOT_MODULE_REMOVE "Remove a Module"
#define MODIFIY_ROBOT_APPLY_UPGRADE "Apply an Upgrade"
#define MODIFIY_ROBOT_RADIOC_ADD "Add a Radio Channel"
#define MODIFIY_ROBOT_RADIOC_REMOVE "Remove a Radio Channel"
#define MODIFIY_ROBOT_COMP_ADD "Replace a Component"
#define MODIFIY_ROBOT_COMP_REMOVE "Remove a Component"
#define MODIFIY_ROBOT_RESET_MODULE "Fully Resets a Robot Module"
32 changes: 32 additions & 0 deletions code/__defines/chat.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*!
* Copyright (c) 2020 Aleksej Komarov
* SPDX-License-Identifier: MIT
*/

/// How many chat payloads to keep in history
#define CHAT_RELIABILITY_HISTORY_SIZE 5
/// How many resends to allow before giving up
#define CHAT_RELIABILITY_MAX_RESENDS 3

#define MESSAGE_TYPE_SYSTEM "system"
#define MESSAGE_TYPE_LOCALCHAT "localchat"
#define MESSAGE_TYPE_PLOCALCHAT "plocalchat"
#define MESSAGE_TYPE_RADIO "radio"
#define MESSAGE_TYPE_NIF "nif"
#define MESSAGE_TYPE_INFO "info"
#define MESSAGE_TYPE_WARNING "warning"
#define MESSAGE_TYPE_VORE "vore"
#define MESSAGE_TYPE_DEADCHAT "deadchat"
#define MESSAGE_TYPE_OOC "ooc"
#define MESSAGE_TYPE_LOOC "looc"
#define MESSAGE_TYPE_ADMINPM "adminpm"
#define MESSAGE_TYPE_MENTORPM "mentorpm"
#define MESSAGE_TYPE_COMBAT "combat"
#define MESSAGE_TYPE_ADMINCHAT "adminchat"
#define MESSAGE_TYPE_PRAYER "prayer"
#define MESSAGE_TYPE_MODCHAT "modchat"
#define MESSAGE_TYPE_RLOOC "rlooc"
#define MESSAGE_TYPE_EVENTCHAT "eventchat"
#define MESSAGE_TYPE_ADMINLOG "adminlog"
#define MESSAGE_TYPE_ATTACKLOG "attacklog"
#define MESSAGE_TYPE_DEBUG "debug"
65 changes: 64 additions & 1 deletion code/__defines/cooldowns.dm
Original file line number Diff line number Diff line change
@@ -1,15 +1,78 @@
//// COOLDOWN SYSTEMS
/*
* We have 2 cooldown systems: timer cooldowns (divided between stoppable and regular) and world.time cooldowns.
*
* When to use each?
*
* * Adding a commonly-checked cooldown, like on a subsystem to check for processing
* * * Use the world.time ones, as they are cheaper.
*
* * Adding a rarely-used one for special situations, such as giving an uncommon item a cooldown on a target.
* * * Timer cooldown, as adding a new variable on each mob to track the cooldown of said uncommon item is going too far.
*
* * Triggering events at the end of a cooldown.
* * * Timer cooldown, registering to its signal.
*
* * Being able to check how long left for the cooldown to end.
* * * Either world.time or stoppable timer cooldowns, depending on the other factors. Regular timer cooldowns do not support this.
*
* * Being able to stop the timer before it ends.
* * * Either world.time or stoppable timer cooldowns, depending on the other factors. Regular timer cooldowns do not support this.
*/


/*
* Cooldown system based on an datum-level associative lazylist using timers.
*/

// admin verb cooldowns
#define COOLDOWN_INTERNET_SOUND "internet_sound"

//TIMER COOLDOWN MACROS

#define COMSIG_CD_STOP(cd_index) "cooldown_[cd_index]"
#define COMSIG_CD_RESET(cd_index) "cd_reset_[cd_index]"

#define TIMER_COOLDOWN_START(cd_source, cd_index, cd_time) LAZYSET(cd_source.cooldowns, cd_index, addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(end_cooldown), cd_source, cd_index), cd_time))

/// Checks if a timer based cooldown is NOT finished.
#define TIMER_COOLDOWN_RUNNING(cd_source, cd_index) LAZYACCESS(cd_source.cooldowns, cd_index)

/// Checks if a timer based cooldown is finished.
#define TIMER_COOLDOWN_FINISHED(cd_source, cd_index) (!TIMER_COOLDOWN_RUNNING(cd_source, cd_index))

#define TIMER_COOLDOWN_END(cd_source, cd_index) LAZYREMOVE(cd_source.cooldowns, cd_index)

/*
* Stoppable timer cooldowns.
* Use indexes the same as the regular tiemr cooldowns.
* They make use of the TIMER_COOLDOWN_RUNNING() and TIMER_COOLDOWN_END() macros the same, just not the TIMER_COOLDOWN_START() one.
* A bit more expensive than the regular timers, but can be reset before they end and the time left can be checked.
*/

#define S_TIMER_COOLDOWN_START(cd_source, cd_index, cd_time) LAZYSET(cd_source.cooldowns, cd_index, addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(end_cooldown), cd_source, cd_index), cd_time, TIMER_STOPPABLE))

#define S_TIMER_COOLDOWN_RESET(cd_source, cd_index) reset_cooldown(cd_source, cd_index)

#define S_TIMER_COOLDOWN_TIMELEFT(cd_source, cd_index) (timeleft(TIMER_COOLDOWN_RUNNING(cd_source, cd_index)))


/*
* Cooldown system based on storing world.time on a variable, plus the cooldown time.
* Better performance over timer cooldowns, lower control. Same functionality.
*/

#define COOLDOWN_DECLARE(cd_index) var/##cd_index = 0

#define STATIC_COOLDOWN_DECLARE(cd_index) var/static/##cd_index = 0

#define COOLDOWN_START(cd_source, cd_index, cd_time) (cd_source.cd_index = world.time + (cd_time))

//Returns true if the cooldown has run its course, false otherwise
#define COOLDOWN_FINISHED(cd_source, cd_index) (cd_source.cd_index < world.time)

#define COOLDOWN_RESET(cd_source, cd_index) cd_source.cd_index = 0

#define COOLDOWN_TIMELEFT(cd_source, cd_index) (max(0, cd_source.cd_index - world.time))
#define COOLDOWN_STARTED(cd_source, cd_index) (cd_source.cd_index != 0)

#define COOLDOWN_TIMELEFT(cd_source, cd_index) (max(0, cd_source.cd_index - world.time))
2 changes: 2 additions & 0 deletions code/__defines/logging.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#define SEND_TEXT(target, text) DIRECT_OUTPUT(target, text)
#define WRITE_FILE(file, text) DIRECT_OUTPUT(file, text)
21 changes: 21 additions & 0 deletions code/__defines/subsystems.dm
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,26 @@
var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_GAME, RUNLEVEL_POSTGAME)
#define RUNLEVEL_FLAG_TO_INDEX(flag) (log(2, flag) + 1) // Convert from the runlevel bitfield constants to index in runlevel_flags list

//! ### SS initialization hints
/**
* Negative values incidate a failure or warning of some kind, positive are good.
* 0 and 1 are unused so that TRUE and FALSE are guarenteed to be invalid values.
*/

/// Subsystem failed to initialize entirely. Print a warning, log, and disable firing.
#define SS_INIT_FAILURE -2

/// The default return value which must be overriden. Will succeed with a warning.
#define SS_INIT_NONE -1

/// Subsystem initialized sucessfully.
#define SS_INIT_SUCCESS 2

/// Successful, but don't print anything. Useful if subsystem was disabled.
#define SS_INIT_NO_NEED 3

//! ### SS initialization load orders

// Subsystem init_order, from highest priority to lowest priority
// Subsystems shutdown in the reverse of the order they initialize in
// The numbers just define the ordering, they are meaningless otherwise.
Expand Down Expand Up @@ -104,6 +124,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define FIRE_PRIORITY_ORBIT 7
#define FIRE_PRIORITY_VOTE 8
#define FIRE_PRIORITY_INSTRUMENTS 9
#define FIRE_PRIORITY_PING 10
#define FIRE_PRIORITY_AI 10
#define FIRE_PRIORITY_GARBAGE 15
#define FIRE_PRIORITY_ALARM 20
Expand Down
6 changes: 3 additions & 3 deletions code/__defines/tgui.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
#define TGUI_WINDOW_HARD_LIMIT 9

/// Maximum ping timeout allowed to detect zombie windows
#define TGUI_PING_TIMEOUT 4 SECONDS
#define TGUI_PING_TIMEOUT (4 SECONDS)
/// Used for rate-limiting to prevent DoS by excessively refreshing a TGUI window
#define TGUI_REFRESH_FULL_UPDATE_COOLDOWN 5 SECONDS
#define TGUI_REFRESH_FULL_UPDATE_COOLDOWN (1 SECONDS)

/// Window does not exist
#define TGUI_WINDOW_CLOSED 0
Expand Down Expand Up @@ -36,4 +36,4 @@
#define TGUI_MODAL_OPEN 1
#define TGUI_MODAL_DELEGATE 2
#define TGUI_MODAL_ANSWER 3
#define TGUI_MODAL_CLOSE 4
#define TGUI_MODAL_CLOSE 4
2 changes: 2 additions & 0 deletions code/_global_vars/_regexes.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
//These are a bunch of regex datums for use /((any|every|no|some|head|foot)where(wolf)?\sand\s)+(\.[\.\s]+\s?where\?)?/i
GLOBAL_DATUM_INIT(is_http_protocol, /regex, regex("^https?://"))
64 changes: 64 additions & 0 deletions code/_helpers/icons.dm
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,37 @@ GLOBAL_LIST_EMPTY(cached_examine_icons)

return list(rsc_ref, hash, "asset.[hash]")

/// Gets a dummy savefile for usage in icon generation.
/// Savefiles generated from this proc will be empty.
/proc/get_dummy_savefile(from_failure = FALSE)
var/static/next_id = 0
if(next_id++ > 9)
next_id = 0
var/savefile_path = "tmp/dummy-save-[next_id].sav"
try
if(fexists(savefile_path))
fdel(savefile_path)
return new /savefile(savefile_path)
catch(var/exception/error)
// if we failed to create a dummy once, try again; maybe someone slept somewhere they shouldnt have
if(from_failure) // this *is* the retry, something fucked up
CRASH("get_dummy_savefile failed to create a dummy savefile: '[error]'")
return get_dummy_savefile(from_failure = TRUE)

/**
* Converts an icon to base64. Operates by putting the icon in the iconCache savefile,
* exporting it as text, and then parsing the base64 from that.
* (This relies on byond automatically storing icons in savefiles as base64)
*/
/proc/icon2base64(icon/icon)
if (!isicon(icon))
return FALSE
var/savefile/dummySave = get_dummy_savefile()
WRITE_FILE(dummySave["dummy"], icon)
var/iconData = dummySave.ExportText("dummy")
var/list/partial = splittext(iconData, "{")
return replacetext(copytext_char(partial[2], 3, -5), "\n", "") //if cleanup fails we want to still return the correct base64

///given a text string, returns whether it is a valid dmi icons folder path
/proc/is_valid_dmi_file(icon_path)
if(!istext(icon_path) || !length(icon_path))
Expand Down Expand Up @@ -673,6 +704,39 @@ GLOBAL_LIST_EMPTY(cached_examine_icons)
return get_asset_url(key)
return "<img class='[extra_classes] icon icon-[icon_state]' src='[get_asset_url(key)]'>"

/proc/icon2base64html(target, var/custom_classes = "")
if (!target)
return
var/static/list/bicon_cache = list()
if (isicon(target))
var/icon/target_icon = target
var/icon_base64 = icon2base64(target_icon)

if (target_icon.Height() > world.icon_size || target_icon.Width() > world.icon_size)
var/icon_md5 = md5(icon_base64)
icon_base64 = bicon_cache[icon_md5]
if (!icon_base64) // Doesn't exist yet, make it.
bicon_cache[icon_md5] = icon_base64 = icon2base64(target_icon)


return "<img class='icon icon-misc [custom_classes]' src='data:image/png;base64,[icon_base64]'>"

// Either an atom or somebody fucked up and is gonna get a runtime, which I'm fine with.
var/atom/target_atom = target
var/key = "[istype(target_atom.icon, /icon) ? "[REF(target_atom.icon)]" : target_atom.icon]:[target_atom.icon_state]"


if (!bicon_cache[key]) // Doesn't exist, make it.
var/icon/target_icon = icon(target_atom.icon, target_atom.icon_state, SOUTH, 1)
if (ishuman(target)) // Shitty workaround for a BYOND issue.
var/icon/temp = target_icon
target_icon = icon()
target_icon.Insert(temp, dir = SOUTH)

bicon_cache[key] = icon2base64(target_icon)

return "<img class='icon icon-[target_atom.icon_state] [custom_classes]' src='data:image/png;base64,[bicon_cache[key]]'>"

//Costlier version of icon2html() that uses getFlatIcon() to account for overlays, underlays, etc. Use with extreme moderation, ESPECIALLY on mobs.
/proc/costly_icon2html(thing, target, sourceonly = FALSE)
if (!thing)
Expand Down
24 changes: 3 additions & 21 deletions code/_helpers/logging.dm
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@

for(var/client/C in GLOB.admins)
if(C.is_preference_enabled(/datum/client_preference/debug/show_debug_logs))
to_chat(C, "<span class='filter_debuglog'>DEBUG: [text]</span>")
to_chat(C,
type = MESSAGE_TYPE_DEBUG,
html = "<span class='filter_debuglog'>DEBUG: [text]</span>")

/proc/log_game(text)
if (config.log_game)
Expand Down Expand Up @@ -163,10 +165,6 @@
if(Debug2)
WRITE_LOG(diary, "TOPIC: [text]")

/proc/log_href(text)
// Configs are checked by caller
WRITE_LOG(href_logfile, "HREF: [text]")

/proc/log_unit_test(text)
to_world_log("## UNIT_TEST: [text]")

Expand All @@ -176,22 +174,6 @@
#define log_reftracker(msg)
#endif

/proc/log_tgui(user_or_client, text)
if(!text)
stack_trace("Pointless log_tgui message")
return
var/entry = ""
if(!user_or_client)
entry += "no user"
else if(istype(user_or_client, /mob))
var/mob/user = user_or_client
entry += "[user.ckey] (as [user])"
else if(istype(user_or_client, /client))
var/client/client = user_or_client
entry += "[client.ckey]"
entry += ":\n[text]"
WRITE_LOG(diary, entry)

/proc/log_asset(text)
WRITE_LOG(diary, "ASSET: [text]")

Expand Down
36 changes: 36 additions & 0 deletions code/_helpers/logging/ui.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/proc/log_href(text)
//WRITE_LOG(GLOB.world_href_log, "HREF: [text]")
WRITE_LOG(href_logfile, "HREF: [text]")

/**
* Appends a tgui-related log entry. All arguments are optional.
*/
/proc/log_tgui(user, message, context,
datum/tgui_window/window,
datum/src_object)
var/entry = ""
// Insert user info
if(!user)
entry += "<nobody>"
else if(istype(user, /mob))
var/mob/mob = user
entry += "[mob.ckey] (as [mob] at [mob.x],[mob.y],[mob.z])"
else if(istype(user, /client))
var/client/client = user
entry += "[client.ckey]"
// Insert context
if(context)
entry += " in [context]"
else if(window)
entry += " in [window.id]"
// Resolve src_object
if(!src_object && window?.locked_by)
src_object = window.locked_by.src_object
// Insert src_object info
if(src_object)
entry += "\nUsing: [src_object.type] [REF(src_object)]"
// Insert message
if(message)
entry += "\n[message]"
//WRITE_LOG(GLOB.tgui_log, entry)
WRITE_LOG(diary, entry)
Loading

0 comments on commit 6d58d8a

Please sign in to comment.