mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-21 07:32:02 +00:00
Christ on a stick. SO MANY ERRORS. REEE. # Conflicts: # baystation12.dme # code/_helpers/lists.dm # code/_helpers/logging.dm # code/_helpers/text.dm # code/_onclick/click.dm # code/controllers/configuration.dm # code/controllers/master_controller.dm # code/datums/supplypacks.dm # code/game/antagonist/antagonist.dm # code/game/antagonist/antagonist_print.dm # code/game/antagonist/outsider/commando.dm # code/game/antagonist/outsider/ninja.dm # code/game/area/areas.dm # code/game/gamemodes/cult/cult_items.dm # code/game/gamemodes/game_mode.dm # code/game/jobs/access.dm # code/game/machinery/atmoalter/canister.dm # code/game/machinery/autolathe.dm # code/game/machinery/doors/airlock.dm # code/game/machinery/recharger.dm # code/game/machinery/suit_storage_unit.dm # code/game/mecha/mech_fabricator.dm # code/game/mecha/mecha.dm # code/game/objects/effects/spiders.dm # code/game/objects/items.dm # code/game/objects/items/devices/PDA/PDA.dm # code/game/objects/items/devices/flash.dm # code/game/objects/items/devices/lightreplacer.dm # code/game/objects/items/devices/paicard.dm # code/game/objects/items/devices/scanners.dm # code/game/objects/items/devices/suit_cooling.dm # code/game/objects/items/devices/uplink.dm # code/game/objects/items/robot/robot_upgrades.dm # code/game/objects/items/toys.dm # code/game/objects/items/weapons/cards_ids.dm # code/game/objects/items/weapons/handcuffs.dm # code/game/objects/items/weapons/manuals.dm # code/game/objects/items/weapons/material/kitchen.dm # code/game/objects/items/weapons/material/misc.dm # code/game/objects/items/weapons/material/swords.dm # code/game/objects/items/weapons/melee/energy.dm # code/game/objects/items/weapons/melee/misc.dm # code/game/objects/items/weapons/scrolls.dm # code/game/objects/items/weapons/storage/belt.dm # code/game/objects/items/weapons/stunbaton.dm # code/game/objects/items/weapons/tools.dm # code/game/objects/objs.dm # code/game/objects/structures/crates_lockers/closets.dm # code/game/objects/structures/crates_lockers/closets/secure/security.dm # code/game/objects/structures/janicart.dm # code/game/sound.dm # code/game/turfs/simulated.dm # code/game/verbs/ooc.dm # code/global.dm # code/modules/admin/verbs/debug.dm # code/modules/admin/verbs/modifyvariables.dm # code/modules/client/client procs.dm # code/modules/client/preferences.dm # code/modules/clothing/clothing.dm # code/modules/clothing/head/hardhat.dm # code/modules/clothing/head/helmet.dm # code/modules/clothing/head/jobs.dm # code/modules/clothing/head/misc_special.dm # code/modules/clothing/shoes/jobs.dm # code/modules/clothing/spacesuits/alien.dm # code/modules/clothing/spacesuits/captain.dm # code/modules/clothing/spacesuits/miscellaneous.dm # code/modules/clothing/spacesuits/rig/rig_pieces.dm # code/modules/clothing/spacesuits/rig/suits/alien.dm # code/modules/clothing/spacesuits/spacesuits.dm # code/modules/clothing/spacesuits/void/merc.dm # code/modules/clothing/spacesuits/void/void.dm # code/modules/clothing/suits/armor.dm # code/modules/clothing/suits/jobs.dm # code/modules/clothing/suits/storage.dm # code/modules/clothing/suits/utility.dm # code/modules/clothing/suits/wiz_robe.dm # code/modules/clothing/under/jobs/security.dm # code/modules/economy/Events.dm # code/modules/economy/Events_Mundane.dm # code/modules/economy/economy_misc.dm # code/modules/events/blob.dm # code/modules/events/event.dm # code/modules/events/event_container.dm # code/modules/events/event_manager.dm # code/modules/events/money_lotto.dm # code/modules/events/prison_break.dm # code/modules/events/spacevine.dm # code/modules/hydroponics/trays/tray.dm # code/modules/mob/dead/observer/observer.dm # code/modules/mob/emote.dm # code/modules/mob/holder.dm # code/modules/mob/language/station.dm # code/modules/mob/living/bot/cleanbot.dm # code/modules/mob/living/carbon/alien/diona/diona.dm # code/modules/mob/living/carbon/alien/diona/diona_attacks.dm # code/modules/mob/living/carbon/give.dm # code/modules/mob/living/carbon/human/emote.dm # code/modules/mob/living/carbon/human/human.dm # code/modules/mob/living/carbon/human/human_defense.dm # code/modules/mob/living/carbon/human/inventory.dm # code/modules/mob/living/carbon/human/life.dm # code/modules/mob/living/carbon/human/species/outsider/vox.dm # code/modules/mob/living/carbon/human/species/station/golem.dm # code/modules/mob/living/carbon/human/species/station/station.dm # code/modules/mob/living/carbon/human/update_icons.dm # code/modules/mob/living/carbon/metroid/metroid.dm # code/modules/mob/living/living.dm # code/modules/mob/living/living_defense.dm # code/modules/mob/living/living_defines.dm # code/modules/mob/living/silicon/ai/ai.dm # code/modules/mob/living/silicon/pai/admin.dm # code/modules/mob/living/silicon/pai/pai.dm # code/modules/mob/living/silicon/robot/drone/drone.dm # code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm # code/modules/mob/living/silicon/robot/emote.dm # code/modules/mob/living/silicon/robot/robot_items.dm # code/modules/mob/living/silicon/robot/robot_modules.dm # code/modules/mob/living/silicon/silicon.dm # code/modules/mob/living/simple_animal/bees.dm # code/modules/mob/living/simple_animal/friendly/cat.dm # code/modules/mob/living/simple_animal/friendly/corgi.dm # code/modules/mob/living/simple_animal/friendly/farm_animals.dm # code/modules/mob/living/simple_animal/friendly/mouse.dm # code/modules/mob/living/simple_animal/friendly/spiderbot.dm # code/modules/mob/living/simple_animal/hostile/hostile.dm # code/modules/mob/living/simple_animal/simple_animal.dm # code/modules/mob/logout.dm # code/modules/mob/mob.dm # code/modules/mob/mob_grab_specials.dm # code/modules/mob/mob_helpers.dm # code/modules/mob/new_player/sprite_accessories.dm # code/modules/organs/organ.dm # code/modules/organs/organ_alien.dm # code/modules/organs/organ_external.dm # code/modules/paperwork/faxmachine.dm # code/modules/projectiles/ammunition/boxes.dm # code/modules/projectiles/ammunition/bullets.dm # code/modules/projectiles/guns/energy/nuclear.dm # code/modules/projectiles/guns/energy/rifle.dm # code/modules/projectiles/guns/energy/special.dm # code/modules/projectiles/guns/projectile.dm # code/modules/projectiles/guns/projectile/automatic.dm # code/modules/projectiles/guns/projectile/pistol.dm # code/modules/projectiles/guns/projectile/revolver.dm # code/modules/projectiles/guns/projectile/shotgun.dm # code/modules/projectiles/projectile/bullets.dm # code/modules/projectiles/projectile/special.dm # code/modules/reagents/reagent_containers.dm # code/modules/reagents/reagent_containers/food/drinks.dm # code/modules/research/designs.dm # code/modules/research/destructive_analyzer.dm # code/modules/research/rdconsole.dm # code/modules/spells/artifacts.dm # code/modules/spells/spellbook.dm # code/modules/tables/tables.dm # code/world.dm # config/example/config.txt # icons/mob/items_lefthand.dmi # icons/mob/items_righthand.dmi # icons/obj/lighting.dmi
373 lines
12 KiB
Plaintext
373 lines
12 KiB
Plaintext
/*
|
||
* Holds procs designed to help with filtering text
|
||
* Contains groups:
|
||
* SQL sanitization
|
||
* Text sanitization
|
||
* Text searches
|
||
* Text modification
|
||
* Misc
|
||
*/
|
||
|
||
|
||
/*
|
||
* SQL sanitization
|
||
*/
|
||
|
||
// Run all strings to be used in an SQL query through this proc first to properly escape out injection attempts.
|
||
/proc/sanitizeSQL(var/t as text)
|
||
var/sqltext = dbcon.Quote(t);
|
||
return copytext(sqltext, 2, lentext(sqltext));//Quote() adds quotes around input, we already do that
|
||
|
||
/*
|
||
* Text sanitization
|
||
*/
|
||
|
||
//Used for preprocessing entered text
|
||
/proc/sanitize(var/input, var/max_length = MAX_MESSAGE_LEN, var/encode = 1, var/trim = 1, var/extra = 1)
|
||
if(!input)
|
||
return
|
||
|
||
if(max_length)
|
||
input = copytext(input,1,max_length)
|
||
|
||
if(extra)
|
||
input = replace_characters(input, list("\n"=" ","\t"=" "))
|
||
|
||
if(encode)
|
||
// The below \ escapes have a space inserted to attempt to enable Travis auto-checking of span class usage. Please do not remove the space.
|
||
//In addition to processing html, html_encode removes byond formatting codes like "\ red", "\ i" and other.
|
||
//It is important to avoid double-encode text, it can "break" quotes and some other characters.
|
||
//Also, keep in mind that escaped characters don't work in the interface (window titles, lower left corner of the main window, etc.)
|
||
input = html_encode(input)
|
||
else
|
||
//If not need encode text, simply remove < and >
|
||
//note: we can also remove here byond formatting codes: 0xFF + next byte
|
||
input = replace_characters(input, list("<"=" ", ">"=" "))
|
||
|
||
if(trim)
|
||
//Maybe, we need trim text twice? Here and before copytext?
|
||
input = trim(input)
|
||
|
||
return input
|
||
|
||
//Run sanitize(), but remove <, >, " first to prevent displaying them as > < &34; in some places, after html_encode().
|
||
//Best used for sanitize object names, window titles.
|
||
//If you have a problem with sanitize() in chat, when quotes and >, < are displayed as html entites -
|
||
//this is a problem of double-encode(when & becomes &), use sanitize() with encode=0, but not the sanitizeSafe()!
|
||
/proc/sanitizeSafe(var/input, var/max_length = MAX_MESSAGE_LEN, var/encode = 1, var/trim = 1, var/extra = 1)
|
||
return sanitize(replace_characters(input, list(">"=" ","<"=" ", "\""="'")), max_length, encode, trim, extra)
|
||
|
||
//Filters out undesirable characters from names
|
||
/proc/sanitizeName(var/input, var/max_length = MAX_NAME_LEN, var/allow_numbers = 1)
|
||
if(!input || length(input) > max_length)
|
||
return //Rejects the input if it is null or if it is longer then the max length allowed
|
||
|
||
var/number_of_alphanumeric = 0
|
||
var/last_char_group = 0
|
||
var/output = ""
|
||
|
||
for(var/i=1, i<=length(input), i++)
|
||
var/ascii_char = text2ascii(input,i)
|
||
switch(ascii_char)
|
||
// A .. Z
|
||
if(65 to 90) //Uppercase Letters
|
||
output += ascii2text(ascii_char)
|
||
number_of_alphanumeric++
|
||
last_char_group = 4
|
||
|
||
// a .. z
|
||
if(97 to 122) //Lowercase Letters
|
||
if(last_char_group<2) output += ascii2text(ascii_char-32) //Force uppercase first character
|
||
else output += ascii2text(ascii_char)
|
||
number_of_alphanumeric++
|
||
last_char_group = 4
|
||
|
||
// 0 .. 9
|
||
if(48 to 57) //Numbers
|
||
if(!last_char_group) continue //suppress at start of string
|
||
if(!allow_numbers) continue
|
||
output += ascii2text(ascii_char)
|
||
number_of_alphanumeric++
|
||
last_char_group = 3
|
||
|
||
// ' - .
|
||
if(39,45,46) //Common name punctuation
|
||
if(!last_char_group) continue
|
||
output += ascii2text(ascii_char)
|
||
last_char_group = 2
|
||
|
||
// ~ | @ : # $ % & * +
|
||
if(126,124,64,58,35,36,37,38,42,43) //Other symbols that we'll allow (mainly for AI)
|
||
if(!last_char_group) continue //suppress at start of string
|
||
if(!allow_numbers) continue
|
||
output += ascii2text(ascii_char)
|
||
last_char_group = 2
|
||
|
||
//Space
|
||
if(32)
|
||
if(last_char_group <= 1) continue //suppress double-spaces and spaces at start of string
|
||
output += ascii2text(ascii_char)
|
||
last_char_group = 1
|
||
else
|
||
return
|
||
|
||
if(number_of_alphanumeric < 2) return //protects against tiny names like "A" and also names like "' ' ' ' ' ' ' '"
|
||
|
||
if(last_char_group == 1)
|
||
output = copytext(output,1,length(output)) //removes the last character (in this case a space)
|
||
|
||
for(var/bad_name in list("space","floor","wall","r-wall","monkey","unknown","inactive ai","plating")) //prevents these common metagamey names
|
||
if(cmptext(output,bad_name)) return //(not case sensitive)
|
||
|
||
return output
|
||
|
||
//Returns null if there is any bad text in the string
|
||
/proc/reject_bad_text(var/text, var/max_length=512)
|
||
if(length(text) > max_length) return //message too long
|
||
var/non_whitespace = 0
|
||
for(var/i=1, i<=length(text), i++)
|
||
switch(text2ascii(text,i))
|
||
if(62,60,92,47) return //rejects the text if it contains these bad characters: <, >, \ or /
|
||
if(127 to 255) return //rejects weird letters like <20>
|
||
if(0 to 31) return //more weird stuff
|
||
if(32) continue //whitespace
|
||
else non_whitespace = 1
|
||
if(non_whitespace) return text //only accepts the text if it has some non-spaces
|
||
|
||
|
||
//Old variant. Haven't dared to replace in some places.
|
||
/proc/sanitize_old(var/t,var/list/repl_chars = list("\n"="#","\t"="#"))
|
||
return html_encode(replace_characters(t,repl_chars))
|
||
|
||
// Truncates text to limit if necessary.
|
||
/proc/dd_limittext(message, length)
|
||
var/size = length(message)
|
||
if (size <= length)
|
||
return message
|
||
else
|
||
return copytext(message, 1, length + 1)
|
||
|
||
/*
|
||
* Text searches
|
||
*/
|
||
|
||
//Checks the beginning of a string for a specified sub-string
|
||
//Returns the position of the substring or 0 if it was not found
|
||
/proc/dd_hasprefix(text, prefix)
|
||
var/start = 1
|
||
var/end = length(prefix) + 1
|
||
return findtext(text, prefix, start, end)
|
||
|
||
//Checks the beginning of a string for a specified sub-string. This proc is case sensitive
|
||
//Returns the position of the substring or 0 if it was not found
|
||
/proc/dd_hasprefix_case(text, prefix)
|
||
var/start = 1
|
||
var/end = length(prefix) + 1
|
||
return findtextEx(text, prefix, start, end)
|
||
|
||
//Checks the end of a string for a specified substring.
|
||
//Returns the position of the substring or 0 if it was not found
|
||
/proc/dd_hassuffix(text, suffix)
|
||
var/start = length(text) - length(suffix)
|
||
if(start)
|
||
return findtext(text, suffix, start, null)
|
||
return
|
||
|
||
//Checks the end of a string for a specified substring. This proc is case sensitive
|
||
//Returns the position of the substring or 0 if it was not found
|
||
/proc/dd_hassuffix_case(text, suffix)
|
||
var/start = length(text) - length(suffix)
|
||
if(start)
|
||
return findtextEx(text, suffix, start, null)
|
||
|
||
/*
|
||
* Text modification
|
||
*/
|
||
/proc/replace_characters(var/t,var/list/repl_chars)
|
||
for(var/char in repl_chars)
|
||
t = replacetext(t, char, repl_chars[char])
|
||
return t
|
||
|
||
//Adds 'u' number of zeros ahead of the text 't'
|
||
/proc/add_zero(t, u)
|
||
while (length(t) < u)
|
||
t = "0[t]"
|
||
return t
|
||
|
||
//Adds 'u' number of spaces ahead of the text 't'
|
||
/proc/add_lspace(t, u)
|
||
while(length(t) < u)
|
||
t = " [t]"
|
||
return t
|
||
|
||
//Adds 'u' number of spaces behind the text 't'
|
||
/proc/add_tspace(t, u)
|
||
while(length(t) < u)
|
||
t = "[t] "
|
||
return t
|
||
|
||
//Returns a string with reserved characters and spaces before the first letter removed
|
||
/proc/trim_left(text)
|
||
for (var/i = 1 to length(text))
|
||
if (text2ascii(text, i) > 32)
|
||
return copytext(text, i)
|
||
return ""
|
||
|
||
//Returns a string with reserved characters and spaces after the last letter removed
|
||
/proc/trim_right(text)
|
||
for (var/i = length(text), i > 0, i--)
|
||
if (text2ascii(text, i) > 32)
|
||
return copytext(text, 1, i + 1)
|
||
return ""
|
||
|
||
//Returns a string with reserved characters and spaces before the first word and after the last word removed.
|
||
/proc/trim(text)
|
||
return trim_left(trim_right(text))
|
||
|
||
//Returns a string with the first element of the string capitalized.
|
||
/proc/capitalize(var/t as text)
|
||
return uppertext(copytext(t, 1, 2)) + copytext(t, 2)
|
||
|
||
//This proc strips html properly, remove < > and all text between
|
||
//for complete text sanitizing should be used sanitize()
|
||
/proc/strip_html_properly(var/input)
|
||
if(!input)
|
||
return
|
||
var/opentag = 1 //These store the position of < and > respectively.
|
||
var/closetag = 1
|
||
while(1)
|
||
opentag = findtext(input, "<")
|
||
closetag = findtext(input, ">")
|
||
if(closetag && opentag)
|
||
if(closetag < opentag)
|
||
input = copytext(input, (closetag + 1))
|
||
else
|
||
input = copytext(input, 1, opentag) + copytext(input, (closetag + 1))
|
||
else if(closetag || opentag)
|
||
if(opentag)
|
||
input = copytext(input, 1, opentag)
|
||
else
|
||
input = copytext(input, (closetag + 1))
|
||
else
|
||
break
|
||
|
||
return input
|
||
|
||
//This proc fills in all spaces with the "replace" var (* by default) with whatever
|
||
//is in the other string at the same spot (assuming it is not a replace char).
|
||
//This is used for fingerprints
|
||
/proc/stringmerge(var/text,var/compare,replace = "*")
|
||
var/newtext = text
|
||
if(lentext(text) != lentext(compare))
|
||
return 0
|
||
for(var/i = 1, i < lentext(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
|
||
//(no way to know what it was supposed to be)
|
||
if(a != b)
|
||
if(a == replace) //if A is the replacement char
|
||
newtext = copytext(newtext,1,i) + b + copytext(newtext, i+1)
|
||
else if(b == replace) //if B is the replacement char
|
||
newtext = copytext(newtext,1,i) + a + copytext(newtext, i+1)
|
||
else //The lists disagree, Uh-oh!
|
||
return 0
|
||
return newtext
|
||
|
||
//This proc returns the number of chars of the string that is the character
|
||
//This is used for detective work to determine fingerprint completion.
|
||
/proc/stringpercent(var/text,character = "*")
|
||
if(!text || !character)
|
||
return 0
|
||
var/count = 0
|
||
for(var/i = 1, i <= lentext(text), i++)
|
||
var/a = copytext(text,i,i+1)
|
||
if(a == character)
|
||
count++
|
||
return count
|
||
|
||
/proc/reverse_text(var/text = "")
|
||
var/new_text = ""
|
||
for(var/i = length(text); i > 0; i--)
|
||
new_text += copytext(text, i, i+1)
|
||
return new_text
|
||
|
||
//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))
|
||
return "\[...\]"
|
||
else
|
||
return string
|
||
else
|
||
return "[copytext_preserve_html(string, 1, 37)]..."
|
||
|
||
//alternative copytext() for encoded text, doesn't break html entities (" and other)
|
||
/proc/copytext_preserve_html(var/text, var/first, var/last)
|
||
return html_encode(copytext(html_decode(text), first, last))
|
||
|
||
//For generating neat chat tag-images
|
||
//The icon var could be local in the proc, but it's a waste of resources
|
||
// to always create it and then throw it out.
|
||
/var/icon/text_tag_icons = new('./icons/chattags.dmi')
|
||
/proc/create_text_tag(var/tagname, var/tagdesc = tagname, var/client/C = null)
|
||
if(C && (C.prefs.toggles & CHAT_NOICONS))
|
||
return tagdesc
|
||
return "<IMG src='\ref[text_tag_icons.icon]' class='text_tag' iconstate='[tagname]'" + (tagdesc ? " alt='[tagdesc]'" : "") + ">"
|
||
|
||
// For processing simple markup, similar to what Skype and Discord use.
|
||
// Enabled from a config setting.
|
||
/proc/process_chat_markup(var/message, var/list/ignore_tags = list())
|
||
if (!config.allow_chat_markup)
|
||
return message
|
||
|
||
if (!message)
|
||
return ""
|
||
|
||
// ---Begin URL caching.
|
||
var/list/urls = list()
|
||
var/i = 1
|
||
while (url_find_lazy.Find(message))
|
||
urls["\ref[urls]-[i]"] = url_find_lazy.match
|
||
i++
|
||
|
||
for (var/ref in urls)
|
||
message = replacetextEx(message, urls[ref], ref)
|
||
// ---End URL caching
|
||
|
||
var/regex/tag_markup
|
||
for (var/tag in (markup_tags - ignore_tags))
|
||
tag_markup = markup_regex[tag]
|
||
message = tag_markup.Replace(message, "[markup_tags[tag][1]]$2[markup_tags[tag][2]]")
|
||
|
||
// ---Unload URL cache
|
||
for (var/ref in urls)
|
||
message = replacetextEx(message, ref, urls[ref])
|
||
|
||
return message
|
||
|
||
//Converts New Lines to html <br>
|
||
/proc/nl2br(var/text)
|
||
return replacetextEx(text,"\n","<br>")
|
||
|
||
/proc/contains_az09(var/input)
|
||
for(var/i=1, i<=length(input), i++)
|
||
var/ascii_char = text2ascii(input,i)
|
||
switch(ascii_char)
|
||
// A .. Z
|
||
if(65 to 90) //Uppercase Letters
|
||
return 1
|
||
// a .. z
|
||
if(97 to 122) //Lowercase Letters
|
||
return 1
|
||
|
||
// 0 .. 9
|
||
if(48 to 57) //Numbers
|
||
return 1
|
||
return 0
|
||
|
||
//A shortcut for assigning a span class to a string of text
|
||
/proc/span(var/class, var/text)
|
||
return "<span class='[class]'>[text]</span>"
|