This repository has been archived on 2023-12-19. You can view files and clone it, but cannot push or open issues or pull requests.
MUR/scripts/networking/server.gd

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)