177 lines
5.8 KiB
GDScript
177 lines
5.8 KiB
GDScript
extends Node
|
|
|
|
const MAX_PEERS = 4
|
|
const LOBBY_READY_WAIT_TIME = 3
|
|
const EMPTY_WAIT_TIME = 30
|
|
const EMPTY_CLOSING_TIME = 60
|
|
|
|
var port:int = -1
|
|
var dedicated_server:bool = false
|
|
var server_secret:String = ""
|
|
var server_id:String = "[GAME:-1] "
|
|
|
|
var timer:Timer
|
|
|
|
signal server_error(type, data)
|
|
|
|
|
|
func _ready():
|
|
for argument in OS.get_cmdline_args():
|
|
if argument.split("=")[0] == "--port":
|
|
dedicated_server = true
|
|
port = int(argument.split("=")[1])
|
|
if argument.split("=")[0] == "--server-id":
|
|
server_id = "[GAME:" + str(argument.split("=")[1]) + "] "
|
|
if argument.split("=")[0] == "--secret":
|
|
server_secret=argument.split("=")[1]
|
|
if argument.split("=")[0] == "--bots":
|
|
gamestate.set_bots(bool(int(argument.split("=")[1])))
|
|
if argument.split("=")[0] == "--bot-difficulty":
|
|
gamestate.set_bot_difficulty(float(argument.split("=")[1]))
|
|
if argument.split("=")[0] == "--server-addr":
|
|
game_server.set_server_addr(str(argument.split("=")[1]))
|
|
if argument.split("=")[0] == "--api-addr":
|
|
game_server.set_api_addr(str(argument.split("=")[1]))
|
|
|
|
if dedicated_server:
|
|
var err = host_game(port)
|
|
if err == OK:
|
|
print(server_id + "New game hosted: port=" + str(port) + " secret=" + str(server_secret) + " bots=" + str(gamestate.bots) + " server-addr=" + game_server.get_server_addr() + " api-addr=" + game_server.get_api_addr())
|
|
print(server_id + "Waiting for connection, closing server in " + str(EMPTY_CLOSING_TIME) + " seconds")
|
|
timer.set_wait_time(EMPTY_CLOSING_TIME)
|
|
timer.connect("timeout",self,"quit_server",[true])
|
|
timer.start()
|
|
else:
|
|
push_error(server_id + "Could not create Server! (port=" + str(port) + " secret=" + str(server_secret) + " server-addr=" + game_server.get_server_addr() + " api-addr=" + game_server.get_api_addr() + ")")
|
|
quit_server()
|
|
|
|
|
|
func host_game(port:int, set_bots:bool = false, bot_difficulty:float = gamestate.DEFAULT_BOT_DIFFICULTY):
|
|
var host = NetworkedMultiplayerENet.new()
|
|
var err = host.create_server(port, MAX_PEERS)
|
|
get_tree().set_network_peer(host)
|
|
|
|
get_tree().connect("network_peer_connected", self, "_client_connected")
|
|
get_tree().connect("network_peer_disconnected", self,"_client_disconnected")
|
|
|
|
gamestate.connect("players_changed",self,"_players_changed")
|
|
gamestate.connect("game_ready",self,"_game_ready")
|
|
gamestate.connect("game_ended",self,"_game_ended")
|
|
|
|
if set_bots:
|
|
gamestate.bots = true
|
|
|
|
if set_bots && bot_difficulty != gamestate.DEFAULT_BOT_DIFFICULTY:
|
|
gamestate.bot_difficulty = bot_difficulty
|
|
|
|
if timer == null:
|
|
timer = Timer.new()
|
|
timer.set_name("timer")
|
|
timer.set_timer_process_mode(Timer.TIMER_PROCESS_PHYSICS)
|
|
timer.set_one_shot(true)
|
|
timer.set_autostart(false)
|
|
add_child(timer)
|
|
|
|
if err != OK:
|
|
emit_signal("server_error", "HOST", err)
|
|
|
|
return err
|
|
|
|
|
|
func local_game(name:String, color:Color, bots:bool, bot_difficulty:float):
|
|
var localhost = NetworkedMultiplayerENet.new()
|
|
localhost.create_server(0, 0)
|
|
get_tree().set_network_peer(localhost)
|
|
gamestate.bots = bots
|
|
gamestate.bot_difficulty = bot_difficulty
|
|
gamestate.set_player(get_tree().get_network_unique_id(), name, color)
|
|
gamestate.prepare_game()
|
|
gamestate.post_start_game()
|
|
|
|
|
|
func update_server_data():
|
|
var req = game_server.http()
|
|
var player_count = 0
|
|
if gamestate.players != null:
|
|
player_count = gamestate.players.size()
|
|
req.put_request("game",to_json({'secret' : server_secret, 'player_count' : player_count, 'running' : gamestate.game_running}))
|
|
|
|
|
|
func _client_connected(id):
|
|
if get_tree().is_network_server():
|
|
if dedicated_server:
|
|
print(server_id + "peer connected: " + str(id))
|
|
gamestate.rpc_id(id, "set_bots" ,gamestate.bots)
|
|
gamestate.rpc_id(id, "bot_difficulty" ,gamestate.bot_difficulty)
|
|
if not timer.is_stopped():
|
|
timer.disconnect("timeout",self,"quit_server")
|
|
timer.stop()
|
|
|
|
|
|
func _client_disconnected(id):
|
|
if get_tree().is_network_server():
|
|
if dedicated_server:
|
|
print(server_id + "peer disconnected: " + str(id))
|
|
if gamestate.game_running:
|
|
emit_signal("server_error", "DISCONNECTED", [id])
|
|
gamestate.rpc("remove_player" ,id)
|
|
else:
|
|
gamestate.rpc("remove_player" ,id)
|
|
|
|
|
|
func _players_changed(players):
|
|
if get_tree().is_network_server():
|
|
if dedicated_server:
|
|
update_server_data()
|
|
if players.empty():
|
|
if gamestate.game_running:
|
|
print(server_id + "All players disconnected, close server.")
|
|
quit_server()
|
|
else:
|
|
print(server_id + "All players disconnected, wait for closing...")
|
|
timer.set_wait_time(EMPTY_WAIT_TIME)
|
|
timer.connect("timeout",self,"quit_server",[true])
|
|
timer.start()
|
|
|
|
|
|
func quit_server(triggered:bool = false):
|
|
if dedicated_server && triggered:
|
|
print(server_id + "Closing time over...quit")
|
|
var req = game_server.http()
|
|
req.connect_http(self,"_on_delete_server")
|
|
req.delete_request("game",to_json({'secret' : server_secret}))
|
|
|
|
|
|
func _on_delete_server(result, response_code, headers, body):
|
|
if result != OK || response_code != HTTPClient.RESPONSE_OK:
|
|
print(server_id + "ERROR: _on_delete_server, server might be in undefined state!")
|
|
get_tree().quit()
|
|
|
|
|
|
func _start_game():
|
|
if get_tree().is_network_server():
|
|
get_tree().set_refuse_new_network_connections(true)
|
|
gamestate.rpc("prepare_game")
|
|
|
|
|
|
func _game_ready(all_ready):
|
|
if get_tree().is_network_server():
|
|
if all_ready:
|
|
timer.set_wait_time(LOBBY_READY_WAIT_TIME)
|
|
timer.connect("timeout",self,"_start_game")
|
|
timer.start()
|
|
else:
|
|
timer.disconnect("timeout",self,"_start_game")
|
|
timer.stop()
|
|
|
|
|
|
func _game_ended():
|
|
get_tree().disconnect("network_peer_connected", self, "_client_connected")
|
|
get_tree().disconnect("network_peer_disconnected", self,"_client_disconnected")
|
|
|
|
gamestate.disconnect("players_changed",self,"_players_changed")
|
|
gamestate.disconnect("game_ready",self,"_game_ready")
|
|
gamestate.disconnect("game_ended",self,"_game_ended")
|
|
|
|
get_tree().set_refuse_new_network_connections(false)
|
|
get_tree().set_network_peer(null) |