mirror of
https://github.com/JohnBreaux/Boat-Battle.git
synced 2024-11-14 21:15:58 +00:00
Debug: Cleanup scring concatenations, hide cheaty features behind a cheat code (it's unsalted sha256, and there are hints ;P), expand perf command to accept more verbose descriptions of performance counters.)
This commit is contained in:
parent
ff45799305
commit
c28b273249
@ -1,5 +1,7 @@
|
|||||||
extends Control
|
extends Control
|
||||||
|
|
||||||
|
# Hello, god class. Though, as an optional module, it's not the worst it could be.
|
||||||
|
# Smells of feature creep, because it absolutely is one.
|
||||||
|
|
||||||
var debug_canvas
|
var debug_canvas
|
||||||
|
|
||||||
@ -14,39 +16,46 @@ var history_pos = 0
|
|||||||
# Controls whether to print to the screen
|
# Controls whether to print to the screen
|
||||||
var echo = true
|
var echo = true
|
||||||
|
|
||||||
|
# Controls whether the player is allowed to cheat:
|
||||||
|
var cheats = false
|
||||||
|
var cheat_code = "989172bdaff124fc237b3f904a1886b91dc3ae718da15a6055ff416284f39a58"
|
||||||
|
|
||||||
onready var expression = Expression.new()
|
onready var expression = Expression.new()
|
||||||
|
|
||||||
# helptext: args list and help blurb accessed by function name
|
# metadata: args list, help blurb, and cheatmap accessed by function name
|
||||||
var helptext = {
|
enum {ARGS, HELPTEXT, IS_CHEAT}
|
||||||
# command_id [args "Help text" ]
|
var command_metadata = {
|
||||||
"command_help": [" [command]", "Print information about command.\n" ],
|
# command_id [args "Help text" is cheat]
|
||||||
"command_history": ["", "Print the history log.\n" ],
|
"command_help": [" [command]", "Print information about command.\n", false],
|
||||||
"command_perf": [" stat", "Print performance info (fps, nodes, proctime, ... )\n" ],
|
"command_history": ["", "Print the history log.\n", false],
|
||||||
|
"command_perf": [" stat", "Print performance info (fps, nodes, proctime, ... )\n", false],
|
||||||
|
|
||||||
"command_list": [" [path]", "List children of path, or of present working node.\n" ],
|
"command_list": [" [path]", "List children of path, or of present working node.\n", false],
|
||||||
"command_start": [" filename", "Load PackedScene filename.tscn as child.\n" ],
|
"command_start": [" filename", "Load PackedScene filename.tscn as child.\n", true ],
|
||||||
"command_kill": [" name", "Kill child node with matching name.\n" ],
|
"command_kill": [" name", "Kill child node with matching name.\n", true ],
|
||||||
|
|
||||||
"command_pwd": ["", "Print the Present Working Node.\n" ],
|
"command_pwd": ["", "Print the Present Working Node.\n", false],
|
||||||
"command_cd": [" path", "Change the Present Working Node to path.\n" ],
|
"command_cd": [" path", "Change the Present Working Node to path.\n", false],
|
||||||
|
|
||||||
"command_print": [" string", "Print string to the in-game debug console.\n" ],
|
"command_print": [" string", "Print string to the in-game debug console.\n", false],
|
||||||
"command_clear": ["", "Clear the debug output.\n" ],
|
"command_clear": ["", "Clear the debug output.\n", false],
|
||||||
# !EXTREMELY DANGER {
|
# !EXTREMELY DANGER {
|
||||||
"command_emit": [" signal [message]", "Emit a message on MessageBus.signal without validation.\n"],
|
"command_emit": [" signal [message]", "Emit a message on MessageBus.signal without validation.\n", true ],
|
||||||
"command_call": [" func [args ...]", "Call func(...) with arguments args.\n" ],
|
"command_call": [" func [args ...]", "Call func(...) with arguments args.\n", true ],
|
||||||
"command_exec": [" expression ...", "Evaluate an arbitrary expression, and print the result.\n"],
|
"command_exec": [" expression ...", "Evaluate an arbitrary expression, and print the result.\n", true ],
|
||||||
# }
|
# }
|
||||||
"command_listprops": ["", "List properties of the Present Working Node\n" ],
|
"command_listprops": ["", "List properties of the Present Working Node\n", true ],
|
||||||
"command_getprop": [" prop", "Get the value of property prop\n" ],
|
"command_getprop": [" prop", "Get the value of property prop\n", true ],
|
||||||
"command_setprop": [" prop value", "Set the property prop to value.\n" ],
|
"command_setprop": [" prop value", "Set the property prop to value.\n", true ],
|
||||||
|
|
||||||
"command_script": [" path", "Load and execute a script at user://scripts/<name>\n" ],
|
"command_script": [" path", "Load and execute a script at user://scripts/<name>\n", false],
|
||||||
"command_echo": [" on/off", "Controls whether lines should be printed to the screen\n" ],
|
"command_echo": [" on/off", "Controls whether lines should be printed to the screen\n", true ],
|
||||||
"command_restart": ["", "Kill the current scene tree and plant a new Root.\n" ],
|
"command_cheat": [" [password]", "Controls whether cheats are enabled, using a fun code\n", false],
|
||||||
"command_exit": ["", "Quits the program.\n" ],
|
|
||||||
|
|
||||||
"command_empty": ["", "No Operation.\n" ],
|
"command_restart": ["", "Kill the current scene tree and plant a new Root.\n", true ],
|
||||||
|
"command_exit": ["", "Quits the program.\n", false],
|
||||||
|
|
||||||
|
"command_empty": ["", "No Operation.\n", false],
|
||||||
}
|
}
|
||||||
|
|
||||||
# List of debug commands accessed by alias
|
# List of debug commands accessed by alias
|
||||||
@ -77,6 +86,8 @@ var commands = {
|
|||||||
|
|
||||||
["script", "sh"]: "command_script",
|
["script", "sh"]: "command_script",
|
||||||
["@echo"]: "command_echo",
|
["@echo"]: "command_echo",
|
||||||
|
["cheat", "*"]: "command_cheat",
|
||||||
|
|
||||||
["restart", "killall"]: "command_restart",
|
["restart", "killall"]: "command_restart",
|
||||||
["exit", "quit"]: "command_exit",
|
["exit", "quit"]: "command_exit",
|
||||||
|
|
||||||
@ -177,10 +188,19 @@ func _on_LineEdit_text_entered(line):
|
|||||||
# returns: name of executed function, or null if nothing executed
|
# returns: name of executed function, or null if nothing executed
|
||||||
func execute_command(command):
|
func execute_command(command):
|
||||||
var command_func = parse(command[0])
|
var command_func = parse(command[0])
|
||||||
if command_func:
|
if command_func and is_command_allowed(command_func):
|
||||||
call(command_func, command)
|
call(command_func, command)
|
||||||
|
else:
|
||||||
|
command_func = null
|
||||||
return command_func
|
return command_func
|
||||||
|
|
||||||
|
# is_command_allowed: Test if the command is allowed (not cheating, or cheating is on)
|
||||||
|
# params: command_func: the name of the function to be executed
|
||||||
|
# returns: true if command is valid, or false if command is cheat and cheating is disabled
|
||||||
|
func is_command_allowed(command_func):
|
||||||
|
# return true if cheats or on, or command is not cheat
|
||||||
|
return cheats or not command_metadata[command_func][IS_CHEAT]
|
||||||
|
|
||||||
# History_related helper functions:
|
# History_related helper functions:
|
||||||
# history_append: add a line of text to the history
|
# history_append: add a line of text to the history
|
||||||
# params: text: line of text (unparsed command) to add to history
|
# params: text: line of text (unparsed command) to add to history
|
||||||
@ -262,7 +282,7 @@ func get_canonical(alias):
|
|||||||
# params: alias: alias of a command
|
# params: alias: alias of a command
|
||||||
# returns: usage string for the command, formatted for printing
|
# returns: usage string for the command, formatted for printing
|
||||||
func get_usage(alias):
|
func get_usage(alias):
|
||||||
return "Usage: " + alias + helptext[parse(alias)][0] + "\n"
|
return "Usage: " + alias + command_metadata[parse(alias)][0] + "\n"
|
||||||
|
|
||||||
# String casting functions
|
# String casting functions
|
||||||
# variant_to_string: Cast arbitrary GDScript Variant to String
|
# variant_to_string: Cast arbitrary GDScript Variant to String
|
||||||
@ -321,7 +341,7 @@ func string_to_variant(string, type):
|
|||||||
TYPE_COLOR_ARRAY:
|
TYPE_COLOR_ARRAY:
|
||||||
res = PoolColorArray(list)
|
res = PoolColorArray(list)
|
||||||
_:
|
_:
|
||||||
debug_print_line("No cast from String to " + types[typeof(type)] + "\n")
|
debug_print_line("No cast from String to %s\n" % types[typeof(type)])
|
||||||
return res
|
return res
|
||||||
|
|
||||||
# listify_string: takes a string and turns it into a list, by splitting on commas and/or spaces
|
# listify_string: takes a string and turns it into a list, by splitting on commas and/or spaces
|
||||||
@ -342,9 +362,9 @@ func listify_string(string):
|
|||||||
# start: Loads scene from res://scenes/*.tscn by filename, and starts it
|
# start: Loads scene from res://scenes/*.tscn by filename, and starts it
|
||||||
func command_start (command):
|
func command_start (command):
|
||||||
if command.size() > 1:
|
if command.size() > 1:
|
||||||
var pack = load("res://scenes/" + command[1] + ".tscn");
|
var pack = load("res://scenes/%s.tscn" % command[1])
|
||||||
get_pwn().add_child(pack.instance());
|
get_pwn().add_child(pack.instance());
|
||||||
debug_print_line("started '" + command[1] + "'\n")
|
debug_print_line("started '%s'\n" % command[1])
|
||||||
else:
|
else:
|
||||||
debug_print_line(get_usage(command[0]))
|
debug_print_line(get_usage(command[0]))
|
||||||
|
|
||||||
@ -357,9 +377,9 @@ func command_kill (command):
|
|||||||
debug_print_line("YOU DIDN'T SAY THE MAGIC WORD!\n")
|
debug_print_line("YOU DIDN'T SAY THE MAGIC WORD!\n")
|
||||||
else:
|
else:
|
||||||
node.queue_free()
|
node.queue_free()
|
||||||
debug_print_line(command[1] + " killed\n")
|
debug_print_line("%s killed\n" % command[1])
|
||||||
else:
|
else:
|
||||||
debug_print_line(command[0] + ": " + command[1] + " not found.\n")
|
debug_print_line("%s: %s not found.\n" % [command[0], command[1]])
|
||||||
else:
|
else:
|
||||||
debug_print_line(get_usage(command[0]))
|
debug_print_line(get_usage(command[0]))
|
||||||
|
|
||||||
@ -393,10 +413,10 @@ func command_emit (command):
|
|||||||
var mbus_signal = command[1].split(' ', true, 1)
|
var mbus_signal = command[1].split(' ', true, 1)
|
||||||
match mbus_signal.size():
|
match mbus_signal.size():
|
||||||
2:
|
2:
|
||||||
debug_print_line("Message: " + String(mbus_signal) + "\n")
|
debug_print_line("Message: %s (%s)" % mbus_signal)
|
||||||
MessageBus.emit_signal(mbus_signal[0], mbus_signal[1])
|
MessageBus.emit_signal(mbus_signal[0], mbus_signal[1])
|
||||||
1:
|
1:
|
||||||
debug_print_line("Message: " + String(mbus_signal) + "\n")
|
debug_print_line("Message: %s" % mbus_signal)
|
||||||
MessageBus.emit_signal(mbus_signal[0])
|
MessageBus.emit_signal(mbus_signal[0])
|
||||||
0: debug_print_line(get_usage(command[0]))
|
0: debug_print_line(get_usage(command[0]))
|
||||||
else:
|
else:
|
||||||
@ -426,18 +446,18 @@ func command_help (command):
|
|||||||
if (command.size() == 1):
|
if (command.size() == 1):
|
||||||
debug_print_line("Valid commands:\n")
|
debug_print_line("Valid commands:\n")
|
||||||
for key in commands:
|
for key in commands:
|
||||||
debug_print_line(key[0] + " ")
|
# if command is allowed in current context, print it
|
||||||
|
if is_command_allowed(commands[key]):
|
||||||
|
debug_print_line(key[0] + " ")
|
||||||
debug_print_line("\n")
|
debug_print_line("\n")
|
||||||
else:
|
else:
|
||||||
var command_func = parse(command[1])
|
var command_func = parse(command[1])
|
||||||
var aliases
|
if command_func in command_metadata and is_command_allowed(command_func):
|
||||||
var text
|
var text = command_metadata[command_func]
|
||||||
if command_func in helptext:
|
var aliases = String(lookup(command[1]))
|
||||||
text = helptext[command_func]
|
debug_print_line("%s%s:\n Aliases: %s\n %s" % [command[1], text[ARGS], aliases, text[HELPTEXT]])
|
||||||
aliases = lookup(command[1])
|
|
||||||
debug_print_line(command[1] + text[0] + ":\n Aliases: " + String(aliases) + "\n "+ text[1])
|
|
||||||
else:
|
else:
|
||||||
debug_print_line(get_canonical(command[0]) + ": command not found: " + command[1] + "\n")
|
debug_print_line("%s: command not found: %s\n" % [command[0], command[1]])
|
||||||
|
|
||||||
# exit: request program exit
|
# exit: request program exit
|
||||||
func command_exit(_command):
|
func command_exit(_command):
|
||||||
@ -457,7 +477,7 @@ func command_call(command):
|
|||||||
debug_print_line("We're sorry, but your call could not be completed as dialed.\n"
|
debug_print_line("We're sorry, but your call could not be completed as dialed.\n"
|
||||||
+ "Please hang up and try your call again.\n")
|
+ "Please hang up and try your call again.\n")
|
||||||
return
|
return
|
||||||
debug_print_line(variant_to_string(call_ret) + "\n")
|
debug_print_line("%s\n" % variant_to_string(call_ret))
|
||||||
else:
|
else:
|
||||||
debug_print_line(get_usage(command[0]))
|
debug_print_line(get_usage(command[0]))
|
||||||
|
|
||||||
@ -469,11 +489,11 @@ func command_exec(command):
|
|||||||
if err == OK:
|
if err == OK:
|
||||||
res = expression.execute([], get_pwn(), false);
|
res = expression.execute([], get_pwn(), false);
|
||||||
if expression.has_execute_failed():
|
if expression.has_execute_failed():
|
||||||
debug_print_line(command[0] + ": command not found: " + command[1])
|
debug_print_line("%s: command not found: %s " % [command[0], command[1]])
|
||||||
res = ""
|
res = ""
|
||||||
else:
|
else:
|
||||||
res = expression.get_error_text()
|
res = expression.get_error_text()
|
||||||
debug_print_line(variant_to_string(res) + "\n")
|
debug_print_line("%s\n" % variant_to_string(res))
|
||||||
else:
|
else:
|
||||||
debug_print_line(get_usage(command[0]))
|
debug_print_line(get_usage(command[0]))
|
||||||
|
|
||||||
@ -484,10 +504,11 @@ func command_listprops(_command):
|
|||||||
proplist.sort_custom(self, "propSort")
|
proplist.sort_custom(self, "propSort")
|
||||||
for prop in proplist:
|
for prop in proplist:
|
||||||
if prop["name"]:
|
if prop["name"]:
|
||||||
props += "" + types[prop["type"]] + " " + prop["name"] + "\n"
|
props += "%s %s\n" % [types[prop["type"]], prop["name"]]
|
||||||
pass
|
pass
|
||||||
debug_print_line(props)
|
debug_print_line(props)
|
||||||
pass
|
pass
|
||||||
|
# propsort: sort props by type, alphabetically
|
||||||
func propSort(a, b):
|
func propSort(a, b):
|
||||||
if a["type"] == b["type"]:
|
if a["type"] == b["type"]:
|
||||||
return a["name"] < b["name"]
|
return a["name"] < b["name"]
|
||||||
@ -518,7 +539,7 @@ func command_history(_command):
|
|||||||
var lnum = 0
|
var lnum = 0
|
||||||
for line in history:
|
for line in history:
|
||||||
if line:
|
if line:
|
||||||
debug_print_line(String(lnum) + ": " + line + "\n")
|
debug_print_line("%2d: %s\n" % [lnum, line])
|
||||||
lnum += 1
|
lnum += 1
|
||||||
#debug_print_line("history_pos = " + String(history_pos) + "\n")
|
#debug_print_line("history_pos = " + String(history_pos) + "\n")
|
||||||
|
|
||||||
@ -527,7 +548,7 @@ func command_perf(command):
|
|||||||
if command.size() > 1:
|
if command.size() > 1:
|
||||||
var stat = perf(command[1])
|
var stat = perf(command[1])
|
||||||
if stat:
|
if stat:
|
||||||
debug_print_line(String(stat) + "\n")
|
debug_print_line("%s\n" % String(stat))
|
||||||
else:
|
else:
|
||||||
debug_print_line("null\n")
|
debug_print_line("null\n")
|
||||||
else:
|
else:
|
||||||
@ -546,11 +567,12 @@ func command_script(command):
|
|||||||
script.push_back(f.get_line())
|
script.push_back(f.get_line())
|
||||||
f.close()
|
f.close()
|
||||||
# Save state and turn off echo
|
# Save state and turn off echo
|
||||||
var state = {"echo": echo,
|
var state = {"echo": echo,
|
||||||
"pwn": present_working_node,
|
"pwn": present_working_node,
|
||||||
"history_pos": history_pos,
|
"history_pos": history_pos,
|
||||||
"history": history,
|
"history": history,
|
||||||
"expression": expression}
|
"expression": expression,
|
||||||
|
"cheats": cheats}
|
||||||
echo = false
|
echo = false
|
||||||
# Execute the script
|
# Execute the script
|
||||||
for cmd in script:
|
for cmd in script:
|
||||||
@ -562,21 +584,85 @@ func command_script(command):
|
|||||||
history_pos = state["history_pos"]
|
history_pos = state["history_pos"]
|
||||||
history = state["history"]
|
history = state["history"]
|
||||||
expression = state["expression"]
|
expression = state["expression"]
|
||||||
|
cheats = state["cheats"]
|
||||||
else:
|
else:
|
||||||
debug_print_line("File not found: " + command[1] + "\n")
|
debug_print_line("File not found: " + command[1] + "\n")
|
||||||
else:
|
else:
|
||||||
debug_print_line(get_usage(command[0]))
|
debug_print_line(get_usage(command[0]))
|
||||||
|
|
||||||
|
# echo: enable and disable echoing commands and their outputs to the terminal
|
||||||
func command_echo(command):
|
func command_echo(command):
|
||||||
if command.size() > 1:
|
if command.size() > 1:
|
||||||
echo = string_to_variant(command[1], TYPE_BOOL)
|
echo = string_to_variant(command[1], TYPE_BOOL)
|
||||||
else:
|
else:
|
||||||
debug_print_line(get_usage(command[0]))
|
debug_print_line(get_usage(command[0]))
|
||||||
|
|
||||||
|
# cheat: Disable cheats, or enable them if you say the magic word
|
||||||
|
func command_cheat(command):
|
||||||
|
# check if there's more than one input to the command:
|
||||||
|
if command.size() > 1:
|
||||||
|
# hash the password
|
||||||
|
var code = command[1].sha256_text()
|
||||||
|
if code == cheat_code:
|
||||||
|
debug_print_line("Cheats enabled.\n")
|
||||||
|
cheats = true
|
||||||
|
return
|
||||||
|
debug_print_line("Ah ah ah, you didn't say the magic word!\n")
|
||||||
|
cheats = false
|
||||||
|
debug_print_line("Cheats disabled.\n")
|
||||||
|
pass
|
||||||
|
|
||||||
|
# look-up table for performance monitor -> index pairs
|
||||||
|
# See https://docs.godotengine.org/en/stable/classes/class_performance.html
|
||||||
|
const monitor_lookup = {
|
||||||
|
# Time
|
||||||
|
"time:fps": 0,
|
||||||
|
"time:process": 1,
|
||||||
|
"time:physics process": 2,
|
||||||
|
# Memory
|
||||||
|
"memory:static": 3,
|
||||||
|
"memory:dynamic": 4,
|
||||||
|
"memory:static max": 5,
|
||||||
|
"memory:dynamic max": 6,
|
||||||
|
"memory:message buffer max": 7,
|
||||||
|
# Objects
|
||||||
|
"object:count": 8,
|
||||||
|
"object:resource count": 9,
|
||||||
|
"object:node count": 10,
|
||||||
|
"object:orphan node count": 11,
|
||||||
|
# Render
|
||||||
|
"render:objects in frame": 12,
|
||||||
|
"render:vertices in frame": 13,
|
||||||
|
"render:material changes in frame": 14,
|
||||||
|
"render:shader changes in frame": 15,
|
||||||
|
"render:surface changes in frame": 16,
|
||||||
|
"render:draw calls in frame": 17,
|
||||||
|
"render:2d items in frame": 18,
|
||||||
|
"render:2d draw calls in frame": 19,
|
||||||
|
"render:video memory used": 20,
|
||||||
|
"render:texture memory used": 21,
|
||||||
|
"render:vertex memory used": 22,
|
||||||
|
"render:total video memory used": 23,
|
||||||
|
# Physics2D
|
||||||
|
"physics2d:active objects": 24,
|
||||||
|
"physics2d:collision pairs": 25,
|
||||||
|
"physics2d:island count":26,
|
||||||
|
# Physics3D
|
||||||
|
"physics3d:active objects": 27,
|
||||||
|
"physics3d:collision pairs": 28,
|
||||||
|
"physics3d:island count": 29,
|
||||||
|
# Audio
|
||||||
|
"audio:output latency": 30
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get a performance counter given a string
|
||||||
func perf(attribute):
|
func perf(attribute):
|
||||||
if attribute.is_valid_integer():
|
if attribute.is_valid_integer():
|
||||||
return Performance.get_monitor(int(attribute))
|
return Performance.get_monitor(int(attribute))
|
||||||
match attribute:
|
if attribute in monitor_lookup:
|
||||||
|
return Performance.get_monitor(monitor_lookup[attribute.to_lower()])
|
||||||
|
# Shortcut to popular counters
|
||||||
|
match attribute.to_lower():
|
||||||
"fps":
|
"fps":
|
||||||
return Performance.get_monitor(Performance.TIME_FPS)
|
return Performance.get_monitor(Performance.TIME_FPS)
|
||||||
"proctime":
|
"proctime":
|
||||||
|
Loading…
Reference in New Issue
Block a user