/* Monitoring computer for the messaging server. Lets you read request console messages. */ // The monitor itself. /obj/structure/machinery/computer/message_monitor name = "messaging monitor console" desc = "Used to access and maintain data on messaging servers. Allows you to view requests console messages." icon_screen = "comm_logs" icon_keyboard = "green_key" icon_keyboard_emis = "green_key_mask" light_color = LIGHT_COLOR_GREEN var/hack_icon = "error" circuit = /obj/item/circuitboard/message_monitor //Server linked to. var/obj/structure/machinery/telecomms/message_server/linkedServer = null //Sparks effect - For emag var/datum/effect_system/sparks/spark_system //Messages - Saves me time if I want to change something. var/noserver = SPAN_ALERT("ALERT: No server detected.") var/incorrectkey = SPAN_WARNING("ALERT: Incorrect decryption key!") var/defaultmsg = SPAN_NOTICE("Welcome. Please select an option.") var/rebootmsg = SPAN_WARNING("%$&(£: Critical %$$@ Error // !RestArting! - ?pLeaSe wAit!") //Computer properties var/screen = 0 // 0 = Main menu, 1 = Message Logs, 2 = Hacked screen, 3 = Custom Message var/hacking = 0 // Is it being hacked into by the AI/Cyborg var/emag = 0 // When it is emagged. var/message = SPAN_NOTICE("System bootup complete. Please select an option.") // The message that shows on the main menu. var/auth = 0 // Are they authenticated? var/optioncount = 8 // Custom Message Properties var/customsender = "System Administrator" var/customjob = "Admin" var/custommessage = "This is a test, please ignore." /obj/structure/machinery/computer/message_monitor/Initialize() ..() spark_system = bind_spark(src, 5) return INITIALIZE_HINT_LATELOAD /obj/structure/machinery/computer/message_monitor/LateInitialize() . = ..() //If the server isn't linked to a server, and there's a server available, default it to the first one in the list. if(!linkedServer) for(var/obj/structure/machinery/telecomms/message_server/S in SSmachinery.all_telecomms) linkedServer = S break /obj/structure/machinery/computer/message_monitor/Destroy() QDEL_NULL(spark_system) linkedServer = null return ..() /obj/structure/machinery/computer/message_monitor/attackby(obj/item/attacking_item, mob/user, params) if(stat & (NOPOWER|BROKEN)) return ..() if(!istype(user)) return TRUE if(attacking_item.tool_behaviour == TOOL_SCREWDRIVER && emag) //Stops people from just unscrewing the monitor and putting it back to get the console working again. to_chat(user, SPAN_WARNING("It is too hot to mess with!")) return TRUE return ..() /obj/structure/machinery/computer/message_monitor/emag_act(var/remaining_charges, var/mob/user) // Will create sparks and print out the console's password. You will then have to wait a while for the console to be back online. // It'll take more time if there's more characters in the password.. if(!emag && operable()) if(!isnull(linkedServer)) emag = TRUE screen = 2 spark_system.queue() var/obj/item/paper/monitorkey/MK = new/obj/item/paper/monitorkey MK.forceMove(loc) // Will help make emagging the console not so easy to get away with. MK.info += "

£%@%(*$%&(£&?*(%&£/{}" addtimer(CALLBACK(src, PROC_REF(UnmagConsole)), 100 * length(linkedServer.decryptkey)) message = rebootmsg update_icon() return TRUE else to_chat(user, SPAN_NOTICE("A no server error appears on the screen.")) /obj/structure/machinery/computer/message_monitor/update_icon() if(emag || hacking) icon_screen = hack_icon else icon_screen = initial(icon_screen) ..() /obj/structure/machinery/computer/message_monitor/attack_hand(var/mob/living/user as mob) if(stat & (NOPOWER|BROKEN)) return if(!istype(user)) return //If the computer is being hacked or is emagged, display the reboot message. if(hacking || emag) message = rebootmsg var/dat = "" dat += "

Message Monitor Console


" dat += "

" if(auth) dat += "

\[Authenticated\] /" dat += " Server Power: [src.linkedServer && src.linkedServer.use_power ? "\[On\]":SPAN_WARNING("\[Off\]")]

" else dat += "

\[Unauthenticated\] /" dat += " Server Power: [src.linkedServer && src.linkedServer.use_power ? "\[On\]":SPAN_WARNING("\[Off\]")]

" if(hacking || emag) screen = 2 else if(!auth || !linkedServer || (linkedServer.stat & (NOPOWER|BROKEN))) if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN))) message = noserver screen = 0 switch(screen) //Main menu if(0) // = TAB var/i = 0 dat += "
[++i]. Link To A Server
" if(auth) if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN))) dat += "
ERROR: Server not found!
" else dat += "
[++i]. View Message Logs
" dat += "
[++i]. View Requests Console Logs
" dat += "
[++i]. Clear Message Logs
" dat += "
[++i]. Clear Requests Console Logs
" dat += "
[++i]. Set Custom Key
" dat += "
[++i]. Send Admin Message
" dat += "
[++i]. Modify Spam Filter
" else for(var/n = ++i; n <= optioncount; n++) dat += "
[n]. ---------------
" if((istype(user, /mob/living/silicon/ai) || istype(user, /mob/living/silicon/robot)) && (user.mind.special_role && user.mind.original == user)) //Malf/Traitor AIs can bruteforce into the system to gain the Key. dat += "
*&@#. Bruteforce Key
" else dat += "
" //Bottom message if(!auth) dat += "

Please authenticate with the server in order to show additional options." else dat += "

Reg, #514 forbids sending messages to a Head of Staff containing Erotic Rendering Properties." //Message Logs if(1) if(src.linkedServer?.stat & (NOPOWER|BROKEN)) dat += "

Server is currently not accepting connections, or is down." else var/index = 3000 dat += "

" + SPAN_ALERT("Only the last [index] messages are stored!") + "" dat += "
Back - Refresh

" for(var/datum/data_pda_msg/message in src.linkedServer.pda_msgs) if(index-- <= 0) break dat += "

[message.sender] --> [message.recipient]: [message.message]" //Hacking screen. if(2) if(istype(user, /mob/living/silicon/ai) || istype(user, /mob/living/silicon/robot)) dat += "Brute-forcing for server key.
It will take 20 seconds for every character that the password has." dat += "In the meantime, this console can reveal your true intentions if you let someone access it. Make sure no humans enter the room during that time." else //It's the same message as the one above but in binary. Because robots understand binary and humans don't... well I thought it was clever. dat += {"01000010011100100111010101110100011001010010110
10110011001101111011100100110001101101001011011100110011
10010000001100110011011110111001000100000011100110110010
10111001001110110011001010111001000100000011010110110010
10111100100101110001000000100100101110100001000000111011
10110100101101100011011000010000001110100011000010110101
10110010100100000001100100011000000100000011100110110010
10110001101101111011011100110010001110011001000000110011
00110111101110010001000000110010101110110011001010111001
00111100100100000011000110110100001100001011100100110000
10110001101110100011001010111001000100000011101000110100
00110000101110100001000000111010001101000011001010010000
00111000001100001011100110111001101110111011011110111001
00110010000100000011010000110000101110011001011100010000
00100100101101110001000000111010001101000011001010010000
00110110101100101011000010110111001110100011010010110110
10110010100101100001000000111010001101000011010010111001
10010000001100011011011110110111001110011011011110110110
00110010100100000011000110110000101101110001000000111001
00110010101110110011001010110000101101100001000000111100
10110111101110101011100100010000001110100011100100111010
10110010100100000011010010110111001110100011001010110111
00111010001101001011011110110111001110011001000000110100
10110011000100000011110010110111101110101001000000110110
00110010101110100001000000111001101101111011011010110010
10110111101101110011001010010000001100001011000110110001
10110010101110011011100110010000001101001011101000010111
00010000001001101011000010110101101100101001000000111001
10111010101110010011001010010000001101110011011110010000
00110100001110101011011010110000101101110011100110010000
00110010101101110011101000110010101110010001000000111010
00110100001100101001000000111001001101111011011110110110
10010000001100100011101010111001001101001011011100110011
10010000001110100011010000110000101110100001000000111010
001101001011011010110010100101110"} //Requests Console Logs if(4) var/index = 0 /* data_rc_msg X - 5% var/rec_dpt = "Unspecified" //name of the person - 15% var/send_dpt = "Unspecified" //name of the sender- 15% var/message = "Blank" //transferred message - 300px var/stamp = "Unstamped" - 15% var/id_auth = "Unauthenticated" - 15% var/priority = "Normal" - 10% */ dat += "
Back - Refresh

" dat += {""} for(var/datum/data_rc_msg/rc in src.linkedServer.rc_msgs) index++ if(index > 3000) break // Del - Sender - Recepient - Message // X - Al Green - Your Mom - WHAT UP!? dat += {""} dat += "
XSending Dep.Receiving Dep. MessageStampID Auth.Priority.
X
[rc.send_dpt] [rc.rec_dpt][rc.message][rc.stamp][rc.id_auth][rc.priority]
" //Spam filter modification if(5) dat += "
Back - Refresh

" var/index = 0 for(var/token in src.linkedServer.spamfilter) index++ if(index > 3000) break dat += "
[index] \[[token]\]
" dat += "
" if (linkedServer.spamfilter.len < linkedServer.spamfilter_limit) dat += "Add token
" dat += "" message = defaultmsg user << browse(HTML_SKELETON_TITLE("Message Monitor Console", dat), "window=message;size=700x700") onclose(user, "message") return /obj/structure/machinery/computer/message_monitor/attack_ai(mob/user as mob) if(!ai_can_interact(user)) return return src.attack_hand(user) /obj/structure/machinery/computer/message_monitor/proc/BruteForce(mob/user as mob) if(isnull(linkedServer)) to_chat(user, SPAN_WARNING("Could not complete brute-force: Linked Server Disconnected!")) else var/currentKey = src.linkedServer.decryptkey to_chat(user, SPAN_WARNING("Brute-force completed! The key is '[currentKey]'.")) src.hacking = 0 update_icon() src.screen = 0 // Return the screen back to normal /obj/structure/machinery/computer/message_monitor/proc/UnmagConsole() src.emag = 0 update_icon() /obj/structure/machinery/computer/message_monitor/proc/ResetMessage() customsender = "System Administrator" custommessage = "This is a test, please ignore." customjob = "Admin" /obj/structure/machinery/computer/message_monitor/Topic(href, href_list) if(..()) return 1 //Authenticate if (href_list["auth"]) if(auth) auth = 0 screen = 0 else var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null) if(dkey && dkey != "") if(src.linkedServer.decryptkey == dkey) auth = 1 else message = incorrectkey //Turn the server on/off. if (href_list["active"]) if(auth) linkedServer.use_power = !linkedServer.use_power //Find a server if (href_list["find"]) var/list/message_servers = list() for(var/obj/structure/machinery/telecomms/message_server/M in SSmachinery.all_telecomms) message_servers += M if(message_servers.len > 1) linkedServer = input(usr,"Please select a server.", "Select a server.", null) as null|anything in message_servers message = SPAN_ALERT("NOTICE: Server selected.") else if(message_servers.len > 0) linkedServer = message_servers[1] message = SPAN_NOTICE("NOTICE: Only Single Server Detected - Server selected.") else message = noserver //View the logs - KEY REQUIRED if (href_list["view"]) if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN))) message = noserver else if(auth) src.screen = 1 //Clears the logs - KEY REQUIRED if (href_list["clear"]) if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN))) message = noserver else if(auth) src.linkedServer.pda_msgs = list() message = SPAN_NOTICE("NOTICE: Logs cleared.") //Clears the requests console logs - KEY REQUIRED if (href_list["clearr"]) if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN))) message = noserver else if(auth) src.linkedServer.rc_msgs = list() message = SPAN_NOTICE("NOTICE: Logs cleared.") //Change the password - KEY REQUIRED if (href_list["pass"]) if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN))) message = noserver else if(auth) var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null) if(dkey && dkey != "") if(src.linkedServer.decryptkey == dkey) var/newkey = trim(input(usr,"Please enter the new key (3 - 16 characters max):")) if(length(newkey) <= 3) message = SPAN_NOTICE("NOTICE: Decryption key too short!") else if(length(newkey) > 16) message = SPAN_NOTICE("NOTICE: Decryption key too long!") else if(newkey && newkey != "") src.linkedServer.decryptkey = newkey message = SPAN_NOTICE("NOTICE: Decryption key set.") else message = incorrectkey //Hack the Console to get the password if (href_list["hack"]) if((istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/living/silicon/robot)) && (usr.mind.special_role && usr.mind.original == usr)) src.hacking = 1 src.screen = 2 update_icon() //Time it takes to bruteforce is dependant on the password length. spawn(100*length(src.linkedServer.decryptkey)) if(src && src.linkedServer && usr) BruteForce(usr) //Delete the log. if (href_list["delete"]) //Are they on the view logs screen? if(screen == 1) if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN))) message = noserver else //if(istype(href_list["delete"], /datum/data_pda_msg)) src.linkedServer.pda_msgs -= locate(href_list["delete"]) message = SPAN_NOTICE("NOTICE: Log Deleted!") //Delete the requests console log. if (href_list["deleter"]) //Are they on the view logs screen? if(screen == 4) if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN))) message = noserver else //if(istype(href_list["delete"], /datum/data_pda_msg)) src.linkedServer.rc_msgs -= locate(href_list["deleter"]) message = SPAN_NOTICE("NOTICE: Log Deleted!") //Create a custom message if (href_list["msg"]) if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN))) message = noserver else if(auth) src.screen = 3 //Requests Console Logs - KEY REQUIRED if(href_list["viewr"]) if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN))) message = noserver else if(auth) src.screen = 4 //to_chat(usr, href_list["select"]) if(href_list["spam"]) if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN))) message = noserver else if(auth) src.screen = 5 if(href_list["addtoken"]) if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN))) message = noserver else src.linkedServer.spamfilter += input(usr,"Enter text you want to be filtered out","Token creation") as text|null if(href_list["deltoken"]) if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN))) message = noserver else var/tokennum = text2num(href_list["deltoken"]) src.linkedServer.spamfilter.Cut(tokennum,tokennum+1) if (href_list["back"]) src.screen = 0 return src.attack_hand(usr) /obj/item/paper/monitorkey //..() name = "Monitor Decryption Key" var/obj/structure/machinery/telecomms/message_server/server = null /obj/item/paper/monitorkey/Initialize() ..() return INITIALIZE_HINT_LATELOAD /obj/item/paper/monitorkey/LateInitialize() for(var/obj/structure/machinery/telecomms/message_server/server in SSmachinery.all_telecomms) if(!isnull(server)) if(!isnull(server.decryptkey)) info = "

Daily Key Reset


The new message monitor key is '[server.decryptkey]'.
Please keep this a secret and away from unauthorized personnel.
If necessary, change the password to a more secure one." info_links = info icon_state = "paper_words" break