Skip to content

Commit

Permalink
Merge upstream (#218)
Browse files Browse the repository at this point in the history
## About The Pull Request

Merge upstream

## Why It's Good For The Game

New fixes and features
  • Loading branch information
larentoun committed Apr 26, 2024
2 parents 4b8c703 + cf4cc89 commit 8cc0238
Show file tree
Hide file tree
Showing 94 changed files with 1,421 additions and 853 deletions.
12 changes: 6 additions & 6 deletions .github/guides/HARDDELETES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Hard Deletes

> Garbage collection is pretty gothic when you think about it.
> Garbage collection is pretty gothic when you think about it.
>
>An object in code is like a ghost, clinging to its former life, and especially to the people it knew. It can only pass on and truly die when it has dealt with its unfinished business. And only when its been forgotten by everyone who ever knew it. If even one other object remembers it, it has a connection to the living world that lets it keep hanging on
>
Expand Down Expand Up @@ -52,7 +52,7 @@ This of course means they can store that location in memory in another object's
/proc/someshit(mem_location)
var/datum/some_obj = new()
some_obj.reference = mem_location
some_obj.reference = mem_location
```

But what happens when you get rid of the object we're passing around references to? If we just cleared it out from memory, everything that holds a reference to it would suddenly be pointing to nowhere, or worse, something totally different!
Expand Down Expand Up @@ -135,13 +135,13 @@ If that fails, search the object's typepath, and look and see if anything is hol
BYOND currently doesn't have the capability to give us information about where a hard delete is. Fortunately we can search for most all of then ourselves.
The procs to perform this search are hidden behind compile time defines, since they'd be way too risky to expose to admin button pressing

If you're having issues solving a harddel and want to perform this check yourself, go to `_compile_options.dm` and uncomment `TESTING`, `REFERENCE_TRACKING`, and `GC_FAILURE_HARD_LOOKUP`
If you're having issues solving a harddel and want to perform this check yourself, go to `_compile_options.dm` and uncomment `REFERENCE_TRACKING_STANDARD`.

You can read more about what each of these do in that file, but the long and short of it is if something would hard delete our code will search for the reference (This will look like your game crashing, just hold out) and print information about anything it finds to the runtime log, which you can find inside the round folder inside `/data/logs/year/month/day`
You can read more about what each of these do in that file, but the long and short of it is if something would hard delete our code will search for the reference (This will look like your game crashing, just hold out) and print information about anything it finds to [log_dir]/harddels.log, which you can find inside the round folder inside `/data/logs/year/month/day`

It'll tell you what object is holding the ref if it's in an object, or what pattern of list transversal was required to find the ref if it's hiding in a list of some sort
It'll tell you what object is holding the ref if it's in an object, or what pattern of list transversal was required to find the ref if it's hiding in a list of some sort, alongside the references remaining.

## Techniques For Fixing Hard Deletes
## Techniques For Fixing Hard Deletes

Once you've found the issue, it becomes a matter of making sure the ref is cleared as a part of Destroy(). I'm gonna walk you through a few patterns and discuss how you might go about fixing them

Expand Down
234 changes: 118 additions & 116 deletions .github/guides/VISUALS.md

Large diffs are not rendered by default.

23 changes: 19 additions & 4 deletions SQL/database_changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,34 @@ Any time you make a change to the schema files, remember to increment the databa

Make sure to also update `DB_MAJOR_VERSION` and `DB_MINOR_VERSION`, which can be found in `code/__DEFINES/subsystem.dm`.

The latest database version is 5.26; The query to update the schema revision table is:
The latest database version is 5.27; The query to update the schema revision table is:

```sql
INSERT INTO `schema_revision` (`major`, `minor`) VALUES (5, 26);
INSERT INTO `schema_revision` (`major`, `minor`) VALUES (5, 27);
```
or

```sql
INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (5, 26);
INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (5, 27);
```

In any query remember to add a prefix to the table names if you use one.

-----------------------------------------------------
Version 5.27, 26 April 2024, by zephyrtfa
Add the ip intel table
```sql
DROP TABLE IF EXISTS `ipintel`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `ipintel` (
`ip` int(10) unsigned NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`intel` double NOT NULL DEFAULT '0',
PRIMARY KEY (`ip`),
KEY `idx_ipintel` (`ip`,`intel`,`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
```
-----------------------------------------------------
Version 5.26, 03 December 2023, by distributivgesetz
Set the default value of cloneloss to 0, as it's obsolete and it won't be set by blackbox anymore.
Expand Down
14 changes: 14 additions & 0 deletions SQL/tgstation_schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,20 @@ CREATE TABLE `ipintel` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `ipintel_whitelist`
--

DROP TABLE IF EXISTS `ipintel_whitelist`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `ipintel_whitelist` (
`ckey` varchar(32) NOT NULL,
`admin_ckey` varchar(32) NOT NULL,
PRIMARY KEY (`ckey`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `legacy_population`
--
Expand Down
1 change: 1 addition & 0 deletions code/__DEFINES/admin_verb.dm
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ _ADMIN_VERB(verb_path_name, verb_permissions, verb_name, verb_desc, verb_categor
#define ADMIN_CATEGORY_OBJECT "Object"
#define ADMIN_CATEGORY_MAPPING "Mapping"
#define ADMIN_CATEGORY_PROFILE "Profile"
#define ADMIN_CATEGORY_IPINTEL "IPIntel"

// Visibility flags
#define ADMIN_VERB_VISIBLITY_FLAG_MAPPING_DEBUG "Map-Debug"
15 changes: 15 additions & 0 deletions code/__DEFINES/ipintel.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#define IPINTEL_RATE_LIMIT_MINUTE "minute"
#define IPINTEL_RATE_LIMIT_DAY "day"

/// An internal error occurred and the query cannot be processed
#define IPINTEL_UNKNOWN_INTERNAL_ERROR "unknown_internal_error"
/// An error occurred with the query and the result is unknown
#define IPINTEL_UNKNOWN_QUERY_ERROR "unknown_query_error"
/// Cannot query as we are rate limited for the rest of the day
#define IPINTEL_RATE_LIMITED_DAY "rate_limited_day"
/// Cannot query as we are rate limited for the rest of the minute
#define IPINTEL_RATE_LIMITED_MINUTE "rate_limited_minute"
/// The IP address is a VPN or bad IP
#define IPINTEL_BAD_IP "bad_ip"
/// The IP address is not a VPN or bad IP
#define IPINTEL_GOOD_IP "good_ip"
40 changes: 40 additions & 0 deletions code/__DEFINES/pronouns.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/// she, he, they, it "%PRONOUN_they" = "p_they"
/// She, He, They, It "%PRONOUN_They" = "p_They"
/// her, his, their, its "%PRONOUN_their" = "p_their"
/// Her, His, Their, Its "%PRONOUN_Their" = "p_Their"
/// hers, his, theirs, its "%PRONOUN_theirs" = "p_theirs"
/// Hers, His, Theirs, Its "%PRONOUN_Theirs" = "p_Theirs"
/// her, him, them, it "%PRONOUN_them" = "p_them"
/// Her, Him, Them, It "%PRONOUN_Them" = "p_Them"
/// has, have "%PRONOUN_have" = "p_have"
/// is, are "%PRONOUN_are" = "p_are"
/// was, were "%PRONOUN_were" = "p_were"
/// does, do "%PRONOUN_do" = "p_do"
/// she has, he has, they have, it has "%PRONOUN_theyve" = "p_theyve"
/// She has, He has, They have, It has "%PRONOUN_Theyve" = "p_Theyve"
/// she is, he is, they are, it is "%PRONOUN_theyre" = "p_theyre"
/// She is, He is, They are, It is "%PRONOUN_Theyre" = "p_Theyre"
/// s, null (she looks, they look) "%PRONOUN_s" = "p_s"
/// es, null (she goes, they go) "%PRONOUN_es" = "p_es"

/// A list for all the pronoun procs, if you need to iterate or search through it or something.
#define ALL_PRONOUNS list( \
"%PRONOUN_they" = TYPE_PROC_REF(/datum, p_they), \
"%PRONOUN_They" = TYPE_PROC_REF(/datum, p_They), \
"%PRONOUN_their" = TYPE_PROC_REF(/datum, p_their), \
"%PRONOUN_Their" = TYPE_PROC_REF(/datum, p_Their), \
"%PRONOUN_theirs" = TYPE_PROC_REF(/datum, p_theirs), \
"%PRONOUN_Theirs" = TYPE_PROC_REF(/datum, p_Theirs), \
"%PRONOUN_them" = TYPE_PROC_REF(/datum, p_them), \
"%PRONOUN_Them" = TYPE_PROC_REF(/datum, p_Them), \
"%PRONOUN_have" = TYPE_PROC_REF(/datum, p_have), \
"%PRONOUN_are" = TYPE_PROC_REF(/datum, p_are), \
"%PRONOUN_were" = TYPE_PROC_REF(/datum, p_were), \
"%PRONOUN_do" = TYPE_PROC_REF(/datum, p_do), \
"%PRONOUN_theyve" = TYPE_PROC_REF(/datum, p_theyve), \
"%PRONOUN_Theyve" = TYPE_PROC_REF(/datum, p_Theyve), \
"%PRONOUN_theyre" = TYPE_PROC_REF(/datum, p_theyre), \
"%PRONOUN_Theyre" = TYPE_PROC_REF(/datum, p_Theyre), \
"%PRONOUN_s" = TYPE_PROC_REF(/datum, p_s), \
"%PRONOUN_es" = TYPE_PROC_REF(/datum, p_es) \
)
2 changes: 1 addition & 1 deletion code/__DEFINES/subsystems.dm
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
*
* make sure you add an update to the schema_version stable in the db changelog
*/
#define DB_MINOR_VERSION 26
#define DB_MINOR_VERSION 27


//! ## Timing subsystem
Expand Down
2 changes: 0 additions & 2 deletions code/__DEFINES/vv.dm
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@

//Helpers for vv_get_dropdown()
#define VV_DROPDOWN_OPTION(href_key, name) . += "<option value='?_src_=vars;[HrefToken()];[href_key]=TRUE;target=[REF(src)]'>[name]</option>"
//Same with VV_DROPDOWN_OPTION, but global proc doesn't have src
#define VV_DROPDOWN_OPTION_APPEARANCE(thing, href_key, name) . += "<option value='?_src_=vars;[HrefToken()];[href_key]=TRUE;target=[REF(thing)]'>[name]</option>"

// VV HREF KEYS
#define VV_HK_TARGET "target"
Expand Down
2 changes: 1 addition & 1 deletion code/__HELPERS/logging/_logging.dm
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ GLOBAL_LIST_INIT(testing_global_profiler, list("_PROFILE_NAME" = "Global"))
SEND_TEXT(world.log, text)
#endif

#if defined(REFERENCE_DOING_IT_LIVE)
#if defined(REFERENCE_TRACKING_LOG_APART)
#define log_reftracker(msg) log_harddel("## REF SEARCH [msg]")

/proc/log_harddel(text)
Expand Down
23 changes: 23 additions & 0 deletions code/__HELPERS/pronouns.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#define GET_TARGET_PRONOUN(target, pronoun, gender) call(target, ALL_PRONOUNS[pronoun])(gender)

//pronoun procs, for getting pronouns without using the text macros that only work in certain positions
//datums don't have gender, but most of their subtypes do!

/datum/proc/p_they(temp_gender)
return "it"

Expand Down Expand Up @@ -69,6 +72,26 @@
else
return "s"

/// A proc to replace pronouns in a string with the appropriate pronouns for a target atom.
/// Uses associative list access from a __DEFINE list, since associative access is slightly
/// faster
/datum/proc/REPLACE_PRONOUNS(target_string, atom/targeted_atom, targeted_gender = null)
/// If someone specifies targeted_gender we choose that,
/// otherwise we go off the gender of our object
var/gender
if(targeted_gender)
if(!istext(targeted_gender) || !(targeted_gender in list(MALE, FEMALE, PLURAL, NEUTER)))
stack_trace("REPLACE_PRONOUNS called with improper parameters.")
return
gender = targeted_gender
else
gender = targeted_atom.gender
var/regex/pronoun_regex = regex("%PRONOUN(_(they|They|their|Their|theirs|Theirs|them|Them|have|are|were|do|theyve|Theyve|theyre|Theyre|s|es))")
while(pronoun_regex.Find(target_string))
target_string = pronoun_regex.Replace(target_string, GET_TARGET_PRONOUN(targeted_atom, pronoun_regex.match, gender))
return target_string


//like clients, which do have gender.
/client/p_they(temp_gender)
if(!temp_gender)
Expand Down
18 changes: 18 additions & 0 deletions code/_compile_options.dm
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#define FIND_REF_NO_CHECK_TICK
#endif //ifdef GC_FAILURE_HARD_LOOKUP

// Log references in their own file, rather then in runtimes.log
//#define REFERENCE_TRACKING_LOG_APART
#endif //ifdef REFERENCE_TRACKING

/*
Expand All @@ -60,8 +62,24 @@
#define REFERENCE_TRACKING
// actually look for refs
#define GC_FAILURE_HARD_LOOKUP
// Log references in their own file
#define REFERENCE_TRACKING_LOG_APART
#endif // REFERENCE_DOING_IT_LIVE

/// Sets up the reftracker to be used locally, to hunt for hard deletions
/// Errors are logged to [log_dir]/harddels.log
//#define REFERENCE_TRACKING_STANDARD
#ifdef REFERENCE_TRACKING_STANDARD
// compile the backend
#define REFERENCE_TRACKING
// actually look for refs
#define GC_FAILURE_HARD_LOOKUP
// spend ALL our time searching, not just part of it
#define FIND_REF_NO_CHECK_TICK
// Log references in their own file
#define REFERENCE_TRACKING_LOG_APART
#endif // REFERENCE_TRACKING_STANDARD

// If this is uncommented, we do a single run though of the game setup and tear down process with unit tests in between
// #define UNIT_TESTS

Expand Down
13 changes: 13 additions & 0 deletions code/_globalvars/bitfields.dm
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,19 @@ DEFINE_BITFIELD(vis_flags, list(
"VIS_UNDERLAY" = VIS_UNDERLAY,
))

// I am so sorry. Required because vis_flags is both undefinable and unreadable on mutable_appearance
// But we need to display them anyway. See /mutable_appearance/appearance_mirror
DEFINE_BITFIELD(_vis_flags, list(
"VIS_HIDE" = VIS_HIDE,
"VIS_INHERIT_DIR" = VIS_INHERIT_DIR,
"VIS_INHERIT_ICON" = VIS_INHERIT_ICON,
"VIS_INHERIT_ICON_STATE" = VIS_INHERIT_ICON_STATE,
"VIS_INHERIT_ID" = VIS_INHERIT_ID,
"VIS_INHERIT_LAYER" = VIS_INHERIT_LAYER,
"VIS_INHERIT_PLANE" = VIS_INHERIT_PLANE,
"VIS_UNDERLAY" = VIS_UNDERLAY,
))

DEFINE_BITFIELD(zap_flags, list(
"ZAP_ALLOW_DUPLICATES" = ZAP_ALLOW_DUPLICATES,
"ZAP_MACHINE_EXPLOSIVE" = ZAP_MACHINE_EXPLOSIVE,
Expand Down
2 changes: 1 addition & 1 deletion code/_globalvars/logging.dm
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ GLOBAL_PROTECT(##log_var_name);\
DECLARE_LOG(config_error_log, DONT_START_LOG)
DECLARE_LOG(perf_log, DONT_START_LOG) // Declared here but name is set in time_track subsystem

#ifdef REFERENCE_DOING_IT_LIVE
#ifdef REFERENCE_TRACKING_LOG_APART
DECLARE_LOG_NAMED(harddel_log, "harddels", START_LOG)
#endif

Expand Down
13 changes: 9 additions & 4 deletions code/_onclick/ai.dm
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
return

/atom/proc/ai_click_alt(mob/living/silicon/ai/user)
SHOULD_CALL_PARENT(FALSE)
return

/atom/proc/AIShiftClick(mob/living/silicon/ai/user)
Expand All @@ -168,12 +169,13 @@

/obj/machinery/door/airlock/ai_click_alt(mob/living/silicon/ai/user)
if(obj_flags & EMAGGED)
return
return NONE

if(!secondsElectrified)
shock_perm(user)
else
shock_restore(user)
return CLICK_ACTION_SUCCESS

/obj/machinery/door/airlock/AIShiftClick(mob/living/silicon/ai/user) // Opens and closes doors!
if(obj_flags & EMAGGED)
Expand Down Expand Up @@ -237,10 +239,10 @@
/// Toggle APC equipment settings
/obj/machinery/power/apc/ai_click_alt(mob/living/silicon/ai/user)
if(!can_use(user, loud = TRUE))
return
return NONE

if(!is_operational || failure_timer)
return
return CLICK_ACTION_BLOCKING

equipment = equipment ? APC_CHANNEL_OFF : APC_CHANNEL_ON
if (user)
Expand All @@ -250,6 +252,7 @@
user.log_message("turned [enabled_or_disabled] the [src] equipment settings", LOG_GAME)
update_appearance()
update()
return CLICK_ACTION_SUCCESS

/obj/machinery/power/apc/attack_ai_secondary(mob/living/silicon/user, list/modifiers)
if(!can_use(user, loud = TRUE))
Expand All @@ -261,8 +264,9 @@
/* AI Turrets */
/obj/machinery/turretid/ai_click_alt(mob/living/silicon/ai/user) //toggles lethal on turrets
if(ailock)
return
return CLICK_ACTION_BLOCKING
toggle_lethal(user)
return CLICK_ACTION_SUCCESS

/obj/machinery/turretid/AICtrlClick(mob/living/silicon/ai/user) //turns off/on Turrets
if(ailock)
Expand All @@ -275,6 +279,7 @@
balloon_alert(user, "disrupted all active calls")
add_hiddenprint(user)
hangup_all_calls()
return CLICK_ACTION_SUCCESS

//
// Override TurfAdjacent for AltClicking
Expand Down
31 changes: 21 additions & 10 deletions code/controllers/configuration/entries/general.dm
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,9 @@

/datum/config_entry/flag/irc_first_connection_alert // do we notify the irc channel when somebody is connecting for the first time?

/datum/config_entry/string/ipintel_base
default = "check.getipintel.net"

/datum/config_entry/string/ipintel_email

/datum/config_entry/string/ipintel_email/ValidateAndSet(str_val)
Expand All @@ -458,18 +461,26 @@
min_val = 0
max_val = 1

/datum/config_entry/number/ipintel_save_good
default = 12
integer = FALSE
min_val = 0
/datum/config_entry/flag/ipintel_reject_rate_limited
default = TRUE

/datum/config_entry/number/ipintel_save_bad
default = 1
integer = FALSE
min_val = 0
/datum/config_entry/flag/ipintel_reject_bad
default = TRUE

/datum/config_entry/string/ipintel_domain
default = "check.getipintel.net"
/datum/config_entry/flag/ipintel_reject_unknown
default = FALSE

/datum/config_entry/number/ipintel_rate_minute
default = 15

/datum/config_entry/number/ipintel_rate_day
default = 500

/datum/config_entry/number/ipintel_cache_length
default = 7

/datum/config_entry/number/ipintel_exempt_playtime_living
default = 0

/datum/config_entry/flag/aggressive_changelog

Expand Down
Loading

0 comments on commit 8cc0238

Please sign in to comment.