private void Start()
        {
            //Retrieves the EntityToken
            GetEntityToken();

            // Get all the configuration values
            config = GameserverSDK.getConfigSettings();
            Debug.Log("[PlayFabServerInstance] Received PlayFab Config");
            connectionInfo = GameserverSDK.GetGameServerConnectionInfo();

            //Retrieve a particular configuration value
            if (config.TryGetValue(GameserverSDK.SessionCookieKey, out string sessionCookie))
            {
                //sessionCookie contains the value
            }

            _connectedPlayers = new List <Microsoft.Playfab.Gaming.GSDK.CSharp.ConnectedPlayer>();

            // This will add your log line the GSDK log file, alongside other information logged by the GSDK
            GameserverSDK.LogMessage("[PlayFabServerInstance] GameServer Starting");
            Debug.Log("[PlayFabServerInstance] GameServer Starting");

            // Alternatively, you can log your own files to the log directory
            string logFolder = GameserverSDK.GetLogsDirectory();

            // Call this while your game is initializing, it will start heartbeating to our agent and put the game server in an Initializing state
            GameserverSDK.Start();
            GameserverSDK.RegisterShutdownCallback(OnShutdown);
            GameserverSDK.RegisterMaintenanceCallback(OnMaintenanceScheduled);
            GameserverSDK.RegisterHealthCallback(IsHealthy);

            /* Add any other initializion code your game server needs before players can connect */
        }
Esempio n. 2
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();

                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();
        }
Esempio n. 3
0
        static async void Initialize()
        {
            try
            {
                GameserverSDK.Start();
                LoadConfig();

                GameserverSDK.RegisterShutdownCallback(() =>
                {
                    g_ServerProcess.Kill();
                });
            }
            catch
            {
                g_bIsRunningInComputeEnvironment = false;

                g_HttpClient = new HttpClient();
                g_HttpClient.DefaultRequestHeaders.Add("Authorization", strAuthHeader);

                // We're running in a dev environment, so lets dummy add our server
                RegisterAsDevelopmentServer();
            }

            LaunchServer();

            await g_IPC.Connect();

            if (g_bIsRunningInComputeEnvironment)
            {
                GameserverSDK.ReadyForPlayers();
                g_bServerAllocated = true;
                g_bPendingServerAllocationIPCMsg = true;
            }
        }
 private void OnServerActive()
 {
     //Fires Start server event so listners can perform startup
     //playFabServerActiveEvent.Raise();
     Debug.Log("Server Started From Agent Activation");
     GameserverSDK.LogMessage("GameServer has become active");
 }
        private void OnShutdown()
        {
            Debug.Log("[PlayFabServerInstance] Server is Shutting down");
            GameserverSDK.LogMessage("Shutting down...");

            OnShutDown.Invoke();
            StartCoroutine(Shutdown());
        }
Esempio n. 6
0
 private static void LogMessage(string message, bool enableGSDKLogging = true)
 {
     Console.WriteLine(message);
     if (enableGSDKLogging)
     {
         GameserverSDK.LogMessage(message);
     }
 }
 public void OnPlayerAdded(string playfabId)
 {
     if (_connectedPlayers != null)
     {
         _connectedPlayers.Add(new ConnectedPlayer(playfabId));
         GameserverSDK.UpdateConnectedPlayers(_connectedPlayers);
         GameserverSDK.LogMessage("GameServer added player: " + playfabId);
     }
 }
Esempio n. 8
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);
        }
 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);
     }
 }
 // This method will be called in case #3, when Azure will perform maintenance on the virtual machine
 void OnMaintenanceScheduled(DateTimeOffset time)
 {
     /* Perform any necessary cleanup, notify your players, etc. */
     Debug.LogFormat("Maintenance Scheduled for: {0}", time.UtcDateTime.ToLongDateString());
     GameserverSDK.LogMessage("GameServer Maintenance Scheduled for: " + time.UtcDateTime.ToLongDateString());
     //foreach (NetworkConnection conn in manager.Connections)
     //{
     //    conn.Send(CustomGameServerMessageTypes.ShutdownMessage, new MaintenanceMessage
     //    {
     //        ScheduledMaintenanceUTC = time.UtcDateTime
     //    });
     //}
 }
Esempio n. 11
0
        // GSDK event handlers - we're setting them on the startup of the app
        public static void RegisterGSDKCallbacksAndStartGSDK()
        {
            // OnShutDown will be called when developer calls the ShutdDownMultiplayerServer API
            // https://docs.microsoft.com/en-us/rest/api/playfab/multiplayer/multiplayerserver/shutdownmultiplayerserver?view=playfab-rest
            GameserverSDK.RegisterShutdownCallback(OnShutdown);
            // This callback will be called on every heartbeat to check if your game is healthy. So it should return quickly
            GameserverSDK.RegisterHealthCallback(IsHealthy);
            // this callback will be called to notify us that Azure will perform maintenance on the VM
            // you can see more details about Azure VM maintenance here https://docs.microsoft.com/en-gb/azure/virtual-machines/maintenance-and-updates?toc=/azure/virtual-machines/windows/toc.json&bc=/azure/virtual-machines/windows/breadcrumb/toc.json
            GameserverSDK.RegisterMaintenanceCallback(OnMaintenanceScheduled);

            // Call this while your game is initializing; it will start sending a heartbeat to our agent
            // since our game server will transition to a standingBy state, we should call this when we're confident that our game server will not crash
            // here we're calling it just before we start our game server process - normally we would call it inside our game code
            GameserverSDK.Start();
        }
Esempio n. 12
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);
            }
        }
Esempio n. 13
0
        public ChessBackEnd(PluginLoadData pluginLoadData) : base(pluginLoadData)
        {
            ClientManager.ClientConnected    += ClientConnected;
            ClientManager.ClientDisconnected += ClientDisconnected;

            GameserverSDK.RegisterShutdownCallback(OnShutdown);
            GameserverSDK.RegisterHealthCallback(OnHealthCheck);

            // Connect to PlayFab agent
            GameserverSDK.Start();
            if (GameserverSDK.ReadyForPlayers())
            {
                // returns true on allocation call, player about to connect
            }
            else
            {
                // returns false when server is being terminated
            }
        }
Esempio n. 14
0
        bool OnHealthCheck()
        {
            // How long has server been active in seconds?
            float awakeTime;

            if (!sessionIdAssigned)
            {
                awakeTime = 0f;
            }
            else
            {
                awakeTime = (float)(DateTime.Now - startDateTime).TotalSeconds;
            }

            // Get server info
            // If session ID has been assigned, server is active
            string sessionIdCheck = null;
            IDictionary <string, string> config = GameserverSDK.getConfigSettings();

            if (config.TryGetValue(GameserverSDK.SessionIdKey, out string sessionId))
            {
                sessionIdCheck = sessionId;

                // If this is the first session assignment, start the activated timer
                if (!sessionIdAssigned)
                {
                    startDateTime     = DateTime.Now;
                    sessionIdAssigned = true;
                }
            }

            Console.WriteLine(sessionIdAssigned);
            Console.WriteLine(awakeTime);

            // If server has been awake for over 10 mins, and no players connected, and the PlayFab server is not in standby (no session id assigned): begin shutdown
            if (awakeTime > 600f && players.Count <= 0 && sessionIdAssigned)
            {
                OnShutdown();
                return(false);
            }

            return(true);
        }
Esempio n. 15
0
        public NetworkManager(PluginLoadData pluginLoadData) : base(pluginLoadData)
        {
            GameserverSDK.Start();

            ClientManager.ClientConnected    += ClientConnected;
            ClientManager.ClientDisconnected += ClientDisconnected;

            GameserverSDK.RegisterShutdownCallback(OnShutdown);
            GameserverSDK.RegisterHealthCallback(OnHealthCheck);
            sessionIdAssigned = false;

            if (GameserverSDK.ReadyForPlayers())
            {
                // returns true on allocation call, player about to connect
            }
            else
            {
                // returns false when server is being terminated
            }
        }
Esempio n. 16
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);
            }
        }
        private IEnumerator ReadyForPlayers()
        {
            yield return(new WaitForSeconds(.5f));

            // 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
            GameserverSDK.ReadyForPlayers();
            if (showDebugMessages)
            {
                Debug.Log("[PlayFabServerInstance] Ready For Players");
            }
            // 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())
            {
                // readyForPlayers returns true when an allocation call has been done, a player is about to connect!
                GameserverSDK.LogMessage("GameServer is ready for players");
            }
            else
            {
                // readyForPlayers returns false when the server is being terminated
                GameserverSDK.LogMessage("GameServer is NOT ready for players");
            }
        }
Esempio n. 18
0
 private static void LogMessage(string message)
 {
     Console.WriteLine(message);
     // This will add your log line to the GSDK log file, alongside other information logged by the GSDK
     GameserverSDK.LogMessage(message);
 }
Esempio n. 19
0
        static void Main(string[] args)
        {
            // GSDK Setup
            try
            {
                GameserverSDK.Start();
            }
            catch (Microsoft.Playfab.Gaming.GSDK.CSharp.GSDKInitializationException initEx)
            {
                LogMessage("Cannot start GSDK. Please make sure the MockAgent is running. ", false);
                LogMessage($"Got Exception: {initEx.ToString()}", false);
                return;
            }
            catch (Exception ex)
            {
                LogMessage($"Got Exception: {ex.ToString()}", false);
            }

            GameserverSDK.RegisterShutdownCallback(OnShutdown);
            GameserverSDK.RegisterHealthCallback(IsHealthy);
            GameserverSDK.RegisterMaintenanceCallback(OnMaintenanceScheduled);

            // Read our asset file
            if (File.Exists(AssetFilePath))
            {
                _assetFileText = File.ReadAllText(AssetFilePath);
            }

            IDictionary <string, string> initialConfig = GameserverSDK.getConfigSettings();

            // Start the http server
            if (initialConfig?.ContainsKey(ListeningPortKey) == true)
            {
                int    listeningPort = int.Parse(initialConfig[ListeningPortKey]);
                string address       = $"http://*:{listeningPort}/";
                _listener.Prefixes.Add(address);
                _listener.Start();
            }
            else
            {
                LogMessage($"Cannot find {ListeningPortKey} in GSDK Config Settings. Please make sure the MockAgent is running " +
                           $"and that the MultiplayerSettings.json file includes {ListeningPortKey} as a GamePort Name.");
                return;
            }

            // Load our game certificate if it was installed
            if (initialConfig?.ContainsKey(GameCertAlias) == true)
            {
                string    expectedThumbprint = initialConfig[GameCertAlias];
                X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
                store.Open(OpenFlags.ReadOnly);
                X509Certificate2Collection certificateCollection = store.Certificates.Find(X509FindType.FindByThumbprint, expectedThumbprint, false);

                if (certificateCollection.Count > 0)
                {
                    _installedCertThumbprint = certificateCollection[0].Thumbprint;
                }
                else
                {
                    LogMessage("Could not find installed game cert in LocalMachine\\My. Expected thumbprint is: " + expectedThumbprint);
                }
            }
            else
            {
                LogMessage("Config did not contain cert! Config is: " + string.Join(";", initialConfig.Select(x => x.Key + "=" + x.Value)));
            }

            Thread t = new Thread(ProcessRequests);

            t.Start();

            if (GameserverSDK.ReadyForPlayers())
            {
                _isActivated = true;

                // 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.");
            }
        }
Esempio n. 20
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()}");
                }
            }
        }
Esempio n. 21
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()}");
                }
            }
        }
Esempio n. 22
0
        static void LaunchServer()
        {
            // Bind gameserver to primary ipv4 network adapter
            IPAddress ipAddr = Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork).ElementAt(0);

            g_ServerProcess = new Process();
            g_ServerProcess.StartInfo.FileName               = "ThunderRumbleServer.exe";
            g_ServerProcess.StartInfo.Arguments              = String.Format("-host {0} -port {1}", g_bIsRunningInComputeEnvironment ? "0.0.0.0" : ipAddr.ToString(), 5000) + (g_bIsRunningInComputeEnvironment ? String.Format(" -logpath {0}", GameserverSDK.GetLogsDirectory()) : "");
            g_ServerProcess.StartInfo.UseShellExecute        = false;
            g_ServerProcess.StartInfo.RedirectStandardOutput = true;
            g_ServerProcess.OutputDataReceived              += OnOutputDataReceived;
            g_ServerProcess.Start();
            g_ServerProcess.BeginOutputReadLine();
        }
Esempio n. 23
0
 private static void LogMessage(string message)
 {
     GameserverSDK.LogMessage(message);
     Console.WriteLine(message);
 }
Esempio n. 24
0
 static void LogMessage(string strMessage)
 {
     File.AppendAllLines(g_bIsRunningInComputeEnvironment ? Path.Combine(GameserverSDK.GetLogsDirectory(), "log.txt") : "log.txt", new string[] { strMessage });
     Console.WriteLine(strMessage);
 }
Esempio n. 25
0
        static void Main(string[] args)
        {
            try
            {
                if (args != null && args.Length > 0)
                {
                    _cmdArgs = string.Join(" ", args);
                }

                GameserverSDK.Start(true);
                GameserverSDK.RegisterShutdownCallback(OnShutdown);
                GameserverSDK.RegisterHealthCallback(GetGameHealth);
                GameserverSDK.RegisterMaintenanceCallback(OnMaintenanceScheduled);

                IDictionary <string, string> gsdkConfiguration = GameserverSDK.getConfigSettings();
                if (gsdkConfiguration.TryGetValue("RealPort", out string listeningPortString))
                {
                    _listeningPort = int.Parse(listeningPortString);
                }

                string address = $"http://*:{_listeningPort}/";
                _listener.Prefixes.Add(address);
                _listener.Start();

                string applicationDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                if (File.Exists(Path.Combine(applicationDirectory, AssetFilePath)))
                {
                    _assetFileText = File.ReadAllText(Path.Combine(applicationDirectory, AssetFilePath));
                }

                // See if we have a configured timeout in the App.config, this was
                // used in our initial round of stress tests to make sure sessions ended
                string timeoutstr = ConfigurationManager.AppSettings.Get(SessionTimeoutInSecondsName);
                if (!string.IsNullOrEmpty(timeoutstr))
                {
                    // failure to convert is intentionally unhandled
                    long timeoutint = Convert.ToInt64(timeoutstr.Trim());

                    _sessionTimeoutTimestamp = DateTimeOffset.Now.AddSeconds(timeoutint);
                }

                IDictionary <string, string> initialConfig = GameserverSDK.getConfigSettings();
                if (initialConfig?.ContainsKey("winRunnerTestCert") == true)
                {
                    string    expectedThumbprint = initialConfig["winRunnerTestCert"];
                    X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
                    store.Open(OpenFlags.ReadOnly);
                    X509Certificate2Collection certificateCollection = store.Certificates.Find(X509FindType.FindByThumbprint, expectedThumbprint, false);

                    if (certificateCollection.Count > 0)
                    {
                        _installedCertThumbprint = certificateCollection[0].Thumbprint;
                    }
                    else
                    {
                        LogMessage("Could not find installed game cert in LocalMachine\\My. Expected thumbprint is: " + expectedThumbprint);
                    }
                }
                else
                {
                    LogMessage("Config did not contain cert! Config is: " + string.Join(";", initialConfig.Select(x => x.Key + "=" + x.Value)));
                }

                Thread t = new Thread(ProcessRequests);
                t.Start();


                string titleId = initialConfig[GameserverSDK.TitleIdKey];
                string buildId = initialConfig[GameserverSDK.BuildIdKey];
                string region  = initialConfig[GameserverSDK.RegionKey];

                LogMessage($"Processing requests for title:{titleId} build:{buildId} in region {region}");

                GameserverSDK.ReadyForPlayers();
                _isActivated = true;

                initialConfig = GameserverSDK.getConfigSettings();

                LogMessage("Config Settings");
                foreach (KeyValuePair <string, string> configTuple in initialConfig)
                {
                    LogMessage($"\t{configTuple.Key}={configTuple.Value}");
                }

                SessionCookie sessionCookie = new SessionCookie();

                if (initialConfig.TryGetValue(GameserverSDK.SessionCookieKey, out string sessionCookieStr))
                {
                    try
                    {
                        if (sessionCookieStr.StartsWith(TimeoutSessionCookiePrefix,
                                                        StringComparison.InvariantCultureIgnoreCase))
                        {
                            if (long.TryParse(sessionCookieStr.Substring(TimeoutSessionCookiePrefix.Length),
                                              out long timeoutSecs))
                            {
                                sessionCookie.TimeoutSecs = timeoutSecs;
                            }
                        }
                        else
                        {
                            sessionCookie = JsonConvert.DeserializeObject <SessionCookie>(sessionCookieStr);
                        }
                    }
                    catch (Exception e)
                    {
                        LogMessage(e.ToString());
                    }
                }

                // If a secret key was specified
                // try to get the title data for this title
                string secretKey = ConfigurationManager.AppSettings.Get(DeveloperSecretKeyName);
                if (!string.IsNullOrWhiteSpace(secretKey))
                {
                    LogMessage("Getting title data");
                    GetTitleData(titleId, secretKey).Wait();
                }
                else
                {
                    LogMessage("Secret Key not specified in app.config. Skipping retrieval of title config");
                }

                // If the session cookie contained a timeout. Shutdown at this time.
                // this overrides whatever may have been set in the App config above
                // We use it for stress testing to make sessions end at random times.
                EnforceTimeout(sessionCookie);
            }
            catch (Exception e)
            {
                LogMessage(e.Message);
                throw;
            }
        }
Esempio n. 26
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();
        }
Esempio n. 27
0
        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();
        }