mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-13 03:02:38 +00:00
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
286 lines
9.9 KiB
Plaintext
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)
|