|
|
- 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
-
|