mirror of
https://github.com/goonstation/goonstation-2016.git
synced 2026-05-18 14:39:01 +01:00
dc4217b498
this is all very alpha please don't hate me too much if i fucked it up
1366 lines
41 KiB
Plaintext
1366 lines
41 KiB
Plaintext
//Small programs not worthy of their own file
|
|
//CONTENTS
|
|
//Background program base
|
|
//Signal interceptor program
|
|
//Ping program
|
|
//Terminal client / File transfer program
|
|
//Signal file creator/editor
|
|
//Disease research program
|
|
//Artifact research program
|
|
//Crew manifest program
|
|
//Robotics research.
|
|
|
|
#define MAX_BACKGROUND_PROGS 7//If staying resident would leave us with more than this, don't do it.
|
|
|
|
//A program designed to remain processing while the user executes more interesting programs
|
|
/datum/computer/file/terminal_program/background
|
|
name = "Background"
|
|
size = 4
|
|
|
|
|
|
//It's like having the master unload it, but it remains processing.
|
|
proc/exit_stay_resident()
|
|
if((!src.holder) || (!src.master))
|
|
return 1
|
|
|
|
if((!istype(holder)) || (!istype(master)))
|
|
return 1
|
|
|
|
if(!(holder in src.master.contents))
|
|
if(master.active_program == src)
|
|
master.active_program = null
|
|
master.processing_programs.Remove(src)
|
|
return 1
|
|
|
|
if(src.master.processing_programs.len > MAX_BACKGROUND_PROGS) //Don't want too many background programs.
|
|
return 1
|
|
|
|
if(!(src in src.master.processing_programs))
|
|
src.master.processing_programs.Add(src)
|
|
|
|
src.master.active_program = src.master.host_program
|
|
|
|
return 0
|
|
|
|
//Signal interception program
|
|
/datum/computer/file/terminal_program/background/signal_catcher
|
|
name = "SigCatcher"
|
|
var/active = 1 //Are we currently catching signals?
|
|
var/logging = 0
|
|
var/list/working_signal = list()
|
|
var/last_command = null
|
|
var/datum/computer/file/text/logfile = null
|
|
|
|
var/const/max_working_signal_len = 8
|
|
var/const/logfile_path = "signal_log"
|
|
|
|
initialize()
|
|
src.print_text("Signal Catcher 1.2<br>Commands: \"active \[ON/OFF/AUTO],\" \"Save \[filename]\" as signal, \"View\" current signal.<br>\"Quit\" to exit but remain in memory, \"FQuit\" to quit normally.")
|
|
|
|
disposing()
|
|
working_signal = null
|
|
logfile = null
|
|
|
|
..()
|
|
|
|
input_text(text)
|
|
if(..())
|
|
return
|
|
|
|
var/list/command_list = parse_string(text)
|
|
var/command = command_list[1]
|
|
command_list -= command_list[1]
|
|
|
|
src.print_text(strip_html(text))
|
|
|
|
switch(lowertext(command))
|
|
if("active") //Determine whether we are catching incoming signals or not
|
|
var/argument1 = null
|
|
if(command_list.len)
|
|
argument1 = command_list[1]
|
|
|
|
switch(lowertext(argument1))
|
|
if("on")
|
|
src.active = 1
|
|
|
|
if("off")
|
|
src.active = 0
|
|
|
|
if("auto")
|
|
src.active = 2
|
|
|
|
else
|
|
src.active = !src.active
|
|
|
|
src.print_text("Signal Catching is now [src.active ? "ON" : "OFF"]")
|
|
|
|
if("log") //Determine whether we should log incoming signals.
|
|
var/argument1 = null
|
|
if(command_list.len)
|
|
argument1 = command_list[1]
|
|
|
|
switch(lowertext(argument1))
|
|
if("on")
|
|
src.logging = 1
|
|
|
|
if("off")
|
|
src.logging = 0
|
|
|
|
else
|
|
src.logging = !logging
|
|
|
|
src.print_text("Signal Logging is now [src.logging ? "ON" : "OFF"]")
|
|
|
|
|
|
if("view")
|
|
if(!src.working_signal || !src.working_signal.len)
|
|
src.print_text("Error, no signal loaded.")
|
|
return
|
|
else
|
|
src.print_text("Current signal:<br>Last Command: [last_command ? last_command : "None"]")
|
|
for(var/x = 1, x <= src.working_signal.len, x++)
|
|
var/part = "\[UNUSED]"
|
|
if(x <= working_signal.len)
|
|
var/title_text = working_signal[x]
|
|
var/main_text = working_signal[title_text]
|
|
part = " \[[isnull(title_text) ? "Untitled" : title_text]] \[[isnull(main_text) ? "Blank" : copytext(strip_html(main_text), 1, 25)]]"
|
|
|
|
src.print_text("\[[x]] [part]")
|
|
|
|
if("save")
|
|
var/new_name = strip_html(jointext(command_list, " "))
|
|
new_name = copytext(new_name, 1, 16)
|
|
|
|
if(!new_name)
|
|
src.print_text("Syntax: \"save \[file name]\"")
|
|
return
|
|
|
|
var/datum/computer/file/signal/saved = get_file_name(new_name, src.holding_folder)
|
|
if(saved && !istype(saved) || get_folder_name(new_name, src.holding_folder))
|
|
src.print_text("Error: Name in use.")
|
|
return
|
|
|
|
if(is_name_invalid(new_name))
|
|
src.print_text("Error: Invalid character in name.")
|
|
return
|
|
|
|
if(saved && istype(saved))
|
|
saved.data = src.working_signal.Copy()
|
|
else
|
|
saved = new /datum/computer/file/signal
|
|
saved.name = new_name
|
|
saved.data = src.working_signal.Copy()
|
|
if(!src.holding_folder.add_file(saved))
|
|
//qdel(saved)
|
|
saved.dispose()
|
|
src.print_text("Error: Cannot save to disk.")
|
|
return
|
|
|
|
src.print_text("Signal \"[new_name]\" saved.")
|
|
|
|
if("help")
|
|
src.print_text("Commands: \"active \[ON/OFF],\" \"Save \[filename]\" as signal, \"View\" current signal.<br>\"Quit\" to exit but remain in memory, \"FQuit\" to quit normally.")
|
|
|
|
if("quit")
|
|
src.print_text("Now returning to OS. Program will remain in background.")
|
|
if(src.exit_stay_resident())
|
|
src.print_text("Error: Background Memory full.")
|
|
|
|
src.master.unload_program(src)
|
|
return
|
|
|
|
if("fquit")
|
|
src.print_text("Now Fully Quitting...")
|
|
src.master.unload_program(src)
|
|
return
|
|
|
|
else
|
|
src.print_text("Unknown Command.")
|
|
|
|
src.master.add_fingerprint(usr)
|
|
src.master.updateUsrDialog()
|
|
return
|
|
|
|
receive_command(obj/source, command, datum/signal/signal)
|
|
if((..()) || (!signal) || !src.active)
|
|
return
|
|
|
|
//Auto mode means shutoff after next signal
|
|
if(src.active == 2) src.active = 0
|
|
|
|
src.working_signal = signal.data:Copy()
|
|
src.working_signal.len = min(src.working_signal.len, max_working_signal_len)
|
|
src.last_command = command
|
|
if(src.logging && !src.holder.read_only)
|
|
if(!src.logfile)
|
|
src.logfile = parse_file_directory(src.logfile_path)
|
|
if(!istype(src.logfile))
|
|
src.logfile = new /datum/computer/file/text
|
|
src.logfile.name = src.logfile_path
|
|
if(!src.holding_folder.add_file(src.logfile))
|
|
//qdel(src.logfile)
|
|
src.logfile.dispose()
|
|
return
|
|
|
|
src.logfile.data += "<br>"
|
|
for(var/i = 1, i <= src.working_signal.len, i++)
|
|
src.logfile.data += "<br>[src.working_signal[i]]: [src.working_signal[src.working_signal[i]]]"
|
|
|
|
return
|
|
|
|
//Pnet ping program.
|
|
/datum/computer/file/terminal_program/background/ping
|
|
name = "Ping"
|
|
var/active = 1
|
|
var/list/replies = list() //Replies to our ping request.
|
|
var/obj/item/peripheral/network/ping_card = null //The card we are actually going to use to send pings.
|
|
|
|
initialize()
|
|
src.ping_card = null
|
|
src.print_text("Ping! V4.92<br>Commands: \"Ping\" to ping network. \"View\" to view prevous ping data.<br>\"Quit\" to exit but remain in memory, \"FQuit\" to quit normally.")
|
|
|
|
src.ping_card = find_peripheral("NET_ADAPTER")
|
|
if(!src.ping_card || !istype(src.ping_card))
|
|
src.ping_card = null
|
|
src.print_text("Error:No network card detected.")
|
|
|
|
return
|
|
|
|
disposing()
|
|
ping_card = null
|
|
replies = null
|
|
|
|
..()
|
|
|
|
input_text(text)
|
|
if(..())
|
|
return
|
|
|
|
var/list/command_list = parse_string(text)
|
|
var/command = command_list[1]
|
|
command_list -= command_list[1]
|
|
|
|
src.print_text(strip_html(text))
|
|
|
|
switch(lowertext(command))
|
|
if("ping")
|
|
if(!src.ping_card)
|
|
src.print_text("Error: Network card required.")
|
|
return
|
|
|
|
var/datum/signal/newsignal = get_free_signal()
|
|
newsignal.encryption = "\ref[src.ping_card]" //No need to actually set data on it
|
|
//The signal is really only needed to target our ping card for the job.
|
|
|
|
src.print_text("Pinging...")
|
|
src.replies = new
|
|
src.peripheral_command("ping", null, "\ref[src.ping_card]")
|
|
|
|
if("view")
|
|
if(!src.replies || !src.replies.len)
|
|
src.print_text("Error, no reply data found.")
|
|
return
|
|
else
|
|
src.print_text("Reply List:")
|
|
var/part = null
|
|
for(var/x = 1, x <= src.replies.len, x++)
|
|
var/reply_id = replies[x]
|
|
var/reply_device = replies[reply_id]
|
|
part += " \[[isnull(reply_id) ? "ERR: ID" : reply_id]]-TYPE: [isnull(reply_device) ? "ERR: DEVICE" : reply_device]<br>"
|
|
|
|
if(part)
|
|
src.print_text(part)
|
|
|
|
|
|
if("help")
|
|
src.print_text("Commands: \"Ping\" to ping network. \"View\" to view prevous ping data.<br>\"Quit\" to exit but remain in memory, \"FQuit\" to quit normally.")
|
|
|
|
if("quit")
|
|
src.print_text("Now returning to OS. Program will remain in background.")
|
|
if(src.exit_stay_resident())
|
|
src.print_text("Error: Background Memory full.")
|
|
|
|
src.master.unload_program(src)
|
|
return
|
|
|
|
if("fquit")
|
|
src.print_text("Now Fully Quitting...")
|
|
src.master.unload_program(src)
|
|
return
|
|
|
|
else
|
|
src.print_text("Unknown Command.")
|
|
|
|
src.master.add_fingerprint(usr)
|
|
src.master.updateUsrDialog()
|
|
return
|
|
|
|
receive_command(obj/source, command, datum/signal/signal)
|
|
if((..()) || (!signal) || !src.active)
|
|
return
|
|
|
|
//If we get a ping reply, add it to the list and print it.
|
|
if(signal.data["command"] == "ping_reply")
|
|
if(!signal.data["device"] || !signal.data["netid"])
|
|
return
|
|
|
|
var/reply_device = signal.data["device"]
|
|
var/reply_id = signal.data["netid"]
|
|
//boutput(world, "device: [reply_device] id: [reply_id]")
|
|
src.replies[reply_id] = reply_device
|
|
src.print_text("\[[reply_id]]-TYPE: [reply_device]")
|
|
|
|
return
|
|
|
|
//Pnet file transfer program.
|
|
/datum/computer/file/terminal_program/file_transfer
|
|
name = "FROG"
|
|
var/tmp/serv_id = null //NetID of connected server
|
|
var/tmp/last_serv_id = null //Last valid serv_id.
|
|
var/tmp/attempt_id = null //Are we attempting to connect to something?
|
|
var/obj/item/peripheral/network/pnet_card = null
|
|
var/tmp/disconnect_wait = -1 //Are we waiting to disconnect?
|
|
var/tmp/ping_wait = 0 //Are we waiting for a ping reply?
|
|
var/auto_accept = 1 //Do we automatically accept connection attempts?
|
|
var/tmp/service_mode = 0
|
|
|
|
var/tmp/datum/computer/file/temp_file
|
|
|
|
var/setup_acc_filepath = "/logs/sysusr"//Where do we look for login data?
|
|
|
|
initialize()
|
|
attempt_id = null
|
|
src.pnet_card = null
|
|
var/introdat = "FROG Terminal Client V1.3<br>Copyright 2053 Thinktronic Systems, LTD."
|
|
|
|
src.pnet_card = find_peripheral("NET_ADAPTER")
|
|
if (!src.pnet_card || !istype(src.pnet_card))
|
|
src.pnet_card = find_peripheral("RAD_ADAPTER")
|
|
if (istype(src.pnet_card))
|
|
src.peripheral_command("mode_net", null, "\ref[pnet_card]")
|
|
introdat += "<br>Network card detected."
|
|
else
|
|
if (src.serv_id)
|
|
src.serv_id = null
|
|
|
|
src.ping_wait = 0
|
|
src.disconnect_wait = 0
|
|
src.serv_id = null
|
|
|
|
src.pnet_card = null
|
|
introdat += "<br>Error: No network card detected."
|
|
|
|
if (src.pnet_card)
|
|
introdat += "<br>Network ID: [pnet_card.net_id]"
|
|
|
|
if (src.serv_id) //We have been rebooted or force-closed OR SOMETHING, so disconnect.
|
|
var/datum/signal/termsignal = get_free_signal()
|
|
|
|
termsignal.data["address_1"] = src.serv_id
|
|
termsignal.data["command"] = "term_disconnect"
|
|
|
|
src.peripheral_command("transmit", termsignal, "\ref[pnet_card]")
|
|
|
|
src.ping_wait = 0
|
|
src.disconnect_wait = 0
|
|
src.serv_id = null
|
|
|
|
src.print_text(introdat + "<br>Ready.")
|
|
|
|
return
|
|
|
|
process()
|
|
if(..())
|
|
return
|
|
|
|
if(src.ping_wait)
|
|
src.ping_wait--
|
|
|
|
if(src.disconnect_wait > 0)
|
|
src.disconnect_wait--
|
|
if(src.disconnect_wait == 0)
|
|
src.print_text("Timed out. Please retry.")
|
|
src.serv_id = null
|
|
src.attempt_id = null
|
|
|
|
input_text(text)
|
|
if(..())
|
|
return
|
|
|
|
var/list/command_list = parse_string(text)
|
|
var/command = lowertext(command_list[1])
|
|
command_list -= command_list[1]
|
|
|
|
src.print_text(">[strip_html(text)]")
|
|
|
|
if(disconnect_wait > 0)
|
|
src.print_text("Alert: System busy, please hold.")
|
|
return
|
|
|
|
if(command == "help" && !src.serv_id)
|
|
var/help_message = {"Terminal Commands:<br>
|
|
term_status - View current status of terminal.<br>
|
|
term_accept - Toggle connection auto-accept.<br>
|
|
term_login - Transmit login file (ID Required)<br>
|
|
term_ping - Scan network for terminal devices.<br>
|
|
term_break - Send break signal to host.<br>
|
|
Connection Commands:<br>
|
|
connect \[Net ID] - Connect to a specified device.<br>
|
|
disconnect - Disconnect from current device.
|
|
File Commands<br>
|
|
file_status - View status of loaded file.<br>
|
|
file_send - Transmit loaded file.<br>
|
|
file_print - Print contents of file.<br>
|
|
file_load - Load file from local disk.
|
|
file_save - Save file to local disk."}
|
|
src.print_text(help_message)
|
|
return
|
|
|
|
switch(command)
|
|
if("term_status")
|
|
if(src.pnet_card)
|
|
var/statdat = pnet_card.return_status_text()
|
|
src.print_text("[pnet_card.func_tag]<br>Status: [statdat]")
|
|
else
|
|
src.print_text("No network card detected.")
|
|
|
|
src.print_text("Current Server Address: [src.serv_id ? src.serv_id : "NONE"]<br>Auto-accept connections is [src.auto_accept ? "ON" : "OFF"]<br>Toggle this with \"term_accept\"[src.service_mode ? "<br>Service mode active." : ""]")
|
|
|
|
if("term_accept")
|
|
src.auto_accept = !src.auto_accept
|
|
src.print_text("Auto-Accept is now [src.auto_accept ? "ON" : "OFF"]")
|
|
|
|
|
|
if ("term_break")
|
|
if (!src.serv_id || !pnet_card)
|
|
return
|
|
|
|
var/datum/signal/termsignal = get_free_signal()
|
|
//termsignal.encryption = "\ref[netcard]"
|
|
termsignal.data["address_1"] = src.serv_id
|
|
termsignal.data["command"] = "term_break"
|
|
|
|
src.peripheral_command("transmit", termsignal, "\ref[pnet_card]")
|
|
|
|
if("term_ping")
|
|
if(src.serv_id)
|
|
src.print_text("Alert: Cannot ping while connected.")
|
|
return
|
|
|
|
if(!src.pnet_card)
|
|
src.print_text("Alert: No network card detected.")
|
|
return
|
|
|
|
var/datum/signal/newsignal = get_free_signal()
|
|
newsignal.encryption = "\ref[src.pnet_card]"
|
|
src.ping_wait = 4
|
|
|
|
src.print_text("Pinging...")
|
|
src.peripheral_command("ping", newsignal, "\ref[src.pnet_card]")
|
|
|
|
if("term_service")
|
|
if (src.serv_id)
|
|
src.print_text("Alert: Cannot switch mode while connected.")
|
|
return
|
|
|
|
src.service_mode = !src.service_mode
|
|
src.print_text("Service mode [src.service_mode ? "" : "de"]activated.")
|
|
|
|
if("term_login")
|
|
var/obj/item/peripheral/scanner = find_peripheral("ID_SCANNER")
|
|
if(!scanner)
|
|
src.print_text("Error: No ID scanner detected.")
|
|
return
|
|
if(!src.pnet_card)
|
|
src.print_text("Alert: No network card detected.")
|
|
return
|
|
if(!src.serv_id)
|
|
src.print_text("Alert: Connection required.")
|
|
return
|
|
src.ping_wait = 2
|
|
|
|
var/datum/signal/scansignal = src.peripheral_command("scan_card",null,"\ref[scanner]")
|
|
if (istype(scansignal))
|
|
var/datum/computer/file/record/udat = new
|
|
udat.fields["registered"] = scansignal.data["registered"]
|
|
udat.fields["assignment"] = scansignal.data["assignment"]
|
|
udat.fields["access"] = scansignal.data["access"]
|
|
if (!udat.fields["access"] || !udat.fields["assignment"] || !udat.fields["access"])
|
|
//qdel(udat)
|
|
udat.dispose()
|
|
return
|
|
|
|
var/datum/signal/termsignal = get_free_signal()
|
|
//termsignal.encryption = "\ref[netcard]"
|
|
termsignal.data["address_1"] = serv_id
|
|
termsignal.data["command"] = "term_file"
|
|
termsignal.data["data"] = "login"
|
|
termsignal.data_file = udat
|
|
|
|
src.peripheral_command("transmit", termsignal, "\ref[pnet_card]")
|
|
return
|
|
|
|
|
|
if("connect")
|
|
if(src.serv_id)
|
|
src.print_text("Alert: Terminal is already connected.")
|
|
return
|
|
|
|
if(src.attempt_id)
|
|
src.print_text("Alert: Already attempting to connect.")
|
|
return
|
|
|
|
var/argument1 = null
|
|
if(command_list.len)
|
|
argument1 = command_list[1]
|
|
|
|
argument1 = ckey(copytext(argument1, 1, 9))
|
|
if(!argument1 || (length(argument1) != 8))
|
|
src.print_text("Alert: Invalid ID. (Must be 8 characters.)")
|
|
return
|
|
|
|
src.attempt_id = argument1
|
|
|
|
var/datum/computer/file/user_data/user_data = get_user_data()
|
|
var/datum/computer/file/record/udat = null
|
|
if (istype(user_data))
|
|
udat = new
|
|
udat.fields["registered"] = user_data.registered
|
|
if (src.service_mode)
|
|
udat.fields["userid"] = format_username(user_data.registered)
|
|
|
|
udat.fields["assignment"] = user_data.assignment
|
|
udat.fields["access"] = list2params(user_data.access)
|
|
if (!udat.fields["registered"] || !udat.fields["assignment"] || !udat.fields["access"])
|
|
//qdel(udat)
|
|
udat.dispose()
|
|
src.print_text("Error: User credential validity error.")
|
|
return
|
|
|
|
var/datum/signal/termsignal = get_free_signal()
|
|
|
|
termsignal.data["address_1"] = argument1
|
|
termsignal.data["command"] = "term_connect"
|
|
termsignal.data["device"] = "[src.service_mode ? "SRV" : "HUI"]_TERMINAL"
|
|
if (istype(udat))
|
|
termsignal.data_file = udat
|
|
|
|
src.disconnect_wait = 4
|
|
|
|
src.print_text("Attempting to connect...")
|
|
src.peripheral_command("transmit", termsignal, "\ref[pnet_card]")
|
|
|
|
if("reconnect")
|
|
if (src.serv_id)
|
|
src.print_text("Alert: Terminal is already connected.")
|
|
return
|
|
|
|
if (src.attempt_id)
|
|
src.print_text("Alert: Already attempting to connect.")
|
|
return
|
|
|
|
if (!src.last_serv_id)
|
|
src.print_text("Alert: No prior connection address in memory.")
|
|
return
|
|
|
|
src.attempt_id = src.last_serv_id
|
|
|
|
var/datum/signal/termsignal = get_free_signal()
|
|
//termsignal.encryption = "\ref[netcard]"
|
|
termsignal.data["address_1"] = src.attempt_id
|
|
termsignal.data["command"] = "term_connect"
|
|
termsignal.data["device"] = "[src.service_mode ? "SRV" : "HUI"]_TERMINAL"
|
|
src.disconnect_wait = 4
|
|
|
|
src.print_text("Attempting to reconnect to \[[src.attempt_id]]...")
|
|
src.peripheral_command("transmit", termsignal, "\ref[pnet_card]")
|
|
|
|
if("disconnect")
|
|
if(src.serv_id)
|
|
var/datum/signal/termsignal = get_free_signal()
|
|
|
|
termsignal.data["address_1"] = src.serv_id
|
|
termsignal.data["command"] = "term_disconnect"
|
|
src.serv_id = null
|
|
|
|
src.peripheral_command("transmit", termsignal, "\ref[pnet_card]")
|
|
src.print_text("Connection Closed.")
|
|
src.disconnect_wait = -1
|
|
|
|
if ("file_load")
|
|
var/toLoadName = "temp"
|
|
if (command_list.len)
|
|
toLoadName = jointext(command_list, "")
|
|
|
|
var/datum/computer/file/loadedFile = parse_file_directory(toLoadName,src.holding_folder)
|
|
|
|
if (istype(loadedFile))
|
|
src.print_text("File loaded.")
|
|
src.temp_file = loadedFile
|
|
return
|
|
|
|
src.print_text("Alert: File not found (or invalid).")
|
|
return
|
|
|
|
if("file_save")
|
|
if (!src.temp_file)
|
|
src.print_text("Error: No file to save!")
|
|
return
|
|
|
|
var/toSaveName = "temp"
|
|
if (command_list.len)
|
|
toSaveName = jointext(command_list, "")
|
|
|
|
var/datum/computer/file/record/saved = get_file_name(toSaveName, src.holding_folder)
|
|
if(saved || get_folder_name(toSaveName, src.holding_folder))
|
|
src.print_text("Error: Name in use.")
|
|
return
|
|
|
|
if(is_name_invalid(toSaveName))
|
|
src.print_text("Error: Invalid character in name.")
|
|
return
|
|
|
|
saved = src.temp_file.copy_file()
|
|
if (!saved)
|
|
src.print_text("Error: Cannot save to disk.")
|
|
return
|
|
|
|
if (!src.holding_folder.add_file(saved))
|
|
saved.dispose()
|
|
src.print_text("Error: Cannot save to disk.")
|
|
return
|
|
|
|
src.print_text("File saved.")
|
|
return
|
|
|
|
if("file_send")
|
|
if (!istype(src.temp_file))
|
|
src.print_text("Alert: No file loaded.")
|
|
return
|
|
|
|
if(!src.serv_id)
|
|
src.print_text("Alert: Connection required.")
|
|
return
|
|
|
|
var/sendText = "login"
|
|
if (command_list.len)
|
|
sendText = jointext(command_list, " ")
|
|
|
|
src.send_term_message(sendText, 1)
|
|
src.print_text("File sent.")
|
|
|
|
if ("file_status")
|
|
if(!src.temp_file || !istype(src.temp_file))
|
|
src.print_text("Alert: No file loaded.")
|
|
return
|
|
|
|
var/file_info = "[temp_file.name] - [temp_file.extension] - \[Size: [temp_file.size]]<br>Enter command \"file_save\" to save to external disk."
|
|
if(istype(temp_file, /datum/computer/file/text))
|
|
file_info += "<br>Enter command \"file_print\" to print."
|
|
else
|
|
file_info += "<br>Unrecognized filetype."
|
|
|
|
src.print_text(file_info)
|
|
|
|
if("file_print")
|
|
if(!src.temp_file)
|
|
src.print_text("Alert: File invalid or missing.")
|
|
return
|
|
|
|
var/to_print = src.temp_file.asText()
|
|
if (!to_print)
|
|
src.print_text("Alert: Nothing to print.")
|
|
return
|
|
|
|
src.print_text("Sending print command...")
|
|
var/datum/signal/printsig = new
|
|
printsig.data["data"] = to_print
|
|
printsig.data["title"] = "Printout"
|
|
|
|
src.peripheral_command("print",printsig)
|
|
|
|
if ("quit")
|
|
if(src.serv_id)
|
|
var/datum/signal/termsignal = get_free_signal()
|
|
|
|
termsignal.data["address_1"] = src.serv_id
|
|
termsignal.data["command"] = "term_disconnect"
|
|
src.serv_id = null
|
|
|
|
src.peripheral_command("transmit", termsignal, "\ref[pnet_card]")
|
|
src.print_text("Connection Closed.")
|
|
src.disconnect_wait = -1
|
|
|
|
src.print_text("Now Quitting...")
|
|
src.master.unload_program(src)
|
|
return
|
|
|
|
else
|
|
src.send_term_message(text)
|
|
|
|
src.master.add_fingerprint(usr)
|
|
src.master.updateUsrDialog()
|
|
return
|
|
|
|
disk_ejected(var/obj/item/disk/data/thedisk)
|
|
if(!thedisk)
|
|
return
|
|
|
|
if(src.holder == thedisk)
|
|
if(src.serv_id)
|
|
var/datum/signal/termsignal = get_free_signal()
|
|
|
|
termsignal.data["address_1"] = src.serv_id
|
|
termsignal.data["command"] = "term_disconnect"
|
|
src.serv_id = null
|
|
|
|
src.peripheral_command("transmit", termsignal, "\ref[pnet_card]")
|
|
src.disconnect_wait = -1
|
|
|
|
src.print_text("<font color=red>Fatal Error. Returning to system...</font>")
|
|
src.master.unload_program(src)
|
|
return
|
|
|
|
return
|
|
|
|
receive_command(obj/source, command, datum/signal/signal)
|
|
if((..()) || (!signal))
|
|
return
|
|
|
|
if(!serv_id || signal.data["sender"] != src.serv_id)
|
|
if(cmptext(signal.data["command"], "ping_reply") && src.ping_wait)
|
|
if(!signal.data["device"] || !signal.data["netid"])
|
|
return
|
|
|
|
var/reply_device = signal.data["device"]
|
|
var/reply_id = signal.data["netid"]
|
|
|
|
src.print_text("P: \[[reply_id]]-TYPE: [reply_device]")
|
|
|
|
//oh, somebody trying to connect!
|
|
else if(cmptext(signal.data["command"], "term_connect") && !src.serv_id)
|
|
if(!attempt_id && signal.data["sender"] && src.auto_accept)
|
|
src.serv_id = signal.data["sender"]
|
|
src.disconnect_wait = -1
|
|
src.print_text("Connection established to [serv_id]!")
|
|
//well okay but now they need to know we've accepted!
|
|
if(signal.data["data"] != "noreply")
|
|
var/datum/signal/termsignal = get_free_signal()
|
|
|
|
termsignal.data["address_1"] = signal.data["sender"]
|
|
termsignal.data["command"] = "term_connect"
|
|
|
|
src.peripheral_command("transmit", termsignal, "\ref[pnet_card]")
|
|
|
|
|
|
else if(cmptext(signal.data["sender"], attempt_id))
|
|
src.attempt_id = null
|
|
src.serv_id = signal.data["sender"]
|
|
src.disconnect_wait = -1
|
|
src.print_text("Connection to [serv_id] successful.")
|
|
|
|
if(cmptext(signal.data["sender"], src.serv_id))
|
|
switch(lowertext(signal.data["command"]))
|
|
if("term_message")
|
|
var/new_message = signal.data["data"]
|
|
if(!new_message)
|
|
return
|
|
|
|
switch(lowertext(signal.data["render"]))
|
|
if("clear") //They want the screen clear before printing
|
|
src.master.temp = null
|
|
|
|
if("multiline") //Oh, they want multiple lines of stuff.
|
|
new_message = replacetext(new_message, "|n", "<br>]")
|
|
|
|
if ("multiline|clear","clear|multiline") //Both of the above!
|
|
src.master.temp = null
|
|
new_message = replacetext(new_message, "|n", "<br>]")
|
|
|
|
src.print_text("][new_message]")
|
|
return
|
|
|
|
if("term_file") //oh boy, a file!
|
|
if(!signal.data_file || !istype(signal.data_file))
|
|
return //oh no the file is bad
|
|
/*
|
|
//Will it fit? Check before clearing out our old temp file!
|
|
if((holder.file_used + signal.data_file.size) > holder.file_amount)
|
|
src.print_text("Alert: Unable to accept file transfer, disk is full!")
|
|
return
|
|
*/
|
|
if(src.temp_file && !src.temp_file.holding_folder)
|
|
temp_file.dispose()
|
|
|
|
src.temp_file = signal.data_file.copy_file()
|
|
src.temp_file.name = "temp"
|
|
src.print_text("Alert: File received from remote host!<br>Valid commands: file_status, file_print")
|
|
|
|
if("term_ping")
|
|
if(signal.data["data"] == "reply")
|
|
var/datum/signal/termsignal = get_free_signal()
|
|
|
|
termsignal.data["address_1"] = signal.data["sender"]
|
|
termsignal.data["command"] = "term_ping"
|
|
|
|
src.peripheral_command("transmit", termsignal, "\ref[pnet_card]")
|
|
return
|
|
|
|
if("term_disconnect")
|
|
src.serv_id = null
|
|
src.attempt_id = null
|
|
|
|
src.print_text("Connection closed by remote host.")
|
|
return
|
|
|
|
return
|
|
|
|
proc/send_term_message(var/message, send_file)
|
|
if(!message || !src.serv_id || !pnet_card)
|
|
return
|
|
|
|
message = strip_html(message)
|
|
|
|
var/datum/signal/termsignal = get_free_signal()
|
|
|
|
termsignal.data["address_1"] = src.serv_id
|
|
termsignal.data["data"] = message
|
|
termsignal.data["command"] = "term_[send_file ? "file" : "message"]"
|
|
if (send_file && src.temp_file)
|
|
termsignal.data_file = src.temp_file.copy_file()
|
|
|
|
src.peripheral_command("transmit", termsignal, "\ref[pnet_card]")
|
|
return
|
|
|
|
proc/get_user_data()
|
|
var/datum/computer/folder/accdir = src.holder.root
|
|
if(src.master.host_program) //Check where the OS is, preferably.
|
|
accdir = src.master.host_program.holder.root
|
|
|
|
var/datum/computer/file/user_data/target = parse_file_directory(setup_acc_filepath, accdir)
|
|
if(target && istype(target))
|
|
return target
|
|
|
|
return null
|
|
|
|
#define WORKING_PACKET_MAX 32
|
|
|
|
/datum/computer/file/terminal_program/sigpal
|
|
name = "SigPal"
|
|
size = 4
|
|
var/list/working_signal = list()
|
|
var/obj/item/peripheral/network/pnet_card
|
|
var/datum/computer/file/attached_file = null
|
|
|
|
disposing()
|
|
pnet_card = null
|
|
working_signal = null
|
|
attached_file = null
|
|
..()
|
|
|
|
initialize()
|
|
working_signal = list()
|
|
src.pnet_card = null
|
|
attached_file = null
|
|
var/introdat = "SigPal Signal Manager<br>Copyright 2053 Thinktronic Systems, LTD."
|
|
|
|
src.pnet_card = find_peripheral("NET_ADAPTER")
|
|
if (!src.pnet_card || !istype(src.pnet_card))
|
|
src.pnet_card = find_peripheral("RAD_ADAPTER")
|
|
if (istype(src.pnet_card))
|
|
src.peripheral_command("mode_net", null, "\ref[pnet_card]")
|
|
introdat += "<br>Network card detected (Radio)."
|
|
else
|
|
|
|
src.pnet_card = null
|
|
introdat += "<br>Error: No network card detected."
|
|
|
|
if (src.pnet_card)
|
|
introdat += "<br>Network ID: [pnet_card.net_id]"
|
|
|
|
|
|
src.print_text("[introdat]<br>Type \"help\" for commands.")
|
|
|
|
|
|
input_text(text)
|
|
if(..())
|
|
return
|
|
|
|
var/list/command_list = parse_string(text)
|
|
var/command = command_list[1]
|
|
command_list -= command_list[1] //Remove the command we are now processing.
|
|
|
|
switch(lowertext(command))
|
|
if ("help")
|
|
src.print_text("Command List:<br> ADD \[key] \[data] to add (or replace) a key-value pair to the packet.<br> REMOVE \[key] to remove existing key pair <br> VIEW to view current packet.<br> SEND to transmit packet over network card.<br> SAVE/LOAD \[file name] to save/load the signal as a record.<br> NEW to clear current signal.<br> FILE to set an attachment to send (This is not saved to disk)")
|
|
return
|
|
|
|
if ("add")
|
|
var/key = null
|
|
var/data = null
|
|
. = 0
|
|
if(command_list.len >= 2)
|
|
|
|
key = command_list[1]
|
|
command_list -= command_list[1]
|
|
key = copytext(lowertext(strip_html(key)), 1, 128)
|
|
|
|
data = jointext(command_list, " ")
|
|
data = copytext(strip_html(data), 1, 256)
|
|
|
|
if(!ckey(key) || ckey(!data))
|
|
src.print_text("Syntax: \"add \[key] \[data]\"")
|
|
return
|
|
|
|
if(src.working_signal.len >= WORKING_PACKET_MAX)
|
|
src.print_text("Error: Maximum packet keys reached.")
|
|
return
|
|
|
|
if(!isnull(src.working_signal[key]))
|
|
. = 1
|
|
|
|
src.working_signal[key] = data
|
|
src.print_text("Addition complete. (Signal length: \[[src.working_signal.len]])[. ? "<br>That key was already present and has been modified." : ""]")
|
|
|
|
if ("remove")
|
|
var/key = lowertext(command_list[1])
|
|
if (key in working_signal)
|
|
working_signal -= key
|
|
src.print_text("Key removed. (Signal length: \[[src.working_signal.len]])")
|
|
else
|
|
src.print_text("Key not present.")
|
|
|
|
if ("send","transmit")
|
|
if (!src.working_signal.len)
|
|
src.print_text("Error: Cannot send empty packet.")
|
|
return
|
|
|
|
if (!src.pnet_card)
|
|
src.print_text("Error: No network card present!")
|
|
return
|
|
|
|
var/datum/signal/sig = get_free_signal()
|
|
for (var/entry in working_signal)
|
|
var/equalpos = findtext("=", entry)
|
|
if (equalpos)
|
|
sig.data["[copytext(entry, 1, equalpos)]"] = "[copytext(entry, equalpos)]"
|
|
else
|
|
if (!isnull(working_signal[entry]))
|
|
sig.data["[entry]"] = working_signal[entry]
|
|
else
|
|
sig.data += entry
|
|
|
|
if (attached_file)
|
|
sig.data_file = attached_file
|
|
|
|
src.peripheral_command("transmit", sig, "\ref[pnet_card]")
|
|
src.print_text("Packet sent.")
|
|
|
|
if ("view")
|
|
if (!src.working_signal.len)
|
|
src.print_text("The current packet is empty.")
|
|
return
|
|
|
|
. = ""
|
|
for (var/key in src.working_signal)
|
|
. += "[key] = [src.working_signal[key]]<br>"
|
|
|
|
|
|
src.print_text(.)
|
|
return
|
|
|
|
if ("save")
|
|
var/new_name = strip_html(jointext(command_list, " "))
|
|
new_name = copytext(new_name, 1, 16)
|
|
|
|
if(!new_name)
|
|
src.print_text("Syntax: \"SAVE \[file name]\"")
|
|
return
|
|
|
|
var/datum/computer/file/record/saved = get_file_name(new_name, src.holding_folder)
|
|
if(saved && !istype(saved) || get_folder_name(new_name, src.holding_folder))
|
|
src.print_text("Error: Name in use.")
|
|
return
|
|
|
|
if(is_name_invalid(new_name))
|
|
src.print_text("Error: Invalid character in name.")
|
|
return
|
|
|
|
if(saved && istype(saved))
|
|
saved.fields = src.working_signal.Copy()
|
|
else
|
|
saved = new /datum/computer/file/record
|
|
saved.name = new_name
|
|
saved.fields = src.working_signal.Copy()
|
|
if(!src.holding_folder.add_file(saved))
|
|
//qdel(saved)
|
|
saved.dispose()
|
|
src.print_text("Error: Cannot save to disk.")
|
|
return
|
|
|
|
src.print_text("Record \"[new_name]\" saved.")
|
|
|
|
if ("load")
|
|
var/file_name = ckey(jointext(command_list, " "))
|
|
|
|
if(!file_name)
|
|
src.print_text("Syntax: \"LOAD \[file name]\"")
|
|
return
|
|
|
|
var/datum/computer/file/record/to_load = get_file_name(file_name, src.holding_folder)
|
|
if(!to_load || !istype(to_load))
|
|
src.print_text("Error: File not found or corrupt.")
|
|
return
|
|
|
|
src.working_signal = to_load.fields.Copy()
|
|
src.working_signal.len = min(src.working_signal.len, WORKING_PACKET_MAX)
|
|
|
|
src.print_text("Load complete.")
|
|
|
|
if ("new")
|
|
src.working_signal = list()
|
|
src.attached_file = null
|
|
src.print_text("Signal cleared.")
|
|
|
|
if ("file")
|
|
var/file_name = ckey(jointext(command_list, " "))
|
|
|
|
if(!file_name)
|
|
src.attached_file = null
|
|
src.print_text("File attachment cleared.")
|
|
return
|
|
|
|
var/datum/computer/file/to_load = get_file_name(file_name, src.holding_folder)
|
|
if(!istype(to_load))
|
|
src.print_text("Error: File not found or corrupt.")
|
|
return
|
|
|
|
attached_file = to_load.copy_file()
|
|
|
|
if ("quit","exit")
|
|
src.master.temp = ""
|
|
print_text("Now quitting...")
|
|
src.master.unload_program(src)
|
|
return
|
|
|
|
else
|
|
src.print_text("Unknown command.")
|
|
|
|
#undef WORKING_PACKET_MAX
|
|
|
|
/datum/computer/file/terminal_program/sigcrafter
|
|
name = "SigCraft"
|
|
size = 4
|
|
var/temp= null
|
|
var/datum/computer/file/included_file = null //File to include in signal file.
|
|
var/list/text_buffer = list()
|
|
var/list/working_signal = list()
|
|
var/selected_line = 1 //Which line of the signal are we working on?
|
|
|
|
#define WORKING_DISPLAY_LENGTH 8 //How many lines is the working portion?
|
|
|
|
input_text(text)
|
|
if(..())
|
|
return
|
|
|
|
var/list/command_list = parse_string(text)
|
|
var/command = command_list[1]
|
|
command_list -= command_list[1] //Remove the command we are now processing.
|
|
|
|
switch(lowertext(command))
|
|
if("line") //Set working line to provided num.
|
|
var/target_line = 0
|
|
if(command_list.len)
|
|
target_line = round(text2num(command_list[1]))
|
|
else
|
|
src.print_half_text("Line number required.")
|
|
return
|
|
|
|
|
|
if((!target_line) || (target_line > WORKING_DISPLAY_LENGTH) || (target_line <= 0))
|
|
src.print_half_text("Error: Line invalid or out of bounds.")
|
|
return
|
|
|
|
src.selected_line = target_line
|
|
src.print_half_text("Active line set to [target_line].")
|
|
|
|
if("add") //Add new line to signal if possible.
|
|
var/title = null
|
|
var/data = null
|
|
if(command_list.len >= 2)
|
|
|
|
title = command_list[1]
|
|
command_list -= command_list[1]
|
|
title = copytext(lowertext(strip_html(title)), 1, 16)
|
|
|
|
data = jointext(command_list, " ")
|
|
data = copytext(strip_html(data), 1, 255)
|
|
|
|
if(!ckey(title) || ckey(!data))
|
|
src.print_half_text("Syntax: \"add \[title] \[data]\"")
|
|
return
|
|
|
|
if(src.working_signal.len >= WORKING_DISPLAY_LENGTH)
|
|
src.print_half_text("Error: Working Signal Full.")
|
|
return
|
|
|
|
if(!isnull(src.working_signal[title]))
|
|
src.print_half_text("Error: Title already in use.")
|
|
return
|
|
|
|
src.working_signal[title] = data
|
|
src.print_half_text("Addition complete. (Signal length: \[[src.working_signal.len]])")
|
|
|
|
if("view")
|
|
if((selected_line > src.working_signal.len) || (selected_line <= 0))
|
|
src.print_half_text("Error: Working line out of bounds.")
|
|
return
|
|
|
|
src.print_half_text("L\[[selected_line]]: [src.working_signal[src.working_signal[selected_line]]]")
|
|
|
|
if("remove")
|
|
if((selected_line > src.working_signal.len) || (selected_line <= 0))
|
|
src.print_half_text("Error: Working line out of bounds.")
|
|
return
|
|
|
|
src.working_signal -= src.working_signal[selected_line]
|
|
|
|
src.print_half_text("Line \[[selected_line]] cleared.")
|
|
|
|
if("load")
|
|
var/file_name = ckey(jointext(command_list, " "))
|
|
|
|
if(!file_name)
|
|
src.print_half_text("Syntax: \"load \[file name]\"")
|
|
return
|
|
|
|
var/datum/computer/file/signal/to_load = get_file_name(file_name, src.holding_folder)
|
|
if(!to_load || !istype(to_load))
|
|
src.print_half_text("Error: File not found or corrupt.")
|
|
return
|
|
|
|
src.working_signal = to_load.data.Copy()
|
|
src.working_signal.len = min(src.working_signal.len, WORKING_DISPLAY_LENGTH)
|
|
src.included_file = null
|
|
if(to_load.data_file)
|
|
src.included_file = to_load.data_file.copy_file()
|
|
|
|
src.print_half_text("Load complete.")
|
|
|
|
if("save")
|
|
var/new_name = strip_html(jointext(command_list, " "))
|
|
new_name = copytext(new_name, 1, 16)
|
|
|
|
if(!new_name)
|
|
src.print_half_text("Syntax: \"save \[file name]\"")
|
|
return
|
|
|
|
var/datum/computer/file/signal/saved = get_file_name(new_name, src.holding_folder)
|
|
if(saved && !istype(saved) || get_folder_name(new_name, src.holding_folder))
|
|
src.print_half_text("Error: Name in use.")
|
|
return
|
|
|
|
if(is_name_invalid(new_name))
|
|
src.print_half_text("Error: Invalid character in name.")
|
|
return
|
|
|
|
if(saved && istype(saved))
|
|
saved.data = src.working_signal.Copy()
|
|
if(saved.data_file)
|
|
//qdel(saved.data_file)
|
|
saved.data_file.dispose()
|
|
if(src.included_file)
|
|
saved.data_file = src.included_file.copy_file()
|
|
else
|
|
saved = new /datum/computer/file/signal
|
|
saved.name = new_name
|
|
saved.data = src.working_signal.Copy()
|
|
if(src.included_file)
|
|
saved.data_file = src.included_file.copy_file()
|
|
if(!src.holding_folder.add_file(saved))
|
|
// qdel(saved)
|
|
saved.dispose()
|
|
src.print_half_text("Error: Cannot save to disk.")
|
|
return
|
|
|
|
src.print_half_text("Signal \"[new_name]\" saved.")
|
|
|
|
if("recsave")
|
|
var/new_name = strip_html(jointext(command_list, " "))
|
|
new_name = copytext(new_name, 1, 16)
|
|
|
|
if(!new_name)
|
|
src.print_half_text("Syntax: \"recsave \[file name]\"")
|
|
return
|
|
|
|
var/datum/computer/file/record/saved = get_file_name(new_name, src.holding_folder)
|
|
if(saved && !istype(saved) || get_folder_name(new_name, src.holding_folder))
|
|
src.print_half_text("Error: Name in use.")
|
|
return
|
|
|
|
if(is_name_invalid(new_name))
|
|
src.print_half_text("Error: Invalid character in name.")
|
|
return
|
|
|
|
if(saved && istype(saved))
|
|
saved.fields = src.working_signal.Copy()
|
|
else
|
|
saved = new /datum/computer/file/record
|
|
saved.name = new_name
|
|
saved.fields = src.working_signal.Copy()
|
|
if(!src.holding_folder.add_file(saved))
|
|
//qdel(saved)
|
|
saved.dispose()
|
|
src.print_half_text("Error: Cannot save to disk.")
|
|
return
|
|
|
|
src.print_half_text("Record \"[new_name]\" saved.")
|
|
|
|
if("file")
|
|
var/inc_path = jointext(command_list, " ")
|
|
if(!ckey(inc_path))
|
|
src.print_half_text("Syntax: \"file \[filepath]\"")
|
|
src.print_half_text("Path of file to include in signal.")
|
|
src.print_half_text("Current: [istype(src.included_file) ? src.included_file.name : "NONE"]")
|
|
return
|
|
|
|
var/datum/computer/file/to_inc = src.parse_file_directory(inc_path, holding_folder)
|
|
if(!istype(to_inc))
|
|
src.print_half_text("Error: Invalid filepath!")
|
|
return
|
|
|
|
src.included_file = to_inc.copy_file()
|
|
src.print_half_text("File set.")
|
|
|
|
if("new")
|
|
src.working_signal = get_free_signal()
|
|
if(src.included_file)
|
|
//qdel(src.included_file)
|
|
src.included_file.dispose()
|
|
src.print_half_text("Work cleared.")
|
|
|
|
if("help")
|
|
src.print_half_text("Commands: Add \[Title] \[Data], Line \[line],")
|
|
src.print_half_text("Load/Save/RecSave \[file], File \[path], New, Remove")
|
|
src.print_half_text("Help, Quit.")
|
|
|
|
if("quit")
|
|
src.master.temp = ""
|
|
print_text("Now quitting...")
|
|
src.master.unload_program(src)
|
|
return
|
|
|
|
else
|
|
print_half_text("Unknown command : \"[copytext(strip_html(command), 1, 16)]\"")
|
|
|
|
src.master.add_fingerprint(usr)
|
|
src.master.updateUsrDialog()
|
|
return
|
|
|
|
initialize()
|
|
//Set working lists back to normal...
|
|
src.text_buffer = new
|
|
src.working_signal = get_free_signal()
|
|
//Their length should be fixed up by the first print_half_text call
|
|
src.print_half_text("Signal Crafter 2.0")
|
|
src.print_half_text("Commands: Add \[Title] \[Data], Line \[line],")
|
|
src.print_half_text("Load/Save \[file], File \[path], New, Remove, Recsave \[file]")
|
|
src.print_half_text("Help, Quit.")
|
|
|
|
/* new disposing() pattern should handle this. -singh
|
|
Del()
|
|
if(src.included_file)
|
|
qdel(src.included_file)
|
|
..()
|
|
*/
|
|
|
|
disposing()
|
|
if (src.included_file)
|
|
src.included_file.dispose()
|
|
src.included_file = null
|
|
|
|
src.text_buffer = null
|
|
src.working_signal = null
|
|
..()
|
|
|
|
proc
|
|
print_half_text(var/text) //Print stuff to the screen while keeping the signal info up
|
|
if((!src.holder) || (!src.master) || !text || disposed)
|
|
return 1
|
|
|
|
if((!istype(holder)) || (!istype(master)))
|
|
return 1
|
|
|
|
if(master.stat & (NOPOWER|BROKEN))
|
|
return 1
|
|
|
|
if(!(holder in src.master.contents))
|
|
if(master.active_program == src)
|
|
master.active_program = null
|
|
return 1
|
|
|
|
if(!src.holder.root)
|
|
src.holder.root = new /datum/computer/folder
|
|
src.holder.root.holder = src
|
|
src.holder.root.name = "root"
|
|
|
|
if(src.text_buffer.len >= 6)
|
|
src.text_buffer -= src.text_buffer[1]
|
|
|
|
src.text_buffer += text
|
|
|
|
src.selected_line = max(min(src.selected_line, 8), 1)
|
|
|
|
if (!istype(working_signal, /list))
|
|
working_signal = list()
|
|
|
|
var/dat = "<center>Current Signal</center><br>"
|
|
for(var/x = 1, x <= WORKING_DISPLAY_LENGTH, x++)
|
|
var/part = "\[UNUSED]"
|
|
if(x <= working_signal.len)
|
|
var/title_text = working_signal[x]
|
|
var/main_text = working_signal[title_text]
|
|
part = " \[[isnull(title_text) ? "Untitled" : title_text]] \[[isnull(main_text) ? "Blank" : copytext(main_text, 1, 25)]]"
|
|
if(src.selected_line == x)
|
|
dat += ">\[[x]] [part]<br>"
|
|
else
|
|
dat += "|\[[x]] [part]<br>"
|
|
|
|
dat += "<hr>"
|
|
|
|
for(var/x in src.text_buffer)
|
|
dat += "[x]<br>"
|
|
|
|
src.master.temp = null
|
|
src.master.temp_add = "[dat]"
|
|
src.master.updateUsrDialog()
|
|
|
|
return 0
|
|
|
|
#undef WORKING_DISPLAY_LENGTH
|
|
|
|
/datum/computer/file/terminal_program/disease_research
|
|
|
|
/datum/computer/file/terminal_program/artifact_research
|
|
|
|
/datum/computer/file/terminal_program/manifest
|
|
name = "Manifest"
|
|
size = 4
|
|
|
|
|
|
initialize()
|
|
|
|
var/dat = "Crew Manifest<br>Entries cannot be modified from this terminal.<br>"
|
|
|
|
for (var/datum/data/record/t in data_core.general)
|
|
dat += "[t.fields["name"]] - [t.fields["rank"]]<br>"
|
|
|
|
src.master.temp = null
|
|
src.print_text("[dat]Now exiting...")
|
|
src.master.unload_program(src)
|
|
|
|
return
|
|
|
|
/datum/computer/file/terminal_program/robotics_research
|
|
|
|
#undef MAX_BACKGROUND_PROGS |