Browse Source

Allow shell arguments, add start-multiple.sh

This will make testing MUCH better, I do believe.
master
Luna 7 years ago
parent
commit
c53b017019
4 changed files with 259 additions and 6 deletions
  1. +2
    -1
      scenes/lobby.tscn
  2. +181
    -0
      scripts/args.gd
  3. +59
    -5
      scripts/lobby.gd
  4. +17
    -0
      util/start-multiple.sh

+ 2
- 1
scenes/lobby.tscn View File

@ -60,6 +60,7 @@ align = 1
[node name="ServerStart" type="Button" parent="." index="1"]
visible = false
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
@ -104,7 +105,7 @@ action_mode = 0
enabled_focus_mode = 2
shortcut = null
group = null
text = "Platforms"
text = "Platform map"
flat = false
align = 0
selected = 0


+ 181
- 0
scripts/args.gd View File

@ -0,0 +1,181 @@
# Adapted from: https://gist.github.com/bitwes/fe1e2aef8da0940104c8
# Example of a script that can be run from the command line and parses out options. This is adapted
# from the Gut command line interface. The first 2 classes are not to be used directly, they are used
# by the Options class and can be ignored. Start reading after the Options class to get a feel for
# how it is used, then work backwards.
#
# This could be easily extracted out into a class itself, but in the interest of how it is being used
# I wanted it all in one file. It is yours to do with what you please, but if you make something out
# of it, I'd love to hear about it. I'm bitwes on godot forums, github, and bitbucket.
extends Control
#-------------------------------------------------------------------------------
# Parses the command line arguments supplied into an array that can then be
# examined and parsed based on how the gut options work.
#-------------------------------------------------------------------------------
class CmdLineParser:
var _opts = []
func _init():
for i in range(OS.get_cmdline_args().size()):
_opts.append(OS.get_cmdline_args()[i])
# Search _opts for an element that starts with the option name
# specified.
func find_option(name):
var found = false
var idx = 0
while(idx < _opts.size() and !found):
if(_opts[idx].find(name) == 0):
found = true
else:
idx += 1
if(found):
return idx
else:
return -1
# Parse out the value of an option. Values are seperated from
# the option name with "="
func get_option_value(full_option):
var split = full_option.split('=')
if(split.size() > 1):
return split[1]
else:
return null
# Parse out multiple comma delimited values from a command line
# option. Values are separated from option name with "=" and
# additional values are comma separated.
func get_option_array_value(full_option):
var value = get_option_value(full_option)
var split = value.split(',')
return split
func get_array_value(option):
var to_return = []
var opt_loc = find_option(option)
if(opt_loc != -1):
to_return = get_option_array_value(_opts[opt_loc])
_opts.remove(opt_loc)
return to_return
# returns the value of an option if it was specfied, otherwise
# it returns the default.
func get_value(option, default):
var to_return = default
var opt_loc = find_option(option)
if(opt_loc != -1):
to_return = get_option_value(_opts[opt_loc])
_opts.remove(opt_loc)
return to_return
# returns true if it finds the option, false if not.
func was_specified(option):
var opt_loc = find_option(option)
if(opt_loc != -1):
_opts.remove(opt_loc)
return opt_loc != -1
#-------------------------------------------------------------------------------
# Simple class to hold a command line option
#-------------------------------------------------------------------------------
class Option:
var value = null
var option_name = ''
var default = null
var description = ''
func _init(name, default_value, desc=''):
option_name = name
default = default_value
description = desc
value = default_value
func pad(value, size, pad_with=' '):
var to_return = value
for i in range(value.length(), size):
to_return += pad_with
return to_return
func to_s(min_space=0):
var subbed_desc = description
if(subbed_desc.find('[default]') != -1):
subbed_desc = subbed_desc.replace('[default]', str(default))
return pad(option_name, min_space) + subbed_desc
#-------------------------------------------------------------------------------
# The high level interface between this script and the command line options
# supplied. Uses Option class and CmdLineParser to extract information from
# the command line and make it easily accessible.
#-------------------------------------------------------------------------------
class Options:
var options = []
var _opts = []
var _banner = ''
func add(name, default, desc):
options.append(Option.new(name, default, desc))
func get_value(name):
var found = false
var idx = 0
while(idx < options.size() and !found):
if(options[idx].option_name == name):
found = true
else:
idx += 1
if(found):
return options[idx].value
else:
print("COULD NOT FIND OPTION " + name)
return null
func set_banner(banner):
_banner = banner
func print_help():
var longest = 0
for i in range(options.size()):
if(options[i].option_name.length() > longest):
longest = options[i].option_name.length()
print('---------------------------------------------------------')
print(_banner)
print("\nOptions\n-------")
for i in range(options.size()):
print(' ' + options[i].to_s(longest + 2))
print('---------------------------------------------------------')
func print_options():
for i in range(options.size()):
print(options[i].option_name + '=' + str(options[i].value))
func parse():
var parser = CmdLineParser.new()
for i in range(options.size()):
var t = typeof(options[i].default)
if(t == TYPE_INT):
options[i].value = int(parser.get_value(options[i].option_name, options[i].default))
elif(t == TYPE_STRING):
options[i].value = parser.get_value(options[i].option_name, options[i].default)
elif(t == TYPE_ARRAY):
options[i].value = parser.get_array_value(options[i].option_name)
elif(t == TYPE_BOOL):
options[i].value = parser.was_specified(options[i].option_name)
elif(t == TYPE_NIL):
print(options[i].option_name + ' cannot be processed, it has a nil datatype')
else:
print(options[i].option_name + ' cannot be processsed, it has unknown datatype:' + str(t))

+ 59
- 5
scripts/lobby.gd View File

@ -1,4 +1,4 @@
extends Control
extends "res://scripts/args.gd"
# class member variables go here, for example:
# var a = 2
@ -10,7 +10,56 @@ var SERVER_PLAYING = true
var player_info = {}
var my_info = {}
func setup_options():
var opts = Options.new()
opts.set_banner(('A non-violent MOBA inspired by Overwatch and Zineth'))
opts.add('-singleplayer', false, 'Whether to run singeplayer, starting immediately')
opts.add('-server', false, 'Whether to run as server')
opts.add('-client', false, 'Immediately connect as client')
opts.add('-silent-server', false, 'If the server is not playing, merely serving')
opts.add('-hero', 'r', 'Your choice of hero (index)')
opts.add('-level', 'r', 'Your choice of level (index) - server only!')
opts.add('-start-game', false, 'Join as a client and immediately start the game')
opts.add('-h', false, "Print help")
return opts
func option_sel(button_name, option):
var button = get_node(button_name)
print("-->")
if option == "r":
option = randi() % button.get_item_count()
print(randi() % 3)
else:
option = int(option)
button.select(option)
func _ready():
var o = setup_options()
o.parse()
randomize()
if o.get_value("-silent-server"):
SERVER_PLAYING = false # TODO: Uncaps :(
if o.get_value("-hero"):
option_sel("HeroSelect", o.get_value("-hero"))
print(get_node("HeroSelect").get_selected_id())
if o.get_value("-level"):
option_sel("ServerStart/LevelSelect", o.get_value("-level"))
if o.get_value("-server"):
call_deferred("_server_init")
if o.get_value("-client"):
call_deferred("_client_init")
if o.get_value("-start-game"):
my_info.start_game = true
call_deferred("_client_init")
if o.get_value("-singleplayer"):
call_deferred("_singleplayer_init")
if o.get_value('-h'):
o.print_help()
quit()
# Called every time the node is added to the scene.
# Initialization here
get_node("Server").connect("pressed", self, "_server_init")
@ -54,11 +103,16 @@ func _player_connected(id):
func _connected_ok():
rpc("register_player", get_tree().get_network_unique_id(), my_info)
if "start_game" in my_info:
rpc_id(1, "start_game")
func collect_info():
my_info.username = get_node("Username").get_text()
my_info.hero = get_node("HeroSelect").get_selected_id()
my_info.is_right_team = false # Server assigns team, wait for that
if not "username" in my_info:
my_info.username = get_node("Username").get_text()
if not "hero" in my_info:
my_info.hero = get_node("HeroSelect").get_selected_id()
if not "is_right_team" in my_info:
my_info.is_right_team = false # Server assigns team, wait for that
remote func register_player(new_peer, info):
player_info[new_peer] = info
@ -113,7 +167,7 @@ func render_player_list():
list += "\n"
get_node("PlayerList").set_text(list)
func start_game():
sync func start_game():
var level = get_node("ServerStart/LevelSelect").get_selected_id()
rpc("pre_configure_game", level)


+ 17
- 0
util/start-multiple.sh View File

@ -0,0 +1,17 @@
#!/bin/sh
count=$1
if [[ $count ]]; then
shift # Only do this if arg exists (fixes error)
else
count=2 # Default 2
fi
godot -server "$@" &
for i in `seq 3 $count` # 3, for 1 + the server + the starter
do
godot -client "$@" &
done
sleep 1
godot -start-game "$@" &

Loading…
Cancel
Save