Replaces Auxlua with the byondapi-based Dreamluau (#84810)

## About The Pull Request

Ever since byondapi went stable, I've been meaning to create a
replacement lua library that uses it instead of the auxtools-based
auxlua. After so many months, I've finally got the code just about into
a position where it's ready for a PR.

[Click here](https://hackmd.io/@aloZJicNQrmfYgykhfFwAQ/BySAS18u0) for a
guide to rewriting auxlua scripts for dreamluau syntax.

## Why It's Good For The Game

Code that runs on production servers should not depend on memory hacks
that are liable to break any time Dream Daemon updates.

## Changelog

🆑
admin: Admin lua scripting uses a new library that (probably) will not
break when BYOND updates.
/🆑

## TODO:
- [x] Convert the lua editor ui to TS
- [x] Include a guide for converting scripts from auxlua syntax to
dreamluau syntax
This commit is contained in:
Y0SH1M4S73R
2024-07-28 14:45:49 -04:00
committed by GitHub
parent b6fd0d1697
commit d1ccb530b2
47 changed files with 13888 additions and 1753 deletions
+71 -29
View File
@@ -16,6 +16,12 @@
/// 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)
@@ -37,37 +43,51 @@
/datum/lua_editor/ui_state(mob/user)
return GLOB.debug_state
/datum/lua_editor/ui_static_data(mob/user)
var/list/data = list()
data["documentation"] = file2text('code/modules/admin/verbs/lua/README.md')
data["auxtools_enabled"] = CONFIG_GET(flag/auxtools_enabled)
data["ss_lua_init"] = SSlua.initialized
return data
/datum/lua_editor/ui_data(mob/user)
var/list/data = list()
if(!CONFIG_GET(flag/auxtools_enabled) || !SSlua.initialized)
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)
data["stateLog"] = kvpify_list(refify_list(current_state.log.Copy((page*50)+1, min((page+1)*50+1, current_state.log.len+1))))
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()
data["globals"] = kvpify_list(refify_list(current_state.globals))
data["states"] = SSlua.states
data["callArguments"] = kvpify_list(refify_list(arguments))
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["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)
@@ -99,6 +119,15 @@
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)
. = ..()
if(.)
@@ -116,6 +145,8 @@
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
@@ -130,11 +161,14 @@
page = 0
return TRUE
if("runCode")
var/code = params["code"]
current_state.ckey_last_runner = usr.ckey
var/result = current_state.load_script(code)
var/index_with_result = current_state.log_result(result)
message_admins("[key_name(usr)] executed [length(code)] bytes of lua code. [ADMIN_LUAVIEW_CHUNK(current_state, index_with_result)]")
run_code(params["code"])
return TRUE
if("runFile")
var/code_file = input(usr, "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"]
@@ -168,27 +202,31 @@
return TRUE
if("callFunction")
var/list/recursive_indices = params["indices"]
var/list/current_list = kvpify_list(current_state.globals)
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"]
if(!(istext(key) || isnum(key)))
to_chat(usr, span_warning("invalid key \[[key]] for function call (expected text or num)"))
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(usr, 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
var/regex/function_regex = regex("^function: 0x\[0-9a-fA-F]+$")
if(function_regex.Find(value))
break
to_chat(usr, span_warning("invalid path element \[[value]] for function call (expected list or text matching [function_regex])"))
return
if(variant_pair["value"] != "function")
to_chat(usr, 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 TRUE
if("resumeTask")
@@ -197,20 +235,21 @@
arguments.Cut()
return TRUE
if("killTask")
var/task_info = params["info"]
SSlua.kill_task(current_state, task_info)
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["tableIndices"], log_entry["param"])
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(usr.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)
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()
@@ -228,6 +267,9 @@
if("previousPage")
page = max(page-1, 0)
return TRUE
if("nukeLog")
current_state.log.Cut()
return TRUE
/datum/lua_editor/ui_close(mob/user)
. = ..()