Artur
2020-04-23 14:19:50 +03:00
parent fe26034410
commit 0b34e20f56
16 changed files with 1303 additions and 92 deletions

View File

@@ -37,28 +37,11 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
return
// asset_cache
var/asset_cache_job
if(href_list["asset_cache_confirm_arrival"])
var/job = text2num(href_list["asset_cache_confirm_arrival"])
//because we skip the limiter, we have to make sure this is a valid arrival and not somebody tricking us
// into letting append to a list without limit.
if (job && job <= last_asset_job && !(job in completed_asset_jobs))
completed_asset_jobs += job
asset_cache_job = asset_cache_confirm_arrival(href_list["asset_cache_confirm_arrival"])
if (!asset_cache_job)
return
else if (job in completed_asset_jobs) //byond bug ID:2256651
to_chat(src, "<span class='danger'>An error has been detected in how your client is receiving resources. Attempting to correct.... (If you keep seeing these messages you might want to close byond and reconnect)</span>")
src << browse("...", "window=asset_cache_browser")
// Keypress passthrough
if(href_list["__keydown"])
var/keycode = browser_keycode_to_byond(href_list["__keydown"])
if(keycode)
keyDown(keycode)
return
if(href_list["__keyup"])
var/keycode = browser_keycode_to_byond(href_list["__keyup"])
if(keycode)
keyUp(keycode)
return
var/mtl = CONFIG_GET(number/minute_topic_limit)
if (!holder && mtl)
@@ -75,7 +58,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
topiclimiter[ADMINSWARNED_AT] = minute
msg += " Administrators have been informed."
log_game("[key_name(src)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute")
message_admins("[ADMIN_LOOKUPFLW(src)] [ADMIN_KICK(usr)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute")
message_admins("[ADMIN_LOOKUPFLW(usr)] [ADMIN_KICK(usr)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute")
to_chat(src, "<span class='danger'>[msg]</span>")
return
@@ -96,23 +79,37 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
if(!(href_list["_src_"] == "chat" && href_list["proc"] == "ping" && LAZYLEN(href_list) == 2))
log_href("[src] (usr:[usr]\[[COORD(usr)]\]) : [hsrc ? "[hsrc] " : ""][href]")
//byond bug ID:2256651
if (asset_cache_job && (asset_cache_job in completed_asset_jobs))
to_chat(src, "<span class='danger'>An error has been detected in how your client is receiving resources. Attempting to correct.... (If you keep seeing these messages you might want to close byond and reconnect)</span>")
src << browse("...", "window=asset_cache_browser")
return
if (href_list["asset_cache_preload_data"])
asset_cache_preload_data(href_list["asset_cache_preload_data"])
return
// Keypress passthrough
if(href_list["__keydown"])
var/keycode = browser_keycode_to_byond(href_list["__keydown"])
if(keycode)
keyDown(keycode)
return
if(href_list["__keyup"])
var/keycode = browser_keycode_to_byond(href_list["__keyup"])
if(keycode)
keyUp(keycode)
return
// Admin PM
if(href_list["priv_msg"])
cmd_admin_pm(href_list["priv_msg"],null)
return
// CITADEL Start - Mentor PM
if (citadel_client_procs(href_list))
return
// CITADEL End
switch(href_list["_src_"])
if("holder")
hsrc = holder
if("usr")
hsrc = mob
if("mentor") // CITADEL
hsrc = mentor_datum // CITADEL END
if("prefs")
if (inprefs)
return
@@ -140,7 +137,6 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
to_chat(src, "Become a BYOND member to access member-perks and features, as well as support the engine that makes this game possible. Only 10 bucks for 3 months! <a href=\"https://secure.byond.com/membership\">Click Here to find out more</a>.")
return 0
return 1
/*
* Call back proc that should be checked in all paths where a client can send messages
*
@@ -259,13 +255,11 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
new /datum/admins(localhost_rank, ckey, 1, 1)
//preferences datum - also holds some persistent data for the client (because we may as well keep these datums to a minimum)
prefs = GLOB.preferences_datums[ckey]
if(prefs)
prefs.parent = src
else
prefs = new /datum/preferences(src)
GLOB.preferences_datums[ckey] = prefs
prefs.last_ip = address //these are gonna be used for banning
prefs.last_id = computer_id //these are gonna be used for banning
fps = prefs.clientfps
@@ -303,12 +297,16 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
player_details = GLOB.player_details[ckey]
player_details.byond_version = full_version
else
player_details = new
player_details = new(ckey)
player_details.byond_version = full_version
GLOB.player_details[ckey] = player_details
. = ..() //calls mob.Login()
if (length(GLOB.stickybanadminexemptions))
GLOB.stickybanadminexemptions -= ckey
if (!length(GLOB.stickybanadminexemptions))
restore_stickybans()
if (byond_version >= 512)
if (!byond_build || byond_build < 1386)
@@ -330,6 +328,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
if(SSinput.initialized)
set_macros()
update_movement_keys()
chatOutput.start() // Starts the chat
@@ -342,12 +341,13 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
connection_timeofday = world.timeofday
winset(src, null, "command=\".configure graphics-hwmode on\"")
var/cev = CONFIG_GET(number/client_error_version)
var/ceb = CONFIG_GET(number/client_error_build)
var/cwv = CONFIG_GET(number/client_warn_version)
if (byond_version < cev) //Out of date client.
if (byond_version < cev || (byond_version == cev && byond_build < ceb)) //Out of date client.
to_chat(src, "<span class='danger'><b>Your version of BYOND is too old:</b></span>")
to_chat(src, CONFIG_GET(string/client_error_message))
to_chat(src, "Your version: [byond_version]")
to_chat(src, "Required version: [cev] or later")
to_chat(src, "Your version: [byond_version].[byond_build]")
to_chat(src, "Required version: [cev].[ceb] or later")
to_chat(src, "Visit <a href=\"https://secure.byond.com/download\">BYOND's website</a> to get the latest version of BYOND.")
if (connecting_admin)
to_chat(src, "Because you are an admin, you are being allowed to walk past this limitation, But it is still STRONGLY suggested you upgrade")
@@ -397,7 +397,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
if (nnpa >= 0)
message_admins("New user: [key_name_admin(src)] is connecting here for the first time.")
if (CONFIG_GET(flag/irc_first_connection_alert))
send2irc_adminless_only("New-user", "[key_name(src)] is connecting for the first time!")
send2tgs_adminless_only("New-user", "[key_name(src)] is connecting for the first time!")
else if (isnum(cached_player_age) && cached_player_age < nnpa)
message_admins("New user: [key_name_admin(src)] just connected with an age of [cached_player_age] day[(player_age==1?"":"s")]")
if(CONFIG_GET(flag/use_account_age_for_jobs) && account_age >= 0)
@@ -405,7 +405,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
if(account_age >= 0 && account_age < nnpa)
message_admins("[key_name_admin(src)] (IP: [address], ID: [computer_id]) is a new BYOND account [account_age] day[(account_age==1?"":"s")] old, created on [account_join_date].")
if (CONFIG_GET(flag/irc_first_connection_alert))
send2irc_adminless_only("new_byond_user", "[key_name(src)] (IP: [address], ID: [computer_id]) is a new BYOND account [account_age] day[(account_age==1?"":"s")] old, created on [account_join_date].")
send2tgs_adminless_only("new_byond_user", "[key_name(src)] (IP: [address], ID: [computer_id]) is a new BYOND account [account_age] day[(account_age==1?"":"s")] old, created on [account_join_date].")
get_message_output("watchlist entry", ckey)
check_ip_intel()
validate_key_in_db()
@@ -466,9 +466,17 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
//////////////
/client/Del()
if(!gc_destroyed)
Destroy() //Clean up signals and timers.
return ..()
/client/Destroy()
GLOB.clients -= src
GLOB.directory -= ckey
log_access("Logout: [key_name(src)]")
GLOB.ahelp_tickets.ClientLogout(src)
if(credits)
QDEL_LIST(credits)
log_access("Logout: [key_name(src)]")
if(holder)
adminGreet(1)
holder.owner = null
@@ -489,19 +497,13 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
"Forever alone :("\
)
send2irc("Server", "[cheesy_message] (No admins online)")
GLOB.ahelp_tickets.ClientLogout(src)
GLOB.directory -= ckey
GLOB.clients -= src
send2tgs("Server", "[cheesy_message] (No admins online)")
QDEL_LIST_ASSOC_VAL(char_render_holders)
if(movingmob != null)
movingmob.client_mobs_in_contents -= mob
UNSETEMPTY(movingmob.client_mobs_in_contents)
Master.UpdateTickRate()
return ..()
/client/Destroy()
. = ..() //Even though we're going to be hard deleted there are still some things that want to know the destroy is happening
return QDEL_HINT_HARDDEL_NOW
/client/proc/set_client_age_from_db(connectiontopic)
@@ -511,7 +513,9 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
return
var/sql_ckey = sanitizeSQL(src.ckey)
var/datum/DBQuery/query_get_related_ip = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ip = INET_ATON('[address]') AND ckey != '[sql_ckey]'")
query_get_related_ip.Execute()
if(!query_get_related_ip.Execute())
qdel(query_get_related_ip)
return
related_accounts_ip = ""
while(query_get_related_ip.NextRow())
related_accounts_ip += "[query_get_related_ip.item[1]], "
@@ -539,10 +543,10 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
qdel(query_client_in_db)
return
if(!query_client_in_db.NextRow())
if (CONFIG_GET(flag/panic_bunker) && !holder && !GLOB.deadmins[ckey] && !(ckey in GLOB.bunker_passthrough))
if (CONFIG_GET(flag/panic_bunker) && !holder && !GLOB.deadmins[ckey])
log_access("Failed Login: [key] - New account attempting to connect during panic bunker")
message_admins("<span class='adminnotice'>Failed Login: [key] - New account attempting to connect during panic bunker</span>")
to_chat(src, "<span class='notice'>You must first join the Discord to verify your account before joining this server.<br>To do so, read the rules and post a request in the #station-access-requests channel under the \"Main server\" category in the Discord server linked here: <a href='https://discord.gg/E6SQuhz'>https://discord.gg/E6SQuhz</a><br>If you have already done so, wait a few minutes then try again; sometimes the server needs to fully load before you can join.</span>") //CIT CHANGE - makes the panic bunker disconnect message point to the discord
to_chat(src, CONFIG_GET(string/panic_bunker_message))
var/list/connectiontopic_a = params2list(connectiontopic)
var/list/panic_addr = CONFIG_GET(string/panic_server_address)
if(panic_addr && !connectiontopic_a["redirect"])
@@ -566,8 +570,6 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
if(!account_join_date)
account_join_date = "Error"
account_age = -1
else if(ckey in GLOB.bunker_passthrough)
GLOB.bunker_passthrough -= ckey
qdel(query_client_in_db)
var/datum/DBQuery/query_get_client_age = SSdbcore.NewQuery("SELECT firstseen, DATEDIFF(Now(),firstseen), accountjoindate, DATEDIFF(Now(),accountjoindate) FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'")
if(!query_get_client_age.Execute())
@@ -691,7 +693,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
if (!cidcheck_failedckeys[ckey])
message_admins("<span class='adminnotice'>[key_name(src)] has been detected as using a cid randomizer. Connection rejected.</span>")
send2irc_adminless_only("CidRandomizer", "[key_name(src)] has been detected as using a cid randomizer. Connection rejected.")
send2tgs_adminless_only("CidRandomizer", "[key_name(src)] has been detected as using a cid randomizer. Connection rejected.")
cidcheck_failedckeys[ckey] = TRUE
note_randomizer_user()
@@ -702,7 +704,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
else
if (cidcheck_failedckeys[ckey])
message_admins("<span class='adminnotice'>[key_name_admin(src)] has been allowed to connect after showing they removed their cid randomizer</span>")
send2irc_adminless_only("CidRandomizer", "[key_name(src)] has been allowed to connect after showing they removed their cid randomizer.")
send2tgs_adminless_only("CidRandomizer", "[key_name(src)] has been allowed to connect after showing they removed their cid randomizer.")
cidcheck_failedckeys -= ckey
if (cidcheck_spoofckeys[ckey])
message_admins("<span class='adminnotice'>[key_name_admin(src)] has been allowed to connect after appearing to have attempted to spoof a cid randomizer check because it <i>appears</i> they aren't spoofing one this time</span>")
@@ -736,7 +738,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
var/sql_system_ckey = sanitizeSQL(system_ckey)
var/sql_ckey = sanitizeSQL(ckey)
//check to see if we noted them in the last day.
var/datum/DBQuery/query_get_notes = SSdbcore.NewQuery("SELECT id FROM [format_table_name("messages")] WHERE type = 'note' AND targetckey = '[sql_ckey]' AND adminckey = '[sql_system_ckey]' AND timestamp + INTERVAL 1 DAY < NOW() AND deleted = 0 AND expire_timestamp > NOW()")
var/datum/DBQuery/query_get_notes = SSdbcore.NewQuery("SELECT id FROM [format_table_name("messages")] WHERE type = 'note' AND targetckey = '[sql_ckey]' AND adminckey = '[sql_system_ckey]' AND timestamp + INTERVAL 1 DAY < NOW() AND deleted = 0 AND (expire_timestamp > NOW() OR expire_timestamp IS NULL)")
if(!query_get_notes.Execute())
qdel(query_get_notes)
return
@@ -745,7 +747,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
return
qdel(query_get_notes)
//regardless of above, make sure their last note is not from us, as no point in repeating the same note over and over.
query_get_notes = SSdbcore.NewQuery("SELECT adminckey FROM [format_table_name("messages")] WHERE targetckey = '[sql_ckey]' AND deleted = 0 AND expire_timestamp > NOW() ORDER BY timestamp DESC LIMIT 1")
query_get_notes = SSdbcore.NewQuery("SELECT adminckey FROM [format_table_name("messages")] WHERE targetckey = '[sql_ckey]' AND deleted = 0 AND (expire_timestamp > NOW() OR expire_timestamp IS NULL) ORDER BY timestamp DESC LIMIT 1")
if(!query_get_notes.Execute())
qdel(query_get_notes)
return
@@ -765,13 +767,19 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
message_admins("<span class='adminnotice'>Proxy Detection: [key_name_admin(src)] IP intel rated [res.intel*100]% likely to be a Proxy/VPN.</span>")
ip_intel = res.intel
/client/Click(atom/object, atom/location, control, params, ignore_spam = FALSE)
/client/Click(atom/object, atom/location, control, params)
var/ab = FALSE
var/list/L = params2list(params)
var/dragged = L["drag"]
if(dragged && !L[dragged])
return
if (object && object == middragatom && L["left"])
ab = max(0, 5 SECONDS-(world.time-middragtime)*0.1)
var/mcl = CONFIG_GET(number/minute_click_limit)
if (!holder && !ignore_spam && mcl)
if (!holder && mcl)
var/minute = round(world.time, 600)
if (!clicklimiter)
clicklimiter = new(LIMITER_SIZE)
@@ -787,16 +795,15 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
msg += " Administrators have been informed."
if (ab)
log_game("[key_name(src)] is using the middle click aimbot exploit")
message_admins("[ADMIN_LOOKUPFLW(src)] [ADMIN_KICK(usr)] is using the middle click aimbot exploit</span>")
message_admins("[ADMIN_LOOKUPFLW(usr)] [ADMIN_KICK(usr)] is using the middle click aimbot exploit</span>")
add_system_note("aimbot", "Is using the middle click aimbot exploit")
log_game("[key_name(src)] Has hit the per-minute click limit of [mcl] clicks in a given game minute")
message_admins("[ADMIN_LOOKUPFLW(src)] [ADMIN_KICK(usr)] Has hit the per-minute click limit of [mcl] clicks in a given game minute")
message_admins("[ADMIN_LOOKUPFLW(usr)] [ADMIN_KICK(usr)] Has hit the per-minute click limit of [mcl] clicks in a given game minute")
to_chat(src, "<span class='danger'>[msg]</span>")
return
var/scl = CONFIG_GET(number/second_click_limit)
if (!holder && !ignore_spam && scl)
if (!holder && scl)
var/second = round(world.time, 10)
if (!clicklimiter)
clicklimiter = new(LIMITER_SIZE)
@@ -808,15 +815,15 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
to_chat(src, "<span class='danger'>Your previous click was ignored because you've done too many in a second</span>")
return
if(ab) //Citadel edit, things with stuff.
return
if (prefs.hotkeys)
// If hotkey mode is enabled, then clicking the map will automatically
// unfocus the text bar. This removes the red color from the text bar
// so that the visual focus indicator matches reality.
winset(src, null, "input.background-color=[COLOR_INPUT_DISABLED]")
else
winset(src, null, "input.focus=true input.background-color=[COLOR_INPUT_ENABLED]")
..()
/client/proc/add_verbs_from_config()
@@ -852,17 +859,18 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
'html/browser/playeroptions.css',
)
spawn (10) //removing this spawn causes all clients to not get verbs.
//load info on what assets the client has
src << browse('code/modules/asset_cache/validate_assets.html', "window=asset_cache_browser")
//Precache the client with all other assets slowly, so as to not block other browse() calls
getFilesSlow(src, SSassets.preload, register_asset = FALSE)
addtimer(CALLBACK(GLOBAL_PROC, /proc/getFilesSlow, src, SSassets.preload, FALSE), 5 SECONDS)
#if (PRELOAD_RSC == 0)
for (var/name in GLOB.vox_sounds)
var/file = GLOB.vox_sounds[name]
Export("##action=load_rsc", file)
stoplag()
for (var/name in GLOB.vox_sounds_male)
var/file = GLOB.vox_sounds_male[name]
Export("##action=load_rsc", file)
stoplag()
#endif
@@ -888,19 +896,33 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
var/viewscale = getviewsize(view)
var/x = viewscale[1]
var/y = viewscale[2]
x = CLAMP(x+change, min, max)
y = CLAMP(y+change, min,max)
x = clamp(x+change, min, max)
y = clamp(y+change, min,max)
change_view("[x]x[y]")
/client/proc/update_movement_keys(datum/preferences/direct_prefs)
var/datum/preferences/D = prefs || direct_prefs
if(!D?.key_bindings)
return
movement_keys = list()
for(var/key in D.key_bindings)
for(var/kb_name in D.key_bindings[key])
switch(kb_name)
if("North")
movement_keys[key] = NORTH
if("East")
movement_keys[key] = EAST
if("West")
movement_keys[key] = WEST
if("South")
movement_keys[key] = SOUTH
/client/proc/change_view(new_size)
if (isnull(new_size))
CRASH("change_view called without argument.")
//CIT CHANGES START HERE - makes change_view change DEFAULT_VIEW to 15x15 depending on preferences
if(prefs && CONFIG_GET(string/default_view))
if(!prefs.widescreenpref && new_size == CONFIG_GET(string/default_view))
new_size = "15x15"
//END OF CIT CHANGES
if(prefs && !prefs.widescreenpref && new_size == CONFIG_GET(string/default_view))
new_size = CONFIG_GET(string/default_view_square)
view = new_size
apply_clickcatcher()
@@ -909,7 +931,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
var/mob/living/M = mob
M.update_damage_hud()
if (prefs.auto_fit_viewport)
fit_viewport()
addtimer(CALLBACK(src,.verb/fit_viewport,10)) //Delayed to avoid wingets from Login calls.
/client/proc/generate_clickcatcher()
if(!void)