Skip to content

Commit

Permalink
fix: properly parse all types of command line arg values (GodotModdin…
Browse files Browse the repository at this point in the history
…g#103)

* fix: properly parse all types of command line arg values

* refactor: adjust code line in doc comments

* refactor: add cmdline arg fixing wrapper function

* fix: also cover args without =
  • Loading branch information
Qubus0 authored and KANAjetzt committed Feb 23, 2023
1 parent 82d2385 commit 3b2257c
Showing 1 changed file with 63 additions and 8 deletions.
71 changes: 63 additions & 8 deletions addons/mod_loader/mod_loader_utils.gd
Original file line number Diff line number Diff line change
Expand Up @@ -188,25 +188,80 @@ static func _get_verbosity() -> int:
# Check if the provided command line argument was present when launching the game
static func is_running_with_command_line_arg(argument: String) -> bool:
for arg in OS.get_cmdline_args():
if arg == argument:
if argument == arg.split("=")[0]:
return true

return false


# Get the command line argument value if present when launching the game
static func get_cmd_line_arg_value(argument: String) -> String:
for arg in OS.get_cmdline_args():
if (arg as String).find("=") > -1:
var key_value := (arg as String).split("=")
# True if the checked argument matches a user-specified arg key
# (eg. checking `--mods-path` will match with `--mods-path="C://mods"`
if key_value[0] == argument:
return key_value[1]
var args := get_fixed_cmdline_args()

for arg_index in args.size():
var arg := args[arg_index] as String

var key := arg.split("=")[0]
if key == argument:
# format: `--arg=value` or `--arg="value"`
if "=" in arg:
var value := arg.trim_prefix(argument + "=")
value = value.trim_prefix('"').trim_suffix('"')
value = value.trim_prefix("'").trim_suffix("'")
return value

# format: `--arg value` or `--arg "value"`
elif arg_index +1 < args.size() and not args[arg_index +1].begins_with("--"):
return args[arg_index + 1]

return ""


static func get_fixed_cmdline_args() -> PoolStringArray:
return fix_godot_cmdline_args_string_space_splitting(OS.get_cmdline_args())


# Reverses a bug in Godot, which splits input strings at spaces even if they are quoted
# e.g. `--arg="some value" --arg-two 'more value'` becomes `[ --arg="some, value", --arg-two, 'more, value' ]`
static func fix_godot_cmdline_args_string_space_splitting(args: PoolStringArray) -> PoolStringArray:
if not OS.has_feature("editor"): # only happens in editor builds
return args
if OS.has_feature("Windows"): # windows is unaffected
return args

var fixed_args := PoolStringArray([])
var fixed_arg := ""
# if we encounter an argument that contains `=` followed by a quote,
# or an argument that starts with a quote, take all following args and
# concatenate them into one, until we find the closing quote
for arg in args:
var arg_string := arg as String
if '="' in arg_string or '="' in fixed_arg or \
arg_string.begins_with('"') or fixed_arg.begins_with('"'):
if not fixed_arg == "":
fixed_arg += " "
fixed_arg += arg_string
if arg_string.ends_with('"'):
fixed_args.append(fixed_arg.trim_prefix(" "))
fixed_arg = ""
continue
# same thing for single quotes
elif "='" in arg_string or "='" in fixed_arg \
or arg_string.begins_with("'") or fixed_arg.begins_with("'"):
if not fixed_arg == "":
fixed_arg += " "
fixed_arg += arg_string
if arg_string.ends_with("'"):
fixed_args.append(fixed_arg.trim_prefix(" "))
fixed_arg = ""
continue

else:
fixed_args.append(arg_string)

return fixed_args


# Returns the current time as a string in the format hh:mm:ss
static func get_time_string() -> String:
var date_time = Time.get_datetime_dict_from_system()
Expand Down

0 comments on commit 3b2257c

Please sign in to comment.