@@ -1,24 +1,62 @@
// 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 "
desc = "Used to Monitor the crew's messages, that are sent via PDA. Can also be used to view Request Console messages. "
icon_state = "comm_logs "
var/hack_icon = "comm_logsc"
var/normal_icon = "comm_logs"
circuit = "/obj/item/weapon/circuitboard/message_monitor"
//Server linked to.
var/obj/machinery/message_server/linkedServer = null
var/screen = 0 // 0 = Main menu, 1 = Message Logs
//Sparks effect - For emag
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread
//Messages - Saves me time if I want to change something.
var/noserver = "<span class='alert'>ALERT: No server detected.</span>"
var/incorrectkey = "<span class='warning'>ALERT: Incorrect decryption key!</span>"
var/defaultmsg = "<span class='notice'>Welcome. Please select an option.</span>"
var/rebootmsg = "<span class='warning'>%$&(<28> : Critical %$$@ Error // !RestArting! <lOadiNg backUp iNput ouTput> - ?pLeaSe wAit!</span>"
//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 class='notice'>System bootup complete. Please select an option.</span>" // The message that shows on the main menu.
// Custom Message Properties
var/customsender = "System Administrator"
var/obj/item/device/pda/customrecepient = null
var/customjob = "Admin"
var/custommessage = "This is a test, please ignore."
/obj/machinery/computer/message_monitor/attackby(obj/item/weapon/O as obj, mob/user as mob)
if(stat & (NOPOWER|BROKEN))
return
if(!istype(user, /mob/living))
return
if(istype(O,/obj/item/weapon/card/emag/))
//Just brings up the Message Log without having to know the passcod e.
if(!hacking)
usr << "<span class='warning'>BZZT.. The console beeps and brings up the Message Logs.</span>"
screen = 1
else
usr << "<span class='notice'>It looks like the console is already being hacked into.</span>"
// Will create sparks and print out the console's password. You will then have to wait a while for the console to be back onlin e.
// It'll take more time if there's more characters in the password..
if(!emag)
icon_state = hack_icon // An error screen I made in the computers.dmi
emag = 1
screen = 2
spark_system.set_up(5, 0, src)
src.spark_system.start()
var/obj/item/weapon/paper/monitorkey/MK = new/obj/item/weapon/paper/monitorkey
MK.loc = src.loc
// Will help make emagging the console not so easy to get away with.
MK.info += "<br><br><font color='red'><3E> %@%(*$%&(<28> &?*(%&<26> /{}</font>"
spawn(100*length(src.linkedServer.decryptkey)) UnmagConsole()
message = rebootmsg
if(isscrewdriver(O) && emag)
//Stops people from just unscrewing the monitor and putting it back to get the console working again.
user << "<span class='warning'>It is too hot to mess with!</span>"
return
..()
return
@@ -34,33 +72,42 @@
return
if(!istype(user, /mob/living))
return
//If the computer is being hacked or is emagged, display the reboot message.
if(hacking || emag)
message = rebootmsg
var/dat = "<head><title>Message Monitor Console</title></head><body>"
dat += "<center><h2>Message Monitor Console</h2></center><hr>"
dat += "<center><h4><font color='blue'[message]</h5></center>"
switch(screen)
//Main menu
if(0)
if(hacking)
if(hacking || emag )
screen = 2
return src.attack_hand(user)
//	 = TAB
if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN)))
dat += "1. ERROR: Server not found<br >"
dat += "<dd><A>	 ERROR: Server not found</A><br></dd >"
else
dat += "<A href='?src=\ref[src];active=1'>1. Toggle Power: [src.linkedServer.active ? "<font color='green'>\[On\]</font>":"<font color='red'>\[Off\]</font>"]</a><br>"
dat += "<A href='?src=\ref[src];find=1'>2. Link To A Server</a><br >"
dat += "<A href='?src=\ref[src];clear=1'>3. Clear Message Logs</a ><hr>"
dat += "<font color='red'> KEY REQUIRED</font><br >"
dat += "<A href='?src=\ref[src];view=1'>4. View Messag e Logs </a><br>"
dat += "<A href='?src=\ref[src];pass=1'>5. Set Custom Key </a><h r><br >"
dat += "<dd>< A href='?src=\ref[src];active=1'>	 1. Toggle Power: [src.linkedServer.active ? "<font color='green'>\[On\]</font>":"<font color='red'>\[Off\]</font>"]</a><br></dd> "
dat += "<dd>< A href='?src=\ref[src];find=1'>	 2. Link To A Server</a><hr></dd >"
dat += "<dd><font color='red'> KEY REQUIRED</font></dd ><hr>"
dat += "<dd><A href='?src=\ref[src];view=1'>	3. View Message Logs </a><br></dd >"
dat += "<dd>< A href='?src=\ref[src];viewr =1'>	 4. View Request Consol e Logs </a></ br></dd> "
dat += "<dd>< A href='?src=\ref[src];clear=1'>	5. Clear Message Logs </a><b r></dd >"
dat += "<dd><A href='?src=\ref[src];clearr=1'>	6. Clear Request Console Logs</a><br></dd>"
dat += "<dd><A href='?src=\ref[src];pass=1'>	7. Set Custom Key</a><br></dd>"
dat += "<dd><A href='?src=\ref[src];msg=1'>	8. Send Admin Message</a><hr><br></dd>"
//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 += "<A href='?src=\ref[src];hack=1'><i><font color='Red'>*&@. Bruteforce Key</font></i></font></a><br>"
dat += "<dd>< A href='?src=\ref[src];hack=1'><i><font color='Red'>*&@# . Bruteforce Key</font></i></font></a><br></dd> "
//Message Logs
if(1)
if(hacking)
if(hacking || emag )
screen = 2
return src.attack_hand(user)
if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN)))
usr << "<span class='notice'>No server detected.</span>"
message = noserver
screen = 0
return src.attack_hand(user)
@@ -68,50 +115,120 @@
//var/recipient = "Unspecified" //name of the person
//var/sender = "Unspecified" //name of the sender
//var/message = "Blank" //transferred message
dat += "<center><A href='?src=\ref[src];back=1'>Return </a> - <A href='?src=\ref[src];refresh=1'>Refresh</center><hr>"
dat += "<table border='1' width='100%'><tr><th width='20 %'>Sender</th><th width='20 %'>Recipient</th><th width='300px' word-wrap: break-word>Message</th></tr>"
for(var/list/ datum/data_pda_msg/pda in src.linkedServer.pda_msgs)
dat += "<center><A href='?src=\ref[src];back=1'>Back </a> - <A href='?src=\ref[src];refresh=1'>Refresh</center><hr>"
dat += "<table border='1' width='100%'><tr><th width = '5%'>X</th><th width='15 %'>Sender</th><th width='15 %'>Recipient</th><th width='300px' word-wrap: break-word>Message</th></tr>"
for(var/datum/data_pda_msg/pda in src.linkedServer.pda_msgs)
index++
if(index > 3000)
break
dat += "<tr><td width='20%'>[pda.sender]</td><td width='20%'>[pda.r eci pient]</td><td width='80%'>[pda.message]</td></tr>"
// Del - Sender - R ece pient - Message
// X - Al Green - Your Mom - WHAT UP!?
dat += "<tr><td width = '5%'><center><A href='?src=\ref[src];delete=\ref[pda]' style='color: rgb(255,0,0)'>X</a></center></td><td width='15%'>[pda.sender]</td><td width='15%'>[pda.recipient]</td><td width='300px'>[pda.message]</td></tr>"
dat += "</table>"
//Hacking screen.
if(2)
if(!hacking)
if(!hacking && !emag )
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.<br> This will take anywhere from two to five minute s."
dat += "Brute-forcing for server key.<br> It will take 20 seconds for every character that the password ha s."
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 += {"0101 01000 110 10000110 100 101110011001000000111011101 1010010110110
0 0110110000100000 011101 000110000 10110101 101100 1010010000 0011000 0101101110
0111 1001011101110110100 00110010 101110010 01100101 00100000011001100 111 001001
10111101101101001000000 111 010 00111 0111 01101111 001000000111 01000 1101111 0010
00000110 01100 11010010111011 0011 00101 0010000 0011 0110 1011010010110111 0011101
0 10111 010001100 1010111 00110010111000 10000001 001 0010 110111 000100 00001110100
01101000 011001010010000001101101 01100101 011000010110111000101101 0111010001
101001 011011010 1100 10100 1011000010000001 1101000110100 0011010010111 00110010
000001100 0110 1101111 01101110011100110110111 1011011000 110010100100000011000
11011000010110 1110001000000111 0010 011001010111011 0011001 0101100 001011011 00
001000000 1111 001 011011110111 010101110010001000000111010001110 0100111010101
1 0010 1001 000000 11010010110111 00111010001100 10101101 1100111 010001 101 0010110
1111011011100111001100 100000 0110 100101100110001000000 111100 101101111011101
01001000000 11011000110010101 1101000010 000001110011011 011110110110101100101
0110111101101110 01100 101 001000000110000 1011 00011011 00011 01100101011 1001101
11 001100100000 011010 010111 010000101110001000000 100110 1011 00001011 010110110
01010010000001110011011101010111 001 001100 101001000000 110111 0011 01111 001000
0 001101 00001110101 011011010 110000 1011011100111001100 1000000110010 10110111 0
0111010 001100101011100100 01000000111 01 0001101000011 00 101001000000111001001
1 0111 101101 111011011 0100100000 011001 00011 1010 10111 001 0011 01 0010110 11100110
0 111001000000 11101000 11010000110000 10111 010000 100000011101000110 1001011011
0 10110010100101110"}
dat += {"01000 0100111001 0011101010111010001100 1010010110<br>
1 01100 11001101111 0111001 00110001 10110100 10110111 00110011<br>
100100000011 0011001101111 0111 0010001000000111 00110110010<br>
10111001001 11011 00110010 101110010 00100000011010110110010<br>
1 0111100 1001011100010 000 001001 001011101000010000 00111011<br>
10110100101 10110001101 100001 0000001110100011 000010 110101<br>
1 0110010100100000001100100 011000000100000 011100 110110010<br>
1011 00011011011110110111 001100 1000111 001100 10000 00110011<br>
0011 0111101110 010001000000110010 10111 0110011001010111001<br>
001 1110010 0100000011000110110100 0011000 010111 00100 110000<br>
10 110001101110 1000 110 01010111001000100000011101000110100<br>
00110000101 1101000010000 001110100011010000 11001010010000<br>
00111000001 100001 01110011 0111 001101 110 111011011110111001<br>
001 100100001000000 1101000011 00001 011100110010 11100010000<br>
001001001 011011 100010000001110100011010000110010100 10000<br>
0011011 0101100101011 00001011011 1001110100011 010010110110<br>
10110 01010010110000100 0000111010001 101 000011010010111001<br>
1 00100 00001100 0110110111101101110011100110110111 10110110<br>
0011001010010000001100011011 0000101 10111 000 1000000111001<br>
0 01100 1010 1110110011 00101 01100001011011000010000001 11100<br>
10 1101 1110111010101 110 01000100000011101000111001001 11010<br>
10110010100100000011010010110111001110100011001010110111<br>
00111010001101001011011110110111001110011001000000110100<br>
10110011000100000011110010110111101110101001000000110110<br>
00110010101110100001000000111001101101111011011010110010<br>
10110111101101110011001010010000001100001011000110110001<br>
10110010101110011011100110010000001101001011101000010111<br>
00010000001001101011000010110101101100101001000000111001<br>
10111010101110010011001010010000001101110011011110010000<br>
00110100001110101011011010110000101101110011100110010000<br>
00110010101101110011101000110010101110010001000000111010<br>
00110100001100101001000000111001001101111011011110110110<br>
10010000001100100011101010111001001101001011011100110011<br>
10010000001110100011010000110000101110100001000000111010<br>
001101001011011010110010100101110"}
//Fake messages
if(3)
if(hacking || emag)
screen = 2
return src.attack_hand(user)
dat += "<center><A href='?src=\ref[src];back=1'>Back</a> - <A href='?src=\ref[src];Reset=1'>Reset</a></center><hr>"
dat += {"<table border='1' width='100%'>
<tr><td width='20%'><A href='?src=\ref[src];select=Sender'>Sender</a></td>
<td width='20%'><A href='?src=\ref[src];select=Recepient'>Recipient</a></td>
<td width='20%'><A href='?src=\ref[src];select=RecJob'>Recepient Job</a></td>
<td width='300px' word-wrap: break-word><A href='?src=\ref[src];select=Message'>Message</a></td></tr>"}
//Sender - Recepient - Message
//Al Green - Your Mom - WHAT UP!?
dat += {"<tr><td width='20%'>[customsender]</td>
<td width='20%'>[customrecepient ? customrecepient.owner : "NONE"]</td>
<td width='20%'>[customjob]</td>
<td width='300px'>[custommessage]</td></tr>"}
dat += "</table><br><center><A href='?src=\ref[src];select=Send'>Send</a>"
//Request Console Logs
if(4)
if(hacking || emag)
screen = 2
return src.attack_hand(user)
if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN)))
message = noserver
screen = 0
return src.attack_hand(user)
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 += "<center><A href='?src=\ref[src];back=1'>Back</a> - <A href='?src=\ref[src];refresh=1'>Refresh</center><hr>"
dat += {"<table border='1' width='100%'><tr><th width = '5%'>X</th><th width='15%'>Sending Dep.</th><th width='15%'>Receiving Dep.</th>
<th width='300px' word-wrap: break-word>Message</th><th width='15%'>Stamp</th><th width='15%'>ID Auth.</th><th width='15%'>Priority.</th></tr>"}
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 += {"<tr><td width = '5%'><center><A href='?src=\ref[src];deleter=\ref[rc]' style='color: rgb(255,0,0)'>X</a></center></td><td width='15%'>[rc.send_dpt]</td>
<td width='15%'>[rc.rec_dpt]</td><td width='300px'>[rc.message]</td><td width='15%'>[rc.stamp]</td><td width='15%'>[rc.id_auth]</td><td width='15%'>[rc.priority]</td></tr>"}
dat += "</table>"
dat += "</body>"
user << browse(dat, "window=message;size=500x700")
message = defaultmsg
user << browse(dat, "window=message;size=700x700")
onclose(user, "message")
return
@@ -122,8 +239,19 @@
var/currentKey = src.linkedServer.decryptkey
user << "<span class='warning'>Brute-force completed! The key is '[currentKey]'.</span>"
src.hacking = 0
src.icon_state = normal_icon
src.screen = 0 // Return the screen back to normal
/obj/machinery/computer/message_monitor/proc/UnmagConsole()
src.icon_state = normal_icon
src.emag = 0
/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
@@ -132,62 +260,210 @@
if(!istype(usr, /mob/living))
return
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
//Turn the server on/off.
if (href_list["active"])
linkedServer.active = !linkedServer.active
//Find a server
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.</span>"
message = "<span class='alert'>NOTICE: Server selected.</span>"
else if(message_servers && message_servers.len > 0)
linkedServer = message_servers[1]
usr << "<span class='notice'>Single Server Detected - Server selected.</span>"
message = "<span class='notice'>NOTICE: Only Single Server Detected - Server selected.</span>"
else
usr << "<span class='notice'>No server detected.</span>"
message = noserver
//View the logs - KEY REQUIRED
if (href_list["view"])
if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
usr << "<span class='notice'>No server detected.</span>"
message = noserver
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 << "<span class='warning'>ALERT: Incorrect password!</span>"
message = incorrectkey
//Clears the logs - KEY REQUIRED
if (href_list["clear"])
if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
usr << "<span class='notice'>No server detected.</span>"
else
src.linkedServer.pda_msgs = list()
usr << "<span class='notice'>Logs cleared.</span>"
if (href_list["pass"])
if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
usr << "<span class='notice'>No server detected.</span>"
message = noserver
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 << "<span class='notice'>Password set.</span>"
if(src.linkedServer.decryptkey == dkey )
src.linkedServer.pda_msgs = list( )
message = "<span class='notice'>NOTICE: Logs cleared.</span>"
else
usr << "<span class='warning'>ALERT: Incorrect password!</span>"
message = incorrectkey
//Clears the request console logs - KEY REQUIRED
if (href_list["clearr"])
if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
message = noserver
else
var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null)
if(dkey && dkey != "")
if(src.linkedServer.decryptkey == dkey)
src.linkedServer.rc_msgs = list()
message = "<span class='notice'>NOTICE: Logs cleared.</span>"
else
message = incorrectkey
//Change the password - KEY REQUIRED
if (href_list["pass"])
if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN)))
message = noserver
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 (3 - 16 characters max):"))
if(length(newkey) <= 3)
message = "<span class='notice'>NOTICE: Decryption key too short!</span>"
else if(length(newkey) > 16)
message = "<span class='notice'>NOTICE: Decryption key too long!</span>"
else if(newkey && newkey != "")
src.linkedServer.decryptkey = newkey
message = "<span class='notice'>NOTICE: Decryption key set.</span>"
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
//usr << "[src.linkedServer.decryptkey]"
spawn((100*6)*rand(2, 4))
src.icon_state = hack_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 class='notice'>NOTICE: Log Deleted!</span>"
//Delete the request 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 class='notice'>NOTICE: Log Deleted!</span>"
//Create a custom message
if (href_list["msg"])
if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
message = noserver
else
var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null)
if(dkey && dkey != "")
if(src.linkedServer.decryptkey == dkey)
src.screen = 3
else
message = incorrectkey
//Fake messaging selection - KEY REQUIRED
if (href_list["select"])
if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
message = noserver
screen = 0
else
switch(href_list["select"])
//Reset
if("Reset")
ResetMessage()
//Select Your Name
if("Sender")
customsender = input(usr, "Please enter the sender's name.") as text|null
//Select Receiver
if("Recepient")
//Get out list of viable PDAs
if(PDAs && PDAs.len > 0)
customrecepient = input(usr, "Select a PDA from the list.") as null|anything in PDAs
else
customrecepient = null
//Enter custom job
if("RecJob")
customjob = input(usr, "Please enter the sender's job.") as text|null
//Enter message
if("Message")
custommessage = input(usr, "Please enter your message.") as text|null
custommessage = copytext(sanitize(custommessage), 1, MAX_MESSAGE_LEN)
//Send message
if("Send")
if(isnull(customsender) || customsender == "")
customsender = "UNKNOWN"
if(isnull(customrecepient))
message = "<span class='notice'>NOTICE: No recepient selected!</span>"
return src.attack_hand(usr)
if(isnull(custommessage) || custommessage == "")
message = "<span class='notice'>NOTICE: No message entered!</span>"
return src.attack_hand(usr)
var/obj/item/device/pda/PDARec = null
for (var/obj/item/device/pda/P in PDAs)
if (!P.owner||P.toff) continue
if(P.owner == customsender)
PDARec = P
//Sender isn't faking as someone who exists
if(isnull(PDARec))
src.linkedServer.send_pda_message("[customrecepient.owner]", "[customsender]","[custommessage]")
customrecepient.tnote += "<i><b>← From <a href='byond://?src=\ref[customrecepient];choice=Message;target=\ref[src]'>[customsender]</a> ([customjob]):</b></i><br>[custommessage]<br>"
if (!customrecepient.silent)
playsound(customrecepient.loc, 'twobeep.ogg', 50, 1)
for (var/mob/O in hearers(3, customrecepient.loc))
O.show_message(text("\icon[customrecepient] *[customrecepient.ttone]*"))
if( customrecepient.loc && ishuman(customrecepient.loc) )
var/mob/living/carbon/human/H = customrecepient.loc
H << "\icon[customrecepient] <b>Message from [customsender] ([customjob]), </b>\"[custommessage]\" (<a href='byond://?src=\ref[src];choice=Message;skiprefresh=1;target=\ref[src]'>Reply</a>)"
log_pda("[usr] (PDA: [customsender]) sent \"[custommessage]\" to [customrecepient.owner]")
customrecepient.overlays = null
customrecepient.overlays += image('pda.dmi', "pda-r")
//Sender is faking as someone who exists
else
src.linkedServer.send_pda_message("[customrecepient.owner]", "[PDARec.owner]","[custommessage]")
customrecepient.tnote += "<i><b>← From <a href='byond://?src=\ref[customrecepient];choice=Message;target=\ref[PDARec]'>[PDARec.owner]</a> ([customjob]):</b></i><br>[custommessage]<br>"
if (!customrecepient.silent)
playsound(customrecepient.loc, 'twobeep.ogg', 50, 1)
for (var/mob/O in hearers(3, customrecepient.loc))
O.show_message(text("\icon[customrecepient] *[customrecepient.ttone]*"))
if( customrecepient.loc && ishuman(customrecepient.loc) )
var/mob/living/carbon/human/H = customrecepient.loc
H << "\icon[customrecepient] <b>Message from [PDARec.owner] ([customjob]), </b>\"[custommessage]\" (<a href='byond://?src=\ref[customrecepient];choice=Message;skiprefresh=1;target=\ref[PDARec]'>Reply</a>)"
log_pda("[usr] (PDA: [PDARec.owner]) sent \"[custommessage]\" to [customrecepient.owner]")
customrecepient.overlays = null
customrecepient.overlays += image('pda.dmi', "pda-r")
//Finally..
ResetMessage()
//Request Console Logs - KEY REQUIRED
if(href_list["viewr"])
if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN)))
message = noserver
else
var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null)
if(dkey && dkey != "")
if(src.linkedServer.decryptkey == dkey)
src.screen = 4
else
message = incorrectkey
//usr << href_list["select"]
if (href_list["back"])
src.screen = 0