diff --git a/baystation12.dme b/baystation12.dme index 708ae6033c4..12b3af529ec 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -555,6 +555,7 @@ #include "code\game\machinery\computer\law.dm" #include "code\game\machinery\computer\lockdown.dm" #include "code\game\machinery\computer\medical.dm" +#include "code\game\machinery\computer\message.dm" #include "code\game\machinery\computer\Operating.dm" #include "code\game\machinery\computer\pod.dm" #include "code\game\machinery\computer\power.dm" diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index d990db18830..fd5ca96bb40 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -29,6 +29,10 @@ var/frame_desc = null var/contain_parts = 1 +/obj/item/weapon/circuitboard/message_monitor + name = "Circuit board (Message Monitor)" + build_path = "/obj/machinery/computer/message_monitor" + origin_tech = "programming=3" /obj/item/weapon/circuitboard/aicore name = "Circuit board (AI core)" origin_tech = "programming=4;biotech=2" diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm new file mode 100644 index 00000000000..7d826a7c2e1 --- /dev/null +++ b/code/game/machinery/computer/message.dm @@ -0,0 +1,209 @@ + +// Allows you to monitor messages that passes the server. + +/obj/machinery/computer/message_monitor + name = "Message Monitor Console" + desc = "Used to Monitor the crew's messages, that are sent via PDA." + icon_state = "comm_monitor" + circuit = "/obj/item/weapon/circuitboard/message_monitor" + var/obj/machinery/message_server/linkedServer = null + var/screen = 0 // 0 = Main menu, 1 = Message Logs + var/hacking = 0 // Is it being hacked into by the AI/Cyborg + + +/obj/machinery/computer/message_monitor/attackby(obj/item/weapon/O as obj, mob/user as mob) + if(istype(O,/obj/item/weapon/card/emag/)) + //Just brings up the Message Log without having to know the passcode. + if(!hacking) + usr << "BZZT.. The console beeps and brings up the Message Logs." + screen = 1 + else + usr << "It looks like the console is already being hacked into." + ..() + return + +/obj/machinery/computer/message_monitor/process() + //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) + if(message_servers && message_servers.len > 0) + linkedServer = message_servers[1] + return + +/obj/machinery/computer/message_monitor/attack_hand(var/mob/user as mob) + if(stat & (NOPOWER|BROKEN)) + return + if(!istype(user, /mob/living)) + return + var/dat = "Message Monitor Console" + dat += "

Message Monitor Console


" + switch(screen) + //Main menu + if(0) + if(hacking) + screen = 2 + return src.attack_hand(user) + if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN))) + dat += "1. ERROR: Server not found
" + else + dat += "1. Toggle Power: [src.linkedServer.active ? "\[On\]":"\[Off\]"]
" + dat += "2. Link To A Server
" + dat += "3. Clear Message Logs
" + dat += " KEY REQUIRED
" + dat += "4. View Message Logs
" + dat += "5. Set Custom Key

" + //Malf/Traitor AIs can bruteforce into the system to gain the Key. + if((istype(user, /mob/living/silicon/ai) || istype(user, /mob/living/silicon/robot)) && (user.mind.special_role && user.mind.original == user)) + dat += "*&@. Bruteforce Key
" + //Message Logs + if(1) + if(hacking) + screen = 2 + return src.attack_hand(user) + if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN))) + usr << "No server detected." + screen = 0 + return src.attack_hand(user) + + var/index = 0 + //var/recipient = "Unspecified" //name of the person + //var/sender = "Unspecified" //name of the sender + //var/message = "Blank" //transferred message + dat += "
Return - Refresh

" + dat += "" + for(var/list/datum/data_pda_msg/pda in src.linkedServer.pda_msgs) + index++ + if(index > 3000) + break + dat += "" + dat += "
SenderRecipientMessage
[pda.sender][pda.recipient][pda.message]
" + //Hacking screen. + if(2) + if(!hacking) + screen = 0 + return src.attack_hand(user) + if(istype(user, /mob/living/silicon/ai) || istype(user, /mob/living/silicon/robot)) + dat += "Brute-forcing for server key.
This will take anywhere from two to five minutes." + 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 += {"010101000110100001101001011100110010000001110111011010010110110 + 0011011000010000001110100011000010110101101100101001000000110000101101110 + 01111001011101110110100001100101011100100110010100100000011001100111001001 + 10111101101101001000000111010001110111011011110010000001110100011011110010 + 00000110011001101001011101100110010100100000011011010110100101101110011101 + 01011101000110010101110011001011100010000001001001011011100010000001110100 + 01101000011001010010000001101101011001010110000101101110001011010111010001 + 10100101101101011001010010110000100000011101000110100001101001011100110010 + 00000110001101101111011011100111001101101111011011000110010100100000011000 + 11011000010110111000100000011100100110010101110110011001010110000101101100 + 00100000011110010110111101110101011100100010000001110100011100100111010101 + 10010100100000011010010110111001110100011001010110111001110100011010010110 + 11110110111001110011001000000110100101100110001000000111100101101111011101 + 01001000000110110001100101011101000010000001110011011011110110110101100101 + 01101111011011100110010100100000011000010110001101100011011001010111001101 + 11001100100000011010010111010000101110001000000100110101100001011010110110 + 01010010000001110011011101010111001001100101001000000110111001101111001000 + 00011010000111010101101101011000010110111001110011001000000110010101101110 + 01110100011001010111001000100000011101000110100001100101001000000111001001 + 10111101101111011011010010000001100100011101010111001001101001011011100110 + 01110010000001110100011010000110000101110100001000000111010001101001011011 + 010110010100101110"} + + + dat += "" + user << browse(dat, "window=message;size=500x700") + onclose(user, "message") + return + +/obj/machinery/computer/message_monitor/attack_ai(mob/user as mob) + return src.attack_hand(user) + +/obj/machinery/computer/message_monitor/proc/BruteForce(mob/user as mob) + var/currentKey = src.linkedServer.decryptkey + user << "Brute-force completed! The key is '[currentKey]'." + src.hacking = 0 + src.screen = 0 // Return the screen back to normal + +/obj/machinery/computer/message_monitor/Topic(href, href_list) + if(..()) + return + if(stat & (NOPOWER|BROKEN)) + return + if(!istype(usr, /mob/living)) + return + if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) + + if (href_list["active"]) + linkedServer.active = !linkedServer.active + + if (href_list["find"]) + if(message_servers && message_servers.len > 1) + src.linkedServer = input(usr,"Please select a server.", "Select a server.", null) as null|anything in message_servers + usr << "Server selected." + else if(message_servers && message_servers.len > 0) + linkedServer = message_servers[1] + usr << "Single Server Detected - Server selected." + else + usr << "No server detected." + + if (href_list["view"]) + if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN))) + usr << "No server detected." + else + var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null) + if(dkey && dkey != "") + if(src.linkedServer.decryptkey == dkey) + src.screen = 1 + else + usr << "ALERT: Incorrect password!" + + + if (href_list["clear"]) + if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN))) + usr << "No server detected." + else + src.linkedServer.pda_msgs = list() + usr << "Logs cleared." + + if (href_list["pass"]) + if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN))) + usr << "No server detected." + else + var/dkey = trim(input(usr,"Please enter the decryption key.") as text|null) + if(dkey && dkey != "") + if(dkey == src.linkedServer.decryptkey) + var/newkey = trim(input(usr,"Please enter the new key.")) + if(newkey && newkey != "") + src.linkedServer.decryptkey = newkey + usr << "Password set." + else + usr << "ALERT: Incorrect 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 + //usr << "[src.linkedServer.decryptkey]" + spawn((100*6)*rand(2, 4)) + if(src && src.linkedServer && usr) + BruteForce(usr) + + + if (href_list["back"]) + src.screen = 0 + + return src.attack_hand(usr) + + +/obj/item/weapon/paper/monitorkey + //..() + name = "Monitor Decryption Key" + var/obj/machinery/message_server/server = null + +/obj/item/weapon/paper/monitorkey/New() + ..() + if(message_servers && message_servers.len > 0) + server = message_servers[1] + info = "

Daily Key Reset


The new message monitor key is '[server.decryptkey]'.
Please keep this a secret.
If necessary, change the password to a more secure one." +// info_links = info + overlays += "paper_words" \ No newline at end of file diff --git a/code/game/objects/devices/PDA/PDA.dm b/code/game/objects/devices/PDA/PDA.dm index 84194da1cee..6e6bce5da89 100755 --- a/code/game/objects/devices/PDA/PDA.dm +++ b/code/game/objects/devices/PDA/PDA.dm @@ -1076,17 +1076,28 @@ if (selected:toff) return + var/obj/machinery/message_server/useMS = null + if(!isnull(message_servers)) + for (var/obj/machinery/message_server/MS in message_servers) + //PDAs are now dependant on the Message Server. + if(MS.active) + useMS = MS + break + if(!isnull(useMS)) // only send the message if it's stable + useMS.send_pda_message("[selected:owner]","[usr.name]","[t]") - usr.show_message("PDA message to [selected:owner]: [t]") - selected:tnote += "← From (AI) [usr.name]:
[t]
" + usr.show_message("PDA message to [selected:owner]: [t]") + selected:tnote += "← From (AI) [usr.name]:
[t]
" - if (!selected:silent) - playsound(selected.loc, 'twobeep.ogg', 50, 1) - for (var/mob/O in hearers(3, selected.loc)) - O.show_message(text("\icon[selected] *[selected:ttone]*")) + if (!selected:silent) + playsound(selected.loc, 'twobeep.ogg', 50, 1) + for (var/mob/O in hearers(3, selected.loc)) + O.show_message(text("\icon[selected] *[selected:ttone]*")) - selected.overlays = null - selected.overlays += image('pda.dmi', "pda-r") + selected.overlays = null + selected.overlays += image('pda.dmi', "pda-r") + else + usr << "ERROR: Server isn't responding." //Some spare PDAs in a box diff --git a/code/modules/chemical/Chemistry-Reagents.dm b/code/modules/chemical/Chemistry-Reagents.dm index 57ded7df769..d86f77622fe 100644 --- a/code/modules/chemical/Chemistry-Reagents.dm +++ b/code/modules/chemical/Chemistry-Reagents.dm @@ -2717,6 +2717,20 @@ datum ..() return +/* reaction_obj(var/obj/O, var/volume) + if(istype(O,/obj/item/weapon/paper)) + var/obj/item/weapon/paper/paperaffected = O + paperaffected.clearpaper() + usr << "The solution melts away the ink on the paper." + if(istype(O,/obj/item/weapon/book)) + if(volume >= 5) + var/obj/item/weapon/book/affectedbook = O + affectedbook.dat = null + usr << "The solution melts away the ink on the book." + else + usr << "It wasn't enough..." + return +*/ beer //It's really much more stronger than other drinks. name = "Beer" id = "beer" diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 6592f15da72..d87c90c2319 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -136,6 +136,13 @@ addtofield(i, "
write", 1) info_links = info_links + "write" +/obj/item/weapon/paper/proc/clearpaper() + info = null + stamps = null + stamped = list() + overlays = null + updateinfolinks() + /obj/item/weapon/paper/proc/parsepencode(var/t, var/obj/item/weapon/pen/P, mob/user as mob, var/iscrayon = 0) t = copytext(sanitize(t),1,MAX_MESSAGE_LEN) @@ -183,6 +190,7 @@ return t + /obj/item/weapon/paper/proc/openhelp(mob/user as mob) user << browse({"Pen Help @@ -204,7 +212,6 @@ \[hr\] : Adds a horizontal rule. "}, "window=paper_help") - /obj/item/weapon/paper/Topic(href, href_list) ..() if ((usr.stat || usr.restrained())) diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index c5c50889465..056c0f21b9f 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -21,4 +21,14 @@ /obj/item/weapon/pen/red desc = "It's a normal red ink pen." icon_state = "pen_red" - colour = "red" \ No newline at end of file + colour = "red" + +/obj/item/weapon/pen/invisble + desc = "It's an invisble pen marker." + icon_state = "pen" + colour = "white" + +/obj/item/weapon/pen/invisble + desc = "It's an invisble pen marker." + icon_state = "pen" + colour = "white" \ No newline at end of file diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index e3cae5c9f63..7392bd3dfb6 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -396,6 +396,15 @@ datum materials = list("$glass" = 2000, "acid" = 20) build_path = "/obj/item/weapon/circuitboard/comm_server" + message_monitor + name = "Circuit Design (Messaging Monitor Console)" + desc = "Allows for the construction of circuit boards used to build a messaging monitor console." + id = "message_monitor" + req_tech = list("programming" = 5) + build_type = IMPRINTER + materials = list("$glass" = 2000, "acid" = 20) + build_path = "/obj/item/weapon/circuitboard/message_monitor" + /////////////////////////////////// //////////AI Module Disks////////// ///////////////////////////////////