|
extends Node
|
|
|
|
var SERVER_TO_SERVER_PORT = 54671
|
|
var MATCHMAKING_PORT = 54672
|
|
var GAME_SIZE = 6
|
|
# Number of games we can make without blowing up the computer
|
|
var MAX_GAMES = 50 # Based on how many ports I decided to forward
|
|
|
|
var next_port = 54673
|
|
|
|
# Filled with queue info which contains
|
|
# { "netid" }
|
|
var skirmishing_players = []
|
|
var skirmish
|
|
# To avoid the confusion of the gameSERVERS being CLIENTS,
|
|
# we just call them games whenever possible
|
|
# var games = []
|
|
var game_connections = []
|
|
var game_streams = []
|
|
|
|
# Matchmaker to game servers
|
|
var matchmaker_to_games
|
|
|
|
enum messages {
|
|
ready_to_connect,
|
|
}
|
|
|
|
onready var lobby = get_node("..")
|
|
|
|
func _ready():
|
|
# By default, having this node doesn't do naything
|
|
# You must call start_matchmaker to enable it
|
|
# If not called, don't call _process (= don't matchmake)
|
|
set_process(false)
|
|
|
|
func start_matchmaker():
|
|
# Actually run the matchmaker
|
|
set_process(true)
|
|
|
|
# Setup skirmish server
|
|
skirmish = spawn_server(true)
|
|
|
|
# Set up communication between GAMESERVERS
|
|
# This is necessary for eg, when a player leaves to backfill
|
|
matchmaker_to_games = TCP_Server.new()
|
|
if matchmaker_to_games.listen(SERVER_TO_SERVER_PORT):
|
|
print("Error, could not listen")
|
|
|
|
# Use ENet for matchmaker because we can (makes client code cleaner)
|
|
var matchmaker_to_players = NetworkedMultiplayerENet.new()
|
|
print("Starting matchmaker on port " + str(MATCHMAKING_PORT))
|
|
matchmaker_to_players.create_server(MATCHMAKING_PORT, MAX_GAMES)
|
|
get_tree().set_network_peer(matchmaker_to_players)
|
|
matchmaker_to_players.connect("peer_connected", self, "queue")
|
|
|
|
func _process(delta):
|
|
# Manage connection to GAMESERVERS (not clients)
|
|
if matchmaker_to_games.is_connection_available(): # check if a gameserver's trying to connect
|
|
var game = matchmaker_to_games.take_connection() # accept connection
|
|
game_connections.append(game) # store the connection
|
|
var stream = PacketPeerStream.new()
|
|
stream.set_stream_peer(game) # bind peerstream to new client
|
|
game_streams.append(stream) # make new data transfer object for game
|
|
for stream in game_streams:
|
|
if stream.get_available_packet_count():
|
|
var message = stream.get_var()
|
|
if message == messages.ready_to_connect:
|
|
var port = stream.get_var()
|
|
print("Server " + str(port) + " has requested connection")
|
|
skirmish_to_game(port, GAME_SIZE)
|
|
|
|
func queue(netid):
|
|
print("Player " + str(netid) + " connected.")
|
|
add_to_game(netid, skirmish)
|
|
skirmishing_players.append(netid)
|
|
check_queue()
|
|
|
|
func add_to_game(netid, port):
|
|
networking.rpc_id(netid, "reconnect", networking.global_server_ip, port)
|
|
|
|
func skirmish_to_game(port, count=1):
|
|
for i in range(count):
|
|
if not skirmishing_players.size():
|
|
return false
|
|
print(skirmishing_players[0])
|
|
print("to")
|
|
print(port)
|
|
add_to_game(skirmishing_players[0], port)
|
|
return true
|
|
|
|
func check_queue():
|
|
# Prefer making a full game to backfilling
|
|
if skirmishing_players.size() >= GAME_SIZE:
|
|
spawn_server()
|
|
# games.append(port)
|
|
|
|
func spawn_server(skirmish=false):
|
|
var args = ['-port='+str(next_port)]
|
|
if skirmish:
|
|
# Begin skirmish immediately, so players "join" instead of "ready"
|
|
args.append("-start-game")
|
|
OS.execute("util/server.sh", args, false)
|
|
next_port += 1
|
|
return (next_port - 1) # Return original port
|
|
|