diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index c5ae3b27d3..5aab3c5abc 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -389,381 +389,404 @@ client return html - Topic(href, href_list, hsrc) +//All BYOND links pass through client/Topic() FIRST and are then directed to [hsrc]/Topic() by the ..() call at the end. +client/Topic(href, href_list, hsrc) - if (href_list["Vars"]) - debug_variables(locate(href_list["Vars"])) + //search the href for script injection //This is a temporary measure + if( findtext(href," 512) 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 ÿ + if(0 to 31) return //more weird stuff + if(32) //whitespace + else non_whitespace = 1 + if(non_whitespace) return text //only accepts the text if it has some non-spaces + /proc/strip_html_simple(var/t,var/limit=MAX_MESSAGE_LEN) var/list/strip_chars = list("<",">") t = copytext(t,1,limit) diff --git a/code/defines/world.dm b/code/defines/world.dm index f3fac8f12b..9a5cf1c6d9 100644 --- a/code/defines/world.dm +++ b/code/defines/world.dm @@ -6,12 +6,12 @@ world Topic(href, href_list[]) - world << "Received a Topic() call!" - world << "[href]" - for(var/a in href_list) - world << "[a]" - if(href_list["hello"]) - world << "Hello world!" - return "Hello world!" - world << "End of Topic() call." - ..() \ No newline at end of file +// world << "Received a Topic() call!" +// world << "[href]" +// for(var/a in href_list) +// world << "[a]" +// if(href_list["hello"]) +// world << "Hello world!" +// return "Hello world!" +// world << "End of Topic() call." +// ..() diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm index 8601b60d50..f00e864cdc 100644 --- a/code/game/machinery/computer/HolodeckControl.dm +++ b/code/game/machinery/computer/HolodeckControl.dm @@ -34,9 +34,6 @@ dat += "Please ensure that only holographic weapons are used in the holodeck if a combat simulation has been loaded.
" - if(issilicon(user) && !emagged) - dat += "(Override Safety Protocols?)
" - if(emagged) dat += "(Begin Atmospheric Burn Simulation)
" dat += "Ensure the holodeck is empty before testing.
" @@ -46,6 +43,8 @@ dat += "
" dat += "Safety Protocols are DISABLED
" else + if(issilicon(user)) + dat += "(Override Safety Protocols?)
" dat += "
" dat += "Safety Protocols are ENABLED
" @@ -88,16 +87,19 @@ loadProgram(target) else if(href_list["burntest"]) + if(!emagged) return target = locate(/area/holodeck/source_burntest) if(target) loadProgram(target) else if(href_list["wildlifecarp"]) + if(!emagged) return target = locate(/area/holodeck/source_wildlife) if(target) loadProgram(target) else if(href_list["AIoverride"]) + if(!issilicon(usr)) return emagged = 1 src.add_fingerprint(usr) diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index 9c9d6c675a..9a02fe6025 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -1,5 +1,5 @@ /******************** Requests Console ********************/ -/** Originally written by errorage, updated by: **/ +/** Originally written by errorage, updated by: Carn, needs more work though. I just added some security fixes */ var/req_console_assistance = list() var/req_console_supplies = list() @@ -41,7 +41,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() // 9 = authentication before sending // 10 = send announcement var/silent = 0 // set to 1 for it not to beep all the time - var/hackState = 0 +// var/hackState = 0 // 0 = not hacked // 1 = hacked var/announcementConsole = 0 @@ -57,270 +57,319 @@ var/list/obj/machinery/requests_console/allConsoles = list() luminosity = 0 /obj/machinery/requests_console/New() - src.name = "[src.department] Requests Console" + name = "[department] Requests Console" allConsoles += src //req_console_departments += department - switch(src.departmentType) + switch(departmentType) if(1) - if(!("[src.department]" in req_console_assistance)) + if(!("[department]" in req_console_assistance)) req_console_assistance += department if(2) - if(!("[src.department]" in req_console_supplies)) + if(!("[department]" in req_console_supplies)) req_console_supplies += department if(3) - if(!("[src.department]" in req_console_information)) + if(!("[department]" in req_console_information)) req_console_information += department if(4) - if(!("[src.department]" in req_console_assistance)) + if(!("[department]" in req_console_assistance)) req_console_assistance += department - if(!("[src.department]" in req_console_supplies)) + if(!("[department]" in req_console_supplies)) req_console_supplies += department if(5) - if(!("[src.department]" in req_console_assistance)) + if(!("[department]" in req_console_assistance)) req_console_assistance += department - if(!("[src.department]" in req_console_information)) + if(!("[department]" in req_console_information)) req_console_information += department if(6) - if(!("[src.department]" in req_console_supplies)) + if(!("[department]" in req_console_supplies)) req_console_supplies += department - if(!("[src.department]" in req_console_information)) + if(!("[department]" in req_console_information)) req_console_information += department if(7) - if(!("[src.department]" in req_console_assistance)) + if(!("[department]" in req_console_assistance)) req_console_assistance += department - if(!("[src.department]" in req_console_supplies)) + if(!("[department]" in req_console_supplies)) req_console_supplies += department - if(!("[src.department]" in req_console_information)) + if(!("[department]" in req_console_information)) req_console_information += department /obj/machinery/requests_console/attack_hand(user as mob) var/dat - dat = text("Requests Console

[src.department] Requests Console

") - if(!src.open) - if (src.screen == 0) - announceAuth = 0 - if (src.newmessagepriority == 1) - dat += text("There are new messages
") - if (src.newmessagepriority == 2) - dat += text("NEW PRIORITY MESSAGES
") - dat += text("View Messages

") + dat = text("Requests Console

[department] Requests Console

") + if(!open) + switch(screen) + if(1) //req. assistance + dat += text("Which department do you need assistance from?

") + for(var/dpt in req_console_assistance) + if (dpt != department) + dat += text("[dpt] (Message or ") + dat += text("High Priority") +// if (hackState == 1) +// dat += text(" or EXTREME)") + dat += text(")
") + dat += text("
Back
") + + if(2) //req. supplies + dat += text("Which department do you need supplies from?

") + for(var/dpt in req_console_supplies) + if (dpt != department) + dat += text("[dpt] (Message or ") + dat += text("High Priority") +// if (hackState == 1) +// dat += text(" or EXTREME)") + dat += text(")
") + dat += text("
Back
") + + if(3) //relay information + dat += text("Which department would you like to send information to?

") + for(var/dpt in req_console_information) + if (dpt != department) + dat += text("[dpt] (Message or ") + dat += text("High Priority") +// if (hackState == 1) +// dat += text(" or EXTREME)") + dat += text(")
") + dat += text("
Back
") + + if(6) //sent successfully + dat += text("Message sent

") + dat += text("Continue
") + + if(7) //unsuccessful; not sent + dat += text("An error occurred.

") + dat += text("Continue
") + + if(8) //view messages + for (var/obj/machinery/requests_console/Console in allConsoles) + if (Console.department == department) + Console.newmessagepriority = 0 + Console.icon_state = "req_comp0" + Console.luminosity = 1 + newmessagepriority = 0 + icon_state = "req_comp0" + for(var/msg in messages) + dat += text("[msg]
") + dat += text("Back to main menu
") + + if(9) //authentication before sending + dat += text("Message Authentication

") + dat += text("Message for [dpt]: [message]

") + dat += text("You may authenticate your message now by scanning your ID or your stamp

") + dat += text("Validated by: [msgVerified]
"); + dat += text("Stamped by: [msgStamped]
"); + dat += text("Send
"); + dat += text("
Back
") + + if(10) //send announcement + dat += text("Station wide announcement

") + if(announceAuth) + dat += text("Authentication accepted

") + else + dat += text("Swipe your card to authenticate yourself.

") + dat += text("Message: [message] Write

") + if (announceAuth && message) + dat += text("Announce
"); + dat += text("
Back
") + + else //main menu + screen = 0 + announceAuth = 0 + if (newmessagepriority == 1) + dat += text("There are new messages
") + if (newmessagepriority == 2) + dat += text("NEW PRIORITY MESSAGES
") + dat += text("View Messages

") + + dat += text("Request Assistance
") + dat += text("Request Supplies
") + dat += text("Relay Anonymous Information

") + if(announcementConsole) + dat += text("Send station-wide announcement

") + if (silent) + dat += text("Speaker OFF") + else + dat += text("Speaker ON") - dat += text("Request Assistance
") - dat += text("Request Supplies
") - dat += text("Relay Anonymous Information

") - if(announcementConsole) - dat += text("Send station-wide announcement

") - //dat += text("
Call Mailman

") // This is the line to call the mailman, it's intended for it to message him on his PDA - if (src.silent) - dat += text("Speaker OFF") - else - dat += text("Speaker ON") - if (src.screen == 1) - dat += text("Which department do you need assistance from?

") - for(var/dpt in req_console_assistance) - if (dpt != src.department) - dat += text("[dpt] (Message or ") - dat += text("High Priority") - if (src.hackState == 1) - dat += text(" or EXTREME)") - dat += text(")
") - dat += text("
Back
") - if (src.screen == 2) - dat += text("Which department do you need supplies from?

") - for(var/dpt in req_console_supplies) - if (dpt != src.department) - dat += text("[dpt] (Message or ") - dat += text("High Priority") - if (src.hackState == 1) - dat += text(" or EXTREME)") - dat += text(")
") - dat += text("
Back
") - if (src.screen == 3) - dat += text("Which department would you like to send information to?

") - for(var/dpt in req_console_information) - if (dpt != src.department) - dat += text("[dpt] (Message or ") - dat += text("High Priority") - if (src.hackState == 1) - dat += text(" or EXTREME)") - dat += text(")
") - dat += text("
Back
") - if (src.screen == 6) - dat += text("Message sent

") - dat += text("Continue
") - if (src.screen == 7) - dat += text("An error occurred.

") - dat += text("Continue
") - if (src.screen == 8) - for (var/obj/machinery/requests_console/CONSOLE in allConsoles) - if (CONSOLE.department == src.department) - CONSOLE.newmessagepriority = 0 - CONSOLE.icon_state = "req_comp0" - CONSOLE.luminosity = 1 - src.newmessagepriority = 0 - icon_state = "req_comp0" - for(var/msg in src.messages) - dat += text("[msg]
") - dat += text("Back to main menu
") - if (src.screen == 9) - dat += text("Message Authentication

") - dat += text("Message for [src.dpt]: [message]

") - dat += text("You may authenticate your message now by scanning your ID or your stamp

") - dat += text("Validated by: [msgVerified]
"); - dat += text("Stamped by: [msgStamped]
"); - dat += text("Send
"); - dat += text("
Back
") - if (src.screen == 10) - dat += text("Station wide announcement

") - if(announceAuth) - dat += text("Authentication accepted

") - else - dat += text("Swipe your card to authenticate yourself.

") - dat += text("Message: [message] Write

") - if (announceAuth && message) - dat += text("Announce
"); - dat += text("
Back
") user << browse("[dat]", "") onclose(user, "req_console") return /obj/machinery/requests_console/Topic(href, href_list) - if(..()) - return + if(..()) return usr.machine = src - src.add_fingerprint(usr) - if(href_list["write"]) - src.dpt = href_list["write"] //write contains the string of the receiving department's name - src.message = strip_html(input(usr, "Write your message", "Messanger", "")) - src.priority = href_list["priority"] - while (findtext(src.message," ") == 1) - src.message = copytext(src.message,2,lentext(src.message)+1) - if (findtext(src.message," ") == 1) - src.message = ""; - if (src.message != "") + add_fingerprint(usr) + + if(reject_bad_text(href_list["write"])) + dpt = ckey(href_list["write"]) //write contains the string of the receiving department's name + + var/new_message = reject_bad_text(input(usr, "Write your message:", "Awaiting Input", "")) + if(new_message) + message = new_message screen = 9 + switch(href_list["priority"]) + if("2") priority = 2 + else priority = -1 else dpt = ""; - msgVerified = ""; - msgStamped = ""; + msgVerified = "" + msgStamped = "" screen = 0 priority = -1 + if(href_list["writeAnnouncement"]) - src.message = input(usr, "Write your message", "Messanger", "") - src.priority = href_list["priority"] - while (findtext(src.message," ") == 1) - src.message = copytext(src.message,2,lentext(src.message)+1) - if (findtext(src.message," ") == 1) - src.message = ""; - if (src.message == "") - announceAuth = 0; + var/new_message = reject_bad_text(input(usr, "Write your message:", "Awaiting Input", "")) + if(new_message) + message = new_message + switch(href_list["priority"]) + if("2") priority = 2 + else priority = -1 + else + message = "" + announceAuth = 0 screen = 0 + if(href_list["sendAnnouncement"]) - world << "[department] announcement: [html_encode(message)]" + if(!announcementConsole) return + world << "[department] announcement: [message]" announceAuth = 0 message = "" screen = 0 - if(href_list["department"] && src.message) - var/log_msg = src.message - var/message = src.message; - message += "
" - if (src.msgVerified) - message += src.msgVerified - message += "
" - if (src.msgStamped) - message += src.msgStamped - message += "
" - src.screen = 7 //if it's successful, this will get overrwritten (7 = unsufccessfull, 6 = successfull) - if (message) + + if( href_list["department"] && message ) + var/log_msg = message + var/sending = message + sending += "
" + if (msgVerified) + sending += msgVerified + sending += "
" + if (msgStamped) + sending += msgStamped + sending += "
" + screen = 7 //if it's successful, this will get overrwritten (7 = unsufccessfull, 6 = successfull) + if (sending) for (var/obj/machinery/message_server/MS in world) - MS.send_rc_message(href_list["department"],src.department,log_msg,msgStamped,msgVerified,priority) - for (var/obj/machinery/requests_console/CONSOLE in allConsoles) - if (ckey(CONSOLE.department) == ckey(href_list["department"])) - if(src.priority == "2") //High priority - if(CONSOLE.newmessagepriority < 2) - CONSOLE.newmessagepriority = 2 - CONSOLE.icon_state = "req_comp2" - if(!CONSOLE.silent) - playsound(CONSOLE.loc, 'twobeep.ogg', 50, 1) - for (var/mob/O in hearers(5, CONSOLE.loc)) - O.show_message(text("\icon[CONSOLE] *The Requests Console beeps: 'PRIORITY Alert in [src.department]'")) - CONSOLE.messages += "High Priority message from [src.department]
[message]" - else if(src.priority == "3" - ) //Not implemanted, but will be - if(CONSOLE.newmessagepriority < 3) - CONSOLE.newmessagepriority = 3 - CONSOLE.icon_state = "req_comp3" - if(!CONSOLE.silent) - playsound(CONSOLE.loc, 'twobeep.ogg', 50, 1) - for (var/mob/O in hearers(7, CONSOLE.loc)) - O.show_message(text("\icon[CONSOLE] *The Requests Console yells: 'EXTREME PRIORITY alert in [src.department]'")) - CONSOLE.messages += "Extreme Priority message from [ckey(src.department)]
[message]" - else // Normal priority - if(CONSOLE.newmessagepriority < 1) - CONSOLE.newmessagepriority = 1 - CONSOLE.icon_state = "req_comp1" - if(!CONSOLE.silent) - playsound(CONSOLE.loc, 'twobeep.ogg', 50, 1) - for (var/mob/O in hearers(4, CONSOLE.loc)) - O.show_message(text("\icon[CONSOLE] *The Requests Console beeps: 'Message from [src.department]'")) - CONSOLE.messages += "Message from [src.department]
[message]" - src.screen = 6 - CONSOLE.luminosity = 2 - src.messages += "Message sent to [src.dpt]
[message]" - if(href_list["setScreen"]) - src.screen = text2num(href_list["setScreen"]) - if (src.screen == 0) - dpt = ""; - msgVerified = ""; - msgStamped = ""; - message = ""; - priority = -1; - if(href_list["setSilent"]) - src.silent = text2num(href_list["setSilent"]) - src.updateUsrDialog() + MS.send_rc_message(href_list["department"],department,log_msg,msgStamped,msgVerified,priority) + + for (var/obj/machinery/requests_console/Console in allConsoles) + if (ckey(Console.department) == ckey(href_list["department"])) + + switch(priority) + if("2") //High priority + if(Console.newmessagepriority < 2) + Console.newmessagepriority = 2 + Console.icon_state = "req_comp2" + if(!Console.silent) + playsound(Console.loc, 'twobeep.ogg', 50, 1) + for (var/mob/O in hearers(5, Console.loc)) + O.show_message(text("\icon[Console] *The Requests Console beeps: 'PRIORITY Alert in [department]'")) + Console.messages += "High Priority message from [department]
[sending]" + + // if("3") //Not implemanted, but will be //Removed as it doesn't look like anybody intends on implimenting it ~Carn + // if(Console.newmessagepriority < 3) + // Console.newmessagepriority = 3 + // Console.icon_state = "req_comp3" + // if(!Console.silent) + // playsound(Console.loc, 'twobeep.ogg', 50, 1) + // for (var/mob/O in hearers(7, Console.loc)) + // O.show_message(text("\icon[Console] *The Requests Console yells: 'EXTREME PRIORITY alert in [department]'")) + // Console.messages += "Extreme Priority message from [ckey(department)]
[message]" + + else // Normal priority + if(Console.newmessagepriority < 1) + Console.newmessagepriority = 1 + Console.icon_state = "req_comp1" + if(!Console.silent) + playsound(Console.loc, 'twobeep.ogg', 50, 1) + for (var/mob/O in hearers(4, Console.loc)) + O.show_message(text("\icon[Console] *The Requests Console beeps: 'Message from [department]'")) + Console.messages += "Message from [department]
[message]" + + screen = 6 + Console.luminosity = 2 + messages += "Message sent to [dpt]
[message]" + + //Handle screen switching + switch(text2num(href_list["setScreen"])) + if(null) //skip + if(1) //req. assistance + screen = 1 + if(2) //req. supplies + screen = 2 + if(3) //relay information + screen = 3 +// if(4) //write message +// screen = 4 + if(5) //choose priority + screen = 5 + if(6) //sent successfully + screen = 6 + if(7) //unsuccessfull; not sent + screen = 7 + if(8) //view messages + screen = 8 + if(9) //authentication + screen = 9 + if(10) //send announcement + if(!announcementConsole) return + screen = 10 + else //main menu + dpt = "" + msgVerified = "" + msgStamped = "" + message = "" + priority = -1 + screen = 0 + + //Handle silencing the console + switch( href_list["setSilent"] ) + if(null) //skip + if("1") silent = 1 + else silent = 0 + + updateUsrDialog() return //err... hacking code, which has no reason for existing... but anyway... it's supposed to unlock priority 3 messanging on that console (EXTREME priority...) the code for that actually exists. /obj/machinery/requests_console/attackby(var/obj/item/weapon/O as obj, var/mob/user as mob) /* if (istype(O, /obj/item/weapon/crowbar)) - if(src.open) - src.open = 0 - src.icon_state="req_comp0" + if(open) + open = 0 + icon_state="req_comp0" else - src.open = 1 - if(src.hackState == 0) - src.icon_state="req_comp_open" - else if(src.hackState == 1) - src.icon_state="req_comp_rewired" + open = 1 + if(hackState == 0) + icon_state="req_comp_open" + else if(hackState == 1) + icon_state="req_comp_rewired" if (istype(O, /obj/item/weapon/screwdriver)) - if(src.open) - if(src.hackState == 0) - src.hackState = 1 - src.icon_state="req_comp_rewired" - else if(src.hackState == 1) - src.hackState = 0 - src.icon_state="req_comp_open" + if(open) + if(hackState == 0) + hackState = 1 + icon_state="req_comp_rewired" + else if(hackState == 1) + hackState = 0 + icon_state="req_comp_open" else user << "You can't do much with that."*/ if (istype(O, /obj/item/weapon/card/id)) - if(src.screen == 9) + if(screen == 9) var/obj/item/weapon/card/id/T = O - src.msgVerified = text("Verified by [T.registered_name] ([T.assignment])") - src.updateUsrDialog() - if(src.screen == 10) + msgVerified = text("Verified by [T.registered_name] ([T.assignment])") + updateUsrDialog() + if(screen == 10) var/obj/item/weapon/card/id/ID = O if (access_RC_announce in ID.access) announceAuth = 1 else announceAuth = 0 user << "\red You are not authorized to send announcements." - src.updateUsrDialog() + updateUsrDialog() if (istype(O, /obj/item/weapon/stamp)) - if(src.screen == 9) + if(screen == 9) var/obj/item/weapon/stamp/T = O - src.msgStamped = text("Stamped with the [T.name]") - src.updateUsrDialog() - return \ No newline at end of file + msgStamped = text("Stamped with the [T.name]") + updateUsrDialog() + return diff --git a/code/modules/chemical/Chemistry-Machinery.dm b/code/modules/chemical/Chemistry-Machinery.dm index 809ce4300d..81eb661af7 100644 --- a/code/modules/chemical/Chemistry-Machinery.dm +++ b/code/modules/chemical/Chemistry-Machinery.dm @@ -206,6 +206,7 @@ if(usr.stat || usr.restrained()) return if(!in_range(src, usr)) return + src.add_fingerprint(usr) usr.machine = src if(!beaker) return var/datum/reagents/R = beaker:reagents @@ -259,18 +260,18 @@ reagents.clear_reagents() icon_state = "mixer0" else if (href_list["createpill"]) - var/name = input(usr,"Name:","Name your pill!",reagents.get_master_reagent_name()) + var/name = reject_bad_text(input(usr,"Name:","Name your pill!",reagents.get_master_reagent_name())) var/obj/item/weapon/reagent_containers/pill/P = new/obj/item/weapon/reagent_containers/pill(src.loc) - if(!name || name == " ") name = reagents.get_master_reagent_name() + if(!name) name = reagents.get_master_reagent_name() P.name = "[name] pill" P.pixel_x = rand(-7, 7) //random position P.pixel_y = rand(-7, 7) reagents.trans_to(P,50) else if (href_list["createbottle"]) if(!condi) - var/name = input(usr,"Name:","Name your bottle!",reagents.get_master_reagent_name()) + var/name = reject_bad_text(input(usr,"Name:","Name your bottle!",reagents.get_master_reagent_name())) var/obj/item/weapon/reagent_containers/glass/bottle/P = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc) - if(!name || name == " ") name = reagents.get_master_reagent_name() + if(!name) name = reagents.get_master_reagent_name() P.name = "[name] bottle" P.pixel_x = rand(-7, 7) //random position P.pixel_y = rand(-7, 7) @@ -281,7 +282,6 @@ else usr << browse(null, "window=chem_master") src.updateUsrDialog() - src.add_fingerprint(usr) return attack_ai(mob/user as mob) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 867c85c263..437e3d0eb0 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -582,27 +582,12 @@ if(src:cameraFollow) src:cameraFollow = null - -/client/Topic(href, href_list) - if(href_list["priv_msg"]) - var/client/C = locate(href_list["priv_msg"]) - if(ismob(C)) //Old stuff can pass in mobs instead of clients - var/mob/M = C - C = M.client - cmd_admin_pm(C,null) - else - ..() - /mob/Topic(href, href_list) - if(href_list["priv_msg"]) //for priv_msg references that have yet to be updated to target clients. Forwards it to client/Topic() - if(client) - client.Topic(href, href_list) - if(href_list["mach_close"]) var/t1 = text("window=[href_list["mach_close"]]") machine = null src << browse(null, t1) - ..() +// ..() return /mob/proc/get_damage() diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm index c3170b36ef..7aa68d683e 100644 --- a/code/modules/paperwork/handlabeler.dm +++ b/code/modules/paperwork/handlabeler.dm @@ -40,7 +40,7 @@ if(mode) usr << "\blue You turn on the hand labeler." //Now let them chose the text. - var/str = input(usr,"Label text?","Set label","") + var/str = reject_bad_text(input(usr,"Label text?","Set label","")) //sanitize stuff! GOD DAMN THIS IS A SECURITY HOLE if(!str || !length(str)) usr << "\red Invalid text." return