mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-27 09:31:54 +00:00
## About The Pull Request Removes the blur of the escape menu so players can sorta see what's going on in their game while going through, so they can react in case something's happening while they're in menu. Changes the font of the escape menu so it's no longer the LISA font Makes the title only show up on the home menu, so being on the suicide panel wont show you "another day on space station 13". Moves the 'back' button on the suicide menu to the top left.   ## Why It's Good For The Game This hopes to make the escape menu a little more easy to go through, removing some obstruction of your game's screen so you can see what's happening around you, and give a little generic part of submenus in case we add more (which I do have at least one planned). ## Changelog 🆑 qol: The escape menu no longer blurs the game in the background. qol: The escape menu now has a more readable font, and the escape menu's back button is now smaller and in the corner. /🆑
535 lines
20 KiB
Plaintext
535 lines
20 KiB
Plaintext
GLOBAL_VAR_INIT(OOC_COLOR, null)//If this is null, use the CSS for OOC. Otherwise, use a custom colour.
|
|
GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8")
|
|
|
|
///talking in OOC uses this
|
|
/client/verb/ooc(msg as text)
|
|
set name = "OOC" //Gave this shit a shorter name so you only have to time out "ooc" rather than "ooc message" to use it --NeoFite
|
|
set category = "OOC"
|
|
|
|
if(GLOB.say_disabled) //This is here to try to identify lag problems
|
|
to_chat(usr, span_danger("Speech is currently admin-disabled."))
|
|
return
|
|
|
|
var/client_initalized = VALIDATE_CLIENT_INITIALIZATION(src)
|
|
if(isnull(mob) || !client_initalized)
|
|
if(!client_initalized)
|
|
unvalidated_client_error() // we only want to throw this warning message when it's directly related to client failure.
|
|
|
|
to_chat(usr, span_warning("Failed to send your OOC message. You attempted to send the following message:\n[span_big(msg)]"))
|
|
return
|
|
|
|
if(isnull(holder))
|
|
if(!GLOB.ooc_allowed)
|
|
to_chat(src, span_danger("OOC is globally muted."))
|
|
return
|
|
if(!GLOB.dooc_allowed && (mob.stat == DEAD))
|
|
to_chat(usr, span_danger("OOC for dead mobs has been turned off."))
|
|
return
|
|
if(prefs.muted & MUTE_OOC)
|
|
to_chat(src, span_danger("You cannot use OOC (muted)."))
|
|
return
|
|
if(is_banned_from(ckey, "OOC"))
|
|
to_chat(src, span_danger("You have been banned from OOC."))
|
|
return
|
|
if(QDELETED(src))
|
|
return
|
|
|
|
msg = trim(copytext_char(sanitize(msg), 1, MAX_MESSAGE_LEN))
|
|
var/raw_msg = msg
|
|
|
|
var/list/filter_result = is_ooc_filtered(msg)
|
|
if (!CAN_BYPASS_FILTER(usr) && filter_result)
|
|
REPORT_CHAT_FILTER_TO_USER(usr, filter_result)
|
|
log_filter("OOC", msg, filter_result)
|
|
return
|
|
|
|
// Protect filter bypassers from themselves.
|
|
// Demote hard filter results to soft filter results if necessary due to the danger of accidentally speaking in OOC.
|
|
var/list/soft_filter_result = filter_result || is_soft_ooc_filtered(msg)
|
|
|
|
if (soft_filter_result)
|
|
if(tgui_alert(usr,"Your message contains \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\". \"[soft_filter_result[CHAT_FILTER_INDEX_REASON]]\", Are you sure you want to say it?", "Soft Blocked Word", list("Yes", "No")) != "Yes")
|
|
return
|
|
message_admins("[ADMIN_LOOKUPFLW(usr)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\" they may be using a disallowed term. Message: \"[msg]\"")
|
|
log_admin_private("[key_name(usr)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\" they may be using a disallowed term. Message: \"[msg]\"")
|
|
|
|
if(!msg)
|
|
return
|
|
|
|
msg = emoji_parse(msg)
|
|
|
|
if(SSticker.HasRoundStarted() && ((msg[1] in list(".",";",":","#")) || findtext_char(msg, "say", 1, 5)))
|
|
if(tgui_alert(usr,"Your message \"[raw_msg]\" looks like it was meant for in game communication, say it in OOC?", "Meant for OOC?", list("Yes", "No")) != "Yes")
|
|
return
|
|
|
|
if(!holder)
|
|
if(handle_spam_prevention(msg,MUTE_OOC))
|
|
return
|
|
if(findtext(msg, "byond://"))
|
|
to_chat(src, span_boldannounce("Advertising other servers is not allowed."))
|
|
log_admin("[key_name(src)] has attempted to advertise in OOC: [msg]")
|
|
message_admins("[key_name_admin(src)] has attempted to advertise in OOC: [msg]")
|
|
return
|
|
|
|
if(!(get_chat_toggles(src) & CHAT_OOC))
|
|
to_chat(src, span_danger("You have OOC muted."))
|
|
return
|
|
|
|
mob.log_talk(raw_msg, LOG_OOC)
|
|
|
|
var/keyname = key
|
|
if(prefs.unlock_content)
|
|
if(prefs.toggles & MEMBER_PUBLIC)
|
|
keyname = "<font color='[prefs.read_preference(/datum/preference/color/ooc_color) || GLOB.normal_ooc_colour]'>[icon2html('icons/ui/chat/member_content.dmi', world, "blag")][keyname]</font>"
|
|
if(prefs.hearted)
|
|
var/datum/asset/spritesheet_batched/sheet = get_asset_datum(/datum/asset/spritesheet_batched/chat)
|
|
keyname = "[sheet.icon_tag("emoji-heart")][keyname]"
|
|
//The linkify span classes and linkify=TRUE below make ooc text get clickable chat href links if you pass in something resembling a url
|
|
for(var/client/receiver as anything in GLOB.clients)
|
|
if(!receiver.prefs) // Client being created or deleted. Despite all, this can be null.
|
|
continue
|
|
if(!(get_chat_toggles(receiver) & CHAT_OOC))
|
|
continue
|
|
if(holder?.fakekey in receiver.prefs.ignoring)
|
|
continue
|
|
var/avoid_highlight = receiver == src
|
|
if(holder)
|
|
if(!holder.fakekey || receiver.holder)
|
|
if(check_rights_for(src, R_ADMIN))
|
|
var/ooc_color = prefs.read_preference(/datum/preference/color/ooc_color)
|
|
to_chat(receiver, span_adminooc("[CONFIG_GET(flag/allow_admin_ooccolor) && ooc_color ? "<font color=[ooc_color]>" :"" ][span_prefix("OOC:")] <EM>[keyname][holder.fakekey ? "/([holder.fakekey])" : ""]:</EM> <span class='message linkify'>[msg]</span>"), avoid_highlighting = avoid_highlight)
|
|
else
|
|
to_chat(receiver, span_adminobserverooc(span_prefix("OOC:</span> <EM>[keyname][holder.fakekey ? "/([holder.fakekey])" : ""]:</EM> <span class='message linkify'>[msg]")), avoid_highlighting = avoid_highlight)
|
|
else
|
|
if(GLOB.OOC_COLOR)
|
|
to_chat(receiver, "<span class='oocplain'><font color='[GLOB.OOC_COLOR]'><b>[span_prefix("OOC:")] <EM>[holder.fakekey ? holder.fakekey : key]:</EM> <span class='message linkify'>[msg]</span></b></font></span>", avoid_highlighting = avoid_highlight)
|
|
else
|
|
to_chat(receiver, span_ooc(span_prefix("OOC:</span> <EM>[holder.fakekey ? holder.fakekey : key]:</EM> <span class='message linkify'>[msg]")), avoid_highlighting = avoid_highlight)
|
|
|
|
else if(!(key in receiver.prefs.ignoring))
|
|
if(GLOB.OOC_COLOR)
|
|
to_chat(receiver, "<span class='oocplain'><font color='[GLOB.OOC_COLOR]'><b>[span_prefix("OOC:")] <EM>[keyname]:</EM> <span class='message linkify'>[msg]</span></b></font></span>", avoid_highlighting = avoid_highlight)
|
|
else
|
|
to_chat(receiver, span_ooc(span_prefix("OOC:</span> <EM>[keyname]:</EM> <span class='message linkify'>[msg]")), avoid_highlighting = avoid_highlight)
|
|
|
|
|
|
/proc/toggle_ooc(toggle = null)
|
|
if(toggle != null) //if we're specifically en/disabling ooc
|
|
if(toggle != GLOB.ooc_allowed)
|
|
GLOB.ooc_allowed = toggle
|
|
else
|
|
return
|
|
else //otherwise just toggle it
|
|
GLOB.ooc_allowed = !GLOB.ooc_allowed
|
|
to_chat(world, "<span class='oocplain'><B>The OOC channel has been globally [GLOB.ooc_allowed ? "enabled" : "disabled"].</B></span>")
|
|
|
|
/proc/toggle_dooc(toggle = null)
|
|
if(toggle != null)
|
|
if(toggle != GLOB.dooc_allowed)
|
|
GLOB.dooc_allowed = toggle
|
|
else
|
|
return
|
|
else
|
|
GLOB.dooc_allowed = !GLOB.dooc_allowed
|
|
|
|
|
|
/client/proc/set_ooc()
|
|
set name = "Set Player OOC Color"
|
|
set desc = "Modifies player OOC Color"
|
|
set category = "Server"
|
|
if(IsAdminAdvancedProcCall())
|
|
return
|
|
|
|
ADMIN_VERB(set_ooc_color, R_FUN, "Set Player OOC Color", "Modifies the global OOC color.", ADMIN_CATEGORY_SERVER)
|
|
var/newColor = input(user, "Please select the new player OOC color.", "OOC color") as color|null
|
|
if(isnull(newColor))
|
|
return
|
|
var/new_color = sanitize_color(newColor)
|
|
message_admins("[key_name_admin(user)] has set the players' ooc color to [new_color].")
|
|
log_admin("[key_name_admin(user)] has set the player ooc color to [new_color].")
|
|
GLOB.OOC_COLOR = new_color
|
|
|
|
/client/proc/reset_ooc()
|
|
set name = "Reset Player OOC Color"
|
|
set desc = "Returns player OOC Color to default"
|
|
set category = "Server"
|
|
if(IsAdminAdvancedProcCall())
|
|
return
|
|
|
|
ADMIN_VERB(reset_ooc_color, R_FUN, "Reset Player OOC Color", "Returns player OOC color to default.", ADMIN_CATEGORY_SERVER)
|
|
if(tgui_alert(user, "Are you sure you want to reset the OOC color of all players?", "Reset Player OOC Color", list("Yes", "No")) != "Yes")
|
|
return
|
|
message_admins("[key_name_admin(user)] has reset the players' ooc color.")
|
|
log_admin("[key_name_admin(user)] has reset player ooc color.")
|
|
GLOB.OOC_COLOR = null
|
|
|
|
//Checks admin notice
|
|
/client/verb/admin_notice()
|
|
set name = "Adminnotice"
|
|
set category = "Admin"
|
|
set desc = "Check the admin notice if it has been set"
|
|
|
|
if(GLOB.admin_notice)
|
|
to_chat(src, "[span_boldnotice("Admin Notice:")]\n \t [GLOB.admin_notice]")
|
|
else
|
|
to_chat(src, span_notice("There are no admin notices at the moment."))
|
|
|
|
/client/verb/motd()
|
|
set name = "MOTD"
|
|
set category = "OOC"
|
|
set desc ="Check the Message of the Day"
|
|
|
|
var/motd = global.config.motd
|
|
if(motd)
|
|
to_chat(src, "<span class='infoplain'><div class=\"motd\">[motd]</div></span>", handle_whitespace=FALSE)
|
|
else
|
|
to_chat(src, span_notice("The Message of the Day has not been set."))
|
|
|
|
/client/proc/self_notes()
|
|
set name = "View Admin Remarks"
|
|
set category = "OOC"
|
|
set desc = "View the notes that admins have written about you"
|
|
|
|
if(!CONFIG_GET(flag/see_own_notes))
|
|
to_chat(usr, span_notice("Sorry, that function is not enabled on this server."))
|
|
return
|
|
|
|
browse_messages(null, usr.ckey, null, TRUE)
|
|
|
|
/client/proc/self_playtime()
|
|
set name = "View tracked playtime"
|
|
set category = "OOC"
|
|
set desc = "View the amount of playtime for roles the server has tracked."
|
|
|
|
if(!CONFIG_GET(flag/use_exp_tracking))
|
|
to_chat(usr, span_notice("Sorry, tracking is currently disabled."))
|
|
return
|
|
|
|
new /datum/job_report_menu(src, usr)
|
|
|
|
// Ignore verb
|
|
/client/verb/select_ignore()
|
|
set name = "Ignore"
|
|
set category = "OOC"
|
|
set desc ="Ignore a player's messages on the OOC channel"
|
|
|
|
// Make a list to choose players from
|
|
var/list/players = list()
|
|
|
|
// Use keys and fakekeys for the same purpose
|
|
var/displayed_key = ""
|
|
|
|
// Try to add every player who's online to the list
|
|
for(var/client/C in GLOB.clients)
|
|
// Don't add ourself
|
|
if(C == src)
|
|
continue
|
|
|
|
// Don't add players we've already ignored if they're not using a fakekey
|
|
if((C.key in prefs.ignoring) && !C.holder?.fakekey)
|
|
continue
|
|
|
|
// Don't add players using a fakekey we've already ignored
|
|
if(C.holder?.fakekey in prefs.ignoring)
|
|
continue
|
|
|
|
// Use the player's fakekey if they're using one
|
|
if(C.holder?.fakekey)
|
|
displayed_key = C.holder.fakekey
|
|
|
|
// Use the player's key if they're not using a fakekey
|
|
else
|
|
displayed_key = C.key
|
|
|
|
// Check if both we and the player are ghosts and they're not using a fakekey
|
|
if(isobserver(mob) && isobserver(C.mob) && !C.holder?.fakekey)
|
|
// Show us if the player is a ghost or not after their displayed key
|
|
// Add the player's displayed key to the list
|
|
players["[displayed_key](ghost)"] = displayed_key
|
|
|
|
// Add the player's displayed key to the list if we or the player aren't a ghost or they're using a fakekey
|
|
else
|
|
players[displayed_key] = displayed_key
|
|
|
|
// Check if the list is empty
|
|
if(!length(players))
|
|
// Express that there are no players we can ignore in chat
|
|
to_chat(src, span_infoplain("There are no other players you can ignore!"))
|
|
|
|
// Stop running
|
|
return
|
|
|
|
// Sort the list
|
|
players = sort_list(players)
|
|
|
|
// Request the player to ignore
|
|
var/selection = tgui_input_list(src, "Select a player", "Ignore", players)
|
|
|
|
// Stop running if we didn't receieve a valid selection
|
|
if(isnull(selection) || !(selection in players))
|
|
return
|
|
|
|
// Store the selected player
|
|
selection = players[selection]
|
|
|
|
// Check if the selected player is on our ignore list
|
|
if(selection in prefs.ignoring)
|
|
// Express that the selected player is already on our ignore list in chat
|
|
to_chat(src, span_infoplain("You are already ignoring [selection]!"))
|
|
|
|
// Stop running
|
|
return
|
|
|
|
// Add the selected player to our ignore list
|
|
prefs.ignoring.Add(selection)
|
|
|
|
// Save our preferences
|
|
prefs.save_preferences()
|
|
|
|
// Express that we've ignored the selected player in chat
|
|
to_chat(src, span_infoplain("You are now ignoring [selection] on the OOC channel."))
|
|
|
|
// Unignore verb
|
|
/client/verb/select_unignore()
|
|
set name = "Unignore"
|
|
set category = "OOC"
|
|
set desc = "Stop ignoring a player's messages on the OOC channel"
|
|
|
|
// Check if we've ignored any players
|
|
if(!length(prefs.ignoring))
|
|
// Express that we haven't ignored any players in chat
|
|
to_chat(src, span_infoplain("You haven't ignored any players!"))
|
|
|
|
// Stop running
|
|
return
|
|
|
|
// Request the player to unignore
|
|
var/selection = tgui_input_list(src, "Select a player", "Unignore", prefs.ignoring)
|
|
|
|
// Stop running if we didn't receive a selection
|
|
if(isnull(selection))
|
|
return
|
|
|
|
// Check if the selected player is not on our ignore list
|
|
if(!(selection in prefs.ignoring))
|
|
// Express that the selected player is not on our ignore list in chat
|
|
to_chat(src, span_infoplain("You are not ignoring [selection]!"))
|
|
|
|
// Stop running
|
|
return
|
|
|
|
// Remove the selected player from our ignore list
|
|
prefs.ignoring.Remove(selection)
|
|
|
|
// Save our preferences
|
|
prefs.save_preferences()
|
|
|
|
// Express that we've unignored the selected player in chat
|
|
to_chat(src, span_infoplain("You are no longer ignoring [selection] on the OOC channel."))
|
|
|
|
/client/proc/show_previous_roundend_report()
|
|
set name = "Your Last Round"
|
|
set category = "OOC"
|
|
set desc = "View the last round end report you've seen"
|
|
|
|
SSticker.show_roundend_report(src, report_type = PERSONAL_LAST_ROUND)
|
|
|
|
/client/proc/show_servers_last_roundend_report()
|
|
set name = "Server's Last Round"
|
|
set category = "OOC"
|
|
set desc = "View the last round end report from this server"
|
|
|
|
SSticker.show_roundend_report(src, report_type = SERVER_LAST_ROUND)
|
|
|
|
/client/verb/fit_viewport()
|
|
set name = "Fit Viewport"
|
|
set category = "OOC"
|
|
set desc = "Fit the width of the map window to match the viewport"
|
|
|
|
// Fetch aspect ratio
|
|
var/view_size = getviewsize(view)
|
|
var/aspect_ratio = view_size[1] / view_size[2]
|
|
|
|
// Calculate desired pixel width using window size and aspect ratio
|
|
var/list/sizes = params2list(winget(src, "mainwindow.split;mapwindow", "size"))
|
|
|
|
// Client closed the window? Some other error? This is unexpected behaviour, let's
|
|
// CRASH with some info.
|
|
if(!sizes["mapwindow.size"])
|
|
CRASH("sizes does not contain mapwindow.size key. This means a winget failed to return what we wanted. --- sizes var: [sizes] --- sizes length: [length(sizes)]")
|
|
|
|
var/list/map_size = splittext(sizes["mapwindow.size"], "x")
|
|
|
|
var/split_size = splittext(sizes["mainwindow.split.size"], "x")
|
|
var/split_width = text2num(split_size[1])
|
|
|
|
// Window is minimized, we can't get proper data so return to avoid division by 0
|
|
if (!split_width)
|
|
return
|
|
|
|
// Gets the type of zoom we're currently using from our view datum
|
|
// If it's 0 we do our pixel calculations based off the size of the mapwindow
|
|
// If it's not, we already know how big we want our window to be, since zoom is the exact pixel ratio of the map
|
|
var/zoom_value = src.view_size?.zoom || 0
|
|
|
|
var/desired_width = 0
|
|
if(zoom_value)
|
|
desired_width = round(view_size[1] * zoom_value * ICON_SIZE_X)
|
|
else
|
|
|
|
// Looks like we expect mapwindow.size to be "ixj" where i and j are numbers.
|
|
// If we don't get our expected 2 outputs, let's give some useful error info.
|
|
if(length(map_size) != 2)
|
|
CRASH("map_size of incorrect length --- map_size var: [map_size] --- map_size length: [length(map_size)]")
|
|
var/height = text2num(map_size[2])
|
|
desired_width = round(height * aspect_ratio)
|
|
|
|
if (text2num(map_size[1]) == desired_width)
|
|
// Nothing to do
|
|
return
|
|
|
|
// Avoid auto-resizing the statpanel and chat into nothing.
|
|
desired_width = min(desired_width, split_width - 300)
|
|
|
|
// Calculate and apply a best estimate
|
|
// +4 pixels are for the width of the splitter's handle
|
|
var/pct = 100 * (desired_width + 4) / split_width
|
|
winset(src, "mainwindow.split", "splitter=[pct]")
|
|
|
|
// Apply an ever-lowering offset until we finish or fail
|
|
var/delta
|
|
for(var/safety in 1 to 10)
|
|
var/after_size = winget(src, "mapwindow", "size")
|
|
map_size = splittext(after_size, "x")
|
|
var/got_width = text2num(map_size[1])
|
|
|
|
if (got_width == desired_width)
|
|
// success
|
|
return
|
|
else if (isnull(delta))
|
|
// calculate a probable delta value based on the difference
|
|
delta = 100 * (desired_width - got_width) / split_width
|
|
else if ((delta > 0 && got_width > desired_width) || (delta < 0 && got_width < desired_width))
|
|
// if we overshot, halve the delta and reverse direction
|
|
delta = -delta/2
|
|
|
|
pct += delta
|
|
winset(src, "mainwindow.split", "splitter=[pct]")
|
|
|
|
/// Attempt to automatically fit the viewport, assuming the user wants it
|
|
/client/proc/attempt_auto_fit_viewport()
|
|
if (!prefs?.read_preference(/datum/preference/toggle/auto_fit_viewport))
|
|
return
|
|
if(fully_created)
|
|
INVOKE_ASYNC(src, VERB_REF(fit_viewport))
|
|
else //Delayed to avoid wingets from Login calls.
|
|
addtimer(CALLBACK(src, VERB_REF(fit_viewport), 1 SECONDS))
|
|
|
|
/client/verb/policy()
|
|
set name = "Show Policy"
|
|
set desc = "Show special server rules related to your current character."
|
|
set category = "OOC"
|
|
|
|
//Collect keywords
|
|
var/list/keywords = mob.get_policy_keywords()
|
|
var/header = get_policy(POLICY_VERB_HEADER)
|
|
var/list/policytext = list(header)
|
|
var/anything = FALSE
|
|
for(var/keyword in keywords)
|
|
var/p = get_policy(keyword)
|
|
if(p)
|
|
policytext += p
|
|
policytext += "<hr>"
|
|
anything = TRUE
|
|
if(!anything)
|
|
policytext += "No related rules found."
|
|
|
|
var/datum/browser/browser = new(usr, "policy", "Server Policy", 600, 500)
|
|
browser.set_content(policytext.Join(""))
|
|
browser.open()
|
|
|
|
/client/verb/fix_stat_panel()
|
|
set name = "Fix Stat Panel"
|
|
set hidden = TRUE
|
|
|
|
init_verbs()
|
|
|
|
/client/proc/export_preferences()
|
|
set name = "Export Preferences"
|
|
set desc = "Export your current preferences to a file."
|
|
set category = "OOC"
|
|
|
|
ASSERT(prefs, "User attempted to export preferences while preferences were null!") // what the fuck
|
|
|
|
prefs.savefile.export_json_to_client(usr, ckey)
|
|
|
|
/client/verb/map_vote_tally_count()
|
|
set name = "Show Map Vote Tallies"
|
|
set desc = "View the current map vote tally counts."
|
|
set category = "Server"
|
|
to_chat(mob, SSmap_vote.tally_printout)
|
|
|
|
|
|
/client/verb/linkforumaccount()
|
|
set category = "OOC"
|
|
set name = "Link Forum Account"
|
|
set desc = "Validates your byond account to your forum account. Required to post on the forums."
|
|
|
|
var/uri = CONFIG_GET(string/forum_link_uri)
|
|
if(!uri)
|
|
to_chat(src, span_warning("This feature is disabled."))
|
|
return
|
|
|
|
if (!SSdbcore.Connect())
|
|
to_chat(src, span_danger("No connection to the database."))
|
|
return
|
|
|
|
if (is_guest_key(ckey))
|
|
to_chat(src, span_danger("Guests can not link accounts."))
|
|
return
|
|
|
|
var/token = generate_account_link_token()
|
|
|
|
var/datum/db_query/query_set_token = SSdbcore.NewQuery("INSERT INTO phpbb.tg_byond_oauth_tokens (`token`, `key`) VALUES (:token, :key)", list("token" = token, "key" = key))
|
|
if(!query_set_token.Execute())
|
|
to_chat(src, span_danger("Failed to insert account link token into database, please try again later."))
|
|
qdel(query_set_token)
|
|
return
|
|
|
|
qdel(query_set_token)
|
|
|
|
to_chat(src, "Now opening a window to login to your forum account, your account will automatically be linked the moment you log in. If this window doesn't load, Please go to <a href=\"[uri]?token=[token]\">[uri]?token=[token]</a> - This link will expire in 30 minutes.")
|
|
src << link("[uri]?token=[token]")
|
|
|
|
/client/proc/generate_account_link_token()
|
|
var/static/entropychain
|
|
if (!entropychain)
|
|
if (fexists("data/entropychain.txt"))
|
|
entropychain = file2text("entropychain.txt")
|
|
else
|
|
entropychain = "LOL THERE IS NO ENTROPY #HEATDEATH"
|
|
else if (prob(rand(1,15)))
|
|
text2file("data/entropychain.txt", entropychain)
|
|
|
|
var/datum/db_query/query_get_token = SSdbcore.NewQuery("SELECT [random_string()], [random_string()]", list(random_string_args(entropychain), random_string_args(entropychain)))
|
|
|
|
if(!query_get_token.Execute())
|
|
to_chat(src, span_danger("Failed to get random string token from database. (Error #1)"))
|
|
qdel(query_get_token)
|
|
return
|
|
|
|
if(!query_get_token.NextRow())
|
|
to_chat(src, span_danger("Could not locate your token in the database. (Error #2)"))
|
|
qdel(query_get_token)
|
|
return
|
|
|
|
entropychain = "[query_get_token.item[2]]"
|
|
return query_get_token.item[1]
|
|
|
|
|
|
/client/proc/random_string()
|
|
return "SHA2(CONCAT(RAND(),UUID(),?,RAND(),UUID()), 512)"
|
|
|
|
/client/proc/random_string_args(entropychain)
|
|
return "[entropychain][GUID()][rand()*rand(999999)][world.time][GUID()][rand()*rand(999999)][world.timeofday][GUID()][rand()*rand(999999)][world.realtime][GUID()][rand()*rand(999999)][time2text(world.timeofday)][GUID()][rand()*rand(999999)][world.tick_usage][computer_id][address][ckey][key][GUID()][rand()*rand(999999)]"
|