Exemplo n.º 1
0
        internal static Patch GetProjectPatch(ISystemOperations so, ISession session, string evfPath)
        {
            var folderIniPath = so.PathCombine(session.FolderPath, "Project.ini");
            var fileIniPath   = so.PathCombine(evfPath, "Project.ini");
            var folderHasIni  = so.FileExists(folderIniPath);
            var fileHasIni    = so.FileExists(fileIniPath);

            if (folderHasIni && fileHasIni)
            {
                if (session.Action == ActionType.Extract)
                {
                    return(Patch.MakeProjectChange(so.FileReadAllText(folderIniPath, Encoding.UTF8), so.FileReadAllText(fileIniPath, Encoding.UTF8)));
                }
                else
                {
                    return(Patch.MakeProjectChange(so.FileReadAllText(fileIniPath, Encoding.UTF8), so.FileReadAllText(folderIniPath, Encoding.UTF8)));
                }
            }
            else if (!folderHasIni && !fileHasIni)
            {
                return(null);
            }
            else if (session.Action == ActionType.Extract ? !folderHasIni : !fileHasIni)
            {
                return(Patch.MakeInsertion("Project", ModuleType.Ini, so.FileReadAllText(session.Action == ActionType.Extract ? fileIniPath : folderIniPath, Encoding.UTF8)));
            }
            else
            {
                return(null); // never suggest deleting Project.INI
            }
        }
Exemplo n.º 2
0
        internal static Patch GetLicensesPatch(ISystemOperations so, ISession session, string evfPath)
        {
            var folderLicensesPath = so.PathCombine(session.FolderPath, "LicenseKeys.bin");
            var fileLicensesPath   = so.PathCombine(evfPath, "LicenseKeys.bin");
            var folderHasLicenses  = so.FileExists(folderLicensesPath);
            var fileHasLicenses    = so.FileExists(fileLicensesPath);

            if (folderHasLicenses && fileHasLicenses)
            {
                if (session.Action == ActionType.Extract)
                {
                    return(Patch.MakeLicensesChange(so.FileReadAllBytes(folderLicensesPath), so.FileReadAllBytes(fileLicensesPath)));
                }
                else
                {
                    return(Patch.MakeLicensesChange(so.FileReadAllBytes(fileLicensesPath), so.FileReadAllBytes(folderLicensesPath)));
                }
            }
            else if (!folderHasLicenses && !fileHasLicenses)
            {
                return(null);
            }
            else if (session.Action == ActionType.Extract ? !folderHasLicenses : !fileHasLicenses)
            {
                return(Patch.MakeLicensesChange(new byte[0], so.FileReadAllBytes(session.Action == ActionType.Extract ? fileLicensesPath : folderLicensesPath)));
            }
            else
            {
                return(Patch.MakeLicensesChange(so.FileReadAllBytes(session.Action == ActionType.Extract ? folderLicensesPath : fileLicensesPath), new byte[0]));
            }
        }
Exemplo n.º 3
0
        private void CreateLegacyGSDKConfigFile(int instanceNumber, string sessionHostUniqueId, Dictionary <string, string> certThumbprints, IDictionary <string, string> portMappings)
        {
            // Legacy games are currently assumed to have only 1 asset.zip file which will have the game.exe as well
            // as the assets. We just place ServiceDefinition.json in that folder itself (since it contains game.exe).
            // This assumption will change later on and the code below will need to adapt.
            string configFilePath =
                Path.Combine(VmConfiguration.GetAssetExtractionFolderPathForSessionHost(instanceNumber, 0),
                             "ServiceDefinition.json");
            ServiceDefinition serviceDefinition;

            if (_systemOperations.FileExists(configFilePath))
            {
                _logger.LogInformation($"Parsing the existing service definition file at {configFilePath}.");
                serviceDefinition = JsonConvert.DeserializeObject <ServiceDefinition>(File.ReadAllText(configFilePath));
                serviceDefinition.JsonWorkerRole = serviceDefinition.JsonWorkerRole ?? new JsonWorkerRole();
            }
            else
            {
                _logger.LogInformation($"Creating the service definition file at {configFilePath}.");
                serviceDefinition = new ServiceDefinition
                {
                    JsonWorkerRole = new JsonWorkerRole()
                };
            }

            SetUpLegacyConfigValues(serviceDefinition, sessionHostUniqueId, instanceNumber, GetVmAgentIpAddress());

            certThumbprints?.ForEach(x => serviceDefinition.JsonWorkerRole.SetConfigValue(x.Key, x.Value));
            portMappings?.ForEach(x => serviceDefinition.JsonWorkerRole.SetConfigValue(x.Key, x.Value));
            _sessionHostsStartInfo.DeploymentMetadata?.ForEach(x => serviceDefinition.JsonWorkerRole.SetConfigValue(x.Key, x.Value));
            string outputJson = JsonConvert.SerializeObject(serviceDefinition, Formatting.Indented, CommonSettings.JsonSerializerSettings);

            // This will overwrite the file if it was already there (which would happen when restarting containers for the same assignment)
            _systemOperations.FileWriteAllText(configFilePath, outputJson);
        }
        public bool IsValid()
        {
            if (string.IsNullOrWhiteSpace(_settings.OutputFolder) || string.IsNullOrWhiteSpace(_settings.TitleId))
            {
                throw new Exception("OutputFolder or TitleId not found. Call SetDefaultsIfNotSpecified() before this method");
            }

            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Console.WriteLine("Running LocalMultiplayerAgent on Linux is not supported yet.");
                return(false);
            }

            if (Globals.GameServerEnvironment == GameServerEnvironment.Linux && !_settings.RunContainer)
            {
                Console.WriteLine("The specified settings are invalid. Using Linux Game Servers requires running in a container.");
                return(false);
            }

            string startGameCommand;

            if (_settings.RunContainer)
            {
                if (_settings.ContainerStartParameters == null)
                {
                    Console.WriteLine("No ContainerStartParameters were specified (and RunContainer is true).");
                    return(false);
                }
                startGameCommand = _settings.ContainerStartParameters.StartGameCommand;
            }
            else
            {
                if (_settings.ProcessStartParameters == null)
                {
                    Console.WriteLine("No ProcessStartParameters were specified (and RunContainer is false).");
                    return(false);
                }
                startGameCommand = _settings.ProcessStartParameters.StartGameCommand;
            }

            bool isSuccess = AreAssetsValid(_settings.AssetDetails);

            // StartGameCommand is optional on Linux
            if (string.IsNullOrWhiteSpace(startGameCommand))
            {
                if (Globals.GameServerEnvironment == GameServerEnvironment.Windows)
                {
                    Console.WriteLine("StartGameCommand must be specified.");
                    isSuccess = false;
                }
            }
            else
            {
                if (startGameCommand.Contains("<your_game_server_exe>"))
                {
                    Console.WriteLine($"StartGameCommand '{startGameCommand}' is invalid");
                    isSuccess = false;
                }
            }

            if (_settings.GameCertificateDetails?.Length > 0)
            {
                HashSet <string> names = new HashSet <string>();
                HashSet <string> paths = new HashSet <string>();

                foreach (GameCertificateDetails certDetails in _settings.GameCertificateDetails)
                {
                    if (string.IsNullOrEmpty(certDetails.Name.Trim()))
                    {
                        Console.WriteLine($"Certificate cannot have an empty name");
                        isSuccess = false;
                        continue;
                    }
                    if (string.IsNullOrEmpty(certDetails.Path) || !certDetails.Path.EndsWith(".pfx"))
                    {
                        Console.WriteLine($"Certificate with filename path '{certDetails.Path}' is not a pfx file");
                        isSuccess = false;
                        continue;
                    }
                    if (!_systemOperations.FileExists(certDetails.Path))
                    {
                        Console.WriteLine($"Certificate with filename {certDetails.Path} does not exist");
                        isSuccess = false;
                        continue;
                    }
                    if (!names.Add(certDetails.Name))
                    {
                        isSuccess = false;
                        Console.WriteLine($"Certificate with name {certDetails.Name} is included more than once");
                    }
                    if (!paths.Add(certDetails.Path))
                    {
                        isSuccess = false;
                        Console.WriteLine($"Certificate with path {certDetails.Path} is included more than once");
                    }
                }
            }

            if (string.IsNullOrWhiteSpace(_settings.Region))
            {
                Console.WriteLine("Region must be specified.");
                isSuccess = false;
            }

            if (_settings.AgentListeningPort == 0)
            {
                Console.WriteLine("AgentListeningPort must be specified.");
                isSuccess = false;
            }

            if (!ulong.TryParse(_settings.TitleId, NumberStyles.HexNumber, NumberFormatInfo.CurrentInfo, out _))
            {
                Console.WriteLine("TitleId must be specified and be a valid hex number");
                isSuccess = false;
            }

            if (_settings.BuildId == Guid.Empty)
            {
                Console.WriteLine("BuildId must be specified.");
                isSuccess = false;
            }

            if (string.IsNullOrEmpty(_settings.SessionConfig?.SessionCookie))
            {
                Console.WriteLine("Warning: SessionCookie is not specified.");
            }

            if (_settings.AgentListeningPort != 56001)
            {
                Console.WriteLine($"Warning: You have specified an AgentListeningPort ({_settings.AgentListeningPort}) that is not the default.  Please make sure that port is open on your firewall by running setup.ps1 with the agent port specified.");
            }

            return(isSuccess);
        }
        public bool IsValid()
        {
            if (string.IsNullOrWhiteSpace(_settings.OutputFolder) || string.IsNullOrWhiteSpace(_settings.TitleId))
            {
                throw new Exception("OutputFolder or TitleId not found. Call SetDefaultsIfNotSpecified() before this method");
            }

            if (!_systemOperations.DirectoryExists(_settings.OutputFolder))
            {
                Console.WriteLine($"OutputFolder '{_settings.OutputFolder}' does not exist. Check your MultiplayerSettings.json file");
                return(false);
            }

            if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                Console.WriteLine("Running LocalMultiplayerAgent is not yet supported on MacOS. We would be happy to accept PRs to make it work!");
                return(false);
            }

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && _settings.RunContainer)
            {
                Console.WriteLine("Running LocalMultiplayerAgent as container mode is not yet supported on Linux. Please set RunContainer to false in MultiplayerSettings.json");
                return(false);
            }

            if (Globals.GameServerEnvironment == GameServerEnvironment.Linux && !_settings.RunContainer)
            {
                Console.WriteLine("The specified settings are invalid. Using Linux Game Servers requires running in a container.");
                return(false);
            }

            string startGameCommand;

            if (_settings.RunContainer)
            {
                if (_settings.ContainerStartParameters == null)
                {
                    Console.WriteLine("No ContainerStartParameters were specified (and RunContainer is true).");
                    return(false);
                }
                startGameCommand = _settings.ContainerStartParameters.StartGameCommand;
            }
            else
            {
                if (_settings.ProcessStartParameters == null)
                {
                    Console.WriteLine("No ProcessStartParameters were specified (and RunContainer is false).");
                    return(false);
                }
                startGameCommand = _settings.ProcessStartParameters.StartGameCommand;
            }

            bool isSuccess = AreAssetsValid(_settings.AssetDetails);

            // StartGameCommand is optional on Linux
            if (string.IsNullOrWhiteSpace(startGameCommand))
            {
                if (Globals.GameServerEnvironment == GameServerEnvironment.Windows)
                {
                    Console.WriteLine("StartGameCommand must be specified.");
                    isSuccess = false;
                }
            }
            else if (startGameCommand.Contains("<your_game_server_exe>"))
            {
                Console.WriteLine($"StartGameCommand '{startGameCommand}' is invalid");
                isSuccess = false;
            }
            else if (_settings.AssetDetails != null && _settings.RunContainer && (Globals.GameServerEnvironment == GameServerEnvironment.Windows))
            {
                if ((!_settings.AssetDetails.Any(x => startGameCommand.Contains(x.MountPath, StringComparison.InvariantCultureIgnoreCase))))
                {
                    Console.WriteLine($"StartGameCommand '{startGameCommand}' is invalid and does not contain the mount path. This should look like: C:\\Assets\\GameServer.exe for example.");
                    isSuccess = false;
                }
            }

            if (_settings.GameCertificateDetails?.Length > 0)
            {
                HashSet <string> names = new HashSet <string>();
                HashSet <string> paths = new HashSet <string>();

                foreach (GameCertificateDetails certDetails in _settings.GameCertificateDetails)
                {
                    if (string.IsNullOrEmpty(certDetails.Name.Trim()))
                    {
                        Console.WriteLine($"Certificate cannot have an empty name");
                        isSuccess = false;
                        continue;
                    }
                    if (string.IsNullOrEmpty(certDetails.Path) || !certDetails.Path.EndsWith(".pfx"))
                    {
                        Console.WriteLine($"Certificate with filename path '{certDetails.Path}' is not a pfx file");
                        isSuccess = false;
                        continue;
                    }
                    if (!_systemOperations.FileExists(certDetails.Path))
                    {
                        Console.WriteLine($"Certificate with filename {certDetails.Path} does not exist");
                        isSuccess = false;
                        continue;
                    }
                    if (!names.Add(certDetails.Name))
                    {
                        isSuccess = false;
                        Console.WriteLine($"Certificate with name {certDetails.Name} is included more than once");
                    }
                    if (!paths.Add(certDetails.Path))
                    {
                        isSuccess = false;
                        Console.WriteLine($"Certificate with path {certDetails.Path} is included more than once");
                    }
                }
            }

            if (string.IsNullOrWhiteSpace(_settings.Region))
            {
                Console.WriteLine("Region must be specified.");
                isSuccess = false;
            }

            if (_settings.AgentListeningPort == 0)
            {
                Console.WriteLine("AgentListeningPort must be specified.");
                isSuccess = false;
            }

            if (!ulong.TryParse(_settings.TitleId, NumberStyles.HexNumber, NumberFormatInfo.CurrentInfo, out _))
            {
                Console.WriteLine("TitleId must be specified and be a valid hex number");
                isSuccess = false;
            }

            if (_settings.BuildId == Guid.Empty)
            {
                Console.WriteLine("BuildId must be specified.");
                isSuccess = false;
            }

            if (string.IsNullOrEmpty(_settings.SessionConfig?.SessionCookie))
            {
                Console.WriteLine("Warning: SessionCookie is not specified.");
            }

            if (_settings.AgentListeningPort != 56001)
            {
                Console.WriteLine($"Warning: You have specified an AgentListeningPort ({_settings.AgentListeningPort}) that is not the default.  Please make sure that port is open on your firewall by running setup.ps1 with the agent port specified.");
            }

            if (_settings.RunContainer)
            {
                foreach (var portList in _settings.PortMappingsList)
                {
                    foreach (var portInfo in portList)
                    {
                        if (portInfo.NodePort == 0)
                        {
                            Console.WriteLine("No NodePort was specified (and RunContainer is true).");
                            isSuccess = false;
                        }
                    }
                }
            }

            if (_settings.NumHeartBeatsForActivateResponse <= 0)
            {
                Console.WriteLine("NumHeartBeatsForActivateResponse must be greater than 0.");
                isSuccess = false;
            }

            if (_settings.NumHeartBeatsForTerminateResponse <= 0)
            {
                Console.WriteLine("NumHeartBeatsForTerminateResponse must be greater than 0.");
                isSuccess = false;
            }

            if (_settings.NumHeartBeatsForTerminateResponse <= _settings.NumHeartBeatsForActivateResponse)
            {
                Console.WriteLine("NumHeartBeatsForTerminateResponse must be greater than NumHeartBeatsForActivateResponse. Ideally more than 1, since you would like the server to be alive for a few seconds");
                isSuccess = false;
            }

            return(isSuccess);
        }