From 93b4cb9efedd6fc90824f2e28c2a59f3c162ef4b Mon Sep 17 00:00:00 2001 From: Kyep Date: Sat, 19 Oct 2019 23:56:29 -0700 Subject: [PATCH 01/25] Option to activate forum account when clicking 'forum' button --- interface/interface.dm | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/interface/interface.dm b/interface/interface.dm index 8edded38e93..a733b8fed78 100644 --- a/interface/interface.dm +++ b/interface/interface.dm @@ -47,9 +47,11 @@ set desc = "Visit the forum." set hidden = 1 if(config.forumurl) - if(alert("This will open the forum in your browser. Are you sure?",,"Yes","No")=="No") - return - src << link(config.forumurl) + if(config.forum_link_url && prefs && !prefs.fuid) + if(alert("You need to activate your forum account. Activate now? (takes 2 seconds)",,"Yes","No")=="Yes") + link_forum_account() + if(alert("Open the forum in your browser?",,"Yes","No")=="Yes") + src << link(config.forumurl) else to_chat(src, "The forum URL is not set in the server configuration.") @@ -85,7 +87,7 @@ src << link(config.discordurl) else to_chat(src, "The Discord URL is not set in the server configuration.") - + /client/verb/donate() set name = "Donate" set desc = "Donate to help with hosting costs." @@ -96,7 +98,7 @@ src << link(config.donationsurl) else to_chat(src, "The rules URL is not set in the server configuration.") - + /client/verb/hotkeys_help() set name = "Hotkey Help" set category = "OOC" From 4ccf3f392484fcae0eef72135ee2e4876621c986 Mon Sep 17 00:00:00 2001 From: Kyep Date: Sun, 20 Oct 2019 00:02:28 -0700 Subject: [PATCH 02/25] Better tracking for admin online status --- code/game/jobs/job_exp.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/jobs/job_exp.dm b/code/game/jobs/job_exp.dm index 359981ded4f..1b64b3e8aee 100644 --- a/code/game/jobs/job_exp.dm +++ b/code/game/jobs/job_exp.dm @@ -286,9 +286,9 @@ var/global/list/role_playtime_requirements = list( var/new_exp = list2params(play_records) prefs.exp = new_exp new_exp = sanitizeSQL(new_exp) - var/DBQuery/update_query = dbcon.NewQuery("UPDATE [format_table_name("player")] SET exp = '[new_exp]' WHERE ckey='[ckey]'") + var/DBQuery/update_query = dbcon.NewQuery("UPDATE [format_table_name("player")] SET exp = '[new_exp]',lastseen = Now() WHERE ckey='[ckey]'") if(!update_query.Execute()) var/err = update_query.ErrorMsg() log_game("SQL ERROR during exp_update_client write. Error : \[[err]\]\n") message_admins("SQL ERROR during exp_update_client write. Error : \[[err]\]\n") - return + return \ No newline at end of file From adbe7f1b4324019616b17cc633fc9a0db4c348d6 Mon Sep 17 00:00:00 2001 From: Kyep Date: Sun, 20 Oct 2019 02:19:53 -0700 Subject: [PATCH 03/25] Hide forum link for new players --- code/modules/client/client procs.dm | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 6f971d308fa..410109151ba 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -413,7 +413,7 @@ for(var/mob/M in GLOB.player_list) if(M.client) playercount += 1 - + if(playercount >= 150 && GLOB.panic_bunker_enabled == 0) GLOB.panic_bunker_enabled = 1 message_admins("Panic bunker has been automatically enabled due to playercount surpassing 150") @@ -553,7 +553,7 @@ src << "Sorry but the server is currently not accepting connections from never before seen players. Please try again later." del(src) return // Dont insert or they can just go in again - + var/DBQuery/query_insert = dbcon.NewQuery("INSERT INTO [format_table_name("player")] (id, ckey, firstseen, lastseen, ip, computerid, lastadminrank) VALUES (null, '[ckey]', Now(), Now(), '[sql_ip]', '[sql_computerid]', '[sql_admin_rank]')") if(!query_insert.Execute()) var/err = query_insert.ErrorMsg() @@ -601,8 +601,13 @@ /client/proc/check_forum_link() - if(config.forum_link_url && prefs && !prefs.fuid) - to_chat(src, "You do not have your forum account linked. LINK FORUM ACCOUNT") + if(!config.forum_link_url || !prefs || prefs.fuid) + return + if(config.use_exp_tracking) + var/living_hours = get_exp_type_num(EXP_TYPE_LIVING) / 60 + if(living_hours < 20) + return + to_chat(src, "You have no verified forum account. VERIFY FORUM ACCOUNT") /client/proc/create_oauth_token() var/DBQuery/query_find_token = dbcon.NewQuery("SELECT token FROM [format_table_name("oauth_tokens")] WHERE ckey = '[ckey]' limit 1") @@ -774,7 +779,7 @@ // Change the way they should download resources. if(config.resource_urls) preload_rsc = pick(config.resource_urls) - else + else preload_rsc = 1 // If config.resource_urls is not set, preload like normal. // Most assets are now handled through global_cache.dm getFiles( From a0081713f33fc2d20018860abb00c42fd42973ae Mon Sep 17 00:00:00 2001 From: Kyep Date: Sat, 2 Nov 2019 18:51:59 -0700 Subject: [PATCH 04/25] Adds web playerinfo link --- code/controllers/configuration.dm | 8 ++++++-- code/modules/admin/admin.dm | 2 ++ code/modules/admin/topic.dm | 7 +++++++ config/example/config.txt | 3 +++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 8ae35d52179..d24e4dc94f5 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -79,7 +79,7 @@ var/auto_cryo_ssd_mins = 0 var/ssd_warning = 0 - + var/list_afk_minimum = 5 // How long people have to be AFK before it's listed on the "List AFK players" verb var/traitor_objectives_amount = 2 @@ -144,6 +144,7 @@ var/ipintel_detailsurl = "https://iphub.info/?ip=" var/forum_link_url + var/forum_playerinfo_url var/admin_legacy_system = 0 //Defines whether the server uses the legacy admin system with admins.txt or the SQL system. Config option in config.txt var/ban_legacy_system = 0 //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. Config option in config.txt @@ -244,7 +245,7 @@ //cube monkey limit var/cubemonkeycap = 20 - + // Makes gamemodes respect player limits var/enable_gamemode_player_limit = 0 @@ -354,6 +355,9 @@ if("forum_link_url") config.forum_link_url = value + if("forum_playerinfo_url") + config.forum_playerinfo_url = value + if("log_ooc") config.log_ooc = 1 diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 6967a374b51..1801324e72d 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -100,6 +100,8 @@ var/global/nologevent = 0 body += "Jobban | " body += "Appearance Ban | " body += "Notes | " + if(config.forum_playerinfo_url) + body += "WebInfo | " if(M.client) if(M.client.check_watchlist(M.client.ckey)) body += "Remove from Watchlist | " diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index a318c316532..8db44a1ce53 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -936,6 +936,13 @@ target = text2num(target) show_note(index = target) + else if(href_list["webtools"]) + var/target_ckey = href_list["webtools"] + if(config.forum_playerinfo_url) + var/url_to_open = config.forum_playerinfo_url + target_ckey + if(alert("Open [url_to_open]",,"Yes","No")=="Yes") + usr.client << link(url_to_open) + else if(href_list["shownoteckey"]) var/target_ckey = href_list["shownoteckey"] show_note(target_ckey) diff --git a/config/example/config.txt b/config/example/config.txt index 7dfdc1e413a..27da54922bb 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -213,6 +213,9 @@ GUEST_BAN ## URL to use to link forum accounts. If not set, no link option will be offered. #FORUM_LINK_URL https://example.com/link.php?token= +## URL to use for admins accessing the web-based tools menu +#FORUM_PLAYERINFO_URL https://example.com/info.php?ckey= + ## Comment to disable checking for the cid randomizer dll. (disabled if database isn't enabled or connected) CHECK_RANDOMIZER From de7b8c52e7ee88755a0a7f17d9f865a3d41a686f Mon Sep 17 00:00:00 2001 From: Kyep Date: Sun, 3 Nov 2019 01:00:01 -0800 Subject: [PATCH 05/25] Add link for newly banned people verifying their forum accounts --- code/modules/admin/topic.dm | 4 ++++ code/modules/client/client procs.dm | 17 ++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 8db44a1ce53..4abdc89677c 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1002,6 +1002,8 @@ feedback_inc("ban_tmp",1) DB_ban_record(BANTYPE_TEMP, M, mins, reason) feedback_inc("ban_tmp_mins",mins) + if(M.client) + M.client.link_forum_account(TRUE) if(config.banappeals) to_chat(M, "To try to resolve this matter head to [config.banappeals]") else @@ -1018,6 +1020,8 @@ AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0, M.lastKnownIP) to_chat(M, "You have been banned by [usr.client.ckey].\nReason: [reason].") to_chat(M, "This ban does not expire automatically and must be appealed.") + if(M.client) + M.client.link_forum_account(TRUE) if(config.banappeals) to_chat(M, "To try to resolve this matter head to [config.banappeals]") else diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 410109151ba..644ac6aa123 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -622,12 +622,15 @@ return return tokenstr -/client/proc/link_forum_account() +/client/proc/link_forum_account(fromban) + if(!config.forum_link_url) + return if(IsGuestKey(key)) to_chat(src, "Guest keys cannot be linked.") return if(prefs && prefs.fuid) - to_chat(src, "Your forum account is already set.") + if(!fromban) + to_chat(src, "Your forum account is already set.") return var/DBQuery/query_find_link = dbcon.NewQuery("SELECT fuid FROM [format_table_name("player")] WHERE ckey = '[ckey]' limit 1") if(!query_find_link.Execute()) @@ -635,15 +638,19 @@ return if(query_find_link.NextRow()) if(query_find_link.item[1]) - to_chat(src, "Your forum account is already set. (" + query_find_link.item[1] + ")") + if(!fromban) + to_chat(src, "Your forum account is already set. (" + query_find_link.item[1] + ")") return var/tokenid = create_oauth_token() if(!tokenid) to_chat(src, "link_forum_account: unable to create token") return var/url = "[config.forum_link_url][tokenid]" - to_chat(src, {"Now opening a windows to verify your information with the forums. If the window does not load, please go to: [url]."}) - src << link(url) + if(fromban) + to_chat(src, {"Verify your forum account before you appeal: [url] (this link expires in a few minutes)"}) + else + to_chat(src, {"Now opening a window to verify your information with the forums. If the window does not load, please go to: [url]"}) + src << link(url) return #undef TOPIC_SPAM_DELAY From db82363bfb63ed77916af367286de8c5e09e91ed Mon Sep 17 00:00:00 2001 From: Kyep Date: Wed, 13 Nov 2019 20:41:28 -0800 Subject: [PATCH 06/25] Adds forum-based link config setting --- code/controllers/configuration.dm | 4 ++++ config/example/config.txt | 5 ++++- interface/interface.dm | 14 +++++++++----- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index d24e4dc94f5..86883654997 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -102,6 +102,7 @@ var/donationsurl = "http://example.org" var/repositoryurl = "http://example.org" var/discordurl = "http://example.org" + var/discordforumurl = "http://example.org" var/overflow_server_url var/forbid_singulo_possession = 0 @@ -487,6 +488,9 @@ if("discordurl") config.discordurl = value + if("discordforumurl") + config.discordforumurl = value + if("donationsurl") config.donationsurl = value diff --git a/config/example/config.txt b/config/example/config.txt index 27da54922bb..f4de07f581f 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -240,6 +240,9 @@ CHECK_RANDOMIZER ## Discord address # DISCORDURL http://example.org +## Discord address (forum-based invite) +# DISCORDFORUMURL http://example.org + ## Donations address # DONATIONSURL http://example.org @@ -454,4 +457,4 @@ DISABLE_HIGH_POP_MC_MODE_AMOUNT 60 #START_NOW_CONFIRMATION ## If uncommented, all gamemodes will respect the number of required players. Defaults to no. -#ENABLE_GAMEMODE_PLAYER_LIMIT \ No newline at end of file +#ENABLE_GAMEMODE_PLAYER_LIMIT diff --git a/interface/interface.dm b/interface/interface.dm index a733b8fed78..a97500ccb4f 100644 --- a/interface/interface.dm +++ b/interface/interface.dm @@ -81,12 +81,16 @@ set name = "Discord" set desc = "Join our Discord server." set hidden = 1 - if(config.discordurl) - if(alert("This will invite you to our Discord server. Are you sure?",,"Yes","No")=="No") - return - src << link(config.discordurl) - else + + var/durl = config.discordurl + if(config.forum_link_url && prefs && prefs.fuid && config.discordforumurl) + durl = config.discordforumurl + if(!durl) to_chat(src, "The Discord URL is not set in the server configuration.") + return + if(alert("This will invite you to our Discord server. Are you sure?",,"Yes","No")=="No") + return + src << link(durl) /client/verb/donate() set name = "Donate" From 7acb902388d3afc85cd362380f8be4f08f5405e0 Mon Sep 17 00:00:00 2001 From: Kyep Date: Sun, 15 Dec 2019 16:28:36 -0800 Subject: [PATCH 07/25] SQL update: track playtime per player per day for stats --- SQL/paradise_schema.sql | 15 +++++++++++++++ SQL/paradise_schema_prefixed.sql | 14 ++++++++++++++ SQL/updates/9-10.sql | 11 +++++++++++ code/__DEFINES/misc.dm | 2 +- code/game/jobs/job_exp.dm | 14 ++++++++++++-- config/example/dbconfig.txt | 2 +- 6 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 SQL/updates/9-10.sql diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index 1e4692b7e3b..445de8b4d08 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -565,3 +565,18 @@ CREATE TABLE `oauth_tokens` ( PRIMARY KEY (`token`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; + + +-- +-- Table structure for table `playtime_history` +-- +DROP TABLE IF EXISTS `playtime_history`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `playtime_history` ( + `ckey` varchar(32) NOT NULL, + `date` DATE NOT NULL, + `time_living` SMALLINT NOT NULL, + `time_ghost` SMALLINT NOT NULL, + PRIMARY KEY (`ckey`, `date`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; \ No newline at end of file diff --git a/SQL/paradise_schema_prefixed.sql b/SQL/paradise_schema_prefixed.sql index aa5d5895e56..f70593fc1ac 100644 --- a/SQL/paradise_schema_prefixed.sql +++ b/SQL/paradise_schema_prefixed.sql @@ -564,3 +564,17 @@ CREATE TABLE `SS13_oauth_tokens` ( PRIMARY KEY (`token`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `SS13_playtime_history` +-- +DROP TABLE IF EXISTS `SS13_playtime_history`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `SS13_playtime_history` ( + `ckey` varchar(32) NOT NULL, + `date` DATE NOT NULL, + `time_living` SMALLINT NOT NULL, + `time_ghost` SMALLINT NOT NULL, + PRIMARY KEY (`ckey`, `date`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; \ No newline at end of file diff --git a/SQL/updates/9-10.sql b/SQL/updates/9-10.sql new file mode 100644 index 00000000000..f82e7c56830 --- /dev/null +++ b/SQL/updates/9-10.sql @@ -0,0 +1,11 @@ +# Updating SQL from ver 9 to 10 - Kyet + +# Add the 'playtime_history' table that tracks playtime per player per day +CREATE TABLE `playtime_history` ( + `ckey` varchar(32) NOT NULL, + `date` DATE NOT NULL, + `time_living` SMALLINT NOT NULL, + `time_ghost` SMALLINT NOT NULL, + PRIMARY KEY (`ckey`, `date`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 7dd5fc5a609..5a2c087e1fd 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -319,7 +319,7 @@ #define INVESTIGATE_BOMB "bombs" // The SQL version required by this version of the code -#define SQL_VERSION 9 +#define SQL_VERSION 10 // Vending machine stuff #define CAT_NORMAL 1 diff --git a/code/game/jobs/job_exp.dm b/code/game/jobs/job_exp.dm index 1b64b3e8aee..b69dbfd3ed4 100644 --- a/code/game/jobs/job_exp.dm +++ b/code/game/jobs/job_exp.dm @@ -263,8 +263,11 @@ var/global/list/role_playtime_requirements = list( myrole = mob.mind.playtime_role else if(mob.mind.assigned_role) myrole = mob.mind.assigned_role + var/added_living = 0 + var/added_ghost = 0 if(mob.stat == CONSCIOUS && myrole) play_records[EXP_TYPE_LIVING] += minutes + added_living += minutes if(announce_changes) to_chat(mob,"You got: [minutes] Living EXP!") for(var/category in exp_jobsmap) @@ -279,6 +282,7 @@ var/global/list/role_playtime_requirements = list( to_chat(mob,"You got: [minutes] Special EXP!") else if(isobserver(mob)) play_records[EXP_TYPE_GHOST] += minutes + added_ghost += minutes if(announce_changes) to_chat(mob,"You got: [minutes] Ghost EXP!") else @@ -289,6 +293,12 @@ var/global/list/role_playtime_requirements = list( var/DBQuery/update_query = dbcon.NewQuery("UPDATE [format_table_name("player")] SET exp = '[new_exp]',lastseen = Now() WHERE ckey='[ckey]'") if(!update_query.Execute()) var/err = update_query.ErrorMsg() - log_game("SQL ERROR during exp_update_client write. Error : \[[err]\]\n") - message_admins("SQL ERROR during exp_update_client write. Error : \[[err]\]\n") + log_game("SQL ERROR during exp_update_client write 1. Error : \[[err]\]\n") + message_admins("SQL ERROR during exp_update_client write 1. Error : \[[err]\]\n") + return + var/DBQuery/update_query_history = dbcon.NewQuery("INSERT INTO [format_table_name("playtime_history")] (ckey, date, time_living, time_ghost) VALUES ('[ckey]',CURDATE(),[added_living],[added_ghost]) ON DUPLICATE KEY UPDATE time_living=time_living+VALUES(time_living),time_ghost=time_ghost+VALUES(time_ghost)") + if(!update_query_history.Execute()) + var/err = update_query_history.ErrorMsg() + log_game("SQL ERROR during exp_update_client write 2. Error : \[[err]\]\n") + message_admins("SQL ERROR during exp_update_client write 2. Error : \[[err]\]\n") return \ No newline at end of file diff --git a/config/example/dbconfig.txt b/config/example/dbconfig.txt index ad859d92543..654a7e348d5 100644 --- a/config/example/dbconfig.txt +++ b/config/example/dbconfig.txt @@ -9,7 +9,7 @@ ## This value must be set to the version of the paradise schema in use. ## If this value does not match, the SQL database will not be loaded and an error will be generated. ## Roundstart will be delayed. -DB_VERSION 9 +DB_VERSION 10 ## Server the MySQL database can be found at. # Examples: localhost, 200.135.5.43, www.mysqldb.com, etc. From 9783ac1598554f0f6d74731038d5ef8376c1fad4 Mon Sep 17 00:00:00 2001 From: Kyep Date: Sun, 15 Dec 2019 18:04:06 -0800 Subject: [PATCH 08/25] add mentor to list of predefined admin ranks --- code/modules/admin/topic.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 4abdc89677c..dfba257b66c 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -212,7 +212,7 @@ if(admin_ranks.len) new_rank = input("Please select a rank", "New rank", null, null) as null|anything in (admin_ranks|"*New Rank*") else - new_rank = input("Please select a rank", "New rank", null, null) as null|anything in list("Game Master","Game Admin", "Trial Admin", "Admin Observer","*New Rank*") + new_rank = input("Please select a rank", "New rank", null, null) as null|anything in list("Mentor", "Trial Admin", "Game Admin", "*New Rank*") var/rights = 0 if(D) From 76f4c88fea6d9d9d171771a27e0848b0a587ea82 Mon Sep 17 00:00:00 2001 From: Kyep Date: Sun, 15 Dec 2019 18:30:31 -0800 Subject: [PATCH 09/25] fixes admin_log not working, flags edited admins/mentors for sync --- code/modules/admin/permissionverbs/permissionedit.dm | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/code/modules/admin/permissionverbs/permissionedit.dm b/code/modules/admin/permissionverbs/permissionedit.dm index 9d9e60db014..57d58533437 100644 --- a/code/modules/admin/permissionverbs/permissionedit.dm +++ b/code/modules/admin/permissionverbs/permissionedit.dm @@ -86,17 +86,18 @@ new_admin = 0 admin_id = text2num(select_query.item[1]) + flag_account_for_forum_sync(adm_ckey) if(new_admin) var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO [format_table_name("admin")] (`id`, `ckey`, `rank`, `level`, `flags`) VALUES (null, '[adm_ckey]', '[new_rank]', -1, 0)") insert_query.Execute() - var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.[format_table_name("admin_log")] (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added new admin [adm_ckey] to rank [new_rank]');") + var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (Now() , '[usr.ckey]', '[usr.client.address]', 'Added new admin [adm_ckey] to rank [new_rank]');") log_query.Execute() to_chat(usr, "New admin added.") else if(!isnull(admin_id) && isnum(admin_id)) var/DBQuery/insert_query = dbcon.NewQuery("UPDATE [format_table_name("admin")] SET rank = '[new_rank]' WHERE id = [admin_id]") insert_query.Execute() - var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.[format_table_name("admin_log")] (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Edited the rank of [adm_ckey] to [new_rank]');") + var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (Now() , '[usr.ckey]', '[usr.client.address]', 'Edited the rank of [adm_ckey] to [new_rank]');") log_query.Execute() to_chat(usr, "Admin rank changed.") @@ -141,16 +142,17 @@ if(!admin_id) return + flag_account_for_forum_sync(adm_ckey) if(admin_rights & new_permission) //This admin already has this permission, so we are removing it. var/DBQuery/insert_query = dbcon.NewQuery("UPDATE [format_table_name("admin")] SET flags = [admin_rights & ~new_permission] WHERE id = [admin_id]") insert_query.Execute() - var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.[format_table_name("admin_log")] (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Removed permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]');") + var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (Now() , '[usr.ckey]', '[usr.client.address]', 'Removed permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]');") log_query.Execute() to_chat(usr, "Permission removed.") else //This admin doesn't have this permission, so we are adding it. var/DBQuery/insert_query = dbcon.NewQuery("UPDATE [format_table_name("admin")] SET flags = '[admin_rights | new_permission]' WHERE id = [admin_id]") insert_query.Execute() - var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.[format_table_name("admin_log")] (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]')") + var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (Now() , '[usr.ckey]', '[usr.client.address]', 'Added permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]')") log_query.Execute() to_chat(usr, "Permission added.") @@ -165,3 +167,4 @@ var/DBQuery/query_update = dbcon.NewQuery("UPDATE [format_table_name("player")] SET lastadminrank = '[sql_admin_rank]' WHERE ckey = '[sql_ckey]'") query_update.Execute() + flag_account_for_forum_sync(sql_ckey) \ No newline at end of file From fe53a5acf9a2dcd3a62043229fd08251359b7cf7 Mon Sep 17 00:00:00 2001 From: Kyep Date: Sun, 15 Dec 2019 19:19:50 -0800 Subject: [PATCH 10/25] fixes broken watchlist functionality --- code/modules/admin/admin.dm | 2 +- code/modules/admin/watchlist.dm | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 1801324e72d..55fb1c4047a 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -103,7 +103,7 @@ var/global/nologevent = 0 if(config.forum_playerinfo_url) body += "WebInfo | " if(M.client) - if(M.client.check_watchlist(M.client.ckey)) + if(check_watchlist(M.client.ckey)) body += "Remove from Watchlist | " body += "Edit Watchlist Reason " else diff --git a/code/modules/admin/watchlist.dm b/code/modules/admin/watchlist.dm index 040bc08112b..a908c2c264b 100644 --- a/code/modules/admin/watchlist.dm +++ b/code/modules/admin/watchlist.dm @@ -113,9 +113,7 @@ output += "
[reason]
" usr << browse(output, "window=watchwin;size=900x500") -/client/proc/check_watchlist(target_ckey) - if(!check_rights(R_ADMIN,0)) - return +/proc/check_watchlist(target_ckey) var/target_sql_ckey = sanitizeSQL(target_ckey) var/DBQuery/query_watch = dbcon.NewQuery("SELECT reason FROM [format_table_name("watch")] WHERE ckey = '[target_sql_ckey]'") if(!query_watch.Execute()) From a4e6dba7384fe08168684d757cfd0e67961b4aac Mon Sep 17 00:00:00 2001 From: Kyep Date: Mon, 16 Dec 2019 15:55:04 -0800 Subject: [PATCH 11/25] fixes connection logging to DB not working --- SQL/paradise_schema.sql | 14 ++++++++++++++ SQL/paradise_schema_prefixed.sql | 13 +++++++++++++ SQL/updates/9-10.sql | 10 ++++++++++ code/modules/client/client procs.dm | 5 ++--- 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index 445de8b4d08..bfab9ba76ce 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -579,4 +579,18 @@ CREATE TABLE `playtime_history` ( `time_living` SMALLINT NOT NULL, `time_ghost` SMALLINT NOT NULL, PRIMARY KEY (`ckey`, `date`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + + +-- +-- Table structure for table `connection_log` +-- +DROP TABLE IF EXISTS `connection_log`; +CREATE TABLE `connection_log` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `datetime` datetime NOT NULL, + `ckey` varchar(32) NOT NULL, + `ip` varchar(32) NOT NULL, + `computerid` varchar(32) NOT NULL, + PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; \ No newline at end of file diff --git a/SQL/paradise_schema_prefixed.sql b/SQL/paradise_schema_prefixed.sql index f70593fc1ac..a83c93b7c38 100644 --- a/SQL/paradise_schema_prefixed.sql +++ b/SQL/paradise_schema_prefixed.sql @@ -577,4 +577,17 @@ CREATE TABLE `SS13_playtime_history` ( `time_living` SMALLINT NOT NULL, `time_ghost` SMALLINT NOT NULL, PRIMARY KEY (`ckey`, `date`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +-- +-- Table structure for table `SS13_connection_log` +-- +DROP TABLE IF EXISTS `SS13_connection_log`; +CREATE TABLE `SS13_connection_log` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `datetime` datetime NOT NULL, + `ckey` varchar(32) NOT NULL, + `ip` varchar(32) NOT NULL, + `computerid` varchar(32) NOT NULL, + PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; \ No newline at end of file diff --git a/SQL/updates/9-10.sql b/SQL/updates/9-10.sql index f82e7c56830..aded1301b82 100644 --- a/SQL/updates/9-10.sql +++ b/SQL/updates/9-10.sql @@ -9,3 +9,13 @@ CREATE TABLE `playtime_history` ( PRIMARY KEY (`ckey`, `date`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; +# Add the 'connection_log' table, which is used to log all connections to the server +DROP TABLE IF EXISTS `connection_log`; +CREATE TABLE `connection_log` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `datetime` datetime NOT NULL, + `ckey` varchar(32) NOT NULL, + `ip` varchar(32) NOT NULL, + `computerid` varchar(32) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 644ac6aa123..082ce969695 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -560,9 +560,8 @@ log_game("SQL ERROR during log_client_to_db (insert). Error : \[[err]\]\n") message_admins("SQL ERROR during log_client_to_db (insert). Error : \[[err]\]\n") - //Logging player access - var/serverip = "[world.internet_address]:[world.port]" - var/DBQuery/query_accesslog = dbcon.NewQuery("INSERT INTO `[format_table_name("connection_log")]`(`id`,`datetime`,`serverip`,`ckey`,`ip`,`computerid`) VALUES(null,Now(),'[serverip]','[ckey]','[sql_ip]','[sql_computerid]');") + // Log player connections to DB + var/DBQuery/query_accesslog = dbcon.NewQuery("INSERT INTO `[format_table_name("connection_log")]`(`datetime`,`ckey`,`ip`,`computerid`) VALUES(Now(),'[ckey]','[sql_ip]','[sql_computerid]');") query_accesslog.Execute() /client/proc/check_ip_intel() From 91a63e97a795acad217c3bc5019d873502f9cad6 Mon Sep 17 00:00:00 2001 From: Kyep Date: Mon, 16 Dec 2019 17:20:07 -0800 Subject: [PATCH 12/25] Add: notes are now recorded with player's playtime, for comparison --- SQL/paradise_schema.sql | 1 + SQL/paradise_schema_prefixed.sql | 1 + SQL/updates/9-10.sql | 3 ++ code/modules/admin/sql_notes.dm | 50 ++++++++++++++++++++------------ 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index bfab9ba76ce..01f83ba0194 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -505,6 +505,7 @@ CREATE TABLE `notes` ( `last_editor` varchar(32), `edits` text, `server` varchar(50) NOT NULL, + `crew_playtime` mediumint(8) UNSIGNED DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; diff --git a/SQL/paradise_schema_prefixed.sql b/SQL/paradise_schema_prefixed.sql index a83c93b7c38..9801c54d6f9 100644 --- a/SQL/paradise_schema_prefixed.sql +++ b/SQL/paradise_schema_prefixed.sql @@ -504,6 +504,7 @@ CREATE TABLE `SS13_notes` ( `last_editor` varchar(32), `edits` text, `server` varchar(50) NOT NULL, + `crew_playtime` mediumint(8) UNSIGNED DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; diff --git a/SQL/updates/9-10.sql b/SQL/updates/9-10.sql index aded1301b82..942aca1b541 100644 --- a/SQL/updates/9-10.sql +++ b/SQL/updates/9-10.sql @@ -19,3 +19,6 @@ CREATE TABLE `connection_log` ( `computerid` varchar(32) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +# Add the 'crew_playtime' field to the 'notes' table, which gives admins some idea of how many hours have passed for a player since they got a note +ALTER TABLE `notes` ADD `crew_playtime` mediumint(8) UNSIGNED DEFAULT '0' AFTER `server`; diff --git a/code/modules/admin/sql_notes.dm b/code/modules/admin/sql_notes.dm index 18112f584c2..a6ac31a4114 100644 --- a/code/modules/admin/sql_notes.dm +++ b/code/modules/admin/sql_notes.dm @@ -4,22 +4,30 @@ if(!dbcon.IsConnected()) to_chat(usr, "Failed to establish database connection.") return + if(!target_ckey) var/new_ckey = ckey(clean_input("Who would you like to add a note for?","Enter a ckey",null)) if(!new_ckey) return - new_ckey = ckey(new_ckey) - var/DBQuery/query_find_ckey = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey = '[new_ckey]'") - if(!query_find_ckey.Execute()) - var/err = query_find_ckey.ErrorMsg() - log_game("SQL ERROR obtaining ckey from player table. Error : \[[err]\]\n") - return - if(!query_find_ckey.NextRow()) - to_chat(usr, "[new_ckey] has not been seen before, you can only add notes to known players.") - return - else - target_ckey = new_ckey - var/target_sql_ckey = ckey(target_ckey) + target_ckey = ckey(new_ckey) + else + target_ckey = ckey(target_ckey) + + var/DBQuery/query_find_ckey = dbcon.NewQuery("SELECT ckey, exp FROM [format_table_name("player")] WHERE ckey = '[target_ckey]'") + if(!query_find_ckey.Execute()) + var/err = query_find_ckey.ErrorMsg() + log_game("SQL ERROR obtaining ckey from player table. Error : \[[err]\]\n") + return + if(!query_find_ckey.NextRow()) + to_chat(usr, "[target_ckey] has not been seen before, you can only add notes to known players.") + return + + var/exp_data = query_find_ckey.item[2] + var/crew_number = 0 + if(exp_data) + var/list/play_records = params2list(exp_data) + crew_number = play_records[EXP_TYPE_CREW] + if(!notetext) notetext = input(usr,"Write your note","Add Note") as message|null if(!notetext) @@ -38,7 +46,7 @@ if(config && config.server_name) server = config.server_name server = sanitizeSQL(server) - var/DBQuery/query_noteadd = dbcon.NewQuery("INSERT INTO [format_table_name("notes")] (ckey, timestamp, notetext, adminckey, server) VALUES ('[target_sql_ckey]', '[timestamp]', '[notetext]', '[admin_sql_ckey]', '[server]')") + var/DBQuery/query_noteadd = dbcon.NewQuery("INSERT INTO [format_table_name("notes")] (ckey, timestamp, notetext, adminckey, server, crew_playtime) VALUES ('[target_ckey]', '[timestamp]', '[notetext]', '[admin_sql_ckey]', '[server]', '[crew_number]')") if(!query_noteadd.Execute()) var/err = query_noteadd.ErrorMsg() log_game("SQL ERROR adding new note to table. Error : \[[err]\]\n") @@ -131,10 +139,10 @@ output = navbar if(target_ckey) var/target_sql_ckey = ckey(target_ckey) - var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT id, timestamp, notetext, adminckey, last_editor, server FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]' ORDER BY timestamp") + var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT id, timestamp, notetext, adminckey, last_editor, server, crew_playtime FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]' ORDER BY timestamp") if(!query_get_notes.Execute()) var/err = query_get_notes.ErrorMsg() - log_game("SQL ERROR obtaining ckey, notetext, adminckey, last_editor, server from notes table. Error : \[[err]\]\n") + log_game("SQL ERROR obtaining ckey, notetext, adminckey, last_editor, server, crew_playtime from notes table. Error : \[[err]\]\n") return output += "

Notes of [target_ckey]

" if(!linkless) @@ -147,7 +155,13 @@ var/adminckey = query_get_notes.item[4] var/last_editor = query_get_notes.item[5] var/server = query_get_notes.item[6] - output += "[timestamp] | [server] | [adminckey]" + var/mins = text2num(query_get_notes.item[7]) + output += "[timestamp] | [server] | [adminckey]" + if(mins) + var/playstring = get_exp_format(mins) + output += " | [playstring] as Crew" + output += "" + if(!linkless) output += " \[Remove Note\] \[Edit Note\]" if(last_editor) @@ -182,10 +196,10 @@ /proc/show_player_info_irc(var/key as text) var/target_sql_ckey = ckey(key) - var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT timestamp, notetext, adminckey, server FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]' ORDER BY timestamp") + var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT timestamp, notetext, adminckey, server, crew_playtime FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]' ORDER BY timestamp") if(!query_get_notes.Execute()) var/err = query_get_notes.ErrorMsg() - log_game("SQL ERROR obtaining timestamp, notetext, adminckey, server from notes table. Error : \[[err]\]\n") + log_game("SQL ERROR obtaining timestamp, notetext, adminckey, server, crew_playtime from notes table. Error : \[[err]\]\n") return var/output = " Info on [key]%0D%0A" while(query_get_notes.NextRow()) From 57412d810f053b344aaa6373d5ad65fd2002b584 Mon Sep 17 00:00:00 2001 From: Kyep Date: Sun, 22 Dec 2019 18:17:15 -0800 Subject: [PATCH 13/25] Text clarification --- code/modules/client/client procs.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 082ce969695..51ca4065801 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -646,7 +646,7 @@ return var/url = "[config.forum_link_url][tokenid]" if(fromban) - to_chat(src, {"Verify your forum account before you appeal: [url] (this link expires in a few minutes)"}) + to_chat(src, {"Copy/paste this URL into your browser to activate your forum account before you appeal: [url] (this link expires soon)"}) else to_chat(src, {"Now opening a window to verify your information with the forums. If the window does not load, please go to: [url]"}) src << link(url) From 19ae2b1254592b181f66107fd4c028985d9ad9b4 Mon Sep 17 00:00:00 2001 From: farie82 Date: Tue, 24 Dec 2019 13:50:40 +0100 Subject: [PATCH 14/25] Revert "Move the handle_changeling proc call to the (new) life signal" --- code/__DEFINES/components.dm | 1 - code/game/gamemodes/changeling/evolution_menu.dm | 5 ----- code/modules/mob/living/carbon/life.dm | 2 +- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index f9fba3ff4a4..df957eaa11e 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -155,7 +155,6 @@ // /mob/living/carbon signals #define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity)) -#define COMSIG_CARBON_LIFE "carbon_life" //from base of mob/living/carbon/Life() () // /mob/living/simple_animal/hostile signals #define COMSIG_HOSTILE_ATTACKINGTARGET "hostile_attackingtarget" diff --git a/code/game/gamemodes/changeling/evolution_menu.dm b/code/game/gamemodes/changeling/evolution_menu.dm index a9d1c3bb480..b6a0213f82f 100644 --- a/code/game/gamemodes/changeling/evolution_menu.dm +++ b/code/game/gamemodes/changeling/evolution_menu.dm @@ -383,9 +383,6 @@ var/list/sting_paths var/mob/living/carbon/C = src //only carbons have dna now, so we have to typecaste mind.changeling.absorbed_dna |= C.dna.Clone() mind.changeling.trim_dna() - - RegisterSignal(C, COMSIG_CARBON_LIFE, CALLBACK(C, /mob/living/carbon/.proc/handle_changeling)) - return 1 //Used to dump the languages from the changeling datum into the actual mob. @@ -424,8 +421,6 @@ var/list/sting_paths if(hud_used) hud_used.lingstingdisplay.icon_state = null hud_used.lingstingdisplay.invisibility = 101 - hud_used.lingchemdisplay.invisibility = 101 - UnregisterSignal(src, COMSIG_CARBON_LIFE) /datum/changeling/proc/has_sting(datum/action/power) for(var/datum/action/P in purchasedpowers) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 6898b75b485..5352ba525f1 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -13,13 +13,13 @@ for(var/obj/item/organ/internal/O in internal_organs) O.on_life() + handle_changeling() handle_wetness(times_fired) // Increase germ_level regularly if(germ_level < GERM_LEVEL_AMBIENT && prob(30)) //if you're just standing there, you shouldn't get more germs beyond an ambient level germ_level++ - SEND_SIGNAL(src, COMSIG_CARBON_LIFE, seconds, times_fired) /////////////// // BREATHING // From ad44e867befe6df1603eaff0a8c0050f192ae3e6 Mon Sep 17 00:00:00 2001 From: Kyep Date: Sat, 4 Jan 2020 16:05:42 -0800 Subject: [PATCH 15/25] forum button linking --- interface/interface.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/interface.dm b/interface/interface.dm index a97500ccb4f..f616e41f713 100644 --- a/interface/interface.dm +++ b/interface/interface.dm @@ -48,8 +48,7 @@ set hidden = 1 if(config.forumurl) if(config.forum_link_url && prefs && !prefs.fuid) - if(alert("You need to activate your forum account. Activate now? (takes 2 seconds)",,"Yes","No")=="Yes") - link_forum_account() + link_forum_account() if(alert("Open the forum in your browser?",,"Yes","No")=="Yes") src << link(config.forumurl) else From 6c201f57af2404a88a72082d488b1325ba498d64 Mon Sep 17 00:00:00 2001 From: Kyep Date: Sat, 4 Jan 2020 16:22:08 -0800 Subject: [PATCH 16/25] Add a spam limiter to the goonchat topic calls Port of: https://github.com/tgstation/tgstation/pull/48524/files --- goon/browserassets/js/browserOutput.js | 3 ++- goon/code/datums/browserOutput.dm | 27 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/goon/browserassets/js/browserOutput.js b/goon/browserassets/js/browserOutput.js index 317fc02b9cb..40a69245188 100644 --- a/goon/browserassets/js/browserOutput.js +++ b/goon/browserassets/js/browserOutput.js @@ -416,7 +416,8 @@ function handleClientData(ckey, ip, compid) { } } - if (opts.clientData.length >= opts.clientDataLimit) { + //Lets make sure we obey our limit (can connect from server with higher limit) + while (opts.clientData.length >= opts.clientDataLimit) { opts.clientData.shift(); } } else { diff --git a/goon/code/datums/browserOutput.dm b/goon/code/datums/browserOutput.dm index cbeb7ae3ab0..2ddcd37bb04 100644 --- a/goon/code/datums/browserOutput.dm +++ b/goon/code/datums/browserOutput.dm @@ -16,11 +16,18 @@ var/list/chatResources = list( "goon/browserassets/html/saveInstructions.html" ) +//Should match the value set in the browser js +#define MAX_COOKIE_LENGTH 5 + /var/savefile/iconCache = new /savefile("data/iconCache.sav") /var/chatDebug = file("data/chatDebug.log") /datum/chatOutput var/client/owner = null + // How many times client data has been checked + var/total_checks = 0 + // When to next clear the client data checks counter + var/next_time_to_clear = 0 var/loaded = 0 var/list/messageQueue = list() var/cookieSent = 0 @@ -137,6 +144,16 @@ var/list/chatResources = list( ehjax_send(data = data) /datum/chatOutput/proc/analyzeClientData(cookie = "") + //Spam check + if(world.time > next_time_to_clear) + next_time_to_clear = world.time + (3 SECONDS) + total_checks = 0 + total_checks += 1 + if(total_checks > SPAM_TRIGGER_AUTOMUTE) + message_admins("[key_name(owner)] kicked for goonchat topic spam") + qdel(owner) + return + if(!cookie) return @@ -145,13 +162,21 @@ var/list/chatResources = list( if(connData && islist(connData) && connData.len > 0 && connData["connData"]) connectionHistory = connData["connData"] var/list/found = new() + if(connectionHistory.len > MAX_COOKIE_LENGTH) + message_admins("[key_name(src.owner)] was kicked for an invalid ban cookie)") + qdel(owner) + return for(var/i = connectionHistory.len; i >= 1; i--) + if(QDELETED(owner)) + //he got cleaned up before we were done + return var/list/row = connectionHistory[i] if(!row || row.len < 3 || !(row["ckey"] && row["compid"] && row["ip"])) return if(world.IsBanned(row["ckey"], row["ip"], row["compid"], FALSE)) found = row break + CHECK_TICK //Add autoban using the DB_ban_record function //Uh oh this fucker has a history of playing on a banned account!! if (found.len > 0) @@ -284,3 +309,5 @@ var/to_chat_src to_chat_immediate(target, message, flag) return SSchat.queue(target, message, flag) + +#undef MAX_COOKIE_LENGTH \ No newline at end of file From 05221acd2810d03d0bd50e9a02ea15ade83578fd Mon Sep 17 00:00:00 2001 From: Kyep Date: Sat, 4 Jan 2020 17:23:44 -0800 Subject: [PATCH 17/25] ports TG PRs 32384 and 48583 1) ports https://github.com/tgstation/tgstation/pull/32384 - fixes our world/IsBanned not being updated to account for a BYOND change where the world/IsBanned proc now includes a 4th param, 'type' 2) ports https://github.com/tgstation/tgstation/pull/48583 - changes by MSO which prevent BYOND from degrading server performance during world topic calls 3) future-proofs calls to world/IsBanned by using explicitly named params to avoid this sort of thing happening again if it changes in future --- code/modules/admin/IsBanned.dm | 11 ++++++++++- goon/code/datums/browserOutput.dm | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index 045819c365b..d776b4a2095 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -1,5 +1,5 @@ //Blocks an attempt to connect before even creating our client datum thing. -world/IsBanned(key, address, computer_id, check_ipintel = TRUE) +world/IsBanned(key, address, computer_id, type, check_ipintel = TRUE) if(!config.ban_legacy_system) if(address) @@ -11,11 +11,20 @@ world/IsBanned(key, address, computer_id, check_ipintel = TRUE) log_adminwarn("Failed Login (invalid data): [key] [address]-[computer_id]") return list("reason"="invalid login data", "desc"="Error: Could not check ban status, please try again. Error message: Your computer provided invalid or blank information to the server on connection (BYOND Username, IP, and Computer ID). Provided information for reference: Username: '[key]' IP: '[address]' Computer ID: '[computer_id]'. If you continue to get this error, please restart byond or contact byond support.") + if(type == "world") + return ..() //shunt world topic banchecks to purely to byond's internal ban system + if(text2num(computer_id) == 2147483647) //this cid causes stickybans to go haywire log_adminwarn("Failed Login (invalid cid): [key] [address]-[computer_id]") return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided an invalid Computer ID.") + var/admin = 0 var/ckey = ckey(key) + + var/client/C = GLOB.directory[ckey] + if (C && ckey == C.ckey && computer_id == C.computer_id && address == C.address) + return //don't recheck connected clients. + if((ckey in admin_datums) || (ckey in GLOB.deadmins)) var/datum/admins/A = admin_datums[ckey] if(A && (A.rights & R_ADMIN)) diff --git a/goon/code/datums/browserOutput.dm b/goon/code/datums/browserOutput.dm index cbeb7ae3ab0..4abb3ac20b8 100644 --- a/goon/code/datums/browserOutput.dm +++ b/goon/code/datums/browserOutput.dm @@ -149,7 +149,7 @@ var/list/chatResources = list( var/list/row = connectionHistory[i] if(!row || row.len < 3 || !(row["ckey"] && row["compid"] && row["ip"])) return - if(world.IsBanned(row["ckey"], row["ip"], row["compid"], FALSE)) + if(world.IsBanned(key=row["ckey"], address=row["ip"], computer_id=row["compid"], type=null, check_ipintel=FALSE)) found = row break //Add autoban using the DB_ban_record function From 7dcb34577bbf839f01fd77a2169606f9164e73d8 Mon Sep 17 00:00:00 2001 From: Kyep Date: Sun, 5 Jan 2020 00:01:08 -0800 Subject: [PATCH 18/25] Ports TG/lummox fix to reduce impact of keysend floods --- code/modules/client/message.dm | 7 ++++--- code/modules/keybindings/bindings_client.dm | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/code/modules/client/message.dm b/code/modules/client/message.dm index a5c78008b4f..bcb69255eca 100644 --- a/code/modules/client/message.dm +++ b/code/modules/client/message.dm @@ -4,6 +4,7 @@ proc/addclientmessage(var/ckey, var/message) ckey = ckey(ckey) if(!ckey || !message) return - if(!(ckey in clientmessages)) - clientmessages[ckey] = list() - clientmessages[ckey] += message + var/list/L = GLOB.clientmessages[ckey] + if(!L) + GLOB.clientmessages[ckey] = L = list() + L += message \ No newline at end of file diff --git a/code/modules/keybindings/bindings_client.dm b/code/modules/keybindings/bindings_client.dm index d59e3da4e8e..f38e485d226 100644 --- a/code/modules/keybindings/bindings_client.dm +++ b/code/modules/keybindings/bindings_client.dm @@ -25,7 +25,7 @@ else log_admin("Client [ckey] was just autokicked for flooding keysends; likely abuse but potentially lagspike.") message_admins("Client [ckey] was just autokicked for flooding keysends; likely abuse but potentially lagspike.") - QDEL_IN(src, 1) + qdel(src) return ///Check if the key is short enough to even be a real key @@ -33,7 +33,7 @@ to_chat(src, "Invalid KeyDown detected! You have been disconnected from the server automatically.") log_admin("Client [ckey] just attempted to send an invalid keypress. Keymessage was over [MAX_KEYPRESS_COMMANDLENGTH] characters, autokicking due to likely abuse.") message_admins("Client [ckey] just attempted to send an invalid keypress. Keymessage was over [MAX_KEYPRESS_COMMANDLENGTH] characters, autokicking due to likely abuse.") - QDEL_IN(src, 1) + qdel(src) return //offset by 1 because the buffer address is 0 indexed because the math was simpler keys_held[current_key_address + 1] = _key From f6d332d8292080632ce73130d7ef0939d8f5e53c Mon Sep 17 00:00:00 2001 From: Kyep Date: Sun, 5 Jan 2020 00:08:09 -0800 Subject: [PATCH 19/25] brings paracode more in line with TG --- code/modules/client/client procs.dm | 12 ++++++------ code/modules/client/message.dm | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 6f971d308fa..c8a70a536ae 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -360,10 +360,10 @@ . = ..() //calls mob.Login() - if(ckey in clientmessages) - for(var/message in clientmessages[ckey]) + if(ckey in GLOB.clientmessages) + for(var/message in GLOB.clientmessages[ckey]) to_chat(src, message) - clientmessages.Remove(ckey) + GLOB.clientmessages.Remove(ckey) if(SSinput.initialized) set_macros() @@ -413,7 +413,7 @@ for(var/mob/M in GLOB.player_list) if(M.client) playercount += 1 - + if(playercount >= 150 && GLOB.panic_bunker_enabled == 0) GLOB.panic_bunker_enabled = 1 message_admins("Panic bunker has been automatically enabled due to playercount surpassing 150") @@ -553,7 +553,7 @@ src << "Sorry but the server is currently not accepting connections from never before seen players. Please try again later." del(src) return // Dont insert or they can just go in again - + var/DBQuery/query_insert = dbcon.NewQuery("INSERT INTO [format_table_name("player")] (id, ckey, firstseen, lastseen, ip, computerid, lastadminrank) VALUES (null, '[ckey]', Now(), Now(), '[sql_ip]', '[sql_computerid]', '[sql_admin_rank]')") if(!query_insert.Execute()) var/err = query_insert.ErrorMsg() @@ -774,7 +774,7 @@ // Change the way they should download resources. if(config.resource_urls) preload_rsc = pick(config.resource_urls) - else + else preload_rsc = 1 // If config.resource_urls is not set, preload like normal. // Most assets are now handled through global_cache.dm getFiles( diff --git a/code/modules/client/message.dm b/code/modules/client/message.dm index bcb69255eca..ba09e7e1567 100644 --- a/code/modules/client/message.dm +++ b/code/modules/client/message.dm @@ -1,4 +1,4 @@ -var/list/clientmessages = list() +GLOBAL_LIST_EMPTY(clientmessages) proc/addclientmessage(var/ckey, var/message) ckey = ckey(ckey) From 2208fb3407340bbef1a78b26c7fd0e9529b22985 Mon Sep 17 00:00:00 2001 From: Kyep Date: Mon, 6 Jan 2020 15:23:34 -0800 Subject: [PATCH 20/25] Updates Travis to use byond 513 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 464e01c8f53..146be925c77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,8 +18,8 @@ addons: env: global: - - BYOND_MAJOR="512" - - BYOND_MINOR="1454" + - BYOND_MAJOR="513" + - BYOND_MINOR="1505" - BYOND_MACRO_COUNT=4 matrix: - DM_MAPFILE="cyberiad" From 57d79c6eef1028bb83dcb6ede3fb953d33904a57 Mon Sep 17 00:00:00 2001 From: Kyep Date: Mon, 6 Jan 2020 15:32:55 -0800 Subject: [PATCH 21/25] cleanup --- interface/interface.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/interface.dm b/interface/interface.dm index f616e41f713..4a140769f18 100644 --- a/interface/interface.dm +++ b/interface/interface.dm @@ -47,9 +47,9 @@ set desc = "Visit the forum." set hidden = 1 if(config.forumurl) - if(config.forum_link_url && prefs && !prefs.fuid) - link_forum_account() if(alert("Open the forum in your browser?",,"Yes","No")=="Yes") + if(config.forum_link_url && prefs && !prefs.fuid) + link_forum_account() src << link(config.forumurl) else to_chat(src, "The forum URL is not set in the server configuration.") From 2fd66d8510d37a4caff4391e3c197082c66745fa Mon Sep 17 00:00:00 2001 From: Kyep Date: Mon, 6 Jan 2020 16:01:20 -0800 Subject: [PATCH 22/25] replaces lentext() with length() --- code/__DEFINES/typeids.dm | 2 +- code/__HELPERS/text.dm | 14 +++++++------- code/game/machinery/doors/brigdoors.dm | 2 +- code/game/machinery/supply_display.dm | 2 +- code/game/objects/structures/musician.dm | 14 +++++++------- code/modules/admin/DB ban/functions.dm | 8 ++++---- code/modules/admin/topic.dm | 8 ++++---- code/modules/admin/verbs/modifyvariables.dm | 8 ++++---- code/modules/client/preference/preferences.dm | 10 +++++----- code/modules/clothing/clothing.dm | 2 +- code/modules/flufftext/TextFilters.dm | 4 ++-- code/modules/mob/hear_say.dm | 2 +- code/modules/mob/living/carbon/human/examine.dm | 2 +- code/modules/mob/living/silicon/pai/pai.dm | 2 +- code/modules/mob/living/silicon/robot/examine.dm | 2 +- code/modules/mob/mob.dm | 2 +- code/modules/mob/mob_helpers.dm | 14 +++++++------- code/modules/shuttle/supply.dm | 4 ++-- 18 files changed, 51 insertions(+), 51 deletions(-) diff --git a/code/__DEFINES/typeids.dm b/code/__DEFINES/typeids.dm index 4fd2c390fa7..16b6e475b8e 100644 --- a/code/__DEFINES/typeids.dm +++ b/code/__DEFINES/typeids.dm @@ -2,5 +2,5 @@ #define TYPEID_NULL "0" #define TYPEID_NORMAL_LIST "f" //helper macros -#define GET_TYPEID(ref) ( ( (lentext(ref) <= 10) ? "TYPEID_NULL" : copytext(ref, 4, lentext(ref) - 6) ) ) +#define GET_TYPEID(ref) ( ( (length(ref) <= 10) ? "TYPEID_NULL" : copytext(ref, 4, length(ref) - 6) ) ) #define IS_NORMAL_LIST(L) (GET_TYPEID("\ref[L]") == TYPEID_NORMAL_LIST) \ No newline at end of file diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index f3b76064517..0f356aa4f4a 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -20,7 +20,7 @@ if(!istext(t)) t = "[t]" // Just quietly assume any non-texts are supposed to be text var/sqltext = dbcon.Quote(t); - return copytext(sqltext, 2, lentext(sqltext));//Quote() adds quotes around input, we already do that + return copytext(sqltext, 2, length(sqltext));//Quote() adds quotes around input, we already do that /proc/format_table_name(table as text) return sqlfdbktableprefix + table @@ -333,9 +333,9 @@ proc/checkhtml(var/t) //is in the other string at the same spot (assuming it is not a replace char). //This is used for fingerprints var/newtext = text - if(lentext(text) != lentext(compare)) + if(length(text) != length(compare)) return 0 - for(var/i = 1, i < lentext(text), i++) + for(var/i = 1, i < length(text), i++) var/a = copytext(text,i,i+1) var/b = copytext(compare,i,i+1) //if it isn't both the same letter, or if they are both the replacement character @@ -355,7 +355,7 @@ proc/checkhtml(var/t) if(!text || !character) return 0 var/count = 0 - for(var/i = 1, i <= lentext(text), i++) + for(var/i = 1, i <= length(text), i++) var/a = copytext(text,i,i+1) if(a == character) count++ @@ -400,8 +400,8 @@ proc/checkhtml(var/t) //Used in preferences' SetFlavorText and human's set_flavor verb //Previews a string of len or less length /proc/TextPreview(var/string,var/len=40) - if(lentext(string) <= len) - if(!lentext(string)) + if(length(string) <= len) + if(!length(string)) return "\[...\]" else return html_encode(string) //NO DECODED HTML YOU CHUCKLEFUCKS @@ -541,7 +541,7 @@ proc/checkhtml(var/t) text = "[text]" else text = "[text]" - + text = copytext(text, 1, MAX_PAPER_MESSAGE_LEN) return text diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index f23734a0079..8bd7af5dad4 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -444,7 +444,7 @@ //Stolen from status_display /obj/machinery/door_timer/proc/texticon(tn, px = 0, py = 0) var/image/I = image('icons/obj/status_display.dmi', "blank") - var/len = lentext(tn) + var/len = length(tn) for(var/d = 1 to len) var/char = copytext(tn, len-d+1, len-d+2) diff --git a/code/game/machinery/supply_display.dm b/code/game/machinery/supply_display.dm index d08f68b2914..1fe7ee6e4cb 100644 --- a/code/game/machinery/supply_display.dm +++ b/code/game/machinery/supply_display.dm @@ -14,7 +14,7 @@ else message1 = "CARGO" message2 = SSshuttle.supply.getTimerStr() - if(lentext(message2) > CHARS_PER_LINE) + if(length(message2) > CHARS_PER_LINE) message2 = "Error" update_display(message1, message2) diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm index 274645933b2..da3ec759d36 100644 --- a/code/game/objects/structures/musician.dm +++ b/code/game/objects/structures/musician.dm @@ -88,12 +88,12 @@ if(!playing || shouldStopPlaying(user)) //If the instrument is playing, or special case playing = 0 return - if(lentext(note) == 0) + if(length(note) == 0) continue var/cur_note = text2ascii(note) - 96 if(cur_note < 1 || cur_note > 7) continue - for(var/i=2 to lentext(note)) + for(var/i=2 to length(note)) var/ni = copytext(note,i,i+1) if(!text2num(ni)) if(ni == "#" || ni == "b" || ni == "n") @@ -159,11 +159,11 @@ if(!in_range(instrumentObj, usr)) return - if(lentext(t) >= 12000) + if(length(t) >= 12000) var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no") if(cont == "no") break - while(lentext(t) > 12000) + while(length(t) > 12000) //split into lines spawn() @@ -180,7 +180,7 @@ lines.Cut(201) var/linenum = 1 for(var/l in lines) - if(lentext(l) > 200) + if(length(l) > 200) to_chat(usr, "Line [linenum] too long!") lines.Remove(l) else @@ -223,7 +223,7 @@ return if(lines.len > 200) return - if(lentext(newline) > 200) + if(length(newline) > 200) newline = copytext(newline, 1, 200) lines.Insert(num, newline) @@ -241,7 +241,7 @@ var/content = html_encode(input("Enter your line: ", instrumentObj.name, lines[num]) as text|null) if(!content || !in_range(instrumentObj, usr)) return - if(lentext(content) > 200) + if(length(content) > 200) content = copytext(content, 1, 200) if(num > lines.len || num < 1) return diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm index 1ce6c2b90f0..86a6b228b60 100644 --- a/code/modules/admin/DB ban/functions.dm +++ b/code/modules/admin/DB ban/functions.dm @@ -469,13 +469,13 @@ datum/admins/proc/DB_ban_unban_by_id(var/id) if(playercid) cidsearch = "AND computerid = '[playercid]' " else - if(adminckey && lentext(adminckey) >= 3) + if(adminckey && length(adminckey) >= 3) adminsearch = "AND a_ckey LIKE '[adminckey]%' " - if(playerckey && lentext(playerckey) >= 3) + if(playerckey && length(playerckey) >= 3) playersearch = "AND ckey LIKE '[playerckey]%' " - if(playerip && lentext(playerip) >= 3) + if(playerip && length(playerip) >= 3) ipsearch = "AND ip LIKE '[playerip]%' " - if(playercid && lentext(playercid) >= 7) + if(playercid && length(playercid) >= 7) cidsearch = "AND computerid LIKE '[playercid]%' " if(dbbantype) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index a318c316532..4c1e86d0fd9 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -3066,7 +3066,7 @@ else if(href_list["ac_set_channel_name"]) src.admincaster_feed_channel.channel_name = strip_html_simple(input(usr, "Provide a Feed Channel Name", "Network Channel Handler", "")) while(findtext(src.admincaster_feed_channel.channel_name," ") == 1) - src.admincaster_feed_channel.channel_name = copytext(src.admincaster_feed_channel.channel_name,2,lentext(src.admincaster_feed_channel.channel_name)+1) + src.admincaster_feed_channel.channel_name = copytext(src.admincaster_feed_channel.channel_name,2,length(src.admincaster_feed_channel.channel_name)+1) src.access_news_network() else if(href_list["ac_set_channel_lock"]) @@ -3105,7 +3105,7 @@ else if(href_list["ac_set_new_message"]) src.admincaster_feed_message.body = adminscrub(input(usr, "Write your Feed story", "Network Channel Handler", "")) while(findtext(src.admincaster_feed_message.body," ") == 1) - src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.body,2,lentext(src.admincaster_feed_message.body)+1) + src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.body,2,length(src.admincaster_feed_message.body)+1) src.access_news_network() else if(href_list["ac_submit_new_message"]) @@ -3159,13 +3159,13 @@ else if(href_list["ac_set_wanted_name"]) src.admincaster_feed_message.author = adminscrub(input(usr, "Provide the name of the Wanted person", "Network Security Handler", "")) while(findtext(src.admincaster_feed_message.author," ") == 1) - src.admincaster_feed_message.author = copytext(admincaster_feed_message.author,2,lentext(admincaster_feed_message.author)+1) + src.admincaster_feed_message.author = copytext(admincaster_feed_message.author,2,length(admincaster_feed_message.author)+1) src.access_news_network() else if(href_list["ac_set_wanted_desc"]) src.admincaster_feed_message.body = adminscrub(input(usr, "Provide the a description of the Wanted person and any other details you deem important", "Network Security Handler", "")) while(findtext(src.admincaster_feed_message.body," ") == 1) - src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.body,2,lentext(src.admincaster_feed_message.body)+1) + src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.body,2,length(src.admincaster_feed_message.body)+1) src.access_news_network() else if(href_list["ac_submit_wanted"]) diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index f3be2161bb2..c5348fbeabe 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -306,11 +306,11 @@ var/list/VVpixelmovement = list("step_x", "step_y", "step_size", "bound_height", // the type with the base type removed from the begaining var/fancytype = types[D.type] if(findtext(fancytype, types[type])) - fancytype = copytext(fancytype, lentext(types[type])+1) - var/shorttype = copytext("[D.type]", lentext("[type]")+1) - if(lentext(shorttype) > lentext(fancytype)) + fancytype = copytext(fancytype, length(types[type])+1) + var/shorttype = copytext("[D.type]", length("[type]")+1) + if(length(shorttype) > length(fancytype)) shorttype = fancytype - if(!lentext(shorttype)) + if(!length(shorttype)) shorttype = "/" .["[D]([shorttype])\ref[D]#[i]"] = D diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index 11eb454a241..56cb55b6b80 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -294,8 +294,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts dat += "Disabilities: \[Set\]
" dat += "Nanotrasen Relation: [nanotrasen_relation]
" dat += "Set Flavor Text
" - if(lentext(flavor_text) <= 40) - if(!lentext(flavor_text)) dat += "\[...\]
" + if(length(flavor_text) <= 40) + if(!length(flavor_text)) dat += "\[...\]
" else dat += "[flavor_text]
" else dat += "[TextPreview(flavor_text)]...
" @@ -886,21 +886,21 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts HTML += "Medical Records
" - if(lentext(med_record) <= 40) + if(length(med_record) <= 40) HTML += "[med_record]" else HTML += "[copytext(med_record, 1, 37)]..." HTML += "
Employment Records
" - if(lentext(gen_record) <= 40) + if(length(gen_record) <= 40) HTML += "[gen_record]" else HTML += "[copytext(gen_record, 1, 37)]..." HTML += "
Security Records
" - if(lentext(sec_record) <= 40) + if(length(sec_record) <= 40) HTML += "[sec_record]
" else HTML += "[copytext(sec_record, 1, 37)]...
" diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 84d77d1482e..adb35b0fb3b 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -527,7 +527,7 @@ BLIND // can't see anything end up with a suffix of _open_open if adjusted twice, since their initial state is _open. */ item_state = copytext(item_state, 1, findtext(item_state, "_open")) if(adjust_flavour) - flavour = "[copytext(adjust_flavour, 3, lentext(adjust_flavour) + 1)] up" //Trims off the 'un' at the beginning of the word. unzip -> zip, unbutton->button. + flavour = "[copytext(adjust_flavour, 3, length(adjust_flavour) + 1)] up" //Trims off the 'un' at the beginning of the word. unzip -> zip, unbutton->button. to_chat(user, "You [flavour] \the [src].") suit_adjusted = 0 //Suit is no longer adjusted. for(var/X in actions) diff --git a/code/modules/flufftext/TextFilters.dm b/code/modules/flufftext/TextFilters.dm index 02a02a6f5b2..e00f653ac45 100644 --- a/code/modules/flufftext/TextFilters.dm +++ b/code/modules/flufftext/TextFilters.dm @@ -1,7 +1,7 @@ proc/Intoxicated(phrase) phrase = html_decode(phrase) - var/leng=lentext(phrase) - var/counter=lentext(phrase) + var/leng=length(phrase) + var/counter=length(phrase) var/newphrase="" var/newletter="" while(counter>=1) diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm index 45d4cda2202..a91aeed7bdf 100644 --- a/code/modules/mob/hear_say.dm +++ b/code/modules/mob/hear_say.dm @@ -162,7 +162,7 @@ if(copytext(heardword,1, 1) in punctuation) heardword = copytext(heardword,2) if(copytext(heardword,-1) in punctuation) - heardword = copytext(heardword,1,lentext(heardword)) + heardword = copytext(heardword,1,length(heardword)) heard = "...You hear something about... '[heardword]'..." else heard = "...You almost hear something......" diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index b859041d02f..85bb90a168e 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -376,7 +376,7 @@ msg += "*---------*
" if(pose) - if( findtext(pose,".",lentext(pose)) == 0 && findtext(pose,"!",lentext(pose)) == 0 && findtext(pose,"?",lentext(pose)) == 0 ) + if( findtext(pose,".",length(pose)) == 0 && findtext(pose,"!",length(pose)) == 0 && findtext(pose,"?",length(pose)) == 0 ) pose = addtext(pose,".") //Makes sure all emotes end with a period. msg += "\n[p_they(TRUE)] [p_are()] [pose]" diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 25547e5de9e..4e280b20de8 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -538,7 +538,7 @@ if(print_flavor_text()) msg += "\n[print_flavor_text()]" if(pose) - if( findtext(pose,".",lentext(pose)) == 0 && findtext(pose,"!",lentext(pose)) == 0 && findtext(pose,"?",lentext(pose)) == 0 ) + if( findtext(pose,".",length(pose)) == 0 && findtext(pose,"!",length(pose)) == 0 && findtext(pose,"?",length(pose)) == 0 ) pose = addtext(pose,".") //Makes sure all emotes end with a period. msg += "\nIt is [pose]" msg += "\n*---------*
" diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm index 56d01fea839..198b687e496 100644 --- a/code/modules/mob/living/silicon/robot/examine.dm +++ b/code/modules/mob/living/silicon/robot/examine.dm @@ -50,7 +50,7 @@ if(print_flavor_text()) msg += "\n[print_flavor_text()]\n" if(pose) - if( findtext(pose,".",lentext(pose)) == 0 && findtext(pose,"!",lentext(pose)) == 0 && findtext(pose,"?",lentext(pose)) == 0 ) + if( findtext(pose,".",length(pose)) == 0 && findtext(pose,"!",length(pose)) == 0 && findtext(pose,"?",length(pose)) == 0 ) pose = addtext(pose,".") //Makes sure all emotes end with a period. msg += "\nIt is [pose]" diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index c9e77e294d2..609940bc2a6 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -726,7 +726,7 @@ var/list/slot_equipment_priority = list( \ /mob/proc/print_flavor_text(var/shrink = 1) if(flavor_text && flavor_text != "") var/msg = replacetext(flavor_text, "\n", " ") - if(lentext(msg) <= 40 || !shrink) + if(length(msg) <= 40 || !shrink) return "[html_encode(msg)]" //Repeat after me, "I will not give players access to decoded HTML." else return "[copytext_preserve_html(msg, 1, 37)]... More..." diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 0c2bb902737..a96a832fef4 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -201,8 +201,8 @@ /proc/slur(phrase, var/list/slurletters = ("'"))//use a different list as an input if you want to make robots slur with $#@%! characters phrase = html_decode(phrase) - var/leng=lentext(phrase) - var/counter=lentext(phrase) + var/leng=length(phrase) + var/counter=length(phrase) var/newphrase="" var/newletter="" while(counter>=1) @@ -295,8 +295,8 @@ proc/muffledspeech(phrase) phrase = html_decode(phrase) - var/leng=lentext(phrase) - var/counter=lentext(phrase) + var/leng=length(phrase) + var/counter=length(phrase) var/newphrase="" var/newletter="" while(counter>=1) @@ -571,7 +571,7 @@ var/list/intents = list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM) for(var/datum/objective/objective in GLOB.all_objectives) if(!mind || objective.target != mind) continue - length = lentext(oldname) + length = length(oldname) pos = findtextEx(objective.explanation_text, oldname) objective.explanation_text = copytext(objective.explanation_text, 1, pos)+newname+copytext(objective.explanation_text, pos+length) return 1 @@ -610,8 +610,8 @@ var/list/intents = list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM) /proc/cultslur(n) // Inflicted on victims of a stun talisman var/phrase = html_decode(n) - var/leng = lentext(phrase) - var/counter=lentext(phrase) + var/leng = length(phrase) + var/counter=length(phrase) var/newphrase="" var/newletter="" while(counter>=1) diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index 9da43d08fbf..446b6466dc5 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -475,7 +475,7 @@ SSnanoui.update_uis(src) return 1 - var/index = copytext(href_list["doorder"], 1, lentext(href_list["doorder"])) //text2num(copytext(href_list["doorder"], 1)) + var/index = copytext(href_list["doorder"], 1, length(href_list["doorder"])) //text2num(copytext(href_list["doorder"], 1)) var/multi = text2num(copytext(href_list["doorder"], -1)) if(!isnum(multi)) return 1 @@ -656,7 +656,7 @@ SSnanoui.update_uis(src) return 1 - var/index = copytext(href_list["doorder"], 1, lentext(href_list["doorder"])) //text2num(copytext(href_list["doorder"], 1)) + var/index = copytext(href_list["doorder"], 1, length(href_list["doorder"])) //text2num(copytext(href_list["doorder"], 1)) var/multi = text2num(copytext(href_list["doorder"], -1)) if(!isnum(multi)) return 1 From f9171913c8a9c8136ce6e9db5d83a726f000fc9d Mon Sep 17 00:00:00 2001 From: AffectedArc07 Date: Tue, 7 Jan 2020 19:46:09 +0000 Subject: [PATCH 23/25] Runtime Transparency (#12886) --- code/__HELPERS/_logging.dm | 3 +++ code/_globalvars/logging.dm | 2 ++ code/game/world.dm | 7 +++++++ code/modules/error_handler/error_handler.dm | 3 +++ 4 files changed, 15 insertions(+) diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm index 65fc87c3b34..8c07fe175b2 100644 --- a/code/__HELPERS/_logging.dm +++ b/code/__HELPERS/_logging.dm @@ -140,6 +140,9 @@ /proc/log_asset(text) WRITE_LOG(GLOB.world_asset_log, "ASSET: [text]") +/proc/log_runtime_summary(text) + WRITE_LOG(GLOB.runtime_summary_log, "[text]") + /** * Standardized method for tracking startup times. */ diff --git a/code/_globalvars/logging.dm b/code/_globalvars/logging.dm index 43482937afb..10c7d74c752 100644 --- a/code/_globalvars/logging.dm +++ b/code/_globalvars/logging.dm @@ -12,6 +12,8 @@ GLOBAL_VAR(world_href_log) GLOBAL_PROTECT(world_href_log) GLOBAL_VAR(world_asset_log) GLOBAL_PROTECT(world_asset_log) +GLOBAL_VAR(runtime_summary_log) +GLOBAL_PROTECT(runtime_summary_log) var/list/jobMax = list() var/list/admin_log = list ( ) diff --git a/code/game/world.dm b/code/game/world.dm index b059a7289de..4488cb2d218 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -414,6 +414,13 @@ var/failed_old_db_connections = 0 start_log(GLOB.world_runtime_log) start_log(GLOB.world_qdel_log) + // This log follows a special format and this path should NOT be used for anything else + GLOB.runtime_summary_log = "data/logs/runtime_summary.log" + if(fexists(GLOB.runtime_summary_log)) + fdel(GLOB.runtime_summary_log) + start_log(GLOB.runtime_summary_log) + // And back to sanity + if(fexists(GLOB.config_error_log)) fcopy(GLOB.config_error_log, "[GLOB.log_directory]/config_error.log") fdel(GLOB.config_error_log) diff --git a/code/modules/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm index 09a5d20833e..4888948344a 100644 --- a/code/modules/error_handler/error_handler.dm +++ b/code/modules/error_handler/error_handler.dm @@ -44,6 +44,9 @@ var/total_runtimes_skipped = 0 error_last_seen[erroruid] = world.time error_cooldown[erroruid] = cooldown + // This line will log a runtime summary to a file which can be publicly distributed without sending player data + log_runtime_summary("Runtime in [e.file],[e.line]: [e]") + // The detailed error info needs some tweaking to make it look nice var/list/srcinfo = null var/list/usrinfo = null From cf2145a9535ebe5c181f044a66ec5c6adead9d09 Mon Sep 17 00:00:00 2001 From: Nokko Date: Tue, 7 Jan 2020 11:46:47 -0800 Subject: [PATCH 24/25] Another spelling fix in surgery (#12885) Fixed misspelling in surgery saw fail step --- code/modules/surgery/generic.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm index 54a9c4c88be..39c21bf1ee1 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -1,7 +1,7 @@ -//Procedures in this file: Gneric surgery steps -////////////////////////////////////////////////////////////////// +//Procedures in this file: Generic surgery steps +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // COMMON STEPS // -////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /datum/surgery_step/generic/ can_infect = 1 @@ -237,7 +237,7 @@ /datum/surgery_step/generic/amputate/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) var/obj/item/organ/external/affected = target.get_organ(target_zone) user.visible_message(" [user]'s hand slips, sawing through the bone in [target]'s [affected.name] with \the [tool]!", \ - " Your hand slips, sawwing through the bone in [target]'s [affected.name] with \the [tool]!") + " Your hand slips, sawing through the bone in [target]'s [affected.name] with \the [tool]!") affected.receive_damage(30) affected.fracture() return 0 From 9dc3a18506a775702928d27c9716da0ba3fde774 Mon Sep 17 00:00:00 2001 From: Kyep Date: Thu, 9 Jan 2020 03:56:17 -0800 Subject: [PATCH 25/25] tweaks link message for banned players --- code/modules/client/client procs.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 5248ba22178..962be47cae9 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -646,10 +646,11 @@ return var/url = "[config.forum_link_url][tokenid]" if(fromban) - to_chat(src, {"Copy/paste this URL into your browser to activate your forum account before you appeal: [url] (this link expires soon)"}) + url += "&fwd=appeal" + to_chat(src, {"Now opening a window to verify your information with the forums, so that you can appeal your ban. If the window does not load, please copy/paste this link: [url]"}) else to_chat(src, {"Now opening a window to verify your information with the forums. If the window does not load, please go to: [url]"}) - src << link(url) + src << link(url) return #undef TOPIC_SPAM_DELAY