Files
Bubberstation/code/modules/admin/verbs/lua/lua_editor.dm
Waterpig bb70889f6e TG Upstream Part 1
3591 individual conflicts

Update build.js

Update install_node.sh

Update byond.js

oh my fucking god

hat

slow

huh

holy shit

we all fall down

2 more I missed

2900 individual conflicts

2700 Individual conflicts

replaces yarn file with tg version, bumping us down to 2200-ish

Down to 2000 individual conflicts

140 down

mmm

aaaaaaaaaaaaaaaaaaa

not yt

575

soon

900 individual conflicts

600 individual conflicts, 121 file conflicts

im not okay

160 across 19 files

29 in 4 files

0 conflicts, compiletime fix time

some minor incap stuff

missed ticks

weird dupe definition stuff

missed ticks 2

incap fixes

undefs and pie fix

Radio update and some extra minor stuff

returns a single override

no more dupe definitions, 175 compiletime errors

Unticked file fix

sound and emote stuff

honk and more radio stuff
2024-10-19 08:04:33 -07:00

286 lines
9.9 KiB
Plaintext

/datum/lua_editor
var/datum/lua_state/current_state
/// Arguments for a function call or coroutine resume
var/list/arguments = list()
/// If not set, the global table will not be shown in the lua editor
var/show_global_table = FALSE
/// The log page we are currently on
var/page = 0
/// If set, we will force the editor's modal to be this
var/force_modal
/// If set, we will force the editor to look at this chunk
var/force_view_chunk
/// If set, we will force the script input to be this
var/force_input
/// If set, the latest code execution performed from the editor raised an error, and this is the message from that error
var/last_error
/datum/lua_editor/New(state, _quick_log_index)
. = ..()
if(state)
current_state = state
LAZYADDASSOCLIST(SSlua.editors, text_ref(current_state), src)
/datum/lua_editor/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "LuaEditor", "Lua")
ui.set_autoupdate(FALSE)
ui.open()
/datum/lua_editor/Destroy(force)
. = ..()
if(current_state)
LAZYREMOVEASSOC(SSlua.editors, text_ref(current_state), src)
/datum/lua_editor/ui_state(mob/user)
return GLOB.debug_state
/datum/lua_editor/ui_data(mob/user)
var/list/data = list()
data["ss_lua_init"] = SSlua.initialized
if(!SSlua.initialized)
return data
data["noStateYet"] = !current_state
data["showGlobalTable"] = show_global_table
if(current_state)
if(current_state.log)
var/list/logs = current_state.log.Copy((page*50)+1, min((page+1)*50+1, current_state.log.len+1))
for(var/i in 1 to logs.len)
var/list/log = logs[i]
log = log.Copy()
if(log["return_values"])
log["return_values"] = kvpify_list(prepare_lua_editor_list(deep_copy_without_cycles(log["return_values"])))
logs[i] = log
data["stateLog"] = logs
data["page"] = page
data["pageCount"] = CEILING(current_state.log.len/50, 1)
data["tasks"] = current_state.get_tasks()
if(show_global_table)
current_state.get_globals()
var/list/values = current_state.globals["values"]
values = deep_copy_without_cycles(values)
values = prepare_lua_editor_list(values)
values = kvpify_list(values)
var/list/variants = current_state.globals["variants"]
data["globals"] = list("values" = values, "variants" = variants)
if(last_error)
data["lastError"] = last_error
last_error = null
data["supressRuntimes"] = current_state.supress_runtimes
data["states"] = list()
for(var/datum/lua_state/state as anything in SSlua.states)
data["states"] += state.display_name
data["callArguments"] = kvpify_list(prepare_lua_editor_list(deep_copy_without_cycles(arguments)))
if(force_modal)
data["forceModal"] = force_modal
force_modal = null
if(force_view_chunk)
data["forceViewChunk"] = force_view_chunk
force_view_chunk = null
if(force_input)
data["force_input"] = force_input
force_input = null
return data
/datum/lua_editor/proc/traverse_list(list/path, list/root, traversal_depth_offset = 0)
var/top_affected_list_depth = LAZYLEN(path)-traversal_depth_offset // The depth of the element to get
if(top_affected_list_depth)
var/list/current_list = root
// We kvpify the list to the depth of the element to get - this allows us to reach list elements contained within a assoc list's key
var/list/path_list = kvpify_list(current_list, top_affected_list_depth-1)
while(LAZYLEN(path) > traversal_depth_offset)
// Navigate to the index of the next path element within the current path element
var/list/path_element = popleft(path)
var/list/list_element = path_list[path_element["index"]]
// Enter the next path element - be it the key or the value
switch(path_element["type"])
if("key")
path_list = list_element["key"]
if("value")
path_list = list_element["value"]
else
to_chat(usr, span_warning("invalid path element type \[[path_element["type"]]] for list traversal (expected \"key\" or \"value\""))
return
// The element we are entering SHOULD be a list, unless we're at the end of the path
if(!islist(path_list) && LAZYLEN(path))
to_chat(usr, span_warning("invalid path element \[[path_list]] for list traversal (expected a list)"))
return
current_list = path_list
return current_list
else
return root
/datum/lua_editor/proc/run_code(code)
var/ckey = usr.ckey
current_state.ckey_last_runner = ckey
var/result = current_state.load_script(code)
var/index_with_result = current_state.log_result(result)
if(result["status"] == "error")
last_error = result["message"]
message_admins("[key_name(usr)] executed [length(code)] bytes of lua code. [ADMIN_LUAVIEW_CHUNK(current_state, index_with_result)]")
/datum/lua_editor/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return
var/mob/user = ui.user
if(!check_rights_for(user.client, R_DEBUG))
return
if(action == "runCodeFile")
params["code"] = file2text(input(user, "Input File") as null|file)
if(isnull(params["code"]))
return
action = "runCode"
switch(action)
if("newState")
var/state_name = params["name"]
if(!length(state_name))
return TRUE
var/datum/lua_state/new_state = new(state_name)
if(QDELETED(new_state))
return
SSlua.states += new_state
LAZYREMOVEASSOC(SSlua.editors, text_ref(current_state), src)
current_state = new_state
LAZYADDASSOCLIST(SSlua.editors, text_ref(current_state), src)
page = 0
return TRUE
if("switchState")
var/state_index = params["index"]
LAZYREMOVEASSOC(SSlua.editors, text_ref(current_state), src)
current_state = SSlua.states[state_index]
LAZYADDASSOCLIST(SSlua.editors, text_ref(current_state), src)
page = 0
return TRUE
if("runCode")
run_code(params["code"])
return TRUE
if("runFile")
var/code_file = input(user, "Select a script to run.", "Lua") as file|null
if(!code_file)
return TRUE
var/code = file2text(code_file)
run_code(code)
return TRUE
if("moveArgUp")
var/list/path = params["path"]
var/list/target_list = traverse_list(path, arguments, traversal_depth_offset = 1)
var/index = popleft(path)["index"]
target_list.Swap(index-1, index)
return TRUE
if("moveArgDown")
var/list/path = params["path"]
var/list/target_list = traverse_list(path, arguments, traversal_depth_offset = 1)
var/index = popleft(path)["index"]
target_list.Swap(index, index+1)
return TRUE
if("removeArg")
var/list/path = params["path"]
var/list/target_list = traverse_list(path, arguments, traversal_depth_offset = 1)
var/index = popleft(path)["index"]
target_list.Cut(index, index+1)
return TRUE
if("addArg")
var/list/path = params["path"]
var/list/target_list = traverse_list(path, arguments)
if(target_list != arguments)
user?.client?.mod_list_add(target_list, null, "a lua editor", "arguments")
else
var/list/vv_val = user?.client?.vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT))
var/class = vv_val["class"]
if(!class)
return
LAZYADD(arguments, list(vv_val["value"]))
return TRUE
if("callFunction")
var/list/recursive_indices = params["indices"]
var/list/current_list = kvpify_list(current_state.globals["values"])
var/list/current_variants = current_state.globals["variants"]
var/function = list()
while(LAZYLEN(recursive_indices))
var/index = popleft(recursive_indices)
var/list/element = current_list[index]
var/key = element["key"]
var/value = element["value"]
var/list/variant_pair = current_variants[index]
var/key_variant = variant_pair["key"]
if(key_variant == "function" || key_variant == "thread" || key_variant == "userdata" || key_variant == "error_as_value")
to_chat(user, span_warning("invalid table key \[[key]] for function call (expected text, num, path, list, or ref, got [key_variant])"))
return
function += key
if(islist(value))
current_list = value
current_variants = variant_pair["value"]
else
if(variant_pair["value"] != "function")
to_chat(user, span_warning("invalid value \[[value]] for function call (expected list or function)"))
return
var/result = current_state.call_function(arglist(list(function) + arguments))
current_state.log_result(result)
if(result["status"] == "error")
last_error = result["message"]
arguments.Cut()
return
if("resumeTask")
var/task_index = params["index"]
SSlua.queue_resume(current_state, task_index, arguments)
arguments.Cut()
return TRUE
if("killTask")
var/is_sleep = params["is_sleep"]
var/index = params["index"]
SSlua.kill_task(current_state, is_sleep, index)
return TRUE
if("vvReturnValue")
var/log_entry_index = params["entryIndex"]
var/list/log_entry = current_state.log[log_entry_index]
var/thing_to_debug = traverse_list(params["indices"], log_entry["return_values"])
if(isweakref(thing_to_debug))
var/datum/weakref/ref = thing_to_debug
thing_to_debug = ref.resolve()
INVOKE_ASYNC(user.client, TYPE_PROC_REF(/client, debug_variables), thing_to_debug)
return FALSE
if("vvGlobal")
var/thing_to_debug = traverse_list(params["indices"], current_state.globals["values"])
if(isweakref(thing_to_debug))
var/datum/weakref/ref = thing_to_debug
thing_to_debug = ref.resolve()
INVOKE_ASYNC(user.client, TYPE_PROC_REF(/client, debug_variables), thing_to_debug)
return FALSE
if("clearArgs")
arguments.Cut()
return TRUE
if("toggleShowGlobalTable")
show_global_table = !show_global_table
return TRUE
if("toggleSupressRuntimes")
current_state.supress_runtimes = !current_state.supress_runtimes
return TRUE
if("nextPage")
page = min(page+1, CEILING(current_state.log.len/50, 1)-1)
return TRUE
if("previousPage")
page = max(page-1, 0)
return TRUE
if("nukeLog")
current_state.log.Cut()
return TRUE
/datum/lua_editor/ui_close(mob/user)
. = ..()
qdel(src)
ADMIN_VERB(lua_editor, R_DEBUG, "Open Lua Editor", "Its codin' time.", ADMIN_CATEGORY_DEBUG)
var/datum/lua_editor/editor = new
editor.ui_interact(user.mob)