mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
Makes the traffic control console less terrible to use (#22478)
* AHAHAHAHAHAHAHAHAHAHAHAHAHA * VESTIGIAL CODE THAT MUST BE DESTROYED * E * FIXES STUFF * Update NtslEditor.js * USELESS VARIABLE THAT DOES NOTHING BUT THE LINTER WANTS IT * IS THIS WHAT IT WANTS * MADE THE SCROLLING NOT TERRIBLY CODED * YES * NOT USED * Update traffic_control.dm * SCROLL BAR
This commit is contained in:
@@ -359,99 +359,3 @@ window "statwindow"
|
||||
background-color = none
|
||||
is-visible = false
|
||||
saved-params = ""
|
||||
|
||||
window "Telecomms IDE"
|
||||
elem "Telecomms IDE"
|
||||
type = MAIN
|
||||
pos = 281,0
|
||||
size = 569x582
|
||||
anchor1 = none
|
||||
anchor2 = none
|
||||
text-color = #eeeeee
|
||||
background-color = #222222
|
||||
is-visible = false
|
||||
saved-params = "pos;size;is-minimized;is-maximized"
|
||||
title = "TCS IDE"
|
||||
statusbar = false
|
||||
on-close = "exittcs"
|
||||
elem "button5"
|
||||
type = BUTTON
|
||||
pos = 209,464
|
||||
size = 70x20
|
||||
anchor1 = 37,80
|
||||
anchor2 = 49,83
|
||||
text-color = #eeeeee
|
||||
background-color = #555555
|
||||
saved-params = "is-checked"
|
||||
text = "Clear Memory"
|
||||
command = "tcsclearmem"
|
||||
elem "button4"
|
||||
type = BUTTON
|
||||
pos = 157,464
|
||||
size = 52x20
|
||||
anchor1 = 28,80
|
||||
anchor2 = 37,83
|
||||
text-color = #eeeeee
|
||||
background-color = #555555
|
||||
saved-params = "is-checked"
|
||||
text = "Revert"
|
||||
command = "tcsrevert"
|
||||
elem "button3"
|
||||
type = BUTTON
|
||||
pos = 105,464
|
||||
size = 52x20
|
||||
anchor1 = 18,80
|
||||
anchor2 = 28,83
|
||||
text-color = #eeeeee
|
||||
background-color = #555555
|
||||
saved-params = "is-checked"
|
||||
text = "Execute"
|
||||
command = "tcsrun"
|
||||
elem "tcserror"
|
||||
type = OUTPUT
|
||||
pos = 0,488
|
||||
size = 566x94
|
||||
anchor1 = 0,84
|
||||
anchor2 = 99,100
|
||||
font-family = "sans-serif"
|
||||
font-size = 9
|
||||
text-color = #eeeeee
|
||||
background-color = #333334
|
||||
saved-params = "max-lines"
|
||||
elem "button2"
|
||||
type = BUTTON
|
||||
pos = 53,464
|
||||
size = 52x20
|
||||
anchor1 = 9,80
|
||||
anchor2 = 18,83
|
||||
text-color = #eeeeee
|
||||
background-color = #555555
|
||||
saved-params = "is-checked"
|
||||
text = "Compile"
|
||||
command = "tcscompile"
|
||||
elem "button1"
|
||||
type = BUTTON
|
||||
pos = 0,464
|
||||
size = 53x20
|
||||
anchor1 = 0,80
|
||||
anchor2 = 9,83
|
||||
text-color = #eeeeee
|
||||
background-color = #555555
|
||||
saved-params = "is-checked"
|
||||
text = "Save"
|
||||
command = "tcssave"
|
||||
elem "tcscode"
|
||||
type = INPUT
|
||||
pos = 0,0
|
||||
size = 569x464
|
||||
anchor1 = 0,0
|
||||
anchor2 = 100,80
|
||||
font-family = "Courier"
|
||||
font-size = 10
|
||||
text-color = #eeeeee
|
||||
background-color = #333334
|
||||
saved-params = ""
|
||||
command = "cancel"
|
||||
multi-line = true
|
||||
no-command = true
|
||||
|
||||
|
||||
204
tgui/packages/tgui/interfaces/NtslEditor.js
Normal file
204
tgui/packages/tgui/interfaces/NtslEditor.js
Normal file
@@ -0,0 +1,204 @@
|
||||
import { useBackend, useLocalState } from '../backend';
|
||||
import { Box, Button, Divider, Input, Tabs, TextArea, Section, Stack } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
|
||||
export const NtslEditor = (props, context) => {
|
||||
// Make sure we don't start larger than 50%/80% of screen width/height.
|
||||
const winWidth = Math.min(900, window.screen.availWidth * 0.5);
|
||||
const winHeight = Math.min(600, window.screen.availHeight * 0.8);
|
||||
|
||||
return (
|
||||
<Window
|
||||
title="Traffic Control Console"
|
||||
width={winWidth}
|
||||
height={winHeight}
|
||||
>
|
||||
<Window.Content>
|
||||
<Stack fill>
|
||||
<Stack.Item width={winWidth-240}>
|
||||
<ScriptEditor />
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<MainMenu />
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
const ScriptEditor = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const { stored_code, user_name } = data;
|
||||
return (
|
||||
<Box width="100%" height="100%">
|
||||
{user_name ?
|
||||
<TextArea
|
||||
noborder
|
||||
scrollbar
|
||||
value={stored_code}
|
||||
width="100%"
|
||||
height="100%"
|
||||
onChange={(e, value) => act('save_code', {
|
||||
saved_code: value,
|
||||
})}
|
||||
onEnter={(e, value) => act('save_code', {
|
||||
saved_code: value+"\n",
|
||||
})}
|
||||
/> :
|
||||
<Section width="100%" height="100%">
|
||||
{stored_code}
|
||||
</Section>
|
||||
}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const MainMenu = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const { emagged, user_name } = data;
|
||||
const [tabIndex, setTabIndex] = useLocalState(context, "tab-index", 1);
|
||||
return (
|
||||
<>
|
||||
<Section width="240px">
|
||||
{user_name ?
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
icon="power-off"
|
||||
color="purple"
|
||||
content="Log Out"
|
||||
disabled={emagged}
|
||||
onClick={() => act('log_out')}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item verticalAlign="middle">
|
||||
{user_name}
|
||||
</Stack.Item>
|
||||
</Stack> : <Button
|
||||
icon="power-off"
|
||||
color="green"
|
||||
content="Log In"
|
||||
onClick={() => act('log_in')}
|
||||
/>}
|
||||
</Section>
|
||||
{user_name &&
|
||||
<Section width="240px" height="90%" fill>
|
||||
<Tabs>
|
||||
<Tabs.Tab
|
||||
selected={tabIndex === 1}
|
||||
onClick={() => setTabIndex(1)}>
|
||||
Compile
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
selected={tabIndex === 2}
|
||||
onClick={() => setTabIndex(2)}>
|
||||
Network
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
selected={tabIndex === 3}
|
||||
onClick={() => setTabIndex(3)}>
|
||||
Logs
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
{ tabIndex === 1 && <CompilerOutput /> }
|
||||
{ tabIndex === 2 && <ServerList /> }
|
||||
{ tabIndex === 3 && <LogViewer /> }
|
||||
</Section>
|
||||
}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const CompilerOutput = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const { compiler_output } = data;
|
||||
return (
|
||||
<>
|
||||
<Box>
|
||||
<Button
|
||||
mb={1}
|
||||
icon="save"
|
||||
content='Compile & Run'
|
||||
onClick={() => act('compile_code')}
|
||||
/>
|
||||
</Box>
|
||||
<Divider />
|
||||
<Section fill scrollable height="87.2%">
|
||||
{compiler_output ? compiler_output.map((error_message, index) => (
|
||||
<Box key={index}>
|
||||
{error_message}
|
||||
</Box>
|
||||
)) : "No compile errors."}
|
||||
</Section>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const ServerList = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const { network, server_data } = data;
|
||||
return (
|
||||
<>
|
||||
<Box>
|
||||
<Button
|
||||
mb={1}
|
||||
icon="sync"
|
||||
content='Reconnect to Network'
|
||||
onClick={() => act('refresh_servers')}
|
||||
/>
|
||||
</Box>
|
||||
<Box>
|
||||
<Input
|
||||
mb={1}
|
||||
value={network}
|
||||
onChange={(e, value) => act('set_network', {
|
||||
new_network: value,
|
||||
})}
|
||||
/>
|
||||
</Box>
|
||||
<Divider />
|
||||
<Section fill scrollable height="82%">
|
||||
{server_data.map((nt_server, index) => (
|
||||
<Box key={index}>
|
||||
<Button.Checkbox
|
||||
mb={0.5}
|
||||
checked={nt_server.run_code}
|
||||
content={nt_server.server_name}
|
||||
onClick={() => act('toggle_code_execution', {
|
||||
selected_server: nt_server.server,
|
||||
})}
|
||||
/>
|
||||
</Box>
|
||||
))}
|
||||
</Section>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const LogViewer = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const { access_log } = data;
|
||||
// This is terrible but nothing else will work
|
||||
return (
|
||||
<>
|
||||
<Box>
|
||||
<Button
|
||||
mb={1}
|
||||
icon='trash'
|
||||
content='Clear Logs'
|
||||
onClick={() => act('clear_logs')}
|
||||
/>
|
||||
</Box>
|
||||
<Divider />
|
||||
<Section fill scrollable height="87.2%">
|
||||
{access_log ? access_log.map((access_message, index) => (
|
||||
<Box key={index}>
|
||||
{access_message}
|
||||
</Box>
|
||||
)) : "Access log could not be found. Please contact an administrator."}
|
||||
</Section>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -4544,7 +4544,6 @@
|
||||
#include "yogstation\code\modules\research\techweb\all_nodes.dm"
|
||||
#include "yogstation\code\modules\ruins\ivymen_den.dm"
|
||||
#include "yogstation\code\modules\ruins\lavaland_ruin_code.dm"
|
||||
#include "yogstation\code\modules\scripting\client_verbs.dm"
|
||||
#include "yogstation\code\modules\scripting\Errors.dm"
|
||||
#include "yogstation\code\modules\scripting\Options.dm"
|
||||
#include "yogstation\code\modules\scripting\stack.dm"
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
|
||||
|
||||
/obj/machinery/computer/telecomms/traffic
|
||||
name = "telecommunications traffic control console"
|
||||
|
||||
var/screen = 0 // the screen number:
|
||||
var/emagged = FALSE
|
||||
var/list/servers = list() // the servers located by the computer
|
||||
var/mob/editingcode
|
||||
var/mob/lasteditor
|
||||
var/list/viewingcode = list()
|
||||
var/obj/machinery/telecomms/server/SelectedServer
|
||||
|
||||
var/network = "NULL" // the network to probe
|
||||
var/temp = "" // temporary feedback messages
|
||||
|
||||
var/storedcode = "" // code stored
|
||||
var/obj/item/card/id/auth = null
|
||||
/// The servers located by the computer
|
||||
var/list/obj/machinery/telecomms/server/servers = list()
|
||||
/// The network to probe
|
||||
var/network = "NULL"
|
||||
/// The current code being used
|
||||
var/storedcode = ""
|
||||
/// The ID currently inserted
|
||||
var/obj/item/card/id/inserted_id
|
||||
/// The name and job on the ID used to log in
|
||||
var/user_name = ""
|
||||
/// Logs for users logging in/out or compiling code
|
||||
var/list/access_log = list()
|
||||
var/process = 0
|
||||
/// Output from compiling to the servers
|
||||
var/list/compiler_output = list()
|
||||
|
||||
circuit = /obj/item/circuitboard/computer/telecomms/comm_traffic
|
||||
|
||||
req_access = list(ACCESS_TCOM_ADMIN)
|
||||
@@ -28,305 +26,165 @@
|
||||
GLOB.traffic_comps += src
|
||||
if(mapload)
|
||||
unlimited_range = TRUE
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/machinery/computer/telecomms/traffic/LateInitialize()
|
||||
. = ..()
|
||||
refresh_servers()
|
||||
for(var/obj/machinery/telecomms/server/new_server in servers)
|
||||
new_server.autoruncode = TRUE
|
||||
|
||||
/obj/machinery/computer/telecomms/traffic/Destroy()
|
||||
GLOB.traffic_comps -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/telecomms/traffic/proc/stop_editing()
|
||||
if(editingcode)
|
||||
if(editingcode.client)
|
||||
winshow(editingcode, "Telecomms IDE", 0) // hide the window!
|
||||
editingcode.unset_machine()
|
||||
editingcode = null
|
||||
/obj/machinery/computer/telecomms/traffic/proc/create_log(entry)
|
||||
if(!user_name)
|
||||
CRASH("[type] tried to create a log with no user_name!")
|
||||
access_log += "\[[get_timestamp()]\] [user_name] [entry]"
|
||||
|
||||
/obj/machinery/computer/telecomms/traffic/process()
|
||||
/obj/machinery/computer/telecomms/traffic/ui_interact(mob/user, datum/tgui/ui)
|
||||
if(is_banned_from(user.ckey, "Network Admin"))
|
||||
return "You are banned from using NTSL."
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "NtslEditor", name)
|
||||
ui.open()
|
||||
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
stop_editing()
|
||||
/obj/machinery/computer/telecomms/traffic/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
var/list/server_data = list()
|
||||
for(var/obj/machinery/telecomms/server/server in servers)
|
||||
server_data.Add(list(list(
|
||||
"server" = REF(server),
|
||||
"server_id" = server.id,
|
||||
"server_name" = server.name,
|
||||
"run_code" = server.autoruncode,
|
||||
)))
|
||||
data["server_data"] = server_data
|
||||
data["stored_code"] = storedcode
|
||||
data["network"] = network
|
||||
data["user_name"] = user_name
|
||||
data["has_access"] = inserted_id
|
||||
data["access_log"] = access_log.Copy()
|
||||
data["compiler_output"] = compiler_output.Copy()
|
||||
data["emagged"] = ((obj_flags & EMAGGED) > 0)
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/telecomms/traffic/ui_act(action, list/params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
if(editingcode && editingcode.machine != src)
|
||||
stop_editing()
|
||||
return
|
||||
|
||||
if(!editingcode)
|
||||
if(length(viewingcode) > 0)
|
||||
editingcode = pick(viewingcode)
|
||||
viewingcode.Remove(editingcode)
|
||||
return
|
||||
|
||||
process = !process
|
||||
if(!process)
|
||||
return
|
||||
|
||||
// loop if there's someone manning the keyboard
|
||||
if(!editingcode.client)
|
||||
stop_editing()
|
||||
return
|
||||
|
||||
// For the typer, the input is enabled. Buffer the typed text
|
||||
storedcode = "[winget(editingcode, "tcscode", "text")]"
|
||||
winset(editingcode, "tcscode", "is-disabled=false")
|
||||
|
||||
// If the player's not manning the keyboard anymore, adjust everything
|
||||
if(!in_range(editingcode, src) && !issilicon(editingcode) || editingcode.machine != src)
|
||||
winshow(editingcode, "Telecomms IDE", 0) // hide the window!
|
||||
editingcode = null
|
||||
return
|
||||
|
||||
// For other people viewing the typer type code, the input is disabled and they can only view the code
|
||||
// (this is put in place so that there's not any magical shenanigans with 50 people inputting different code all at once)
|
||||
|
||||
if(length(viewingcode))
|
||||
// This piece of code is very important - it escapes quotation marks so string aren't cut off by the input element
|
||||
var/showcode = replacetext(storedcode, "\\\"", "\\\\\"")
|
||||
showcode = replacetext(storedcode, "\"", "\\\"")
|
||||
|
||||
for(var/mob/M in viewingcode)
|
||||
|
||||
if( (M.machine == src && in_range(M, src) ) || issilicon(M))
|
||||
winset(M, "tcscode", "is-disabled=true")
|
||||
winset(M, "tcscode", "text=\"[showcode]\"")
|
||||
|
||||
switch(action)
|
||||
if("refresh_servers")
|
||||
refresh_servers()
|
||||
return TRUE
|
||||
if("toggle_code_execution")
|
||||
var/obj/machinery/telecomms/server/selected_server = locate(params["selected_server"])
|
||||
selected_server.autoruncode = !selected_server.autoruncode
|
||||
return TRUE
|
||||
if("save_code")
|
||||
storedcode = params["saved_code"]
|
||||
return TRUE
|
||||
if("compile_code")
|
||||
if(!user_name)
|
||||
message_admins("[key_name_admin(usr)] attempted compiling NTSL without being logged in.") // tell admins that someone tried a javascript injection
|
||||
return
|
||||
for(var/obj/machinery/telecomms/server/server as anything in servers)
|
||||
server.setcode(storedcode)
|
||||
qdel(compiler_output)
|
||||
compiler_output = compile_all(usr)
|
||||
return TRUE
|
||||
if("set_network")
|
||||
if(!user_name)
|
||||
return
|
||||
network = params["new_network"]
|
||||
return TRUE
|
||||
if("log_in")
|
||||
var/mob/usr_mob = usr
|
||||
if(usr_mob.has_unlimited_silicon_privilege)
|
||||
user_name = "System Administrator"
|
||||
else if(check_access(inserted_id))
|
||||
user_name = "[inserted_id?.registered_name] ([inserted_id?.assignment])"
|
||||
else
|
||||
viewingcode.Remove(M)
|
||||
winshow(M, "Telecomms IDE", 0) // hide the windows
|
||||
|
||||
|
||||
/obj/machinery/computer/telecomms/traffic/ui_interact(mob/user)
|
||||
if(..())
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = "<HTML><HEAD><meta charset='UTF-8'><TITLE>Telecommunication Traffic Control</TITLE></HEAD><BODY><center><b>Telecommunications Traffic Control</b></center>"
|
||||
dat += "<br><b><font color='[(auth ? "green" : "red")]'>[(auth ? "AUTHED" : "NOT AUTHED")]:</font></b> <A href='?src=\ref[src];auth=1'>[(!auth ? "Insert ID" : auth)]</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];print=1'>View System Log</A><HR>"
|
||||
|
||||
if(issilicon(user) || auth)
|
||||
|
||||
switch(screen)
|
||||
|
||||
|
||||
// --- Main Menu ---
|
||||
|
||||
if(0)
|
||||
dat += "<br>[temp]<br>"
|
||||
dat += "<br>Current Network: <a href='?src=\ref[src];network=1'>[network]</a><br>"
|
||||
if(servers.len)
|
||||
dat += "<br>Detected Telecommunication Servers:<ul>"
|
||||
for(var/obj/machinery/telecomms/T in servers)
|
||||
dat += "<li><a href='?src=\ref[src];viewserver=[T.id]'>\ref[T] [T.name]</a> ([T.id])</li>"
|
||||
dat += "</ul>"
|
||||
dat += "<br><a href='?src=\ref[src];operation=release'>\[Flush Buffer\]</a>"
|
||||
|
||||
else
|
||||
dat += "<br>No servers detected. Scan for servers: <a href='?src=\ref[src];operation=scan'>\[Scan\]</a>"
|
||||
|
||||
|
||||
// --- Viewing Server ---
|
||||
|
||||
if(1)
|
||||
if(SelectedServer)
|
||||
dat += "<br>[temp]<br>"
|
||||
dat += "<center><a href='?src=\ref[src];operation=mainmenu'>\[Main Menu\]</a> <a href='?src=\ref[src];operation=refresh'>\[Refresh\]</a></center>"
|
||||
dat += "<br>Current Network: [network]"
|
||||
dat += "<br>Selected Server: [SelectedServer.id]"
|
||||
dat += "<br><br>"
|
||||
dat += "<br><a href='?src=\ref[src];operation=editcode'>\[Edit Code\]</a>"
|
||||
dat += "<br>Signal Execution: "
|
||||
if(SelectedServer.autoruncode)
|
||||
dat += "<a href='?src=\ref[src];operation=togglerun'>ALWAYS</a>"
|
||||
else
|
||||
dat += "<a href='?src=\ref[src];operation=togglerun'>NEVER</a>"
|
||||
else
|
||||
screen = 0
|
||||
var/obj/item/card/id/user_id = usr_mob.get_idcard(TRUE)
|
||||
if(!check_access(user_id))
|
||||
return
|
||||
user_name = "[user_id?.registered_name] ([user_id?.assignment])"
|
||||
create_log("has logged in.")
|
||||
return TRUE
|
||||
if("log_out")
|
||||
if(obj_flags & EMAGGED)
|
||||
return TRUE
|
||||
create_log("has logged out.")
|
||||
user_name = null
|
||||
return TRUE
|
||||
if("clear_logs")
|
||||
if(!user_name)
|
||||
message_admins("[key_name_admin(usr)] attempted clearing NTSL logs without being logged in.")
|
||||
return
|
||||
qdel(access_log)
|
||||
access_log = list()
|
||||
create_log("cleared access logs.")
|
||||
return TRUE
|
||||
|
||||
dat += "</BODY></HTML>"
|
||||
user << browse(dat, "window=traffic_control;size=575x400")
|
||||
onclose(user, "server_control")
|
||||
/obj/machinery/computer/telecomms/traffic/ui_close(mob/user)
|
||||
return ..()
|
||||
|
||||
temp = ""
|
||||
return
|
||||
/obj/machinery/computer/telecomms/traffic/proc/refresh_servers()
|
||||
qdel(servers)
|
||||
servers = list()
|
||||
for(var/obj/machinery/telecomms/server/new_server as anything in GLOB.tcomms_servers)
|
||||
if(new_server.network != network)
|
||||
continue
|
||||
if(!unlimited_range && get_dist(src, new_server))
|
||||
continue
|
||||
servers.Add(new_server)
|
||||
|
||||
/obj/machinery/computer/telecomms/traffic/proc/create_log(entry, mob/user)
|
||||
var/id = null
|
||||
if(issilicon(user) || isAI(user))
|
||||
id = "System Administrator"
|
||||
else if(ispAI(user))
|
||||
id = "[user.name] (pAI)"
|
||||
else
|
||||
if(auth)
|
||||
id = "[auth.registered_name] ([auth.assignment])"
|
||||
else
|
||||
return
|
||||
access_log += "\[[get_timestamp()]\] [id] [entry]"
|
||||
/obj/machinery/computer/telecomms/traffic/proc/compile_all(mob/user)
|
||||
if(is_banned_from(user.ckey, "Network Admin"))
|
||||
return list("You are banned from using NTSL.")
|
||||
if(!servers.len)
|
||||
return list("No servers detected.")
|
||||
for(var/obj/machinery/telecomms/server/server as anything in servers)
|
||||
var/list/compile_errors = server.compile(user)
|
||||
if(!compile_errors)
|
||||
return list("A fatal error has occured. Please contact your local network adminstrator.")
|
||||
if(istext(compile_errors))
|
||||
return splittext(compile_errors, "\n")
|
||||
var/list/text_list = list()
|
||||
for(var/datum/scriptError/error in compile_errors)
|
||||
text_list.Add(error.message)
|
||||
if(text_list.len)
|
||||
return text_list
|
||||
create_log("compiled to all linked servers on [network].")
|
||||
return list("Compiling finished.")
|
||||
|
||||
/obj/machinery/computer/telecomms/traffic/proc/print_logs()
|
||||
. = "<HTML><HEAD><meta charset='UTF-8'></HEAD><BODY><center><h2>Traffic Control Telecomms System Log</h2></center><HR>"
|
||||
for(var/entry in access_log)
|
||||
. += entry + "<BR>"
|
||||
. += "</BODY></HTML>"
|
||||
return .
|
||||
|
||||
/obj/machinery/computer/telecomms/traffic/Topic(href, href_list)
|
||||
if(..())
|
||||
/obj/machinery/computer/telecomms/traffic/attackby(obj/item/item, mob/user, params)
|
||||
if(istype(item, /obj/item/card/id) && check_access(item) && user.transferItemToLoc(item, src))
|
||||
inserted_id = item
|
||||
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
|
||||
return
|
||||
|
||||
|
||||
add_fingerprint(usr)
|
||||
usr.set_machine(src)
|
||||
|
||||
if(href_list["auth"])
|
||||
if(iscarbon(usr))
|
||||
var/mob/living/carbon/C = usr
|
||||
if(!auth)
|
||||
var/obj/item/card/id/I = C.get_active_held_item()
|
||||
if(istype(I))
|
||||
if(check_access(I))
|
||||
if(!C.transferItemToLoc(I, src))
|
||||
return
|
||||
auth = I
|
||||
create_log("has logged in.", usr)
|
||||
else
|
||||
create_log("has logged out.", usr)
|
||||
auth.loc = src.loc
|
||||
C.put_in_hands(auth)
|
||||
auth = null
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
if(href_list["print"])
|
||||
usr << browse(print_logs(), "window=traffic_logs")
|
||||
return
|
||||
|
||||
if(!auth && !issilicon(usr) && !emagged)
|
||||
to_chat(usr, span_danger("ACCESS DENIED."))
|
||||
return
|
||||
|
||||
if(href_list["viewserver"])
|
||||
screen = 1
|
||||
for(var/obj/machinery/telecomms/T in servers)
|
||||
if(T.id == href_list["viewserver"])
|
||||
SelectedServer = T
|
||||
create_log("selected server [T.name]", usr)
|
||||
break
|
||||
if(href_list["operation"])
|
||||
create_log("has performed action: [href_list["operation"]].", usr)
|
||||
switch(href_list["operation"])
|
||||
|
||||
if("release")
|
||||
servers = list()
|
||||
screen = 0
|
||||
|
||||
if("mainmenu")
|
||||
screen = 0
|
||||
|
||||
if("scan")
|
||||
if(servers.len > 0)
|
||||
temp = "<font color = #D70B00>- FAILED: CANNOT PROBE WHEN BUFFER FULL -</font color>"
|
||||
|
||||
else
|
||||
if(unlimited_range)
|
||||
for(var/obj/machinery/telecomms/server/T as anything in GLOB.tcomms_servers)
|
||||
if(T.network == network)
|
||||
servers.Add(T)
|
||||
else
|
||||
for(var/obj/machinery/telecomms/server/T in range(25, src))
|
||||
if(T.network == network)
|
||||
servers.Add(T)
|
||||
|
||||
if(!servers.len)
|
||||
temp = "<font color = #D70B00>- FAILED: UNABLE TO LOCATE SERVERS IN \[[network]\] -</font color>"
|
||||
else
|
||||
temp = "<font color = #336699>- [servers.len] SERVERS PROBED & BUFFERED -</font color>"
|
||||
|
||||
screen = 0
|
||||
|
||||
if("editcode")
|
||||
if(is_banned_from(usr.ckey, "Network Admin"))
|
||||
to_chat(usr, span_warning("You are banned from using NTSL."))
|
||||
return
|
||||
if(editingcode == usr)
|
||||
return
|
||||
if(usr in viewingcode)
|
||||
return
|
||||
if(!editingcode)
|
||||
lasteditor = usr
|
||||
editingcode = usr
|
||||
winshow(editingcode, "Telecomms IDE", 1) // show the IDE
|
||||
winset(editingcode, "tcscode", "is-disabled=false")
|
||||
winset(editingcode, "tcscode", "text=\"\"")
|
||||
var/showcode = replacetext(storedcode, "\\\"", "\\\\\"")
|
||||
showcode = replacetext(storedcode, "\"", "\\\"")
|
||||
winset(editingcode, "tcscode", "text=\"[showcode]\"")
|
||||
|
||||
else
|
||||
viewingcode.Add(usr)
|
||||
winshow(usr, "Telecomms IDE", 1) // show the IDE
|
||||
winset(usr, "tcscode", "is-disabled=true")
|
||||
winset(editingcode, "tcscode", "text=\"\"")
|
||||
var/showcode = replacetext(storedcode, "\"", "\\\"")
|
||||
winset(usr, "tcscode", "text=\"[showcode]\"")
|
||||
|
||||
if("togglerun")
|
||||
SelectedServer.autoruncode = !(SelectedServer.autoruncode)
|
||||
|
||||
if(href_list["network"])
|
||||
|
||||
var/newnet = stripped_input(usr, "Which network do you want to view?", "Comm Monitor", network)
|
||||
|
||||
if(newnet && canAccess(usr))
|
||||
if(length(newnet) > 15)
|
||||
temp = "<font color = #D70B00>- FAILED: NETWORK TAG STRING TOO LONG -</font color>"
|
||||
|
||||
else
|
||||
|
||||
network = newnet
|
||||
screen = 0
|
||||
servers = list()
|
||||
temp = "<font color = #336699>- NEW NETWORK TAG SET IN ADDRESS \[[network]\] -</font color>"
|
||||
create_log("has set the network to [network].", usr)
|
||||
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/telecomms/traffic/attackby(obj/O, mob/user, params)
|
||||
src.updateUsrDialog()
|
||||
if(istype(O, /obj/item/card/id) && check_access(O) && user.transferItemToLoc(O, src))
|
||||
auth = O
|
||||
create_log("has logged in.", usr)
|
||||
else
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/telecomms/traffic/emag_act(mob/user, obj/item/card/emag/emag_card)
|
||||
if(emagged)
|
||||
if(obj_flags & EMAGGED)
|
||||
return FALSE
|
||||
obj_flags |= EMAGGED
|
||||
user_name = "System Administrator"
|
||||
create_log("has logged in.")
|
||||
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
|
||||
emagged = TRUE
|
||||
to_chat(user, span_notice("You you disable the security protocols."))
|
||||
|
||||
/obj/machinery/computer/telecomms/traffic/proc/canAccess(mob/user)
|
||||
if(issilicon(user) || in_range(user, src))
|
||||
return 1
|
||||
return 0
|
||||
to_chat(user, span_notice("You bypass the console's security protocols."))
|
||||
|
||||
/obj/machinery/computer/telecomms/traffic/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(!user.canUseTopic(src, BE_CLOSE))
|
||||
return
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
if(!auth)
|
||||
var/obj/item/card/id/I = C.get_active_held_item()
|
||||
if(istype(I))
|
||||
if(check_access(I))
|
||||
if(!C.transferItemToLoc(I, src))
|
||||
return
|
||||
auth = I
|
||||
create_log("has logged in.", user)
|
||||
else
|
||||
create_log("has logged out.", user)
|
||||
auth.forceMove(drop_location())
|
||||
C.put_in_hands(auth)
|
||||
auth = null
|
||||
updateUsrDialog()
|
||||
return
|
||||
var/mob/living/carbon/carbon_user = user
|
||||
if(inserted_id)
|
||||
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
|
||||
inserted_id.forceMove(drop_location())
|
||||
carbon_user.put_in_hands(inserted_id)
|
||||
inserted_id = null
|
||||
|
||||
@@ -1,241 +0,0 @@
|
||||
/client/verb/tcssave()
|
||||
set hidden = 1
|
||||
|
||||
if(is_banned_from(usr.ckey, "Network Admin"))
|
||||
to_chat(usr, span_warning("You are banned from using NTSL."))
|
||||
return
|
||||
if(!mob.machine && !issilicon(mob))
|
||||
src << output(null, "tcserror")
|
||||
src << output("<font color = red>Failed to save: Unable to locate machine. (Back up your code before exiting the window!)</font color>", "tcserror")
|
||||
if(!telecomms_check(mob))
|
||||
src << output(null, "tcserror")
|
||||
src << output("<font color = red>Failed to save: Unable to locate machine. (Back up your code before exiting the window!)</font color>", "tcserror")
|
||||
return
|
||||
var/obj/machinery/computer/telecomms/traffic/Machine = mob.machine
|
||||
if(Machine.editingcode != mob)
|
||||
return
|
||||
|
||||
if(Machine.SelectedServer)
|
||||
var/obj/machinery/telecomms/server/Server = Machine.SelectedServer
|
||||
var/tcscode=winget(src, "tcscode", "text")
|
||||
Server.setcode( tcscode ) // this actually saves the code from input to the server
|
||||
src << output(null, "tcserror") // clear the errors
|
||||
else
|
||||
src << output(null, "tcserror")
|
||||
src << output("<font color = red>Failed to save: Unable to locate server machine. (Back up your code before exiting the window!)</font color>", "tcserror")
|
||||
|
||||
/client/verb/tcscompile()
|
||||
set hidden = 1
|
||||
|
||||
if(is_banned_from(usr.ckey, "Network Admin"))
|
||||
to_chat(usr, span_warning("You are banned from using NTSL."))
|
||||
return
|
||||
if(!mob.machine && !issilicon(mob))
|
||||
src << output(null, "tcserror")
|
||||
src << output("<font color = red>Failed to compile: Unable to locate machine. (Back up your code before exiting the window!)</font color>", "tcserror")
|
||||
return
|
||||
if(!telecomms_check(mob))
|
||||
src << output(null, "tcserror")
|
||||
src << output("<font color = red>Failed to compile: Unable to locate machine. (Back up your code before exiting the window!)</font color>", "tcserror")
|
||||
return
|
||||
var/obj/machinery/computer/telecomms/traffic/Machine = mob.machine
|
||||
if(Machine.editingcode != mob)
|
||||
return
|
||||
if(!Machine.SelectedServer)
|
||||
src << output(null, "tcserror")
|
||||
src << output("<font color = red>Failed to compile: Unable to locate server machine. (Back up your code before exiting the window!)</font color>", "tcserror")
|
||||
return
|
||||
|
||||
var/obj/machinery/telecomms/server/Server = Machine.SelectedServer
|
||||
Server.setcode( winget(src, "tcscode", "text") ) // save code first
|
||||
|
||||
spawn(0)
|
||||
// Output all the compile-time errors
|
||||
src << output(null, "tcserror")
|
||||
src << output("Compiling on [Server.name]...", "tcserror")
|
||||
|
||||
var/list/compileerrors = Server.compile(mob) // then compile the code! this can return a string or a list.
|
||||
if(!telecomms_check(mob))
|
||||
return
|
||||
|
||||
if(!compileerrors)
|
||||
src << output("<b>NTSL.exe Error</b>", "tcserror")
|
||||
src << output("<font color = red>\t><b>A fatal error has occured. Please contact your local network adminstrator.</b></font color>", "tcserror")
|
||||
else if(istext(compileerrors))
|
||||
src << output("<b>NTSL.exe Error</b>", "tcserror")
|
||||
src << output("<font color = red>\t><b>[compileerrors]</b></font color>", "tcserror")
|
||||
else if(length(compileerrors))
|
||||
src << output("<b>Compile Errors</b>", "tcserror")
|
||||
var/i = 1
|
||||
for(var/datum/scriptError/e in compileerrors)
|
||||
if(i) //. Bold the first one, since it's probably important
|
||||
src << output("<font color = red>\t><b>[e.message]</b></font color>", "tcserror")
|
||||
i = 0
|
||||
else
|
||||
src << output("<font color = red>\t>[e.message]</font color>", "tcserror")
|
||||
src << output("([compileerrors.len] errors)", "tcserror")
|
||||
|
||||
// Output compile errors to all other people viewing the code too
|
||||
for(var/mob/M in Machine.viewingcode)
|
||||
if(M.client)
|
||||
M << output(null, "tcserror")
|
||||
M << output("<b>Compile Errors</b>", "tcserror")
|
||||
i = 1 //. Still using var/i from above
|
||||
for(var/datum/scriptError/e in compileerrors)
|
||||
if(i)
|
||||
M << output("<font color = red>\t><b>[e.message]</b></font color>", "tcserror")
|
||||
i = 0
|
||||
else
|
||||
M << output("<font color = red>\t>[e.message]</font color>", "tcserror")
|
||||
M << output("([compileerrors.len] errors)", "tcserror")
|
||||
|
||||
|
||||
else // Returned a blank list, means no errors.
|
||||
src << output("<font color = blue>TCS compilation successful!</font color>", "tcserror")
|
||||
src << output("Time of compile: [gameTimestamp("hh:mm:ss")]","tcserror")
|
||||
//. ^ To make it obvious that it's done a new compile
|
||||
src << output("(0 errors)", "tcserror")
|
||||
|
||||
for(var/mob/M in Machine.viewingcode)
|
||||
if(M.client)
|
||||
M << output("<font color = blue>TCS compilation successful!</font color>", "tcserror")
|
||||
M << output("Time of compile: [gameTimestamp("hh:mm:ss")]","tcserror")
|
||||
M << output("(0 errors)", "tcserror")
|
||||
if(Server.compile_warnings.len)
|
||||
src << output("<b>Compile Warnings</b>", "tcserror")
|
||||
for(var/datum/scriptError/e in Server.compile_warnings)
|
||||
src << output("<font color = yellow>\t>[e.message]</font color>", "tcserror")
|
||||
src << output("([Server.compile_warnings.len] warnings)", "tcserror")
|
||||
for(var/fuck_you_for_making_me_do_this_altoids in Machine.viewingcode)
|
||||
var/mob/M = fuck_you_for_making_me_do_this_altoids
|
||||
if(M.client)
|
||||
M << output("<b>Compile Warnings</b>", "tcserror")
|
||||
for(var/datum/scriptError/e in Server.compile_warnings)
|
||||
M << output("<font color = yellow>\t>[e.message]</font color>", "tcserror")
|
||||
M << output("([Server.compile_warnings.len] warnings)", "tcserror")
|
||||
|
||||
/client/verb/tcsrun()
|
||||
set hidden = 1
|
||||
|
||||
if(is_banned_from(usr.ckey, "Network Admin"))
|
||||
to_chat(usr, span_warning("You are banned from using NTSL."))
|
||||
return
|
||||
if(!mob.machine && !issilicon(mob))
|
||||
src << output(null, "tcserror")
|
||||
src << output("<font color = red>Failed to run: Unable to locate machine. (Back up your code before exiting the window!)</font color>", "tcserror")
|
||||
return
|
||||
if(!telecomms_check(mob))
|
||||
src << output(null, "tcserror")
|
||||
src << output("<font color = red>Failed to run: Unable to locate machine. (Back up your code before exiting the window!)</font color>", "tcserror")
|
||||
return
|
||||
var/obj/machinery/computer/telecomms/traffic/Machine = mob.machine
|
||||
if(Machine.editingcode != mob)
|
||||
return
|
||||
if(!Machine.SelectedServer)
|
||||
src << output(null, "tcserror")
|
||||
src << output("<font color = red>Failed to run: Unable to locate server machine. (Back up your code before exiting the window!)</font color>", "tcserror")
|
||||
return
|
||||
|
||||
var/obj/machinery/telecomms/server/Server = Machine.SelectedServer
|
||||
var/datum/signal/signal = new()
|
||||
signal.data["message"] = ""
|
||||
if(Server.freq_listening.len > 0)
|
||||
signal.frequency = Server.freq_listening[1]
|
||||
else
|
||||
signal.frequency = 1459
|
||||
signal.data["name"] = ""
|
||||
signal.data["job"] = ""
|
||||
signal.data["reject"] = FALSE
|
||||
signal.data["server"] = Server
|
||||
Server.Compiler.Run(signal)
|
||||
|
||||
/client/verb/exittcs()
|
||||
set hidden = 1
|
||||
|
||||
if(is_banned_from(usr.ckey, "Network Admin"))
|
||||
to_chat(usr, span_warning("You are banned from using NTSL."))
|
||||
return
|
||||
if(!mob.machine && !issilicon(mob))
|
||||
return
|
||||
if(!telecomms_check(mob))
|
||||
return
|
||||
var/obj/machinery/computer/telecomms/traffic/Machine = mob.machine
|
||||
if(Machine.editingcode == mob)
|
||||
Machine.storedcode = "[winget(mob, "tcscode", "text")]"
|
||||
Machine.editingcode = null
|
||||
else if(mob in Machine.viewingcode)
|
||||
Machine.viewingcode.Remove(mob)
|
||||
|
||||
/client/verb/tcsrevert()
|
||||
set hidden = 1
|
||||
|
||||
if(is_banned_from(usr.ckey, "Network Admin"))
|
||||
to_chat(usr, span_warning("You are banned from using NTSL."))
|
||||
return
|
||||
if(!mob.machine && !issilicon(mob))
|
||||
src << output(null, "tcserror")
|
||||
src << output("<font color = red>Failed to revert: Unable to locate machine.</font color>", "tcserror")
|
||||
return
|
||||
if(!telecomms_check(mob))
|
||||
src << output(null, "tcserror")
|
||||
src << output("<font color = red>Failed to revert: Unable to locate machine.</font color>", "tcserror")
|
||||
return
|
||||
var/obj/machinery/computer/telecomms/traffic/Machine = mob.machine
|
||||
if(Machine.editingcode != mob)
|
||||
return
|
||||
if(!Machine.SelectedServer)
|
||||
src << output(null, "tcserror")
|
||||
src << output("<font color = red>Failed to revert: Unable to locate server machine.</font color>", "tcserror")
|
||||
return
|
||||
|
||||
var/obj/machinery/telecomms/server/Server = Machine.SelectedServer
|
||||
// Replace quotation marks with quotation macros for proper winset() compatibility
|
||||
var/showcode = replacetext(Server.rawcode, "\\\"", "\\\\\"")
|
||||
showcode = replacetext(showcode, "\"", "\\\"")
|
||||
winset(mob, "tcscode", "text=\"[showcode]\"")
|
||||
src << output(null, "tcserror") // clear the errors
|
||||
|
||||
/client/verb/tcsclearmem()
|
||||
set hidden = 1
|
||||
|
||||
if(is_banned_from(usr.ckey, "Network Admin"))
|
||||
to_chat(usr, span_warning("You are banned from using NTSL."))
|
||||
return
|
||||
if(!mob.machine && !issilicon(mob))
|
||||
src << output(null, "tcserror")
|
||||
src << output("<font color = red>Failed to clear memory: Unable to locate machine.</font color>", "tcserror")
|
||||
return
|
||||
if(!telecomms_check(mob))
|
||||
src << output(null, "tcserror")
|
||||
src << output("<font color = red>Failed to clear memory: Unable to locate machine.</font color>", "tcserror")
|
||||
return
|
||||
var/obj/machinery/computer/telecomms/traffic/Machine = mob.machine
|
||||
if(Machine.editingcode != mob)
|
||||
return
|
||||
if(!Machine.SelectedServer)
|
||||
src << output(null, "tcserror")
|
||||
src << output("<font color = red>Failed to clear memory: Unable to locate server machine.</font color>", "tcserror")
|
||||
return
|
||||
|
||||
var/obj/machinery/telecomms/server/Server = Machine.SelectedServer
|
||||
Server.memory = list() // clear the memory
|
||||
// Show results
|
||||
//// Write shitty code comments
|
||||
src << output(null, "tcserror")
|
||||
src << output("<font color = blue>Server memory cleared!</font color>", "tcserror")
|
||||
for(var/mob/M in Machine.viewingcode)
|
||||
if(M.client)
|
||||
M << output("<font color = blue>Server memory cleared!</font color>", "tcserror")
|
||||
|
||||
/**
|
||||
* Checks to see if 'mob_checking''s machine is a traffic control computer they can access.
|
||||
*/
|
||||
/proc/telecomms_check(mob/mob_checking)
|
||||
if(!mob_checking)
|
||||
return FALSE
|
||||
if(!istype(mob_checking.machine, /obj/machinery/computer/telecomms/traffic))
|
||||
return FALSE
|
||||
if(!issilicon(mob_checking) && !in_range(mob_checking.machine, mob_checking))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
Reference in New Issue
Block a user