mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 10:21:11 +00:00
Update NTSL from /tg/.
This commit is contained in:
@@ -226,6 +226,12 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
|
|||||||
|
|
||||||
var/list/obj/item/device/radio/radios = list()
|
var/list/obj/item/device/radio/radios = list()
|
||||||
|
|
||||||
|
// Cut down on the message sizes.
|
||||||
|
|
||||||
|
message = copytext(message, 1, MAX_BROADCAST_LEN)
|
||||||
|
vmessage = copytext(vmessage, 1, MAX_BROADCAST_LEN)
|
||||||
|
|
||||||
|
|
||||||
// --- Broadcast only to intercom devices ---
|
// --- Broadcast only to intercom devices ---
|
||||||
|
|
||||||
if(data == 1)
|
if(data == 1)
|
||||||
|
|||||||
@@ -59,8 +59,10 @@
|
|||||||
del(A)
|
del(A)
|
||||||
construct_op --
|
construct_op --
|
||||||
stat &= ~BROKEN // the machine's not borked anymore!
|
stat &= ~BROKEN // the machine's not borked anymore!
|
||||||
|
else
|
||||||
|
user << "You need more cable"
|
||||||
if(istype(P, /obj/item/weapon/crowbar))
|
if(istype(P, /obj/item/weapon/crowbar))
|
||||||
user << "You begin prying out the circuit board other components..."
|
user << "You begin prying out the circuit board and components..."
|
||||||
playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
|
playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
|
||||||
if(do_after(user,60))
|
if(do_after(user,60))
|
||||||
user << "You finish prying out the components."
|
user << "You finish prying out the components."
|
||||||
@@ -275,14 +277,13 @@
|
|||||||
|
|
||||||
|
|
||||||
/obj/machinery/telecomms/Topic(href, href_list)
|
/obj/machinery/telecomms/Topic(href, href_list)
|
||||||
|
if(..())
|
||||||
|
return
|
||||||
|
|
||||||
if(!issilicon(usr))
|
if(!issilicon(usr))
|
||||||
if(!istype(usr.get_active_hand(), /obj/item/device/multitool))
|
if(!istype(usr.get_active_hand(), /obj/item/device/multitool))
|
||||||
return
|
return
|
||||||
|
|
||||||
if(stat & (BROKEN|NOPOWER))
|
|
||||||
return
|
|
||||||
|
|
||||||
var/obj/item/device/multitool/P = get_multitool(usr)
|
var/obj/item/device/multitool/P = get_multitool(usr)
|
||||||
|
|
||||||
if(href_list["input"])
|
if(href_list["input"])
|
||||||
@@ -343,13 +344,17 @@
|
|||||||
|
|
||||||
if(text2num(href_list["unlink"]) <= length(links))
|
if(text2num(href_list["unlink"]) <= length(links))
|
||||||
var/obj/machinery/telecomms/T = links[text2num(href_list["unlink"])]
|
var/obj/machinery/telecomms/T = links[text2num(href_list["unlink"])]
|
||||||
temp = "<font color = #666633>-% Removed \ref[T] [T.name] from linked entities. %-</font color>"
|
if(T)
|
||||||
|
temp = "<font color = #666633>-% Removed \ref[T] [T.name] from linked entities. %-</font color>"
|
||||||
|
|
||||||
// Remove link entries from both T and src.
|
// Remove link entries from both T and src.
|
||||||
|
|
||||||
if(src in T.links)
|
if(T.links)
|
||||||
T.links.Remove(src)
|
T.links.Remove(src)
|
||||||
links.Remove(T)
|
links.Remove(T)
|
||||||
|
|
||||||
|
else
|
||||||
|
temp = "<font color = #666633>-% Unable to locate machine to unlink from, try again. %-</font color>"
|
||||||
|
|
||||||
if(href_list["link"])
|
if(href_list["link"])
|
||||||
|
|
||||||
@@ -380,7 +385,6 @@
|
|||||||
src.Options_Topic(href, href_list)
|
src.Options_Topic(href, href_list)
|
||||||
|
|
||||||
usr.set_machine(src)
|
usr.set_machine(src)
|
||||||
src.add_fingerprint(usr)
|
|
||||||
|
|
||||||
updateUsrDialog()
|
updateUsrDialog()
|
||||||
|
|
||||||
|
|||||||
@@ -125,9 +125,13 @@
|
|||||||
//Servers
|
//Servers
|
||||||
|
|
||||||
/obj/machinery/telecomms/server/presets
|
/obj/machinery/telecomms/server/presets
|
||||||
|
|
||||||
network = "tcommsat"
|
network = "tcommsat"
|
||||||
|
|
||||||
|
/obj/machinery/telecomms/server/presets/New()
|
||||||
|
..()
|
||||||
|
name = id
|
||||||
|
|
||||||
|
|
||||||
/obj/machinery/telecomms/server/presets/science
|
/obj/machinery/telecomms/server/presets/science
|
||||||
id = "Science Server"
|
id = "Science Server"
|
||||||
freq_listening = list(1351)
|
freq_listening = list(1351)
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
|
|||||||
copy.data["original"] = signal.data["original"]
|
copy.data["original"] = signal.data["original"]
|
||||||
|
|
||||||
else
|
else
|
||||||
del(copy)
|
copy = null
|
||||||
|
|
||||||
|
|
||||||
send_count++
|
send_count++
|
||||||
@@ -167,10 +167,11 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
|
|||||||
var/turf/position = get_turf(src)
|
var/turf/position = get_turf(src)
|
||||||
var/turf/T_position = get_turf(T)
|
var/turf/T_position = get_turf(T)
|
||||||
if((position.z == T_position.z) || (src.long_range_link && T.long_range_link))
|
if((position.z == T_position.z) || (src.long_range_link && T.long_range_link))
|
||||||
for(var/x in autolinkers)
|
if(src != T)
|
||||||
if(T.autolinkers.Find(x))
|
for(var/x in autolinkers)
|
||||||
if(src != T)
|
if(x in T.autolinkers)
|
||||||
links |= T
|
links |= T
|
||||||
|
break
|
||||||
|
|
||||||
/obj/machinery/telecomms/update_icon()
|
/obj/machinery/telecomms/update_icon()
|
||||||
if(on)
|
if(on)
|
||||||
@@ -519,6 +520,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
|
|||||||
// would add up to md5("password123comsat")
|
// would add up to md5("password123comsat")
|
||||||
var/language = "human"
|
var/language = "human"
|
||||||
var/obj/item/device/radio/headset/server_radio = null
|
var/obj/item/device/radio/headset/server_radio = null
|
||||||
|
var/last_signal = 0 // Last time it sent a signal
|
||||||
|
|
||||||
/obj/machinery/telecomms/server/New()
|
/obj/machinery/telecomms/server/New()
|
||||||
..()
|
..()
|
||||||
@@ -526,6 +528,13 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
|
|||||||
Compiler.Holder = src
|
Compiler.Holder = src
|
||||||
server_radio = new()
|
server_radio = new()
|
||||||
|
|
||||||
|
/obj/machinery/telecomms/server/Del()
|
||||||
|
// Garbage collects all the NTSL datums.
|
||||||
|
if(Compiler)
|
||||||
|
Compiler.GC()
|
||||||
|
Compiler = null
|
||||||
|
..()
|
||||||
|
|
||||||
/obj/machinery/telecomms/server/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from)
|
/obj/machinery/telecomms/server/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from)
|
||||||
|
|
||||||
if(signal.data["message"])
|
if(signal.data["message"])
|
||||||
@@ -593,8 +602,19 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
|
|||||||
if(istext(t))
|
if(istext(t))
|
||||||
rawcode = t
|
rawcode = t
|
||||||
|
|
||||||
/obj/machinery/telecomms/server/proc/compile()
|
/obj/machinery/telecomms/server/proc/admin_log(var/mob/mob)
|
||||||
|
|
||||||
|
var/msg="[mob.name] has compiled a script to server [src]:"
|
||||||
|
diary << msg
|
||||||
|
diary << rawcode
|
||||||
|
src.investigate_log("[msg]<br>[rawcode]", "ntsl")
|
||||||
|
if(length(rawcode)) // Let's not bother the admins for empty code.
|
||||||
|
message_admins("[mob.real_name] ([mob.key]) has compiled and uploaded a NTLS script to [src.id] ([mob.x],[mob.y],[mob.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[mob.x];Y=[mob.y];Z=[mob.z]'>JMP</a>)",0,1)
|
||||||
|
|
||||||
|
/obj/machinery/telecomms/server/proc/compile(var/mob/user)
|
||||||
|
|
||||||
if(Compiler)
|
if(Compiler)
|
||||||
|
admin_log(user)
|
||||||
return Compiler.Compile(rawcode)
|
return Compiler.Compile(rawcode)
|
||||||
|
|
||||||
/obj/machinery/telecomms/server/proc/update_logs()
|
/obj/machinery/telecomms/server/proc/update_logs()
|
||||||
|
|||||||
@@ -19,62 +19,81 @@
|
|||||||
var/temp = "" // temporary feedback messages
|
var/temp = "" // temporary feedback messages
|
||||||
|
|
||||||
var/storedcode = "" // code stored
|
var/storedcode = "" // code stored
|
||||||
|
var/obj/item/weapon/card/id/auth = null
|
||||||
|
var/list/access_log = list()
|
||||||
proc/update_ide()
|
var/process = 0
|
||||||
|
|
||||||
// loop if there's someone manning the keyboard
|
|
||||||
while(editingcode)
|
|
||||||
if(!editingcode.client)
|
|
||||||
editingcode = null
|
|
||||||
break
|
|
||||||
|
|
||||||
// For the typer, the input is enabled. Buffer the typed text
|
|
||||||
if(editingcode)
|
|
||||||
storedcode = "[winget(editingcode, "tcscode", "text")]"
|
|
||||||
if(editingcode) // double if's to work around a runtime error
|
|
||||||
winset(editingcode, "tcscode", "is-disabled=false")
|
|
||||||
|
|
||||||
// If the player's not manning the keyboard anymore, adjust everything
|
|
||||||
if( (!(editingcode in range(1, src)) && !issilicon(editingcode)) || (editingcode.machine != src && !issilicon(editingcode)))
|
|
||||||
if(editingcode)
|
|
||||||
winshow(editingcode, "Telecomms IDE", 0) // hide the window!
|
|
||||||
editingcode = null
|
|
||||||
break
|
|
||||||
|
|
||||||
// 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 && M in view(1, src) ) || issilicon(M))
|
|
||||||
winset(M, "tcscode", "is-disabled=true")
|
|
||||||
winset(M, "tcscode", "text=\"[showcode]\"")
|
|
||||||
else
|
|
||||||
viewingcode.Remove(M)
|
|
||||||
winshow(M, "Telecomms IDE", 0) // hide the window!
|
|
||||||
|
|
||||||
sleep(5)
|
|
||||||
|
|
||||||
if(length(viewingcode) > 0)
|
|
||||||
editingcode = pick(viewingcode)
|
|
||||||
viewingcode.Remove(editingcode)
|
|
||||||
update_ide()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
req_access = list(access_tcomsat)
|
req_access = list(access_tcomsat)
|
||||||
|
|
||||||
attack_hand(mob/user as mob)
|
/obj/machinery/computer/telecomms/traffic/proc/stop_editing()
|
||||||
if(stat & (BROKEN|NOPOWER))
|
if(editingcode)
|
||||||
return
|
if(editingcode.client)
|
||||||
user.set_machine(src)
|
winshow(editingcode, "Telecomms IDE", 0) // hide the window!
|
||||||
var/dat = "<TITLE>Telecommunication Traffic Control</TITLE><center><b>Telecommunications Traffic Control</b></center>"
|
editingcode.unset_machine()
|
||||||
|
editingcode = null
|
||||||
|
|
||||||
|
/obj/machinery/computer/telecomms/traffic/process()
|
||||||
|
|
||||||
|
if(stat & (NOPOWER|BROKEN))
|
||||||
|
stop_editing()
|
||||||
|
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]\"")
|
||||||
|
else
|
||||||
|
viewingcode.Remove(M)
|
||||||
|
winshow(M, "Telecomms IDE", 0) // hide the windows
|
||||||
|
|
||||||
|
|
||||||
|
/obj/machinery/computer/telecomms/traffic/attack_hand(mob/user as mob)
|
||||||
|
if(stat & (BROKEN|NOPOWER))
|
||||||
|
return
|
||||||
|
user.set_machine(src)
|
||||||
|
var/dat = "<TITLE>Telecommunication Traffic Control</TITLE><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.registered_name)]</A><BR>"
|
||||||
|
dat += "<A href='?src=\ref[src];print=1'>View System Log</A><HR>"
|
||||||
|
|
||||||
|
if(issilicon(user) || auth)
|
||||||
|
|
||||||
switch(screen)
|
switch(screen)
|
||||||
|
|
||||||
@@ -98,145 +117,196 @@
|
|||||||
// --- Viewing Server ---
|
// --- Viewing Server ---
|
||||||
|
|
||||||
if(1)
|
if(1)
|
||||||
dat += "<br>[temp]<br>"
|
if(SelectedServer)
|
||||||
dat += "<center><a href='?src=\ref[src];operation=mainmenu'>\[Main Menu\]</a> <a href='?src=\ref[src];operation=refresh'>\[Refresh\]</a></center>"
|
dat += "<br>[temp]<br>"
|
||||||
dat += "<br>Current Network: [network]"
|
dat += "<center><a href='?src=\ref[src];operation=mainmenu'>\[Main Menu\]</a> <a href='?src=\ref[src];operation=refresh'>\[Refresh\]</a></center>"
|
||||||
dat += "<br>Selected Server: [SelectedServer.id]<br><br>"
|
dat += "<br>Current Network: [network]"
|
||||||
dat += "<br><a href='?src=\ref[src];operation=editcode'>\[Edit Code\]</a>"
|
dat += "<br>Selected Server: [SelectedServer.id]<br><br>"
|
||||||
dat += "<br>Signal Execution: "
|
dat += "<br><a href='?src=\ref[src];operation=editcode'>\[Edit Code\]</a>"
|
||||||
if(SelectedServer.autoruncode)
|
dat += "<br>Signal Execution: "
|
||||||
dat += "<a href='?src=\ref[src];operation=togglerun'>ALWAYS</a>"
|
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
|
else
|
||||||
dat += "<a href='?src=\ref[src];operation=togglerun'>NEVER</a>"
|
screen = 0
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
user << browse(dat, "window=traffic_control;size=575x400")
|
user << browse(dat, "window=traffic_control;size=575x400")
|
||||||
onclose(user, "server_control")
|
onclose(user, "server_control")
|
||||||
|
|
||||||
temp = ""
|
temp = ""
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/machinery/computer/telecomms/traffic/proc/create_log(var/entry, var/mob/user)
|
||||||
|
var/id = null
|
||||||
|
if(issilicon(user))
|
||||||
|
id = "System Administrator"
|
||||||
|
else
|
||||||
|
if(auth)
|
||||||
|
id = "[auth.registered_name] ([auth.assignment])"
|
||||||
|
else
|
||||||
|
error("There is a null auth while the user isn't a silicon! ([user.name], [user.type])")
|
||||||
|
return
|
||||||
|
access_log += "\[[get_timestamp()]\] [id] [entry]"
|
||||||
|
|
||||||
|
/obj/machinery/computer/telecomms/traffic/proc/print_logs()
|
||||||
|
. = "<center><h2>Traffic Control Telecomms System Log</h2></center><HR>"
|
||||||
|
for(var/entry in access_log)
|
||||||
|
. += entry + "<BR>"
|
||||||
|
return .
|
||||||
|
|
||||||
|
/obj/machinery/computer/telecomms/traffic/Topic(href, href_list)
|
||||||
|
if(..())
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
Topic(href, href_list)
|
add_fingerprint(usr)
|
||||||
if(..())
|
usr.set_machine(src)
|
||||||
|
|
||||||
|
if(href_list["auth"])
|
||||||
|
if(iscarbon(usr))
|
||||||
|
var/mob/living/carbon/C = usr
|
||||||
|
if(!auth)
|
||||||
|
var/obj/item/weapon/card/id/I = C.get_active_hand()
|
||||||
|
if(istype(I))
|
||||||
|
if(check_access(I))
|
||||||
|
C.drop_item()
|
||||||
|
I.loc = src
|
||||||
|
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
|
return
|
||||||
|
|
||||||
|
if(href_list["print"])
|
||||||
add_fingerprint(usr)
|
usr << browse(print_logs(), "window=traffic_logs")
|
||||||
usr.set_machine(src)
|
|
||||||
if(!src.allowed(usr) && !emagged)
|
|
||||||
usr << "\red 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
|
|
||||||
break
|
|
||||||
|
|
||||||
if(href_list["operation"])
|
|
||||||
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
|
|
||||||
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(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]\"")
|
|
||||||
spawn()
|
|
||||||
update_ide()
|
|
||||||
|
|
||||||
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"])
|
|
||||||
// Haha what
|
|
||||||
//world.log << "diddly widdly scrub fuck nigger [issilicon(usr)] [istype(usr, /mob/living/silicon)]"
|
|
||||||
var/newnet = input(usr, "Which network do you want to view?", "Comm Monitor", network) as null|text
|
|
||||||
|
|
||||||
if(newnet && ((usr in range(1, src) || issilicon(usr))))
|
|
||||||
if(length(newnet) > 15)
|
|
||||||
temp = "<font color = #D70B00>- FAILED: NETWORK TAG STRING TOO LENGHTLY -</font color>"
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
network = newnet
|
|
||||||
screen = 0
|
|
||||||
servers = list()
|
|
||||||
temp = "<font color = #336699>- NEW NETWORK TAG SET IN ADDRESS \[[network]\] -</font color>"
|
|
||||||
|
|
||||||
updateUsrDialog()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
attackby(var/obj/item/weapon/D as obj, var/mob/user as mob)
|
if(!auth && !issilicon(usr) && !emagged)
|
||||||
if(istype(D, /obj/item/weapon/screwdriver))
|
usr << "\red ACCESS DENIED."
|
||||||
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
|
||||||
if(do_after(user, 20))
|
|
||||||
if (src.stat & BROKEN)
|
|
||||||
user << "\blue The broken glass falls out."
|
|
||||||
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
|
|
||||||
new /obj/item/weapon/shard( src.loc )
|
|
||||||
var/obj/item/weapon/circuitboard/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( A )
|
|
||||||
for (var/obj/C in src)
|
|
||||||
C.loc = src.loc
|
|
||||||
A.circuit = M
|
|
||||||
A.state = 3
|
|
||||||
A.icon_state = "3"
|
|
||||||
A.anchored = 1
|
|
||||||
del(src)
|
|
||||||
else
|
|
||||||
user << "\blue You disconnect the monitor."
|
|
||||||
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
|
|
||||||
var/obj/item/weapon/circuitboard/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( A )
|
|
||||||
for (var/obj/C in src)
|
|
||||||
C.loc = src.loc
|
|
||||||
A.circuit = M
|
|
||||||
A.state = 4
|
|
||||||
A.icon_state = "4"
|
|
||||||
A.anchored = 1
|
|
||||||
del(src)
|
|
||||||
else if(istype(D, /obj/item/weapon/card/emag) && !emagged)
|
|
||||||
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
|
|
||||||
emagged = 1
|
|
||||||
user << "\blue You you disable the security protocols"
|
|
||||||
src.updateUsrDialog()
|
|
||||||
return
|
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
|
||||||
|
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(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 = input(usr, "Which network do you want to view?", "Comm Monitor", network) as null|text
|
||||||
|
|
||||||
|
if(newnet && canAccess(usr))
|
||||||
|
if(length(newnet) > 15)
|
||||||
|
temp = "<font color = #D70B00>- FAILED: NETWORK TAG STRING TOO LENGHTLY -</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(var/obj/item/weapon/D as obj, var/mob/user as mob)
|
||||||
|
if(istype(D, /obj/item/weapon/screwdriver))
|
||||||
|
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||||
|
if(do_after(user, 20))
|
||||||
|
if (src.stat & BROKEN)
|
||||||
|
user << "\blue The broken glass falls out."
|
||||||
|
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
|
||||||
|
new /obj/item/weapon/shard( src.loc )
|
||||||
|
var/obj/item/weapon/circuitboard/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( A )
|
||||||
|
for (var/obj/C in src)
|
||||||
|
C.loc = src.loc
|
||||||
|
A.circuit = M
|
||||||
|
A.state = 3
|
||||||
|
A.icon_state = "3"
|
||||||
|
A.anchored = 1
|
||||||
|
del(src)
|
||||||
|
else
|
||||||
|
user << "\blue You disconnect the monitor."
|
||||||
|
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
|
||||||
|
var/obj/item/weapon/circuitboard/comm_traffic/M = new /obj/item/weapon/circuitboard/comm_traffic( A )
|
||||||
|
for (var/obj/C in src)
|
||||||
|
C.loc = src.loc
|
||||||
|
A.circuit = M
|
||||||
|
A.state = 4
|
||||||
|
A.icon_state = "4"
|
||||||
|
A.anchored = 1
|
||||||
|
del(src)
|
||||||
|
else if(istype(D, /obj/item/weapon/card/emag) && !emagged)
|
||||||
|
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
|
||||||
|
emagged = 1
|
||||||
|
user << "\blue You you disable the security protocols"
|
||||||
|
src.updateUsrDialog()
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/machinery/computer/telecomms/traffic/proc/canAccess(var/mob/user)
|
||||||
|
if(issilicon(user) || in_range(user, src))
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
@@ -69,11 +69,15 @@
|
|||||||
//
|
//
|
||||||
IfStatement
|
IfStatement
|
||||||
var
|
var
|
||||||
|
skip = 0
|
||||||
node
|
node
|
||||||
BlockDefinition
|
BlockDefinition
|
||||||
block
|
block
|
||||||
else_block //may be null
|
else_block //may be null
|
||||||
expression/cond
|
expression/cond
|
||||||
|
statement/else_if
|
||||||
|
|
||||||
|
ElseIf
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Class: WhileLoop
|
Class: WhileLoop
|
||||||
|
|||||||
@@ -60,6 +60,15 @@
|
|||||||
New(name, token/t)
|
New(name, token/t)
|
||||||
message="Function '[name]' defined twice."
|
message="Function '[name]' defined twice."
|
||||||
|
|
||||||
|
ParameterFunction
|
||||||
|
message = "You cannot use a function inside a parameter."
|
||||||
|
|
||||||
|
New(token/t)
|
||||||
|
var/line = "?"
|
||||||
|
if(t)
|
||||||
|
line = t.line
|
||||||
|
message = "[line]: [message]"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Class: runtimeError
|
Class: runtimeError
|
||||||
An error thrown by the interpreter in running the script.
|
An error thrown by the interpreter in running the script.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
client/verb/tcssave()
|
client/verb/tcssave()
|
||||||
set hidden = 1
|
set hidden = 1
|
||||||
if(mob.machine || issilicon(mob))
|
if(mob.machine || issilicon(mob))
|
||||||
if((istype(mob.machine, /obj/machinery/computer/telecomms/traffic) && mob.machine in view(1, mob)) || issilicon(mob))
|
if(telecomms_check(mob))
|
||||||
var/obj/machinery/computer/telecomms/traffic/Machine = mob.machine
|
var/obj/machinery/computer/telecomms/traffic/Machine = mob.machine
|
||||||
if(Machine.editingcode != mob)
|
if(Machine.editingcode != mob)
|
||||||
return
|
return
|
||||||
@@ -9,9 +9,6 @@ client/verb/tcssave()
|
|||||||
if(Machine.SelectedServer)
|
if(Machine.SelectedServer)
|
||||||
var/obj/machinery/telecomms/server/Server = Machine.SelectedServer
|
var/obj/machinery/telecomms/server/Server = Machine.SelectedServer
|
||||||
var/tcscode=winget(src, "tcscode", "text")
|
var/tcscode=winget(src, "tcscode", "text")
|
||||||
var/msg="[mob.name] is adding script to server [Server]: [tcscode]"
|
|
||||||
diary << msg
|
|
||||||
message_admins("[mob.name] has uploaded a NTLS script to [Machine.SelectedServer] ([mob.x],[mob.y],[mob.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[mob.x];Y=[mob.y];Z=[mob.z]'>JMP</a>)",0,1)
|
|
||||||
Server.setcode( tcscode ) // this actually saves the code from input to the server
|
Server.setcode( tcscode ) // this actually saves the code from input to the server
|
||||||
src << output(null, "tcserror") // clear the errors
|
src << output(null, "tcserror") // clear the errors
|
||||||
else
|
else
|
||||||
@@ -28,7 +25,7 @@ client/verb/tcssave()
|
|||||||
client/verb/tcscompile()
|
client/verb/tcscompile()
|
||||||
set hidden = 1
|
set hidden = 1
|
||||||
if(mob.machine || issilicon(mob))
|
if(mob.machine || issilicon(mob))
|
||||||
if((istype(mob.machine, /obj/machinery/computer/telecomms/traffic) && mob.machine in view(1, mob)) || (issilicon(mob) && istype(mob.machine, /obj/machinery/computer/telecomms/traffic) ))
|
if(telecomms_check(mob))
|
||||||
var/obj/machinery/computer/telecomms/traffic/Machine = mob.machine
|
var/obj/machinery/computer/telecomms/traffic/Machine = mob.machine
|
||||||
if(Machine.editingcode != mob)
|
if(Machine.editingcode != mob)
|
||||||
return
|
return
|
||||||
@@ -36,35 +33,40 @@ client/verb/tcscompile()
|
|||||||
if(Machine.SelectedServer)
|
if(Machine.SelectedServer)
|
||||||
var/obj/machinery/telecomms/server/Server = Machine.SelectedServer
|
var/obj/machinery/telecomms/server/Server = Machine.SelectedServer
|
||||||
Server.setcode( winget(src, "tcscode", "text") ) // save code first
|
Server.setcode( winget(src, "tcscode", "text") ) // save code first
|
||||||
var/list/compileerrors = Server.compile() // then compile the code!
|
|
||||||
|
|
||||||
// Output all the compile-time errors
|
spawn(0)
|
||||||
src << output(null, "tcserror")
|
// Output all the compile-time errors
|
||||||
|
src << output(null, "tcserror")
|
||||||
|
src << output("<font color = black>Please wait, compiling...</font>", "tcserror")
|
||||||
|
|
||||||
if(compileerrors.len)
|
var/list/compileerrors = Server.compile(mob) // then compile the code!
|
||||||
src << output("<b>Compile Errors</b>", "tcserror")
|
if(!telecomms_check(mob))
|
||||||
for(var/scriptError/e in compileerrors)
|
return
|
||||||
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
|
if(compileerrors.len)
|
||||||
for(var/mob/M in Machine.viewingcode)
|
src << output("<b>Compile Errors</b>", "tcserror")
|
||||||
if(M.client)
|
for(var/scriptError/e in compileerrors)
|
||||||
M << output(null, "tcserror")
|
src << output("<font color = red>\t>[e.message]</font color>", "tcserror")
|
||||||
M << output("<b>Compile Errors</b>", "tcserror")
|
src << output("([compileerrors.len] errors)", "tcserror")
|
||||||
for(var/scriptError/e in compileerrors)
|
|
||||||
M << output("<font color = red>\t>[e.message]</font color>", "tcserror")
|
// Output compile errors to all other people viewing the code too
|
||||||
M << output("([compileerrors.len] errors)", "tcserror")
|
for(var/mob/M in Machine.viewingcode)
|
||||||
|
if(M.client)
|
||||||
|
M << output(null, "tcserror")
|
||||||
|
M << output("<b>Compile Errors</b>", "tcserror")
|
||||||
|
for(var/scriptError/e in compileerrors)
|
||||||
|
M << output("<font color = red>\t>[e.message]</font color>", "tcserror")
|
||||||
|
M << output("([compileerrors.len] errors)", "tcserror")
|
||||||
|
|
||||||
|
|
||||||
else
|
else
|
||||||
src << output("<font color = blue>TCS compilation successful!</font color>", "tcserror")
|
src << output("<font color = blue>TCS compilation successful!</font color>", "tcserror")
|
||||||
src << output("(0 errors)", "tcserror")
|
src << output("(0 errors)", "tcserror")
|
||||||
|
|
||||||
for(var/mob/M in Machine.viewingcode)
|
for(var/mob/M in Machine.viewingcode)
|
||||||
if(M.client)
|
if(M.client)
|
||||||
M << output("<font color = blue>TCS compilation successful!</font color>", "tcserror")
|
M << output("<font color = blue>TCS compilation successful!</font color>", "tcserror")
|
||||||
M << output("(0 errors)", "tcserror")
|
M << output("(0 errors)", "tcserror")
|
||||||
|
|
||||||
else
|
else
|
||||||
src << output(null, "tcserror")
|
src << output(null, "tcserror")
|
||||||
@@ -79,56 +81,26 @@ client/verb/tcscompile()
|
|||||||
client/verb/tcsrun()
|
client/verb/tcsrun()
|
||||||
set hidden = 1
|
set hidden = 1
|
||||||
if(mob.machine || issilicon(mob))
|
if(mob.machine || issilicon(mob))
|
||||||
if((istype(mob.machine, /obj/machinery/computer/telecomms/traffic) && mob.machine in view(1, mob)) || (issilicon(mob) && istype(mob.machine, /obj/machinery/computer/telecomms/traffic) ))
|
if(telecomms_check(mob))
|
||||||
var/obj/machinery/computer/telecomms/traffic/Machine = mob.machine
|
var/obj/machinery/computer/telecomms/traffic/Machine = mob.machine
|
||||||
if(Machine.editingcode != mob)
|
if(Machine.editingcode != mob)
|
||||||
return
|
return
|
||||||
|
|
||||||
if(Machine.SelectedServer)
|
if(Machine.SelectedServer)
|
||||||
var/obj/machinery/telecomms/server/Server = Machine.SelectedServer
|
var/obj/machinery/telecomms/server/Server = Machine.SelectedServer
|
||||||
Server.setcode( winget(src, "tcscode", "text") ) // save code first
|
|
||||||
var/list/compileerrors = Server.compile() // then compile the code!
|
|
||||||
|
|
||||||
// Output all the compile-time errors
|
|
||||||
src << output(null, "tcserror")
|
|
||||||
|
|
||||||
if(compileerrors.len)
|
|
||||||
src << output("<b>Compile Errors</b>", "tcserror")
|
|
||||||
for(var/scriptError/e in compileerrors)
|
|
||||||
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")
|
|
||||||
for(var/scriptError/e in compileerrors)
|
|
||||||
M << output("<font color = red>\t>[e.message]</font color>", "tcserror")
|
|
||||||
M << output("([compileerrors.len] errors)", "tcserror")
|
|
||||||
|
|
||||||
|
var/datum/signal/signal = new()
|
||||||
|
signal.data["message"] = ""
|
||||||
|
if(Server.freq_listening.len > 0)
|
||||||
|
signal.frequency = Server.freq_listening[1]
|
||||||
else
|
else
|
||||||
// Finally, we run the code!
|
signal.frequency = 1459
|
||||||
src << output("<font color = blue>TCS compilation successful! Code executed.</font color>", "tcserror")
|
signal.data["name"] = ""
|
||||||
src << output("(0 errors)", "tcserror")
|
signal.data["job"] = ""
|
||||||
|
signal.data["reject"] = 0
|
||||||
|
signal.data["server"] = Server
|
||||||
|
|
||||||
for(var/mob/M in Machine.viewingcode)
|
Server.Compiler.Run(signal)
|
||||||
if(M.client)
|
|
||||||
M << output("<font color = blue>TCS compilation successful!</font color>", "tcserror")
|
|
||||||
M << output("(0 errors)", "tcserror")
|
|
||||||
|
|
||||||
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"] = 0
|
|
||||||
signal.data["server"] = Server
|
|
||||||
|
|
||||||
Server.Compiler.Run(signal)
|
|
||||||
|
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -145,7 +117,7 @@ client/verb/tcsrun()
|
|||||||
client/verb/exittcs()
|
client/verb/exittcs()
|
||||||
set hidden = 1
|
set hidden = 1
|
||||||
if(mob.machine || issilicon(mob))
|
if(mob.machine || issilicon(mob))
|
||||||
if((istype(mob.machine, /obj/machinery/computer/telecomms/traffic) && mob.machine in view(1, mob)) || (issilicon(mob) && istype(mob.machine, /obj/machinery/computer/telecomms/traffic) ))
|
if(telecomms_check(mob))
|
||||||
var/obj/machinery/computer/telecomms/traffic/Machine = mob.machine
|
var/obj/machinery/computer/telecomms/traffic/Machine = mob.machine
|
||||||
if(Machine.editingcode == mob)
|
if(Machine.editingcode == mob)
|
||||||
Machine.storedcode = "[winget(mob, "tcscode", "text")]"
|
Machine.storedcode = "[winget(mob, "tcscode", "text")]"
|
||||||
@@ -157,7 +129,7 @@ client/verb/exittcs()
|
|||||||
client/verb/tcsrevert()
|
client/verb/tcsrevert()
|
||||||
set hidden = 1
|
set hidden = 1
|
||||||
if(mob.machine || issilicon(mob))
|
if(mob.machine || issilicon(mob))
|
||||||
if((istype(mob.machine, /obj/machinery/computer/telecomms/traffic) && mob.machine in view(1, mob)) || (issilicon(mob) && istype(mob.machine, /obj/machinery/computer/telecomms/traffic) ))
|
if(telecomms_check(mob))
|
||||||
var/obj/machinery/computer/telecomms/traffic/Machine = mob.machine
|
var/obj/machinery/computer/telecomms/traffic/Machine = mob.machine
|
||||||
if(Machine.editingcode != mob)
|
if(Machine.editingcode != mob)
|
||||||
return
|
return
|
||||||
@@ -186,7 +158,7 @@ client/verb/tcsrevert()
|
|||||||
client/verb/tcsclearmem()
|
client/verb/tcsclearmem()
|
||||||
set hidden = 1
|
set hidden = 1
|
||||||
if(mob.machine || issilicon(mob))
|
if(mob.machine || issilicon(mob))
|
||||||
if((istype(mob.machine, /obj/machinery/computer/telecomms/traffic) && mob.machine in view(1, mob)) || (issilicon(mob) && istype(mob.machine, /obj/machinery/computer/telecomms/traffic) ))
|
if(telecomms_check(mob))
|
||||||
var/obj/machinery/computer/telecomms/traffic/Machine = mob.machine
|
var/obj/machinery/computer/telecomms/traffic/Machine = mob.machine
|
||||||
if(Machine.editingcode != mob)
|
if(Machine.editingcode != mob)
|
||||||
return
|
return
|
||||||
@@ -208,4 +180,9 @@ client/verb/tcsclearmem()
|
|||||||
src << output("<font color = red>Failed to clear memory: Unable to locate machine.</font color>", "tcserror")
|
src << output("<font color = red>Failed to clear memory: Unable to locate machine.</font color>", "tcserror")
|
||||||
else
|
else
|
||||||
src << output(null, "tcserror")
|
src << output(null, "tcserror")
|
||||||
src << output("<font color = red>Failed to clear memory: Unable to locate machine.</font color>", "tcserror")
|
src << output("<font color = red>Failed to clear memory: Unable to locate machine.</font color>", "tcserror")
|
||||||
|
|
||||||
|
/proc/telecomms_check(var/mob/mob)
|
||||||
|
if(mob && istype(mob.machine, /obj/machinery/computer/telecomms/traffic) && in_range(mob.machine, mob) || issilicon(mob) && istype(mob.machine, /obj/machinery/computer/telecomms/traffic))
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
@@ -10,11 +10,26 @@
|
|||||||
HandleError(runtimeError/e)
|
HandleError(runtimeError/e)
|
||||||
Compiler.Holder.add_entry(e.ToString(), "Execution Error")
|
Compiler.Holder.add_entry(e.ToString(), "Execution Error")
|
||||||
|
|
||||||
|
GC()
|
||||||
|
..()
|
||||||
|
Compiler = null
|
||||||
|
|
||||||
|
|
||||||
/datum/TCS_Compiler
|
/datum/TCS_Compiler
|
||||||
|
|
||||||
var/n_Interpreter/TCS_Interpreter/interpreter
|
var/n_Interpreter/TCS_Interpreter/interpreter
|
||||||
var/obj/machinery/telecomms/server/Holder // the server that is running the code
|
var/obj/machinery/telecomms/server/Holder // the server that is running the code
|
||||||
var/ready = 1 // 1 if ready to run code
|
var/ready = 1 // 1 if ready to run code
|
||||||
|
|
||||||
|
/* -- Set ourselves to Garbage Collect -- */
|
||||||
|
|
||||||
|
proc/GC()
|
||||||
|
|
||||||
|
Holder = null
|
||||||
|
if(interpreter)
|
||||||
|
interpreter.GC()
|
||||||
|
|
||||||
|
|
||||||
/* -- Compile a raw block of text -- */
|
/* -- Compile a raw block of text -- */
|
||||||
|
|
||||||
proc/Compile(code as message)
|
proc/Compile(code as message)
|
||||||
@@ -54,7 +69,9 @@
|
|||||||
interpreter.SetVar("E" , 2.718281828) // value of e
|
interpreter.SetVar("E" , 2.718281828) // value of e
|
||||||
interpreter.SetVar("SQURT2" , 1.414213562) // value of the square root of 2
|
interpreter.SetVar("SQURT2" , 1.414213562) // value of the square root of 2
|
||||||
interpreter.SetVar("FALSE" , 0) // boolean shortcut to 0
|
interpreter.SetVar("FALSE" , 0) // boolean shortcut to 0
|
||||||
|
interpreter.SetVar("false" , 0) // boolean shortcut to 0
|
||||||
interpreter.SetVar("TRUE" , 1) // boolean shortcut to 1
|
interpreter.SetVar("TRUE" , 1) // boolean shortcut to 1
|
||||||
|
interpreter.SetVar("true" , 1) // boolean shortcut to 1
|
||||||
|
|
||||||
interpreter.SetVar("NORTH" , NORTH) // NORTH (1)
|
interpreter.SetVar("NORTH" , NORTH) // NORTH (1)
|
||||||
interpreter.SetVar("SOUTH" , SOUTH) // SOUTH (2)
|
interpreter.SetVar("SOUTH" , SOUTH) // SOUTH (2)
|
||||||
@@ -93,13 +110,13 @@
|
|||||||
interpreter.SetProc("broadcast", "tcombroadcast", signal, list("message", "freq", "source", "job"))
|
interpreter.SetProc("broadcast", "tcombroadcast", signal, list("message", "freq", "source", "job"))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
-> Send a signal used by signallers.
|
-> Send a code signal.
|
||||||
@format: signal(frequency, code)
|
@format: signal(frequency, code)
|
||||||
|
|
||||||
@param frequency: Frequency to broadcast to
|
@param frequency: Frequency to send the signal to
|
||||||
@param code: Code to send
|
@param code: Encryption code to send the signal with
|
||||||
*/
|
*/
|
||||||
interpreter.SetProc("signal", /proc/ntsl_send_signal)
|
interpreter.SetProc("signal", "signaler", signal, list("freq", "code"))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
-> Store a value permanently to the server machine (not the actual game hosting machine, the ingame machine)
|
-> Store a value permanently to the server machine (not the actual game hosting machine, the ingame machine)
|
||||||
@@ -184,8 +201,12 @@
|
|||||||
interpreter.SetProc("round", /proc/n_round)
|
interpreter.SetProc("round", /proc/n_round)
|
||||||
interpreter.SetProc("clamp", /proc/n_clamp)
|
interpreter.SetProc("clamp", /proc/n_clamp)
|
||||||
interpreter.SetProc("inrange", /proc/n_inrange)
|
interpreter.SetProc("inrange", /proc/n_inrange)
|
||||||
|
interpreter.SetProc("rand", /proc/rand_chance)
|
||||||
// End of Donkie~
|
// End of Donkie~
|
||||||
|
|
||||||
|
// Time
|
||||||
|
interpreter.SetProc("time", /proc/time)
|
||||||
|
interpreter.SetProc("timestamp", /proc/timestamp)
|
||||||
|
|
||||||
// Run the compiled code
|
// Run the compiled code
|
||||||
interpreter.Run()
|
interpreter.Run()
|
||||||
@@ -193,21 +214,16 @@
|
|||||||
// Backwards-apply variables onto signal data
|
// Backwards-apply variables onto signal data
|
||||||
/* sanitize EVERYTHING. fucking players can't be trusted with SHIT */
|
/* sanitize EVERYTHING. fucking players can't be trusted with SHIT */
|
||||||
|
|
||||||
signal.data["message"] = interpreter.GetVar("$content")
|
signal.data["message"] = interpreter.GetCleanVar("$content", signal.data["message"])
|
||||||
signal.frequency = interpreter.GetVar("$freq")
|
signal.frequency = interpreter.GetCleanVar("$freq", signal.frequency)
|
||||||
|
|
||||||
var/setname = ""
|
var/setname = interpreter.GetCleanVar("$source", signal.data["name"])
|
||||||
var/obj/machinery/telecomms/server/S = signal.data["server"]
|
|
||||||
if(interpreter.GetVar("$source") in S.stored_names)
|
|
||||||
setname = interpreter.GetVar("$source")
|
|
||||||
else
|
|
||||||
setname = "<i>[interpreter.GetVar("$source")]</i>"
|
|
||||||
|
|
||||||
if(signal.data["name"] != setname)
|
if(signal.data["name"] != setname)
|
||||||
signal.data["realname"] = setname
|
signal.data["realname"] = setname
|
||||||
signal.data["name"] = setname
|
signal.data["name"] = setname
|
||||||
signal.data["job"] = interpreter.GetVar("$job")
|
signal.data["job"] = interpreter.GetCleanVar("$job", signal.data["job"])
|
||||||
signal.data["reject"] = !(interpreter.GetVar("$pass")) // set reject to the opposite of $pass
|
signal.data["reject"] = !(interpreter.GetCleanVar("$pass")) // set reject to the opposite of $pass
|
||||||
|
|
||||||
// If the message is invalid, just don't broadcast it!
|
// If the message is invalid, just don't broadcast it!
|
||||||
if(signal.data["message"] == "" || !signal.data["message"])
|
if(signal.data["message"] == "" || !signal.data["message"])
|
||||||
@@ -215,6 +231,8 @@
|
|||||||
|
|
||||||
/* -- Actual language proc code -- */
|
/* -- Actual language proc code -- */
|
||||||
|
|
||||||
|
var/const/SIGNAL_COOLDOWN = 20 // 2 seconds
|
||||||
|
|
||||||
datum/signal
|
datum/signal
|
||||||
|
|
||||||
proc/mem(var/address, var/value)
|
proc/mem(var/address, var/value)
|
||||||
@@ -229,6 +247,37 @@ datum/signal
|
|||||||
S.memory[address] = value
|
S.memory[address] = value
|
||||||
|
|
||||||
|
|
||||||
|
proc/signaler(var/freq = 1459, var/code = 30)
|
||||||
|
|
||||||
|
if(isnum(freq) && isnum(code))
|
||||||
|
|
||||||
|
var/obj/machinery/telecomms/server/S = data["server"]
|
||||||
|
|
||||||
|
if(S.last_signal + SIGNAL_COOLDOWN > world.timeofday && S.last_signal < MIDNIGHT_ROLLOVER)
|
||||||
|
return
|
||||||
|
S.last_signal = world.timeofday
|
||||||
|
|
||||||
|
var/datum/radio_frequency/connection = radio_controller.return_frequency(freq)
|
||||||
|
|
||||||
|
if(findtext(num2text(freq), ".")) // if the frequency has been set as a decimal
|
||||||
|
freq *= 10 // shift the decimal one place
|
||||||
|
|
||||||
|
freq = sanitize_frequency(freq)
|
||||||
|
|
||||||
|
code = round(code)
|
||||||
|
code = Clamp(code, 0, 100)
|
||||||
|
|
||||||
|
var/datum/signal/signal = new
|
||||||
|
signal.source = S
|
||||||
|
signal.encryption = code
|
||||||
|
signal.data["message"] = "ACTIVATE"
|
||||||
|
|
||||||
|
connection.post_signal(S, signal)
|
||||||
|
|
||||||
|
var/time = time2text(world.realtime,"hh:mm:ss")
|
||||||
|
lastsignalers.Add("[time] <B>:</B> [S.id] sent a signal command, which was triggered by NTSL.<B>:</B> [format_frequency(freq)]/[code]")
|
||||||
|
|
||||||
|
|
||||||
proc/tcombroadcast(var/message, var/freq, var/source, var/job)
|
proc/tcombroadcast(var/message, var/freq, var/source, var/job)
|
||||||
|
|
||||||
var/datum/signal/newsign = new
|
var/datum/signal/newsign = new
|
||||||
@@ -244,7 +293,7 @@ datum/signal
|
|||||||
if(!source)
|
if(!source)
|
||||||
source = "[html_encode(uppertext(S.id))]"
|
source = "[html_encode(uppertext(S.id))]"
|
||||||
hradio = new // sets the hradio as a radio intercom
|
hradio = new // sets the hradio as a radio intercom
|
||||||
if(!freq)
|
if(!freq || (!isnum(freq) && text2num(freq) == null))
|
||||||
freq = 1459
|
freq = 1459
|
||||||
if(findtext(num2text(freq), ".")) // if the frequency has been set as a decimal
|
if(findtext(num2text(freq), ".")) // if the frequency has been set as a decimal
|
||||||
freq *= 10 // shift the decimal one place
|
freq *= 10 // shift the decimal one place
|
||||||
@@ -254,12 +303,9 @@ datum/signal
|
|||||||
|
|
||||||
newsign.data["mob"] = null
|
newsign.data["mob"] = null
|
||||||
newsign.data["mobtype"] = /mob/living/carbon/human
|
newsign.data["mobtype"] = /mob/living/carbon/human
|
||||||
if(source in S.stored_names)
|
newsign.data["name"] = source
|
||||||
newsign.data["name"] = source
|
|
||||||
else
|
|
||||||
newsign.data["name"] = "<i>[html_encode(uppertext(source))]<i>"
|
|
||||||
newsign.data["realname"] = newsign.data["name"]
|
newsign.data["realname"] = newsign.data["name"]
|
||||||
newsign.data["job"] = job
|
newsign.data["job"] = "[job]"
|
||||||
newsign.data["compression"] = 0
|
newsign.data["compression"] = 0
|
||||||
newsign.data["message"] = message
|
newsign.data["message"] = message
|
||||||
newsign.data["type"] = 2 // artificial broadcast
|
newsign.data["type"] = 2 // artificial broadcast
|
||||||
@@ -277,6 +323,8 @@ datum/signal
|
|||||||
newsign.data["vmask"] = 0
|
newsign.data["vmask"] = 0
|
||||||
newsign.data["level"] = list()
|
newsign.data["level"] = list()
|
||||||
|
|
||||||
|
newsign.sanitize_data()
|
||||||
|
|
||||||
var/pass = S.relay_information(newsign, "/obj/machinery/telecomms/hub")
|
var/pass = S.relay_information(newsign, "/obj/machinery/telecomms/hub")
|
||||||
if(!pass)
|
if(!pass)
|
||||||
S.relay_information(newsign, "/obj/machinery/telecomms/broadcaster") // send this simple message to broadcasters
|
S.relay_information(newsign, "/obj/machinery/telecomms/broadcaster") // send this simple message to broadcasters
|
||||||
|
|||||||
@@ -94,6 +94,10 @@
|
|||||||
/proc/delay(var/time)
|
/proc/delay(var/time)
|
||||||
sleep(time)
|
sleep(time)
|
||||||
|
|
||||||
|
// Clone of rand()
|
||||||
|
/proc/rand_chance(var/low = 0, var/high)
|
||||||
|
return rand(low, high)
|
||||||
|
|
||||||
// Clone of prob()
|
// Clone of prob()
|
||||||
/proc/prob_chance(var/chance)
|
/proc/prob_chance(var/chance)
|
||||||
return prob(chance)
|
return prob(chance)
|
||||||
@@ -123,6 +127,7 @@
|
|||||||
if(container)
|
if(container)
|
||||||
if(istype(container, /list) || istext(container))
|
if(istype(container, /list) || istext(container))
|
||||||
return length(container)
|
return length(container)
|
||||||
|
return 0
|
||||||
|
|
||||||
// BY DONKIE~
|
// BY DONKIE~
|
||||||
// String stuff
|
// String stuff
|
||||||
@@ -134,6 +139,12 @@
|
|||||||
if(istext(string))
|
if(istext(string))
|
||||||
return uppertext(string)
|
return uppertext(string)
|
||||||
|
|
||||||
|
/proc/time()
|
||||||
|
return world.timeofday
|
||||||
|
|
||||||
|
/proc/timestamp(var/format = "hh:mm:ss") // Get the game time in text
|
||||||
|
return time2text(world.time + 432000, format)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
//Makes a list where all indicies in a string is a seperate index in the list
|
//Makes a list where all indicies in a string is a seperate index in the list
|
||||||
// JUST A HELPER DON'T ADD TO NTSCRIPT
|
// JUST A HELPER DON'T ADD TO NTSCRIPT
|
||||||
@@ -165,8 +176,10 @@ proc/string_explode(var/string, var/separator)
|
|||||||
|
|
||||||
Just found out there was already a string explode function, did some benchmarking, and that function were a bit faster, sticking to that.
|
Just found out there was already a string explode function, did some benchmarking, and that function were a bit faster, sticking to that.
|
||||||
*/
|
*/
|
||||||
proc/string_explode(var/string, var/separator)
|
|
||||||
if(istext(string) && istext(separator))
|
|
||||||
|
proc/string_explode(var/string, var/separator = "")
|
||||||
|
if(istext(string) && (istext(separator) || isnull(separator)))
|
||||||
return text2list(string, separator)
|
return text2list(string, separator)
|
||||||
|
|
||||||
proc/n_repeat(var/string, var/amount)
|
proc/n_repeat(var/string, var/amount)
|
||||||
@@ -247,15 +260,18 @@ proc/n_inrange(var/num, var/min=-1, var/max=1)
|
|||||||
|
|
||||||
// Non-recursive
|
// Non-recursive
|
||||||
// Imported from Mono string.ReplaceUnchecked
|
// Imported from Mono string.ReplaceUnchecked
|
||||||
|
/*
|
||||||
/proc/string_replacetext(var/haystack,var/a,var/b)
|
/proc/string_replacetext(var/haystack,var/a,var/b)
|
||||||
if(istext(haystack)&&istext(a)&&istext(b))
|
if(istext(haystack)&&istext(a)&&istext(b))
|
||||||
var/i = 1
|
var/i = 1
|
||||||
var/lenh=lentext(haystack)
|
var/lenh=lentext(haystack)
|
||||||
var/lena=lentext(a)
|
var/lena=lentext(a)
|
||||||
|
//var/lenb=lentext(b)
|
||||||
var/count = 0
|
var/count = 0
|
||||||
var/list/dat = list()
|
var/list/dat = list()
|
||||||
while (i < lenh)
|
while (i < lenh)
|
||||||
var/found = findtext(haystack, a, i, 0)
|
var/found = findtext(haystack, a, i, 0)
|
||||||
|
//diary << "findtext([haystack], [a], [i], 0)=[found]"
|
||||||
if (found == 0) // Not found
|
if (found == 0) // Not found
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
@@ -263,50 +279,49 @@ proc/n_inrange(var/num, var/min=-1, var/max=1)
|
|||||||
dat+=found
|
dat+=found
|
||||||
count+=1
|
count+=1
|
||||||
else
|
else
|
||||||
|
//diary << "Script found [a] [count] times, aborted"
|
||||||
break
|
break
|
||||||
|
//diary << "Found [a] at [found]! Moving up..."
|
||||||
i = found + lena
|
i = found + lena
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return haystack
|
return haystack
|
||||||
|
//var/nlen = lenh + ((lenb - lena) * count)
|
||||||
var/buf = copytext(haystack,1,dat[1]) // Prefill
|
var/buf = copytext(haystack,1,dat[1]) // Prefill
|
||||||
var/lastReadPos = 0
|
var/lastReadPos = 0
|
||||||
for (i = 1, i <= count, i++)
|
for (i = 1, i <= count, i++)
|
||||||
var/precopy = dat[i] - lastReadPos-1
|
var/precopy = dat[i] - lastReadPos-1
|
||||||
|
//internal static unsafe void CharCopy (String target, int targetIndex, String source, int sourceIndex, int count)
|
||||||
|
//fixed (char* dest = target, src = source)
|
||||||
|
//CharCopy (dest + targetIndex, src + sourceIndex, count);
|
||||||
|
//CharCopy (dest + curPos, source + lastReadPos, precopy);
|
||||||
buf+=copytext(haystack,lastReadPos,precopy)
|
buf+=copytext(haystack,lastReadPos,precopy)
|
||||||
|
diary << "buf+=copytext([haystack],[lastReadPos],[precopy])"
|
||||||
|
diary<<"[buf]"
|
||||||
lastReadPos = dat[i] + lena
|
lastReadPos = dat[i] + lena
|
||||||
|
//CharCopy (dest + curPos, replace, newValue.length);
|
||||||
buf+=b
|
buf+=b
|
||||||
|
diary<<"[buf]"
|
||||||
buf+=copytext(haystack,lastReadPos, 0)
|
buf+=copytext(haystack,lastReadPos, 0)
|
||||||
return buf
|
return buf
|
||||||
|
*/
|
||||||
|
|
||||||
|
/proc/string_replacetext(text, find, replacement)
|
||||||
/proc/ntsl_send_signal(var/freq,var/code)
|
if(istext(text) && istext(find) && istext(replacement))
|
||||||
if(isnum(freq)&&isnum(code))
|
var/find_len = length(find)
|
||||||
if(!radio_controller)
|
if(find_len < 1) return text
|
||||||
sleep(20)
|
. = ""
|
||||||
if(!radio_controller)
|
var/last_found = 1
|
||||||
|
var/count = 0
|
||||||
|
while(1)
|
||||||
|
count += 1
|
||||||
|
if(count > SCRIPT_MAX_REPLACEMENTS_ALLOWED)
|
||||||
|
break
|
||||||
|
var/found = findtext(text, find, last_found, 0)
|
||||||
|
. += copytext(text, last_found, found)
|
||||||
|
if(found)
|
||||||
|
. += replacement
|
||||||
|
last_found = found + find_len
|
||||||
|
continue
|
||||||
return
|
return
|
||||||
// Sanitize frequency
|
|
||||||
var/new_frequency = freq
|
|
||||||
if(new_frequency < 1200 || new_frequency > 1600)
|
|
||||||
new_frequency = sanitize_frequency(new_frequency)
|
|
||||||
|
|
||||||
// Sanitize code
|
#undef SCRIPT_MAX_REPLACEMENTS_ALLOWED
|
||||||
code = round(code)
|
|
||||||
code = min(100, code)
|
|
||||||
code = max(1, code)
|
|
||||||
|
|
||||||
// Since we're not an object, we can't do this.
|
|
||||||
/*
|
|
||||||
radio_controller.remove_object(src, frequency)
|
|
||||||
frequency = new_frequency
|
|
||||||
radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT)
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Therefore, we do this hacky bit of crap instead.
|
|
||||||
var/datum/radio_frequency/radio_connection = radio_controller.return_frequency(freq)
|
|
||||||
|
|
||||||
// Go go gadget
|
|
||||||
var/datum/signal/signal = new
|
|
||||||
signal.source = null // Oh god I hope this works.
|
|
||||||
signal.encryption = code
|
|
||||||
signal.data["message"] = "ACTIVATE"
|
|
||||||
radio_connection.post_signal(null, signal)
|
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
ASSERT(program)
|
ASSERT(program)
|
||||||
src.program = program
|
src.program = program
|
||||||
CreateGlobalScope()
|
CreateGlobalScope()
|
||||||
|
alertadmins = 0 // reset admin alerts
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Proc: Run
|
Proc: Run
|
||||||
@@ -29,7 +30,6 @@
|
|||||||
Run()
|
Run()
|
||||||
cur_recursion = 0 // reset recursion
|
cur_recursion = 0 // reset recursion
|
||||||
cur_statements = 0 // reset CPU tracking
|
cur_statements = 0 // reset CPU tracking
|
||||||
alertadmins = 0
|
|
||||||
|
|
||||||
ASSERT(src.program)
|
ASSERT(src.program)
|
||||||
RunBlock(src.program)
|
RunBlock(src.program)
|
||||||
@@ -110,6 +110,17 @@
|
|||||||
var/x = globalScope.variables[name]
|
var/x = globalScope.variables[name]
|
||||||
return Eval(x)
|
return Eval(x)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Proc: GetCleanVar
|
||||||
|
Returns the value of a global variable in the script and cleans it (sanitizes).
|
||||||
|
*/
|
||||||
|
|
||||||
|
GetCleanVar(name, compare)
|
||||||
|
var/x = GetVar(name)
|
||||||
|
if(istext(x) && compare && x != compare) // Was changed
|
||||||
|
x = sanitize(x)
|
||||||
|
return x
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Proc: CallProc
|
Proc: CallProc
|
||||||
Calls a global function defined in the script and, amazingly enough, returns its return value. Remember to ensure that the function
|
Calls a global function defined in the script and, amazingly enough, returns its return value. Remember to ensure that the function
|
||||||
|
|||||||
@@ -33,11 +33,11 @@
|
|||||||
status=0
|
status=0
|
||||||
returnVal
|
returnVal
|
||||||
|
|
||||||
max_statements=1000 // maximum amount of statements that can be called in one execution. this is to prevent massive crashes and exploitation
|
max_statements=900 // maximum amount of statements that can be called in one execution. this is to prevent massive crashes and exploitation
|
||||||
cur_statements=0 // current amount of statements called
|
cur_statements=0 // current amount of statements called
|
||||||
alertadmins=0 // set to 1 if the admins shouldn't be notified of anymore issues
|
alertadmins=0 // set to 1 if the admins shouldn't be notified of anymore issues
|
||||||
max_iterations=100 // max number of uninterrupted loops possible
|
max_iterations=100 // max number of uninterrupted loops possible
|
||||||
max_recursion=50 // max recursions without returning anything (or completing the code block)
|
max_recursion=10 // max recursions without returning anything (or completing the code block)
|
||||||
cur_recursion=0 // current amount of recursion
|
cur_recursion=0 // current amount of recursion
|
||||||
/*
|
/*
|
||||||
Var: persist
|
Var: persist
|
||||||
@@ -55,6 +55,14 @@
|
|||||||
if(program)Load(program)
|
if(program)Load(program)
|
||||||
|
|
||||||
proc
|
proc
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set ourselves to Garbage Collect
|
||||||
|
*/
|
||||||
|
GC()
|
||||||
|
..()
|
||||||
|
container = null
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Proc: RaiseError
|
Proc: RaiseError
|
||||||
Raises a runtime error.
|
Raises a runtime error.
|
||||||
@@ -76,6 +84,19 @@
|
|||||||
globalScope = S
|
globalScope = S
|
||||||
return S
|
return S
|
||||||
|
|
||||||
|
/*
|
||||||
|
Proc: AlertAdmins
|
||||||
|
Alerts the admins of a script that is bad.
|
||||||
|
*/
|
||||||
|
AlertAdmins()
|
||||||
|
if(container && !alertadmins)
|
||||||
|
if(istype(container, /datum/TCS_Compiler))
|
||||||
|
var/datum/TCS_Compiler/Compiler = container
|
||||||
|
var/obj/machinery/telecomms/server/Holder = Compiler.Holder
|
||||||
|
var/message = "Potential crash-inducing NTSL script detected at telecommunications server [Compiler.Holder] ([Holder.x], [Holder.y], [Holder.z])."
|
||||||
|
|
||||||
|
alertadmins = 1
|
||||||
|
message_admins(message, 1)
|
||||||
/*
|
/*
|
||||||
Proc: RunBlock
|
Proc: RunBlock
|
||||||
Runs each statement in a block of code.
|
Runs each statement in a block of code.
|
||||||
@@ -100,15 +121,7 @@
|
|||||||
cur_statements++
|
cur_statements++
|
||||||
if(cur_statements >= max_statements)
|
if(cur_statements >= max_statements)
|
||||||
RaiseError(new/runtimeError/MaxCPU())
|
RaiseError(new/runtimeError/MaxCPU())
|
||||||
|
AlertAdmins()
|
||||||
if(container && !alertadmins)
|
|
||||||
if(istype(container, /datum/TCS_Compiler))
|
|
||||||
var/datum/TCS_Compiler/Compiler = container
|
|
||||||
var/obj/machinery/telecomms/server/Holder = Compiler.Holder
|
|
||||||
var/message = "Potential crash-inducing NTSL script detected at telecommunications server [Compiler.Holder] ([Holder.x], [Holder.y], [Holder.z])."
|
|
||||||
|
|
||||||
alertadmins = 1
|
|
||||||
message_admins(message, 1)
|
|
||||||
break
|
break
|
||||||
|
|
||||||
if(istype(S, /node/statement/VariableAssignment))
|
if(istype(S, /node/statement/VariableAssignment))
|
||||||
@@ -171,6 +184,7 @@
|
|||||||
|
|
||||||
// If recursion gets too high (max 50 nested functions) throw an error
|
// If recursion gets too high (max 50 nested functions) throw an error
|
||||||
if(cur_recursion >= max_recursion)
|
if(cur_recursion >= max_recursion)
|
||||||
|
AlertAdmins()
|
||||||
RaiseError(new/runtimeError/RecursionLimitReached())
|
RaiseError(new/runtimeError/RecursionLimitReached())
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@@ -223,10 +237,21 @@
|
|||||||
Checks a condition and runs either the if block or else block.
|
Checks a condition and runs either the if block or else block.
|
||||||
*/
|
*/
|
||||||
RunIf(node/statement/IfStatement/stmt)
|
RunIf(node/statement/IfStatement/stmt)
|
||||||
if(Eval(stmt.cond))
|
if(!stmt.skip)
|
||||||
RunBlock(stmt.block)
|
if(Eval(stmt.cond))
|
||||||
else if(stmt.else_block)
|
RunBlock(stmt.block)
|
||||||
RunBlock(stmt.else_block)
|
// Loop through the if else chain and tell them to be skipped.
|
||||||
|
var/node/statement/IfStatement/i = stmt.else_if
|
||||||
|
var/fail_safe = 800
|
||||||
|
while(i && fail_safe)
|
||||||
|
fail_safe -= 1
|
||||||
|
i.skip = 1
|
||||||
|
i = i.else_if
|
||||||
|
|
||||||
|
else if(stmt.else_block)
|
||||||
|
RunBlock(stmt.else_block)
|
||||||
|
// We don't need to skip you anymore.
|
||||||
|
stmt.skip = 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Proc: RunWhile
|
Proc: RunWhile
|
||||||
@@ -312,3 +337,4 @@
|
|||||||
//TODO: check for invalid name
|
//TODO: check for invalid name
|
||||||
S.variables["[name]"] = value
|
S.variables["[name]"] = value
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ n_scriptOptions
|
|||||||
An associative list used by the parser to parse keywords. Indices are strings which will trigger the keyword when parsed and the
|
An associative list used by the parser to parse keywords. Indices are strings which will trigger the keyword when parsed and the
|
||||||
associated values are <nS_Keyword> types of which the <n_Keyword.Parse()> proc will be called.
|
associated values are <nS_Keyword> types of which the <n_Keyword.Parse()> proc will be called.
|
||||||
*/
|
*/
|
||||||
keywords = list("if" = /n_Keyword/nS_Keyword/kwIf, "else" = /n_Keyword/nS_Keyword/kwElse, \
|
keywords = list("if" = /n_Keyword/nS_Keyword/kwIf, "else" = /n_Keyword/nS_Keyword/kwElse, "elseif" = /n_Keyword/nS_Keyword/kwElseIf, \
|
||||||
"while" = /n_Keyword/nS_Keyword/kwWhile, "break" = /n_Keyword/nS_Keyword/kwBreak, \
|
"while" = /n_Keyword/nS_Keyword/kwWhile, "break" = /n_Keyword/nS_Keyword/kwBreak, \
|
||||||
"continue" = /n_Keyword/nS_Keyword/kwContinue, \
|
"continue" = /n_Keyword/nS_Keyword/kwContinue, \
|
||||||
"return" = /n_Keyword/nS_Keyword/kwReturn, "def" = /n_Keyword/nS_Keyword/kwDef)
|
"return" = /n_Keyword/nS_Keyword/kwReturn, "def" = /n_Keyword/nS_Keyword/kwDef)
|
||||||
|
|||||||
@@ -180,12 +180,18 @@
|
|||||||
- <ParseParenExpression()>
|
- <ParseParenExpression()>
|
||||||
- <ParseParamExpression()>
|
- <ParseParamExpression()>
|
||||||
*/
|
*/
|
||||||
ParseExpression(list/end=list(/token/end), list/ErrChars=list("{", "}"))
|
ParseExpression(list/end=list(/token/end), list/ErrChars=list("{", "}"), check_functions = 0)
|
||||||
var/stack
|
var/stack
|
||||||
opr=new
|
opr=new
|
||||||
val=new
|
val=new
|
||||||
src.expecting=VALUE
|
src.expecting=VALUE
|
||||||
|
var/loop = 0
|
||||||
for()
|
for()
|
||||||
|
loop++
|
||||||
|
if(loop > 800)
|
||||||
|
errors+=new/scriptError("Too many nested tokens.")
|
||||||
|
return
|
||||||
|
|
||||||
if(EndOfExpression(end))
|
if(EndOfExpression(end))
|
||||||
break
|
break
|
||||||
if(istype(curToken, /token/symbol) && ErrChars.Find(curToken.value))
|
if(istype(curToken, /token/symbol) && ErrChars.Find(curToken.value))
|
||||||
@@ -206,6 +212,7 @@
|
|||||||
NextToken()
|
NextToken()
|
||||||
continue
|
continue
|
||||||
val.Push(ParseParenExpression())
|
val.Push(ParseParenExpression())
|
||||||
|
|
||||||
else if(istype(curToken, /token/symbol)) //Operator found.
|
else if(istype(curToken, /token/symbol)) //Operator found.
|
||||||
var/node/expression/operator/curOperator //Figure out whether it is unary or binary and get a new instance.
|
var/node/expression/operator/curOperator //Figure out whether it is unary or binary and get a new instance.
|
||||||
if(src.expecting==OPERATOR)
|
if(src.expecting==OPERATOR)
|
||||||
@@ -226,16 +233,24 @@
|
|||||||
continue
|
continue
|
||||||
opr.Push(curOperator)
|
opr.Push(curOperator)
|
||||||
src.expecting=VALUE
|
src.expecting=VALUE
|
||||||
|
|
||||||
else if(ntok && ntok.value=="(" && istype(ntok, /token/symbol)\
|
else if(ntok && ntok.value=="(" && istype(ntok, /token/symbol)\
|
||||||
&& istype(curToken, /token/word)) //Parse function call
|
&& istype(curToken, /token/word)) //Parse function call
|
||||||
var/token/preToken=curToken
|
|
||||||
var/old_expect=src.expecting
|
if(!check_functions)
|
||||||
var/fex=ParseFunctionExpression()
|
|
||||||
if(old_expect!=VALUE)
|
var/token/preToken=curToken
|
||||||
errors+=new/scriptError/ExpectedToken("operator", preToken)
|
var/old_expect=src.expecting
|
||||||
NextToken()
|
var/fex=ParseFunctionExpression()
|
||||||
continue
|
if(old_expect!=VALUE)
|
||||||
val.Push(fex)
|
errors+=new/scriptError/ExpectedToken("operator", preToken)
|
||||||
|
NextToken()
|
||||||
|
continue
|
||||||
|
val.Push(fex)
|
||||||
|
else
|
||||||
|
errors+=new/scriptError/ParameterFunction(curToken)
|
||||||
|
break
|
||||||
|
|
||||||
else if(istype(curToken, /token/keyword)) //inline keywords
|
else if(istype(curToken, /token/keyword)) //inline keywords
|
||||||
var/n_Keyword/kw=options.keywords[curToken.value]
|
var/n_Keyword/kw=options.keywords[curToken.value]
|
||||||
kw=new kw(inline=1)
|
kw=new kw(inline=1)
|
||||||
@@ -244,6 +259,7 @@
|
|||||||
return
|
return
|
||||||
else
|
else
|
||||||
errors+=new/scriptError/BadToken(curToken)
|
errors+=new/scriptError/BadToken(curToken)
|
||||||
|
|
||||||
else if(istype(curToken, /token/end)) //semicolon found where it wasn't expected
|
else if(istype(curToken, /token/end)) //semicolon found where it wasn't expected
|
||||||
errors+=new/scriptError/BadToken(curToken)
|
errors+=new/scriptError/BadToken(curToken)
|
||||||
NextToken()
|
NextToken()
|
||||||
@@ -255,6 +271,7 @@
|
|||||||
continue
|
continue
|
||||||
val.Push(GetExpression(curToken))
|
val.Push(GetExpression(curToken))
|
||||||
src.expecting=OPERATOR
|
src.expecting=OPERATOR
|
||||||
|
|
||||||
NextToken()
|
NextToken()
|
||||||
|
|
||||||
while(opr.Top()) Reduce(opr, val) //Reduce the value stack completely
|
while(opr.Top()) Reduce(opr, val) //Reduce the value stack completely
|
||||||
@@ -280,12 +297,16 @@
|
|||||||
|
|
||||||
for()
|
for()
|
||||||
loops++
|
loops++
|
||||||
if(loops>=1000)
|
if(loops>=800)
|
||||||
CRASH("Something TERRIBLE has gone wrong in ParseFunctionExpression ;__;")
|
errors += new/scriptError("Too many nested expressions.")
|
||||||
|
break
|
||||||
|
//CRASH("Something TERRIBLE has gone wrong in ParseFunctionExpression ;__;")
|
||||||
|
|
||||||
if(istype(curToken, /token/symbol) && curToken.value==")")
|
if(istype(curToken, /token/symbol) && curToken.value==")")
|
||||||
return exp
|
return exp
|
||||||
exp.parameters+=ParseParamExpression()
|
exp.parameters+=ParseParamExpression()
|
||||||
|
if(errors.len)
|
||||||
|
return exp
|
||||||
if(curToken.value==","&&istype(curToken, /token/symbol))NextToken() //skip comma
|
if(curToken.value==","&&istype(curToken, /token/symbol))NextToken() //skip comma
|
||||||
if(istype(curToken, /token/end)) //Prevents infinite loop...
|
if(istype(curToken, /token/end)) //Prevents infinite loop...
|
||||||
errors+=new/scriptError/ExpectedToken(")")
|
errors+=new/scriptError/ExpectedToken(")")
|
||||||
@@ -310,5 +331,6 @@
|
|||||||
See Also:
|
See Also:
|
||||||
- <ParseExpression()>
|
- <ParseExpression()>
|
||||||
*/
|
*/
|
||||||
ParseParamExpression()
|
ParseParamExpression(var/check_functions = 0)
|
||||||
return ParseExpression(list(",", ")"))
|
var/cf = check_functions
|
||||||
|
return ParseExpression(list(",", ")"), check_functions = cf)
|
||||||
@@ -51,9 +51,9 @@ var/const/Represents a special statement in the code triggered by a keyword.
|
|||||||
kwReturn
|
kwReturn
|
||||||
Parse(n_Parser/nS_Parser/parser)
|
Parse(n_Parser/nS_Parser/parser)
|
||||||
.=KW_PASS
|
.=KW_PASS
|
||||||
if(istype(parser.curBlock, /node/BlockDefinition/GlobalBlock))
|
if(istype(parser.curBlock, /node/BlockDefinition/GlobalBlock)) // Exit out of the program by setting the tokens list size to the same as index.
|
||||||
parser.errors+=new/scriptError/BadReturn(parser.curToken)
|
parser.tokens.len = parser.index
|
||||||
. = KW_WARN
|
return
|
||||||
var/node/statement/ReturnStatement/stmt=new
|
var/node/statement/ReturnStatement/stmt=new
|
||||||
parser.NextToken() //skip 'return' token
|
parser.NextToken() //skip 'return' token
|
||||||
stmt.value=parser.ParseExpression()
|
stmt.value=parser.ParseExpression()
|
||||||
@@ -73,6 +73,31 @@ var/const/Represents a special statement in the code triggered by a keyword.
|
|||||||
stmt.block=new
|
stmt.block=new
|
||||||
parser.AddBlock(stmt.block)
|
parser.AddBlock(stmt.block)
|
||||||
|
|
||||||
|
kwElseIf
|
||||||
|
Parse(n_Parser/nS_Parser/parser)
|
||||||
|
.=KW_PASS
|
||||||
|
var/list/L=parser.curBlock.statements
|
||||||
|
var/node/statement/IfStatement/ifstmt
|
||||||
|
|
||||||
|
if(L && L.len)
|
||||||
|
ifstmt = L[L.len] //Get the last statement in the current block
|
||||||
|
if(!ifstmt || !istype(ifstmt) || ifstmt.else_if)
|
||||||
|
parser.errors += new/scriptError/ExpectedToken("if statement", parser.curToken)
|
||||||
|
return KW_FAIL
|
||||||
|
|
||||||
|
var/node/statement/IfStatement/ElseIf/stmt = new
|
||||||
|
parser.NextToken() //skip 'if' token
|
||||||
|
stmt.cond = parser.ParseParenExpression()
|
||||||
|
if(!parser.CheckToken(")", /token/symbol))
|
||||||
|
return KW_FAIL
|
||||||
|
if(!parser.CheckToken("{", /token/symbol, skip=0)) //Token needs to be preserved for parse loop, so skip=0
|
||||||
|
return KW_ERR
|
||||||
|
parser.curBlock.statements+=stmt
|
||||||
|
stmt.block=new
|
||||||
|
ifstmt.else_if = stmt
|
||||||
|
parser.AddBlock(stmt.block)
|
||||||
|
|
||||||
|
|
||||||
kwElse
|
kwElse
|
||||||
Parse(n_Parser/nS_Parser/parser)
|
Parse(n_Parser/nS_Parser/parser)
|
||||||
.=KW_PASS
|
.=KW_PASS
|
||||||
|
|||||||
@@ -174,8 +174,9 @@
|
|||||||
var/loops = 0
|
var/loops = 0
|
||||||
for()
|
for()
|
||||||
loops++
|
loops++
|
||||||
if(loops>=6000)
|
if(loops>=800)
|
||||||
CRASH("Something TERRIBLE has gone wrong in ParseFunctionStatement ;__;")
|
errors +=new/scriptError("Cannot find ending params.")
|
||||||
|
return
|
||||||
|
|
||||||
if(!curToken)
|
if(!curToken)
|
||||||
errors+=new/scriptError/EndOfFile()
|
errors+=new/scriptError/EndOfFile()
|
||||||
@@ -184,6 +185,6 @@
|
|||||||
curBlock.statements+=stmt
|
curBlock.statements+=stmt
|
||||||
NextToken() //Skip close parenthesis
|
NextToken() //Skip close parenthesis
|
||||||
return
|
return
|
||||||
var/node/expression/P=ParseParamExpression()
|
var/node/expression/P=ParseParamExpression(check_functions = 1)
|
||||||
stmt.parameters+=P
|
stmt.parameters+=P
|
||||||
if(istype(curToken, /token/symbol) && curToken.value==",") NextToken()
|
if(istype(curToken, /token/symbol) && curToken.value==",") NextToken()
|
||||||
Reference in New Issue
Block a user