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 } }
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])); } }
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); }