/*
The monitoring computer for the messaging server.
Lets you read PDA and request console messages.
*/
#define LINKED_SERVER_NONRESPONSIVE (!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN)))
// The monitor itself.
/obj/machinery/computer/message_monitor
name = "message monitor console"
desc = "Used to monitor the crew's PDA messages, as well as request console messages."
icon_screen = "comm_logs"
circuit = /obj/item/circuitboard/computer/message_monitor
//Server linked to.
var/obj/machinery/telecomms/message_server/linkedServer = null
//Sparks effect - For emag
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread
//Messages - Saves me time if I want to change something.
var/noserver = "ALERT: No server detected."
var/incorrectkey = "ALERT: Incorrect decryption key!"
var/defaultmsg = "Welcome. Please select an option."
var/rebootmsg = "%$&(�: Critical %$$@ Error // !RestArting! - ?pLeaSe wAit!"
//Computer properties
var/screen = 0 // 0 = Main menu, 1 = Message Logs, 2 = Hacked screen, 3 = Custom Message
var/hacking = FALSE // Is it being hacked into by the AI/Cyborg
var/message = "System bootup complete. Please select an option." // The message that shows on the main menu.
var/auth = FALSE // Are they authenticated?
var/optioncount = 7
// Custom Message Properties
var/customsender = "System Administrator"
var/obj/item/pda/customrecepient = null
var/customjob = "Admin"
var/custommessage = "This is a test, please ignore."
light_color = LIGHT_COLOR_GREEN
/obj/machinery/computer/message_monitor/attackby(obj/item/O, mob/living/user, params)
if(istype(O, /obj/item/screwdriver) && (obj_flags & EMAGGED))
//Stops people from just unscrewing the monitor and putting it back to get the console working again.
to_chat(user, "It is too hot to mess with!")
else
return ..()
/obj/machinery/computer/message_monitor/emag_act(mob/user)
. = ..()
if(obj_flags & EMAGGED)
return
if(isnull(linkedServer))
to_chat(user, "A no server error appears on the screen.")
return
obj_flags |= EMAGGED
screen = 2
spark_system.set_up(5, 0, src)
spark_system.start()
var/obj/item/paper/monitorkey/MK = new(loc, linkedServer)
// Will help make emagging the console not so easy to get away with.
MK.info += "
�%@%(*$%&(�&?*(%&�/{}"
var/time = 100 * length(linkedServer.decryptkey)
addtimer(CALLBACK(src, .proc/UnmagConsole), time)
message = rebootmsg
return TRUE
/obj/machinery/computer/message_monitor/New()
. = ..()
GLOB.telecomms_list += src
/obj/machinery/computer/message_monitor/Initialize()
..()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/computer/message_monitor/LateInitialize()
//Is 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/machinery/telecomms/message_server/S in GLOB.telecomms_list)
linkedServer = S
break
/obj/machinery/computer/message_monitor/Destroy()
GLOB.telecomms_list -= src
. = ..()
/obj/machinery/computer/message_monitor/ui_interact(mob/living/user)
. = ..()
//If the computer is being hacked or is emagged, display the reboot message.
if(hacking || (obj_flags & EMAGGED))
message = rebootmsg
var/dat = "
"
if(auth)
dat += ""
else
dat += " \[Unauthenticated\] /"
dat += " Server Power: [linkedServer && linkedServer.toggled ? "\[On\]":"\[Off\]"]
"
if(hacking || (obj_flags & EMAGGED))
screen = 2
else if(!auth || LINKED_SERVER_NONRESPONSIVE)
if(LINKED_SERVER_NONRESPONSIVE)
message = noserver
screen = 0
switch(screen)
//Main menu
if(0)
// = TAB
var/i = 0
dat += " [++i]. Link To A Server"
if(auth)
if(LINKED_SERVER_NONRESPONSIVE)
dat += " ERROR: Server not found!
"
else
dat += " [++i]. View Message Logs
"
dat += " [++i]. View Request Console Logs "
dat += " [++i]. Clear Message Logs
"
dat += " [++i]. Clear Request Console Logs
"
dat += " [++i]. Set Custom Key
"
dat += " [++i]. Send Admin Message
"
else
for(var/n = ++i; n <= optioncount; n++)
dat += " [n]. ---------------
"
var/mob/living/silicon/S = usr
if(istype(S) && S.hack_software)
//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)
var/index = 0
dat += "Back - Refresh
"
dat += "| X | Sender | Recipient | Message |
"
for(var/datum/data_pda_msg/pda in linkedServer.pda_msgs)
index++
if(index > 3000)
break
// Del - Sender - Recepient - Message
// X - Al Green - Your Mom - WHAT UP!?
dat += "| X | [pda.sender] | [pda.recipient] | [pda.message][pda.picture ? " (Photo)":""] |
"
dat += "
"
//Hacking screen.
if(2)
if(isAI(user) || iscyborg(user))
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"}
//Fake messages
if(3)
dat += "Back - Reset
"
dat += {"
| Sender |
Sender's Job |
Recipient |
Message |
"}
//Sender - Sender's Job - Recepient - Message
//Al Green- Your Dad - Your Mom - WHAT UP!?
dat += {"| [customsender] |
[customjob] |
[customrecepient ? customrecepient.owner : "NONE"] |
[custommessage] |
"}
dat += "
Send"
//Request 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 += {"| X | Sending Dep. | Receiving Dep. |
Message | Stamp | ID Auth. | Priority. |
"}
for(var/datum/data_rc_msg/rc in linkedServer.rc_msgs)
index++
if(index > 3000)
break
// Del - Sender - Recepient - Message
// X - Al Green - Your Mom - WHAT UP!?
dat += {"| X | [rc.send_dpt] |
[rc.rec_dpt] | [rc.message] | [rc.stamp] | [rc.id_auth] | [rc.priority] |
"}
dat += "
"
message = defaultmsg
var/datum/browser/popup = new(user, "hologram_console", name, 700, 700)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open()
/obj/machinery/computer/message_monitor/proc/BruteForce(mob/user)
if(isnull(linkedServer))
to_chat(user, "Could not complete brute-force: Linked Server Disconnected!")
else
var/currentKey = linkedServer.decryptkey
to_chat(user, "Brute-force completed! The key is '[currentKey]'.")
hacking = FALSE
screen = 0 // Return the screen back to normal
/obj/machinery/computer/message_monitor/proc/UnmagConsole()
obj_flags &= ~EMAGGED
/obj/machinery/computer/message_monitor/proc/ResetMessage()
customsender = "System Administrator"
customrecepient = null
custommessage = "This is a test, please ignore."
customjob = "Admin"
/obj/machinery/computer/message_monitor/Topic(href, href_list)
if(..())
return
if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || issilicon(usr))
//Authenticate
if (href_list["auth"])
if(LINKED_SERVER_NONRESPONSIVE)
message = noserver
else if(auth)
auth = FALSE
screen = 0
else
var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null)
if(dkey && dkey != "")
if(linkedServer.decryptkey == dkey)
auth = TRUE
else
message = incorrectkey
//Turn the server on/off.
if (href_list["active"])
if(LINKED_SERVER_NONRESPONSIVE)
message = noserver
else if(auth)
linkedServer.toggled = !linkedServer.toggled
//Find a server
if (href_list["find"])
var/list/message_servers = list()
for (var/obj/machinery/telecomms/message_server/M in GLOB.telecomms_list)
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 = "NOTICE: Server selected."
else if(message_servers.len > 0)
linkedServer = message_servers[1]
message = "NOTICE: Only Single Server Detected - Server selected."
else
message = noserver
//View the logs - KEY REQUIRED
if (href_list["view_logs"])
if(LINKED_SERVER_NONRESPONSIVE)
message = noserver
else if(auth)
screen = 1
//Clears the logs - KEY REQUIRED
if (href_list["clear_logs"])
if(LINKED_SERVER_NONRESPONSIVE)
message = noserver
else if(auth)
linkedServer.pda_msgs = list()
message = "NOTICE: Logs cleared."
//Clears the request console logs - KEY REQUIRED
if (href_list["clear_requests"])
if(LINKED_SERVER_NONRESPONSIVE)
message = noserver
else if(auth)
linkedServer.rc_msgs = list()
message = "NOTICE: Logs cleared."
//Change the password - KEY REQUIRED
if (href_list["pass"])
if(LINKED_SERVER_NONRESPONSIVE)
message = noserver
else if(auth)
var/dkey = stripped_input(usr, "Please enter the decryption key.")
if(dkey && dkey != "")
if(linkedServer.decryptkey == dkey)
var/newkey = trim(input(usr,"Please enter the new key (3 - 16 characters max):"))
if(length(newkey) <= 3)
message = "NOTICE: Decryption key too short!"
else if(length(newkey) > 16)
message = "NOTICE: Decryption key too long!"
else if(newkey && newkey != "")
linkedServer.decryptkey = newkey
message = "NOTICE: Decryption key set."
else
message = incorrectkey
//Hack the Console to get the password
if (href_list["hack"])
var/mob/living/silicon/S = usr
if(istype(S) && S.hack_software)
hacking = TRUE
screen = 2
//Time it takes to bruteforce is dependant on the password length.
spawn(100*length(linkedServer.decryptkey))
if(src && linkedServer && usr)
BruteForce(usr)
//Delete the log.
if (href_list["delete_logs"])
//Are they on the view logs screen?
if(screen == 1)
if(LINKED_SERVER_NONRESPONSIVE)
message = noserver
else //if(istype(href_list["delete_logs"], /datum/data_pda_msg))
linkedServer.pda_msgs -= locate(href_list["delete_logs"])
message = "NOTICE: Log Deleted!"
//Delete the request console log.
if (href_list["delete_requests"])
//Are they on the view logs screen?
if(screen == 4)
if(LINKED_SERVER_NONRESPONSIVE)
message = noserver
else //if(istype(href_list["delete_logs"], /datum/data_pda_msg))
linkedServer.rc_msgs -= locate(href_list["delete_requests"])
message = "NOTICE: Log Deleted!"
//Create a custom message
if (href_list["msg"])
if(LINKED_SERVER_NONRESPONSIVE)
message = noserver
else if(auth)
screen = 3
//Fake messaging selection - KEY REQUIRED
if (href_list["select"])
if(LINKED_SERVER_NONRESPONSIVE)
message = noserver
screen = 0
else
switch(href_list["select"])
//Reset
if("Reset")
ResetMessage()
//Select Your Name
if("Sender")
customsender = stripped_input(usr, "Please enter the sender's name.") || customsender
//Select Receiver
if("Recepient")
//Get out list of viable PDAs
var/list/obj/item/pda/sendPDAs = get_viewable_pdas()
if(GLOB.PDAs && GLOB.PDAs.len > 0)
customrecepient = input(usr, "Select a PDA from the list.") as null|anything in sortNames(sendPDAs)
else
customrecepient = null
//Enter custom job
if("RecJob")
customjob = stripped_input(usr, "Please enter the sender's job.") || customjob
//Enter message
if("Message")
custommessage = stripped_input(usr, "Please enter your message.") || custommessage
//Send message
if("Send")
if(isnull(customsender) || customsender == "")
customsender = "UNKNOWN"
if(isnull(customrecepient))
message = "NOTICE: No recepient selected!"
return attack_hand(usr)
if(isnull(custommessage) || custommessage == "")
message = "NOTICE: No message entered!"
return attack_hand(usr)
var/datum/signal/subspace/pda/signal = new(src, list(
"name" = "[customsender]",
"job" = "[customjob]",
"message" = custommessage,
"emoji_message" = emoji_parse(custommessage),
"targets" = list("[customrecepient.owner] ([customrecepient.ownjob])")
))
// this will log the signal and transmit it to the target
linkedServer.receive_information(signal, null)
usr.log_message("(PDA: [name]) sent \"[custommessage]\" to [signal.format_target()]", LOG_PDA)
//Request Console Logs - KEY REQUIRED
if(href_list["view_requests"])
if(LINKED_SERVER_NONRESPONSIVE)
message = noserver
else if(auth)
screen = 4
if (href_list["back"])
screen = 0
return attack_hand(usr)
#undef LINKED_SERVER_NONRESPONSIVE
/obj/item/paper/monitorkey
name = "monitor decryption key"
/obj/item/paper/monitorkey/Initialize(mapload, obj/machinery/telecomms/message_server/server)
..()
if (server)
print(server)
return INITIALIZE_HINT_NORMAL
else
return INITIALIZE_HINT_LATELOAD
/obj/item/paper/monitorkey/proc/print(obj/machinery/telecomms/message_server/server)
info = "Daily Key Reset
The new message monitor key is '[server.decryptkey]'.
Please keep this a secret and away from the clown.
If necessary, change the password to a more secure one."
info_links = info
add_overlay("paper_words")
/obj/item/paper/monitorkey/LateInitialize()
for (var/obj/machinery/telecomms/message_server/server in GLOB.telecomms_list)
if (server.decryptkey)
print(server)
break