Unicode awareness Part 2 -- copytext() (#48512)

* Unicode support Part 2 -- copytext()

This is the transition of all copytext() calls to be unicode aware and also some nearby calls in the same functions. Most things are just replacing copytext() with copytext_char() as a terrible character limiter but a few others were slightly more involved.

I replaced a ton of
````
var/something = sanitize(input())
something = copytext(something, 1, MAX_MESSAGE_LEN)
````

with a single stripped_input() call. stripped_input() already calls html_encode(), trim(), and some other sanitization so there shouldn't be any major issues there.

This is still VERY rough btw; DNA is a mess, the status displays are complete ass, there's a copytext() in code\datums\shuttles.dm that I'm not sure what to do with, and I didn't touch anything in the tools folder. I haven't tested this much at all yet, I only got it to compile earlier this morning. There's also likely to be weird bugs until I get around to fixing length(), findtext(), and the rest of the string procs.

* Makes the code functional

* Assume color hex strings are always # followed by ascii.
Properly encodes and decodes the stuff in mob_helpers.dm which fixes some issues there.

* Removes ninjaspeak since it's unused
This commit is contained in:
MrPerson
2020-01-18 13:07:22 +13:00
committed by oranges
parent e7a9bf4a6d
commit f7eb2c905b
110 changed files with 501 additions and 557 deletions
+3 -5
View File
@@ -451,11 +451,9 @@ GLOBAL_PROTECT(admin_verbs_hideable)
mob.name = mob.real_name
mob.mouse_opacity = initial(mob.mouse_opacity)
else
var/new_key = ckeyEx(input("Enter your desired display name.", "Fake Key", key) as text|null)
var/new_key = ckeyEx(stripped_input(usr, "Enter your desired display name.", "Fake Key", key, 26))
if(!new_key)
return
if(length(new_key) >= 26)
new_key = copytext(new_key, 1, 26)
holder.fakekey = new_key
createStealthKey()
if(isobserver(mob))
@@ -562,9 +560,9 @@ GLOBAL_PROTECT(admin_verbs_hideable)
set desc = "Gives a spell to a mob."
var/list/spell_list = list()
var/type_length = length("/obj/effect/proc_holder/spell") + 2
var/type_length = length_char("/obj/effect/proc_holder/spell") + 2
for(var/A in GLOB.spells)
spell_list[copytext("[A]", type_length)] = A
spell_list[copytext_char("[A]", type_length)] = A
var/obj/effect/proc_holder/spell/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in sortList(spell_list)
if(!S)
return
+1 -1
View File
@@ -340,7 +340,7 @@
if(!SSticker.HasRoundStarted())
alert("The game hasn't started yet!")
return
var/objective = copytext(sanitize(input("Enter an objective")),1,MAX_MESSAGE_LEN)
var/objective = stripped_input(usr, "Enter an objective")
if(!objective)
return
SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Traitor All", "[objective]"))
+3 -11
View File
@@ -1727,8 +1727,6 @@
if(!check_rights(R_ADMIN))
return
src.admincaster_feed_channel.channel_name = stripped_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,length(src.admincaster_feed_channel.channel_name)+1)
src.access_news_network()
else if(href_list["ac_set_channel_lock"])
@@ -1768,9 +1766,7 @@
else if(href_list["ac_set_new_message"])
if(!check_rights(R_ADMIN))
return
src.admincaster_feed_message.body = adminscrub(input(usr, "Write your Feed story.", "Network Channel Handler", ""))
while (findtext(src.admincaster_feed_message.returnBody(-1)," ") == 1)
src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.returnBody(-1),2,length(src.admincaster_feed_message.returnBody(-1))+1)
src.admincaster_feed_message.body = adminscrub(stripped_input(usr, "Write your Feed story.", "Network Channel Handler", ""))
src.access_news_network()
else if(href_list["ac_submit_new_message"])
@@ -1829,17 +1825,13 @@
else if(href_list["ac_set_wanted_name"])
if(!check_rights(R_ADMIN))
return
src.admincaster_wanted_message.criminal = adminscrub(input(usr, "Provide the name of the Wanted person.", "Network Security Handler", ""))
while(findtext(src.admincaster_wanted_message.criminal," ") == 1)
src.admincaster_wanted_message.criminal = copytext(admincaster_wanted_message.criminal,2,length(admincaster_wanted_message.criminal)+1)
src.admincaster_wanted_message.criminal = adminscrub(stripped_input(usr, "Provide the name of the Wanted person.", "Network Security Handler", ""))
src.access_news_network()
else if(href_list["ac_set_wanted_desc"])
if(!check_rights(R_ADMIN))
return
src.admincaster_wanted_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_wanted_message.body," ") == 1)
src.admincaster_wanted_message.body = copytext(src.admincaster_wanted_message.body,2,length(src.admincaster_wanted_message.body)+1)
src.admincaster_wanted_message.body = adminscrub(stripped_input(usr, "Provide the a description of the Wanted person and any other details you deem important.", "Network Security Handler", ""))
src.access_news_network()
else if(href_list["ac_submit_wanted"])
+18 -17
View File
@@ -906,8 +906,8 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
else if(ispath(expression[i]))
val = expression[i]
else if(copytext(expression[i], 1, 2) in list("'", "\""))
val = copytext(expression[i], 2, length(expression[i]))
else if(expression[i][1] in list("'", "\""))
val = copytext_char(expression[i], 2, -1)
else if(expression[i] == "\[")
var/list/expressions_list = expression[++i]
@@ -1014,12 +1014,12 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
if(is_proper_datum(object))
D = object
if (object == world && (!long || expression[start + 1] == ".") && !(expression[start] in exclude) && copytext(expression[start], 1, 3) != "SS")
if (object == world && (!long || expression[start + 1] == ".") && !(expression[start] in exclude) && copytext(expression[start], 1, 3) != "SS") //3 == length("SS") + 1
to_chat(usr, "<span class='danger'>World variables are not allowed to be accessed. Use global.</span>")
return null
else if(expression [start] == "{" && long)
if(lowertext(copytext(expression[start + 1], 1, 3)) != "0x")
if(lowertext(copytext(expression[start + 1], 1, 3)) != "0x") //3 == length("0x") + 1
to_chat(usr, "<span class='danger'>Invalid pointer syntax: [expression[start + 1]]</span>")
return null
v = locate("\[[expression[start + 1]]]")
@@ -1061,8 +1061,8 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
if("CFG")
v = config
else
if(copytext(expression[start], 1, 3) == "SS") //Subsystem
var/SSname = copytext(expression[start], 3)
if(copytext(expression[start], 1, 3) == "SS") //Subsystem //3 == length("SS") + 1
var/SSname = copytext_char(expression[start], 3)
var/SSlength = length(SSname)
var/datum/controller/subsystem/SS
var/SSmatch
@@ -1106,9 +1106,10 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
var/word = ""
var/list/query_list = list()
var/len = length(query_text)
var/char = ""
for(var/i = 1, i <= len, i++)
var/char = copytext(query_text, i, i + 1)
for(var/i = 1, i <= len, i += length(char))
char = query_text[i]
if(char in whitespace)
if(word != "")
@@ -1127,7 +1128,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
query_list += word
word = ""
var/char2 = copytext(query_text, i + 1, i + 2)
var/char2 = query_text[i + length(char)]
if(char2 in multi[char])
query_list += "[char][char2]"
@@ -1143,13 +1144,13 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
word = "'"
for(i++, i <= len, i++)
char = copytext(query_text, i, i + 1)
for(i += length(char), i <= len, i += length(char))
char = query_text[i]
if(char == "'")
if(copytext(query_text, i + 1, i + 2) == "'")
if(query_text[i + length(char)] == "'")
word += "'"
i++
i += length(query_text[i + length(char)])
else
break
@@ -1171,13 +1172,13 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
word = "\""
for(i++, i <= len, i++)
char = copytext(query_text, i, i + 1)
for(i += length(char), i <= len, i += length(char))
char = query_text[i]
if(char == "\"")
if(copytext(query_text, i + 1, i + 2) == "'")
if(query_text[i + length(char)] == "'")
word += "\""
i++
i += length(query_text[i + length(char)])
else
break
@@ -260,7 +260,7 @@
node += "*"
i++
else if (copytext(token(i), 1, 2) == "/")
else if(token(i)[1] == "/")
i = object_type(i, node)
else
@@ -391,7 +391,7 @@
//object_type: <type path>
/datum/SDQL_parser/proc/object_type(i, list/node)
if (copytext(token(i), 1, 2) != "/")
if(token(i)[1] != "/")
return parse_error("Expected type, but it didn't begin with /")
var/path = text2path(token(i))
@@ -430,7 +430,7 @@
//string: ''' <some text> ''' | '"' <some text > '"'
/datum/SDQL_parser/proc/string(i, list/node)
if(copytext(token(i), 1, 2) in list("'", "\""))
if(token(i)[1] in list("'", "\""))
node += token(i)
else
@@ -441,7 +441,7 @@
//array: '[' expression_list ']'
/datum/SDQL_parser/proc/array(i, list/node)
// Arrays get turned into this: list("[", list(exp_1a = exp_1b, ...), ...), "[" is to mark the next node as an array.
if(copytext(token(i), 1, 2) != "\[")
if(token(i)[1] != "\[")
parse_error("Expected an array but found '[token(i)]'")
return i + 1
@@ -613,7 +613,7 @@
node += "null"
i++
else if(lowertext(copytext(token(i), 1, 3)) == "0x" && isnum(hex2num(copytext(token(i), 3))))
else if(lowertext(copytext(token(i), 1, 3)) == "0x" && isnum(hex2num(copytext(token(i), 3))))//3 == length("0x") + 1
node += hex2num(copytext(token(i), 3))
i++
@@ -621,16 +621,16 @@
node += text2num(token(i))
i++
else if(copytext(token(i), 1, 2) in list("'", "\""))
else if(token(i)[1] in list("'", "\""))
i = string(i, node)
else if(copytext(token(i), 1, 2) == "\[") // Start a list.
else if(token(i)[1] == "\[") // Start a list.
i = array(i, node)
else if(copytext(token(i), 1, 3) == "@\[")
else if(copytext(token(i), 1, 3) == "@\[")//3 == length("@\[") + 1
i = selectors_array(i, node)
else if(copytext(token(i), 1, 2) == "/")
else if(token(i)[1] == "/")
i = object_type(i, node)
else
+1 -1
View File
@@ -167,7 +167,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
//is_bwoink is TRUE if this ticket was started by an admin PM
/datum/admin_help/New(msg, client/C, is_bwoink)
//clean the input msg
msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN))
msg = sanitize(copytext_char(msg, 1, MAX_MESSAGE_LEN))
if(!msg || !C || !C.mob)
qdel(src)
return
+4 -4
View File
@@ -40,7 +40,7 @@
return
var/client/C
if(istext(whom))
if(cmptext(copytext(whom,1,2),"@"))
if(whom[1] == "@")
whom = findStealthKey(whom)
C = GLOB.directory[whom]
else if(istype(whom, /client))
@@ -75,7 +75,7 @@
var/client/recipient
var/external = 0
if(istext(whom))
if(cmptext(copytext(whom,1,2),"@"))
if(whom[1] == "@")
whom = findStealthKey(whom)
if(whom == "IRCKEY")
external = 1
@@ -132,7 +132,7 @@
//clean the message if it's not sent by a high-rank admin
if(!check_rights(R_SERVER|R_DEBUG,0)||external)//no sending html to the poor bots
msg = trim(sanitize(copytext(msg,1,MAX_MESSAGE_LEN)))
msg = trim(sanitize(msg), MAX_MESSAGE_LEN)
if(!msg)
return
@@ -293,7 +293,7 @@
if(!stealthkey)
stealthkey = GenTgsStealthKey()
msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN))
msg = sanitize(copytext_char(msg, 1, MAX_MESSAGE_LEN))
if(!msg)
return "Error: No message"
+1 -1
View File
@@ -5,7 +5,7 @@
if(!check_rights(0))
return
msg = emoji_parse(copytext(sanitize(msg), 1, MAX_MESSAGE_LEN))
msg = emoji_parse(copytext_char(sanitize(msg), 1, MAX_MESSAGE_LEN))
if(!msg)
return
+1 -1
View File
@@ -14,7 +14,7 @@
if (handle_spam_prevention(msg,MUTE_DEADCHAT))
return
msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN)
msg = copytext_char(sanitize(msg), 1, MAX_MESSAGE_LEN)
mob.log_talk(msg, LOG_DSAY)
if (!msg)
@@ -33,7 +33,7 @@
var/map = input(src, "Choose a Map Template to upload to template storage","Upload Map Template") as null|file
if(!map)
return
if(copytext("[map]",-4) != ".dmm")
if(copytext("[map]", -4) != ".dmm")//4 == length(".dmm")
to_chat(src, "<span class='warning'>Filename must end in '.dmm': [map]</span>")
return
var/datum/map_template/M
+1 -1
View File
@@ -49,7 +49,7 @@
if(isnull(map_file))
return
if(copytext("[map_file]",-4) != ".dmm")
if(copytext("[map_file]", -4) != ".dmm")//4 == length(".dmm")
to_chat(src, "<span class='warning'>Filename must end in '.dmm': [map_file]</span>")
return
+4 -4
View File
@@ -6,7 +6,7 @@
to_chat(usr, "<span class='danger'>Speech is currently admin-disabled.</span>")
return
msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN)
msg = copytext_char(sanitize(msg), 1, MAX_MESSAGE_LEN)
if(!msg)
return
log_prayer("[src.key]/([src.name]): [msg]")
@@ -54,21 +54,21 @@
//log_admin("HELP: [key_name(src)]: [msg]")
/proc/CentCom_announce(text , mob/Sender)
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
var/msg = copytext_char(sanitize(text), 1, MAX_MESSAGE_LEN)
msg = "<span class='adminnotice'><b><font color=orange>CENTCOM:</font>[ADMIN_FULLMONTY(Sender)] [ADMIN_CENTCOM_REPLY(Sender)]:</b> [msg]</span>"
to_chat(GLOB.admins, msg)
for(var/obj/machinery/computer/communications/C in GLOB.machines)
C.overrideCooldown()
/proc/Syndicate_announce(text , mob/Sender)
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
var/msg = copytext_char(sanitize(text), 1, MAX_MESSAGE_LEN)
msg = "<span class='adminnotice'><b><font color=crimson>SYNDICATE:</font>[ADMIN_FULLMONTY(Sender)] [ADMIN_SYNDICATE_REPLY(Sender)]:</b> [msg]</span>"
to_chat(GLOB.admins, msg)
for(var/obj/machinery/computer/communications/C in GLOB.machines)
C.overrideCooldown()
/proc/Nuke_request(text , mob/Sender)
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
var/msg = copytext_char(sanitize(text), 1, MAX_MESSAGE_LEN)
msg = "<span class='adminnotice'><b><font color=orange>NUKE CODE REQUEST:</font>[ADMIN_FULLMONTY(Sender)] [ADMIN_CENTCOM_REPLY(Sender)] [ADMIN_SET_SD_CODE]:</b> [msg]</span>"
to_chat(GLOB.admins, msg)
for(var/obj/machinery/computer/communications/C in GLOB.machines)
@@ -55,9 +55,9 @@ GLOBAL_PROTECT(VVpixelmovement)
// the type with the base type removed from the begaining
var/fancytype = types[D.type]
if (findtext(fancytype, types[type]))
fancytype = copytext(fancytype, length(types[type])+1)
var/shorttype = copytext("[D.type]", length("[type]")+1)
if (length(shorttype) > length(fancytype))
fancytype = copytext(fancytype, length(types[type]) + 1)
var/shorttype = copytext("[D.type]", length("[type]") + 1)
if (length_char(shorttype) > length_char(fancytype))
shorttype = fancytype
if (!length(shorttype))
shorttype = "/"