using Microsoft.WindowsAPICodePack.Dialogs; using ServerManagerTool.Common; using ServerManagerTool.Common.Lib; using ServerManagerTool.Common.Model; using ServerManagerTool.Common.Serialization; using ServerManagerTool.Common.Utils; using ServerManagerTool.Enums; using ServerManagerTool.Lib; using ServerManagerTool.Lib.ViewModel; using ServerManagerTool.Plugin.Common; using ServerManagerTool.Utils; using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Input; using WPFSharp.Globalizer; namespace ServerManagerTool { public enum ServerSettingsCustomLevelsAction { ExportPlayerLevels, ImportPlayerLevels, UpdatePlayerXPCap, ExportDinoLevels, ImportDinoLevels, UpdateDinoXPCap, } public enum ServerSettingsResetAction { // Sections AdministrationSection, RulesSection, ChatAndNotificationsSection, HudAndVisualsSection, PlayerSettingsSection, DinoSettingsSection, EnvironmentSection, StructuresSection, EngramsSection, CustomLevelsSection, SOTFSection, PGMSection, MapSpawnerOverridesSection, CraftingOverridesSection, SupplyCrateOverridesSection, StackSizeOverridesSection, PreventTransferOverridesSection, // Properties MapNameTotalConversionProperty, BanListProperty, PlayerMaxXpProperty, DinoMaxXpProperty, PlayerBaseStatMultipliers, PlayerPerLevelStatMultipliers, DinoWildPerLevelStatMultipliers, DinoTamedPerLevelStatMultipliers, DinoTamedAddPerLevelStatMultipliers, DinoTamedAffinityPerLevelStatMultipliers, ItemStatClamps, RCONWindowExtents, ServerOptions, ServerLogOptions, } /// /// Interaction logic for ServerSettings.xaml /// partial class ServerSettingsControl : UserControl { private readonly GlobalizedApplication _globalizer = GlobalizedApplication.Instance; private CancellationTokenSource _upgradeCancellationSource = null; // Using a DependencyProperty as the backing store for ServerManager. This enables animation, styling, binding, etc... public static readonly DependencyProperty BaseDinoModListProperty = DependencyProperty.Register(nameof(BaseDinoModList), typeof(ComboBoxItemList), typeof(ServerSettingsControl), new PropertyMetadata(null)); public static readonly DependencyProperty BaseEngramModListProperty = DependencyProperty.Register(nameof(BaseEngramModList), typeof(ComboBoxItemList), typeof(ServerSettingsControl), new PropertyMetadata(null)); public static readonly DependencyProperty BaseResourceModListProperty = DependencyProperty.Register(nameof(BaseResourceModList), typeof(ComboBoxItemList), typeof(ServerSettingsControl), new PropertyMetadata(null)); public static readonly DependencyProperty BaseDinoListProperty = DependencyProperty.Register(nameof(BaseDinoList), typeof(ComboBoxItemList), typeof(ServerSettingsControl), new PropertyMetadata(null)); public static readonly DependencyProperty BaseMapSpawnerListProperty = DependencyProperty.Register(nameof(BaseMapSpawnerList), typeof(ComboBoxItemList), typeof(ServerSettingsControl), new PropertyMetadata(null)); public static readonly DependencyProperty BasePrimalItemListProperty = DependencyProperty.Register(nameof(BasePrimalItemList), typeof(ComboBoxItemList), typeof(ServerSettingsControl), new PropertyMetadata(null)); public static readonly DependencyProperty BaseSupplyCrateListProperty = DependencyProperty.Register(nameof(BaseSupplyCrateList), typeof(ComboBoxItemList), typeof(ServerSettingsControl), new PropertyMetadata(null)); public static readonly DependencyProperty BaseGameMapsProperty = DependencyProperty.Register(nameof(BaseGameMaps), typeof(ComboBoxItemList), typeof(ServerSettingsControl), new PropertyMetadata(null)); public static readonly DependencyProperty BaseTotalConversionsProperty = DependencyProperty.Register(nameof(BaseTotalConversions), typeof(ComboBoxItemList), typeof(ServerSettingsControl), new PropertyMetadata(null)); public static readonly DependencyProperty BaseBranchesProperty = DependencyProperty.Register(nameof(BaseBranches), typeof(ComboBoxItemList), typeof(ServerSettingsControl), new PropertyMetadata(null)); public static readonly DependencyProperty BaseEventsProperty = DependencyProperty.Register(nameof(BaseEvents), typeof(ComboBoxItemList), typeof(ServerSettingsControl), new PropertyMetadata(null)); public static readonly DependencyProperty BetaVersionProperty = DependencyProperty.Register(nameof(BetaVersion), typeof(bool), typeof(ServerSettingsControl), new PropertyMetadata(false)); public static readonly DependencyProperty CurrentConfigProperty = DependencyProperty.Register(nameof(CurrentConfig), typeof(Config), typeof(ServerSettingsControl)); public static readonly DependencyProperty IsAdministratorProperty = DependencyProperty.Register(nameof(IsAdministrator), typeof(bool), typeof(ServerSettingsControl), new PropertyMetadata(false)); public static readonly DependencyProperty NetworkInterfacesProperty = DependencyProperty.Register(nameof(NetworkInterfaces), typeof(List), typeof(ServerSettingsControl), new PropertyMetadata(new List())); public static readonly DependencyProperty RuntimeProperty = DependencyProperty.Register(nameof(Runtime), typeof(ServerRuntime), typeof(ServerSettingsControl)); public static readonly DependencyProperty ServerManagerProperty = DependencyProperty.Register(nameof(ServerManager), typeof(ServerManager), typeof(ServerSettingsControl), new PropertyMetadata(null)); public static readonly DependencyProperty ServerProperty = DependencyProperty.Register(nameof(Server), typeof(Server), typeof(ServerSettingsControl), new PropertyMetadata(null, ServerPropertyChanged)); public static readonly DependencyProperty SettingsProperty = DependencyProperty.Register(nameof(Settings), typeof(ServerProfile), typeof(ServerSettingsControl)); public static readonly DependencyProperty SelectedModDinoProperty = DependencyProperty.Register(nameof(SelectedModDino), typeof(string), typeof(ServerSettingsControl), new PropertyMetadata("All")); public static readonly DependencyProperty SelectedModEngramProperty = DependencyProperty.Register(nameof(SelectedModEngram), typeof(string), typeof(ServerSettingsControl), new PropertyMetadata("All")); public static readonly DependencyProperty SelectedModResourceProperty = DependencyProperty.Register(nameof(SelectedModResource), typeof(string), typeof(ServerSettingsControl), new PropertyMetadata("All")); public static readonly DependencyProperty SelectedCraftingOverrideProperty = DependencyProperty.Register(nameof(SelectedCraftingOverride), typeof(CraftingOverride), typeof(ServerSettingsControl)); public static readonly DependencyProperty SelectedCustomEngineSettingProperty = DependencyProperty.Register(nameof(SelectedCustomEngineSetting), typeof(CustomSection), typeof(ServerSettingsControl)); public static readonly DependencyProperty SelectedCustomGameSettingProperty = DependencyProperty.Register(nameof(SelectedCustomGameSetting), typeof(CustomSection), typeof(ServerSettingsControl)); public static readonly DependencyProperty SelectedCustomGameUserSettingProperty = DependencyProperty.Register(nameof(SelectedCustomGameUserSetting), typeof(CustomSection), typeof(ServerSettingsControl)); public static readonly DependencyProperty SelectedNPCSpawnSettingProperty = DependencyProperty.Register(nameof(SelectedNPCSpawnSetting), typeof(NPCSpawnSettings), typeof(ServerSettingsControl)); public static readonly DependencyProperty SelectedSupplyCrateOverrideProperty = DependencyProperty.Register(nameof(SelectedSupplyCrateOverride), typeof(SupplyCrateOverride), typeof(ServerSettingsControl)); public static readonly DependencyProperty SelectedSupplyCrateItemSetProperty = DependencyProperty.Register(nameof(SelectedSupplyCrateItemSet), typeof(SupplyCrateItemSet), typeof(ServerSettingsControl)); public static readonly DependencyProperty SelectedSupplyCrateItemSetEntryProperty = DependencyProperty.Register(nameof(SelectedSupplyCrateItemSetEntry), typeof(SupplyCrateItemSetEntry), typeof(ServerSettingsControl)); public static readonly DependencyProperty FilterOnlySelectedEngramsProperty = DependencyProperty.Register(nameof(FilterOnlySelectedEngrams), typeof(bool), typeof(ServerSettingsControl), new PropertyMetadata(false)); public static readonly DependencyProperty ProcessPrioritiesProperty = DependencyProperty.Register(nameof(ProcessPriorities), typeof(ComboBoxItemList), typeof(ServerSettingsControl), new PropertyMetadata(null)); public static readonly DependencyProperty CurrentCultureProperty = DependencyProperty.Register(nameof(CurrentCulture), typeof(CultureInfo), typeof(ServerSettingsControl), new PropertyMetadata(null)); public static readonly DependencyProperty DisplayModInformationProperty = DependencyProperty.Register(nameof(DisplayModInformation), typeof(bool), typeof(ServerSettingsControl), new PropertyMetadata(false)); public static readonly DependencyProperty CustomLevelProgressionsInformationProperty = DependencyProperty.Register(nameof(CustomLevelProgressionsInformation), typeof(string), typeof(ServerSettingsControl), new PropertyMetadata("")); public static readonly DependencyProperty ProfileLastStartedProperty = DependencyProperty.Register(nameof(ProfileLastStarted), typeof(string), typeof(ServerSettingsControl), new PropertyMetadata("")); public static readonly DependencyProperty DinoFilterStringProperty = DependencyProperty.Register(nameof(DinoFilterString), typeof(string), typeof(ServerSettingsControl), new PropertyMetadata("")); public static readonly DependencyProperty EngramFilterStringProperty = DependencyProperty.Register(nameof(EngramFilterString), typeof(string), typeof(ServerSettingsControl), new PropertyMetadata("")); public static readonly DependencyProperty ResourceFilterStringProperty = DependencyProperty.Register(nameof(ResourceFilterString), typeof(string), typeof(ServerSettingsControl), new PropertyMetadata("")); #region Properties public ComboBoxItemList BaseDinoModList { get { return (ComboBoxItemList)GetValue(BaseDinoModListProperty); } set { SetValue(BaseDinoModListProperty, value); } } public ComboBoxItemList BaseEngramModList { get { return (ComboBoxItemList)GetValue(BaseEngramModListProperty); } set { SetValue(BaseEngramModListProperty, value); } } public ComboBoxItemList BaseResourceModList { get { return (ComboBoxItemList)GetValue(BaseResourceModListProperty); } set { SetValue(BaseResourceModListProperty, value); } } public ComboBoxItemList BaseDinoList { get { return (ComboBoxItemList)GetValue(BaseDinoListProperty); } set { SetValue(BaseDinoListProperty, value); } } public ComboBoxItemList BaseMapSpawnerList { get { return (ComboBoxItemList)GetValue(BaseMapSpawnerListProperty); } set { SetValue(BaseMapSpawnerListProperty, value); } } public ComboBoxItemList BasePrimalItemList { get { return (ComboBoxItemList)GetValue(BasePrimalItemListProperty); } set { SetValue(BasePrimalItemListProperty, value); } } public ComboBoxItemList BaseSupplyCrateList { get { return (ComboBoxItemList)GetValue(BaseSupplyCrateListProperty); } set { SetValue(BaseSupplyCrateListProperty, value); } } public ComboBoxItemList BaseGameMaps { get { return (ComboBoxItemList)GetValue(BaseGameMapsProperty); } set { SetValue(BaseGameMapsProperty, value); } } public ComboBoxItemList BaseTotalConversions { get { return (ComboBoxItemList)GetValue(BaseTotalConversionsProperty); } set { SetValue(BaseTotalConversionsProperty, value); } } public ComboBoxItemList BaseBranches { get { return (ComboBoxItemList)GetValue(BaseBranchesProperty); } set { SetValue(BaseBranchesProperty, value); } } public ComboBoxItemList BaseEvents { get { return (ComboBoxItemList)GetValue(BaseEventsProperty); } set { SetValue(BaseEventsProperty, value); } } public bool BetaVersion { get { return (bool)GetValue(BetaVersionProperty); } set { SetValue(BetaVersionProperty, value); } } public Config CurrentConfig { get { return GetValue(CurrentConfigProperty) as Config; } set { SetValue(CurrentConfigProperty, value); } } public bool IsAdministrator { get { return (bool)GetValue(IsAdministratorProperty); } set { SetValue(IsAdministratorProperty, value); } } public List NetworkInterfaces { get { return (List)GetValue(NetworkInterfacesProperty); } set { SetValue(NetworkInterfacesProperty, value); } } public ServerRuntime Runtime { get { return GetValue(RuntimeProperty) as ServerRuntime; } set { SetValue(RuntimeProperty, value); } } public ServerManager ServerManager { get { return (ServerManager)GetValue(ServerManagerProperty); } set { SetValue(ServerManagerProperty, value); } } public Server Server { get { return (Server)GetValue(ServerProperty); } set { SetValue(ServerProperty, value); } } public ServerProfile Settings { get { return GetValue(SettingsProperty) as ServerProfile; } set { SetValue(SettingsProperty, value); } } public string SelectedModDino { get { return (string)GetValue(SelectedModDinoProperty); } set { SetValue(SelectedModDinoProperty, value); } } public string SelectedModEngram { get { return (string)GetValue(SelectedModEngramProperty); } set { SetValue(SelectedModEngramProperty, value); } } public string SelectedModResource { get { return (string)GetValue(SelectedModResourceProperty); } set { SetValue(SelectedModResourceProperty, value); } } public CraftingOverride SelectedCraftingOverride { get { return GetValue(SelectedCraftingOverrideProperty) as CraftingOverride; } set { SetValue(SelectedCraftingOverrideProperty, value); } } public CustomSection SelectedCustomEngineSetting { get { return GetValue(SelectedCustomEngineSettingProperty) as CustomSection; } set { SetValue(SelectedCustomEngineSettingProperty, value); } } public CustomSection SelectedCustomGameSetting { get { return GetValue(SelectedCustomGameSettingProperty) as CustomSection; } set { SetValue(SelectedCustomGameSettingProperty, value); } } public CustomSection SelectedCustomGameUserSetting { get { return GetValue(SelectedCustomGameUserSettingProperty) as CustomSection; } set { SetValue(SelectedCustomGameUserSettingProperty, value); } } public NPCSpawnSettings SelectedNPCSpawnSetting { get { return GetValue(SelectedNPCSpawnSettingProperty) as NPCSpawnSettings; } set { SetValue(SelectedNPCSpawnSettingProperty, value); } } public SupplyCrateOverride SelectedSupplyCrateOverride { get { return GetValue(SelectedSupplyCrateOverrideProperty) as SupplyCrateOverride; } set { SetValue(SelectedSupplyCrateOverrideProperty, value); } } public SupplyCrateItemSet SelectedSupplyCrateItemSet { get { return GetValue(SelectedSupplyCrateItemSetProperty) as SupplyCrateItemSet; } set { SetValue(SelectedSupplyCrateItemSetProperty, value); } } public SupplyCrateItemSetEntry SelectedSupplyCrateItemSetEntry { get { return GetValue(SelectedSupplyCrateItemSetEntryProperty) as SupplyCrateItemSetEntry; } set { SetValue(SelectedSupplyCrateItemSetEntryProperty, value); } } public bool FilterOnlySelectedEngrams { get { return (bool)GetValue(FilterOnlySelectedEngramsProperty); } set { SetValue(FilterOnlySelectedEngramsProperty, value); } } public ComboBoxItemList ProcessPriorities { get { return (ComboBoxItemList)GetValue(ProcessPrioritiesProperty); } set { SetValue(ProcessPrioritiesProperty, value); } } public CultureInfo CurrentCulture { get { return (CultureInfo)GetValue(CurrentCultureProperty); } set { SetValue(CurrentCultureProperty, value); } } public bool DisplayModInformation { get { return (bool)GetValue(DisplayModInformationProperty); } set { SetValue(DisplayModInformationProperty, value); } } public string CustomLevelProgressionsInformation { get { return (string)GetValue(CustomLevelProgressionsInformationProperty); } set { SetValue(CustomLevelProgressionsInformationProperty, value); } } public string ProfileLastStarted { get { return (string)GetValue(ProfileLastStartedProperty); } set { SetValue(ProfileLastStartedProperty, value); } } public string DinoFilterString { get { return (string)GetValue(DinoFilterStringProperty); } set { SetValue(DinoFilterStringProperty, value); } } public string EngramFilterString { get { return (string)GetValue(EngramFilterStringProperty); } set { SetValue(EngramFilterStringProperty, value); } } public string ResourceFilterString { get { return (string)GetValue(ResourceFilterStringProperty); } set { SetValue(ResourceFilterStringProperty, value); } } #endregion public ServerSettingsControl() { this.BetaVersion = App.Instance.BetaVersion; this.CurrentConfig = Config.Default; this.CurrentCulture = Thread.CurrentThread.CurrentCulture; InitializeComponent(); WindowUtils.RemoveDefaultResourceDictionary(this, Config.Default.DefaultGlobalizationFile); this.ServerManager = ServerManager.Instance; this.IsAdministrator = SecurityUtils.IsAdministrator(); this.DisplayModInformation = !string.IsNullOrWhiteSpace(SteamUtils.SteamWebApiKey); RefreshBaseDinoModList(); RefreshBaseEngramModList(); RefreshBaseResourceModList(); RefreshCustomLevelProgressionsInformation(); this.BaseDinoList = new ComboBoxItemList(); this.BaseMapSpawnerList = new ComboBoxItemList(); this.BasePrimalItemList = new ComboBoxItemList(); this.BaseSupplyCrateList = new ComboBoxItemList(); this.BaseGameMaps = new ComboBoxItemList(); this.BaseTotalConversions = new ComboBoxItemList(); this.BaseBranches = new ComboBoxItemList(); this.BaseEvents = new ComboBoxItemList(); this.ProcessPriorities = new ComboBoxItemList(); UpdateLastStartedDetails(false); // hook into the language change event GlobalizedApplication.Instance.GlobalizationManager.ResourceDictionaryChangedEvent += ResourceDictionaryChangedEvent; } #region Event Methods private static void ServerPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var ssc = (ServerSettingsControl)d; var oldserver = (Server)e.OldValue; var server = (Server)e.NewValue; if (server != null) { TaskUtils.RunOnUIThreadAsync(() => { oldserver?.Profile.Save(false, false, null); ssc.Settings = server.Profile; ssc.Runtime = server.Runtime; ssc.ReinitializeNetworkAdapters(); ssc.RefreshBaseDinoList(); ssc.RefreshBaseMapSpawnerList(); ssc.RefreshBasePrimalItemList(); ssc.RefreshBaseSupplyCrateList(); ssc.RefreshBaseGameMapsList(); ssc.RefreshBaseTotalConversionsList(); ssc.RefreshBaseBranchesList(); ssc.RefreshBaseEventsList(); ssc.RefreshProcessPrioritiesList(); ssc.DisplayModInformation = !string.IsNullOrWhiteSpace(SteamUtils.SteamWebApiKey); ssc.UpdateLastStartedDetails(false); }).DoNotWait(); } } private void ResourceDictionaryChangedEvent(object source, ResourceDictionaryChangedEventArgs e) { this.CurrentCulture = Thread.CurrentThread.CurrentCulture; this.Settings.DinoSettings.UpdateForLocalization(); this.Settings.EngramSettings.UpdateForLocalization(); this.Settings.NPCSpawnSettings.UpdateForLocalization(); this.Settings.ConfigOverrideSupplyCrateItems.UpdateForLocalization(); this.Settings.ConfigOverrideItemMaxQuantity.UpdateForLocalization(); this.RefreshBaseDinoModList(); this.RefreshBaseEngramModList(); this.RefreshBaseResourceModList(); this.RefreshBaseDinoList(); this.RefreshBaseMapSpawnerList(); this.RefreshBasePrimalItemList(); this.RefreshBaseSupplyCrateList(); this.RefreshBaseGameMapsList(); this.RefreshBaseTotalConversionsList(); this.RefreshBaseBranchesList(); this.RefreshBaseEventsList(); this.RefreshProcessPrioritiesList(); this.HarvestResourceItemAmountClassMultipliersListBox.Items.Refresh(); this.RefreshCustomLevelProgressionsInformation(); this.UpdateLastStartedDetails(false); Runtime.UpdateServerStatusString(); } private void Window_Closed(object sender, EventArgs e) { Window.GetWindow(this)?.Activate(); if (sender is Window) ((Window)sender).Closed -= Window_Closed; if (sender is ShutdownWindow) this.Runtime?.ResetModCheckTimer(); if (sender is ModDetailsWindow) { ((ModDetailsWindow)sender).SavePerformed -= ModDetailsWindow_SavePerformed; RefreshBaseGameMapsList(); RefreshBaseTotalConversionsList(); } } private void ModDetailsWindow_SavePerformed(object sender, ProfileEventArgs e) { if (sender is ModDetailsWindow && Equals(e.Profile, Settings)) { RefreshBaseGameMapsList(); RefreshBaseTotalConversionsList(); } } private async void Start_Click(object sender, RoutedEventArgs e) { MessageBoxResult result = MessageBoxResult.None; switch (this.Runtime.Status) { case ServerStatus.Initializing: case ServerStatus.Running: // check if the server is initialising. if (this.Runtime.Status == ServerStatus.Initializing) { result = MessageBox.Show(_globalizer.GetResourceString("ServerSettings_StartServer_StartingLabel"), _globalizer.GetResourceString("ServerSettings_StartServer_StartingTitle"), MessageBoxButton.YesNo, MessageBoxImage.Warning); if (result == MessageBoxResult.No) return; try { PluginHelper.Instance.ProcessAlert(AlertType.Shutdown, this.Settings.ProfileName, Config.Default.Alert_ServerStopMessage); await Task.Delay(2000); await this.Server.StopAsync(); } catch (Exception ex) { MessageBox.Show(ex.Message, _globalizer.GetResourceString("ServerSettings_StopServer_FailedTitle"), MessageBoxButton.OK, MessageBoxImage.Error); } } else { try { var shutdownWindow = ShutdownWindow.OpenShutdownWindow(this.Server); if (shutdownWindow == null) { MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ShutdownServer_AlreadyOpenLabel"), _globalizer.GetResourceString("ServerSettings_ShutdownServer_FailedTitle"), MessageBoxButton.OK, MessageBoxImage.Error); return; } shutdownWindow.Owner = Window.GetWindow(this); shutdownWindow.Closed += Window_Closed; shutdownWindow.Show(); } catch (Exception ex) { MessageBox.Show(ex.Message, _globalizer.GetResourceString("ServerSettings_ShutdownServer_FailedTitle"), MessageBoxButton.OK, MessageBoxImage.Error); } } break; case ServerStatus.Stopped: Mutex mutex = null; bool createdNew = false; try { // try to establish a mutex for the profile. mutex = new Mutex(true, ServerApp.GetMutexName(this.Server.Profile.InstallDirectory), out createdNew); // check if the mutex was established if (createdNew) { if (Config.Default.ManagePublicIPAutomatically) { // check and update the public IP address await App.DiscoverMachinePublicIPAsync(false); } this.Settings.Save(false, false, null); if (Config.Default.ServerUpdate_OnServerStart) { if (!await UpdateServer(false, true, Config.Default.ServerUpdate_UpdateModsWhenUpdatingServer, true)) { if (MessageBox.Show(_globalizer.GetResourceString("ServerUpdate_WarningLabel"), _globalizer.GetResourceString("ServerUpdate_Title"), MessageBoxButton.YesNo, MessageBoxImage.Warning) != MessageBoxResult.Yes) return; } } string validateMessage; if (!this.Server.Profile.Validate(false, out validateMessage)) { var outputMessage = _globalizer.GetResourceString("ProfileValidation_WarningLabel").Replace("{validateMessage}", validateMessage); if (MessageBox.Show(outputMessage, _globalizer.GetResourceString("ProfileValidation_Title"), MessageBoxButton.YesNo, MessageBoxImage.Warning) != MessageBoxResult.Yes) return; } await this.Server.StartAsync(); // update the profile's last started time UpdateLastStartedDetails(true); var startupMessage = Config.Default.Alert_ServerStartedMessage; if (Config.Default.Alert_ServerStartedMessageIncludeIPandPort) startupMessage += $" {Config.Default.MachinePublicIP}:{this.Settings.QueryPort}"; PluginHelper.Instance.ProcessAlert(AlertType.Startup, this.Settings.ProfileName, startupMessage); if (this.Settings.ForceRespawnDinos) PluginHelper.Instance.ProcessAlert(AlertType.Startup, this.Settings.ProfileName, Config.Default.Alert_ForceRespawnDinos); await Task.Delay(2000); } else { // display an error message and exit MessageBox.Show(_globalizer.GetResourceString("ServerSettings_StartServer_MutexFailedLabel"), _globalizer.GetResourceString("ServerSettings_StartServer_FailedTitle"), MessageBoxButton.OK, MessageBoxImage.Information); } } catch (Exception ex) { MessageBox.Show(ex.Message, _globalizer.GetResourceString("ServerSettings_StartServer_FailedTitle"), MessageBoxButton.OK, MessageBoxImage.Error); } finally { if (mutex != null) { if (createdNew) { mutex.ReleaseMutex(); mutex.Dispose(); } mutex = null; } } break; } } private async void Upgrade_Click(object sender, RoutedEventArgs e) { switch (this.Runtime.Status) { case ServerStatus.Stopped: case ServerStatus.Uninstalled: break; case ServerStatus.Running: case ServerStatus.Initializing: var result = MessageBox.Show(_globalizer.GetResourceString("ServerSettings_UpgradeServer_RunningLabel"), _globalizer.GetResourceString("ServerSettings_UpgradeServer_RunningTitle"), MessageBoxButton.YesNo, MessageBoxImage.Warning); if (result == MessageBoxResult.No) return; break; case ServerStatus.Updating: return; } this.Settings.Save(false, false, null); await UpdateServer(true, true, Config.Default.ServerUpdate_UpdateModsWhenUpdatingServer, false); } private async void ModUpgrade_Click(object sender, RoutedEventArgs e) { switch (this.Runtime.Status) { case ServerStatus.Stopped: case ServerStatus.Uninstalled: break; default: return; } this.Settings.Save(false, false, null); await UpdateServer(true, false, true, false); } private void OpenRCON_Click(object sender, RoutedEventArgs e) { var window = RCONWindow.GetRCONForServer(this.Server); window.Closed += Window_Closed; window.Show(); if (window.WindowState == WindowState.Minimized) { window.WindowState = WindowState.Normal; } window.Focus(); } private void OpenPlayerList_Click(object sender, RoutedEventArgs e) { var window = PlayerListWindow.GetWindowForServer(this.Server); window.Closed += Window_Closed; window.Show(); if (window.WindowState == WindowState.Minimized) { window.WindowState = WindowState.Normal; } window.Focus(); } private void OpenModDetails_Click(object sender, RoutedEventArgs e) { var window = new ModDetailsWindow(this.Server.Profile); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; window.SavePerformed += ModDetailsWindow_SavePerformed; window.Show(); window.Focus(); } private void HelpSOTF_Click(object sender, RoutedEventArgs e) { if (string.IsNullOrWhiteSpace(Config.Default.ArkSotfUrl)) return; Process.Start(Config.Default.ArkSotfUrl); } private void PatchNotes_Click(object sender, RoutedEventArgs e) { var url = string.Empty; if (Settings.SOTF_Enabled) url =Config.Default.ArkSotF_PatchNotesUrl; else url = Config.Default.ArkSE_PatchNotesUrl; if (string.IsNullOrWhiteSpace(url)) return; Process.Start(url); } private void NeedAdmin_Click(object sender, RoutedEventArgs e) { MessageBox.Show(_globalizer.GetResourceString("ServerSettings_AdminRequired_ErrorLabel"), _globalizer.GetResourceString("ServerSettings_AdminRequired_ErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Information); } private void RefreshLocalIPs_Click(object sender, RoutedEventArgs e) { ReinitializeNetworkAdapters(); } private void OpenLogFolder_Click(object sender, RoutedEventArgs e) { var logFolder = Path.Combine(App.GetLogFolder(), this.Server.Profile.ProfileID.ToLower()); if (!Directory.Exists(logFolder)) logFolder = App.GetLogFolder(); if (!Directory.Exists(logFolder)) logFolder = Config.Default.DataDir; Process.Start("explorer.exe", logFolder); } private void OpenServerFolder_Click(object sender, RoutedEventArgs e) { Process.Start("explorer.exe", this.Server.Profile.InstallDirectory); } private async void CreateSupportZip_Click(object sender, RoutedEventArgs e) { const int MAX_DAYS = 2; var cursor = this.Cursor; try { Application.Current.Dispatcher.Invoke(() => this.Cursor = Cursors.Wait); await Task.Delay(500); var obfuscateFiles = new Dictionary(); var files = new List(); // var file = Path.Combine(this.Settings.InstallDirectory, Config.Default.LastUpdatedTimeFile); if (File.Exists(file)) files.Add(file); file = Path.Combine(this.Settings.InstallDirectory, "version.txt"); if (File.Exists(file)) files.Add(file); // \ShooterGame\Content\Mods var folder = Path.Combine(this.Settings.InstallDirectory, Config.Default.ServerModsRelativePath); var dirInfo = new DirectoryInfo(folder); if (dirInfo.Exists) { files.AddRange(dirInfo.GetFiles("*.mod").Select(modFile => modFile.FullName)); foreach (var modFolder in dirInfo.GetDirectories()) { file = Path.Combine(modFolder.FullName, Config.Default.LastUpdatedTimeFile); if (File.Exists(file)) files.Add(file); } } // \ShooterGame\Saved\Config\WindowsServer file = Path.Combine(this.Settings.GetProfileServerConfigDir(), Config.Default.ServerGameConfigFile); if (File.Exists(file)) { var iniFile = IniFileUtils.ReadFromFile(file); if (iniFile != null) { obfuscateFiles.Add(file, iniFile.ToOutputString()); } } file = Path.Combine(this.Settings.GetProfileServerConfigDir(), Config.Default.ServerGameUserSettingsConfigFile); if (File.Exists(file)) { var iniFile = IniFileUtils.ReadFromFile(file); if (iniFile != null) { iniFile.WriteKey("ServerSettings", "ServerPassword", "obfuscated"); iniFile.WriteKey("ServerSettings", "ServerAdminPassword", "obfuscated"); iniFile.WriteKey("ServerSettings", "SpectatorPassword", "obfuscated"); obfuscateFiles.Add(file, iniFile.ToOutputString()); } } file = Path.Combine(this.Settings.GetProfileServerConfigDir(), Config.Default.LauncherFile); if (File.Exists(file)) files.Add(file); // Logs folder = Path.Combine(Config.Default.DataDir, Config.Default.LogsDir, ServerApp.LOGPREFIX_AUTOBACKUP); dirInfo = new DirectoryInfo(folder); if (dirInfo.Exists) { files.AddRange(dirInfo.GetFiles("*.log").Where(f => f.LastWriteTime > DateTime.Today.AddDays(-MAX_DAYS)).Select(logFile => logFile.FullName)); } folder = Path.Combine(Config.Default.DataDir, Config.Default.LogsDir, ServerApp.LOGPREFIX_AUTOSHUTDOWN); dirInfo = new DirectoryInfo(folder); if (dirInfo.Exists) { files.AddRange(dirInfo.GetFiles("*.log").Where(f => f.LastWriteTime > DateTime.Today.AddDays(-MAX_DAYS)).Select(logFile => logFile.FullName)); } folder = Path.Combine(Config.Default.DataDir, Config.Default.LogsDir, ServerApp.LOGPREFIX_AUTOUPDATE); dirInfo = new DirectoryInfo(folder); if (dirInfo.Exists) { files.AddRange(dirInfo.GetFiles("*.log").Where(f => f.LastWriteTime > DateTime.Today.AddDays(-MAX_DAYS)).Select(logFile => logFile.FullName)); } // Logs/ folder = Path.Combine(Config.Default.DataDir, Config.Default.LogsDir, this.Settings.ProfileID.ToLower()); dirInfo = new DirectoryInfo(folder); if (dirInfo.Exists) { files.AddRange(dirInfo.GetFiles("*.*", SearchOption.AllDirectories).Where(f => f.LastWriteTime > DateTime.Today.AddDays(-MAX_DAYS)).Select(logFile => logFile.FullName)); } // Profile file = this.Settings.GetProfileFile(); if (File.Exists(file)) { var profileFile = ServerProfile.LoadFromProfileFile(file, null); if (profileFile != null) { profileFile.AdminPassword = "obfuscated"; profileFile.ServerPassword = "obfuscated"; profileFile.SpectatorPassword = "obfuscated"; profileFile.WebAlarmKey = "obfuscated"; profileFile.WebAlarmUrl = "obfuscated"; profileFile.BranchPassword = "obfuscated"; obfuscateFiles.Add(file, profileFile.ToOutputString()); } } // \SteamCMD\steamapps\workshop\content\ if (this.Settings.SOTF_Enabled) folder = Path.Combine(Config.Default.DataDir, Config.Default.SteamCmdDir, Config.Default.ArkSteamWorkshopFolderRelativePath_SotF); else folder = Path.Combine(Config.Default.DataDir, Config.Default.SteamCmdDir, Config.Default.ArkSteamWorkshopFolderRelativePath); if (Directory.Exists(folder)) { foreach (var modFolder in Directory.GetDirectories(folder)) { file = Path.Combine(modFolder, Config.Default.LastUpdatedTimeFile); if (File.Exists(file)) files.Add(file); } } if (!this.Settings.SOTF_Enabled) { // if (!string.IsNullOrWhiteSpace(Config.Default.AutoUpdate_CacheDir)) { var branchName = string.IsNullOrWhiteSpace(this.Settings.BranchName) ? Config.Default.DefaultServerBranchName : this.Settings.BranchName; file = IOUtils.NormalizePath(Path.Combine(Config.Default.AutoUpdate_CacheDir, $"{Config.Default.ServerBranchFolderPrefix}{branchName}", Config.Default.LastUpdatedTimeFile)); if (File.Exists(file)) files.Add(file); } } // scheduled tasks (profile level) var taskKey = this.Settings.GetProfileKey(); var taskXML = TaskSchedulerUtils.GetScheduleTaskInformation(TaskSchedulerUtils.TaskType.AutoStart, taskKey, null); if (!string.IsNullOrWhiteSpace(taskXML)) obfuscateFiles.Add($"Task-{TaskSchedulerUtils.TaskType.AutoStart}.xml", taskXML); taskXML = TaskSchedulerUtils.GetScheduleTaskInformation(TaskSchedulerUtils.TaskType.AutoShutdown, taskKey, "#1"); if (!string.IsNullOrWhiteSpace(taskXML)) obfuscateFiles.Add($"Task-{TaskSchedulerUtils.TaskType.AutoShutdown}-#1.xml", taskXML); taskXML = TaskSchedulerUtils.GetScheduleTaskInformation(TaskSchedulerUtils.TaskType.AutoShutdown, taskKey, "#2"); if (!string.IsNullOrWhiteSpace(taskXML)) obfuscateFiles.Add($"Task-{TaskSchedulerUtils.TaskType.AutoShutdown}-#2.xml", taskXML); // scheduled tasks (manager level) taskKey = TaskSchedulerUtils.ComputeKey(Config.Default.DataDir); taskXML = TaskSchedulerUtils.GetScheduleTaskInformation(TaskSchedulerUtils.TaskType.AutoBackup, taskKey, null); if (!string.IsNullOrWhiteSpace(taskXML)) obfuscateFiles.Add($"Task-{TaskSchedulerUtils.TaskType.AutoBackup}.xml", taskXML); taskXML = TaskSchedulerUtils.GetScheduleTaskInformation(TaskSchedulerUtils.TaskType.AutoUpdate, taskKey, null); if (!string.IsNullOrWhiteSpace(taskXML)) obfuscateFiles.Add($"Task-{TaskSchedulerUtils.TaskType.AutoUpdate}.xml", taskXML); // archive comment - mostly global config settings var comment = new StringBuilder(); comment.AppendLine($"Windows Platform: {Environment.OSVersion.Platform}"); comment.AppendLine($"Windows Version: {Environment.OSVersion.VersionString}"); comment.AppendLine($"Game Server Version: {this.Settings.LastInstalledVersion}"); comment.AppendLine($"Server Manager Version: {App.Instance.Version}"); comment.AppendLine($"Server Manager Code: {Config.Default.ServerManagerCode}"); comment.AppendLine($"Server Manager Key: {Config.Default.ASMUniqueKey}"); comment.AppendLine($"Server Manager Directory: {Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)}"); comment.AppendLine($"MachinePublicIP: {Config.Default.MachinePublicIP}"); comment.AppendLine($"Data Directory: {Config.Default.DataDir}"); comment.AppendLine($"Profiles Directory: {Config.Default.ConfigDirectory}"); if (!string.IsNullOrWhiteSpace(Config.Default.BackupPath)) comment.AppendLine($"Backup Directory: {Config.Default.BackupPath}"); else comment.AppendLine($"Backup Directory: *{Path.Combine(Config.Default.DataDir, Config.Default.BackupDir)}"); comment.AppendLine($"Server Directory: {this.Settings.InstallDirectory}"); comment.AppendLine($"SotF Server: {this.Settings.SOTF_Enabled}"); comment.AppendLine($"PGM Server: {this.Settings.PGM_Enabled}"); comment.AppendLine($"IsAdministrator: {SecurityUtils.IsAdministrator()}"); comment.AppendLine($"RunAsAdministratorPrompt: {Config.Default.RunAsAdministratorPrompt}"); comment.AppendLine($"ManageFirewallAutomatically: {Config.Default.ManageFirewallAutomatically}"); comment.AppendLine($"ValidateProfileOnServerStart: {Config.Default.ValidateProfileOnServerStart}"); comment.AppendLine($"SteamCMD File: {SteamCmdUpdater.GetSteamCmdFile(Config.Default.DataDir)}"); comment.AppendLine($"SteamCmdRedirectOutput: {Config.Default.SteamCmdRedirectOutput}"); comment.AppendLine($"SteamCmd_UseAnonymousCredentials: {Config.Default.SteamCmd_UseAnonymousCredentials}"); comment.AppendLine($"SteamCmd_Username Set: {!string.IsNullOrWhiteSpace(Config.Default.SteamCmd_Username)}"); comment.AppendLine($"SteamCmd_Password Set: {!string.IsNullOrWhiteSpace(Config.Default.SteamCmd_Password)}"); comment.AppendLine($"SteamAPIKey: {!string.IsNullOrWhiteSpace(CommonConfig.Default.SteamAPIKey)}"); comment.AppendLine($"SectionSOTFEnabled: {Config.Default.SectionSOTFEnabled}"); comment.AppendLine($"SectionPGMEnabled: {Config.Default.SectionPGMEnabled}"); comment.AppendLine($"SectionCraftingOverridesEnabled: {Config.Default.SectionCraftingOverridesEnabled}"); comment.AppendLine($"SectionMapSpawnerOverridesEnabled: {Config.Default.SectionMapSpawnerOverridesEnabled}"); comment.AppendLine($"SectionSupplyCrateOverridesEnabled: {Config.Default.SectionSupplyCrateOverridesEnabled}"); comment.AppendLine($"SectionStackSizeOverridesEnabled: {Config.Default.SectionStackSizeOverridesEnabled}"); comment.AppendLine($"SectionPreventTransferOverridesEnabled: {Config.Default.SectionPreventTransferOverridesEnabled}"); comment.AppendLine($"AutoBackup_EnableBackup: {Config.Default.AutoBackup_EnableBackup}"); comment.AppendLine($"AutoBackup_BackupPeriod: {Config.Default.AutoBackup_BackupPeriod}"); comment.AppendLine($"AutoBackup_DeleteOldFiles: {Config.Default.AutoBackup_DeleteOldFiles}"); comment.AppendLine($"AutoBackup_DeleteInterval: {Config.Default.AutoBackup_DeleteInterval}"); comment.AppendLine($"AutoUpdate_EnableUpdate: {Config.Default.AutoUpdate_EnableUpdate}"); comment.AppendLine($"AutoUpdate_CacheDir: {Config.Default.AutoUpdate_CacheDir}"); comment.AppendLine($"AutoUpdate_UpdatePeriod: {Config.Default.AutoUpdate_UpdatePeriod}"); comment.AppendLine($"AutoUpdate_UseSmartCopy: {Config.Default.AutoUpdate_UseSmartCopy}"); comment.AppendLine($"AutoUpdate_RetryOnFail: {Config.Default.AutoUpdate_RetryOnFail}"); comment.AppendLine($"AutoUpdate_ShowUpdateReason: {Config.Default.AutoUpdate_ShowUpdateReason}"); comment.AppendLine($"AutoUpdate_ValidateServerFiles: {Config.Default.AutoUpdate_ValidateServerFiles}"); comment.AppendLine($"AutoUpdate_OverrideServerStartup: {Config.Default.AutoUpdate_OverrideServerStartup}"); comment.AppendLine($"AutoRestart_EnabledGracePeriod: {Config.Default.AutoRestart_EnabledGracePeriod}"); comment.AppendLine($"AutoRestart_GracePeriod: {Config.Default.AutoRestart_GracePeriod}"); comment.AppendLine($"ServerShutdown_EnableWorldSave: {Config.Default.ServerShutdown_EnableWorldSave}"); comment.AppendLine($"ServerShutdown_CheckForOnlinePlayers: {Config.Default.ServerShutdown_CheckForOnlinePlayers}"); comment.AppendLine($"ServerShutdown_SendShutdownMessages: {Config.Default.ServerShutdown_SendShutdownMessages}"); comment.AppendLine($"ServerShutdown_GracePeriod: {Config.Default.ServerShutdown_GracePeriod}"); comment.AppendLine($"ServerUpdate_UpdateModsWhenUpdatingServer: {Config.Default.ServerUpdate_UpdateModsWhenUpdatingServer}"); comment.AppendLine($"ServerUpdate_ForceCopyMods: {Config.Default.ServerUpdate_ForceCopyMods}"); comment.AppendLine($"ServerUpdate_ForceUpdateMods: {Config.Default.ServerUpdate_ForceUpdateMods}"); comment.AppendLine($"ServerUpdate_ForceUpdateModsIfNoSteamInfo: {Config.Default.ServerUpdate_ForceUpdateModsIfNoSteamInfo}"); comment.AppendLine($"ServerUpdate_OnServerStart: {Config.Default.ServerUpdate_OnServerStart}"); comment.AppendLine($"EmailNotify_AutoRestart: {Config.Default.EmailNotify_AutoRestart}"); comment.AppendLine($"EmailNotify_AutoBackup: {Config.Default.EmailNotify_AutoBackup}"); comment.AppendLine($"EmailNotify_AutoUpdate: {Config.Default.EmailNotify_AutoUpdate}"); comment.AppendLine($"EmailNotify_ShutdownRestart: {Config.Default.EmailNotify_ShutdownRestart}"); comment.AppendLine($"ServerShutdown_UseShutdownCommand: {Config.Default.ServerShutdown_UseShutdownCommand}"); comment.AppendLine($"ServerShutdown_WorldSaveDelay: {Config.Default.ServerShutdown_WorldSaveDelay}"); comment.AppendLine($"BackupWorldFile: {Config.Default.BackupWorldFile}"); comment.AppendLine($"AutoUpdate_VerifyServerAfterUpdate: {Config.Default.AutoUpdate_VerifyServerAfterUpdate}"); comment.AppendLine($"UpdateDirectoryPermissions: {Config.Default.UpdateDirectoryPermissions}"); var zipFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), this.Settings.ProfileID + ".zip"); if (File.Exists(zipFile)) File.Delete(zipFile); ZipUtils.ZipFiles(zipFile, files.ToArray(), comment.ToString()); foreach (var kvp in obfuscateFiles) { ZipUtils.ZipAFile(zipFile, kvp.Key, kvp.Value); } var message = _globalizer.GetResourceString("ServerSettings_SupportZipSuccessLabel").Replace("{filename}", Path.GetFileName(zipFile)); MessageBox.Show(message, _globalizer.GetResourceString("ServerSettings_SupportZipTitle"), MessageBoxButton.OK, MessageBoxImage.Information); } catch (Exception ex) { MessageBox.Show(ex.Message, _globalizer.GetResourceString("ServerSettings_SupportZipErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error); } finally { Application.Current.Dispatcher.Invoke(() => this.Cursor = cursor); } } private async void ValidateProfile_Click(object sender, RoutedEventArgs e) { var cursor = this.Cursor; try { Application.Current.Dispatcher.Invoke(() => this.Cursor = Cursors.Wait); await Task.Delay(500); string validationMessage; var result = this.Settings.Validate(true, out validationMessage); if (result) MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ProfileValidateSuccessLabel"), _globalizer.GetResourceString("ServerSettings_ProfileValidateTitle"), MessageBoxButton.OK, MessageBoxImage.Warning); else MessageBox.Show(validationMessage, _globalizer.GetResourceString("ServerSettings_ProfileValidateTitle"), MessageBoxButton.OK, MessageBoxImage.Warning); } catch (Exception ex) { MessageBox.Show(ex.Message, _globalizer.GetResourceString("ServerSettings_ProfileValidateErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error); } finally { Application.Current.Dispatcher.Invoke(() => this.Cursor = cursor); } } private void SelectInstallDirectory_Click(object sender, RoutedEventArgs e) { var dialog = new CommonOpenFileDialog(); dialog.IsFolderPicker = true; dialog.Title = _globalizer.GetResourceString("ServerSettings_InstallServer_Title"); if (!String.IsNullOrWhiteSpace(Settings.InstallDirectory)) { dialog.InitialDirectory = Settings.InstallDirectory; } var result = dialog.ShowDialog(Window.GetWindow(this)); if (result == CommonFileDialogResult.Ok) { Settings.ChangeInstallationFolder(dialog.FileName); } } private void Load_Click(object sender, RoutedEventArgs e) { if (!Directory.Exists(Config.Default.ConfigDirectory)) { Directory.CreateDirectory(Config.Default.ConfigDirectory); } var dialog = new CommonOpenFileDialog { EnsureFileExists = true, InitialDirectory = Config.Default.ConfigDirectory, Multiselect = false, Title = _globalizer.GetResourceString("ServerSettings_LoadConfig_Title") }; dialog.Filters.Add(new CommonFileDialogFilter("Profile", Config.Default.LoadProfileExtensionList)); if (dialog.ShowDialog(Window.GetWindow(this)) == CommonFileDialogResult.Ok) { try { this.Server.ImportFromPath(dialog.FileName, Settings); this.Server.Profile.ResetProfileId(); this.Settings = this.Server.Profile; this.Runtime = this.Server.Runtime; } catch (Exception ex) { MessageBox.Show(String.Format(_globalizer.GetResourceString("ServerSettings_LoadConfig_ErrorLabel"), dialog.FileName, ex.Message, ex.StackTrace), _globalizer.GetResourceString("ServerSettings_LoadConfig_ErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Exclamation); } } } private void ShowCmd_Click(object sender, RoutedEventArgs e) { var cmdLine = new CommandLineWindow(String.Format("{0} {1}", this.Runtime.GetServerExe(), this.Settings.GetServerArgs())); cmdLine.Owner = Window.GetWindow(this); cmdLine.ShowDialog(); } private void ArkAutoSettings_Click(object sender, RoutedEventArgs e) { MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ArkAutoSettings_ErrorLabel"), _globalizer.GetResourceString("ServerSettings_ArkAutoSettings_ErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Information); } private async void SaveBackup_Click(object sender, RoutedEventArgs e) { try { Application.Current.Dispatcher.Invoke(() => this.Cursor = System.Windows.Input.Cursors.Wait); var app = new ServerApp(true) { DeleteOldServerBackupFiles = !Config.Default.AutoBackup_EnableBackup, SendEmails = false, OutputLogs = false, ServerProcess = ServerProcessType.Backup, }; var profile = ServerProfileSnapshot.Create(Server.Profile); var exitCode = await Task.Run(() => app.PerformProfileBackup(profile)); if (exitCode != ServerApp.EXITCODE_NORMALEXIT && exitCode != ServerApp.EXITCODE_CANCELLED) throw new ApplicationException($"An error occured during the backup process - ExitCode: {exitCode}"); MessageBox.Show(_globalizer.GetResourceString("ServerSettings_BackupServer_SuccessfulLabel"), _globalizer.GetResourceString("ServerSettings_BackupServer_Title"), MessageBoxButton.OK, MessageBoxImage.Information); } catch (Exception ex) { MessageBox.Show(ex.Message, _globalizer.GetResourceString("ServerSettings_BackupServer_FailedTitle"), MessageBoxButton.OK, MessageBoxImage.Error); } finally { Application.Current.Dispatcher.Invoke(() => this.Cursor = null); } } private void SaveRestore_Click(object sender, RoutedEventArgs e) { var window = new WorldSaveRestoreWindow(Server.Profile); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; window.ShowDialog(); } private void HiddenField_GotFocus(object sender, RoutedEventArgs e) { var hideTextBox = sender as TextBox; if (hideTextBox != null) { TextBox textBox = null; if (Equals(hideTextBox, HideServerPasswordTextBox)) textBox = ServerPasswordTextBox; if (Equals(hideTextBox, HideAdminPasswordTextBox)) textBox = AdminPasswordTextBox; if (Equals(hideTextBox, HideSpectatorPasswordTextBox)) textBox = SpectatorPasswordTextBox; if (Equals(hideTextBox, HideWebKeyTextBox)) textBox = WebKeyTextBox; if (Equals(hideTextBox, HideWebURLTextBox)) textBox = WebURLTextBox; if (Equals(hideTextBox, HideBranchPasswordTextBox)) textBox = BranchPasswordTextBox; if (textBox != null) { textBox.Visibility = System.Windows.Visibility.Visible; hideTextBox.Visibility = System.Windows.Visibility.Collapsed; textBox.Focus(); } UpdateLayout(); } } private void HiddenField_LostFocus(object sender, RoutedEventArgs e) { var textBox = sender as TextBox; if (textBox != null) { TextBox hideTextBox = null; if (textBox == ServerPasswordTextBox) hideTextBox = HideServerPasswordTextBox; if (textBox == AdminPasswordTextBox) hideTextBox = HideAdminPasswordTextBox; if (textBox == SpectatorPasswordTextBox) hideTextBox = HideSpectatorPasswordTextBox; if (textBox == WebKeyTextBox) hideTextBox = HideWebKeyTextBox; if (textBox == WebURLTextBox) hideTextBox = HideWebURLTextBox; if (textBox == BranchPasswordTextBox) hideTextBox = HideBranchPasswordTextBox; if (hideTextBox != null) { hideTextBox.Visibility = System.Windows.Visibility.Visible; textBox.Visibility = System.Windows.Visibility.Collapsed; } UpdateLayout(); } } private void ComboBox_PreviewMouseWheel(object sender, MouseWheelEventArgs e) { var comboBox = sender as ComboBox; if (comboBox == null) return; if (comboBox.IsDropDownOpen) return; e.Handled = true; } private void ComboBoxItemList_LostFocus(object sender, RoutedEventArgs e) { var comboBox = sender as ComboBox; if (comboBox == null) return; if (comboBox.SelectedItem == null) { var text = comboBox.Text; var source = comboBox.ItemsSource as ComboBoxItemList; source?.Add(new Common.Model.ComboBoxItem { ValueMember = text, DisplayMember = text, }); comboBox.SelectedValue = text; } var expression = comboBox.GetBindingExpression(Selector.SelectedValueProperty); expression?.UpdateSource(); expression = comboBox.GetBindingExpression(ComboBox.TextProperty); expression?.UpdateSource(); } private void OutOfDateModUpdate_Click(object sender, RoutedEventArgs e) { this.Runtime?.ResetModCheckTimer(); } private void ProfileName_SourceUpdated(object sender, DataTransferEventArgs e) { Settings.UpdateProfileToolTip(); } private void ServerName_SourceUpdated(object sender, DataTransferEventArgs e) { Settings.ValidateServerName(); } private void ServerPort_SourceUpdated(object sender, DataTransferEventArgs e) { // force the porperty to be updated. Settings.ServerPort = Settings.ServerPort; } private void MOTD_SourceUpdated(object sender, DataTransferEventArgs e) { Settings.ValidateMOTD(); } private void SyncProfile_Click(object sender, RoutedEventArgs e) { var window = new ProfileSyncWindow(ServerManager, Server.Profile); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; window.ShowDialog(); } private void EnableSOTFCheckbox_SourceUpdated(object sender, DataTransferEventArgs e) { var checkBox = sender as CheckBox; if (checkBox == null || checkBox != EnableSOTFCheckbox) return; this.Settings.ServerMap = string.Empty; this.Settings.TotalConversionModId = string.Empty; this.Settings.ServerModIds = string.Empty; this.Settings.BranchName = string.Empty; this.Settings.BranchPassword = string.Empty; this.Settings.EventName = string.Empty; RefreshBaseGameMapsList(); RefreshBaseTotalConversionsList(); RefreshBaseBranchesList(); RefreshBaseEventsList(); } private void OpenAffinity_Click(object sender, RoutedEventArgs e) { var window = new ProcessorAffinityWindow(Server.Profile.ProfileName, Server.Profile.ProcessAffinity) { Owner = Window.GetWindow(this) }; window.Closed += Window_Closed; var result = window.ShowDialog(); if (result.HasValue && result.Value) { Server.Profile.ProcessAffinity = window.AffinityValue; } } #region Dinos private void DinoCustomization_Reset(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DinoCustomization_ResetLabel"), _globalizer.GetResourceString("ServerSettings_DinoCustomization_ResetTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; this.Settings.DinoSettings.Reset(); RefreshBaseDinoList(); } private void DinoMod_OnFilter(object sender, FilterEventArgs e) { e.Accepted = FilterInDino(e.Item as DinoSettings); } private void FilterDino_Click(object sender, RoutedEventArgs e) { var view = this.DinoSettingsGrid.ItemsSource as ListCollectionView; view?.Refresh(); } private void PasteCustomDinos_Click(object sender, RoutedEventArgs e) { var window = new CustomConfigDataWindow(); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; var result = window.ShowDialog(); if (!result.HasValue || !result.Value) return; // read the pasted data into an ini file. var iniFile = IniFileUtils.ReadString(window.ConfigData); Server.Profile.DinoSettings.RenderToModel(); // cycle through the sections, adding them to the engrams list. Will bypass any sections that are named as per the ARK default sections. foreach (var section in iniFile.Sections.Where(s => s.SectionName != null && !SystemIniFile.IniSectionNames.ContainsValue(s.SectionName))) { var dinoSpawnWeightMultipliers = new AggregateIniValueList(nameof(Server.Profile.DinoSpawnWeightMultipliers), null); dinoSpawnWeightMultipliers.FromIniValues(section.KeysToStringArray().Where(s => s.StartsWith($"{dinoSpawnWeightMultipliers.IniCollectionKey}="))); Server.Profile.DinoSpawnWeightMultipliers.AddRange(dinoSpawnWeightMultipliers); Server.Profile.DinoSpawnWeightMultipliers.IsEnabled |= dinoSpawnWeightMultipliers.IsEnabled; var preventDinoTameClassNames = new StringIniValueList(nameof(Server.Profile.PreventDinoTameClassNames), null); preventDinoTameClassNames.FromIniValues(section.KeysToStringArray().Where(s => s.StartsWith($"{preventDinoTameClassNames.IniCollectionKey}="))); Server.Profile.PreventDinoTameClassNames.AddRange(preventDinoTameClassNames); Server.Profile.PreventDinoTameClassNames.IsEnabled |= preventDinoTameClassNames.IsEnabled; var npcReplacements = new AggregateIniValueList(nameof(Server.Profile.NPCReplacements), null); npcReplacements.FromIniValues(section.KeysToStringArray().Where(s => s.StartsWith($"{npcReplacements.IniCollectionKey}="))); Server.Profile.NPCReplacements.AddRange(npcReplacements); Server.Profile.NPCReplacements.IsEnabled |= npcReplacements.IsEnabled; var tamedDinoClassDamageMultipliers = new AggregateIniValueList(nameof(Server.Profile.TamedDinoClassDamageMultipliers), null); tamedDinoClassDamageMultipliers.FromIniValues(section.KeysToStringArray().Where(s => s.StartsWith($"{tamedDinoClassDamageMultipliers.IniCollectionKey}="))); Server.Profile.TamedDinoClassDamageMultipliers.AddRange(tamedDinoClassDamageMultipliers); Server.Profile.TamedDinoClassDamageMultipliers.IsEnabled |= tamedDinoClassDamageMultipliers.IsEnabled; var tamedDinoClassResistanceMultipliers = new AggregateIniValueList(nameof(Server.Profile.TamedDinoClassResistanceMultipliers), null); tamedDinoClassResistanceMultipliers.FromIniValues(section.KeysToStringArray().Where(s => s.StartsWith($"{tamedDinoClassResistanceMultipliers.IniCollectionKey}="))); Server.Profile.TamedDinoClassResistanceMultipliers.AddRange(tamedDinoClassResistanceMultipliers); Server.Profile.TamedDinoClassResistanceMultipliers.IsEnabled |= tamedDinoClassResistanceMultipliers.IsEnabled; var dinoClassDamageMultipliers = new AggregateIniValueList(nameof(Server.Profile.DinoClassDamageMultipliers), null); dinoClassDamageMultipliers.FromIniValues(section.KeysToStringArray().Where(s => s.StartsWith($"{dinoClassDamageMultipliers.IniCollectionKey}="))); Server.Profile.DinoClassDamageMultipliers.AddRange(dinoClassDamageMultipliers); Server.Profile.DinoClassDamageMultipliers.IsEnabled |= dinoClassDamageMultipliers.IsEnabled; var dinoClassResistanceMultipliers = new AggregateIniValueList(nameof(Server.Profile.DinoClassResistanceMultipliers), null); dinoClassResistanceMultipliers.FromIniValues(section.KeysToStringArray().Where(s => s.StartsWith($"{dinoClassResistanceMultipliers.IniCollectionKey}="))); Server.Profile.DinoClassResistanceMultipliers.AddRange(dinoClassResistanceMultipliers); Server.Profile.DinoClassResistanceMultipliers.IsEnabled |= dinoClassResistanceMultipliers.IsEnabled; } Server.Profile.DinoSettings = new DinoSettingsList(Server.Profile.DinoSpawnWeightMultipliers, Server.Profile.PreventDinoTameClassNames, Server.Profile.NPCReplacements, Server.Profile.TamedDinoClassDamageMultipliers, Server.Profile.TamedDinoClassResistanceMultipliers, Server.Profile.DinoClassDamageMultipliers, Server.Profile.DinoClassResistanceMultipliers); Server.Profile.DinoSettings.RenderToView(); RefreshBaseDinoList(); } private void RemoveDinoSetting_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DinoCustomization_DinoRemoveRecordLabel"), _globalizer.GetResourceString("ServerSettings_DinoCustomization_DinoRemoveRecordTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; var dino = ((DinoSettings)((Button)e.Source).DataContext); if (!dino.KnownDino) { this.Settings.DinoSettings.Remove(dino); RefreshBaseDinoList(); } } private void SaveCustomDinos_Click(object sender, RoutedEventArgs e) { Settings.DinoSettings.RenderToModel(); var iniValues = Settings.DinoSpawnWeightMultipliers.ToIniValues().ToList(); iniValues.AddRange(Settings.PreventDinoTameClassNames.ToIniValues()); iniValues.AddRange(Settings.NPCReplacements.ToIniValues()); iniValues.AddRange(Settings.DinoClassDamageMultipliers.ToIniValues()); iniValues.AddRange(Settings.DinoClassResistanceMultipliers.ToIniValues()); iniValues.AddRange(Settings.TamedDinoClassDamageMultipliers.ToIniValues()); iniValues.AddRange(Settings.TamedDinoClassResistanceMultipliers.ToIniValues()); var iniValue = string.Join("\r\n", iniValues); var window = new CommandLineWindow(iniValue); window.OutputTextWrapping = TextWrapping.NoWrap; window.Height = 500; window.Title = _globalizer.GetResourceString("ServerSettings_DinoCustomizations_SaveTitle"); window.Owner = Window.GetWindow(this); window.ShowDialog(); } private bool FilterInDino(DinoSettings dino) { if (dino == null) return false; return (SelectedModDino == GameData.MOD_ALL || dino.Mod == SelectedModDino) && (string.IsNullOrWhiteSpace(DinoFilterString) || dino.DisplayName.ToLower().Contains(DinoFilterString.ToLower())); } #endregion #region Resources private void HarvestResourceItemAmountClassMultipliers_Reset(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_CustomHarvest_ResetLabel"), _globalizer.GetResourceString("ServerSettings_CustomHarvest_ResetTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; this.Settings.HarvestResourceItemAmountClassMultipliers.Reset(); } private void PasteCustomResources_Click(object sender, RoutedEventArgs e) { var window = new CustomConfigDataWindow(); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; var result = window.ShowDialog(); if (!result.HasValue || !result.Value) return; // read the pasted data into an ini file. var iniFile = IniFileUtils.ReadString(window.ConfigData); // cycle through the sections, adding them to the engrams list. Will bypass any sections that are named as per the ARK default sections. foreach (var section in iniFile.Sections.Where(s => s.SectionName != null && !SystemIniFile.IniSectionNames.ContainsValue(s.SectionName))) { var harvestResourceItemAmountClassMultipliers = new AggregateIniValueList(nameof(Server.Profile.HarvestResourceItemAmountClassMultipliers), null); harvestResourceItemAmountClassMultipliers.FromIniValues(section.KeysToStringArray().Where(s => s.StartsWith($"{harvestResourceItemAmountClassMultipliers.IniCollectionKey}="))); Server.Profile.HarvestResourceItemAmountClassMultipliers.AddRange(harvestResourceItemAmountClassMultipliers); Server.Profile.HarvestResourceItemAmountClassMultipliers.IsEnabled |= harvestResourceItemAmountClassMultipliers.IsEnabled; } } private void RemoveHarvestResource_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_Harvest_HarvestRemoveRecordLabel"), _globalizer.GetResourceString("ServerSettings_Harvest_HarvestRemoveRecordTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; var resource = ((ResourceClassMultiplier)((Button)e.Source).DataContext); if (!resource.KnownResource) this.Settings.HarvestResourceItemAmountClassMultipliers.Remove(resource); } private void ResourceMod_OnFilter(object sender, FilterEventArgs e) { e.Accepted = FilterInResource(e.Item as ResourceClassMultiplier); } private void FilterResource_Click(object sender, RoutedEventArgs e) { var view = this.HarvestResourceItemAmountClassMultipliersListBox.ItemsSource as ListCollectionView; view?.Refresh(); } private void SaveCustomResources_Click(object sender, RoutedEventArgs e) { var iniValues = Settings.HarvestResourceItemAmountClassMultipliers.ToIniValues().ToList(); var iniValue = string.Join("\r\n", iniValues); var window = new CommandLineWindow(iniValue); window.OutputTextWrapping = TextWrapping.NoWrap; window.Height = 500; window.Title = _globalizer.GetResourceString("ServerSettings_CustomResources_SaveTitle"); window.Owner = Window.GetWindow(this); window.ShowDialog(); } private bool FilterInResource(ResourceClassMultiplier resource) { if (resource == null) return false; return (SelectedModResource == GameData.MOD_ALL || resource.Mod == SelectedModResource) && (string.IsNullOrWhiteSpace(ResourceFilterString) || resource.DisplayName.ToLower().Contains(ResourceFilterString.ToLower())); } #endregion #region Engrams private void Engrams_Reset(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_EngramsOverride_ResetLabel"), _globalizer.GetResourceString("ServerSettings_EngramsOverride_ResetTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; this.Settings.ResetEngramsSection(); } private void Engrams_SelectAll(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_EngramsOverride_SelectAllConfirmLabel"), _globalizer.GetResourceString("ServerSettings_EngramsOverride_SelectAllConfirmTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; foreach (var engram in Settings.EngramSettings) { if (FilterInEngram(engram)) engram.SaveEngramOverride = true; } } private void Engrams_UnselectAll(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_EngramsOverride_UnselectAllConfirmLabel"), _globalizer.GetResourceString("ServerSettings_EngramsOverride_UnselectAllConfirmTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; foreach (var engram in Settings.EngramSettings) { if (FilterInEngram(engram)) engram.SaveEngramOverride = false; } } private void EngramMod_OnFilter(object sender, FilterEventArgs e) { e.Accepted = FilterInEngram(e.Item as EngramSettings); } private async void ExportCustomEngrams_Click(object sender, RoutedEventArgs e) { // ask user for a filename to save the engram data to var dialog = new CommonSaveFileDialog { Title = GlobalizedApplication.Instance.GetResourceString("ServerSettings_EngramsOverride_ExportDialogTitle"), DefaultExtension = GlobalizedApplication.Instance.GetResourceString("ServerSettings_EngramsOverride_ExportDefaultExtension") }; dialog.Filters.Add(new CommonFileDialogFilter(GlobalizedApplication.Instance.GetResourceString("ServerSettings_EngramsOverride_ExportFilterLabel"), GlobalizedApplication.Instance.GetResourceString("ServerSettings_EngramsOverride_ExportFilterExtension"))); if (dialog == null || dialog.ShowDialog(Window.GetWindow(this)) != CommonFileDialogResult.Ok) return; var cursor = this.Cursor; try { Application.Current.Dispatcher.Invoke(() => this.Cursor = Cursors.Wait); await Task.Delay(500); // update the data export Settings.EngramSettings.OnlyAllowSpecifiedEngrams = Settings.OnlyAllowSpecifiedEngrams; // perform the json serialization Common.Utils.JsonUtils.SerializeToFile(new { Settings.EngramSettings.OnlyAllowSpecifiedEngrams, EngramSettings = Settings.EngramSettings.ToList(), }, dialog.FileName); } catch (Exception ex) { MessageBox.Show(ex.Message, GlobalizedApplication.Instance.GetResourceString("ServerSettings_EngramsOverride_ExportErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error); } finally { Application.Current.Dispatcher.Invoke(() => this.Cursor = cursor); } } private void FilterEngram_Click(object sender, RoutedEventArgs e) { var view = this.EngramsOverrideGrid.ItemsSource as ListCollectionView; view?.Refresh(); } private async void ImportCustomEngrams_Click(object sender, RoutedEventArgs e) { // ask user for a filename to load the engram data from var dialog = new CommonOpenFileDialog { Title = GlobalizedApplication.Instance.GetResourceString("ServerSettings_EngramsOverride_ImportDialogTitle"), DefaultExtension = GlobalizedApplication.Instance.GetResourceString("ServerSettings_EngramsOverride_ImportDefaultExtension") }; dialog.Filters.Add(new CommonFileDialogFilter(GlobalizedApplication.Instance.GetResourceString("ServerSettings_EngramsOverride_ImportFilterLabel"), GlobalizedApplication.Instance.GetResourceString("ServerSettings_EngramsOverride_ImportFilterExtension"))); if (dialog == null || dialog.ShowDialog(Window.GetWindow(this)) != CommonFileDialogResult.Ok) return; // confirm with user which option to use - Overwrite, Merge or Cancel var result = MessageBox.Show(GlobalizedApplication.Instance.GetResourceString("ServerSettings_EngramsOverride_ImportConfirmationLabel"), GlobalizedApplication.Instance.GetResourceString("ServerSettings_EngramsOverride_ImportConfirmationTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question); if (result != MessageBoxResult.Yes) return; var cursor = this.Cursor; try { Application.Current.Dispatcher.Invoke(() => this.Cursor = Cursors.Wait); await Task.Delay(500); // perform the json deserialization var input = Common.Utils.JsonUtils.DeserializeFromFile(dialog.FileName, new { OnlyAllowSpecifiedEngrams = false, EngramSettings = new List(), }); if (input?.EngramSettings != null) { // perform the class population Settings.OnlyAllowSpecifiedEngrams = input.OnlyAllowSpecifiedEngrams; Settings.EngramSettings.OnlyAllowSpecifiedEngrams = input.OnlyAllowSpecifiedEngrams; foreach (var engramSetting in input.EngramSettings.Where(engram => !string.IsNullOrWhiteSpace(engram.EngramClassName))) { var foundEngramSetting = Settings.EngramSettings.FirstOrDefault(engram => engram.EngramClassName.Equals(engramSetting.EngramClassName, StringComparison.OrdinalIgnoreCase)); if (foundEngramSetting == null) { // engram not found, add to the list Settings.EngramSettings.Add(engramSetting); } else { // engram was found, update the values foundEngramSetting.Mod = engramSetting.Mod; foundEngramSetting.IsTekgram = engramSetting.IsTekgram; foundEngramSetting.EngramLevelRequirement = engramSetting.EngramLevelRequirement; foundEngramSetting.EngramPointsCost = engramSetting.EngramPointsCost; foundEngramSetting.EngramHidden = engramSetting.EngramHidden; foundEngramSetting.RemoveEngramPreReq = engramSetting.RemoveEngramPreReq; foundEngramSetting.EngramAutoUnlock = engramSetting.EngramAutoUnlock; foundEngramSetting.LevelToAutoUnlock = engramSetting.LevelToAutoUnlock; foundEngramSetting.SaveEngramOverride = engramSetting.SaveEngramOverride; } } // perform a model reload Settings.EngramSettings.RenderToModel(); } } catch (Exception ex) { MessageBox.Show(ex.Message, GlobalizedApplication.Instance.GetResourceString("ServerSettings_EngramsOverride_ImportErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error); } finally { Application.Current.Dispatcher.Invoke(() => this.Cursor = cursor); } } private void PasteCustomEngrams_Click(object sender, RoutedEventArgs e) { var window = new CustomConfigDataWindow(); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; var result = window.ShowDialog(); if (!result.HasValue || !result.Value) return; // read the pasted data into an ini file. var iniFile = IniFileUtils.ReadString(window.ConfigData); Server.Profile.EngramSettings.OnlyAllowSpecifiedEngrams = Server.Profile.OnlyAllowSpecifiedEngrams; Server.Profile.EngramSettings.RenderToModel(); // cycle through the sections, adding them to the engrams list. Will bypass any sections that are named as per the ARK default sections. foreach (var section in iniFile.Sections.Where(s => s.SectionName != null && !SystemIniFile.IniSectionNames.ContainsValue(s.SectionName))) { var overrideNamedEngramEntries = new EngramEntryList(nameof(Server.Profile.OverrideNamedEngramEntries)); overrideNamedEngramEntries.FromIniValues(section.KeysToStringArray().Where(s => s.StartsWith($"{overrideNamedEngramEntries.IniCollectionKey}="))); Server.Profile.OverrideNamedEngramEntries.AddRange(overrideNamedEngramEntries); Server.Profile.OverrideNamedEngramEntries.IsEnabled |= overrideNamedEngramEntries.IsEnabled; var engramEntryAutoUnlocks = new EngramAutoUnlockList(nameof(Server.Profile.EngramEntryAutoUnlocks)); engramEntryAutoUnlocks.FromIniValues(section.KeysToStringArray().Where(s => s.StartsWith($"{engramEntryAutoUnlocks.IniCollectionKey}="))); Server.Profile.EngramEntryAutoUnlocks.AddRange(engramEntryAutoUnlocks); Server.Profile.EngramEntryAutoUnlocks.IsEnabled |= engramEntryAutoUnlocks.IsEnabled; } Server.Profile.EngramSettings = new EngramSettingsList(Server.Profile.OverrideNamedEngramEntries, Server.Profile.EngramEntryAutoUnlocks); Server.Profile.EngramSettings.OnlyAllowSpecifiedEngrams = Server.Profile.OnlyAllowSpecifiedEngrams; Server.Profile.EngramSettings.RenderToView(); } private void RemoveEngramOverride_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_EngramsOverride_EngramsRemoveRecordLabel"), _globalizer.GetResourceString("ServerSettings_EngramsOverride_EngramsRemoveRecordTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; var engram = ((EngramSettings)((Button)e.Source).DataContext); if (!engram.KnownEngram) this.Settings.EngramSettings.Remove(engram); } private void SaveCustomEngrams_Click(object sender, RoutedEventArgs e) { Settings.EngramSettings.OnlyAllowSpecifiedEngrams = Settings.OnlyAllowSpecifiedEngrams; Settings.EngramSettings.RenderToModel(); var iniValues = Settings.OverrideNamedEngramEntries.ToIniValues().ToList(); iniValues.AddRange(Settings.EngramEntryAutoUnlocks.ToIniValues()); var iniValue = string.Join("\r\n", iniValues); var window = new CommandLineWindow(iniValue); window.OutputTextWrapping = TextWrapping.NoWrap; window.Height = 500; window.Title = _globalizer.GetResourceString("ServerSettings_CustomEngrams_SaveTitle"); window.Owner = Window.GetWindow(this); window.ShowDialog(); } private bool FilterInEngram(EngramSettings engram) { if (engram == null) return false; return (SelectedModEngram == GameData.MOD_ALL || engram.Mod == SelectedModEngram) && (!Settings.OnlyAllowSpecifiedEngrams || !FilterOnlySelectedEngrams || engram.SaveEngramOverride) && (string.IsNullOrWhiteSpace(EngramFilterString) || engram.DisplayName.ToLower().Contains(EngramFilterString.ToLower())); } #endregion #region Crafting Overrides private void AddCraftingOverride_Click(object sender, RoutedEventArgs e) { Settings.ConfigOverrideItemCraftingCosts.Add(new CraftingOverride()); Settings.ConfigOverrideItemCraftingCosts.IsEnabled = true; } private void AddCraftingOverrideResource_Click(object sender, RoutedEventArgs e) { if (SelectedCraftingOverride == null) { MessageBox.Show(_globalizer.GetResourceString("ServerSettings_AddChildErrorLabel"), _globalizer.GetResourceString("ServerSettings_AddChildErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error); return; } SelectedCraftingOverride.BaseCraftingResourceRequirements.Add(new CraftingResourceRequirement()); } private void ClearCraftingOverrides_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ClearLabel"), _globalizer.GetResourceString("ServerSettings_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; SelectedCraftingOverride = null; Settings.ConfigOverrideItemCraftingCosts.Clear(); Settings.ConfigOverrideItemCraftingCosts.IsEnabled = false; } private void ClearCraftingOverrideResources_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ClearLabel"), _globalizer.GetResourceString("ServerSettings_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; SelectedCraftingOverride?.BaseCraftingResourceRequirements.Clear(); } private void PasteCraftingOverride_Click(object sender, RoutedEventArgs e) { var window = new CustomConfigDataWindow(); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; var result = window.ShowDialog(); if (!result.HasValue || !result.Value) return; // read the pasted data into an ini file. var iniFile = IniFileUtils.ReadString(window.ConfigData.Replace(" ", "")); // cycle through the sections, adding them to the engrams list. Will bypass any sections that are named as per the ARK default sections. foreach (var section in iniFile.Sections.Where(s => s.SectionName != null && !SystemIniFile.IniSectionNames.ContainsValue(s.SectionName))) { var configOverrideItemCraftingCosts = new AggregateIniValueList(nameof(Server.Profile.ConfigOverrideItemCraftingCosts), null); configOverrideItemCraftingCosts.FromIniValues(section.KeysToStringArray().Where(s => s.StartsWith($"{configOverrideItemCraftingCosts.IniCollectionKey}="))); Server.Profile.ConfigOverrideItemCraftingCosts.AddRange(configOverrideItemCraftingCosts); Server.Profile.ConfigOverrideItemCraftingCosts.IsEnabled |= configOverrideItemCraftingCosts.IsEnabled; } RefreshBasePrimalItemList(); } private void RemoveCraftingOverrideItem_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DeleteLabel"), _globalizer.GetResourceString("ServerSettings_DeleteTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; var item = ((CraftingOverride)((Button)e.Source).DataContext); Settings.ConfigOverrideItemCraftingCosts.Remove(item); Settings.ConfigOverrideItemCraftingCosts.IsEnabled = Settings.ConfigOverrideItemCraftingCosts.Count > 0; } private void RemoveCraftingOverrideResource_Click(object sender, RoutedEventArgs e) { if (SelectedCraftingOverride == null) return; if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DeleteLabel"), _globalizer.GetResourceString("ServerSettings_DeleteTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; var item = ((CraftingResourceRequirement)((Button)e.Source).DataContext); SelectedCraftingOverride.BaseCraftingResourceRequirements.Remove(item); } private void SaveCraftingOverride_Click(object sender, RoutedEventArgs e) { var iniValues = Settings.ConfigOverrideItemCraftingCosts.ToIniValues().ToList(); var iniValue = string.Join("\r\n", iniValues); var window = new CommandLineWindow(iniValue); window.OutputTextWrapping = TextWrapping.NoWrap; window.Height = 500; window.Title = _globalizer.GetResourceString("ServerSettings_CraftingOverrides_SaveTitle"); window.Owner = Window.GetWindow(this); window.ShowDialog(); } private void SaveCraftingOverrideItem_Click(object sender, RoutedEventArgs e) { var item = ((CraftingOverride)((Button)e.Source).DataContext); if (item == null) return; var iniName = Settings.ConfigOverrideItemCraftingCosts.IniCollectionKey; var iniValue = $"{iniName}={item.ToINIValue()}"; var window = new CommandLineWindow(iniValue); window.OutputTextWrapping = TextWrapping.Wrap; window.Height = 500; window.Title = _globalizer.GetResourceString("ServerSettings_CraftingOverrides_SaveTitle"); window.Owner = Window.GetWindow(this); window.ShowDialog(); } #endregion #region Custom GameUserSettings private void AddCustomGameUserSettingItem_Click(object sender, RoutedEventArgs e) { SelectedCustomGameUserSetting?.Add(string.Empty, string.Empty); } private void AddCustomGameUserSettingSection_Click(object sender, RoutedEventArgs e) { Settings.CustomGameUserSettings.Add(string.Empty, new string[0]); } private void ClearCustomGameUserSettingItems_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ClearLabel"), _globalizer.GetResourceString("ServerSettings_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; SelectedCustomGameUserSetting?.Clear(); } private void ClearCustomGameUserSettingSections_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ClearLabel"), _globalizer.GetResourceString("ServerSettings_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; SelectedCustomGameUserSetting = null; Settings.CustomGameUserSettings.Clear(); } private void ImportCustomGameUserSettingSections_Click(object sender, RoutedEventArgs e) { var dialog = new CommonOpenFileDialog(); dialog.EnsureFileExists = true; dialog.Multiselect = false; dialog.Title = _globalizer.GetResourceString("ServerSettings_LoadCustomConfig_Title"); dialog.Filters.Add(new CommonFileDialogFilter("Ini Files", "*.ini")); dialog.InitialDirectory = Settings.InstallDirectory; var result = dialog.ShowDialog(Window.GetWindow(this)); if (result == CommonFileDialogResult.Ok) { try { // read the selected ini file. var iniFile = IniFileUtils.ReadFromFile(dialog.FileName); // cycle through the sections, adding them to the custom section list. Will bypass any sections that are named as per the ARK default sections. foreach (var section in iniFile.Sections.Where(s => !string.IsNullOrWhiteSpace(s.SectionName) && !SystemIniFile.IniSectionNames.ContainsValue(s.SectionName))) { Settings.CustomGameUserSettings.Add(section.SectionName, section.KeysToStringArray(), false); } MessageBox.Show(_globalizer.GetResourceString("ServerSettings_LoadCustomConfig_Label"), _globalizer.GetResourceString("ServerSettings_LoadCustomConfig_Title"), MessageBoxButton.OK, MessageBoxImage.Information); } catch (Exception ex) { MessageBox.Show(ex.Message, _globalizer.GetResourceString("ServerSettings_LoadCustomConfig_ErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Exclamation); } } } private void PasteCustomGameUserSettingItems_Click(object sender, RoutedEventArgs e) { if (SelectedCustomGameUserSetting == null) return; var window = new CustomConfigDataWindow(); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; var result = window.ShowDialog(); if (!result.HasValue || !result.Value) return; // read the pasted data into an ini file. var iniFile = IniFileUtils.ReadString(window.ConfigData); // get the section with the same name as the currently selected custom section. var section = iniFile?.GetSection(SelectedCustomGameUserSetting.SectionName); // check if the section exists. if (section == null) // section is not exists, get the section with the empty name. section = iniFile?.GetSection(string.Empty) ?? new IniSection(); // cycle through the section keys, adding them to the selected custom section. foreach (var key in section.Keys) { // check if the key name has been defined. if (!string.IsNullOrWhiteSpace(key.KeyName)) SelectedCustomGameUserSetting.Add(key.KeyName, key.KeyValue); } } private void PasteCustomGameUserSettingSections_Click(object sender, RoutedEventArgs e) { var window = new CustomConfigDataWindow(); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; var result = window.ShowDialog(); if (!result.HasValue || !result.Value) return; // read the pasted data into an ini file. var iniFile = IniFileUtils.ReadString(window.ConfigData); // cycle through the sections, adding them to the custom section list. Will bypass any sections that are named as per the ARK default sections. foreach (var section in iniFile.Sections.Where(s => !string.IsNullOrWhiteSpace(s.SectionName) && !SystemIniFile.IniSectionNames.ContainsValue(s.SectionName))) { Settings.CustomGameUserSettings.Add(section.SectionName, section.KeysToStringArray(), false); } } private void ReloadCustomGameUserSettings_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ReloadLabel"), _globalizer.GetResourceString("ServerSettings_ReloadTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; try { // build a full exclusion list var exclusions = new List(); foreach (var serverProfileCategory in Enum.GetValues(typeof(ServerProfileCategory))) { if ((ServerProfileCategory)serverProfileCategory == ServerProfileCategory.CustomGameUserSettings) continue; exclusions.Add((ServerProfileCategory)serverProfileCategory); } var configIniFile = Path.Combine(ServerProfile.GetProfileServerConfigDir(Settings), Config.Default.ServerGameUserSettingsConfigFile); // load only this section, using the full exclusion list var tempServerProfile = ServerProfile.LoadFromINIFiles(configIniFile, null, exclusions.ToArray()); // perform a profile sync Settings.SyncSettings(ServerProfileCategory.CustomGameUserSettings, tempServerProfile); } catch (Exception ex) { MessageBox.Show(ex.Message, _globalizer.GetResourceString("ServerSettings_ReloadErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error); } } private void RemoveCustomGameUserSettingItem_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DeleteLabel"), _globalizer.GetResourceString("ServerSettings_DeleteTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; if (SelectedCustomGameUserSetting == null) return; var item = ((CustomItem)((Button)e.Source).DataContext); SelectedCustomGameUserSetting.Remove(item); } private void RemoveCustomGameUserSettingSection_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DeleteLabel"), _globalizer.GetResourceString("ServerSettings_DeleteTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; var section = ((CustomSection)((Button)e.Source).DataContext); Settings.CustomGameUserSettings.Remove(section); } #endregion #region Custom GameSettings private void AddCustomGameSettingItem_Click(object sender, RoutedEventArgs e) { SelectedCustomGameSetting?.Add(string.Empty, string.Empty); } private void AddCustomGameSettingSection_Click(object sender, RoutedEventArgs e) { Settings.CustomGameSettings.Add(string.Empty, new string[0]); } private void ClearCustomGameSettingItems_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ClearLabel"), _globalizer.GetResourceString("ServerSettings_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; SelectedCustomGameSetting?.Clear(); } private void ClearCustomGameSettingSections_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ClearLabel"), _globalizer.GetResourceString("ServerSettings_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; SelectedCustomGameSetting = null; Settings.CustomGameSettings.Clear(); } private void ImportCustomGameSettingSections_Click(object sender, RoutedEventArgs e) { var dialog = new CommonOpenFileDialog(); dialog.EnsureFileExists = true; dialog.Multiselect = false; dialog.Title = _globalizer.GetResourceString("ServerSettings_LoadCustomConfig_Title"); dialog.Filters.Add(new CommonFileDialogFilter("Ini Files", "*.ini")); dialog.InitialDirectory = Settings.InstallDirectory; var result = dialog.ShowDialog(Window.GetWindow(this)); if (result == CommonFileDialogResult.Ok) { try { // read the selected ini file. var iniFile = IniFileUtils.ReadFromFile(dialog.FileName); // cycle through the sections, adding them to the custom section list. Will bypass any sections that are named as per the ARK default sections. foreach (var section in iniFile.Sections.Where(s => !string.IsNullOrWhiteSpace(s.SectionName) && !SystemIniFile.IniSectionNames.ContainsValue(s.SectionName))) { Settings.CustomGameSettings.Add(section.SectionName, section.KeysToStringArray(), false); } MessageBox.Show(_globalizer.GetResourceString("ServerSettings_LoadCustomConfig_Label"), _globalizer.GetResourceString("ServerSettings_LoadCustomConfig_Title"), MessageBoxButton.OK, MessageBoxImage.Information); } catch (Exception ex) { MessageBox.Show(ex.Message, _globalizer.GetResourceString("ServerSettings_LoadCustomConfig_ErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Exclamation); } } } private void PasteCustomGameSettingItems_Click(object sender, RoutedEventArgs e) { if (SelectedCustomGameSetting == null) return; var window = new CustomConfigDataWindow(); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; var result = window.ShowDialog(); if (!result.HasValue || !result.Value) return; // read the pasted data into an ini file. var iniFile = IniFileUtils.ReadString(window.ConfigData); // get the section with the same name as the currently selected custom section. var section = iniFile?.GetSection(SelectedCustomGameSetting.SectionName); // check if the section exists. if (section == null) // section is not exists, get the section with the empty name. section = iniFile?.GetSection(string.Empty) ?? new IniSection(); // cycle through the section keys, adding them to the selected custom section. foreach (var key in section.Keys) { // check if the key name has been defined. if (!string.IsNullOrWhiteSpace(key.KeyName)) SelectedCustomGameSetting.Add(key.KeyName, key.KeyValue); } } private void PasteCustomGameSettingSections_Click(object sender, RoutedEventArgs e) { var window = new CustomConfigDataWindow(); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; var result = window.ShowDialog(); if (!result.HasValue || !result.Value) return; // read the pasted data into an ini file. var iniFile = IniFileUtils.ReadString(window.ConfigData); // cycle through the sections, adding them to the custom section list. Will bypass any sections that are named as per the ARK default sections. foreach (var section in iniFile.Sections.Where(s => !string.IsNullOrWhiteSpace(s.SectionName) && !SystemIniFile.IniSectionNames.ContainsValue(s.SectionName))) { Settings.CustomGameSettings.Add(section.SectionName, section.KeysToStringArray(), false); } } private void ReloadCustomGameSettings_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ReloadLabel"), _globalizer.GetResourceString("ServerSettings_ReloadTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; try { // build a full exclusion list var exclusions = new List(); foreach (var serverProfileCategory in Enum.GetValues(typeof(ServerProfileCategory))) { if ((ServerProfileCategory)serverProfileCategory == ServerProfileCategory.CustomGameSettings) continue; exclusions.Add((ServerProfileCategory)serverProfileCategory); } var configIniFile = Path.Combine(ServerProfile.GetProfileServerConfigDir(Settings), Config.Default.ServerGameUserSettingsConfigFile); // load only this section, using the full exclusion list var tempServerProfile = ServerProfile.LoadFromINIFiles(configIniFile, null, exclusions.ToArray()); // perform a profile sync Settings.SyncSettings(ServerProfileCategory.CustomGameSettings, tempServerProfile); } catch (Exception ex) { MessageBox.Show(ex.Message, _globalizer.GetResourceString("ServerSettings_ReloadErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error); } } private void RemoveCustomGameSettingItem_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DeleteLabel"), _globalizer.GetResourceString("ServerSettings_DeleteTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; if (SelectedCustomGameSetting == null) return; var item = ((CustomItem)((Button)e.Source).DataContext); SelectedCustomGameSetting.Remove(item); } private void RemoveCustomGameSettingSection_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DeleteLabel"), _globalizer.GetResourceString("ServerSettings_DeleteTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; var section = ((CustomSection)((Button)e.Source).DataContext); Settings.CustomGameSettings.Remove(section); } #endregion #region Custom EngineSettings private void AddCustomEngineSettingItem_Click(object sender, RoutedEventArgs e) { SelectedCustomEngineSetting?.Add(string.Empty, string.Empty); } private void AddCustomEngineSettingSection_Click(object sender, RoutedEventArgs e) { Settings.CustomEngineSettings.Add(string.Empty, new string[0]); } private void ClearCustomEngineSettingItems_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ClearLabel"), _globalizer.GetResourceString("ServerSettings_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; SelectedCustomEngineSetting?.Clear(); } private void ClearCustomEngineSettingSections_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ClearLabel"), _globalizer.GetResourceString("ServerSettings_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; SelectedCustomEngineSetting = null; Settings.CustomEngineSettings.Clear(); } private void ImportCustomEngineSettingSections_Click(object sender, RoutedEventArgs e) { var dialog = new CommonOpenFileDialog(); dialog.EnsureFileExists = true; dialog.Multiselect = false; dialog.Title = _globalizer.GetResourceString("ServerSettings_LoadCustomConfig_Title"); dialog.Filters.Add(new CommonFileDialogFilter("Ini Files", "*.ini")); dialog.InitialDirectory = Settings.InstallDirectory; var result = dialog.ShowDialog(Window.GetWindow(this)); if (result == CommonFileDialogResult.Ok) { try { // read the selected ini file. var iniFile = IniFileUtils.ReadFromFile(dialog.FileName); // cycle through the sections, adding them to the custom section list. Will bypass any sections that are named as per the ARK default sections. foreach (var section in iniFile.Sections.Where(s => !string.IsNullOrWhiteSpace(s.SectionName) && !SystemIniFile.IniSectionNames.ContainsValue(s.SectionName))) { Settings.CustomEngineSettings.Add(section.SectionName, section.KeysToStringArray(), false); } MessageBox.Show(_globalizer.GetResourceString("ServerSettings_LoadCustomConfig_Label"), _globalizer.GetResourceString("ServerSettings_LoadCustomConfig_Title"), MessageBoxButton.OK, MessageBoxImage.Information); } catch (Exception ex) { MessageBox.Show(ex.Message, _globalizer.GetResourceString("ServerSettings_LoadCustomConfig_ErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Exclamation); } } } private void PasteCustomEngineSettingItems_Click(object sender, RoutedEventArgs e) { if (SelectedCustomEngineSetting == null) return; var window = new CustomConfigDataWindow(); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; var result = window.ShowDialog(); if (!result.HasValue || !result.Value) return; // read the pasted data into an ini file. var iniFile = IniFileUtils.ReadString(window.ConfigData); // get the section with the same name as the currently selected custom section. var section = iniFile?.GetSection(SelectedCustomEngineSetting.SectionName); // check if the section exists. if (section == null) // section is not exists, get the section with the empty name. section = iniFile?.GetSection(string.Empty) ?? new IniSection(); // cycle through the section keys, adding them to the selected custom section. foreach (var key in section.Keys) { // check if the key name has been defined. if (!string.IsNullOrWhiteSpace(key.KeyName)) SelectedCustomEngineSetting.Add(key.KeyName, key.KeyValue); } } private void PasteCustomEngineSettingSections_Click(object sender, RoutedEventArgs e) { var window = new CustomConfigDataWindow(); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; var result = window.ShowDialog(); if (!result.HasValue || !result.Value) return; // read the pasted data into an ini file. var iniFile = IniFileUtils.ReadString(window.ConfigData); // cycle through the sections, adding them to the custom section list. Will bypass any sections that are named as per the ARK default sections. foreach (var section in iniFile.Sections.Where(s => !string.IsNullOrWhiteSpace(s.SectionName) && !SystemIniFile.IniSectionNames.ContainsValue(s.SectionName))) { Settings.CustomEngineSettings.Add(section.SectionName, section.KeysToStringArray(), false); } } private void ReloadCustomEngineSettings_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ReloadLabel"), _globalizer.GetResourceString("ServerSettings_ReloadTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; try { // build a full exclusion list var exclusions = new List(); foreach (var serverProfileCategory in Enum.GetValues(typeof(ServerProfileCategory))) { if ((ServerProfileCategory)serverProfileCategory == ServerProfileCategory.CustomEngineSettings) continue; exclusions.Add((ServerProfileCategory)serverProfileCategory); } var configIniFile = Path.Combine(ServerProfile.GetProfileServerConfigDir(Settings), Config.Default.ServerGameUserSettingsConfigFile); // load only this section, using the full exclusion list var tempServerProfile = ServerProfile.LoadFromINIFiles(configIniFile, null, exclusions.ToArray()); // perform a profile sync Settings.SyncSettings(ServerProfileCategory.CustomEngineSettings, tempServerProfile); } catch (Exception ex) { MessageBox.Show(ex.Message, _globalizer.GetResourceString("ServerSettings_ReloadErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error); } } private void RemoveCustomEngineSettingItem_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DeleteLabel"), _globalizer.GetResourceString("ServerSettings_DeleteTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; if (SelectedCustomEngineSetting == null) return; var item = ((CustomItem)((Button)e.Source).DataContext); SelectedCustomEngineSetting.Remove(item); } private void RemoveCustomEngineSettingSection_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DeleteLabel"), _globalizer.GetResourceString("ServerSettings_DeleteTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; var section = ((CustomSection)((Button)e.Source).DataContext); Settings.CustomEngineSettings.Remove(section); } #endregion #region Custom Levels private CommonFileDialog GetCustomLevelCommonFileDialog(ServerSettingsCustomLevelsAction action) { CommonFileDialog dialog = null; switch (action) { case ServerSettingsCustomLevelsAction.ExportDinoLevels: case ServerSettingsCustomLevelsAction.ExportPlayerLevels: dialog = new CommonSaveFileDialog(); dialog.Title = GlobalizedApplication.Instance.GetResourceString("ServerSettings_CustomLevel_ExportDialogTitle"); dialog.DefaultExtension = GlobalizedApplication.Instance.GetResourceString("ServerSettings_CustomLevel_ExportDefaultExtension"); dialog.Filters.Add(new CommonFileDialogFilter(GlobalizedApplication.Instance.GetResourceString("ServerSettings_CustomLevel_ExportFilterLabel"), GlobalizedApplication.Instance.GetResourceString("ServerSettings_CustomLevel_ExportFilterExtension"))); break; case ServerSettingsCustomLevelsAction.ImportDinoLevels: case ServerSettingsCustomLevelsAction.ImportPlayerLevels: dialog = new CommonOpenFileDialog(); dialog.Title = GlobalizedApplication.Instance.GetResourceString("ServerSettings_CustomLevel_ImportDialogTitle"); dialog.DefaultExtension = GlobalizedApplication.Instance.GetResourceString("ServerSettings_CustomLevel_ImportDefaultExtension"); dialog.Filters.Add(new CommonFileDialogFilter(GlobalizedApplication.Instance.GetResourceString("ServerSettings_CustomLevel_ImportFilterLabel"), GlobalizedApplication.Instance.GetResourceString("ServerSettings_CustomLevel_ImportFilterExtension"))); break; } return dialog; } public ICommand CustomLevelActionCommand { get { return new RelayCommand( execute: (action) => { var errorTitle = GlobalizedApplication.Instance.GetResourceString("Generic_ErrorLabel"); try { var dialog = GetCustomLevelCommonFileDialog(action); var dialogValue = string.Empty; if (dialog != null && dialog.ShowDialog(Window.GetWindow(this)) == CommonFileDialogResult.Ok) dialogValue = dialog.FileName; switch (action) { case ServerSettingsCustomLevelsAction.ExportDinoLevels: errorTitle = GlobalizedApplication.Instance.GetResourceString("ServerSettings_CustomLevel_ExportErrorTitle"); this.Settings.ExportDinoLevels(dialogValue); break; case ServerSettingsCustomLevelsAction.ImportDinoLevels: errorTitle = GlobalizedApplication.Instance.GetResourceString("ServerSettings_CustomLevel_ImportErrorTitle"); this.Settings.ImportDinoLevels(dialogValue); break; case ServerSettingsCustomLevelsAction.UpdateDinoXPCap: errorTitle = GlobalizedApplication.Instance.GetResourceString("ServerSettings_CustomLevel_UpdateErrorTitle"); this.Settings.UpdateOverrideMaxExperiencePointsDino(); break; case ServerSettingsCustomLevelsAction.ExportPlayerLevels: errorTitle = GlobalizedApplication.Instance.GetResourceString("ServerSettings_CustomLevel_ExportErrorTitle"); this.Settings.ExportPlayerLevels(dialogValue); break; case ServerSettingsCustomLevelsAction.ImportPlayerLevels: errorTitle = GlobalizedApplication.Instance.GetResourceString("ServerSettings_CustomLevel_ImportErrorTitle"); this.Settings.ImportPlayerLevels(dialogValue); break; case ServerSettingsCustomLevelsAction.UpdatePlayerXPCap: errorTitle = GlobalizedApplication.Instance.GetResourceString("ServerSettings_CustomLevel_UpdateErrorTitle"); this.Settings.UpdateOverrideMaxExperiencePointsPlayer(); break; } } catch (Exception ex) { MessageBox.Show(ex.Message, errorTitle, MessageBoxButton.OK, MessageBoxImage.Error); } }, canExecute: (action) => true ); } } private void AddDinoLevel_Click(object sender, RoutedEventArgs e) { var level = ((Level)((Button)e.Source).DataContext); this.Settings.DinoLevels.AddNewLevel(level, Config.Default.CustomLevelXPIncrease_Dino); } private void AddPlayerLevel_Click(object sender, RoutedEventArgs e) { var level = ((Level)((Button)e.Source).DataContext); this.Settings.PlayerLevels.AddNewLevel(level, Config.Default.CustomLevelXPIncrease_Player); } private void DinoLevels_Clear(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DinoLevels_ClearLabel"), _globalizer.GetResourceString("ServerSettings_DinoLevels_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; this.Settings.ClearLevelProgression(LevelProgression.Dino); } private void DinoLevels_Recalculate(object sender, RoutedEventArgs e) { this.Settings.DinoLevels.UpdateTotals(); this.CustomDinoLevelsView.Items.Refresh(); } private void DinoLevels_ResetOfficial(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DinoLevels_ResetLabel"), _globalizer.GetResourceString("ServerSettings_DinoLevels_ResetTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; this.Settings.ResetLevelProgressionToOfficial(LevelProgression.Dino); } private void MaxXPPlayer_Reset(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_PlayerMaxXP_ResetLabel"), _globalizer.GetResourceString("ServerSettings_PlayerMaxXP_ResetTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; this.Settings.ResetOverrideMaxExperiencePointsPlayer(); } private void MaxXPDino_Reset(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DinoMaxXP_ResetLabel"), _globalizer.GetResourceString("ServerSettings_DinoMaxXP_ResetTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; this.Settings.ResetOverrideMaxExperiencePointsDino(); } private void PlayerLevels_Clear(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_PlayerLevels_ClearLabel"), _globalizer.GetResourceString("ServerSettings_PlayerLevels_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; this.Settings.ClearLevelProgression(LevelProgression.Player); } private void PlayerLevels_Recalculate(object sender, RoutedEventArgs e) { this.Settings.PlayerLevels.UpdateTotals(); this.CustomPlayerLevelsView.Items.Refresh(); } private void PlayerLevels_ResetOfficial(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_PlayerLevels_ResetLabel"), _globalizer.GetResourceString("ServerSettings_PlayerLevels_ResetTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; this.Settings.ResetLevelProgressionToOfficial(LevelProgression.Player); } private void RemoveDinoLevel_Click(object sender, RoutedEventArgs e) { if (this.Settings.DinoLevels.Count == 1) { MessageBox.Show(_globalizer.GetResourceString("ServerSettings_CustomLevels_LastRemove_ErrorLabel"), _globalizer.GetResourceString("ServerSettings_CustomLevels_LastRemove_ErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Hand); } else { var level = ((Level)((Button)e.Source).DataContext); this.Settings.DinoLevels.RemoveLevel(level); } } private void RemovePlayerLevel_Click(object sender, RoutedEventArgs e) { if (this.Settings.PlayerLevels.Count == 1) { MessageBox.Show(_globalizer.GetResourceString("ServerSettings_CustomLevels_LastRemove_ErrorLabel"), _globalizer.GetResourceString("ServerSettings_CustomLevels_LastRemove_ErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Hand); } else { var level = ((Level)((Button)e.Source).DataContext); this.Settings.PlayerLevels.RemoveLevel(level); } } private void EnableLevelProgressions_SourceUpdated(object sender, DataTransferEventArgs e) { if (!Settings.EnableLevelProgressions) { Settings.EnableDinoLevelProgressions = false; } } #endregion #region Server Files private void AddAdminPlayer_Click(object sender, RoutedEventArgs e) { var window = new AddUserWindow(); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; var result = window.ShowDialog(); if (result.HasValue && result.Value) { try { Settings.DestroyServerFilesWatcher(); var steamIdsString = window.Users; var steamIds = steamIdsString.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); var steamUsers = SteamUtils.GetSteamUserDetails(steamIds.ToList()); var steamUserList = PlayerUserList.GetList(steamUsers, steamIds); Settings.ServerFilesAdmins.AddRange(steamUserList); Settings.SaveServerFileAdministrators(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Add Error", MessageBoxButton.OK, MessageBoxImage.Error); } finally { Settings.SetupServerFilesWatcher(); } } } private void AddExclusivePlayer_Click(object sender, RoutedEventArgs e) { var window = new AddUserWindow(); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; var result = window.ShowDialog(); if (result.HasValue && result.Value) { try { Settings.DestroyServerFilesWatcher(); var steamIdsString = window.Users; var steamIds = steamIdsString.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); var steamUsers = SteamUtils.GetSteamUserDetails(steamIds.ToList()); var steamUserList = PlayerUserList.GetList(steamUsers, steamIds); Settings.ServerFilesExclusive.AddRange(steamUserList); Settings.SaveServerFileExclusive(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Add Error", MessageBoxButton.OK, MessageBoxImage.Error); } finally { Settings.SetupServerFilesWatcher(); } } } private void AddWhitelistPlayer_Click(object sender, RoutedEventArgs e) { var window = new AddUserWindow(); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; var result = window.ShowDialog(); if (result.HasValue && result.Value) { try { Settings.DestroyServerFilesWatcher(); var steamIdsString = window.Users; var steamIds = steamIdsString.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); var steamUsers = SteamUtils.GetSteamUserDetails(steamIds.ToList()); var steamUserList = PlayerUserList.GetList(steamUsers, steamIds); Settings.ServerFilesWhitelisted.AddRange(steamUserList); Settings.SaveServerFileWhitelisted(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Add Error", MessageBoxButton.OK, MessageBoxImage.Error); } finally { Settings.SetupServerFilesWatcher(); } } } private void ClearAdminPlayers_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ClearLabel"), _globalizer.GetResourceString("ServerSettings_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; try { Settings.DestroyServerFilesWatcher(); Settings.ServerFilesAdmins.Clear(); Settings.SaveServerFileAdministrators(); } finally { Settings.SetupServerFilesWatcher(); } } private void ClearExclusivePlayers_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ClearLabel"), _globalizer.GetResourceString("ServerSettings_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; try { Settings.DestroyServerFilesWatcher(); Settings.ServerFilesExclusive.Clear(); Settings.SaveServerFileExclusive(); } finally { Settings.SetupServerFilesWatcher(); } } private void ClearWhitelistPlayers_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ClearLabel"), _globalizer.GetResourceString("ServerSettings_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; try { Settings.DestroyServerFilesWatcher(); Settings.ServerFilesWhitelisted.Clear(); Settings.SaveServerFileWhitelisted(); } finally { Settings.SetupServerFilesWatcher(); } } private async void ReloadAdminPlayers_Click(object sender, RoutedEventArgs e) { var cursor = this.Cursor; try { Application.Current.Dispatcher.Invoke(() => this.Cursor = Cursors.Wait); await Task.Delay(500); Settings.LoadServerFileAdministrators(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Refresh Error", MessageBoxButton.OK, MessageBoxImage.Error); } finally { Application.Current.Dispatcher.Invoke(() => this.Cursor = cursor); } } private async void ReloadExclusivePlayers_Click(object sender, RoutedEventArgs e) { var cursor = this.Cursor; try { Application.Current.Dispatcher.Invoke(() => this.Cursor = Cursors.Wait); await Task.Delay(500); Settings.LoadServerFileExclusive(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Refresh Error", MessageBoxButton.OK, MessageBoxImage.Error); } finally { Application.Current.Dispatcher.Invoke(() => this.Cursor = cursor); } } private async void ReloadWhitelistPlayers_Click(object sender, RoutedEventArgs e) { var cursor = this.Cursor; try { Application.Current.Dispatcher.Invoke(() => this.Cursor = Cursors.Wait); await Task.Delay(500); Settings.LoadServerFileWhitelisted(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Refresh Error", MessageBoxButton.OK, MessageBoxImage.Error); } finally { Application.Current.Dispatcher.Invoke(() => this.Cursor = cursor); } } private void RemoveAdminPlayer_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DeleteLabel"), _globalizer.GetResourceString("ServerSettings_DeleteTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; try { Settings.DestroyServerFilesWatcher(); var mod = ((PlayerUserItem)((Button)e.Source).DataContext); Settings.ServerFilesAdmins.Remove(mod.PlayerId); Settings.SaveServerFileAdministrators(); } finally { Settings.SetupServerFilesWatcher(); } } private void RemoveExclusivePlayer_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DeleteLabel"), _globalizer.GetResourceString("ServerSettings_DeleteTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; try { Settings.DestroyServerFilesWatcher(); var mod = ((PlayerUserItem)((Button)e.Source).DataContext); Settings.ServerFilesExclusive.Remove(mod.PlayerId); Settings.SaveServerFileExclusive(); } finally { Settings.SetupServerFilesWatcher(); } } private void RemoveWhitelistPlayer_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DeleteLabel"), _globalizer.GetResourceString("ServerSettings_DeleteTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; try { Settings.DestroyServerFilesWatcher(); var mod = ((PlayerUserItem)((Button)e.Source).DataContext); Settings.ServerFilesWhitelisted.Remove(mod.PlayerId); Settings.SaveServerFileWhitelisted(); } finally { Settings.SetupServerFilesWatcher(); } } #endregion #region PGM Settings private void PastePGMSettings_Click(object sender, RoutedEventArgs e) { var window = new CustomConfigDataWindow(); window.ConfigDataTextWrapping = TextWrapping.Wrap; window.Title = _globalizer.GetResourceString("ServerSettings_PGM_PasteSettingsTitle"); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; var result = window.ShowDialog(); if (!result.HasValue || !result.Value) return; if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_PGM_PasteSettingsConfirmLabel"), _globalizer.GetResourceString("ServerSettings_PGM_PasteSettingsConfirmTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; // read the pasted data into an ini file. var iniFile = IniFileUtils.ReadString(window.ConfigData); var prop = Settings.GetType().GetProperty(nameof(Settings.PGM_Terrain)); if (prop == null) return; var attr = prop.GetCustomAttributes(typeof(IniFileEntryAttribute), false).OfType().FirstOrDefault(); var keyName = string.IsNullOrWhiteSpace(attr?.Key) ? prop.Name : attr.Key; // cycle through the sections, adding them to the engrams list. Will bypass any sections that are named as per the ARK default sections. foreach (var section in iniFile.Sections.Where(s => s.SectionName != null && !SystemIniFile.IniSectionNames.ContainsValue(s.SectionName))) { foreach (var key in section.Keys.Where(s => s.KeyName.Equals(keyName))) { Settings.PGM_Terrain.InitializeFromINIValue(key.KeyValue); } } } private void SavePGMSettings_Click(object sender, RoutedEventArgs e) { var prop = Settings.GetType().GetProperty(nameof(Settings.PGM_Terrain)); if (prop == null) return; var attr = prop.GetCustomAttributes(typeof(IniFileEntryAttribute), false).OfType().FirstOrDefault(); var iniName = string.IsNullOrWhiteSpace(attr?.Key) ? prop.Name : attr.Key; var iniValue = $"{iniName}={Settings.PGM_Terrain.ToINIValue()}"; var window = new CommandLineWindow(iniValue); window.OutputTextWrapping = TextWrapping.Wrap; window.Height = 500; window.Title = _globalizer.GetResourceString("ServerSettings_PGM_SaveSettingsTitle"); window.Owner = Window.GetWindow(this); window.ShowDialog(); } private void RandomPGMSettings_Click(object sender, RoutedEventArgs e) { Settings.RandomizePGMSettings(); } #endregion #region Map Spawner Overrides private void AddNPCSpawn_Click(object sender, RoutedEventArgs e) { Settings.NPCSpawnSettings.Add(new NPCSpawnSettings()); } private void AddNPCSpawnEntry_Click(object sender, RoutedEventArgs e) { if (SelectedNPCSpawnSetting == null) { MessageBox.Show(_globalizer.GetResourceString("ServerSettings_AddChildErrorLabel"), _globalizer.GetResourceString("ServerSettings_AddChildErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error); return; } SelectedNPCSpawnSetting.NPCSpawnEntrySettings.Add(new NPCSpawnEntrySettings()); } private void ClearNPCSpawn_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ClearLabel"), _globalizer.GetResourceString("ServerSettings_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; SelectedNPCSpawnSetting = null; Settings.NPCSpawnSettings.Clear(); } private void ClearNPCSpawnEntry_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ClearLabel"), _globalizer.GetResourceString("ServerSettings_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; SelectedNPCSpawnSetting?.NPCSpawnEntrySettings.Clear(); } private void PasteNPCSpawn_Click(object sender, RoutedEventArgs e) { var window = new CustomConfigDataWindow(); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; var result = window.ShowDialog(); if (!result.HasValue || !result.Value) return; // read the pasted data into an ini file. var iniFile = IniFileUtils.ReadString(window.ConfigData.Replace(" ", "")); Server.Profile.NPCSpawnSettings.RenderToModel(); // cycle through the sections, adding them to the custom section list. Will bypass any sections that are named as per the ARK default sections. foreach (var section in iniFile.Sections.Where(s => s.SectionName != null && !SystemIniFile.IniSectionNames.ContainsValue(s.SectionName))) { var configAddNPCSpawnEntriesContainer = new NPCSpawnContainerList(nameof(Server.Profile.ConfigAddNPCSpawnEntriesContainer), NPCSpawnContainerType.Add); configAddNPCSpawnEntriesContainer.FromIniValues(section.KeysToStringArray().Where(s => s.StartsWith($"{configAddNPCSpawnEntriesContainer.IniCollectionKey}="))); Server.Profile.ConfigAddNPCSpawnEntriesContainer.AddRange(configAddNPCSpawnEntriesContainer); Server.Profile.ConfigAddNPCSpawnEntriesContainer.IsEnabled |= configAddNPCSpawnEntriesContainer.IsEnabled; var configSubtractNPCSpawnEntriesContainer = new NPCSpawnContainerList(nameof(Server.Profile.ConfigSubtractNPCSpawnEntriesContainer), NPCSpawnContainerType.Subtract); configSubtractNPCSpawnEntriesContainer.FromIniValues(section.KeysToStringArray().Where(s => s.StartsWith($"{configSubtractNPCSpawnEntriesContainer.IniCollectionKey}="))); Server.Profile.ConfigSubtractNPCSpawnEntriesContainer.AddRange(configSubtractNPCSpawnEntriesContainer); Server.Profile.ConfigSubtractNPCSpawnEntriesContainer.IsEnabled |= configSubtractNPCSpawnEntriesContainer.IsEnabled; var configOverrideNPCSpawnEntriesContainer = new NPCSpawnContainerList(nameof(Server.Profile.ConfigOverrideNPCSpawnEntriesContainer), NPCSpawnContainerType.Override); configOverrideNPCSpawnEntriesContainer.FromIniValues(section.KeysToStringArray().Where(s => s.StartsWith($"{configOverrideNPCSpawnEntriesContainer.IniCollectionKey}="))); Server.Profile.ConfigOverrideNPCSpawnEntriesContainer.AddRange(configOverrideNPCSpawnEntriesContainer); Server.Profile.ConfigOverrideNPCSpawnEntriesContainer.IsEnabled |= configOverrideNPCSpawnEntriesContainer.IsEnabled; } Server.Profile.NPCSpawnSettings = new NPCSpawnSettingsList(Server.Profile.ConfigAddNPCSpawnEntriesContainer, Server.Profile.ConfigSubtractNPCSpawnEntriesContainer, Server.Profile.ConfigOverrideNPCSpawnEntriesContainer); Server.Profile.NPCSpawnSettings.RenderToView(); RefreshBaseMapSpawnerList(); RefreshBaseDinoList(); } private void RemoveNPCSpawn_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DeleteLabel"), _globalizer.GetResourceString("ServerSettings_DeleteTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; var item = ((NPCSpawnSettings)((Button)e.Source).DataContext); Settings.NPCSpawnSettings.Remove(item); } private void RemoveNPCSpawnEntry_Click(object sender, RoutedEventArgs e) { if (SelectedNPCSpawnSetting == null) return; if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DeleteLabel"), _globalizer.GetResourceString("ServerSettings_DeleteTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; var item = ((NPCSpawnEntrySettings)((Button)e.Source).DataContext); SelectedNPCSpawnSetting.NPCSpawnEntrySettings.Remove(item); } private void SaveNPCSpawns_Click(object sender, RoutedEventArgs e) { Settings.NPCSpawnSettings.RenderToModel(); var iniValues = Settings.ConfigAddNPCSpawnEntriesContainer.ToIniValues().ToList(); iniValues.AddRange(Settings.ConfigSubtractNPCSpawnEntriesContainer.ToIniValues()); iniValues.AddRange(Settings.ConfigOverrideNPCSpawnEntriesContainer.ToIniValues()); var iniValue = string.Join("\r\n", iniValues); var window = new CommandLineWindow(iniValue); window.OutputTextWrapping = TextWrapping.NoWrap; window.Height = 500; window.Title = _globalizer.GetResourceString("ServerSettings_MapSpawnerOverrides_SaveTitle"); window.Owner = Window.GetWindow(this); window.ShowDialog(); } private void SaveNPCSpawn_Click(object sender, RoutedEventArgs e) { Settings.NPCSpawnSettings.RenderToModel(); var item = ((NPCSpawnSettings)((Button)e.Source).DataContext); if (item == null) return; string iniName = null; string iniValue = null; switch (item.ContainerType) { case NPCSpawnContainerType.Add: iniName = Settings.ConfigAddNPCSpawnEntriesContainer.IniCollectionKey; var addItem = Settings.ConfigAddNPCSpawnEntriesContainer.FirstOrDefault(i => i.UniqueId == item.UniqueId); iniValue = $"{iniName}={addItem?.ToIniValue(Settings.ConfigAddNPCSpawnEntriesContainer.ContainerType)}"; break; case NPCSpawnContainerType.Subtract: iniName = Settings.ConfigSubtractNPCSpawnEntriesContainer.IniCollectionKey; var subtractItem = Settings.ConfigSubtractNPCSpawnEntriesContainer.FirstOrDefault(i => i.UniqueId == item.UniqueId); iniValue = $"{iniName}={subtractItem?.ToIniValue(Settings.ConfigSubtractNPCSpawnEntriesContainer.ContainerType)}"; break; case NPCSpawnContainerType.Override: iniName = Settings.ConfigOverrideNPCSpawnEntriesContainer.IniCollectionKey; var overrideItem = Settings.ConfigOverrideNPCSpawnEntriesContainer.FirstOrDefault(i => i.UniqueId == item.UniqueId); iniValue = $"{iniName}={overrideItem?.ToIniValue(Settings.ConfigOverrideNPCSpawnEntriesContainer.ContainerType)}"; break; default: return; } var window = new CommandLineWindow(iniValue); window.OutputTextWrapping = TextWrapping.Wrap; window.Height = 500; window.Title = _globalizer.GetResourceString("ServerSettings_MapSpawnerOverrides_SaveTitle"); window.Owner = Window.GetWindow(this); window.ShowDialog(); } #endregion #region Supply Crate Overrides private void AddSupplyCrate_Click(object sender, RoutedEventArgs e) { Settings.ConfigOverrideSupplyCrateItems.Add(new SupplyCrateOverride()); Settings.ConfigOverrideSupplyCrateItems.IsEnabled = true; } private void AddSupplyCrateItemSet_Click(object sender, RoutedEventArgs e) { if (SelectedSupplyCrateOverride == null) { MessageBox.Show(_globalizer.GetResourceString("ServerSettings_AddChildErrorLabel"), _globalizer.GetResourceString("ServerSettings_AddChildErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error); return; } SelectedSupplyCrateOverride.ItemSets.Add(new SupplyCrateItemSet()); } private void AddSupplyCrateItemSetEntry_Click(object sender, RoutedEventArgs e) { if (SelectedSupplyCrateItemSet == null) { MessageBox.Show(_globalizer.GetResourceString("ServerSettings_AddChildErrorLabel"), _globalizer.GetResourceString("ServerSettings_AddChildErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error); return; } SelectedSupplyCrateItemSet.ItemEntries.Add(new SupplyCrateItemSetEntry()); } private void AddSupplyCrateItem_Click(object sender, RoutedEventArgs e) { if (SelectedSupplyCrateItemSetEntry == null) { MessageBox.Show(_globalizer.GetResourceString("ServerSettings_AddChildErrorLabel"), _globalizer.GetResourceString("ServerSettings_AddChildErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error); return; } SelectedSupplyCrateItemSetEntry.Items.Add(new SupplyCrateItemEntrySettings()); } private void ClearSupplyCrates_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ClearLabel"), _globalizer.GetResourceString("ServerSettings_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; SelectedSupplyCrateItemSetEntry = null; SelectedSupplyCrateItemSet = null; SelectedSupplyCrateOverride = null; Settings.ConfigOverrideSupplyCrateItems.Clear(); Settings.ConfigOverrideSupplyCrateItems.IsEnabled = false; } private void ClearSupplyCrateItemSets_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ClearLabel"), _globalizer.GetResourceString("ServerSettings_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; SelectedSupplyCrateItemSetEntry = null; SelectedSupplyCrateItemSet = null; SelectedSupplyCrateOverride?.ItemSets.Clear(); } private void ClearSupplyCrateItemSetEntries_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ClearLabel"), _globalizer.GetResourceString("ServerSettings_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; SelectedSupplyCrateItemSetEntry = null; SelectedSupplyCrateItemSet?.ItemEntries.Clear(); } private void ClearSupplyCrateItems_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ClearLabel"), _globalizer.GetResourceString("ServerSettings_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; SelectedSupplyCrateItemSetEntry?.Items.Clear(); } private void PasteSupplyCrate_Click(object sender, RoutedEventArgs e) { var window = new CustomConfigDataWindow(); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; var result = window.ShowDialog(); if (!result.HasValue || !result.Value) return; // read the pasted data into an ini file. var iniFile = IniFileUtils.ReadString(window.ConfigData.Replace(" ", "")); Server.Profile.ConfigOverrideSupplyCrateItems.RenderToModel(); // cycle through the sections, adding them to the engrams list. Will bypass any sections that are named as per the ARK default sections. foreach (var section in iniFile.Sections.Where(s => s.SectionName != null && !SystemIniFile.IniSectionNames.ContainsValue(s.SectionName))) { var configOverrideSupplyCrateItems = new SupplyCrateOverrideList(nameof(Server.Profile.ConfigOverrideSupplyCrateItems)); configOverrideSupplyCrateItems.FromIniValues(section.KeysToStringArray().Where(s => s.StartsWith($"{configOverrideSupplyCrateItems.IniCollectionKey}="))); Server.Profile.ConfigOverrideSupplyCrateItems.AddRange(configOverrideSupplyCrateItems); Server.Profile.ConfigOverrideSupplyCrateItems.IsEnabled |= configOverrideSupplyCrateItems.IsEnabled; } var errors = Server.Profile.ConfigOverrideSupplyCrateItems.RenderToView(); RefreshBaseSupplyCrateList(); RefreshBasePrimalItemList(); if (errors.Length > 0) { var error = $"The following errors have been found:\r\n\r\n{string.Join("\r\n", errors)}"; var window2 = new CommandLineWindow(error); window2.OutputTextWrapping = TextWrapping.NoWrap; window2.Height = 500; window2.Title = "Import Errors"; window2.Owner = Window.GetWindow(this); window2.ShowDialog(); } } private void RemoveSupplyCrate_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DeleteLabel"), _globalizer.GetResourceString("ServerSettings_DeleteTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; var item = ((SupplyCrateOverride)((Button)e.Source).DataContext); Settings.ConfigOverrideSupplyCrateItems.Remove(item); Settings.ConfigOverrideSupplyCrateItems.IsEnabled = Settings.ConfigOverrideSupplyCrateItems.Count > 0; } private void RemoveSupplyCrateItemSet_Click(object sender, RoutedEventArgs e) { if (SelectedSupplyCrateOverride == null) return; if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DeleteLabel"), _globalizer.GetResourceString("ServerSettings_DeleteTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; var item = ((SupplyCrateItemSet)((Button)e.Source).DataContext); SelectedSupplyCrateOverride.ItemSets.Remove(item); } private void RemoveSupplyCrateItemSetEntry_Click(object sender, RoutedEventArgs e) { if (SelectedSupplyCrateItemSet == null) return; if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DeleteLabel"), _globalizer.GetResourceString("ServerSettings_DeleteTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; var item = ((SupplyCrateItemSetEntry)((Button)e.Source).DataContext); SelectedSupplyCrateItemSet.ItemEntries.Remove(item); } private void RemoveSupplyCrateItem_Click(object sender, RoutedEventArgs e) { if (SelectedSupplyCrateItemSetEntry == null) return; if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DeleteLabel"), _globalizer.GetResourceString("ServerSettings_DeleteTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; var item = ((SupplyCrateItemEntrySettings)((Button)e.Source).DataContext); SelectedSupplyCrateItemSetEntry.Items.Remove(item); } private void SaveSupplyCrates_Click(object sender, RoutedEventArgs e) { Settings.ConfigOverrideSupplyCrateItems.RenderToModel(); var iniValues = Settings.ConfigOverrideSupplyCrateItems.ToIniValues().ToList(); var iniValue = string.Join("\r\n", iniValues); var window = new CommandLineWindow(iniValue); window.OutputTextWrapping = TextWrapping.NoWrap; window.Height = 500; window.Title = _globalizer.GetResourceString("ServerSettings_SupplyCrate_SaveTitle"); window.Owner = Window.GetWindow(this); window.ShowDialog(); } private void SaveSupplyCrate_Click(object sender, RoutedEventArgs e) { var item = ((SupplyCrateOverride)((Button)e.Source).DataContext); if (item == null) return; Settings.ConfigOverrideSupplyCrateItems.RenderToModel(); var iniName = Settings.ConfigOverrideSupplyCrateItems.IniCollectionKey; var iniValue = $"{iniName}={item.ToINIValue()}"; var window = new CommandLineWindow(iniValue); window.OutputTextWrapping = TextWrapping.Wrap; window.Height = 500; window.Title = _globalizer.GetResourceString("ServerSettings_SupplyCrate_SaveTitle"); window.Owner = Window.GetWindow(this); window.ShowDialog(); } #endregion #region Stack Size Overrides private void AddStackSizeOverride_Click(object sender, RoutedEventArgs e) { Settings.ConfigOverrideItemMaxQuantity.Add(new StackSizeOverride()); Settings.ConfigOverrideItemMaxQuantity.IsEnabled = true; } private void ClearStackSizeOverrides_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ClearLabel"), _globalizer.GetResourceString("ServerSettings_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; Settings.ConfigOverrideItemMaxQuantity.Clear(); Settings.ConfigOverrideItemMaxQuantity.IsEnabled = false; } private void PasteStackSizeOverride_Click(object sender, RoutedEventArgs e) { var window = new CustomConfigDataWindow(); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; var result = window.ShowDialog(); if (!result.HasValue || !result.Value) return; // read the pasted data into an ini file. var iniFile = IniFileUtils.ReadString(window.ConfigData.Replace(" ", "")); Server.Profile.ConfigOverrideItemMaxQuantity.RenderToModel(); // cycle through the sections, adding them to the list. Will bypass any sections that are named as per the ARK default sections. foreach (var section in iniFile.Sections.Where(s => s.SectionName != null && !SystemIniFile.IniSectionNames.ContainsValue(s.SectionName))) { var configOverrideItemMaxQuantity = new AggregateIniValueList(nameof(Server.Profile.ConfigOverrideItemMaxQuantity), null); configOverrideItemMaxQuantity.FromIniValues(section.KeysToStringArray().Where(s => s.StartsWith($"{configOverrideItemMaxQuantity.IniCollectionKey}="))); Server.Profile.ConfigOverrideItemMaxQuantity.AddRange(configOverrideItemMaxQuantity); Server.Profile.ConfigOverrideItemMaxQuantity.IsEnabled |= configOverrideItemMaxQuantity.IsEnabled; } var errors = Server.Profile.ConfigOverrideItemMaxQuantity.RenderToView(); RefreshBasePrimalItemList(); if (errors.Length > 0) { var error = $"The following errors have been found:\r\n\r\n{string.Join("\r\n", errors)}"; var window2 = new CommandLineWindow(error); window2.OutputTextWrapping = TextWrapping.NoWrap; window2.Height = 500; window2.Title = "Import Errors"; window2.Owner = Window.GetWindow(this); window2.ShowDialog(); } } private void RemoveStackSizeOverrideItem_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DeleteLabel"), _globalizer.GetResourceString("ServerSettings_DeleteTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; var item = ((StackSizeOverride)((Button)e.Source).DataContext); Settings.ConfigOverrideItemMaxQuantity.Remove(item); Settings.ConfigOverrideItemMaxQuantity.IsEnabled = Settings.ConfigOverrideItemMaxQuantity.Count > 0; } private void SaveStackSizeOverride_Click(object sender, RoutedEventArgs e) { Settings.ConfigOverrideItemMaxQuantity.RenderToModel(); var iniValues = Settings.ConfigOverrideItemMaxQuantity.ToIniValues().ToList(); var iniValue = string.Join("\r\n", iniValues); var window = new CommandLineWindow(iniValue); window.OutputTextWrapping = TextWrapping.NoWrap; window.Height = 500; window.Title = _globalizer.GetResourceString("ServerSettings_StackSizeOverrides_SaveTitle"); window.Owner = Window.GetWindow(this); window.ShowDialog(); } private void SaveStackSizeOverrideItem_Click(object sender, RoutedEventArgs e) { var item = ((StackSizeOverride)((Button)e.Source).DataContext); if (item == null) return; var iniName = Settings.ConfigOverrideItemMaxQuantity.IniCollectionKey; var iniValue = $"{iniName}={item.ToINIValue()}"; var window = new CommandLineWindow(iniValue); window.OutputTextWrapping = TextWrapping.Wrap; window.Height = 500; window.Title = _globalizer.GetResourceString("ServerSettings_StackSizeOverrides_SaveTitle"); window.Owner = Window.GetWindow(this); window.ShowDialog(); } #endregion #region Prevent Transfer Overrides private void AddPreventTransferOverride_Click(object sender, RoutedEventArgs e) { Settings.PreventTransferForClassNames.Add(new PreventTransferOverride()); Settings.PreventTransferForClassNames.IsEnabled = true; } private void ClearPreventTransferOverrides_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ClearLabel"), _globalizer.GetResourceString("ServerSettings_ClearTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; Settings.PreventTransferForClassNames.Clear(); Settings.PreventTransferForClassNames.IsEnabled = false; } private void PastePreventTransferOverride_Click(object sender, RoutedEventArgs e) { var window = new CustomConfigDataWindow(); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; var result = window.ShowDialog(); if (!result.HasValue || !result.Value) return; // read the pasted data into an ini file. var iniFile = IniFileUtils.ReadString(window.ConfigData.Replace(" ", "")); Server.Profile.PreventTransferForClassNames.RenderToModel(); // cycle through the sections, adding them to the list. Will bypass any sections that are named as per the ARK default sections. foreach (var section in iniFile.Sections.Where(s => s.SectionName != null && !SystemIniFile.IniSectionNames.ContainsValue(s.SectionName))) { var preventTransferForClassNames = new AggregateIniValueList(nameof(Server.Profile.PreventTransferForClassNames), null); preventTransferForClassNames.FromIniValues(section.KeysToStringArray().Where(s => s.StartsWith($"{preventTransferForClassNames.IniCollectionKey}="))); Server.Profile.PreventTransferForClassNames.AddRange(preventTransferForClassNames); Server.Profile.PreventTransferForClassNames.IsEnabled |= preventTransferForClassNames.IsEnabled; } var errors = Server.Profile.PreventTransferForClassNames.RenderToView(); RefreshBaseDinoList(); if (errors.Length > 0) { var error = $"The following errors have been found:\r\n\r\n{string.Join("\r\n", errors)}"; var window2 = new CommandLineWindow(error); window2.OutputTextWrapping = TextWrapping.NoWrap; window2.Height = 500; window2.Title = "Import Errors"; window2.Owner = Window.GetWindow(this); window2.ShowDialog(); } } private void RemovePreventTransferOverrideItem_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_DeleteLabel"), _globalizer.GetResourceString("ServerSettings_DeleteTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; var item = ((PreventTransferOverride)((Button)e.Source).DataContext); Settings.PreventTransferForClassNames.Remove(item); Settings.PreventTransferForClassNames.IsEnabled = Settings.PreventTransferForClassNames.Count > 0; } private void SavePreventTransferOverride_Click(object sender, RoutedEventArgs e) { Settings.PreventTransferForClassNames.RenderToModel(); var iniValues = Settings.PreventTransferForClassNames.ToIniValues().ToList(); var iniValue = string.Join("\r\n", iniValues); var window = new CommandLineWindow(iniValue); window.OutputTextWrapping = TextWrapping.NoWrap; window.Height = 500; window.Title = _globalizer.GetResourceString("ServerSettings_PreventTransferOverrides_SaveTitle"); window.Owner = Window.GetWindow(this); window.ShowDialog(); } private void SavePreventTransferOverrideItem_Click(object sender, RoutedEventArgs e) { var item = ((PreventTransferOverride)((Button)e.Source).DataContext); if (item == null) return; var iniName = Settings.PreventTransferForClassNames.IniCollectionKey; var iniValue = $"{iniName}={item.ToINIValue()}"; var window = new CommandLineWindow(iniValue); window.OutputTextWrapping = TextWrapping.Wrap; window.Height = 500; window.Title = _globalizer.GetResourceString("ServerSettings_PreventTransferOverrides_SaveTitle"); window.Owner = Window.GetWindow(this); window.ShowDialog(); } #endregion #endregion #region Methods public void RefreshBaseDinoModList() { var selectedValue = SelectedModDino; var newList = new ComboBoxItemList(); var value = GameData.MOD_ALL; var name = _globalizer.GetResourceString($"Mod_{value}"); newList.Add(new Common.Model.ComboBoxItem(value, name)); var values = GameData.GetDinoSpawns().GroupBy(d => d.Mod).OrderBy(g => g.Key).Select(g => g.Key).ToList(); foreach (var modValue in values) { if (string.IsNullOrWhiteSpace(modValue)) continue; var modName = _globalizer.GetResourceString($"Mod_{modValue}"); if (string.IsNullOrWhiteSpace(modName)) modName = modValue; newList.Add(new Common.Model.ComboBoxItem(modValue, modName)); } value = GameData.MOD_UNKNOWN; name = _globalizer.GetResourceString($"Mod_{value}"); newList.Add(new Common.Model.ComboBoxItem(value, name)); this.BaseDinoModList = newList; this.ModDinoComboBox.SelectedValue = selectedValue; } public void RefreshBaseEngramModList() { var selectedValue = SelectedModEngram; var newList = new ComboBoxItemList(); var value = GameData.MOD_ALL; var name = _globalizer.GetResourceString($"Mod_{value}"); newList.Add(new Common.Model.ComboBoxItem(value, name)); var values = GameData.GetEngrams().GroupBy(d => d.Mod).OrderBy(g => g.Key).Select(g => g.Key).ToList(); foreach (var modValue in values) { if (string.IsNullOrWhiteSpace(modValue)) continue; var modName = _globalizer.GetResourceString($"Mod_{modValue}"); if (string.IsNullOrWhiteSpace(modName)) modName = modValue; newList.Add(new Common.Model.ComboBoxItem(modValue, modName)); } value = GameData.MOD_UNKNOWN; name = _globalizer.GetResourceString($"Mod_{value}"); newList.Add(new Common.Model.ComboBoxItem(value, name)); this.BaseEngramModList = newList; this.ModEngramComboBox.SelectedValue = selectedValue; } public void RefreshBaseResourceModList() { var selectedValue = SelectedModResource; var newList = new ComboBoxItemList(); var value = GameData.MOD_ALL; var name = _globalizer.GetResourceString($"Mod_{value}"); newList.Add(new Common.Model.ComboBoxItem(value, name)); var values = GameData.GetResourceMultipliers().GroupBy(d => d.Mod).OrderBy(g => g.Key).Select(g => g.Key).ToList(); foreach (var modValue in values) { if (string.IsNullOrWhiteSpace(modValue)) continue; var modName = _globalizer.GetResourceString($"Mod_{modValue}"); if (string.IsNullOrWhiteSpace(modName)) modName = modValue; newList.Add(new Common.Model.ComboBoxItem(modValue, modName)); } value = GameData.MOD_UNKNOWN; name = _globalizer.GetResourceString($"Mod_{value}"); newList.Add(new Common.Model.ComboBoxItem(value, name)); this.BaseResourceModList = newList; this.ModResourceComboBox.SelectedValue = selectedValue; } public void RefreshBaseDinoList() { var newList = new ComboBoxItemList(); foreach (var dino in GameData.GetDinoSpawns()) { if (string.IsNullOrWhiteSpace(dino.ClassName)) continue; newList.Add(new Common.Model.ComboBoxItem { DisplayMember = string.IsNullOrWhiteSpace(dino.Mod) ? $"{dino.DisplayName}" : $"({dino.DisplayMod}) {dino.DisplayName}", ValueMember = dino.ClassName, }); } newList.Sort(i => $"{i.GroupMember}||{i.DisplayMember}"); foreach (var dinoSetting in this.Settings.DinoSettings) { if (string.IsNullOrWhiteSpace(dinoSetting.ReplacementClass)) continue; if (!newList.Any(s => s.ValueMember.Equals(dinoSetting.ReplacementClass, StringComparison.OrdinalIgnoreCase))) { newList.Add(new Common.Model.ComboBoxItem { DisplayMember = dinoSetting.ReplacementClass, ValueMember = dinoSetting.ReplacementClass, }); } } foreach (var spawnSetting in this.Settings.NPCSpawnSettings) { foreach (var spawnEntry in spawnSetting.NPCSpawnEntrySettings) { if (string.IsNullOrWhiteSpace(spawnEntry.NPCClassString)) continue; if (!newList.Any(s => s.ValueMember.Equals(spawnEntry.NPCClassString, StringComparison.OrdinalIgnoreCase))) { newList.Add(new Common.Model.ComboBoxItem { DisplayMember = spawnEntry.NPCClassString, ValueMember = spawnEntry.NPCClassString, }); } } } foreach (var preventTransfer in this.Settings.PreventTransferForClassNames) { if (string.IsNullOrWhiteSpace(preventTransfer.DinoClassString)) continue; if (!newList.Any(s => s.ValueMember.Equals(preventTransfer.DinoClassString, StringComparison.OrdinalIgnoreCase))) { newList.Add(new Common.Model.ComboBoxItem { DisplayMember = preventTransfer.DinoClassString, ValueMember = preventTransfer.DinoClassString, }); } } try { this.DinoSettingsGrid.BeginInit(); this.NPCSpawnEntrySettingsGrid.BeginInit(); this.PreventTransferOverrideGrid.BeginInit(); this.BaseDinoList = newList; } finally { this.DinoSettingsGrid.EndInit(); this.NPCSpawnEntrySettingsGrid.EndInit(); this.PreventTransferOverrideGrid.EndInit(); } } public void RefreshBaseMapSpawnerList() { var newList = new ComboBoxItemList(); foreach (var mapSpawner in GameData.GetMapSpawners()) { newList.Add(new Common.Model.ComboBoxItem { DisplayMember = string.IsNullOrWhiteSpace(mapSpawner.Mod) ? $"{mapSpawner.DisplayName}" : $"({mapSpawner.DisplayMod}) {mapSpawner.DisplayName}", ValueMember = mapSpawner.ClassName, }); } newList.Sort(i => $"{i.GroupMember}||{i.DisplayMember}"); foreach (var spawnSetting in this.Settings.NPCSpawnSettings) { if (string.IsNullOrWhiteSpace(spawnSetting.NPCSpawnEntriesContainerClassString)) continue; if (!newList.Any(s => s.ValueMember.Equals(spawnSetting.NPCSpawnEntriesContainerClassString, StringComparison.OrdinalIgnoreCase))) { newList.Add(new Common.Model.ComboBoxItem { DisplayMember = spawnSetting.NPCSpawnEntriesContainerClassString, ValueMember = spawnSetting.NPCSpawnEntriesContainerClassString, }); } } try { this.NPCSpawnSettingsGrid.BeginInit(); this.BaseMapSpawnerList = newList; } finally { this.NPCSpawnSettingsGrid.EndInit(); } } public void RefreshBasePrimalItemList() { var newList = new ComboBoxItemList(); foreach (var primalItem in GameData.GetItems()) { newList.Add(new Common.Model.ComboBoxItem { DisplayMember = string.IsNullOrWhiteSpace(primalItem.Mod) ? $"{primalItem.DisplayName}" : $"({primalItem.DisplayMod}) {primalItem.DisplayName}", ValueMember = primalItem.ClassName, }); } newList.Sort(i => $"{i.GroupMember}||{i.DisplayMember}"); foreach (var craftingItem in this.Settings.ConfigOverrideItemCraftingCosts) { if (string.IsNullOrWhiteSpace(craftingItem.ItemClassString)) continue; if (!newList.Any(s => s.ValueMember.Equals(craftingItem.ItemClassString, StringComparison.OrdinalIgnoreCase))) { newList.Add(new Common.Model.ComboBoxItem { DisplayMember = craftingItem.ItemClassString, ValueMember = craftingItem.ItemClassString, }); } foreach (var craftingResource in craftingItem.BaseCraftingResourceRequirements) { if (string.IsNullOrWhiteSpace(craftingResource.ResourceItemTypeString)) continue; if (!newList.Any(s => s.ValueMember.Equals(craftingResource.ResourceItemTypeString, StringComparison.OrdinalIgnoreCase))) { newList.Add(new Common.Model.ComboBoxItem { DisplayMember = craftingResource.ResourceItemTypeString, ValueMember = craftingResource.ResourceItemTypeString, }); } } } foreach (var supplyCrate in this.Settings.ConfigOverrideSupplyCrateItems) { foreach (var itemSet in supplyCrate.ItemSets) { foreach (var itemEntry in itemSet.ItemEntries) { foreach (var itemClass in itemEntry.Items) { if (string.IsNullOrWhiteSpace(itemClass.ItemClassString)) continue; if (!newList.Any(s => s.ValueMember.Equals(itemClass.ItemClassString, StringComparison.OrdinalIgnoreCase))) { newList.Add(new Common.Model.ComboBoxItem { DisplayMember = itemClass.ItemClassString, ValueMember = itemClass.ItemClassString, }); } } } } } foreach (var stackSize in this.Settings.ConfigOverrideItemMaxQuantity) { if (string.IsNullOrWhiteSpace(stackSize.ItemClassString)) continue; if (!newList.Any(s => s.ValueMember.Equals(stackSize.ItemClassString, StringComparison.OrdinalIgnoreCase))) { newList.Add(new Common.Model.ComboBoxItem { DisplayMember = stackSize.ItemClassString, ValueMember = stackSize.ItemClassString, }); } } try { this.CraftingOverrideItemGrid.BeginInit(); this.CraftingOverrideResourceGrid.BeginInit(); this.SupplyCrateItemsGrid.BeginInit(); this.StackSizeOverrideGrid.BeginInit(); this.BasePrimalItemList = newList; } finally { this.CraftingOverrideItemGrid.EndInit(); this.CraftingOverrideResourceGrid.EndInit(); this.SupplyCrateItemsGrid.EndInit(); this.StackSizeOverrideGrid.EndInit(); } } public void RefreshBaseSupplyCrateList() { var newList = new ComboBoxItemList(); foreach (var primalItem in GameData.GetSupplyCrates()) { newList.Add(new Common.Model.ComboBoxItem { DisplayMember = string.IsNullOrWhiteSpace(primalItem.Mod) ? $"{primalItem.DisplayName}" : $"({primalItem.DisplayMod}) {primalItem.DisplayName}", ValueMember = primalItem.ClassName, }); } newList.Sort(i => $"{i.GroupMember}||{i.DisplayMember}"); foreach (var supplyCrate in this.Settings.ConfigOverrideSupplyCrateItems) { if (!newList.Any(s => s.ValueMember.Equals(supplyCrate.SupplyCrateClassString, StringComparison.OrdinalIgnoreCase))) { if (string.IsNullOrWhiteSpace(supplyCrate.SupplyCrateClassString)) continue; newList.Add(new Common.Model.ComboBoxItem { DisplayMember = supplyCrate.SupplyCrateClassString, ValueMember = supplyCrate.SupplyCrateClassString, }); } } try { this.SupplyCratesGrid.BeginInit(); this.BaseSupplyCrateList = newList; } finally { this.SupplyCratesGrid.EndInit(); } } public void RefreshBaseGameMapsList() { var newList = new ComboBoxItemList(); if (this.Settings.SOTF_Enabled) { foreach (var item in GameData.GetGameMapsSotF()) { item.DisplayMember = GameData.FriendlyMapSotFNameForClass(item.ValueMember); newList.Add(item); } } else { foreach (var item in GameData.GetGameMaps()) { item.DisplayMember = GameData.FriendlyMapNameForClass(item.ValueMember); newList.Add(item); } } if (!string.IsNullOrWhiteSpace(this.Settings.ServerMap)) { if (!newList.Any(m => m.ValueMember.Equals(this.Settings.ServerMap, StringComparison.OrdinalIgnoreCase))) { newList.Add(new Common.Model.ComboBoxItem { DisplayMember = this.Settings.SOTF_Enabled ? GameData.FriendlyMapSotFNameForClass(this.Settings.ServerMap) : GameData.FriendlyMapNameForClass(this.Settings.ServerMap), ValueMember = this.Settings.ServerMap, }); } } this.BaseGameMaps = newList; this.GameMapComboBox.SelectedValue = this.Settings.ServerMap; } public void RefreshBaseTotalConversionsList() { var newList = new ComboBoxItemList(); if (this.Settings.SOTF_Enabled) { foreach (var item in GameData.GetTotalConversionsSotF()) { item.DisplayMember = GameData.FriendlyTotalConversionSotFNameForClass(item.ValueMember); newList.Add(item); } } else { foreach (var item in GameData.GetTotalConversions()) { item.DisplayMember = GameData.FriendlyTotalConversionNameForClass(item.ValueMember); newList.Add(item); } } if (!string.IsNullOrWhiteSpace(this.Settings.TotalConversionModId)) { if (!newList.Any(m => m.ValueMember.Equals(this.Settings.TotalConversionModId, StringComparison.OrdinalIgnoreCase))) { newList.Add(new Common.Model.ComboBoxItem { DisplayMember = this.Settings.SOTF_Enabled ? GameData.FriendlyTotalConversionSotFNameForClass(this.Settings.TotalConversionModId) : GameData.FriendlyTotalConversionNameForClass(this.Settings.TotalConversionModId), ValueMember = this.Settings.TotalConversionModId, }); } } this.BaseTotalConversions = newList; this.TotalConversionComboBox.SelectedValue = this.Settings.TotalConversionModId; } public void RefreshBaseBranchesList() { var newList = new ComboBoxItemList(); if (this.Settings.SOTF_Enabled) { foreach (var item in GameData.GetBranchesSotF()) { item.DisplayMember = GameData.FriendlyBranchSotFName(string.IsNullOrWhiteSpace(item.ValueMember) ? Config.Default.DefaultServerBranchName : item.ValueMember); newList.Add(item); } } else { foreach (var item in GameData.GetBranches()) { item.DisplayMember = GameData.FriendlyBranchName(string.IsNullOrWhiteSpace(item.ValueMember) ? Config.Default.DefaultServerBranchName : item.ValueMember); newList.Add(item); } } if (!string.IsNullOrWhiteSpace(this.Settings.BranchName)) { if (!newList.Any(m => m.ValueMember.Equals(this.Settings.BranchName, StringComparison.OrdinalIgnoreCase))) { newList.Add(new Common.Model.ComboBoxItem { DisplayMember = this.Settings.SOTF_Enabled ? GameData.FriendlyBranchSotFName(this.Settings.BranchName) : GameData.FriendlyBranchName(this.Settings.BranchName), ValueMember = this.Settings.BranchName, }); } } this.BaseBranches = newList; this.BranchComboBox.SelectedValue = this.Settings.BranchName; } public void RefreshBaseEventsList() { var newList = new ComboBoxItemList(); if (this.Settings.SOTF_Enabled) { foreach (var item in GameData.GetEventsSotF()) { item.DisplayMember = GameData.FriendlyEventSotFName(string.IsNullOrWhiteSpace(item.ValueMember) ? string.Empty : item.ValueMember); newList.Add(item); } } else { foreach (var item in GameData.GetEvents()) { item.DisplayMember = GameData.FriendlyEventName(string.IsNullOrWhiteSpace(item.ValueMember) ? string.Empty : item.ValueMember); newList.Add(item); } } if (!string.IsNullOrWhiteSpace(this.Settings.EventName)) { if (!newList.Any(m => m.ValueMember.Equals(this.Settings.EventName, StringComparison.OrdinalIgnoreCase))) { newList.Add(new Common.Model.ComboBoxItem { DisplayMember = this.Settings.SOTF_Enabled ? GameData.FriendlyEventSotFName(this.Settings.EventName) : GameData.FriendlyEventName(this.Settings.EventName), ValueMember = this.Settings.EventName, }); } } this.BaseEvents = newList; this.EventComboBox.SelectedValue = this.Settings.EventName; } public void RefreshProcessPrioritiesList() { var newList = new ComboBoxItemList(); foreach (var priority in ProcessUtils.GetProcessPriorityList()) { newList.Add(new Common.Model.ComboBoxItem(priority, _globalizer.GetResourceString($"Priority_{priority}"))); } var profilePriority = this.Settings.ProcessPriority; this.ProcessPriorities = newList; this.ProcessPriorityComboBox.SelectedValue = profilePriority; } public void RefreshCustomLevelProgressionsInformation() { var information = _globalizer.GetResourceString("ServerSettings_CustomLevelProgressions_InformationLabel"); CustomLevelProgressionsInformation = information.Replace("{levels}", GameData.LevelsPlayerAdditional.ToString()); } private void ReinitializeNetworkAdapters() { var adapters = NetworkUtils.GetAvailableIPV4NetworkAdapters(); // // Filter out self-assigned addresses // adapters.RemoveAll(a => a.IPAddress.StartsWith("169.254.")); adapters.Insert(0, new NetworkAdapterEntry(String.Empty, _globalizer.GetResourceString("ServerSettings_LocalIPGameChooseLabel"))); var savedServerIp = this.Settings.ServerIP; this.NetworkInterfaces = adapters; this.Settings.ServerIP = savedServerIp; if (!String.IsNullOrWhiteSpace(this.Settings.ServerIP)) { if (adapters.FirstOrDefault(a => String.Equals(a.IPAddress, this.Settings.ServerIP, StringComparison.OrdinalIgnoreCase)) == null) { MessageBox.Show( String.Format(_globalizer.GetResourceString("ServerSettings_LocalIP_ErrorLabel"), this.Settings.ServerIP), _globalizer.GetResourceString("ServerSettings_LocalIP_ErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error); } } } public ICommand ResetActionCommand { get { return new RelayCommand( execute: (action) => { if (action != ServerSettingsResetAction.MapNameTotalConversionProperty) { if (MessageBox.Show(_globalizer.GetResourceString("ServerSettings_ResetLabel"), _globalizer.GetResourceString("ServerSettings_ResetTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; } switch (action) { // sections case ServerSettingsResetAction.AdministrationSection: this.Settings.ResetAdministrationSection(); RefreshBaseGameMapsList(); RefreshBaseTotalConversionsList(); RefreshBaseBranchesList(); RefreshBaseEventsList(); RefreshProcessPrioritiesList(); break; case ServerSettingsResetAction.ChatAndNotificationsSection: this.Settings.ResetChatAndNotificationSection(); break; case ServerSettingsResetAction.CraftingOverridesSection: this.Settings.ResetCraftingOverridesSection(); RefreshBasePrimalItemList(); break; case ServerSettingsResetAction.CustomLevelsSection: this.Settings.ResetCustomLevelsSection(); break; case ServerSettingsResetAction.DinoSettingsSection: this.Settings.ResetDinoSettingsSection(); RefreshBaseDinoList(); break; case ServerSettingsResetAction.EngramsSection: this.Settings.ResetEngramsSection(); break; case ServerSettingsResetAction.EnvironmentSection: this.Settings.ResetEnvironmentSection(); break; case ServerSettingsResetAction.HudAndVisualsSection: this.Settings.ResetHUDAndVisualsSection(); break; case ServerSettingsResetAction.MapSpawnerOverridesSection: this.Settings.ResetNPCSpawnOverridesSection(); RefreshBaseMapSpawnerList(); RefreshBaseDinoList(); break; case ServerSettingsResetAction.PGMSection: this.Settings.ResetPGMSection(); break; case ServerSettingsResetAction.PlayerSettingsSection: this.Settings.ResetPlayerSettings(); break; case ServerSettingsResetAction.RulesSection: this.Settings.ResetRulesSection(); break; case ServerSettingsResetAction.SOTFSection: this.Settings.ResetSOTFSection(); break; case ServerSettingsResetAction.StructuresSection: this.Settings.ResetStructuresSection(); break; case ServerSettingsResetAction.SupplyCrateOverridesSection: this.Settings.ResetSupplyCrateOverridesSection(); RefreshBaseSupplyCrateList(); RefreshBasePrimalItemList(); break; case ServerSettingsResetAction.StackSizeOverridesSection: this.Settings.ResetStackSizeOverridesSection(); RefreshBasePrimalItemList(); break; case ServerSettingsResetAction.PreventTransferOverridesSection: this.Settings.ResetPreventTransferOverridesSection(); RefreshBaseDinoList(); break; // Properties case ServerSettingsResetAction.MapNameTotalConversionProperty: // set the map name to the ARK default. var mapName = string.Empty; // check if we are running an official total conversion mod. if (!ModUtils.IsOfficialMod(this.Settings.TotalConversionModId)) { // we need to read the mod file and retreive the map name mapName = ModUtils.GetMapName(this.Settings.InstallDirectory, this.Settings.TotalConversionModId); if (string.IsNullOrWhiteSpace(mapName)) { MessageBox.Show(_globalizer.GetResourceString("ServerSettings_FindTotalConversionMapNameErrorLabel"), _globalizer.GetResourceString("ServerSettings_FindTotalConversionMapNameErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error); break; } } this.Settings.ServerMap = mapName; MessageBox.Show(_globalizer.GetResourceString("ServerSettings_FindTotalConversionMapNameSuccessLabel"), _globalizer.GetResourceString("ServerSettings_FindTotalConversionMapNameSuccessTitle"), MessageBoxButton.OK, MessageBoxImage.Information); break; case ServerSettingsResetAction.BanListProperty: this.Settings.ResetBanlist(); break; case ServerSettingsResetAction.PlayerMaxXpProperty: this.Settings.ResetOverrideMaxExperiencePointsPlayer(); break; case ServerSettingsResetAction.DinoMaxXpProperty: this.Settings.ResetOverrideMaxExperiencePointsDino(); break; case ServerSettingsResetAction.PlayerBaseStatMultipliers: this.Settings.PlayerBaseStatMultipliers.Reset(); break; case ServerSettingsResetAction.PlayerPerLevelStatMultipliers: this.Settings.PerLevelStatsMultiplier_Player.Reset(); break; case ServerSettingsResetAction.DinoWildPerLevelStatMultipliers: this.Settings.PerLevelStatsMultiplier_DinoWild.Reset(); break; case ServerSettingsResetAction.DinoTamedPerLevelStatMultipliers: this.Settings.PerLevelStatsMultiplier_DinoTamed.Reset(); break; case ServerSettingsResetAction.DinoTamedAddPerLevelStatMultipliers: this.Settings.PerLevelStatsMultiplier_DinoTamed_Add.Reset(); break; case ServerSettingsResetAction.DinoTamedAffinityPerLevelStatMultipliers: this.Settings.PerLevelStatsMultiplier_DinoTamed_Affinity.Reset(); break; case ServerSettingsResetAction.ItemStatClamps: break; case ServerSettingsResetAction.RCONWindowExtents: this.Settings.ResetRCONWindowExtents(); break; case ServerSettingsResetAction.ServerOptions: this.Settings.ResetServerOptions(); break; case ServerSettingsResetAction.ServerLogOptions: this.Settings.ResetServerLogOptions(); break; } }, canExecute: (action) => true ); } } public ICommand SaveCommand { get { return new RelayCommand( execute: async (parameter) => { try { dockPanel.IsEnabled = false; OverlayMessage.Content = _globalizer.GetResourceString("ServerSettings_OverlayMessage_SavingLabel"); OverlayGrid.Visibility = Visibility.Visible; await Task.Delay(100); // NOTE: This parameter is of type object and must be cast in most cases before use. var server = parameter as Server; if (server != null) { if (server.Profile.EnableAutoShutdown1 || server.Profile.EnableAutoShutdown2) { if (server.Profile.SOTF_Enabled) { MessageBox.Show(_globalizer.GetResourceString("ServerSettings_Save_AutoRestart_SotF_ErrorLabel"), _globalizer.GetResourceString("ServerSettings_Save_AutoRestart_SotF_ErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Warning); server.Profile.EnableAutoShutdown1 = false; server.Profile.RestartAfterShutdown1 = true; server.Profile.EnableAutoShutdown2 = false; server.Profile.RestartAfterShutdown2 = true; server.Profile.AutoRestartIfShutdown = false; } } if (server.Profile.EnableAutoUpdate) { if (server.Profile.SOTF_Enabled) { MessageBox.Show(_globalizer.GetResourceString("ServerSettings_Save_AutoUpdate_SotF_ErrorLabel"), _globalizer.GetResourceString("ServerSettings_Save_AutoUpdate_SotF_ErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Warning); server.Profile.EnableAutoUpdate = false; server.Profile.AutoRestartIfShutdown = false; } } server.Profile.Save(false, false, (p, m, n) => { OverlayMessage.Content = m; }); RefreshBaseDinoList(); RefreshBaseMapSpawnerList(); RefreshBasePrimalItemList(); RefreshBaseSupplyCrateList(); RefreshBaseGameMapsList(); RefreshBaseTotalConversionsList(); RefreshBaseBranchesList(); RefreshBaseEventsList(); RefreshProcessPrioritiesList(); if (Config.Default.UpdateDirectoryPermissions) { OverlayMessage.Content = _globalizer.GetResourceString("ServerSettings_OverlayMessage_PermissionsLabel"); await Task.Delay(100); server.Profile.UpdateDirectoryPermissions(); } OverlayMessage.Content = _globalizer.GetResourceString("ServerSettings_OverlayMessage_SchedulesLabel"); await Task.Delay(100); if (!server.Profile.UpdateSchedules()) { MessageBox.Show(_globalizer.GetResourceString("ServerSettings_Save_UpdateSchedule_ErrorLabel"), _globalizer.GetResourceString("ServerSettings_Save_UpdateSchedule_ErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error); } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Save Error", MessageBoxButton.OK, MessageBoxImage.Error); } finally { OverlayGrid.Visibility = Visibility.Collapsed; dockPanel.IsEnabled = true; } }, canExecute: (parameter) => { return (parameter as Server) != null; } ); } } private async Task UpdateServer(bool establishLock, bool updateServer, bool updateMods, bool closeProgressWindow) { if (_upgradeCancellationSource != null) return false; ProgressWindow window = null; Mutex mutex = null; bool createdNew = !establishLock; try { if (establishLock) { // try to establish a mutex for the profile. mutex = new Mutex(true, ServerApp.GetMutexName(this.Server.Profile.InstallDirectory), out createdNew); } // check if the mutex was established if (createdNew) { this._upgradeCancellationSource = new CancellationTokenSource(); window = new ProgressWindow(string.Format(_globalizer.GetResourceString("Progress_UpgradeServer_WindowTitle"), this.Server.Profile.ProfileName)); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; window.Show(); await Task.Delay(1000); var branch = new ServerBranchSnapshot() { BranchName = this.Server.Profile.BranchName, BranchPassword = this.Server.Profile.BranchPassword }; return await this.Server.UpgradeAsync(_upgradeCancellationSource.Token, updateServer, branch, true, updateMods, (p, m, n) => { TaskUtils.RunOnUIThreadAsync(() => { window?.AddMessage(m, n); }).DoNotWait(); }); } else { // display an error message and exit MessageBox.Show(_globalizer.GetResourceString("ServerSettings_UpgradeServer_MutexFailedLabel"), _globalizer.GetResourceString("ServerSettings_UpgradeServer_FailedTitle"), MessageBoxButton.OK, MessageBoxImage.Information); return false; } } catch (Exception ex) { if (window != null) { window.AddMessage(ex.Message); window.AddMessage(ex.StackTrace); } MessageBox.Show(ex.Message, _globalizer.GetResourceString("ServerSettings_UpgradeServer_FailedTitle"), MessageBoxButton.OK, MessageBoxImage.Error); return false; } finally { this._upgradeCancellationSource = null; if (window != null) { window.CloseWindow(); if (closeProgressWindow) window.Close(); } if (mutex != null) { if (createdNew) { mutex.ReleaseMutex(); mutex.Dispose(); } mutex = null; } } } public void UpdateLastStartedDetails(bool updateProfile) { if (updateProfile) { // update the profile's last started time this.Settings.LastStarted = DateTime.Now; this.Settings.SaveProfile(); } var date = Settings == null || Settings.LastStarted == DateTime.MinValue ? string.Empty : $"{Settings.LastStarted:G}"; this.ProfileLastStarted = $"{_globalizer.GetResourceString("ServerSettings_LastStartedLabel")} {date}"; } #endregion private void OpenSupplyCrateOverridesWindow_Click(object sender, RoutedEventArgs e) { var window = new SupplyCrateOverridesWindow(this.Server.Profile); window.Owner = Window.GetWindow(this); window.Closed += Window_Closed; //window.SavePerformed += SupplyCrateOverridesWindow_SavePerformed; window.Show(); window.Focus(); } } }