public void OnPlayerAdded(string playfabId)
 {
     if (_connectedPlayers != null)
     {
         _connectedPlayers.Add(new ConnectedPlayer(playfabId));
         GameserverSDK.UpdateConnectedPlayers(_connectedPlayers);
         GameserverSDK.LogMessage("GameServer added player: " + playfabId);
     }
 }
 public void OnPlayerRemoved(string playfabId)
 {
     if (_connectedPlayers != null)
     {
         ConnectedPlayer player = _connectedPlayers.Find(x => x.PlayerId.Equals(playfabId, StringComparison.OrdinalIgnoreCase));
         _connectedPlayers.Remove(player);
         GameserverSDK.UpdateConnectedPlayers(_connectedPlayers);
         GameserverSDK.LogMessage("GameServer removed player: " + player.PlayerId);
         //PlayFabMultiplayerAgentAPI.UpdateConnectedPlayers(_connectedPlayers);
     }
 }
예제 #3
0
        void UpdatePlayFabPlayers()
        {
            List <ConnectedPlayer> listPfPlayers = new List <ConnectedPlayer>();

            foreach (KeyValuePair <IClient, Player> player in players)
            {
                listPfPlayers.Add(new ConnectedPlayer(player.Value.playerName));
            }

            GameserverSDK.UpdateConnectedPlayers(listPfPlayers);
        }
예제 #4
0
        public static void ProcessPlayerList()
        {
            // Update player list if dirty
            if (PlayersIsDirty)
            {
                PlayersIsDirty = false;

                List <ConnectedPlayer> lstPlayers = new List <ConnectedPlayer>();
                foreach (var keyValuePair in Players)
                {
                    lstPlayers.Add(new ConnectedPlayer(keyValuePair.Value));
                }

                GameserverSDK.UpdateConnectedPlayers(lstPlayers);
            }
        }
예제 #5
0
        // starts main game process and wait for it to complete
        public static void InitiateAndWaitForGameProcess(string gameserverExe, IEnumerable <string> args)
        {
            // here we're starting the script that initiates the game process
            gameProcess = StartProcess(gameserverExe, args);
            // as part of wrapping the main game server executable,
            // we create event handlers to process the output from the game (standard output/standard error)
            // based on this output, we will activate the server and process connected players
            gameProcess.OutputDataReceived += DataReceived;
            gameProcess.ErrorDataReceived  += DataReceived;
            // start reading output (stdout/stderr) from the game
            gameProcess.BeginOutputReadLine();
            gameProcess.BeginErrorReadLine();

            // Call this when your game is done initializing and players can connect
            // Note: This is a blocking call, and will return when this game server is either allocated or terminated
            if (GameserverSDK.ReadyForPlayers())
            {
                // After allocation, we can grab the session cookie from the config
                IDictionary <string, string> activeConfig = GameserverSDK.getConfigSettings();

                var connectedPlayers = new List <ConnectedPlayer>();
                // initial players includes the list of the players that are allowed to connect to the game
                // they might or might not end up connecting
                // in this sample we're nevertheless adding them to the list
                foreach (var player in GameserverSDK.GetInitialPlayers())
                {
                    connectedPlayers.Add(new ConnectedPlayer(player));
                }
                GameserverSDK.UpdateConnectedPlayers(connectedPlayers);

                if (activeConfig.TryGetValue(GameserverSDK.SessionCookieKey, out string sessionCookie))
                {
                    LogMessage($"The session cookie from the allocation call is: {sessionCookie}");
                }
            }
            else
            {
                // No allocation happened, the server is getting terminated (likely because there are too many already in standing by)
                LogMessage("Server is getting terminated.");
                gameProcess?.Kill(); // we still need to call WaitForExit https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.kill?view=netcore-3.1#remarks
            }

            // wait till it exits or crashes
            gameProcess.WaitForExit();
        }
예제 #6
0
        // runs when we received data (stdout/stderr) from our game server process
        public static void DataReceived(object sender, DataReceivedEventArgs e)
        {
            Console.WriteLine(e.Data); // used for debug purposes only - you can use `docker logs <container_id> to see the stdout logs
            if (e.Data.Contains("Opening IP socket"))
            {
                // Call this when your game is done initializing and players can connect
                // Note: This is a blocking call, and will return when this game server is either allocated or terminated
                if (GameserverSDK.ReadyForPlayers())
                {
                    // After allocation, we can grab the session cookie from the config
                    IDictionary <string, string> activeConfig = GameserverSDK.getConfigSettings();

                    if (activeConfig.TryGetValue(GameserverSDK.SessionCookieKey, out string sessionCookie))
                    {
                        LogMessage($"The session cookie from the allocation call is: {sessionCookie}");
                    }
                }
                else
                {
                    // No allocation happened, the server is getting terminated (likely because there are too many already in standing by)
                    LogMessage("Server is getting terminated.");
                    gameProcess?.Kill(); // we still need to call WaitForExit https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.kill?view=netcore-3.1#remarks
                }
            }
            else if (e.Data.Contains("ClientBegin:")) // new player connected
            {
                players.Add(new ConnectedPlayer("gamer" + new Random().Next(0, 21)));
                GameserverSDK.UpdateConnectedPlayers(players);
            }
            else if (e.Data.Contains("ClientDisconnect:")) // player disconnected
            {
                players.RemoveAt(new Random().Next(0, players.Count));
                GameserverSDK.UpdateConnectedPlayers(players);
                // some games may need to exit if player count is zero
            }
            else if (e.Data.Contains("AAS shutdown")) // game changes map
            {
                players.Clear();
                GameserverSDK.UpdateConnectedPlayers(players);
            }
        }
예제 #7
0
        /// <summary>
        /// Listens for any requests and responds with the game server's config values
        /// </summary>
        private static void ProcessRequests()
        {
            while (_listener.IsListening)
            {
                try
                {
                    HttpListenerContext  context  = _listener.GetContext();
                    HttpListenerRequest  request  = context.Request;
                    HttpListenerResponse response = context.Response;

                    string requestMessage = $"HTTP:Received {request.Headers.ToString()}";
                    LogMessage(requestMessage);

                    IDictionary <string, string> config = null;

                    // For each request, "add" a connected player, but limit player count to 20.
                    const int maxPlayers = 20;
                    if (players.Count < maxPlayers)
                    {
                        players.Add(new ConnectedPlayer("gamer" + requestCount));
                    }
                    else
                    {
                        LogMessage($"Player not added since max of {maxPlayers} is reached. Current request count: {requestCount}.");
                    }

                    requestCount++;
                    GameserverSDK.UpdateConnectedPlayers(players);

                    config = GameserverSDK.getConfigSettings() ?? new Dictionary <string, string>();

                    config.Add("isActivated", _isActivated.ToString());
                    config.Add("assetFileText", _assetFileText);
                    config.Add("logsDirectory", GameserverSDK.GetLogsDirectory());
                    config.Add("installedCertThumbprint", _installedCertThumbprint);

                    if (_nextMaintenance != DateTimeOffset.MinValue)
                    {
                        config.Add("nextMaintenance", _nextMaintenance.ToLocalTime().ToString());
                    }

                    string content = JsonConvert.SerializeObject(config, Formatting.Indented);

                    response.AddHeader("Content-Type", "application/json");
                    byte[] buffer = System.Text.Encoding.UTF8.GetBytes(content);
                    response.ContentLength64 = buffer.Length;
                    using (System.IO.Stream output = response.OutputStream)
                    {
                        output.Write(buffer, 0, buffer.Length);
                    }
                }
                catch (HttpListenerException httpEx)
                {
                    // This one is expected if we stopped the listener because we were asked to shutdown
                    LogMessage($"Got HttpListenerException: {httpEx.ToString()}, we are being shut down.");
                }
                catch (Exception ex)
                {
                    LogMessage($"Got Exception: {ex.ToString()}");
                }
            }
        }
예제 #8
0
파일: Program.cs 프로젝트: PlayFab/gsdk
        static void Main(string[] args)
        {
            // Test startup
            GameserverSDK.Start();

            GameserverSDK.RegisterShutdownCallback(() => Console.WriteLine("Server is shutting me down!!!!!"));
            GameserverSDK.RegisterHealthCallback(getIsHealthy);
            GameserverSDK.RegisterMaintenanceCallback(maintenanceScheduled);

            // Test grabbing config
            Console.WriteLine("Config before Active.");
            foreach (var config in GameserverSDK.getConfigSettings())
            {
                Console.WriteLine($"{config.Key}: {config.Value}");
            }

            if (GameserverSDK.ReadyForPlayers())
            {
                IList <string> initialPlayers = GameserverSDK.GetInitialPlayers();
                Console.WriteLine("Initial Players: " + string.Join(",", initialPlayers));

                List <ConnectedPlayer> players = new List <ConnectedPlayer>()
                {
                    new ConnectedPlayer("player1"),
                    new ConnectedPlayer("player2")
                };
                GameserverSDK.UpdateConnectedPlayers(players);

                Console.WriteLine("Config after Active.");
                foreach (var config in GameserverSDK.getConfigSettings())
                {
                    Console.WriteLine($"{config.Key}: {config.Value}");
                }

                // Print a rainbow
                int size = 13;
                for (int i = 0; i < 5; i++)
                {
                    String edge   = new String(new char[size]).Replace('\0', ' ');
                    String middle = new String(new char[2 * i]).Replace('\0', ' ');
                    Console.WriteLine(edge + "====" + middle + "=====" + edge);
                    size--;
                }

                for (int i = 0; i < 4; i++)
                {
                    String edge   = new String(new char[size]).Replace('\0', ' ');
                    String middle = new String(new char[10]).Replace('\0', ' ');
                    Console.WriteLine(edge + "====" + middle + "=====" + edge);
                }

                // Leave running a bit more to see the heartbeats
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine("...");
                    System.Threading.Thread.Sleep(1000);
                }
            }
            else
            {
                Console.WriteLine("Did not activate, instead shutting down...");
            }

            Console.WriteLine("Press enter to exit.");
            Console.ReadKey();
        }
예제 #9
0
        /// <summary>
        /// Listens for any requests and responds with the game host's config values
        /// </summary>
        /// <param name="config">The config values we're returning</param>
        private static void ProcessRequests()
        {
            while (_listener.IsListening)
            {
                try
                {
                    HttpListenerContext  context  = _listener.GetContext();
                    HttpListenerRequest  request  = context.Request;
                    HttpListenerResponse response = context.Response;

                    LogMessage(string.Format("HTTP:Received {0}", request.Headers.ToString()));

                    IDictionary <string, string> config = null;

                    // For each request, "add" a connected player, but limit player count to 20.
                    const int maxPlayers = 20;
                    if (players.Count < maxPlayers)
                    {
                        players.Add(new ConnectedPlayer("gamer" + requestCount));
                    }
                    else
                    {
                        LogMessage($"Player not added since max of {maxPlayers} is reached. Current request count: {requestCount}.");
                    }

                    requestCount++;

                    GameserverSDK.UpdateConnectedPlayers(players);

                    config = GameserverSDK.getConfigSettings() ?? new Dictionary <string, string>();

                    // First, check if we need to delay shutdown for testing
                    if (config.TryGetValue(GameserverSDK.SessionCookieKey, out string sessionCookie) && sessionCookie.Equals("delayshutdown", StringComparison.OrdinalIgnoreCase))
                    {
                        _delayShutdown = true;
                    }

                    // If the server has been allocated, add the list of players to the response.
                    if (_isActivated)
                    {
                        config.Add("initialPlayers", string.Join(",", GameserverSDK.GetInitialPlayers()));
                    }

                    config.Add("isActivated", _isActivated.ToString());
                    config.Add("isShutdown", _isShutdown.ToString());
                    config.Add("assetFileText", _assetFileText);
                    config.Add("logsDirectory", GameserverSDK.GetLogsDirectory());
                    config.Add("sharedContentDirectory", GameserverSDK.GetSharedContentDirectory());
                    config.Add("installedCertThumbprint", _installedCertThumbprint);
                    config.Add("cmdArgs", _cmdArgs);

                    if (_nextMaintenance != DateTimeOffset.MinValue)
                    {
                        config.Add("nextMaintenance", _nextMaintenance.ToLocalTime().ToString());
                    }

                    foreach (GamePort portInformation in GameserverSDK.GetGameServerConnectionInfo().GamePortsConfiguration)
                    {
                        config.Add($"Public{portInformation.Name}", portInformation.ClientConnectionPort.ToString());
                    }

                    string content = JsonConvert.SerializeObject(config, Formatting.Indented);

                    response.AddHeader("Content-Type", "application/json");
                    byte[] buffer = System.Text.Encoding.UTF8.GetBytes(content);
                    response.ContentLength64 = buffer.Length;
                    using (System.IO.Stream output = response.OutputStream)
                    {
                        output.Write(buffer, 0, buffer.Length);
                    }

                    // Once we're shut down, return a response one more time (so the tests can
                    // verify the _isShutdown field) and then actually terminate
                    if (_isShutdown)
                    {
                        _listener.Stop();
                        _listener.Close();
                    }
                }
                catch (HttpListenerException httpEx)
                {
                    // This one is expected if we stopped the listener because we were asked to shutdown
                    LogMessage($"Got HttpListenerException: {httpEx.ToString()}, shutdown value is: {_isShutdown} ");
                }
                catch (Exception ex)
                {
                    LogMessage($"Got Exception: {ex.ToString()}");
                }
            }
        }
예제 #10
0
        // starts main game process and wait for it to complete
        public static void InitiateAndWaitForGameProcess(string gameserverExe, IEnumerable <string> args)
        {
            // Here we're starting the script that initiates the game process

            activeConfig = GameserverSDK.getConfigSettings();

            // When Wrapper is running in a container, Port Information (Port Name, Port Number, and Protocol) is already set as build configuration.
            // For example, if you already set port number as 80 in container build configuration, activeConfig will return 80 as port number.
            // But if Wrapper is running as a process, port will be mapped internally by MPS, so different number will be dynamically assigned.
            if (activeConfig.TryGetValue(portName, out string listeningPortString))
            {
                GameserverSDK.LogMessage($"{portName}:{listeningPortString} was found in GSDK Config Settings.");
                _listeningPort = listeningPortString;
            }
            else
            {
                LogMessage($"Cannot find {portName} in GSDK Config Settings. Please make sure the LocalMultiplayerAgent is running " +
                           $"and that the MultiplayerSettings.json file includes correct {portName} as a GamePort Name.");
                return;
            }

            // Check if there is any process already using the port (_listeningPort). This will only work for Windows.
            if (CheckIfPortIsUsed(gameserverExe))
            {
                return;
            }
            ;

            // We pass port number as a 3rd argument when we start fakegame.exe
            // Port number is grabbed via GSDK and will be passed to fake game as a listening port.
            gameProcess = StartProcess(gameserverExe, string.Join(' ', args.Append(_listeningPort)));
            // as part of wrapping the main game server executable,
            // we create event handlers to process the output from the game (standard output/standard error)
            // based on this output, we will activate the server and process connected players
            gameProcess.OutputDataReceived += DataReceived;
            gameProcess.ErrorDataReceived  += DataReceived;
            // start reading output (stdout/stderr) from the game
            gameProcess.BeginOutputReadLine();
            gameProcess.BeginErrorReadLine();

            // Call this when your game is done initializing and players can connect
            // Note: This is a blocking call, and will return when this game server is either allocated or terminated
            if (GameserverSDK.ReadyForPlayers())
            {
                // After allocation, we can grab the session cookie from the config
                activeConfig = GameserverSDK.getConfigSettings();

                var connectedPlayers = new List <ConnectedPlayer>();
                // initial players includes the list of the players that are allowed to connect to the game
                // they might or might not end up connecting
                // in this sample we're nevertheless adding them to the list
                foreach (var player in GameserverSDK.GetInitialPlayers())
                {
                    connectedPlayers.Add(new ConnectedPlayer(player));
                }
                GameserverSDK.UpdateConnectedPlayers(connectedPlayers);

                if (activeConfig.TryGetValue(GameserverSDK.SessionCookieKey, out string sessionCookie))
                {
                    LogMessage($"The session cookie from the allocation call is: {sessionCookie}");
                }
            }
            else
            {
                // No allocation happened, the server is getting terminated (likely because there are too many already in standing by)
                LogMessage("Server is getting terminated.");
                gameProcess?.Kill(); // we still need to call WaitForExit https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.kill?view=netcore-3.1#remarks
            }

            // wait till it exits or crashes
            gameProcess.WaitForExit();
        }