diff --git a/.github/workflows/msbuild.yml b/.github/workflows/msbuild.yml
new file mode 100644
index 00000000..4711f49d
--- /dev/null
+++ b/.github/workflows/msbuild.yml
@@ -0,0 +1,38 @@
+name: Build Server Managers
+
+on:
+ push:
+ paths:
+ - 'src/**'
+ - '.github/workflows/msbuild.yml'
+ workflow_dispatch:
+
+env:
+ # Path to the solution file relative to the root of the project.
+ SOLUTION_FILE_PATH: ./src
+
+ # Configuration type to build.
+ # You can convert this to a build matrix if you need coverage of multiple configuration types.
+ # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
+ BUILD_CONFIGURATION: Release
+
+jobs:
+ build:
+ runs-on: windows-latest
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Add MSBuild to PATH
+ uses: microsoft/setup-msbuild@v1.0.2
+
+ - name: Restore NuGet packages
+ working-directory: ${{env.GITHUB_WORKSPACE}}
+ run: nuget restore ${{env.SOLUTION_FILE_PATH}}
+
+ - name: Build
+ working-directory: ${{env.GITHUB_WORKSPACE}}
+ # Add additional options to the MSBuild command line here (like platform or verbosity level).
+ # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference
+ run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}}
+
diff --git a/.github/workflows/webapi.yml b/.github/workflows/webapi.yml
new file mode 100644
index 00000000..65f87da9
--- /dev/null
+++ b/.github/workflows/webapi.yml
@@ -0,0 +1,59 @@
+# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
+# More GitHub Actions for Azure: https://github.com/Azure/actions
+
+name: Build and Deploy ASP.Net Core app to Azure Web app
+
+on:
+ push:
+ paths:
+ - 'src/ServerManager.WebApplication/**'
+ - '.github/workflows/webapi.yml'
+ workflow_dispatch:
+
+jobs:
+ build:
+ runs-on: windows-latest
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Set up .NET Core
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '5.0.x'
+ include-prerelease: true
+
+ - name: Build with dotnet
+ run: dotnet build ./src/ServerManager.WebApplication/ServerManager.WebApplication.csproj --configuration Release
+
+ - name: dotnet publish
+ run: dotnet publish ./src/ServerManager.WebApplication/ServerManager.WebApplication.csproj -c Release -o ${{env.DOTNET_ROOT}}/webapi
+
+ - name: Upload artifact for deployment job
+ uses: actions/upload-artifact@v2
+ with:
+ name: .net-app
+ path: ${{env.DOTNET_ROOT}}/webapi
+
+ deploy:
+ if: contains(github.ref, 'master')
+ runs-on: windows-latest
+ needs: build
+ environment:
+ name: 'Production'
+ url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
+
+ steps:
+ - name: Download artifact from build job
+ uses: actions/download-artifact@v2
+ with:
+ name: .net-app
+
+ - name: Deploy to Azure Web App
+ id: deploy-to-webapp
+ uses: azure/webapps-deploy@v2
+ with:
+ app-name: 'servermanagers'
+ slot-name: 'Production'
+ publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_79D9F7C17C684A9F9789102CFD05755B }}
+ package: .
diff --git a/ASM/ArkServerManager_1.1.400.exe b/ASM/ArkServerManager_1.1.400.exe
new file mode 100644
index 00000000..8db2e177
Binary files /dev/null and b/ASM/ArkServerManager_1.1.400.exe differ
diff --git a/ASM/ArkServerManager_1.1.400.zip b/ASM/ArkServerManager_1.1.400.zip
new file mode 100644
index 00000000..a0de62eb
Binary files /dev/null and b/ASM/ArkServerManager_1.1.400.zip differ
diff --git a/ASM/ArkServerManager_1.1.401.exe b/ASM/ArkServerManager_1.1.401.exe
new file mode 100644
index 00000000..f1628329
Binary files /dev/null and b/ASM/ArkServerManager_1.1.401.exe differ
diff --git a/ASM/ArkServerManager_1.1.401.zip b/ASM/ArkServerManager_1.1.401.zip
new file mode 100644
index 00000000..62bb5952
Binary files /dev/null and b/ASM/ArkServerManager_1.1.401.zip differ
diff --git a/ASM/ArkServerManager_1.1.402.exe b/ASM/ArkServerManager_1.1.402.exe
new file mode 100644
index 00000000..4901a548
Binary files /dev/null and b/ASM/ArkServerManager_1.1.402.exe differ
diff --git a/ASM/ArkServerManager_1.1.402.zip b/ASM/ArkServerManager_1.1.402.zip
new file mode 100644
index 00000000..6f26e93c
Binary files /dev/null and b/ASM/ArkServerManager_1.1.402.zip differ
diff --git a/ASM/ArkServerManager_1.1.403.exe b/ASM/ArkServerManager_1.1.403.exe
new file mode 100644
index 00000000..503538da
Binary files /dev/null and b/ASM/ArkServerManager_1.1.403.exe differ
diff --git a/ASM/ArkServerManager_1.1.403.zip b/ASM/ArkServerManager_1.1.403.zip
new file mode 100644
index 00000000..f957937b
Binary files /dev/null and b/ASM/ArkServerManager_1.1.403.zip differ
diff --git a/ASM/ArkServerManager_1.1.404.exe b/ASM/ArkServerManager_1.1.404.exe
new file mode 100644
index 00000000..31264663
Binary files /dev/null and b/ASM/ArkServerManager_1.1.404.exe differ
diff --git a/ASM/ArkServerManager_1.1.404.zip b/ASM/ArkServerManager_1.1.404.zip
new file mode 100644
index 00000000..7279899c
Binary files /dev/null and b/ASM/ArkServerManager_1.1.404.zip differ
diff --git a/ASM/ArkServerManager_1.1.405.exe b/ASM/ArkServerManager_1.1.405.exe
new file mode 100644
index 00000000..604550e7
Binary files /dev/null and b/ASM/ArkServerManager_1.1.405.exe differ
diff --git a/ASM/ArkServerManager_1.1.405.zip b/ASM/ArkServerManager_1.1.405.zip
new file mode 100644
index 00000000..cf3472ba
Binary files /dev/null and b/ASM/ArkServerManager_1.1.405.zip differ
diff --git a/ASM/ArkServerManager_1.1.406.exe b/ASM/ArkServerManager_1.1.406.exe
new file mode 100644
index 00000000..52ce2639
Binary files /dev/null and b/ASM/ArkServerManager_1.1.406.exe differ
diff --git a/ASM/ArkServerManager_1.1.406.zip b/ASM/ArkServerManager_1.1.406.zip
new file mode 100644
index 00000000..c1aed533
Binary files /dev/null and b/ASM/ArkServerManager_1.1.406.zip differ
diff --git a/ASM/ArkServerManager_1.1.407.exe b/ASM/ArkServerManager_1.1.407.exe
new file mode 100644
index 00000000..c8a75b14
Binary files /dev/null and b/ASM/ArkServerManager_1.1.407.exe differ
diff --git a/ASM/ArkServerManager_1.1.407.zip b/ASM/ArkServerManager_1.1.407.zip
new file mode 100644
index 00000000..bfc9f985
Binary files /dev/null and b/ASM/ArkServerManager_1.1.407.zip differ
diff --git a/ASM/ArkServerManager_1.1.408.exe b/ASM/ArkServerManager_1.1.408.exe
new file mode 100644
index 00000000..cdb3a565
Binary files /dev/null and b/ASM/ArkServerManager_1.1.408.exe differ
diff --git a/ASM/ArkServerManager_1.1.408.zip b/ASM/ArkServerManager_1.1.408.zip
new file mode 100644
index 00000000..30dbd6a3
Binary files /dev/null and b/ASM/ArkServerManager_1.1.408.zip differ
diff --git a/ASM/ArkServerManager_1.1.409.exe b/ASM/ArkServerManager_1.1.409.exe
new file mode 100644
index 00000000..f9aff528
Binary files /dev/null and b/ASM/ArkServerManager_1.1.409.exe differ
diff --git a/ASM/ArkServerManager_1.1.409.zip b/ASM/ArkServerManager_1.1.409.zip
new file mode 100644
index 00000000..157801e6
Binary files /dev/null and b/ASM/ArkServerManager_1.1.409.zip differ
diff --git a/ASM/ArkServerManager_1.1.410.exe b/ASM/ArkServerManager_1.1.410.exe
new file mode 100644
index 00000000..8964a320
Binary files /dev/null and b/ASM/ArkServerManager_1.1.410.exe differ
diff --git a/ASM/ArkServerManager_1.1.410.zip b/ASM/ArkServerManager_1.1.410.zip
new file mode 100644
index 00000000..eb8ad6cc
Binary files /dev/null and b/ASM/ArkServerManager_1.1.410.zip differ
diff --git a/ASM/VersionFeed.xml b/ASM/VersionFeed.xml
index 90820d4a..7a82ae25 100644
--- a/ASM/VersionFeed.xml
+++ b/ASM/VersionFeed.xml
@@ -5,7 +5,294 @@
Ark Server Manager Version Feed
This is the Ark Server Manager release version feed.
- 2021-06-19T03:00:00Z
+ 2021-12-05T00:00:00Z
+
+
+ urn:uuid:BE37B3FD-B498-4B1C-9D4D-754EA0F4A357
+ 1.1.410 (1.1.410.2)
+ 1.1.410.2
+
+ 2021-12-05T00:00:00Z
+
+
+
+ CHANGE
+
+
+ Changed some globalization key values (maps, branches, total conversions and events).
+ Changed the primitive plus gamedata header from Mods to TotalConversions.
+ Changed the way the data directory is selected and created on first startup of the server manager.
+ de-DE Translation file updated.
+ pt-BR Translation file updated.
+ ru-RU Translation file updated.
+ zh-CN Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:0B63D89E-0C36-41DE-96E7-BFB140250C02
+ 1.1.409 (1.1.409.3)
+ 1.1.409.3
+
+ 2021-12-01T00:00:00Z
+
+
+
+ NEW
+
+
+ Added the Profile ID to the top of the profile window.
+
+
CHANGE
+
+
+ Added globalization to the Main Window Start Mode setting in the Global Settings.
+ zh-CN Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:50F06456-861E-483C-82BB-6072A428C652
+ 1.1.408 (1.1.408.1)
+ 1.1.408.1
+
+ 2021-11-24T00:00:00Z
+
+
+
+ BUGFIX
+
+
+ Fixed a crashing bug when ASM closes and is unable to find the backup location to save the config settings.
+
+
NEW
+
+
+ Global Settings - added option to set the Main Window start mode - Normal, Maximized, Minimized.
+ Main Window - now stores the Left and Top positions of the window, when in Normal mode. Will restore the window position when started. Defaults to 50,50.
+
+
CHANGE
+
+
+ Fixed the steamcmd warning about 'Please use force_install_dir before login!'.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:2FF0893A-1412-4062-BF87-058F14E787FC
+ 1.1.407 (1.1.407.2)
+ 1.1.407.2
+
+ 2021-11-23T00:00:00Z
+
+
+
+ CHANGES
+
+
+ Server Status checks - a few code tweaks to the server status checks.
+ pt-BR Translation file updated.
+ zh-CN Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:CAE2A89D-B098-483C-B4D4-CFFE257C066C
+ 1.1.406 (1.1.406.1)
+ 1.1.406.1
+
+ 2021-11-20T01:00:00Z
+
+
+
+ NEW
+
+
+ Server Settings - Rules Section - added bShowCreativeMode setting.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:79020463-01A7-466D-9B4A-1B14941C9C32
+ 1.1.405 (1.1.405.1)
+ 1.1.405.1
+
+ 2021-11-20T00:00:00Z
+
+
+
+ NEW
+
+
+ Server Settings - Rules Section - added DestroyTamesOverLevelClamp setting.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:FE1BAB29-859F-4939-AC97-304772112929
+ 1.1.404 (1.1.404.1)
+ 1.1.404.1
+
+ 2021-11-14T00:00:00Z
+
+
+
+ BUGFIX
+
+
+ RCON Window - Fixed the tribe name missing from the player list.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:191D15BB-817E-407B-882A-7CF063DD79A0
+ 1.1.403 (1.1.403.1)
+ 1.1.403.1
+
+ 2021-11-11T00:00:00Z
+
+
+
+ NEW
+
+
+ Server Settings - added resizing to all the grids, so the height can be increased/decreased. The height is also remembered, so when you reopen ASM, it will size the grid correctly.
+
+
CHANGES
+
+
+ Server Settings - Supply Crate Section - Added indicator icons to each grid row, for better troubleshooting of possible issues.
+ ru-RU Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:49048180-FB6F-4D54-ACDF-6A79BF7354F8
+ 1.1.402 (1.1.402.1)
+ 1.1.402.1
+
+ 2021-09-01T00:00:00Z
+
+
+
+ CHANGES
+
+
+ ru-RU Translation file updated.
+ zh-CN Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:025F6C3D-F9D1-46A7-A0B5-680291F5B1D7
+ 1.1.401 (1.1.401.1)
+ 1.1.401.1
+
+ 2021-08-22T00:00:00Z
+
+
+
+ CHANGES
+
+
+ Ragnarok and Valguero gamedata files updated.
+ pt-BR Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:58A33D1B-6937-4092-87BE-C5DC4E0EB829
+ 1.1.400 (1.1.400.1)
+ 1.1.400.1
+
+ 2021-08-20T00:00:00Z
+
+
+
+ CHANGES
+
+
+ fr-FR Translation file updated.
+ ru-RU Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
urn:uuid:0A751BBA-54B5-40A6-AB09-C6B2539DAFE7
diff --git a/ASM/beta/VersionFeed.xml b/ASM/beta/VersionFeed.xml
index 4998ec18..b066b3e4 100644
--- a/ASM/beta/VersionFeed.xml
+++ b/ASM/beta/VersionFeed.xml
@@ -5,21 +5,106 @@
Ark Server Manager Version Feed
This is the Ark Server Manager beta version feed.
- 2021-06-19T03:00:00Z
+ 2021-12-12T00:00:00Z
- urn:uuid:C69AFC93-0532-4703-9917-0D4296CBD559
- 1.1.399 (1.1.399.3)
- 1.1.399.3
+ urn:uuid:C02D44F9-E3AA-4CA0-BF2F-110F8C83CC21
+ 1.1.411 (1.1.411.7)
+ 1.1.411.7
- 2021-06-19T03:00:00Z
+ 2021-12-12T00:00:00Z
+
+
+
+ NEW
+
+
+ Added gamedata file for the Lost Island DLC - only contains the map name for the Map droplist - do not use until the DLC is officially released!
+ Added Lost Island to the language files for translation.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:F75C6AFF-2A27-49BE-917A-7EAAACCCBF17
+ 1.1.411 (1.1.411.6)
+ 1.1.411.6
+
+ 2021-12-12T00:00:00Z
+
+
+
+ CHANGE
+
+
+ fr-FR Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:0BCB8BBA-330F-4063-8B7E-5B144589999A
+ 1.1.411 (1.1.411.5)
+ 1.1.411.5
+
+ 2021-12-10T00:00:00Z
+
+
+
+ CHANGE
+
+
+ Server Monitor window now stores it's location.
+ Reference library updates.
+ pt-BR Translation file updated.
+ ru-RU Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:7697EBD7-DEF6-422B-B9A6-D4B77F31D572
+ 1.1.411 (1.1.411.4)
+ 1.1.411.4
+
+ 2021-12-09T00:00:00Z
BUGFIX
- Server Settings - Prevent Transfer Section - Added valid check to prevent writing record if dino not selected.
+ Fixed a minor issue when clicking the data directory reset button - fringe case that I found during testing.
+
+
NEW
+
+
+ Server Settings - Dino Section - Added MutagenLevelBoost and MutagenLevelBoostBred settings.
+
+
CHANGE
+
+
+ pt-BR Translation file updated.
+ ru-RU Translation file updated.
+ zh-CN Translation file updated.
@@ -31,18 +116,18 @@
- urn:uuid:D9B9BAD5-5CAE-4A94-9229-516E8335ED34
- 1.1.399 (1.1.399.2)
- 1.1.399.2
+ urn:uuid:8290F43D-98F4-4F4D-8DD8-0A3EF5A45656
+ 1.1.411 (1.1.411.3)
+ 1.1.411.3
- 2021-06-19T01:00:00Z
+ 2021-12-08T00:00:00Z
- NEW
+ BUGFIX
- Server Settings - Prevent Transfer Section - Added new section to handle the PreventTransferForClassNames settings. This section can be enabled/disables from the global settings, if you want to management these manually.
+ Fixed language translation of Data Directory window.
@@ -54,18 +139,50 @@
- urn:uuid:0A751BBA-54B5-40A6-AB09-C6B2539DAFE7
- 1.1.399 (1.1.399.1)
- 1.1.399.1
+ urn:uuid:ADBF3FE0-017C-4E23-8FE8-EFE75E7C8BA1
+ 1.1.411 (1.1.411.2)
+ 1.1.411.2
- 2021-06-19T00:00:00Z
+ 2021-12-08T00:00:00Z
+
+
+
+ CHANGE
+
+
+ Global Settings - Added reset button to the Data Directory Location.
+ pt-BR Translation file updated.
+ zh-CN Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:DBAFCE91-2235-4B6C-AE9B-5E4EF9FEC8F5
+ 1.1.411 (1.1.411.1)
+ 1.1.411.1
+
+ 2021-12-06T00:00:00Z
NEW
- Server Settings - Rules Section - Added new Genesis: Part 2 settings, bDisableWorldBuffs, bEnableWorldBuffScaling and WorldBuffScalingEfficacy.
+
+ A new Discord Bot has been added to the server manager.
+ This new discord bot will allow you to send Start, Stop, Shutdown, Restart, Backup and Update commands to the server manager from within your discord client.
+ To setup the new discord bot, open the global settings and scroll down to the Discord section.
+
+ NOTE: This is long process to get the discord bot working, and I have created a forum post with detailed instructions how to do it.
+
+
diff --git a/ASM/beta/en-US.xaml b/ASM/beta/en-US.xaml
index 13fc5a8b..12c4e7fe 100644
--- a/ASM/beta/en-US.xaml
+++ b/ASM/beta/en-US.xaml
@@ -13,7 +13,38 @@
Error
-
+
+ The Island
+ The Center
+ Scorched Earth
+ Ragnarok
+ Aberration
+ Extinction
+ Valguero
+ Genesis: Part 1
+ Crystal Isles
+ Genesis: Part 2
+ Lost Island
+
+
+
+ Primitive Plus
+
+
+
+ Live
+
+
+
+ None
+ Valentines Day
+ Easter
+ Fear Evolved (Halloween)
+ Turkey Trial
+ Winter Wonderland
+
+
+
All
Unknown
ARK Prime
@@ -26,6 +57,7 @@
Genesis: Part 1
Crystal Isles
Genesis: Part 2
+ Lost Island
PGM
@@ -51,6 +83,12 @@
All
+
+ Normal
+ Minimized
+ Maximized
+
+
Run as Administrator
This application requires administration priviledges to access ALL functionality. Would you like to Run as Administrator?
@@ -66,8 +104,9 @@
Select a Data Directory
Confirm location
The server manager will store profiles and SteamCMD in the following directories:\r\n\r\nProfiles: {0}\r\nSteamCMD: {1}\r\n\r\nIs this ok?
- Data Directory Selection Error
- The directory you have chosen is within the server manager installation folder. This is not recommended, please choose another folder.
+ Data Directory Selection Error
+ The directory you have chosen is within the server manager installation folder. This is not recommended, please choose another folder.
+ The directory you have chosen is on the desktop. This is not recommended, please choose another folder.
Failed to save profile
Failed to save profile {0}. {1}\n{2}
@@ -128,6 +167,25 @@
Processor
+
+ Data Folder Selection
+ It appears you do not have a data directory set. The data directory is where your profiles and SteamCMD will be stored. It is not the same as the server installation directory, which you can choose for each profile.
+ Select the drive where the data folder should be located.
+ Data Folder Name:
+ The name of the server manager data folder.
+ Local Disk
+ {0} free of {1}
+
+ Ok
+ Cancel
+ Refresh
+
+ Data Directory Selection Error
+ The data folder name you have entered is not valid.
+ Server Manager Restart Required
+ The data folder has been set, you must now restart the server manager to use the new settings.
+
+
Close
@@ -421,6 +479,7 @@
Reset
This will reset ALL the user global settings for the server manager. The server manager will be closed if successful.
Enable Run as Administrator Prompt on Startup
+ Main Window Start Mode:
Minimize To Tray
Manage firewall settings automatically
Manage Public IP automatically
@@ -553,7 +612,24 @@
This message will be displayed when the server shutdown has been cancelled.
Show shutdown reason with ALL shutdown messages
If enabled, the shutdown reason will be shown with all shutdown message; otherwise it will only be shown at the start of the server shutdown.
-
+
+ Enable Discord Bot
+ You will need to restart the server manager if you change any settings for the Discord Bot.
+ Token:
+ The token associated with the discord bot.
+ Server Id:
+ The id of the discord server the bot will listen to.
+ Prefix:
+ The prefix that must be used when sending a command via discord.
+ Get Token...
+ Help...
+ If enabled, the backup command can be sent from discord.
+ If enabled, the restart command can be sent from discord.
+ If enabled, the shutdown command can be sent from discord.
+ If enabled, the start command can be sent from discord.
+ If enabled, the stop command can be sent from discord.
+ If enabled, the update command can be sent from discord.
+
SMTP Email Settings
Host:
The name or IP address of the host used for SMTP transmissions.
@@ -605,6 +681,8 @@
Changing the data directory will move any existing profiles to the new location, but it will not move any server installations. Do you still want to change this directory?
Failed to change data directory
There was an error changing the data directory: {0}\r\nPlease correct the error and try again, or contact technical support for assistance.
+ Confirm Data Directory Reset
+ Click 'Yes' to confirm you want to reset the location of the data directory. Once reset, the server manager will shutdown and you will need to restart.
Select Backup Directory
Select Cache Directory
@@ -718,6 +796,9 @@
Reinstall SteamCMD Error
An error occured while trying to reinstall SteamCMD. This has left SteamCmd in an unstable state, try reinstalling again or please report this.\r\nException: {0}
+ Discord Bot Running Commands
+ The discord bot has one or more running commands, do you want to continue shutting down the server manager?
+
Start Server Confirmation
You are about to start the server, do you want to continue?
Shutdown Server Confirmation
@@ -756,6 +837,8 @@
+ Profile ID:
+ The unique ID assigned to the profile.
Profile:
The name for the server profile. This is not the public name users will see in Ark. For that, set the 'Server Name' field.
Installed Version:
@@ -1120,12 +1203,32 @@
If enabled, the server will be restarted even if shutdown for Auto-Restarts and Auto-Updates.
+
+ Discord Bot Details
+ Channel Id:
+ The id of the discord server channel this profile will listen to.
+ Allow Backup
+ If enabled, the profile will listen for backup commands from discord.
+ Allow Restart
+ If enabled, the profile will listen for restart commands from discord.
+ Allow Shutdown
+ If enabled, the profile will listen for shutdown commands from discord.
+ Allow Start
+ If enabled, the profile will listen for start commands from discord.
+ Allow Stop
+ If enabled, the profile will listen for stop commands from discord.
+ Allow Update
+ If enabled, the profile will listen for update commands from discord.
+
+
Rules
Enable Hardcore Mode
Enables hardcore mode (players can not respawn, a new character must be created).
Enable PvP
Enables Player vs Player mode (players are able to deal damage to or kill each other. In PvP players can also damage or destroy another tribe's buildings or kill their dinos).
+ Enable Creative Mode
+ If enabled, allows creative mode.
Enable PvE Cave Building
If enabled, allows building in caves when PvE mode is enabled.
Enable PvE Cryo Sickness
@@ -1161,7 +1264,9 @@
Determines the maximum levels of creatures in the world. The higher the value, the higher the Maximum Creature Level.
Difficulty Offset:
Determines the maximum levels of creatures in the world. The higher the value, the higher the Maximum Creature Level.
-
+ Destroy Tames Over Level:
+ Tames that exceed this level will be deleted on server start. To disable deletion set to 0.
+
Enable Tribute Downloads
If enabled, this will allow downloading external survivors/items/dinos into your server.
No Survivor Downloads
@@ -1535,14 +1640,18 @@
Per-Level Stat Multipliers (Tamed) - Add
Per-Level Stat Multipliers (Tamed) - Affinity
Per-Level Stat Multipliers (Wild)
+ Mutagen Level Boost (Wild)
+ Mutagen Level Boost (Bred)
Dino Breeding Multipliers
If enabled, allows scale factors to be applied to each base stat.
If enabled, allows scale factors to be applied to each stat.
If enabled, allows scale factors to be applied to the Taming Addition for each stat.
If enabled, allows scale factors to be applied to the Taming Multiplier for each stat.
If enabled, allows scale factors to be applied to the Tamed Stat Increase for each stat.
- Reset all multipliers back to defaults.
- Reset all multipliers back to defaults.
+ If enabled, allows scale factors to be applied to the Number of levels Mutagen adds to tames with wild ancestry.
+ If enabled, allows scale factors to be applied to the Number of levels Mutagen adds to tames with bred ancestry.
+ Reset all values back to defaults.
+ Reset all values back to defaults.
Mating Interval:
Specifies the multiplier for time between tamed dino mating. Lower values decrease the time between mating.
@@ -1663,8 +1772,8 @@
If enabled, structures in PvP will automatically decay if left unused after a period of time.
PvP Zone Structure Damage:
Specifies the scaling factor for the damage structures take within caves/cave entrances, in PvP.
- Max Structures Visible:
- The maximum number of structures which will be visible to the player. Lower values may help with server speed.
+ Max Structures in Range:
+ Specifies the maximum number of structures that can be constructed within a certain (currently hard-coded) range.
Per-Platform Structures Multiplier:
Specifies the scaling factor for the maximum number of structures allowed on a single platform/saddle/raft.
Max Platform Saddle Structures:
@@ -2462,36 +2571,6 @@
Settings
-
- The Island
- The Center
- Scorched Earth
- Ragnarok
- Aberration
- Extinction
- Valguero
- Genesis: Part 1
- Crystal Isles
- Genesis: Part 2
-
-
-
- Primitive Plus
-
-
-
- Live
-
-
-
- None
- Valentines Day
- Easter
- Fear Evolved (Halloween)
- Turkey Trial
- Winter Wonderland
-
-
@@ -3641,7 +3720,7 @@
Astrocetus Tek Saddle
- Tek Shoulder Cannon
+ Tek Claws
Tek Cruise Missile
Tek Grenade Launcher
Tek Hover Skiff
@@ -5490,4 +5569,32 @@
There was a problem while performing the server update. This may leave your server in a incomplete state.\r\n\r\nDo you want to continue with the server start, this could cause problems?
+
+ Discord Bot Error
+ The discord bot requires a valid token so it can log into the discord server\r\nThis can be set in the global settings.
+ The discord bot prefix contains invalid characters. Only letters and numbers are allowed.
+
+ Command '{0}' has not been enabled.
+ Unknown command '{0}'.
+ Another command is currently being processed.
+ Another command '{0}' is currently running against profile '{1}'.
+ Command '{0}' has been disabled for profile '{1}'.
+
+ The '{0}' command requires a profile id.
+ Profile '{0}' was not found or is not associated with the channel.
+ Profile '{0}' is in a state '{1}' that cannot run this command.
+ Profile '{0}' is currently being updated.
+
+ Call to server '{0}' failed.
+ A backup request for server '{0}' has been sent.
+ A restart request for server '{0}' has been sent.
+ A shutdown request for server '{0}' has been sent.
+ A start request for server '{0}' has been sent.
+ A stop request for server '{0}' has been sent.
+ An update request for server '{0}' has been sent.
+
+ Count:
+ Map:
+
+
\ No newline at end of file
diff --git a/ASM/beta/latest.txt b/ASM/beta/latest.txt
index 15128a33..b64b069b 100644
--- a/ASM/beta/latest.txt
+++ b/ASM/beta/latest.txt
@@ -1 +1 @@
-1.1.399.3
+1.1.411.7
diff --git a/ASM/beta/latest.zip b/ASM/beta/latest.zip
index 0042d311..ef2570a1 100644
Binary files a/ASM/beta/latest.zip and b/ASM/beta/latest.zip differ
diff --git a/ASM/en-US.xaml b/ASM/en-US.xaml
index 13fc5a8b..2384aae1 100644
--- a/ASM/en-US.xaml
+++ b/ASM/en-US.xaml
@@ -13,7 +13,37 @@
Error
-
+
+ The Island
+ The Center
+ Scorched Earth
+ Ragnarok
+ Aberration
+ Extinction
+ Valguero
+ Genesis: Part 1
+ Crystal Isles
+ Genesis: Part 2
+
+
+
+ Primitive Plus
+
+
+
+ Live
+
+
+
+ None
+ Valentines Day
+ Easter
+ Fear Evolved (Halloween)
+ Turkey Trial
+ Winter Wonderland
+
+
+
All
Unknown
ARK Prime
@@ -51,6 +81,12 @@
All
+
+ Normal
+ Minimized
+ Maximized
+
+
Run as Administrator
This application requires administration priviledges to access ALL functionality. Would you like to Run as Administrator?
@@ -66,8 +102,9 @@
Select a Data Directory
Confirm location
The server manager will store profiles and SteamCMD in the following directories:\r\n\r\nProfiles: {0}\r\nSteamCMD: {1}\r\n\r\nIs this ok?
- Data Directory Selection Error
- The directory you have chosen is within the server manager installation folder. This is not recommended, please choose another folder.
+ Data Directory Selection Error
+ The directory you have chosen is within the server manager installation folder. This is not recommended, please choose another folder.
+ The directory you have chosen is on the desktop. This is not recommended, please choose another folder.
Failed to save profile
Failed to save profile {0}. {1}\n{2}
@@ -128,6 +165,25 @@
Processor
+
+ Data Folder Selection
+ It appears you do not have a data directory set. The data directory is where your profiles and SteamCMD will be stored. It is not the same as the server installation directory, which you can choose for each profile.
+ Select the drive where the data folder should be located.
+ Data Folder Name:
+ The name of the server manager data folder.
+ Local Disk
+ {0} free of {1}
+
+ Ok
+ Cancel
+ Refresh
+
+ Data Directory Selection Error
+ The data folder name you have entered is not valid.
+ Server Manager Restart Required
+ The data folder has been set, you must now restart the server manager to use the new settings.
+
+
Close
@@ -421,6 +477,7 @@
Reset
This will reset ALL the user global settings for the server manager. The server manager will be closed if successful.
Enable Run as Administrator Prompt on Startup
+ Main Window Start Mode:
Minimize To Tray
Manage firewall settings automatically
Manage Public IP automatically
@@ -756,6 +813,8 @@
+ Profile ID:
+ The unique ID assigned to the profile.
Profile:
The name for the server profile. This is not the public name users will see in Ark. For that, set the 'Server Name' field.
Installed Version:
@@ -1126,6 +1185,8 @@
Enables hardcore mode (players can not respawn, a new character must be created).
Enable PvP
Enables Player vs Player mode (players are able to deal damage to or kill each other. In PvP players can also damage or destroy another tribe's buildings or kill their dinos).
+ Enable Creative Mode
+ If enabled, allows creative mode.
Enable PvE Cave Building
If enabled, allows building in caves when PvE mode is enabled.
Enable PvE Cryo Sickness
@@ -1161,7 +1222,9 @@
Determines the maximum levels of creatures in the world. The higher the value, the higher the Maximum Creature Level.
Difficulty Offset:
Determines the maximum levels of creatures in the world. The higher the value, the higher the Maximum Creature Level.
-
+ Destroy Tames Over Level:
+ Tames that exceed this level will be deleted on server start. To disable deletion set to 0.
+
Enable Tribute Downloads
If enabled, this will allow downloading external survivors/items/dinos into your server.
No Survivor Downloads
@@ -1663,8 +1726,8 @@
If enabled, structures in PvP will automatically decay if left unused after a period of time.
PvP Zone Structure Damage:
Specifies the scaling factor for the damage structures take within caves/cave entrances, in PvP.
- Max Structures Visible:
- The maximum number of structures which will be visible to the player. Lower values may help with server speed.
+ Max Structures in Range:
+ Specifies the maximum number of structures that can be constructed within a certain (currently hard-coded) range.
Per-Platform Structures Multiplier:
Specifies the scaling factor for the maximum number of structures allowed on a single platform/saddle/raft.
Max Platform Saddle Structures:
@@ -2462,36 +2525,6 @@
Settings
-
- The Island
- The Center
- Scorched Earth
- Ragnarok
- Aberration
- Extinction
- Valguero
- Genesis: Part 1
- Crystal Isles
- Genesis: Part 2
-
-
-
- Primitive Plus
-
-
-
- Live
-
-
-
- None
- Valentines Day
- Easter
- Fear Evolved (Halloween)
- Turkey Trial
- Winter Wonderland
-
-
@@ -3641,7 +3674,7 @@
Astrocetus Tek Saddle
- Tek Shoulder Cannon
+ Tek Claws
Tek Cruise Missile
Tek Grenade Launcher
Tek Hover Skiff
diff --git a/ASM/images/ASM.png b/ASM/images/ASM.png
new file mode 100644
index 00000000..76e22cf3
Binary files /dev/null and b/ASM/images/ASM.png differ
diff --git a/ASM/images/Bot01.png b/ASM/images/Bot01.png
new file mode 100644
index 00000000..a854a047
Binary files /dev/null and b/ASM/images/Bot01.png differ
diff --git a/ASM/images/Bot02.png b/ASM/images/Bot02.png
new file mode 100644
index 00000000..a80732ff
Binary files /dev/null and b/ASM/images/Bot02.png differ
diff --git a/ASM/images/Bot03.png b/ASM/images/Bot03.png
new file mode 100644
index 00000000..4cbdd5bb
Binary files /dev/null and b/ASM/images/Bot03.png differ
diff --git a/ASM/images/Bot04.png b/ASM/images/Bot04.png
new file mode 100644
index 00000000..558668bb
Binary files /dev/null and b/ASM/images/Bot04.png differ
diff --git a/ASM/images/Bot05.png b/ASM/images/Bot05.png
new file mode 100644
index 00000000..445b4c1e
Binary files /dev/null and b/ASM/images/Bot05.png differ
diff --git a/ASM/images/Bot06.png b/ASM/images/Bot06.png
new file mode 100644
index 00000000..da6dbee1
Binary files /dev/null and b/ASM/images/Bot06.png differ
diff --git a/ASM/images/Bot07.png b/ASM/images/Bot07.png
new file mode 100644
index 00000000..39ee5f17
Binary files /dev/null and b/ASM/images/Bot07.png differ
diff --git a/ASM/images/Bot08.png b/ASM/images/Bot08.png
new file mode 100644
index 00000000..f09fa99a
Binary files /dev/null and b/ASM/images/Bot08.png differ
diff --git a/ASM/images/Bot09.png b/ASM/images/Bot09.png
new file mode 100644
index 00000000..7e544410
Binary files /dev/null and b/ASM/images/Bot09.png differ
diff --git a/ASM/images/Bot10.png b/ASM/images/Bot10.png
new file mode 100644
index 00000000..12d1ef6b
Binary files /dev/null and b/ASM/images/Bot10.png differ
diff --git a/ASM/images/Bot11.png b/ASM/images/Bot11.png
new file mode 100644
index 00000000..23d5f28d
Binary files /dev/null and b/ASM/images/Bot11.png differ
diff --git a/ASM/images/Bot12.png b/ASM/images/Bot12.png
new file mode 100644
index 00000000..f6a5dbcf
Binary files /dev/null and b/ASM/images/Bot12.png differ
diff --git a/ASM/images/Bot13.png b/ASM/images/Bot13.png
new file mode 100644
index 00000000..9f8727af
Binary files /dev/null and b/ASM/images/Bot13.png differ
diff --git a/ASM/images/Bot14.png b/ASM/images/Bot14.png
new file mode 100644
index 00000000..a7666ac1
Binary files /dev/null and b/ASM/images/Bot14.png differ
diff --git a/ASM/images/Bot15.png b/ASM/images/Bot15.png
new file mode 100644
index 00000000..279e1fc4
Binary files /dev/null and b/ASM/images/Bot15.png differ
diff --git a/ASM/images/Bot16.png b/ASM/images/Bot16.png
new file mode 100644
index 00000000..50dfc198
Binary files /dev/null and b/ASM/images/Bot16.png differ
diff --git a/ASM/images/Bot17.png b/ASM/images/Bot17.png
new file mode 100644
index 00000000..0fd90c0a
Binary files /dev/null and b/ASM/images/Bot17.png differ
diff --git a/ASM/images/WebApiKey.png b/ASM/images/WebApiKey.png
new file mode 100644
index 00000000..f522a70f
Binary files /dev/null and b/ASM/images/WebApiKey.png differ
diff --git a/ASM/latest.exe b/ASM/latest.exe
index f2ec6208..8964a320 100644
Binary files a/ASM/latest.exe and b/ASM/latest.exe differ
diff --git a/ASM/latest.txt b/ASM/latest.txt
index 23148d32..73a41c03 100644
--- a/ASM/latest.txt
+++ b/ASM/latest.txt
@@ -1 +1 @@
-1.1.399
+1.1.410
diff --git a/ASM/latest.zip b/ASM/latest.zip
index 0042d311..eb8ad6cc 100644
Binary files a/ASM/latest.zip and b/ASM/latest.zip differ
diff --git a/CSM/ConanServerManager_1.1.51.exe b/CSM/ConanServerManager_1.1.51.exe
new file mode 100644
index 00000000..87c20af8
Binary files /dev/null and b/CSM/ConanServerManager_1.1.51.exe differ
diff --git a/CSM/ConanServerManager_1.1.51.zip b/CSM/ConanServerManager_1.1.51.zip
new file mode 100644
index 00000000..3a5cd8ea
Binary files /dev/null and b/CSM/ConanServerManager_1.1.51.zip differ
diff --git a/CSM/ConanServerManager_1.1.52.exe b/CSM/ConanServerManager_1.1.52.exe
new file mode 100644
index 00000000..e77af100
Binary files /dev/null and b/CSM/ConanServerManager_1.1.52.exe differ
diff --git a/CSM/ConanServerManager_1.1.52.zip b/CSM/ConanServerManager_1.1.52.zip
new file mode 100644
index 00000000..bf6308f8
Binary files /dev/null and b/CSM/ConanServerManager_1.1.52.zip differ
diff --git a/CSM/ConanServerManager_1.1.53.exe b/CSM/ConanServerManager_1.1.53.exe
new file mode 100644
index 00000000..6a4318a6
Binary files /dev/null and b/CSM/ConanServerManager_1.1.53.exe differ
diff --git a/CSM/ConanServerManager_1.1.53.zip b/CSM/ConanServerManager_1.1.53.zip
new file mode 100644
index 00000000..b78f6a21
Binary files /dev/null and b/CSM/ConanServerManager_1.1.53.zip differ
diff --git a/CSM/ConanServerManager_1.1.54.exe b/CSM/ConanServerManager_1.1.54.exe
new file mode 100644
index 00000000..0b299f5a
Binary files /dev/null and b/CSM/ConanServerManager_1.1.54.exe differ
diff --git a/CSM/ConanServerManager_1.1.54.zip b/CSM/ConanServerManager_1.1.54.zip
new file mode 100644
index 00000000..a5faf492
Binary files /dev/null and b/CSM/ConanServerManager_1.1.54.zip differ
diff --git a/CSM/ConanServerManager_1.1.55.exe b/CSM/ConanServerManager_1.1.55.exe
new file mode 100644
index 00000000..33267533
Binary files /dev/null and b/CSM/ConanServerManager_1.1.55.exe differ
diff --git a/CSM/ConanServerManager_1.1.55.zip b/CSM/ConanServerManager_1.1.55.zip
new file mode 100644
index 00000000..cc4e3efc
Binary files /dev/null and b/CSM/ConanServerManager_1.1.55.zip differ
diff --git a/CSM/VersionFeed.xml b/CSM/VersionFeed.xml
index acdbd3d6..6b861df7 100644
--- a/CSM/VersionFeed.xml
+++ b/CSM/VersionFeed.xml
@@ -5,7 +5,140 @@
Conan Server Manager Version Feed
This is the Conan Server Manager release version feed.
- 2020-11-25T00:00:00Z
+ 2021-12-02T00:00:00Z
+
+
+ urn:uuid:A3A790A9-D511-4CE8-AC15-A36B3DAB4385
+ 1.1.55 (1.1.55.2)
+ 1.1.55.2
+
+ 2021-12-05T00:00:00Z
+
+
+
+ CHANGE
+
+
+ Changed some globalization key values (maps and branches).
+ Changed the way the data directory is selected and created on first startup of the server manager.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:38961ED8-0964-4C1A-B09C-8AE2C5FCF76E
+ 1.1.54 (1.1.54.3)
+ 1.1.54.3
+
+ 2021-12-01T00:00:00Z
+
+
+
+ NEW
+
+
+ Added the Profile ID to the top of the profile window.
+
+
CHANGE
+
+
+ Added globalization to the Main Window Start Mode setting in the Global Settings.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:80B2DFDC-E9BE-4B56-A1FE-DD57E64647D1
+ 1.1.53 (1.1.53.1)
+ 1.1.53.1
+
+ 2021-11-24T00:00:00Z
+
+
+
+ BUGFIX
+
+
+ Fixed a crashing bug when CSM closes and is unable to find the backup location to save the config settings.
+
+
NEW
+
+
+ Global Settings - added option to set the Main Window start mode - Normal, Maximized, Minimized.
+ Main Window - now stores the Left and Top positions of the window, when in Normal mode. Will restore the window position when started. Defaults to 50,50.
+ Server Settings - added resizing to all the grids, so the height can be increased/decreased. The height is also remembered, so when you reopen, it will size the grid correctly.
+
+
CHANGE
+
+
+ Fixed the steamcmd warning about 'Please use force_install_dir before login!'.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:285E9972-4FC6-49EA-8FAD-1086F7FC5354
+ 1.1.52 (1.1.52.1)
+ 1.1.52.1
+
+ 2021-11-21T00:00:00Z
+
+
+
+ CHANGE
+
+
+ Server Status checks - a few code tweaks to the server status checks.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:2B49A030-A742-476B-B811-6F0D7780B117
+ 1.1.51 (1.1.51.1)
+ 1.1.51.1
+
+ 2021-08-22T00:00:00Z
+
+
+
+ NEW
+
+
+ Server Settings - Added new server transfer options (server whitelist option in future version).
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
urn:uuid:6914861A-2D4E-4F08-89A3-D3D7A77F74C1
diff --git a/CSM/beta/VersionFeed.xml b/CSM/beta/VersionFeed.xml
index 045b3f9f..9a499dcf 100644
--- a/CSM/beta/VersionFeed.xml
+++ b/CSM/beta/VersionFeed.xml
@@ -5,21 +5,144 @@
Conan Server Manager Version Feed
This is the Conan Server Manager beta version feed.
- 2020-11-25T00:00:00Z
+ 2021-12-12T00:00:00Z
- urn:uuid:6914861A-2D4E-4F08-89A3-D3D7A77F74C1
- 1.1.50 (1.1.50.1)
- 1.1.50.1
+ urn:uuid:4C15C7A9-317C-4A9B-B426-6E885B918D3B
+ 1.1.56 (1.1.56.6)
+ 1.1.56.6
- 2020-11-25T00:00:00Z
+ 2021-12-12T00:00:00Z
+
+
+
+ BUGFIX
+
+
+ Reference library updates.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:126E8E9F-7FF2-4239-88D6-5FFC89925463
+ 1.1.56 (1.1.56.5)
+ 1.1.56.5
+
+ 2021-12-10T00:00:00Z
+
+
+
+ BUGFIX
+
+
+ Server Monitor window now stores it's location.
+ Reference library updates.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:BECA74AB-1107-40B0-932A-A851E978EABF
+ 1.1.56 (1.1.56.4)
+ 1.1.56.4
+
+ 2021-12-09T00:00:00Z
+
+
+
+ BUGFIX
+
+
+ Fixed a minor issue when clicking the data directory reset button - fringe case that I found during testing.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:8C834060-F20F-4ACE-8F49-0B459531BA3C
+ 1.1.56 (1.1.56.3)
+ 1.1.56.3
+
+ 2021-12-08T00:00:00Z
+
+
+
+ BUGFIX
+
+
+ Fixed language translation of Data Directory window.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:339F72FC-920A-4425-AF86-AF9B34611A21
+ 1.1.56 (1.1.56.2)
+ 1.1.56.2
+
+ 2021-12-08T00:00:00Z
+
+
+
+ CHANGE
+
+
+ Global Settings - Added reset button to the Data Directory Location.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:F8A08616-749B-48E7-87D5-D97E86AB3926
+ 1.1.56 (1.1.56.1)
+ 1.1.56.1
+
+ 2021-12-06T00:00:00Z
NEW
- Global Settings - Added option to automatically manage the Public IP, default to True. If disabled, then the Public IP must be updated manually.
+
+ A new Discord Bot has been added to the server manager.
+ This new discord bot will allow you to send Start, Stop, Shutdown, Restart, Backup and Update commands to the server manager from within your discord client.
+ To setup the new discord bot, open the global settings and scroll down to the Discord section.
+
+ NOTE: This is long process to get the discord bot working, and I have created a forum post with detailed instructions how to do it.
+
+
diff --git a/CSM/beta/en-US.xaml b/CSM/beta/en-US.xaml
index ce4bffb4..9a6c123b 100644
--- a/CSM/beta/en-US.xaml
+++ b/CSM/beta/en-US.xaml
@@ -13,6 +13,15 @@
Error
+
+ The Exiled Lands
+ Isle of Siptah
+
+
+
+ Live
+
+
Unknown
Not Downloaded
@@ -26,10 +35,6 @@
Unknown
-
- Live
-
-
Europe
North America
@@ -39,11 +44,6 @@
Japan
-
- The Exiled Lands
- Isle of Siptah
-
-
Low
Below Normal
@@ -57,6 +57,12 @@
All
+
+ Normal
+ Minimized
+ Maximized
+
+
x
%
@@ -91,8 +97,9 @@
Select a Data Directory
Confirm location
The server manager will store profiles and SteamCMD in the following directories:\r\n\r\nProfiles: {0}\r\nSteamCMD: {1}\r\n\r\nIs this ok?
- Data Directory Selection Error
- The directory you have chosen is within the server manager installation folder. This is not recommended, please choose another folder.
+ Data Directory Selection Error
+ The directory you have chosen is within the server manager installation folder. This is not recommended, please choose another folder.
+ The directory you have chosen is on the desktop. This is not recommended, please choose another folder.
Failed to save profile
Failed to save profile {0}. {1}\n{2}
@@ -161,6 +168,25 @@
Processor
+
+ Data Folder Selection
+ It appears you do not have a data directory set. The data directory is where your profiles and SteamCMD will be stored. It is not the same as the server installation directory, which you can choose for each profile.
+ Select the drive where the data folder should be located.
+ Data Folder Name:
+ The name of the server manager data folder.
+ Local Disk
+ {0} free of {1}
+
+ Ok
+ Cancel
+ Refresh
+
+ Data Directory Selection Error
+ The data folder name you have entered is not valid.
+ Server Manager Restart Required
+ The data folder has been set, you must now restart the server manager to use the new settings.
+
+
Mod Details
Mod Details - {0}
@@ -602,6 +628,9 @@
Reinstall SteamCMD Error
An error occured while trying to reinstall SteamCMD. This has left SteamCmd in an unstable state, try reinstalling again or please report this.\r\nException: {0}
+ Discord Bot Running Commands
+ The discord bot has one or more running commands, do you want to continue shutting down the server manager?
+
Start Server Confirmation
You are about to start the server, do you want to continue?
Shutdown Server Confirmation
@@ -623,6 +652,7 @@
Reset
This will reset ALL the user global settings for the server manager. The server manager will be closed if successful.
Enable Run as Administrator Prompt on Startup
+ Main Window Start Mode:
Minimize To Tray
Manage firewall settings automatically
Manage Public IP automatically
@@ -741,6 +771,23 @@
Show shutdown reason with ALL shutdown messages
If enabled, the shutdown reason will be shown with all shutdown message; otherwise it will only be shown at the start of the server shutdown.
+ Enable Discord Bot
+ You will need to restart the server manager if you change any settings for the Discord Bot.
+ Token:
+ The token associated with the discord bot.
+ Server Id:
+ The id of the discord server the bot will listen to.
+ Prefix:
+ The prefix that must be used when sending a command via discord.
+ Get Token...
+ Help...
+ If enabled, the backup command can be sent from discord.
+ If enabled, the restart command can be sent from discord.
+ If enabled, the shutdown command can be sent from discord.
+ If enabled, the start command can be sent from discord.
+ If enabled, the stop command can be sent from discord.
+ If enabled, the update command can be sent from discord.
+
SMTP Email Settings
Host:
The name or IP address of the host used for SMTP transmissions.
@@ -788,6 +835,8 @@
Changing the data directory will move any existing profiles to the new location, but it will not move any server installations. Do you still want to change this directory?
Failed to change data directory
There was an error changing the data directory: {0}\r\nPlease correct the error and try again, or contact technical support for assistance.
+ Confirm Data Directory Reset
+ Click 'Yes' to confirm you want to reset the location of the data directory. Once reset, the server manager will shutdown and you will need to restart.
Select Backup Directory
Select Cache Directory
@@ -840,6 +889,8 @@
+ Profile ID:
+ The unique ID assigned to the profile.
Profile:
The name for the server profile. This is not the public name users will see in the game. For that, set the 'Server Name' field.
Installed Version:
@@ -1043,6 +1094,10 @@
Set the amount of AFK time before a character is kicked.
Server Region:
Selecting a server region will affect how your server is filtered in the list. Select your region to help players find a server that is close to them.
+ Enable Server Transfers
+ If enabled, will enable character server transfers.
+ Can Import Directly from Same Server
+ If enabled, will allow players to directly import characters that were exported from exactly the same server.
Branch Details
Branch Name:
@@ -1088,6 +1143,24 @@
If enabled, the server will be restarted even if shutdown for Auto-Restarts and Auto-Updates.
+
+ Discord Bot Details
+ Channel Id:
+ The id of the discord server channel this profile will listen to.
+ Allow Backup
+ If enabled, the profile will listen for backup commands from discord.
+ Allow Restart
+ If enabled, the profile will listen for restart commands from discord.
+ Allow Shutdown
+ If enabled, the profile will listen for shutdown commands from discord.
+ Allow Start
+ If enabled, the profile will listen for start commands from discord.
+ Allow Stop
+ If enabled, the profile will listen for stop commands from discord.
+ Allow Update
+ If enabled, the profile will listen for update commands from discord.
+
+
Server File Details
NOTE: Any changes will require a server restart to take effect.
@@ -1160,4 +1233,32 @@
There was a problem while performing the server update. This may leave your server in a incomplete state.\r\n\r\nDo you want to continue with the server start, this could cause problems?
+
+ Discord Bot Error
+ The discord bot requires a valid token so it can log into the discord server\r\nThis can be set in the global settings.
+ The discord bot prefix contains invalid characters. Only letters and numbers are allowed.
+
+ Command '{0}' has not been enabled.
+ Unknown command '{0}'.
+ Another command is currently being processed.
+ Another command '{0}' is currently running against profile '{1}'.
+ Command '{0}' has been disabled for profile '{1}'.
+
+ The '{0}' command requires a profile id.
+ Profile '{0}' was not found or is not associated with the channel.
+ Profile '{0}' is in a state '{1}' that cannot run this command.
+ Profile '{0}' is currently being updated.
+
+ Call to server '{0}' failed.
+ A backup request for server '{0}' has been sent.
+ A restart request for server '{0}' has been sent.
+ A shutdown request for server '{0}' has been sent.
+ A start request for server '{0}' has been sent.
+ A stop request for server '{0}' has been sent.
+ An update request for server '{0}' has been sent.
+
+ Count:
+ Map:
+
+
\ No newline at end of file
diff --git a/CSM/beta/latest.txt b/CSM/beta/latest.txt
index 71562986..20d52c3e 100644
--- a/CSM/beta/latest.txt
+++ b/CSM/beta/latest.txt
@@ -1 +1 @@
-1.1.50.1
+1.1.56.6
diff --git a/CSM/beta/latest.zip b/CSM/beta/latest.zip
index 0d6371de..aac86862 100644
Binary files a/CSM/beta/latest.zip and b/CSM/beta/latest.zip differ
diff --git a/CSM/en-US.xaml b/CSM/en-US.xaml
index ce4bffb4..e61a9e28 100644
--- a/CSM/en-US.xaml
+++ b/CSM/en-US.xaml
@@ -13,6 +13,15 @@
Error
+
+ The Exiled Lands
+ Isle of Siptah
+
+
+
+ Live
+
+
Unknown
Not Downloaded
@@ -26,10 +35,6 @@
Unknown
-
- Live
-
-
Europe
North America
@@ -39,11 +44,6 @@
Japan
-
- The Exiled Lands
- Isle of Siptah
-
-
Low
Below Normal
@@ -57,6 +57,12 @@
All
+
+ Normal
+ Minimized
+ Maximized
+
+
x
%
@@ -91,8 +97,9 @@
Select a Data Directory
Confirm location
The server manager will store profiles and SteamCMD in the following directories:\r\n\r\nProfiles: {0}\r\nSteamCMD: {1}\r\n\r\nIs this ok?
- Data Directory Selection Error
- The directory you have chosen is within the server manager installation folder. This is not recommended, please choose another folder.
+ Data Directory Selection Error
+ The directory you have chosen is within the server manager installation folder. This is not recommended, please choose another folder.
+ The directory you have chosen is on the desktop. This is not recommended, please choose another folder.
Failed to save profile
Failed to save profile {0}. {1}\n{2}
@@ -161,6 +168,25 @@
Processor
+
+ Data Folder Selection
+ It appears you do not have a data directory set. The data directory is where your profiles and SteamCMD will be stored. It is not the same as the server installation directory, which you can choose for each profile.
+ Select the drive where the data folder should be located.
+ Data Folder Name:
+ The name of the server manager data folder.
+ Local Disk
+ {0} free of {1}
+
+ Ok
+ Cancel
+ Refresh
+
+ Data Directory Selection Error
+ The data folder name you have entered is not valid.
+ Server Manager Restart Required
+ The data folder has been set, you must now restart the server manager to use the new settings.
+
+
Mod Details
Mod Details - {0}
@@ -623,6 +649,7 @@
Reset
This will reset ALL the user global settings for the server manager. The server manager will be closed if successful.
Enable Run as Administrator Prompt on Startup
+ Main Window Start Mode:
Minimize To Tray
Manage firewall settings automatically
Manage Public IP automatically
@@ -840,6 +867,8 @@
+ Profile ID:
+ The unique ID assigned to the profile.
Profile:
The name for the server profile. This is not the public name users will see in the game. For that, set the 'Server Name' field.
Installed Version:
@@ -1043,6 +1072,10 @@
Set the amount of AFK time before a character is kicked.
Server Region:
Selecting a server region will affect how your server is filtered in the list. Select your region to help players find a server that is close to them.
+ Enable Server Transfers
+ If enabled, will enable character server transfers.
+ Can Import Directly from Same Server
+ If enabled, will allow players to directly import characters that were exported from exactly the same server.
Branch Details
Branch Name:
diff --git a/CSM/images/Bot01.png b/CSM/images/Bot01.png
new file mode 100644
index 00000000..a854a047
Binary files /dev/null and b/CSM/images/Bot01.png differ
diff --git a/CSM/images/Bot02.png b/CSM/images/Bot02.png
new file mode 100644
index 00000000..4c5d7ea4
Binary files /dev/null and b/CSM/images/Bot02.png differ
diff --git a/CSM/images/Bot03.png b/CSM/images/Bot03.png
new file mode 100644
index 00000000..2711a70d
Binary files /dev/null and b/CSM/images/Bot03.png differ
diff --git a/CSM/images/Bot04.png b/CSM/images/Bot04.png
new file mode 100644
index 00000000..a28715d7
Binary files /dev/null and b/CSM/images/Bot04.png differ
diff --git a/CSM/images/Bot05.png b/CSM/images/Bot05.png
new file mode 100644
index 00000000..445b4c1e
Binary files /dev/null and b/CSM/images/Bot05.png differ
diff --git a/CSM/images/Bot06.png b/CSM/images/Bot06.png
new file mode 100644
index 00000000..f4558301
Binary files /dev/null and b/CSM/images/Bot06.png differ
diff --git a/CSM/images/Bot07.png b/CSM/images/Bot07.png
new file mode 100644
index 00000000..82ea839a
Binary files /dev/null and b/CSM/images/Bot07.png differ
diff --git a/CSM/images/Bot08.png b/CSM/images/Bot08.png
new file mode 100644
index 00000000..f09fa99a
Binary files /dev/null and b/CSM/images/Bot08.png differ
diff --git a/CSM/images/Bot09.png b/CSM/images/Bot09.png
new file mode 100644
index 00000000..7e544410
Binary files /dev/null and b/CSM/images/Bot09.png differ
diff --git a/CSM/images/Bot10.png b/CSM/images/Bot10.png
new file mode 100644
index 00000000..12d1ef6b
Binary files /dev/null and b/CSM/images/Bot10.png differ
diff --git a/CSM/images/Bot11.png b/CSM/images/Bot11.png
new file mode 100644
index 00000000..23d5f28d
Binary files /dev/null and b/CSM/images/Bot11.png differ
diff --git a/CSM/images/Bot12.png b/CSM/images/Bot12.png
new file mode 100644
index 00000000..f6a5dbcf
Binary files /dev/null and b/CSM/images/Bot12.png differ
diff --git a/CSM/images/Bot13.png b/CSM/images/Bot13.png
new file mode 100644
index 00000000..07b5ae17
Binary files /dev/null and b/CSM/images/Bot13.png differ
diff --git a/CSM/images/Bot14.png b/CSM/images/Bot14.png
new file mode 100644
index 00000000..f228a440
Binary files /dev/null and b/CSM/images/Bot14.png differ
diff --git a/CSM/images/Bot15.png b/CSM/images/Bot15.png
new file mode 100644
index 00000000..0f1b2652
Binary files /dev/null and b/CSM/images/Bot15.png differ
diff --git a/CSM/images/Bot16.png b/CSM/images/Bot16.png
new file mode 100644
index 00000000..50dfc198
Binary files /dev/null and b/CSM/images/Bot16.png differ
diff --git a/CSM/images/Bot17.png b/CSM/images/Bot17.png
new file mode 100644
index 00000000..354262ee
Binary files /dev/null and b/CSM/images/Bot17.png differ
diff --git a/CSM/images/CSM.png b/CSM/images/CSM.png
new file mode 100644
index 00000000..3a29a421
Binary files /dev/null and b/CSM/images/CSM.png differ
diff --git a/CSM/images/WebApiKey.png b/CSM/images/WebApiKey.png
new file mode 100644
index 00000000..46d629d2
Binary files /dev/null and b/CSM/images/WebApiKey.png differ
diff --git a/CSM/latest.exe b/CSM/latest.exe
index a3e63144..33267533 100644
Binary files a/CSM/latest.exe and b/CSM/latest.exe differ
diff --git a/CSM/latest.txt b/CSM/latest.txt
index 59fd21ec..5ebc7199 100644
--- a/CSM/latest.txt
+++ b/CSM/latest.txt
@@ -1 +1 @@
-1.1.50
+1.1.55
diff --git a/CSM/latest.zip b/CSM/latest.zip
index 75c3ac14..cc4e3efc 100644
Binary files a/CSM/latest.zip and b/CSM/latest.zip differ
diff --git a/GameData/Template/Template.gamedata b/GameData/Template/Template.gamedata
index bbcabbb5..8f2087d6 100644
--- a/GameData/Template/Template.gamedata
+++ b/GameData/Template/Template.gamedata
@@ -2,6 +2,7 @@
"Application": "ark",
"Version": "1.0.0",
"Created": "2020-03-04T00:00:00.0000000Z",
+ "Mod": "[ArkPrime|TheCenter|PrimitivePlus|ScorchedEarth|Ragnarok|Aberration|Extinction|Genesis|CrystalIsles|Genesis2|LostIsland|]"
"Creatures": [
{
"NameTag": "Achatina",
diff --git a/Plugins/Discord/ServerManager.Plugin.Discord_1.0.18.zip b/Plugins/Discord/ServerManager.Plugin.Discord_1.0.18.zip
new file mode 100644
index 00000000..c5f1d7a8
Binary files /dev/null and b/Plugins/Discord/ServerManager.Plugin.Discord_1.0.18.zip differ
diff --git a/Plugins/Discord/VersionFeed.xml b/Plugins/Discord/VersionFeed.xml
index b78d0d3b..981fd7c5 100644
--- a/Plugins/Discord/VersionFeed.xml
+++ b/Plugins/Discord/VersionFeed.xml
@@ -5,7 +5,37 @@
Discord Plugin Version Feed
This is the Discord Plugin release version feed.
- 2020-07-13T00:00:00Z
+ 2021-12-03T00:00:00Z
+
+
+ urn:uuid:C01A4AA0-D839-4732-9814-301DAC6EB094
+ 1.0.18 (1.0.18.1)
+ 1.0.18.1
+
+ 2021-12-03T00:00:00Z
+
+
+
+ NEW
+
+
+ de-DE Translation file added.
+ pt-BR Translation file added.
+ zh-CN Translation file added.
+
+
CHANGE
+
+
+ Have enabled globalization support for the plugin.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
urn:uuid:D8974ABF-8444-4D40-A594-D4443921B3B8
diff --git a/Plugins/Discord/beta/VersionFeed.xml b/Plugins/Discord/beta/VersionFeed.xml
index 4b6c8eaf..3c7cbb83 100644
--- a/Plugins/Discord/beta/VersionFeed.xml
+++ b/Plugins/Discord/beta/VersionFeed.xml
@@ -5,21 +5,22 @@
Discord Plugin Version Feed
This is the Discord Plugin beta version feed.
- 2020-07-12T02:00:00Z
+ 2021-12-12T00:00:00Z
- urn:uuid:4750D17C-2C8F-4D8C-AA17-B3512F002170
- 1.0.17 (1.0.17.2)
- 1.0.17.2
+ urn:uuid:DDB25735-1D20-4580-B5FE-1AD4BD107376
+ 1.0.19 (1.0.19.3)
+ 1.0.19.3
- 2020-07-12T02:00:00Z
+ 2021-12-12T00:00:00Z
CHANGE
- Added drag/drop feature to the config window.
+ fr-FR Translation file added.
+ pt-BR Translation file updated.
@@ -31,18 +32,47 @@
- urn:uuid:D8974ABF-8444-4D40-A594-D4443921B3B8
- 1.0.17 (1.0.17.1)
- 1.0.17.1
+ urn:uuid:FD4F56C3-9E44-4422-A761-87E7F957454F
+ 1.0.19 (1.0.19.2)
+ 1.0.19.2
- 2020-07-12T00:00:00Z
+ 2021-12-09T00:00:00Z
CHANGE
- Profile name has been converted to a droplist and is now populated with the Server Manager Profile Names for selection.
+ Changed the plugin initialization so it throws an exception if unable to load config file, rather than creating a new config file.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:A9EC2F32-E026-485F-BD7B-C657DBA95B54
+ 1.0.19 (1.0.19.1)
+ 1.0.19.1
+
+ 2021-12-09T00:00:00Z
+
+
+
+ BUGFIX
+
+
+ Fixed alert test message to support globalization.
+
+
CHANGE
+
+
+ de-DE Translation file updated.
+ pt-BR Translation file updated.
diff --git a/Plugins/Discord/beta/en-US.xaml b/Plugins/Discord/beta/en-US.xaml
index d060132d..0ff41e2c 100644
--- a/Plugins/Discord/beta/en-US.xaml
+++ b/Plugins/Discord/beta/en-US.xaml
@@ -4,6 +4,18 @@
xmlns:sys="clr-namespace:System;assembly=mscorlib"
>
+
+ Backup
+ Error
+ Mod Update Detected
+ Shutdown
+ Shutdown Message
+ Shutdown Reason
+ Server Status Change
+ Startup
+ Update Results
+
+
Cancel
Close
@@ -106,6 +118,8 @@
Test Action Error
An error occurred while trying to test the config profile.
The profile is not enabled and cannot be tested.
+
+ Test '{0}' alert type message for profile name '{1}'
diff --git a/Plugins/Discord/beta/latest.txt b/Plugins/Discord/beta/latest.txt
index 818827af..4821a307 100644
--- a/Plugins/Discord/beta/latest.txt
+++ b/Plugins/Discord/beta/latest.txt
@@ -1 +1 @@
-1.0.17.2
+1.0.19.3
diff --git a/Plugins/Discord/beta/latest.zip b/Plugins/Discord/beta/latest.zip
index 032a7338..4838a11d 100644
Binary files a/Plugins/Discord/beta/latest.zip and b/Plugins/Discord/beta/latest.zip differ
diff --git a/Plugins/Discord/en-US.xaml b/Plugins/Discord/en-US.xaml
index d060132d..82a5f111 100644
--- a/Plugins/Discord/en-US.xaml
+++ b/Plugins/Discord/en-US.xaml
@@ -4,6 +4,18 @@
xmlns:sys="clr-namespace:System;assembly=mscorlib"
>
+
+ Backup
+ Error
+ Mod Update Detected
+ Shutdown
+ Shutdown Message
+ Shutdown Reason
+ Server Status Change
+ Startup
+ Update Results
+
+
Cancel
Close
diff --git a/Plugins/Discord/latest.txt b/Plugins/Discord/latest.txt
index d1aa8e52..54473825 100644
--- a/Plugins/Discord/latest.txt
+++ b/Plugins/Discord/latest.txt
@@ -1 +1 @@
-1.0.17
+1.0.18
diff --git a/Plugins/Discord/latest.zip b/Plugins/Discord/latest.zip
index 9a04e357..c5f1d7a8 100644
Binary files a/Plugins/Discord/latest.zip and b/Plugins/Discord/latest.zip differ
diff --git a/README.md b/README.md
index e5a4a084..dff440a5 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
Managers for different steam dedicated game servers.
# Forums
-Ark Server Manager - https://arkservermanager.freeforums.net/
+Ark Server Manager - https://arkservermanager.freeforums.net
-Server Managers - https://servermanagers.freeforums.net/
+Conan Server Manager - https://servermanagers.freeforums.net
# Invite link to discord
-discord.gg/HB8DXXt
+https://discord.gg/HB8DXXt
diff --git a/src/.gitignore b/src/.gitignore
index ecad615e..caeecf03 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -350,6 +350,6 @@ MigrationBackup/
.ionide/
# custom files
-Deploy*Github.cmd
-Installer.*
-MakeLatest*.ps1
+#Deploy*Github.cmd
+Installer.txt
+#MakeLatest*.ps1
diff --git a/src/ARKServerManager.Common/ARKServerManager.Common.csproj b/src/ARKServerManager.Common/ARKServerManager.Common.csproj
index 5e3bcbe9..7f2c4d66 100644
--- a/src/ARKServerManager.Common/ARKServerManager.Common.csproj
+++ b/src/ARKServerManager.Common/ARKServerManager.Common.csproj
@@ -1,9 +1,5 @@
- %24/Development/ServerManagers/Main/ARKServerManager.Common
- {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- https://dev.azure.com/bretthewitson
- .
Debug;Release;Debug - Beta
@@ -15,11 +11,6 @@
none
false
-
-
-
-
-
diff --git a/src/ARKServerManager.Common/Properties/AssemblyInfo.cs b/src/ARKServerManager.Common/Properties/AssemblyInfo.cs
index 659d1651..a04d1780 100644
--- a/src/ARKServerManager.Common/Properties/AssemblyInfo.cs
+++ b/src/ARKServerManager.Common/Properties/AssemblyInfo.cs
@@ -1,35 +1,19 @@
using System.Reflection;
using System.Runtime.InteropServices;
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
[assembly: AssemblyTitle("ARKServerManager Common Library")]
[assembly: AssemblyDescription("The library is used to provide common functionality to the ark server manager.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Bletch1971")]
[assembly: AssemblyProduct("Server Managers")]
-[assembly: AssemblyCopyright("Copyright © 2015-2020")]
+[assembly: AssemblyCopyright("Copyright © 2015-2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
-// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("dd0a2401-99b8-4de1-b8ed-9b075172f8af")]
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
+// include semantic versioning - ARKServerManager
[assembly: AssemblyVersion("1.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/ARKServerManager.Common/Utils/GameDataUtils.cs b/src/ARKServerManager.Common/Utils/GameDataUtils.cs
index e2aa7bcc..ed64ca61 100644
--- a/src/ARKServerManager.Common/Utils/GameDataUtils.cs
+++ b/src/ARKServerManager.Common/Utils/GameDataUtils.cs
@@ -37,7 +37,7 @@ namespace ServerManagerTool.Utils
data.SupplyCrates.AddRange(fileData.SupplyCrates);
data.Inventories.AddRange(fileData.Inventories);
data.GameMaps.AddRange(fileData.GameMaps);
- data.Mods.AddRange(fileData.Mods);
+ data.TotalConversions.AddRange(fileData.TotalConversions);
data.PlayerLevels.AddRange(fileData.PlayerLevels);
data.CreatureLevels.AddRange(fileData.CreatureLevels);
data.Branches.AddRange(fileData.Branches);
@@ -117,7 +117,7 @@ namespace ServerManagerTool.Utils
public List GameMaps = new List();
[DataMember(IsRequired = false)]
- public List Mods = new List();
+ public List TotalConversions = new List();
[DataMember(IsRequired = false)]
public List PlayerLevels = new List();
@@ -153,7 +153,7 @@ namespace ServerManagerTool.Utils
data.SupplyCrates.ForEach(c => c.IsUserData = isUserData);
data.Inventories.ForEach(c => c.IsUserData = isUserData);
data.GameMaps.ForEach(c => c.IsUserData = isUserData);
- data.Mods.ForEach(c => c.IsUserData = isUserData);
+ data.TotalConversions.ForEach(c => c.IsUserData = isUserData);
data.Branches.ForEach(c => c.IsUserData = isUserData);
data.Events.ForEach(c => c.IsUserData = isUserData);
data.OfficialMods.ForEach(c => c.IsUserData = isUserData);
diff --git a/src/ARKServerManager/ARKServerManager.csproj b/src/ARKServerManager/ARKServerManager.csproj
index 1309d442..b7242f38 100644
--- a/src/ARKServerManager/ARKServerManager.csproj
+++ b/src/ARKServerManager/ARKServerManager.csproj
@@ -37,7 +37,7 @@
Server Managers
false
1
- 1.1.400.%2a
+ 1.1.0.%2a
false
true
false
@@ -106,6 +106,9 @@
7.3
prompt
+
+ true
+
..\packages\DotNetZip.1.13.8\lib\net40\DotNetZip.dll
@@ -173,6 +176,7 @@
MSBuild:Compile
Designer
+
@@ -191,23 +195,29 @@
+
-
+
+
+
AddUserWindow.xaml
-
+
+
+ DataDirectoryWindow.xaml
+
PlayerListWindow.xaml
@@ -239,9 +249,6 @@
ServerMonitorWindow.xaml
-
- SupplyCrateOverridesWindow.xaml
-
VersionFeedWindow.xaml
@@ -271,7 +278,7 @@
CommandLineWindow.xaml
-
+
GlobalSettingsControl.xaml
@@ -304,7 +311,7 @@
RCONWindow.xaml
-
+
ServerSettingsControl.xaml
@@ -314,9 +321,17 @@
SettingsWindow.xaml
+
+
+
+
+
Always
+
+ Always
+
@@ -389,6 +404,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
@@ -417,10 +436,6 @@
Designer
MSBuild:Compile
-
- Designer
- MSBuild:Compile
-
Designer
MSBuild:Compile
@@ -483,7 +498,7 @@
Designer
MSBuild:Compile
-
+
Designer
MSBuild:Compile
@@ -512,7 +527,7 @@
Designer
MSBuild:Compile
-
+
Designer
MSBuild:Compile
@@ -608,6 +623,10 @@
{7c99d9f7-0c65-4116-927a-94eb018c88fd}
ServerManager.Common
+
+ {c4c8000d-5e45-497c-a218-b95a1567010e}
+ ServerManager.Discord
+
{3e0c9ee6-780f-4fef-ba03-e38062a5fdb6}
ServerManager.Updater
diff --git a/src/ARKServerManager/App.config b/src/ARKServerManager/App.config
index 76a5db80..febac3a6 100644
--- a/src/ARKServerManager/App.config
+++ b/src/ARKServerManager/App.config
@@ -33,7 +33,7 @@
+login anonymous +quit
- +login anonymous +force_install_dir "{0}" "+app_update 376030 {1} {2}" +quit
+ +force_install_dir "{0}" +login anonymous "+app_update 376030 {1} {2}" +quit
Servers
@@ -102,7 +102,7 @@
http://arkservermanager.freeforums.net/thread/1194/faq-frequently-asked
- +login anonymous +force_install_dir "{0}" "+app_update 445400 {1} {2}" +quit
+ +force_install_dir "{0}" +login anonymous "+app_update 445400 {1} {2}" +quit
https://survivetheark.com/index.php?/forums/forum/5-changelog-patch-notes/
@@ -210,7 +210,7 @@
Server
-
+ https://servermanagers.azurewebsites.net/api/server/{0}/{1}/{2}/{3}
PGARK
@@ -264,7 +264,7 @@
.png
- ED89B8FA-0E0B-46CC-A90B-595E69AE9A7E
+ 6DCE02B1-8F41-4AF8-A6EA-E2E026CAB023
GameData
@@ -344,6 +344,15 @@
version.txt
+
+ asmdata
+
+
+ https://discord.com/developers/applications
+
+
+ https://arkservermanager.freeforums.net/thread/8764/get-own-discord-bot
+
@@ -741,6 +750,105 @@
True
+
+ 400
+
+
+ 200
+
+
+ 200
+
+
+ 200
+
+
+ 200
+
+
+ 400
+
+
+ 400
+
+
+ 400
+
+
+ 400
+
+
+ 400
+
+
+ 400
+
+
+ 400
+
+
+ 250
+
+
+ 400
+
+
+ 400
+
+
+ 400
+
+
+ 100
+
+
+ Normal
+
+
+ 50
+
+
+ 50
+
+
+ False
+
+
+ asm
+
+
+
+
+
+
+
+
+ False
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ 50
+
+
+ 50
+
diff --git a/src/ARKServerManager/App.xaml.cs b/src/ARKServerManager/App.xaml.cs
index 20e699c8..2e79faa1 100644
--- a/src/ARKServerManager/App.xaml.cs
+++ b/src/ARKServerManager/App.xaml.cs
@@ -1,16 +1,16 @@
using ArkData;
-using Microsoft.WindowsAPICodePack.Dialogs;
using NLog;
using NLog.Config;
using NLog.Targets;
using ServerManagerTool.Common;
using ServerManagerTool.Common.Utils;
+using ServerManagerTool.DiscordBot;
using ServerManagerTool.Enums;
using ServerManagerTool.Lib;
using ServerManagerTool.Plugin.Common;
+using ServerManagerTool.Utils;
using ServerManagerTool.Windows;
using System;
-using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
@@ -18,9 +18,9 @@ using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
+using System.Threading;
using System.Threading.Tasks;
using System.Windows;
-using System.Xml;
using WPFSharp.Globalizer;
namespace ServerManagerTool
@@ -38,6 +38,7 @@ namespace ServerManagerTool
public event PropertyChangedEventHandler PropertyChanged;
+ private CancellationTokenSource _tokenSource;
private GlobalizedApplication _globalizer;
private bool _applicationStarted;
private string _args;
@@ -176,11 +177,6 @@ namespace ServerManagerTool
}
}
- private IList FetchProfiles()
- {
- return ServerManager.Instance.Servers.Select(s => new ServerManagerTool.Plugin.Common.Lib.Profile() { ProfileName = s?.Profile?.ProfileName ?? string.Empty, InstallationFolder = s?.Profile?.InstallDirectory ?? string.Empty }).ToList();
- }
-
public static string GetLogFolder() => IOUtils.NormalizePath(Path.Combine(Config.Default.DataDir, Config.Default.LogsDir));
public static string GetProfileLogFolder(string profileId) => IOUtils.NormalizePath(Path.Combine(Config.Default.DataDir, Config.Default.LogsDir, profileId.ToLower()));
@@ -311,7 +307,8 @@ namespace ServerManagerTool
var installPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
PluginHelper.Instance.BetaEnabled = this.BetaVersion;
PluginHelper.Instance.LoadPlugins(installPath, true);
- PluginHelper.Instance.SetFetchProfileCallback(FetchProfiles);
+ PluginHelper.Instance.SetFetchProfileCallback(DiscordPluginHelper.FetchProfiles);
+ OnResourceDictionaryChanged(Thread.CurrentThread.CurrentCulture.Name);
// check if we are starting ASM for the old server restart - no longer supported
if (e.Args.Any(a => a.StartsWith(Constants.ARG_AUTORESTART, StringComparison.OrdinalIgnoreCase)))
@@ -410,68 +407,29 @@ namespace ServerManagerTool
ApplicationStarted = true;
- // Initial configuration setting
- if (String.IsNullOrWhiteSpace(Config.Default.DataDir))
- {
- MessageBox.Show(_globalizer.GetResourceString("Application_DataDirectoryLabel"), _globalizer.GetResourceString("Application_DataDirectoryTitle"), MessageBoxButton.OK, MessageBoxImage.Information);
+ var restartRequired = false;
+ if (string.IsNullOrWhiteSpace(Config.Default.DataDir))
+ {
+ var dataDirectoryWindow = new DataDirectoryWindow();
+ dataDirectoryWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;
+ var result = dataDirectoryWindow.ShowDialog();
- var installationFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
- if (!installationFolder.EndsWith(@"\"))
- installationFolder += @"\";
-
- while (String.IsNullOrWhiteSpace(Config.Default.DataDir))
+ if (!result.HasValue || !result.Value)
{
- var dialog = new CommonOpenFileDialog
- {
- EnsureFileExists = true,
- IsFolderPicker = true,
- Multiselect = false,
- Title = _globalizer.GetResourceString("Application_DataDirectory_DialogTitle"),
- InitialDirectory = installationFolder
- };
-
- if (dialog.ShowDialog() != CommonFileDialogResult.Ok)
- {
- Environment.Exit(0);
- }
-
- MessageBoxResult confirm = MessageBoxResult.Cancel;
-
- // check if the folder is under the installation folder
- var newDataFolder = dialog.FileName;
- if (!newDataFolder.EndsWith(@"\"))
- newDataFolder += @"\";
-
- if (newDataFolder.StartsWith(installationFolder))
- {
- confirm = MessageBoxResult.No;
- MessageBox.Show(_globalizer.GetResourceString("Application_DataDirectory_WithinInstallFolderErrorLabel"), _globalizer.GetResourceString("Application_DataDirectory_WithinInstallFolderErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error);
- }
- else
- {
- confirm = MessageBox.Show(String.Format(_globalizer.GetResourceString("Application_DataDirectory_ConfirmLabel"), Path.Combine(newDataFolder, Config.Default.ProfilesDir), Path.Combine(newDataFolder, Config.Default.SteamCmdDir)), _globalizer.GetResourceString("Application_DataDirectory_ConfirmTitle"), MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
- }
-
- if (confirm == MessageBoxResult.Cancel)
- {
- Environment.Exit(0);
- }
- else if (confirm == MessageBoxResult.Yes)
- {
- if (newDataFolder.EndsWith(@"\"))
- newDataFolder = newDataFolder.Substring(0, newDataFolder.Length -1);
-
- Config.Default.DataDir = newDataFolder;
- ReconfigureLogging();
- break;
- }
+ Environment.Exit(0);
}
+
+ restartRequired = true;
}
Config.Default.ConfigDirectory = Path.Combine(Config.Default.DataDir, Config.Default.ProfilesDir);
System.IO.Directory.CreateDirectory(Config.Default.ConfigDirectory);
- Config.Default.Save();
- CommonConfig.Default.Save();
+ SaveConfigFiles();
+
+ if (restartRequired)
+ {
+ Environment.Exit(0);
+ }
DataFileDetails.PlayerFileExtension = Config.Default.PlayerFileExtension;
DataFileDetails.TribeFileExtension = Config.Default.TribeFileExtension;
@@ -490,6 +448,25 @@ namespace ServerManagerTool
StartupUri = new Uri("Windows/AutoUpdateWindow.xaml", UriKind.RelativeOrAbsolute);
}
+
+ if (Config.Default.DiscordBotEnabled)
+ {
+ _tokenSource = new CancellationTokenSource();
+
+ Task discordTask = Task.Run(async () =>
+ {
+ await ServerManagerBotFactory.GetServerManagerBot()?.StartAsync(Config.Default.DiscordBotToken, Config.Default.DiscordBotPrefix, Config.Default.DataDir, DiscordBotHelper.HandleDiscordCommand, DiscordBotHelper.HandleTranslation, _tokenSource.Token);
+ }, _tokenSource.Token)
+ .ContinueWith(t => {
+ var message = t.Exception.InnerException is null ? t.Exception.Message : t.Exception.InnerException.Message;
+ if (message.StartsWith("#"))
+ {
+ message = _globalizer.GetResourceString(message.Substring(1)) ?? message.Substring(1);
+ }
+
+ MessageBox.Show(message, _globalizer.GetResourceString("DiscordBot_ErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error);
+ }, TaskContinuationOptions.OnlyOnFaulted);
+ }
}
protected override void OnExit(ExitEventArgs e)
@@ -504,6 +481,11 @@ namespace ServerManagerTool
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
+ public void OnResourceDictionaryChanged(string languageCode)
+ {
+ PluginHelper.Instance.OnResourceDictionaryChanged(languageCode);
+ }
+
public static void ReconfigureLogging()
{
string logDir = Path.Combine(Config.Default.DataDir, Config.Default.LogsDir);
@@ -525,6 +507,12 @@ namespace ServerManagerTool
private void ShutDownApplication()
{
+ if (!(_tokenSource is null))
+ {
+ _tokenSource.Cancel();
+ _tokenSource.Dispose();
+ }
+
if (ApplicationStarted)
{
foreach (var server in ServerManager.Instance.Servers)
@@ -538,13 +526,31 @@ namespace ServerManagerTool
MessageBox.Show(String.Format(_globalizer.GetResourceString("Application_Profile_SaveFailedLabel"), server.Profile.ProfileName, ex.Message, ex.StackTrace), _globalizer.GetResourceString("Application_Profile_SaveFailedTitle"), MessageBoxButton.OK, MessageBoxImage.Error);
}
}
- Config.Default.Save();
- CommonConfig.Default.Save();
+ SaveConfigFiles();
}
PluginHelper.Instance?.Dispose();
ApplicationStarted = false;
}
+
+ public static void SaveConfigFiles(bool includeBackup = true)
+ {
+ Config.Default.Save();
+ CommonConfig.Default.Save();
+
+ Config.Default.Reload();
+ CommonConfig.Default.Reload();
+
+ var installFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ var backupFolder = includeBackup
+ ? IOUtils.NormalizePath(string.IsNullOrWhiteSpace(Config.Default.BackupPath)
+ ? Path.Combine(Config.Default.DataDir, Config.Default.BackupDir)
+ : Path.Combine(Config.Default.BackupPath))
+ : null;
+
+ SettingsUtils.BackupUserConfigSettings(Config.Default, "userconfig.json", installFolder, backupFolder);
+ SettingsUtils.BackupUserConfigSettings(CommonConfig.Default, "commonconfig.json", installFolder, backupFolder);
+ }
}
}
diff --git a/src/ARKServerManager/Art/Collapse.ico b/src/ARKServerManager/Art/Collapse.ico
new file mode 100644
index 00000000..7b5a3cf5
Binary files /dev/null and b/src/ARKServerManager/Art/Collapse.ico differ
diff --git a/src/ARKServerManager/Art/Expand.ico b/src/ARKServerManager/Art/Expand.ico
new file mode 100644
index 00000000..8fb70ffa
Binary files /dev/null and b/src/ARKServerManager/Art/Expand.ico differ
diff --git a/src/ARKServerManager/Art/StatusBad.ico b/src/ARKServerManager/Art/StatusBad.ico
new file mode 100644
index 00000000..2baffa9d
Binary files /dev/null and b/src/ARKServerManager/Art/StatusBad.ico differ
diff --git a/src/ARKServerManager/Art/StatusGood.ico b/src/ARKServerManager/Art/StatusGood.ico
new file mode 100644
index 00000000..c1c810bd
Binary files /dev/null and b/src/ARKServerManager/Art/StatusGood.ico differ
diff --git a/src/ARKServerManager/Art/StatusWarning.ico b/src/ARKServerManager/Art/StatusWarning.ico
new file mode 100644
index 00000000..67b2ce82
Binary files /dev/null and b/src/ARKServerManager/Art/StatusWarning.ico differ
diff --git a/src/ARKServerManager/Art/favicon.ico b/src/ARKServerManager/Art/favicon.ico
index 2ed732cb..9f1a5760 100644
Binary files a/src/ARKServerManager/Art/favicon.ico and b/src/ARKServerManager/Art/favicon.ico differ
diff --git a/src/ARKServerManager/Config.Designer.cs b/src/ARKServerManager/Config.Designer.cs
index 1f386aee..5f9d64bb 100644
--- a/src/ARKServerManager/Config.Designer.cs
+++ b/src/ARKServerManager/Config.Designer.cs
@@ -12,7 +12,7 @@ namespace ServerManagerTool {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.0.3.0")]
public sealed partial class Config : global::System.Configuration.ApplicationSettingsBase {
private static Config defaultInstance = ((Config)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Config())));
@@ -82,7 +82,7 @@ namespace ServerManagerTool {
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("+login anonymous +force_install_dir \"{0}\" \"+app_update 376030 {1} {2}\" +quit")]
+ [global::System.Configuration.DefaultSettingValueAttribute("+force_install_dir \"{0}\" +login anonymous \"+app_update 376030 {1} {2}\" +quit")]
public string SteamCmdInstallServerArgsFormat {
get {
return ((string)(this["SteamCmdInstallServerArgsFormat"]));
@@ -578,7 +578,7 @@ namespace ServerManagerTool {
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("+login anonymous +force_install_dir \"{0}\" \"+app_update 445400 {1} {2}\" +quit")]
+ [global::System.Configuration.DefaultSettingValueAttribute("+force_install_dir \"{0}\" +login anonymous \"+app_update 445400 {1} {2}\" +quit")]
public string SteamCmdInstallServerArgsFormat_SotF {
get {
return ((string)(this["SteamCmdInstallServerArgsFormat_SotF"]));
@@ -1339,7 +1339,7 @@ namespace ServerManagerTool {
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("")]
+ [global::System.Configuration.DefaultSettingValueAttribute("https://servermanagers.azurewebsites.net/api/server/{0}/{1}/{2}/{3}")]
public string ServerStatusUrlFormat {
get {
return ((string)(this["ServerStatusUrlFormat"]));
@@ -1947,7 +1947,7 @@ namespace ServerManagerTool {
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("ED89B8FA-0E0B-46CC-A90B-595E69AE9A7E")]
+ [global::System.Configuration.DefaultSettingValueAttribute("6DCE02B1-8F41-4AF8-A6EA-E2E026CAB023")]
public string ServerManagerCode {
get {
return ((string)(this["ServerManagerCode"]));
@@ -2563,5 +2563,428 @@ namespace ServerManagerTool {
this["SectionPreventTransferOverridesEnabled"] = value;
}
}
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("400")]
+ public global::System.Windows.GridLength PreventTransferOverrideGridHeight {
+ get {
+ return ((global::System.Windows.GridLength)(this["PreventTransferOverrideGridHeight"]));
+ }
+ set {
+ this["PreventTransferOverrideGridHeight"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("200")]
+ public global::System.Windows.GridLength SupplyCratesGridHeight {
+ get {
+ return ((global::System.Windows.GridLength)(this["SupplyCratesGridHeight"]));
+ }
+ set {
+ this["SupplyCratesGridHeight"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("200")]
+ public global::System.Windows.GridLength SupplyCrateItemSetsGridHeight {
+ get {
+ return ((global::System.Windows.GridLength)(this["SupplyCrateItemSetsGridHeight"]));
+ }
+ set {
+ this["SupplyCrateItemSetsGridHeight"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("200")]
+ public global::System.Windows.GridLength SupplyCrateItemSetEntriesGridHeight {
+ get {
+ return ((global::System.Windows.GridLength)(this["SupplyCrateItemSetEntriesGridHeight"]));
+ }
+ set {
+ this["SupplyCrateItemSetEntriesGridHeight"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("200")]
+ public global::System.Windows.GridLength SupplyCrateItemsGridHeight {
+ get {
+ return ((global::System.Windows.GridLength)(this["SupplyCrateItemsGridHeight"]));
+ }
+ set {
+ this["SupplyCrateItemsGridHeight"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("400")]
+ public global::System.Windows.GridLength NPCSpawnSettingsGridHeight {
+ get {
+ return ((global::System.Windows.GridLength)(this["NPCSpawnSettingsGridHeight"]));
+ }
+ set {
+ this["NPCSpawnSettingsGridHeight"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("400")]
+ public global::System.Windows.GridLength StackSizeOverrideGridHeight {
+ get {
+ return ((global::System.Windows.GridLength)(this["StackSizeOverrideGridHeight"]));
+ }
+ set {
+ this["StackSizeOverrideGridHeight"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("400")]
+ public global::System.Windows.GridLength CraftingOverrideItemGridHeight {
+ get {
+ return ((global::System.Windows.GridLength)(this["CraftingOverrideItemGridHeight"]));
+ }
+ set {
+ this["CraftingOverrideItemGridHeight"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("400")]
+ public global::System.Windows.GridLength CustomLevelsGridHeight {
+ get {
+ return ((global::System.Windows.GridLength)(this["CustomLevelsGridHeight"]));
+ }
+ set {
+ this["CustomLevelsGridHeight"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("400")]
+ public global::System.Windows.GridLength CustomEngineSettingsGridHeight {
+ get {
+ return ((global::System.Windows.GridLength)(this["CustomEngineSettingsGridHeight"]));
+ }
+ set {
+ this["CustomEngineSettingsGridHeight"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("400")]
+ public global::System.Windows.GridLength CustomGameSettingsGridHeight {
+ get {
+ return ((global::System.Windows.GridLength)(this["CustomGameSettingsGridHeight"]));
+ }
+ set {
+ this["CustomGameSettingsGridHeight"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("400")]
+ public global::System.Windows.GridLength CustomGameUserSettingsGridHeight {
+ get {
+ return ((global::System.Windows.GridLength)(this["CustomGameUserSettingsGridHeight"]));
+ }
+ set {
+ this["CustomGameUserSettingsGridHeight"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("250")]
+ public global::System.Windows.GridLength ServerFilesGridHeight {
+ get {
+ return ((global::System.Windows.GridLength)(this["ServerFilesGridHeight"]));
+ }
+ set {
+ this["ServerFilesGridHeight"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("400")]
+ public global::System.Windows.GridLength EngramsGridHeight {
+ get {
+ return ((global::System.Windows.GridLength)(this["EngramsGridHeight"]));
+ }
+ set {
+ this["EngramsGridHeight"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("400")]
+ public global::System.Windows.GridLength EnvironmentListBoxHeight {
+ get {
+ return ((global::System.Windows.GridLength)(this["EnvironmentListBoxHeight"]));
+ }
+ set {
+ this["EnvironmentListBoxHeight"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("400")]
+ public global::System.Windows.GridLength DinoSettingsGridHeight {
+ get {
+ return ((global::System.Windows.GridLength)(this["DinoSettingsGridHeight"]));
+ }
+ set {
+ this["DinoSettingsGridHeight"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("100")]
+ public global::System.Windows.GridLength MOTDHeight {
+ get {
+ return ((global::System.Windows.GridLength)(this["MOTDHeight"]));
+ }
+ set {
+ this["MOTDHeight"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("Normal")]
+ public global::System.Windows.WindowState MainWindow_WindowState {
+ get {
+ return ((global::System.Windows.WindowState)(this["MainWindow_WindowState"]));
+ }
+ set {
+ this["MainWindow_WindowState"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("50")]
+ public double MainWindow_Left {
+ get {
+ return ((double)(this["MainWindow_Left"]));
+ }
+ set {
+ this["MainWindow_Left"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("50")]
+ public double MainWindow_Top {
+ get {
+ return ((double)(this["MainWindow_Top"]));
+ }
+ set {
+ this["MainWindow_Top"] = value;
+ }
+ }
+
+ [global::System.Configuration.ApplicationScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("asmdata")]
+ public string DefaultDataDirectoryName {
+ get {
+ return ((string)(this["DefaultDataDirectoryName"]));
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool DiscordBotEnabled {
+ get {
+ return ((bool)(this["DiscordBotEnabled"]));
+ }
+ set {
+ this["DiscordBotEnabled"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("asm")]
+ public string DiscordBotPrefix {
+ get {
+ return ((string)(this["DiscordBotPrefix"]));
+ }
+ set {
+ this["DiscordBotPrefix"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("")]
+ public string DiscordBotToken {
+ get {
+ return ((string)(this["DiscordBotToken"]));
+ }
+ set {
+ this["DiscordBotToken"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("")]
+ public string DiscordBotServerId {
+ get {
+ return ((string)(this["DiscordBotServerId"]));
+ }
+ set {
+ this["DiscordBotServerId"] = value;
+ }
+ }
+
+ [global::System.Configuration.ApplicationScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("https://discord.com/developers/applications")]
+ public string DiscordBotApplyUrl {
+ get {
+ return ((string)(this["DiscordBotApplyUrl"]));
+ }
+ }
+
+ [global::System.Configuration.ApplicationScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("https://arkservermanager.freeforums.net/thread/8764/get-own-discord-bot")]
+ public string DiscordBotHelpUrl {
+ get {
+ return ((string)(this["DiscordBotHelpUrl"]));
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool SectionDiscordBotIsExpanded {
+ get {
+ return ((bool)(this["SectionDiscordBotIsExpanded"]));
+ }
+ set {
+ this["SectionDiscordBotIsExpanded"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool AllowDiscordBackup {
+ get {
+ return ((bool)(this["AllowDiscordBackup"]));
+ }
+ set {
+ this["AllowDiscordBackup"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool AllowDiscordUpdate {
+ get {
+ return ((bool)(this["AllowDiscordUpdate"]));
+ }
+ set {
+ this["AllowDiscordUpdate"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool AllowDiscordStart {
+ get {
+ return ((bool)(this["AllowDiscordStart"]));
+ }
+ set {
+ this["AllowDiscordStart"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool AllowDiscordRestart {
+ get {
+ return ((bool)(this["AllowDiscordRestart"]));
+ }
+ set {
+ this["AllowDiscordRestart"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool AllowDiscordShutdown {
+ get {
+ return ((bool)(this["AllowDiscordShutdown"]));
+ }
+ set {
+ this["AllowDiscordShutdown"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool AllowDiscordStop {
+ get {
+ return ((bool)(this["AllowDiscordStop"]));
+ }
+ set {
+ this["AllowDiscordStop"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("50")]
+ public double ServerMonitorWindow_Left {
+ get {
+ return ((double)(this["ServerMonitorWindow_Left"]));
+ }
+ set {
+ this["ServerMonitorWindow_Left"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("50")]
+ public double ServerMonitorWindow_Top {
+ get {
+ return ((double)(this["ServerMonitorWindow_Top"]));
+ }
+ set {
+ this["ServerMonitorWindow_Top"] = value;
+ }
+ }
}
}
diff --git a/src/ARKServerManager/Config.settings b/src/ARKServerManager/Config.settings
index 0a55a9a5..c11d5ae4 100644
--- a/src/ARKServerManager/Config.settings
+++ b/src/ARKServerManager/Config.settings
@@ -21,7 +21,7 @@
- +login anonymous +force_install_dir "{0}" "+app_update 376030 {1} {2}" +quit
+ +force_install_dir "{0}" +login anonymous "+app_update 376030 {1} {2}" +quit
Servers
@@ -162,7 +162,7 @@
1000
- +login anonymous +force_install_dir "{0}" "+app_update 445400 {1} {2}" +quit
+ +force_install_dir "{0}" +login anonymous "+app_update 445400 {1} {2}" +quit
https://survivetheark.com/index.php?/forums/forum/5-changelog-patch-notes/
@@ -378,7 +378,7 @@
Server
-
+ https://servermanagers.azurewebsites.net/api/server/{0}/{1}/{2}/{3}
PGARK
@@ -543,7 +543,7 @@
A wild dino wipe is scheduled after the server starts and may delay login until it is complete. Please be patient.
- ED89B8FA-0E0B-46CC-A90B-595E69AE9A7E
+ 6DCE02B1-8F41-4AF8-A6EA-E2E026CAB023
@@ -716,5 +716,113 @@
True
+
+ 400
+
+
+ 200
+
+
+ 200
+
+
+ 200
+
+
+ 200
+
+
+ 400
+
+
+ 400
+
+
+ 400
+
+
+ 400
+
+
+ 400
+
+
+ 400
+
+
+ 400
+
+
+ 250
+
+
+ 400
+
+
+ 400
+
+
+ 400
+
+
+ 100
+
+
+ Normal
+
+
+ 50
+
+
+ 50
+
+
+ asmdata
+
+
+ False
+
+
+ asm
+
+
+
+
+
+
+
+
+ https://discord.com/developers/applications
+
+
+ https://arkservermanager.freeforums.net/thread/8764/get-own-discord-bot
+
+
+ False
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ 50
+
+
+ 50
+
\ No newline at end of file
diff --git a/src/ARKServerManager/Delegates/ServerStatusChangeDelegate.cs b/src/ARKServerManager/Delegates/ServerStatusChangeDelegate.cs
new file mode 100644
index 00000000..c7ab834a
--- /dev/null
+++ b/src/ARKServerManager/Delegates/ServerStatusChangeDelegate.cs
@@ -0,0 +1,6 @@
+using ServerManagerTool.Enums;
+
+namespace ServerManagerTool.Delegates
+{
+ public delegate void ServerStatusChangeDelegate(ServerStatus serverStatus);
+}
diff --git a/src/ARKServerManager/Enums/AvailabilityStatus.cs b/src/ARKServerManager/Enums/AvailabilityStatus.cs
index f2588330..81846709 100644
--- a/src/ARKServerManager/Enums/AvailabilityStatus.cs
+++ b/src/ARKServerManager/Enums/AvailabilityStatus.cs
@@ -3,9 +3,9 @@
public enum AvailabilityStatus
{
Unknown,
- NeedPublicIP,
+ SetPublicIP,
Unavailable,
- WaitingForPublication,
+ Waiting,
Available
}
}
diff --git a/src/ARKServerManager/Enums/ServerProcessType.cs b/src/ARKServerManager/Enums/ServerProcessType.cs
index 861e2081..7298dfd9 100644
--- a/src/ARKServerManager/Enums/ServerProcessType.cs
+++ b/src/ARKServerManager/Enums/ServerProcessType.cs
@@ -10,5 +10,6 @@
Backup,
Shutdown,
Restart,
+ Update,
}
}
diff --git a/src/ARKServerManager/GameData/Extinction.gamedata b/src/ARKServerManager/GameData/Extinction.gamedata
index bbfa7613..d417ee6e 100644
--- a/src/ARKServerManager/GameData/Extinction.gamedata
+++ b/src/ARKServerManager/GameData/Extinction.gamedata
@@ -1,7 +1,7 @@
{
"Application": "ark",
- "Version": "1.0.0",
- "Created": "2018-11-07T11:00:00.0000000Z",
+ "Version": "1.1.0",
+ "Created": "2021-08-23T11:00:00.0000000Z",
"Creatures": [
{
"NameTag": "Artho",
@@ -293,14 +293,6 @@
}
],
"Engrams": [
- {
- "Level": 88,
- "Points": 60,
- "IsTekGram": false,
- "ClassName": "EngramEntry_CryoFridge_C",
- "Description": "Cryofridge",
- "Mod": "Extinction"
- },
{
"Level": 22,
"Points": 6,
@@ -309,14 +301,6 @@
"Description": "Dino Leash",
"Mod": "Extinction"
},
- {
- "Level": 51,
- "Points": 20,
- "IsTekGram": false,
- "ClassName": "EngramEntry_EmptyCryopod_C",
- "Description": "Empty Cryopod",
- "Mod": "Extinction"
- },
{
"Level": 38,
"Points": 6,
@@ -479,13 +463,6 @@
}
],
"Items": [
- {
- "Category": "Saddles",
- "IsHarvestable": false,
- "ClassName": "PrimalItem_WeaponEmptyCryopod_C",
- "Description": "Empty Cryopod",
- "Mod": "Extinction"
- },
{
"Category": "Saddles",
"IsHarvestable": false,
@@ -846,15 +823,15 @@
{
"Category": "Spawner",
"IsHarvestable": false,
- "ClassName": "PrimalItem_Spawner_Mek_C",
- "Description": "Unassembled Mek",
+ "ClassName": "PrimalItem_Spawner_Enforcer_CityTerminal_C",
+ "Description": "Unassembled Enforcer CityTerminal",
"Mod": "Extinction"
},
{
- "Category": "Structure",
+ "Category": "Spawner",
"IsHarvestable": false,
- "ClassName": "PrimalItemStructure_CryoFridge_C",
- "Description": "Cryofridge",
+ "ClassName": "PrimalItem_Spawner_Mek_C",
+ "Description": "Unassembled Mek",
"Mod": "Extinction"
},
{
diff --git a/src/ARKServerManager/GameData/LostIsland.gamedata b/src/ARKServerManager/GameData/LostIsland.gamedata
new file mode 100644
index 00000000..7f8e2736
--- /dev/null
+++ b/src/ARKServerManager/GameData/LostIsland.gamedata
@@ -0,0 +1,13 @@
+{
+ "Application": "ark",
+ "Version": "1.0.0",
+ "Created": "2021-12-14T00:00:00.0000000Z",
+ "GameMaps": [
+ {
+ "IsSotF": false,
+ "ClassName": "LostIsland",
+ "Description": "Lost Island",
+ "Mod": "LostIsland"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/ARKServerManager/GameData/PrimitivePlus.gamedata b/src/ARKServerManager/GameData/PrimitivePlus.gamedata
index 75294eb7..92248bf2 100644
--- a/src/ARKServerManager/GameData/PrimitivePlus.gamedata
+++ b/src/ARKServerManager/GameData/PrimitivePlus.gamedata
@@ -3148,7 +3148,7 @@
"Mod": "PrimitivePlus"
}
],
- "Mods": [
+ "TotalConversions": [
{
"IsSotF": false,
"ClassName": "111111111",
diff --git a/src/ARKServerManager/GameData/Ragnarok.gamedata b/src/ARKServerManager/GameData/Ragnarok.gamedata
index dbb636db..0f42a90f 100644
--- a/src/ARKServerManager/GameData/Ragnarok.gamedata
+++ b/src/ARKServerManager/GameData/Ragnarok.gamedata
@@ -249,6 +249,38 @@
"Mod": "Ragnarok"
}
],
+ "Inventories": [
+ {
+ "ClassName": "DinoDropInventoryComponent_BossDragon_Easy_Ragnarok_C",
+ "Description": "Boss Inventory - Dragon (Easy)",
+ "Mod": "Ragnarok"
+ },
+ {
+ "ClassName": "DinoDropInventoryComponent_BossDragon_Medium_Ragnarok_C",
+ "Description": "Boss Inventory - Dragon (Medium)",
+ "Mod": "Ragnarok"
+ },
+ {
+ "ClassName": "DinoDropInventoryComponent_BossDragon_Hard_Ragnarok_C",
+ "Description": "Boss Inventory - Dragon (Hard)",
+ "Mod": "Ragnarok"
+ },
+ {
+ "ClassName": "DinoDropInventoryComponent_BossManticore_Easy_Ragnarok_C",
+ "Description": "Boss Inventory - Manticore (Easy)",
+ "Mod": "Ragnarok"
+ },
+ {
+ "ClassName": "DinoDropInventoryComponent_BossManticore_Medium_Ragnarok_C",
+ "Description": "Boss Inventory - Manticore (Medium)",
+ "Mod": "Ragnarok"
+ },
+ {
+ "ClassName": "DinoDropInventoryComponent_BossManticore_Hard_Ragnarok_C",
+ "Description": "Boss Inventory - Manticore (Hard)",
+ "Mod": "Ragnarok"
+ }
+ ],
"GameMaps": [
{
"IsSotF": false,
diff --git a/src/ARKServerManager/GameData/ScorchedEarth.gamedata b/src/ARKServerManager/GameData/ScorchedEarth.gamedata
index 787bcb30..f53eb7aa 100644
--- a/src/ARKServerManager/GameData/ScorchedEarth.gamedata
+++ b/src/ARKServerManager/GameData/ScorchedEarth.gamedata
@@ -35,14 +35,6 @@
"Description": "Oil Jug Bug",
"Mod": "ScorchedEarth"
},
- {
- "NameTag": "Manticore",
- "IsSpawnable": false,
- "IsTameable": "False",
- "ClassName": "Manticore_Character_BP_C",
- "Description": "Manticore",
- "Mod": "ScorchedEarth"
- },
{
"NameTag": "Mantis",
"IsSpawnable": true,
diff --git a/src/ARKServerManager/GameData/SurvivalEvolved.gamedata b/src/ARKServerManager/GameData/SurvivalEvolved.gamedata
index 09725617..55d5a720 100644
--- a/src/ARKServerManager/GameData/SurvivalEvolved.gamedata
+++ b/src/ARKServerManager/GameData/SurvivalEvolved.gamedata
@@ -1,7 +1,7 @@
{
"Application": "ark",
- "Version": "1.7.2",
- "Created": "2020-12-03T00:00:00.0000000Z",
+ "Version": "1.7.3",
+ "Created": "2021-08-23T00:00:00.0000000Z",
"Creatures": [
{
"NameTag": "Achatina",
@@ -4301,6 +4301,14 @@
"Description": "Wooden Window",
"Mod": "ArkPrime"
},
+ {
+ "Level": 0,
+ "Points": 0,
+ "IsTekGram": true,
+ "ClassName": "EngramEntry_TekATV_C",
+ "Description": "Tek ATV",
+ "Mod": "ArkPrime"
+ },
{
"Level": 0,
"Points": 0,
@@ -6848,6 +6856,13 @@
"Description": "Yutyrannus Saddle",
"Mod": "ArkPrime"
},
+ {
+ "Category": "Artifacts",
+ "IsHarvestable": false,
+ "ClassName": "PrimalItemArtifactGeneric_C",
+ "Description": "Artifact Universal",
+ "Mod": "ArkPrime"
+ },
{
"Category": "Artifacts",
"IsHarvestable": false,
@@ -7604,6 +7619,48 @@
"Description": "Bio Toxin",
"Mod": "ArkPrime"
},
+ {
+ "Category": "Consumables",
+ "IsHarvestable": false,
+ "ClassName": "PrimalItemConsumable_Kibble_Base_XSmall_C",
+ "Description": "Kibble (Basic)",
+ "Mod": "ArkPrime"
+ },
+ {
+ "Category": "Consumables",
+ "IsHarvestable": false,
+ "ClassName": "PrimalItemConsumable_Kibble_Base_Small_C",
+ "Description": "Kibble (Simple)",
+ "Mod": "ArkPrime"
+ },
+ {
+ "Category": "Consumables",
+ "IsHarvestable": false,
+ "ClassName": "PrimalItemConsumable_Kibble_Base_Medium_C",
+ "Description": "Kibble (Regular)",
+ "Mod": "ArkPrime"
+ },
+ {
+ "Category": "Consumables",
+ "IsHarvestable": false,
+ "ClassName": "PrimalItemConsumable_Kibble_Base_Large_C",
+ "Description": "Kibble (Superior)",
+ "Mod": "ArkPrime"
+ },
+ {
+ "Category": "Consumables",
+ "IsHarvestable": false,
+ "ClassName": "PrimalItemConsumable_Kibble_Base_XLarge_C",
+ "Description": "Kibble (Exceptional)",
+ "Mod": "ArkPrime"
+ },
+ {
+ "Category": "Consumables",
+ "IsHarvestable": false,
+ "ClassName": "PrimalItemConsumable_Kibble_Base_Special_C",
+ "Description": "Kibble (Extraordinary)",
+ "Mod": "ArkPrime"
+ },
{
"Category": "Consumables",
"IsHarvestable": false,
diff --git a/src/ARKServerManager/GameData/Valguero.gamedata b/src/ARKServerManager/GameData/Valguero.gamedata
index ee0cd176..a1eb3e71 100644
--- a/src/ARKServerManager/GameData/Valguero.gamedata
+++ b/src/ARKServerManager/GameData/Valguero.gamedata
@@ -306,6 +306,53 @@
"Mod": "Valguero"
}
],
+ "Inventories": [
+ {
+ "ClassName": "DinoDropInventoryComponent_BossDragon_Easy_Valguero_C",
+ "Description": "Boss Inventory - Dragon (Easy)",
+ "Mod": "Valguero"
+ },
+ {
+ "ClassName": "DinoDropInventoryComponent_BossDragon_Medium_Valguero_C",
+ "Description": "Boss Inventory - Dragon (Medium)",
+ "Mod": "Valguero"
+ },
+ {
+ "ClassName": "DinoDropInventoryComponent_BossDragon_Hard_Valguero_C",
+ "Description": "Boss Inventory - Dragon (Hard)",
+ "Mod": "Valguero"
+ },
+ {
+ "ClassName": "DinoDropInventoryComponent_BossManticore_Easy_Valguero_C",
+ "Description": "Boss Inventory - Manticore (Easy)",
+ "Mod": "Valguero"
+ },
+ {
+ "ClassName": "DinoDropInventoryComponent_BossManticore_Medium_Valguero_C",
+ "Description": "Boss Inventory - Manticore (Medium)",
+ "Mod": "Valguero"
+ },
+ {
+ "ClassName": "DinoDropInventoryComponent_BossManticore_Hard_Valguero_C",
+ "Description": "Boss Inventory - Manticore (Hard)",
+ "Mod": "Valguero"
+ },
+ {
+ "ClassName": "DinoDropInventoryComponent_BossGorilla_Easy_Valguero_C",
+ "Description": "Boss Inventory - Megapithecus (Easy)",
+ "Mod": "Valguero"
+ },
+ {
+ "ClassName": "DinoDropInventoryComponent_BossGorilla_Medium_Valguero_C",
+ "Description": "Boss Inventory - Megapithecus (Medium)",
+ "Mod": "Valguero"
+ },
+ {
+ "ClassName": "DinoDropInventoryComponent_BossGorilla_Hard_Valguero_C",
+ "Description": "Boss Inventory - Megapithecus (Hard)",
+ "Mod": "Valguero"
+ }
+ ],
"GameMaps": [
{
"IsSotF": false,
diff --git a/src/ARKServerManager/Globalization/de-DE/de-DE.xaml b/src/ARKServerManager/Globalization/de-DE/de-DE.xaml
index e31fd211..c265f2ea 100644
--- a/src/ARKServerManager/Globalization/de-DE/de-DE.xaml
+++ b/src/ARKServerManager/Globalization/de-DE/de-DE.xaml
@@ -13,7 +13,34 @@
Fehler
-
+
+ The Island
+ The Center
+ Scorched Earth
+ Ragnarok
+ Aberration
+ Extinction
+ Valguero
+ Genesis
+
+
+
+ Primitive Plus
+
+
+
+ Live
+
+
+
+ Valentines Day
+ Easter
+ Fear Evolved (Halloween)
+ Turkey Trial
+ Winter Wonderland
+
+
+
Alle
Unbekannt
ARK Prime
@@ -65,8 +92,8 @@
Wähle ein Datenverzeichnis
Bestätige Auswahl
Der Server Manager speichert Profile und SteamCMD in den folgenden Verzeichnissen:\r\n\r\nProfile: {0}\r\nSteamCMD: {1}\r\n\r\nIst das in Ordnung?
- Fehler bei Auswahl des Datenverzeichnisses
- Das von Dir ausgewählte Verzeichnis befindet sich im Installationsordner des Server-Managers. Dies wird nicht empfohlen, bitte wähle einen anderen Ordner.
+ Fehler bei Auswahl des Datenverzeichnisses
+ Das von Dir ausgewählte Verzeichnis befindet sich im Installationsordner des Server-Managers. Dies wird nicht empfohlen, bitte wähle einen anderen Ordner.
Profil konnte nicht gespeichert werden
Profil konnte nicht gespeichert werden {0}. {1}\n{2}
@@ -2268,10 +2295,10 @@
Zeige Steam Profil...
Zeige Profil...
Zeige Stamm...
- Kokpiere ID...
+ Kopiere ID...
Kopiere Spieler ID...
- Adminname:
+ Admin Name:
Dies ist der Name, mit dem Serverchat-Nachrichten vorangestellt werden, die von der Konsole gesendet werden.
Status:
Spieler:
@@ -2282,7 +2309,7 @@
OK
Abbrechen
- Aendern
+ Ändern
Senden
RCON: {0}
@@ -2380,33 +2407,6 @@
Einstellungen
-
- The Island
- The Center
- Scorched Earth
- Ragnarok
- Aberration
- Extinction
- Valguero
- Genesis
-
-
-
- Primitive Plus
-
-
-
- Live
-
-
-
- Valentines Day
- Easter
- Fear Evolved (Halloween)
- Turkey Trial
- Winter Wonderland
-
-
@@ -4035,7 +4035,7 @@
Elektronik
Element
Element (Hergestellt)
- Element Fragment
+ Elementarsplitter
Faser
Feuerstein
Benzin
@@ -4086,7 +4086,7 @@
Dino Bunny Ears Skin
Dino Easter Chick Hat
Cute Dino Helmet Skin
- Dino Easter Egg Hat
+ Dino Easter Ei Hat
Dino Party Hat Skin
Dino Santa Hat Skin
Dino Glasses
@@ -4094,7 +4094,7 @@
DodoRex Mask Skin
DodoWyvern Mask Skin
Easter Chick Hat
- Easter Egg Hat
+ Easter Ei Hat
Safari Hat Skin
Fireworks Flaregun Skin
Nerdry Glasses
@@ -4142,7 +4142,7 @@
Large Crop Plot
Medium Crop Plot
Small Crop Plot
- Bunny Egg
+ Bunny Ei
Large Elevator Platform
Small Elevator Platform
Medium Elevator Platform
@@ -4392,19 +4392,19 @@
ARK Thorny Dragon Saddle Skin
Thorny Dragon Saddle
Cactus Sap
- Camelsaurus Egg
- Mantis Egg
- Moth Egg
- Thorny Dragon Egg
- Vulture Egg
- Kibble (Camelsaurus Egg)
- Kibble (Mantis Egg)
- Kibble (Moth Egg)
- Kibble (Thorny Dragon Egg)
- Kibble (Vulture Egg)
- Wyvern Egg Fire
- Wyvern Egg Lightning
- Wyvern Egg Poison
+ Camelsaurus Ei
+ Mantis Ei
+ Moth Ei
+ Thorny Dragon Ei
+ Vulture Ei
+ Kibble (Camelsaurus Ei)
+ Kibble (Mantis Ei)
+ Kibble (Moth Ei)
+ Kibble (Thorny Dragon Ei)
+ Kibble (Vulture Ei)
+ Wyvern Ei Fire
+ Wyvern Ei Lightning
+ Wyvern Ei Poison
Plant Species Y Seed
Fire Talon
Lightning Talon
@@ -4748,13 +4748,13 @@
Rock Drake Saddle
Tek Rock Drake Saddle
Zip-Line Motor Attachment
- Basilisk Egg
- Featherlight Egg
- Glowtail Egg
- Rock Drake Egg
- Kibble (Featherlight Egg)
- Kibble (Glowtail Egg)
- Kibble (Rock Drake Egg)
+ Basilisk Ei
+ Featherlight Ei
+ Glowtail Ei
+ Rock Drake Ei
+ Kibble (Featherlight Ei)
+ Kibble (Glowtail Ei)
+ Kibble (Rock Drake Ei)
Aquatic Mushroom
Ascerbic Mushroom
Auric Mushroom
@@ -4792,7 +4792,7 @@
- Empty Cryopod
+ Leere Kryokapsel
Taxidermy Tool
Tek Gravity Grenade
Cannon Shell
@@ -4813,8 +4813,8 @@
Artifact of Growth
Artifact of the Void
Gasbags bladder
- Snow Owl Egg
- Velonasaur Egg
+ Snow Owl Ei
+ Velonasaur Ei
Gacha Crystal
Superior Augmented Kibble
Regular Augmented Kibble
@@ -4827,16 +4827,16 @@
Condensed Gas
Corrupted Nodule
Corrupted Wood
- Element Dust
- Crafted Element Dust (Element)
- Crafted Element Dust (Element Shard)
- Unstable Element
+ Element Staub
+ Hergestellter Elementstaub (Element)
+ Hergestellter Elementstaub (Elementarsplitter)
+ Instabiles Element
Fragmented Green Gem
Corrupt Heart
Red Crystalized Sap
Scrap Metal
Scrap Metal Ingot
- Unstable Element Shard
+ Instabiler Elementarsplitter
Silicate
HomoDeus Boots
HomoDeus Gloves
@@ -4982,35 +4982,35 @@
Wyvern
WyvernTrench
- Deepwater
- InlandWater
- Ocean
- TheDeepwater
- TheOcean
- Beach
- Grassland
- Jungle
- Mountain
- Snow
- SnowMountain
- SnowShoreline
- Swamp
+ Tiefsee
+ Inland-Wasser
+ Ozean
+ DieTiefsee
+ DerOzean
+ Strand
+ Grasland
+ Dschungel
+ Berg
+ Schnee
+ SchneeBerg
+ SchneeKüstenlinie
+ Sumpf
Redwoods
- Bear
- Castle
- Center
- CenterWater
+ Bär
+ Burg
+ Mitte
+ ZentrumWasser
Golem
Griffin
Iceworm
Jerboa
MonkeyIsland
Mudslide
- PolarBear
- Scotland
- SnowForest
- SnowPlains
+ PolarBär
+ Schottland
+ SchneeWald
+ SchneeGebiete
Basilisks
BioLumCave
@@ -5075,32 +5075,32 @@
- Cave Loot Crate (Green)
- Cave Loot Crate (Blue)
- Cave Loot Crate (Yellow)
- Cave Loot Crate (Red)
- Ice Cave Loot Crate (Blue)
- Ice Cave Loot Crate (Yellow)
- Ice Cave Loot Crate (Red)
- Deep Sea Loot Crate
- Swamp Cave Loot Crate (Blue)
- Swamp Cave Loot Crate (Yellow)
- Swamp Cave Loot Crate (Red)
- Underwater Cave Loot Crate (Blue)
- Underwater Cave Loot Crate (Yellow)
- Underwater Cave Loot Crate (Red)
- White Beacon
- White Beacon (Double items)
- Green Beacon
- Green Beacon (Double items)
- Blue Beacon
- Blue Beacon (Double items)
- Purple Beacon
- Purple Beacon (Double items)
- Yellow Beacon
- Yellow Beacon (Double items)
- Red Beacon
- Red Beacon (Double items)
+ Höhlen Beutekiste (Grün)
+ Höhlen Beutekiste (Blau)
+ Höhlen Beutekiste (Gelb)
+ Höhlen Beutekiste (Rot)
+ Eis Höhlen Beutekiste (Blau)
+ Eis Höhlen Beutekiste (Gelb)
+ Eis Höhlen Beutekiste (Rot)
+ Tiefsee Beutekiste
+ Sumpf Höhlen Beutekiste (Blau)
+ Sumpf Höhlen Beutekiste (Gelb)
+ Sumpf Höhlen Beutekiste (Rot)
+ Unterwasser Höhlen Beutekiste (Blau)
+ Unterwasser Höhlen Beutekiste (Gelb)
+ Unterwasser Höhlen Beutekiste (Rot)
+ Weißer Beacon
+ Weißer Beacon (Doppelte Gegenstände)
+ Grüner Beacon
+ Grüner Beacon (Doppelte Gegenstände)
+ Blauer Beacon
+ Blauer Beacon (Doppelte Gegenstände)
+ Lila Beacon
+ Lila Beacon (Doppelte Gegenstände)
+ Gelbe Beacon
+ Gelbe Beacon (Doppelte Gegenstände)
+ Rote Beacon
+ Rote Beacon (Doppelte Gegenstände)
Artifact Container Hunter
Artifact Container Pack
Artifact Container Massive
@@ -5113,57 +5113,57 @@
Artifact Container Cunning
Artifact Container Brute
- Cave Loot Crate 1
- Cave Loot Crate 2
- Cave Loot Crate 3
- White Beacon
- White Beacon (Double items)
- Green Beacon
- Green Beacon (Double items)
- Blue Beacon
- Blue Beacon (Double items)
- Purple Beacon
- Purple Beacon (Double items)
- Yellow Beacon
- Yellow Beacon (Double items)
- Red Beacon
- Red Beacon (Double items)
+ Höhlen Beutekiste 1
+ Höhlen Beutekiste 2
+ Höhlen Beutekiste 3
+ Weißer Beacon
+ Weißer Beacon (Doppelte Gegenstände)
+ Grüner Beacon
+ Grüner Beacon (Doppelte Gegenstände)
+ Blauer Beacon
+ Blauer Beacon (Doppelte Gegenstände)
+ Lila Beacon
+ Lila Beacon (Doppelte Gegenstände)
+ Gelbe Beacon
+ Gelbe Beacon (Doppelte Gegenstände)
+ Rote Beacon
+ Rote Beacon (Doppelte Gegenstände)
Artifact Container Destroyer
Artifact Container Gatekeeper
Artifact Container Crag
- White Beacon
- White Beacon (Double items)
- Green Beacon
- Green Beacon (Double items)
- Blue Beacon
- Blue Beacon (Double items)
- Purple Beacon
- Purple Beacon (Double items)
- Yellow Beacon
- Yellow Beacon (Double items)
- Red Beacon
- Red Beacon (Double items)
- Dungeon Loot Crate (Blue)
- Dungeon Loot Crate (Purple)
- Dungeon Loot Crate (Yellow)
- Dungeon Loot Crate (Red)
- Surface Blue Beacon
- Surface Blue Beacon (Double items)
- Surface Purple Beacon
- Surface Purple Beacon (Double items)
- Surface Yellow Beacon
- Surface Yellow Beacon (Double items)
- Surface Red Beacon
- Surface Red Beacon (Double items)
+ Weißer Beacon
+ Weißer Beacon (Doppelte Gegenstände)
+ Grüner Beacon
+ Grüner Beacon (Doppelte Gegenstände)
+ Blauer Beacon
+ Blauer Beacon (Doppelte Gegenstände)
+ Lila Beacon
+ Lila Beacon (Doppelte Gegenstände)
+ Gelbe Beacon
+ Gelbe Beacon (Doppelte Gegenstände)
+ Rote Beacon
+ Rote Beacon (Doppelte Gegenstände)
+ Dungeon Beutekiste (Blau)
+ Dungeon Beutekiste (Lila)
+ Dungeon Beutekiste (Gelb)
+ Dungeon Beutekiste (Rot)
+ Surface Blauer Beacon
+ Surface Blauer Beacon (Doppelte Gegenstände)
+ Surface Lila Beacon
+ Surface Lila Beacon (Doppelte Gegenstände)
+ Surface Gelbe Beacon
+ Surface Gelbe Beacon (Doppelte Gegenstände)
+ Surface Rote Beacon
+ Surface Rote Beacon (Doppelte Gegenstände)
Artifact Container Depths
Artifact Container Shadows
Artifact Container Stalker
Artifact Container Lost
- Cave Loot Crate (Blue)
- Cave Loot Crate (Yellow)
- Cave Loot Crate (Red)
+ Höhlen Beutekiste (Blau)
+ Höhlen Beutekiste (Gelb)
+ Höhlen Beutekiste (Rot)
Artifact Container Chaos
Artifact Container Growth
Artifact Container Void
@@ -5175,102 +5175,102 @@
- Boss Inventory - Broodmother (Easy)
- Boss Inventory - Broodmother (Medium)
- Boss Inventory - Broodmother (Hard)
- Boss Inventory - Megapithecus (Easy)
- Boss Inventory - Megapithecus (Medium)
- Boss Inventory - Megapithecus (Hard)
- Boss Inventory - Dragon (Easy)
- Boss Inventory - Dragon (Medium)
- Boss Inventory - Dragon (Hard)
- Boss Inventory - End Boss Minion
+ Boss Inventar - Brutmutter (Leicht)
+ Boss Inventar - Brutmutter (Medium)
+ Boss Inventar - Brutmutter (Hart)
+ Boss Inventar - Megapithecus (Leicht)
+ Boss Inventar - Megapithecus (Medium)
+ Boss Inventar - Megapithecus (Hart)
+ Boss Inventar - Dragon (Leicht)
+ Boss Inventar - Dragon (Medium)
+ Boss Inventar - Dragon (Hart)
+ Boss Inventar - End Boss Minion
- Boss Inventory - Manticore (Easy)
- Boss Inventory - Manticore (Medium)
- Boss Inventory - Manticore (Hard)
+ Boss Inventar - Manticore (Leicht)
+ Boss Inventar - Manticore (Medium)
+ Boss Inventar - Manticore (Hart)
- Boss Inventory - Broodmother (Easy)
- Boss Inventory - Broodmother (Medium)
- Boss Inventory - Broodmother (Hard)
- Boss Inventory - Megapithecus (Easy)
- Boss Inventory - Megapithecus (Medium)
- Boss Inventory - Megapithecus (Hard)
+ Boss Inventar - Brutmutter (Leicht)
+ Boss Inventar - Brutmutter (Medium)
+ Boss Inventar - Brutmutter (Hart)
+ Boss Inventar - Megapithecus (Leicht)
+ Boss Inventar - Megapithecus (Medium)
+ Boss Inventar - Megapithecus (Hart)
- Boss Inventory - Titan
- Boss Inventory - Desert Titan
- Boss Inventory - Forest Titan
- Boss Inventory - Ice Titan
+ Boss Inventar - Titan
+ Boss Inventar - Desert Titan
+ Boss Inventar - Forest Titan
+ Boss Inventar - Ice Titan
- Profile Validation
- The following validation problems were encountered.\r\n\r\n{validateMessage}\r\n\r\nDo you want to continue with the server start, this could cause problems?
+ Profil Validierung
+ Die folgenden Validierungsprobleme sind aufgetreten.\r\n\r\n{validateMessage}\r\n\r\nMöchten Sie mit dem Serverstart fortfahren, da dies zu Problemen führen könnte?
- The server port is outside the valid range ({PortMinimum}-{PortMaximum}).
- The query port is outside the valid range ({PortMinimum}-{PortMaximum}).
- The rcon port is outside the valid range ({PortMinimum}-{PortMaximum}).
+ Der Server-Port liegt außerhalb des gültigen Bereichs ({PortMinimum}-{PortMaximum}).
+ Der Query Port liegt außerhalb des gültigen Bereichs ({PortMinimum}-{PortMaximum}).
+ Der RCON Port liegt außerhalb des gültigen Bereichs ({PortMinimum}-{PortMaximum}).
- The map name has not been entered.
+ Der Name der Karte ist nicht angegeben worden.
- Server files have not been downloaded, server folder does not exist.
- Server files have not been downloaded properly, server executable file ({ServerExe}) does not exist.
- The server files are for a different application.
+ Die Server Dateien wurden nicht heruntergeladen, der Server Ordner existiert nicht.
+ Die Server Dateien wurden nicht richtig heruntergeladen, die ausführbare Serverdatei ({ServerExe}) existiert nicht.
+ Die Server Dateien sind für eine andere Anwendung.
- Map mod has not been downloaded, mod folder does not exist.
- Map mod has not been downloaded properly, mod file does not exist.
- The map mod is not a valid map mod.
- Map mod has not been downloaded properly, mod file is invalid.
- Map mod file does not exist or is invalid.
- The map name does not match the map mod's map name.
- The map mod is for a different application.
- The map mod is outdated.
- The map mod details could not be retrieved from steam.
+ Die Map Mod wurde nicht heruntergeladen, der Mod Ordner existiert nicht.
+ Die Map Mod wurde nicht richtig heruntergeladen, die Mod Datei existiert nicht.
+ Die Map Mod ist keine gültige Map Mod.
+ Die Map Mod wurde nicht richtig heruntergeladen, die Mod Datei ist ungültig.
+ Die Map Mod Datei existiert nicht oder ist ungültig.
+ Der Map Name stimmt nicht mit dem Map Namen der Map Mod überein.
+ Die Map Mod ist für eine andere Anwendung gedacht.
+ Die Map Mod ist veraltet.
+ Die Map Mod Details konnten nicht von Steam abgerufen werden.
- Total conversion mod has not been downloaded, mod folder does not exist.
- Total conversion mod has not been downloaded properly, mod file does not exist.
- The total conversion mod is not a valid total conversion mod.
- Total conversion mod has not been downloaded properly, mod file is invalid.
- Total conversion mod file does not exist or is invalid.
- The map name does not match the total conversion mod's map name.
- The total conversion mod is for a different application.
- The total conversion mod is outdated.
- The total conversion mod details could not be retrieved from steam.
+ Total Conversion Mod wurde nicht heruntergeladen, Mod Ordner existiert nicht.
+ Der Total Conversion Mod wurde nicht richtig heruntergeladen, die Mod Datei existiert nicht.
+ Die Total Conversion Mod ist keine gültige Total Conversion Mod.
+ Die Total Conversion Mod wurde nicht richtig heruntergeladen, die Mod Datei ist ungültig.
+ Die Datei Total Conversion Mod existiert nicht oder ist ungültig.
+ Der Name der Map stimmt nicht mit dem Namen der Map der Total Conversion Mod überein.
+ Der Total Conversion Mod ist für eine andere Anwendung gedacht.
+ Die Total Conversion Mod ist veraltet.
+ Die Details der Total Conversion Mod konnten nicht über Steam abgerufen werden.
- Mod {modId} has not been downloaded, mod folder does not exist.
- Mod {modId} has not been downloaded properly, mod file does not exist.
- Mod {modId} is for a different application.
- Mod {modId} is outdated.
- Mod {modId} details could not be retrieved from steam.
+ Mod {modId} wurde nicht heruntergeladen, der Mod Ordner existiert nicht.
+ Mod {modId} wurde nicht richtig heruntergeladen, Mod Datei existiert nicht.
+ Mod {modId} ist für eine andere Anwendung bestimmt.
+ Mod {modId} ist veraltet.
+ Mod {modId} Details konnten nicht von Steam abgerufen werden.
- Saving...
- Checking Player and Dino Max XP...
- Constructing Dino Information...
- Constructing Engram Information...
- Constructing Map Spawner Information...
- Constructing Supply Crate Information...
- Constructing Stack Size Information...
- Saving Profile File...
- Saving Config Files...
- Saving Launcher File...
- Checking Web Alarm File...
- Checking Directory Permissions...
- Checking Scheduled Tasks...
+ Speichere...
+ Spieler und Dino Max XP prüfen...
+ Erstellen von Dino Informationen...
+ Erstellen von Engramm Informationen...
+ Erstellung von Map Spawner Informationen...
+ Informationen zum Bau von Versorgungskisten...
+ Stack Size Informationen erstellen....
+ Speichere Profile Datei...
+ Speichere Config Dateien...
+ Speichere Launcher Datei...
+ Prüfe Web Alarm Datei...
+ Prüfen von Verzeichnisberechtigungen...
+ Geplante Aufgaben prüfen...
- Backup file could not be found or does not exist.
- The server save folder could not be found or does not exist.\r\n{saveFolder}
- The backup does not contain the world save file.
+ Die Sicherungsdatei konnte nicht gefunden werden oder existiert nicht.
+ Der Server-Speicherordner konnte nicht gefunden werden oder existiert nicht.\r\n{saveFolder}
+ Die Sicherung enthält nicht die Welt-Sicherungsdatei.
Server Update
- There was a problem while performing the server update. This may leave your server in a incomplete state.\r\n\r\nDo you want to continue with the server start, this could cause problems?
+ Bei der Durchführung des Server-Updates ist ein Problem aufgetreten. Dies kann dazu führen, dass sich Ihr Server in einem inkompletten Zustand befindet.\r\n\r\nMöchten Sie mit dem Serverstart fortfahren, da dies zu Problemen führen könnte?
\ No newline at end of file
diff --git a/src/ARKServerManager/Globalization/en-US/en-US.xaml b/src/ARKServerManager/Globalization/en-US/en-US.xaml
index b733ae53..c59fab28 100644
--- a/src/ARKServerManager/Globalization/en-US/en-US.xaml
+++ b/src/ARKServerManager/Globalization/en-US/en-US.xaml
@@ -13,7 +13,38 @@
Error
-
+
+ The Island
+ The Center
+ Scorched Earth
+ Ragnarok
+ Aberration
+ Extinction
+ Valguero
+ Genesis: Part 1
+ Crystal Isles
+ Genesis: Part 2
+ Lost Island
+
+
+
+ Primitive Plus
+
+
+
+ Live
+
+
+
+ None
+ Valentines Day
+ Easter
+ Fear Evolved (Halloween)
+ Turkey Trial
+ Winter Wonderland
+
+
+
All
Unknown
ARK Prime
@@ -26,6 +57,7 @@
Genesis: Part 1
Crystal Isles
Genesis: Part 2
+ Lost Island
PGM
@@ -51,6 +83,12 @@
All
+
+ Normal
+ Minimized
+ Maximized
+
+
Run as Administrator
This application requires administration priviledges to access ALL functionality. Would you like to Run as Administrator?
@@ -66,8 +104,9 @@
Select a Data Directory
Confirm location
The server manager will store profiles and SteamCMD in the following directories:\r\n\r\nProfiles: {0}\r\nSteamCMD: {1}\r\n\r\nIs this ok?
- Data Directory Selection Error
- The directory you have chosen is within the server manager installation folder. This is not recommended, please choose another folder.
+ Data Directory Selection Error
+ The directory you have chosen is within the server manager installation folder. This is not recommended, please choose another folder.
+ The directory you have chosen is on the desktop. This is not recommended, please choose another folder.
Failed to save profile
Failed to save profile {0}. {1}\n{2}
@@ -128,6 +167,25 @@
Processor
+
+ Data Folder Selection
+ It appears you do not have a data directory set. The data directory is where your profiles and SteamCMD will be stored. It is not the same as the server installation directory, which you can choose for each profile.
+ Select the drive where the data folder should be located.
+ Data Folder Name:
+ The name of the server manager data folder.
+ Local Disk
+ {0} free of {1}
+
+ Ok
+ Cancel
+ Refresh
+
+ Data Directory Selection Error
+ The data folder name you have entered is not valid.
+ Server Manager Restart Required
+ The data folder has been set, you must now restart the server manager to use the new settings.
+
+
Close
@@ -421,6 +479,7 @@
Reset
This will reset ALL the user global settings for the server manager. The server manager will be closed if successful.
Enable Run as Administrator Prompt on Startup
+ Main Window Start Mode:
Minimize To Tray
Manage firewall settings automatically
Manage Public IP automatically
@@ -553,7 +612,24 @@
This message will be displayed when the server shutdown has been cancelled.
Show shutdown reason with ALL shutdown messages
If enabled, the shutdown reason will be shown with all shutdown message; otherwise it will only be shown at the start of the server shutdown.
-
+
+ Enable Discord Bot
+ You will need to restart the server manager if you change any settings for the Discord Bot.
+ Token:
+ The token associated with the discord bot.
+ Server Id:
+ The id of the discord server the bot will listen to.
+ Prefix:
+ The prefix that must be used when sending a command via discord.
+ Get Token...
+ Help...
+ If enabled, the backup command can be sent from discord.
+ If enabled, the restart command can be sent from discord.
+ If enabled, the shutdown command can be sent from discord.
+ If enabled, the start command can be sent from discord.
+ If enabled, the stop command can be sent from discord.
+ If enabled, the update command can be sent from discord.
+
SMTP Email Settings
Host:
The name or IP address of the host used for SMTP transmissions.
@@ -605,6 +681,8 @@
Changing the data directory will move any existing profiles to the new location, but it will not move any server installations. Do you still want to change this directory?
Failed to change data directory
There was an error changing the data directory: {0}\r\nPlease correct the error and try again, or contact technical support for assistance.
+ Confirm Data Directory Reset
+ Click 'Yes' to confirm you want to reset the location of the data directory. Once reset, the server manager will shutdown and you will need to restart.
Select Backup Directory
Select Cache Directory
@@ -718,6 +796,9 @@
Reinstall SteamCMD Error
An error occured while trying to reinstall SteamCMD. This has left SteamCmd in an unstable state, try reinstalling again or please report this.\r\nException: {0}
+ Discord Bot Running Commands
+ The discord bot has one or more running commands, do you want to continue shutting down the server manager?
+
Start Server Confirmation
You are about to start the server, do you want to continue?
Shutdown Server Confirmation
@@ -756,6 +837,8 @@
+ Profile ID:
+ The unique ID assigned to the profile.
Profile:
The name for the server profile. This is not the public name users will see in Ark. For that, set the 'Server Name' field.
Installed Version:
@@ -1120,12 +1203,32 @@
If enabled, the server will be restarted even if shutdown for Auto-Restarts and Auto-Updates.
+
+ Discord Bot Details
+ Channel Id:
+ The id of the discord server channel this profile will listen to.
+ Allow Backup
+ If enabled, the profile will listen for backup commands from discord.
+ Allow Restart
+ If enabled, the profile will listen for restart commands from discord.
+ Allow Shutdown
+ If enabled, the profile will listen for shutdown commands from discord.
+ Allow Start
+ If enabled, the profile will listen for start commands from discord.
+ Allow Stop
+ If enabled, the profile will listen for stop commands from discord.
+ Allow Update
+ If enabled, the profile will listen for update commands from discord.
+
+
Rules
Enable Hardcore Mode
Enables hardcore mode (players can not respawn, a new character must be created).
Enable PvP
Enables Player vs Player mode (players are able to deal damage to or kill each other. In PvP players can also damage or destroy another tribe's buildings or kill their dinos).
+ Enable Creative Mode
+ If enabled, allows creative mode.
Enable PvE Cave Building
If enabled, allows building in caves when PvE mode is enabled.
Enable PvE Cryo Sickness
@@ -1161,7 +1264,9 @@
Determines the maximum levels of creatures in the world. The higher the value, the higher the Maximum Creature Level.
Difficulty Offset:
Determines the maximum levels of creatures in the world. The higher the value, the higher the Maximum Creature Level.
-
+ Destroy Tames Over Level:
+ Tames that exceed this level will be deleted on server start. To disable deletion set to 0.
+
Enable Tribute Downloads
If enabled, this will allow downloading external survivors/items/dinos into your server.
No Survivor Downloads
@@ -1535,14 +1640,18 @@
Per-Level Stat Multipliers (Tamed) - Add
Per-Level Stat Multipliers (Tamed) - Affinity
Per-Level Stat Multipliers (Wild)
+ Mutagen Level Boost (Wild)
+ Mutagen Level Boost (Bred)
Dino Breeding Multipliers
If enabled, allows scale factors to be applied to each base stat.
If enabled, allows scale factors to be applied to each stat.
If enabled, allows scale factors to be applied to the Taming Addition for each stat.
If enabled, allows scale factors to be applied to the Taming Multiplier for each stat.
If enabled, allows scale factors to be applied to the Tamed Stat Increase for each stat.
- Reset all multipliers back to defaults.
- Reset all multipliers back to defaults.
+ If enabled, allows scale factors to be applied to the Number of levels Mutagen adds to tames with wild ancestry.
+ If enabled, allows scale factors to be applied to the Number of levels Mutagen adds to tames with bred ancestry.
+ Reset all values back to defaults.
+ Reset all values back to defaults.
Mating Interval:
Specifies the multiplier for time between tamed dino mating. Lower values decrease the time between mating.
@@ -1663,8 +1772,8 @@
If enabled, structures in PvP will automatically decay if left unused after a period of time.
PvP Zone Structure Damage:
Specifies the scaling factor for the damage structures take within caves/cave entrances, in PvP.
- Max Structures Visible:
- The maximum number of structures which will be visible to the player. Lower values may help with server speed.
+ Max Structures in Range:
+ Specifies the maximum number of structures that can be constructed within a certain (currently hard-coded) range.
Per-Platform Structures Multiplier:
Specifies the scaling factor for the maximum number of structures allowed on a single platform/saddle/raft.
Max Platform Saddle Structures:
@@ -2462,36 +2571,6 @@
Settings
-
- The Island
- The Center
- Scorched Earth
- Ragnarok
- Aberration
- Extinction
- Valguero
- Genesis: Part 1
- Crystal Isles
- Genesis: Part 2
-
-
-
- Primitive Plus
-
-
-
- Live
-
-
-
- None
- Valentines Day
- Easter
- Fear Evolved (Halloween)
- Turkey Trial
- Winter Wonderland
-
-
@@ -3641,7 +3720,7 @@
Astrocetus Tek Saddle
- Tek Shoulder Cannon
+ Tek Claws
Tek Cruise Missile
Tek Grenade Launcher
Tek Hover Skiff
@@ -5490,4 +5569,32 @@
There was a problem while performing the server update. This may leave your server in a incomplete state.\r\n\r\nDo you want to continue with the server start, this could cause problems?
+
+ Discord Bot Error
+ The discord bot requires a valid token so it can log into the discord server\r\nThis can be set in the global settings.
+ The discord bot prefix contains invalid characters. Only letters and numbers are allowed.
+
+ Command '{0}' has not been enabled.
+ Unknown command '{0}'.
+ Another command is currently being processed.
+ Another command '{0}' is currently running against profile '{1}'.
+ Command '{0}' has been disabled for profile '{1}'.
+
+ The '{0}' command requires a profile id.
+ Profile '{0}' was not found or is not associated with the channel.
+ Profile '{0}' is in a state '{1}' that cannot run this command.
+ Profile '{0}' is currently being updated.
+
+ Call to server '{0}' failed.
+ A backup request for server '{0}' has been sent.
+ A restart request for server '{0}' has been sent.
+ A shutdown request for server '{0}' has been sent.
+ A start request for server '{0}' has been sent.
+ A stop request for server '{0}' has been sent.
+ An update request for server '{0}' has been sent.
+
+ Count:
+ Map:
+
+
\ No newline at end of file
diff --git a/src/ARKServerManager/Globalization/es-ES/es-ES.xaml b/src/ARKServerManager/Globalization/es-ES/es-ES.xaml
index 773b46d9..55223869 100644
--- a/src/ARKServerManager/Globalization/es-ES/es-ES.xaml
+++ b/src/ARKServerManager/Globalization/es-ES/es-ES.xaml
@@ -13,7 +13,35 @@
Error
-
+
+ The Island
+ The Center
+ Scorched Earth
+ Ragnarok
+ Aberración
+ Extinción
+ Valguero
+ Genesis
+
+
+
+ Primitive Plus
+
+
+
+ Pública
+
+
+
+ Ninguno
+ Love Evolved (San Valentín)
+ Eggcellent Adventure (Pascua)
+ Fear Evolved (Halloween)
+ Turkey Trial (Acción de Gracias)
+ Winter Wonderland (Navidad)
+
+
+
Todos
Desconocido
ARK Prime
@@ -65,8 +93,8 @@
Seleccionar un directorio de datos
Confirmar ubicación
El gestor de servidores almacenará los perfiles y SteamCMD en los siguientes directorios:\r\n\r\nPerfiles: {0}\r\nSteamCMD: {1}\r\n\r\n¿Es correcto?
- Error de selección de directorio de datos
- El directorio que has elegido está en la carpeta de instalación del gestor de servidores, lo que no se recomienda. Por favor elige otra carpeta.
+ Error de selección de directorio de datos
+ El directorio que has elegido está en la carpeta de instalación del gestor de servidores, lo que no se recomienda. Por favor elige otra carpeta.
Fallo al guardar el perfil
Falló el guardado del perfil {0}. {1}\n{2}
@@ -2400,34 +2428,6 @@
Ajustes
-
- The Island
- The Center
- Scorched Earth
- Ragnarok
- Aberración
- Extinción
- Valguero
- Genesis
-
-
-
- Primitive Plus
-
-
-
- Pública
-
-
-
- Ninguno
- Love Evolved (San Valentín)
- Eggcellent Adventure (Pascua)
- Fear Evolved (Halloween)
- Turkey Trial (Acción de Gracias)
- Winter Wonderland (Navidad)
-
-
diff --git a/src/ARKServerManager/Globalization/fr-FR/fr-FR.xaml b/src/ARKServerManager/Globalization/fr-FR/fr-FR.xaml
index 9496a00a..89e0c5d0 100644
--- a/src/ARKServerManager/Globalization/fr-FR/fr-FR.xaml
+++ b/src/ARKServerManager/Globalization/fr-FR/fr-FR.xaml
@@ -13,7 +13,37 @@
Erreur
-
+
+ The Island
+ The Center
+ Scorched Earth
+ Ragnarok
+ Aberration
+ Extinction
+ Valguero
+ Genesis
+ Crystal Isles
+ Genesis: Part 2
+
+
+
+ Primitive Plus
+
+
+
+ Version Steam (Défaut)
+
+
+
+ Aucun
+ Saint-Valentin
+ Pâques
+ Fear Evolved (Halloween)
+ Turkey Trial
+ Winter Wonderland
+
+
+
All
Unknown
ARK Prime
@@ -25,6 +55,7 @@
Extinction
Genesis
Crystal Isles
+ Genesis: Part 2
PGM
@@ -50,6 +81,12 @@
Tout
+
+ Normal
+ Minimisé
+ Maximisé
+
+
Exécuter en tant qu'administrateur
Cette application nécessite des privilèges d'administrateur pour accéder à toutes les fonctionnalités. Souhaitez-vous exécuter en tant qu'administrateur?
@@ -65,8 +102,9 @@
Sélectionnez un répertoire de données
Confirmer l'emplacement
Ark Server Manager stockera les profils et SteamCMD dans les répertoires suivants:\r\n\r\n Profils:{0}\r\n SteamCMD:{1}\r\n\r\n Est-ce correct?
- Erreur de sélection du répertoire de données
- Le répertoire que vous avez choisi se trouve dans le dossier d'installation du gestionnaire du serveur. Ce n'est pas recommandé, veuillez choisir un autre dossier.
+ Erreur de sélection du répertoire de données
+ Le répertoire que vous avez choisi se trouve dans le dossier d'installation du gestionnaire du serveur. Ce n'est pas recommandé, veuillez choisir un autre dossier.
+ Le répertoire que vous avez choisi est sur le bureau. Ceci n'est pas recommandé, veuillez choisir un autre dossier .
Échec de l'enregistrement du profil
Échec de l'enregistrement du profil {0}. {1}\n{2}
@@ -127,6 +165,25 @@
Processeur
+
+ Sélection de dossiers de données
+ Il semble que vous n'ayez pas de répertoire de données défini. Le répertoire de données est où vos profils et vos profils SteamCMD seront stockés. Ce n'est pas la même chose que le répertoire d'installation du serveur, que vous pouvez choisir pour chaque profil.
+ Sélectionnez le lecteur où le dossier de données doit être localisé.
+ Nom du dossier de données :
+ Le nom du dossier Données du gestionnaire de serveur.
+ Disque local
+ {0} libre de {1}
+
+ Ok
+ Annuler
+ Rafraîchir
+
+ Erreur de sélection du répertoire de données
+ Le nom du dossier de données que vous avez entré n'est pas valide.
+ Le redémarrage du gestionnaire de serveur requis
+ Le dossier de données a été défini, vous devez maintenant redémarrer le gestionnaire de serveur pour utiliser les nouveaux paramètres.
+
+
Fermer
@@ -259,9 +316,11 @@
Synchronisation du profil - {0}
Erreur du chargement du profil synchronisé
Procéder a la Synchronisation du profil
+ Vous êtes sur le point de sélectionnés des profils avec les paramètres des sections sélectionnées du profil actuel. Vous ne pourrez pas annuler, voulez-vous continuer?
Erreur du Procéssus de Synchronisation du profil
Vous n'avez pas sélectionné de profil à copier.
Vous n'avez sélectionné aucune section pour copier les paramètres de.
+ Les paramètres des sections sélectionnées ont été copiés avec succès du profil actuel aux profils sélectionnés.
Tout selectionner
Tout déselectionner
Proceder
@@ -418,8 +477,10 @@
Réinitialiser
Cela réinitialisera TOUS les paramètres globaux de l'utilisateur pour le gestionnaire de serveur. Le gestionnaire de serveur sera fermé en cas de succès.
Exécuter en tant qu'administrateur au démarrage
+ Mode de démarrage de la fenêtre principale:
Réduire dans la barre des tâches
Gérer les paramètres du pare-feu automatiquement
+ Gérer automatiquement l'IP Public
Répertoire de données:
Répertoire de sauvegarde:
Clé WebApi Steam:
@@ -441,6 +502,8 @@
Si cette option est activée, la personnalisation de spawn dino de cartes seront gérés par ASM.
Personnalisation de Caisses de butin
Si activé, la personnalisation de "Caisse d'approvisionnement", dit aussi "Caisse de butin" ou "supply Crate" seront gérés par ASM.
+ Activer Empêcher les remplacements de transfert
+ Si activé, les substitutions de transfert d'Empêchement seront gérées par le gestionnaire de serveur.
Paramètres Ark PGM
Si activé, les paramètres PGM seront gérés par ASM.
Paramètres SotF
@@ -627,6 +690,8 @@
Ce message sera affiché lors de l'arrêt du serveur.
Message démarré par le serveur:
Ce message sera affiché lors du démarrage du serveur.
+ Inclure l'IP Public et le port dans le message Démarrer
+ Le message de démarrage comprendra l'IP publique et le port.
Erreur de processus de sauvegarde:
Ce message sera affiché lorsque le processus de sauvegarde automatique a rencontré une erreur.
Erreur de processus d'arrêt:
@@ -721,7 +786,7 @@
Démarrage de la mise à jour...
-
+
_Fichier
_Quitter
@@ -748,9 +813,11 @@
- Profil:
- Le nom du profil du serveur. Ce n'est pas le nom public que les utilisateurs verront dans Ark. Pour cela, définissez le champ "Nom du serveur".
- Version ARK installée:
+ ID Profile:
+ L'ID unique attribué au profil.
+ Profile:
+ Le nom du profil du serveur. Ce n'est pas le nom public que les utilisateurs verront dans Ark. Pour cela, définissez le champ "Nom du serveur.
+ Version installée:
La version du serveur Ark actuellement téléchargée (REMARQUE: ne sera pas mise à jour tant que le serveur ne sera pas démarré).
Mods obsolètes:
Nombres de mods qui sont actuellement obsolètes.
@@ -893,7 +960,9 @@
Mise en réseau
Port du serveur:
- Les utilisateurs du port utiliseront pour se connecter à votre serveur. La valeur par défaut est 7777. Modifiez ceci et le port de requête si vous souhaitez héberger plusieurs serveurs sur une machine.
+ Les utilisateurs du port l'utiliseront pour se connecter à votre serveur. La valeur par défaut est 7777. Modifiez ceci et le port de requête si vous souhaitez héberger plusieurs serveurs sur une machine.
+ Peer Port:
+ Port d'interface utilisé pour déterminer la disponibilité du serveur. La valeur par défaut est 7778 .
Port query:
Le port Steam utilise pour communiquer avec votre serveur. La valeur par défaut est 27015. Changez ceci et le port du serveur si vous souhaitez héberger plusieurs serveurs sur une machine.
IP Locale:
@@ -1116,6 +1185,8 @@
Active le mode hardcore (les joueurs ne peuvent pas réapparaître, un nouveau personnage doit être créé).
Activer PvP
Active le mode Joueur contre Joueur (les joueurs peuvent infliger des dégâts ou s'entraider). En PvP, les joueurs peuvent aussi endommager ou détruire les bâtiments d'une autre tribu ou tuer leurs dinosaures..
+ Activer le mode créatif
+ Si activé, permet le mode créatif.
Activer Construction dans les grottes en PvE
Si activé, permet de construire dans des grottes lorsque le mode PvE est activé.
Activer la maladie de cryo PvE
@@ -1151,6 +1222,8 @@
Détermine les niveaux maximum de créatures dans le jeu. Plus la valeur est élevée, plus le niveau de créature maximum est élevé.
Coefficient de Difficulté:
Détermine les niveaux maximum de créatures dans le jeu. Plus la valeur est élevée, plus le niveau de créature maximum est élevé.
+ Détruire les Tames sur le niveau:
+ Tames dépassant ce niveau sera supprimé sur le lancement du serveur. Désactiver la suppression définie sur 0.
Activer les téléchargements tribu
Si activé, cela permettra de télécharger des survivants/objets/dinos externes sur votre serveur.
@@ -1274,11 +1347,6 @@
Limiter le nombre d'objets jétés par un joueur dans une zone
Limitez le nombre d'articles jetés dans une zone (avec LimitNonPlayerDroppedItemsRange).
- Autoriser utilisation de L'armure TEK
- si activé, permet au joueur d'utiliser L'armure Tek sur la carte Genesis.
- Désactiver les missions
- si activé, désactive toutes les missions sur la carte Genesis.
-
Activer Nerf de Cryopode
Si activé, ajustera la quantité de dégâts qu'une créature fait, pendant un certain temps, après qu'elle ait été libérée d'un cryopode.
Durée du Nerf de Cryopode
@@ -1287,6 +1355,44 @@
Spécifie le multiplicateur des dégâts infligés par les créatures, après leur libération d'un cryopode. Des valeurs plus faibles signifient que le dommage effectué sera inférieur (par exemple, 0,01 signifie que 99% des dommages sont supprimés).
Multiplicateur de Pourcentage de dommages entrants
Spécifie l'augmentation en pourcentage du multiplicateur de dégâts entrant d'une créature, après qu'ils ont été libérés d'un cryopode. Des valeurs plus élevées signifient plus de dégâts entrants infligés à la créature (par exemple, 0,25 = 25% de dégâts supplémentaires).
+
+ Autoriser utilisation de l'armure TEK
+ si activé, permet au joueur d'utiliser L'armure Tek sur la carte Genesis.
+ Désactiver les missions
+ si activé, désactive toutes les missions sur la carte Genesis.
+
+ Désactiver l'armure Tek au Spawn
+ Si activé, empêchera le joueur de spawn avec l'armure Tek.
+
+ Désactiver Buffs généraux
+ Si activé, désactivera les effets généraux des missions.
+ Activer la mise à l'échelle du buff général
+ Si activé, causera des buff généraux pour réduire leurs avantages de manière multiplicative, plutôt que d'ajouter/soustraire une quantité forfaitaire à la valeur au moment de l'exécution.
+ Mise à l'échelle de l'éfficacité du buff général
+ Spécifie l'echelle global pour réduire/augmenter l'efficacité des buffs général (par exemple 1 est par défaut, 0,5 serait de 50% moins efficace, 2,0 serait 2x plus efficace) .
+
+ Hexagons
+ Désactiver le magasin Hexagagon
+ Si activé, le magasin hexagonal sera désactivé.
+ Autoriser uniquement le commerce des points d'engramme
+ Si activé, seuls les points d'engramme peuvent être vendus sur le magasin hexagonal.
+ Hexagones maximum par personnage
+ Spécifie le nombre maximum d'hexagones que chaque joueur peut avoir.
+ Multiplicateur de récompense hexagone
+ Spécifie le multiplicateur pour les récompenses d'hexagones.
+ Multiplicateur de coûts hexagones
+ Spécifie le multiplicateur pour le coût de l'hexagone par articles.
+
+ Vérouillage des stat d'item
+ AVERTISSEMENT: Cela modifiera définitivement les statistiques de tous les éléments existants, assurez-vous de sauvegarder votre sauvegarde actuelle avant de modifier et de jouer avec les valeurs de vérouillage.
+ Qualité générique
+ Armure
+ Durabilité maximale
+ Pourcentage de dégâts d'armes
+ Munitions d'attachement d'arme
+ Isolation hypotermique
+ Poids
+ Hyper isolant
@@ -1427,6 +1533,8 @@
Si activé, permet vol dans les grottes.
Permettre la récupération de l'endurance en vol
Si activé, récupère l'endurance en se tenant debout en vol.
+ Autoriser les niveau de la vitesse des Volants
+ Si activé, permet le nivau de la vitesse de déplacement des créatures volantes.
Empêchez le bonus de couple
Si cette option est activée, le le bonus de couple dino sera désactivé.
Désactiver l'entrave au sol des dinos volants avec explosifs
@@ -2227,6 +2335,23 @@
+
+
+ Empêcher les substitutions de transfert
+ Empêcher les transferts
+ Empêcher les paramètres de remplacement de transfert
+ Remarque: Si vous souhaitez gérer vos substitutions manuellement ou avec une autre application, vous pouvez désactiver l'option qui empêchera le gestionnaire de serveur gérant les substitutions. Voir les "options de substitution personnalisées" dans les paramètres globaux.
+ AVERTISSEMENT: L'ajout de dinos à cette liste les empêchera d'être transféré vers et depuis le serveur.
+
+ Dino
+ Chaîne de classe Dino
+
+ Ajouter Empêcher l'élément de transfert
+ Supprimer tous Empêcher les éléments de transfert
+ Coller empêche les articles de transfert des données
+ Supprimer Empêcher l'élément de transfert
+ Enregistrer éviter les données d'éléments de transfert
+
Détails du joueur
@@ -2400,34 +2525,6 @@
Paramètres
-
- The Island
- The Center
- Scorched Earth
- Ragnarok
- Aberration
- Extinction
- Valguero
- Genesis
-
-
-
- Primitive Plus
-
-
-
- Version Steam (Défaut)
-
-
-
- Aucun
- Saint-Valentin
- Pâques
- Fear Evolved (Halloween)
- Turkey Trial
- Winter Wonderland
-
-
@@ -2560,54 +2657,48 @@
- Boss Broodmother Lysrix
- Boss Broodmother Lysrix Gamma
- Boss Broodmother Lysrix Beta
- Boss Broodmother Lysrix Alpha
- Boss Broodmother Lysrix Gamma (The Center)
- Boss Broodmother Lysrix Beta (The Center)
- Boss Broodmother Lysrix Alpha (The Center)
+ Broodmother Lysrix
+ Broodmother Lysrix (Easy Variant)
+ Broodmother Lysrix (Medium Variant)
+ Broodmother Lysrix (Hard Variant)
- Boss Megapithecus
- Boss Megapithecus Gamma
- Boss Megapithecus Beta
- Boss Megapithecus Alpha
- Boss Megapithecus Gamma (The Center)
- Boss Megapithecus Beta (The Center)
- Boss Megapithecus Alpha (The Center)
+ Megapithecus
+ Megapithecus (Easy Variant)
+ Megapithecus (Medium Variant)
+ Megapithecus (Hard Variant)
- Boss Dragon
- Boss Dragon Gamma
- Boss Dragon Beta
- Boss Dragon Alpha
+ Dragon
+ Dragon (Easy Variant)
+ Dragon (Medium Variant)
+ Dragon (Hard Variant)
- Boss Attaque Drones
- Boss Attaque Drones Beta
- Boss Attaque Drones Alpha
+ Attack Drone
+ Attack Drone (Medium Variant)
+ Attack Drone (Hard Variant)
- Boss Unités de défense
- Boss Unités de défense Beta
- Boss Unités de défense Alpha
+ Defense Unit
+ Defense Unit (Medium Variant)
+ Defense Unit (Hard Variant)
- Boss Surveillant
- Boss Surveillant Gamma
- Boss Surveillant Beta
- Boss Surveillant Alpha
+ Overseer
+ Overseer (Easy Variant)
+ Overseer (Medium Variant)
+ Overseer (Hard Variant)
- Boss Gardien Dragon
- Boss Gardien Dragon Gamma
- Boss Gardien Dragon Beta
- Boss Gardien Dragon Alpha
+ Dragon Guardian
+ Dragon Guardian (Easy Variant)
+ Dragon Guardian (Medium Variant)
+ Dragon Guardian (Hard Variant)
- Boss Gardien Megapithecus
- Boss Gardien Megapithecus Gamma
- Boss Gardien Megapithecus Beta
- Boss Gardien Megapithecus Alpha
+ Megapithecus Guardian
+ Megapithecus Guardian (Easy Variant)
+ Megapithecus Guardian (Medium Variant)
+ Megapithecus Guardian (Hard Variant)
- Boss Gardien Broodmother
- Boss Gardien Broodmother Gamma
- Boss Gardien Broodmother Beta
- Boss Gardien Broodmother Alpha
+ Broodmother Guardian
+ Broodmother Guardian (Easy Variant)
+ Broodmother Guardian (Medium Variant)
+ Broodmother Guardian (Hard Variant)
@@ -2639,142 +2730,160 @@
- Griffon
- Ours polair
- Wyverne de glace
+ Griffin
+ Polar Bear
+ Ice Wyvern
+ Iceworm
- Boss Ver des glaces
- Boss Golem de pierre
+ Ice Worm
+ Lava Golem
- Boss Dragon Gamma (Ragnarok)
- Boss Dragon Beta (Ragnarok)
- Boss Dragon Alpha (Ragnarok)
+ Dragon (Easy Variant)
+ Dragon (Medium Variant)
+ Dragon (Hard Variant)
- Boss Manticore Gamma (Ragnarok)
- Boss Manticore Beta (Ragnarok)
- Boss Manticore Alpha (Ragnarok)
+ Manticore (Easy Variant)
+ Manticore (Medium Variant)
+ Manticore (Hard Variant)
+
+
+
+ Broodmother Lysrix (Easy Variant)
+ Broodmother Lysrix (Medium Variant)
+ Broodmother Lysrix (Hard Variant)
+
+ Megapithecus (Easy Variant)
+ Megapithecus (Medium Variant)
+ Megapithecus (Hard Variant)
+
+
+
+ Deinonychus
+ Ice Golem
+ Chalk Golem
+ Broodmother (Lysrix)
- Achatina Irradié
- Angler Irradié
- Ankylosaure Irradié
- Arthropluera Irradié
- Baryonyx Irradié
- Gigantopithecus Irradié
- Titanoboa Irradié
- Carno Irradié
- Cnidaria Irradié
- Coelacanth Irradié
- Dimetrodon Irradié
- Dimorphodon Irradié
- Diplocaulus Irradié
- Diplodocus Irradié
- Ours Sinistre Irradié
- Dodo Irradié
- Doedicurus Irradié
- Meganeura Irradié
- Bousier Irradié
- Electrophorus Irradié
- Equus Irradié
- Iguanodon Irradié
- Lystrosaurus Irradié
- Manta Irradié
- Megalania Irradié
- Megalosaurus Irradié
- Moschops Irradié
- Loutre Irradié
- Parasaure Irradié
- Paracer Irradié
- Piranha Irradié
- Purlovia Irradié
- Raptor Irradié
- Saumon Irradié
- Sarco Irradié
- Scorpion Irradié
- Mouton Irradié
- Araignée Irradié
- Spinosaure Irradié
- Stegosaure Irradié
- Grenouille Irradiée
- Triceratops Irradié
- Trilobite Irradié
- Tortue Irradiée
+ Aberrant Achatina
+ Aberrant Anglerfish
+ Aberrant Ankylosaurus
+ Aberrant Arthropluera
+ Aberrant Baryonyx
+ Aberrant Gigantopithecus
+ Aberrant Titanoboa
+ Aberrant Carnotaurus
+ Aberrant Cnidaria
+ Aberrant Coelacanth
+ Aberrant Dimetrodon
+ Aberrant Dimorphodon
+ Aberrant Diplocaulus
+ Aberrant Diplodocus
+ Aberrant Direbear
+ Aberrant Dodo
+ Aberrant Doedicurus
+ Aberrant Meganeura
+ Aberrant Dung Beetle
+ Aberrant Electrophorus
+ Aberrant Equus
+ Aberrant Iguanodon
+ Aberrant Lystrosaurus
+ Aberrant Manta
+ Aberrant Megalania
+ Aberrant Megalosaurus
+ Aberrant Moschops
+ Aberrant Otter
+ Aberrant Parasaur
+ Aberrant Paraceratherium
+ Aberrant Piranha
+ Aberrant Purlovia
+ Aberrant Raptor
+ Aberrant Salmon
+ Aberrant Sarco
+ Aberrant Pulmonoscorpius
+ Aberrant Ovis
+ Aberrant Araneo
+ Aberrant Spino
+ Aberrant Stegosaurus
+ Aberrant Beelzebufo
+ Aberrant Triceratops
+ Aberrant Trilobite
+ Aberrant Carbonemys
Basilisk
Ravager
Nameless
Karkinos
- Lamproie
- Plumineux
- Lumicorne
- Gecko Luisant
+ Lamprey
+ Featherlight
+ Shinehorn
+ Glowtail
Bulbdog
- Luiciole
- Rat des profondeurs
+ Glowbug
+ Roll Rat
Seeker
- Dragon Rocheux
- Nameless Reine
+ Rock Drake
+ Nameless Queen
- Nameless Serviteur
- Nameless de Surface
+ Nameless (Minion)
+ Nameless (Surface)
Alpha Basilisk
Alpha Karkinos
- Alpha Reaper Roi de Surface
- Seeker de Surface
- Reaper Reine
- Reaper Roi
- Reaper male Subalterne
- Reaper Roi Elementaire
- Reaper Roi de Surface
- Reaper Roi Aprivoisé
+ Alpha Surface Reaper King
+ Seeker (Surface)
+ Reaper Queen
+ Reaper King
+ Subterranean Reaper King
+ Elemental Reaper King
+ Surface Reaper King
+ Reaper King Tamed
- Boss Rockwell
- Boss Rockwell Gamma
- Boss Rockwell Beta
- Boss Rockwell Alpha
- Boss Rockwell Tentaculaire
- Boss Rockwell Tentaculaire Alpha
- Boss Rockwell Tentaculaire Beta
- Boss Rockwell Tentaculaire Gamma
+ Rockwell
+ Rockwell (Easy Variant)
+ Rockwell (Medium Variant)
+ Rockwell (Hard Variant)
+ Rockwell Tentacle
+ Rockwell Tentacle (Hard Variant)
+ Rockwell Tentacle (Medium Variant)
+ Rockwell Tentacle (Easy Variant)
- Arthropluera corrompu
- Carnotaurus corrompu
- Chalicotherium corrompu
- Ver des sables corrompu
- Dilophosaur corrompu
- Dimorphodon corrompu
- Giganotosaurus corrompu
- Rex enragé corrompu
- Triceratops enragé corrompu
- Paraceratherium corrompu
- Pteranodon corrompu
- Raptor corrompu
- Rex corrompu
- Dragon rocheux corrompu
- Spino corrompu
- Stegosaurus corrompu
- Triceratops corrompu
- Reaper King corrompu
- Wyvern corrompu
+ Corrupted Arthropluera
+ Corrupted Carnotaurus
+ Corrupted Chalicotherium
+ Corrupted Deathworm
+ Corrupted Dilophosaur
+ Corrupted Dimorphodon
+ Corrupted Giganotosaurus
+ Enraged Corrupted Rex
+ Enraged Triceratops
+ Corrupted Paraceratherium
+ Corrupted Pteranodon
+ Corrupted Raptor
+ Corrupted Rex
+ Corrupted Rock Drake
+ Corrupted Spino
+ Corrupted Stegosaurus
+ Corrupted Triceratops
+ Corrupted Reaper King
+ Corrupted Wyvern
- Titan du désert
- Exécuteur
- Titan de la forêt
+ Desert Titan
+ Enforcer
+ Forest Titan
Gacha
- Sacagaz
+ GasBags
Managarmr
- Titan de glace
+ Ice Titan
Mega Mek
Mek
- Harfang des neiges
- Éclaireur
+ Snow Owl
+ Scout
Velonasaur
Defense Unit
@@ -2785,6 +2894,55 @@
King Titan (Alpha)
King Titan (Beta)
+
+
+ Astrocetus
+ Bloodstalker
+ Magmasaur
+ Megachelon
+ Ferox Small
+ Ferox Large
+ Insect Swarm
+ Parakeet Fish School
+ Tek Hover Skiff
+ Tek Triceratops
+ Tek Giganotosaurus
+ X-Allosaur
+ X-Ankylosaur
+ X-Argentavis
+ X-Basilosaurus
+ X-Dunkleosteus
+ X-Ichthyosaurus
+ X-Megalodon
+ X-Mosasaur
+ X-Otter
+ X-Parasaur
+ X-Raptor
+ X-Rex
+ X-Rock Elemental
+ X-Sabertooth
+ X-Sabertooth Salmon
+ X-Sabertooth Salmon (Rare)
+ X-Spinosaur
+ X-Tapejara
+ X-Triceratops
+ X-Woolly Rhino
+ X-Yutyrannus
+
+
+
+ Moeder, Master of the Ocean (Easy Variant)
+ Moeder, Master of the Ocean (Medium Variant)
+ Moeder, Master of the Ocean (Hard Variant)
+
+ Eel Minion (Gamma)
+ Eel Minion (Beta)
+ Eel Minion (Alpha)
+
+ Corrupted Master Controller (Easy Variant)
+ Corrupted Master Controller (Medium Variant)
+ Corrupted Master Controller (Hard Variant)
+
@@ -3503,6 +3661,27 @@
Pont Tek
Grenade de gravité
+
+
+ Selle de Magmasaur
+ Plateforme de Megachelon
+ Filet de pêche
+ Plateforme Oceanique en bois
+ Plateforme Oceanique en métal
+ Plaque de pression
+ Foreuse minière
+
+
+
+ Selle tek d'Astrocetus
+ Griffes Tek
+ Missile Tek de croisière
+ Lanceur Tek de Grenade
+ Tek Hover Skiff
+ Tek Jump Pad
+ Tek Sensor
+ Cannon d'épaule Tek
+
@@ -4883,6 +5062,50 @@
Trophée du Roi des Titans (Gamma)
+
+ Griffes Tek
+ Lanceur Tek de Grenade
+ Filet de pêche
+ Missile Tek de croisière
+ Foreuse minière
+ Cannon d'épaule Tek
+ Selle tek d'Astrocetus
+ Selle de Magmasaur (Genesis)
+ Plateforme de Megachelon (Genesis)
+ Tier 1 Lootcrate (Genesis)
+ Tier 2 Lootcrate (Genesis)
+ Tier 3 Lootcrate (Genesis)
+ Oeuf de Bloodstalker (Genesis)
+ Oeuf de Magmasaur (Genesis)
+ Oeuf de Megachelo (Genesis)
+ Oeuf de Trike Tek (Genesis)
+ Ambergris
+ Fragment de Carapace
+ Pollen de haute qualité
+ Pépite d'or
+ Glande de phéromone Reaper (Genesis)
+ Crâne d'Alpha X-Triceratops
+ Dent de mégalodon-X
+ Casque du Master Controller
+ Skin de Casque d'Avatar corrompu
+ Skin de Plastron d'Avatar corrompu
+ Skin de jambière d'Avatar corrompu
+ Skin de gants d'Avatar corrompu
+ Skin de bottes d'Avatar corrompu
+ Unassembled TEK Hover Skiff
+ Drapeau du Moeder
+ Drapeau du VR Boss
+ Plateforme Oceanique en métal
+ Plaque de pression
+ Tek Sensor
+ Tek Jump Pad
+ Plateforme Oceanique en bois
+ Trophé du Gamma Moeder (Гамма)
+ Trophé du Beta Moeder (Бета)
+ Trophé du Alpha Moeder (Альфа)
+ Trophé du Master Controller
+
+
@@ -5222,6 +5445,10 @@
Boss Inventory - Desert Titan
Boss Inventory - Forest Titan
Boss Inventory - Ice Titan
+
+ Boss Inventory - Crystal Wyvern Queen (Gamma)
+ Boss Inventory - Crystal Wyvern Queen (Beta)
+ Boss Inventory - Crystal Wyvern Queen (Alpha)
@@ -5231,6 +5458,7 @@
Les problèmes de validation suivants ont été rencontrés.\r\n\r\n{validateMessage}\r\n\r\n Souhaitez-vous continuer le démarrage du serveur, cela pourrait provoquer des problèmes?
Le port du serveur est en dehors de la plage valide ({PortMinimum}-{PortMaximum}).
+ Le port peer du serveur est en dehors de la plage valide ({PortMinimum}-{PortMaximum}).
Le port de requête est en dehors de la plage valide ({PortMinimum}-{PortMaximum}).
Le port rcon est en dehors de la plage valide ({PortMinimum}-{PortMaximum}).
@@ -5275,6 +5503,7 @@
Création d'informations sur les Spawn de carte...
Création d'informations sur les caisses de bultin...
Création d'informations sur le Stack...
+ Construire des informations d'empêchement de transfert d'empêchement...
Enregistrement du fichier de profil...
Enregistrement des fichiers de configuration...
Enregistrement du fichier de lancement...
diff --git a/src/ARKServerManager/Globalization/pt-BR/pt-BR.xaml b/src/ARKServerManager/Globalization/pt-BR/pt-BR.xaml
index 4bc6b138..beb43096 100644
--- a/src/ARKServerManager/Globalization/pt-BR/pt-BR.xaml
+++ b/src/ARKServerManager/Globalization/pt-BR/pt-BR.xaml
@@ -13,7 +13,37 @@
Error
-
+
+ The Island
+ The Center
+ Scorched Earth
+ Ragnarok
+ Aberration
+ Extinction
+ Valguero
+ Genesis: Part 1
+ Crystal Isles
+ Genesis: Part 2
+
+
+
+ Primitive Plus
+
+
+
+ Live
+
+
+
+ Nenhum
+ Dia dos namorados
+ Páscoa
+ Fear Evolved (Halloween)
+ Turkey Trial
+ Winter Wonderland
+
+
+
Todos
Desconhecido
ARK Prime
@@ -51,6 +81,12 @@
Todos
+
+ Normal
+ Minimizado
+ Maximizado
+
+
Executar como administrador
Este aplicativo requer privilégios de administração para acessar toda a funcionalidade. Você gostaria de executar como administrador?
@@ -66,9 +102,10 @@
Selecione um diretório de dados
Confirme a localização
O Ark Server Manager armazenará os perfis e o SteamCMD nos seguintes diretórios:\r\n\r\nProfiles: {0}\r\nSteamCMD: {1}\r\n\r\n Está tudo bem?
- Erro na seleção do diretório de dados
- O diretório que você escolheu está dentro da pasta de instalação do gerenciador de servidor. Isso não é recomendado, escolha outra pasta.
- Não foi possível guardar o perfil
+ Erro na seleção do diretório de dados
+ O diretório que você escolheu está dentro da pasta de instalação do gerenciador de servidor. Isso não é recomendado, escolha outra pasta.
+ O diretório que você escolheu está na área de trabalho. Isso não é recomendado, escolha outra pasta.
+ Não foi possível guardar o perfil
Não foi possível guardar o perfil {0}. {1}\n{2}
Mostrar janela principal
@@ -128,6 +165,25 @@
Processador
+
+ Seleção da pasta de dados
+ Parece que você não tem um conjunto de diretórios de dados. O diretório de dados é onde seus perfis e o SteamCMD serão armazenados. Não é o mesmo que o diretório de instalação do servidor, que você pode escolher para cada perfil.
+ Selecione a unidade onde a pasta de dados deve estar localizada.
+ Nome da pasta de dados:
+ O nome da pasta de dados do server manager.
+ Disco local
+ {0} livre de {1}
+
+ Ok
+ Cancelar
+ Atualizar
+
+ Erro de seleção no diretório de dados
+ O nome da pasta de dados que você digitou não é válido.
+ Reinicialização do Server Manager necessária
+ A pasta de dados foi configurada, você deve agora reiniciar o server manager para usar as novas configurações.
+
+
Fechar
@@ -421,6 +477,7 @@
Redefinir
Isso redefinirá TODAS as configurações globais do usuário para o gerenciador do servidor. O gerenciador do servidor será fechado se for bem-sucedido.
Ativar e executar como Prompt de Administrador na Inicialização
+ Modo de início da janela principal:
Minimizar para a bandeja
Gerenciar configurações de firewall automaticamente
Gerenciar IP público automaticamente
@@ -445,6 +502,8 @@
Se ativado, as substituições do gerador de mapa serão gerenciadas pelo ASM.
Ativar substituições de Supply Crate
Se habilitado, as substituições de supply crate serão gerenciadas pelo ASM.
+ Ativar Prevenção de Substituição de Transferência
+ Se habilitado, as substituições de transferência de prevenção serão gerenciadas pelo gerenciador do servidor.
Ativar configurações do Ark PGM
Se ativado, as configurações do PGM serão gerenciadas pelo ASM.
Ativar configurações SotF
@@ -552,6 +611,23 @@
Mostrar o motivo de desligamento com TODAS as mensagens de desligamento
Se habilitado, o motivo do desligamento será mostrado com todas as mensagens de desligamento; caso contrário, ele será mostrado apenas no início do encerramento do servidor.
+ Habilitar Discord Bot
+ Você precisará reiniciar o server manager se alterar alguma configuração do Discord Bot.
+ Token:
+ O token associado ao bot discord.
+ Server Id:
+ O id do servidor discord que o bot usará.
+ Prefix:
+ O prefixo que deve ser usado ao enviar um comando via discord.
+ Obter Token...
+ Ajuda...
+ Se ativado, o comando de backup pode ser enviado do discord.
+ Se ativado, o comando de reiniciar pode ser enviado do discord.
+ Se habilitado, o comando de desligar pode ser enviado do discord.
+ Se habilitado, o comando de iniciar pode ser enviado do discord.
+ Se habilitado, o comando de parar pode ser enviado do discord.
+ Se ativado, o comando de atualizar pode ser enviado do discord.
+
Configurações de email SMTP
Host:
O nome ou endereço IP do host usado para transmissões de SMTP.
@@ -603,6 +679,8 @@
Alterar o diretório de dados moverá os perfis existentes para o novo local, mas não moverá nenhuma instalação do servidor. Você ainda quer mudar este diretório?
Falha ao alterar o diretório de dados
Ocorreu um erro ao alterar o diretório de dados: {0}\r\nPor favor, corrija o erro e tente novamente ou entre em contato com o suporte técnico para obter assistência.
+ Confirmar redefinição do diretório de dados
+ Clique em 'Sim' para confirmar que deseja redefinir a localização do diretório de dados. Uma vez reiniciado, o gerenciador do servidor será encerrado e você precisará reiniciá-lo.
Selecione o diretório de backup
Selecione o diretório de cache
@@ -716,6 +794,9 @@
Reinstale o erro do SteamCMD
Ocorreu um erro ao tentar reinstalar o SteamCMD. Isso deixou o SteamCmd em um estado instável, tente reinstalar novamente ou informe isso.\R\nException: {0}
+ Discord Bot executando comandos
+ O bot discord tem um ou mais comandos em execução. Quer continuar fechando o server manager?
+
Iniciar a confirmação do servidor
Você está prestes a iniciar o servidor, deseja continuar?
Confirmação do servidor de desligamento
@@ -754,6 +835,8 @@
+ Perfil ID:
+ O ID exclusivo atribuído ao perfil.
Perfil:
O nome do perfil do servidor. Este nao e o nome publico que os usuários verao em Ark. Para isso, defina o campo 'Server Name'.
Versão Instalada:
@@ -1118,13 +1201,33 @@
Se ativado, o servidor será reiniciado mesmo se o desligamento for Reinicializações Automáticas e Atualizações Automáticas.
+
+ Detalhes do Discord Bot
+ Id do canal:
+ O id do canal do discord que este perfil irá usar.
+ Permitir backup
+ Se ativado, o perfil usará os comandos de backup pelo discord.
+ Permitir Reinício
+ Se ativado, o perfil usará comandos de reinicialização pelo discord.
+ Permitir desligamento
+ Se ativado, o perfil usará comandos de desligamento pelo discord.
+ Permitir iníciar
+ Se ativado, o perfil usará os comandos de iníciar pelo discord.
+ Permitir parar
+ Se ativado, o perfil usará os comandos de parar pelo discord.
+ Permitir atualização
+ Se ativado, o perfil usará os comandos de atualização pelo discord.
+
+
Regras
Ativar o modo Hardcore
Ativa o modo hardcore (os jogadores não podem renascer, um novo personagem deve ser criado).
Ativar PvP
Ativa o modo Jogador contra Jogador (jogadores são capazes de causar dano ou matar uns aos outros. Em jogadores PvP também podem danificar ou destruir os edifícios de outra tribo ou matar seus dinossauros).
- Ativar construçoes em Caverna PvE
+ Ativar o modo criativo
+ Se ativado, permite o modo criativo.
+ Ativar construçoes em Caverna PvE
Se habilitado, permite a construção em cavernas quando o modo PVE estiver habilitado.
Ativar doença criogênica do PvE
Se ativado, se você liberar uma criatura domesticada de um criodo, você terá um cronômetro de doença crio quando o modo PvE estiver ativado.
@@ -1159,6 +1262,8 @@
Determina os níveis máximos de criaturas do mundo. Quanto maior o valor, maior o Nível Máximo de Criatura.
Dificuldade Offset:
Determina os níveis máximos de criaturas do mundo. Quanto maior o valor, maior o Nível Máximo de Criatura.
+ Destruir domados acima do nível:
+ Dinos que excedem esse nível serão excluídos ao iniciar o servidor. Para desativar a exclusão definida para 0.
Ativar downloads de tributo
Se habilitado, isso permitirá o download de sobreviventes / itens / dinossauros externos em seu servidor.
@@ -1281,7 +1386,16 @@
Limite o número de itens descartados em uma área (junto com LimitNonPlayerDroppedItemsCount).
Limitar a contagem de itens descartados por não jogadores
Limite o número de itens descartados em uma área (junto com LimitNonPlayerDroppedItemsRange).
-
+
+ Habilitar Cryopod Nerf
+ Se ativado, ajustará a quantidade de dano que uma criatura causa, por um período de tempo, após ter sido liberada de um criópode.
+ Duração de Cryopod Nerf
+ A quantidade de tempo, em segundos, em que o ajuste de dano entrará em vigor para criaturas liberadas de um criópode.
+ Multiplicador de Dano Criópode Nerf
+ Especifica o multiplicador pelo dano causado pelas criaturas, depois que elas são liberadas de um criópode. Valores mais baixos significam que a vazão realizada será menor (por exemplo, 0,01 significa que 99% do dano é removido).
+ Porcentagem do multiplicador de danos recebidos
+ Especifica o aumento percentual no multiplicador de dano recebido de uma criatura, depois que ela é liberada de um criópode. Valores mais altos significam mais dano recebido à criatura (por exemplo, 0.25 = 25% a mais de dano).
+
Permitir poderes do TekSuit
se ativado, permitirá que o jogador use TekSuit Powers no mapa Genesis.
Desativar missões
@@ -1290,6 +1404,13 @@
Desativar TEK Suit no Spawn
Se habilitado, irá prevenir que o jogador de spawn com o TEK Suit.
+ Desativar os Buffs do Mapa
+ Se habilitado, desabilitará os efeitos das Missões completamente.
+ Habilitar escala de Buff no Mapa
+ Se habilitado, fará com que os buffs do Mapa escalem seus benefícios multiplicativamente, ao invés de adicionar / subtrair uma quantia fixa ao valor em tempo de execução.
+ Buff de escalonamento global
+ Especifica a escala global para reduzir / aumentar a eficácia dos buffs mundiais (por exemplo, 1 é o padrão, 0,5 seria 50% menos eficaz, 2,0 seria 2x mais eficaz).
+
Hexagons
Desativar Hexagon Store
Se estiver habilitado, o hexagon store será desabilitado.
@@ -1302,15 +1423,6 @@
Multiplicador de custo Hexagons
Especifica o multiplicador para o custo Hexagons dos itens.
- Habilitar Cryopod Nerf
- Se ativado, ajustará a quantidade de dano que uma criatura causa, por um período de tempo, após ter sido liberada de um criópode.
- Duração de Cryopod Nerf
- A quantidade de tempo, em segundos, em que o ajuste de dano entrará em vigor para criaturas liberadas de um criópode.
- Multiplicador de Dano Criópode Nerf
- Especifica o multiplicador pelo dano causado pelas criaturas, depois que elas são liberadas de um criópode. Valores mais baixos significam que a vazão realizada será menor (por exemplo, 0,01 significa que 99% do dano é removido).
- Porcentagem do multiplicador de danos recebidos
- Especifica o aumento percentual no multiplicador de dano recebido de uma criatura, depois que ela é liberada de um criópode. Valores mais altos significam mais dano recebido à criatura (por exemplo, 0.25 = 25% a mais de dano).
-
Item Stat Clamps
AVISO: Isso mudará permanentemente as estatísticas de qualquer item existente, portanto, certifique-se de fazer backup de seu salvamento atual antes de modificar e brincar com os valores de fixo.
Qualidade Genérica
@@ -1526,12 +1638,16 @@
Multiplicadores de estatísticas por nível (domado) - Adicionar
Multiplicadores de estatísticas por nível (domado) - afinidade
Multiplicadores de status por nível (wild)
+ Aumento de nível de Mutagen (Wild)
+ Aumento de nível de Mutagen (Bred)
Dino Multiplicadores de Reprodução
Se habilitado, permite que os fatores de escala sejam aplicados a cada estatística base.
Se ativado, permite que os fatores de escala sejam aplicados a cada estatística.
Se ativado, permite que os fatores de escala sejam aplicados à adição de domado para cada estatística.
Se ativado, permite que os fatores de escala sejam aplicados ao Multiplicador da Dominação para cada estatística.
Se habilitado, permite que os fatores de escala sejam aplicados ao aumento de status domado para cada estatística.
+ Se ativado, permite que os fatores de escala sejam aplicados ao número de níveis que o Mutagen adiciona a domar dino selvagem.
+ Se ativado, permite que os fatores de escala sejam aplicados ao número de níveis que o Mutagen adiciona a domados de bred.
Redefinir todos os multiplicadores de volta aos padrões.
Redefinir todos os multiplicadores de volta aos padrões.
@@ -1551,7 +1667,7 @@
Quanto de efeito nas estatísticas a qualidade de Imprinti tem. Defina como 0 para desativar efetivamente o sistema.
Escala de quantidade da impressão:
Multiplicador aplicado à porcentagem que cada impressão fornece. Este multiplicador é global, o que significa que afetará a progressão imprinting de todas as espécies. Valores mais altos aumentam a quantidade de cada impressão.
- Intervalo de acaracia:
+ Intervalo de acaricia:
Um multiplicador de quantas vezes os bebês querem abraçar. Valores mais baixos significam que você precisará acariciá-los com mais frequência para obter uma qualidade de impressão.
Período de carência
Um multiplicador de quanto tempo depois de atrasar o aconchego com o bebê antes da qualidade da imprint começa a diminuir. Valores mais altos aumentam o período de carência.
@@ -2263,6 +2379,23 @@
+
+
+ Impedir sobreposições de transferência
+ Impedir Transferências
+ Impedir configurações de substituição de transferência
+ NOTA: Se quiser gerenciar suas substituições manualmente ou com outro aplicativo, você pode desabilitar a opção que impedirá o gerenciador do servidor de gerenciar as substituições. Veja as 'Opções de substituição personalizadas' nas configurações globais.
+ AVISO: Adicionar dinossauros a esta lista impedirá que sejam transferidos para o servidor.
+
+ Dino
+ Dino Class String
+
+ Adicionar item de prevenção de transferência
+ Excluir todos os itens de prevenção de transferência
+ Colar dados de itens de prevenção de transferência
+ Excluir item de impedimento de transferência
+ Salvar dados de itens de prevenção de transferência
+
Detalhes do Jogador
@@ -2436,36 +2569,6 @@
Definições
-
- The Island
- The Center
- Scorched Earth
- Ragnarok
- Aberration
- Extinction
- Valguero
- Genesis: Part 1
- Crystal Isles
- Genesis: Part 2
-
-
-
- Primitive Plus
-
-
-
- Live
-
-
-
- Nenhum
- Dia dos namorados
- Páscoa
- Fear Evolved (Halloween)
- Turkey Trial
- Winter Wonderland
-
-
@@ -5370,6 +5473,16 @@
Boss Inventory - Dragon (Medium)
Boss Inventory - Dragon (Hard)
Boss Inventory - End Boss Minion
+
+ Boss Inventory - Dragon (Easy)
+ Boss Inventory - Dragon (Medium)
+ Boss Inventory - Dragon (Hard)
+ Boss Inventory - Manticore (Easy)
+ Boss Inventory - Manticore (Medium)
+ Boss Inventory - Manticore (Hard)
+ Boss Inventory - Megapithecus (Easy)
+ Boss Inventory - Megapithecus (Medium)
+ Boss Inventory - Megapithecus (Hard)
Boss Inventory - Manticore (Easy)
Boss Inventory - Manticore (Medium)
@@ -5390,6 +5503,13 @@
Boss Inventory - Crystal Wyvern Queen (Gamma)
Boss Inventory - Crystal Wyvern Queen (Beta)
Boss Inventory - Crystal Wyvern Queen (Alpha)
+
+ Boss Inventory - Dragon (Gamma)
+ Boss Inventory - Dragon (Beta)
+ Boss Inventory - Dragon (Alpha)
+ Boss Inventory - Manticore (Gamma)
+ Boss Inventory - Manticore (Beta)
+ Boss Inventory - Manticore (Alpha)
@@ -5444,6 +5564,7 @@
Construindo informações do Spawner no mapa ...
Construindo informações de Supply Crate...
Construindo informações sobre o stack ...
+ Construindo Informações de Prevenção de Transferência ...
Salvando arquivo de perfil...
Salvando arquivos de configuração...
Salvando arquivo do iniciador...
@@ -5463,4 +5584,32 @@
Ocorreu um problema ao executar a atualização do servidor. Isso pode deixar o servidor em um estado incompleto.\r\n\r\nDeseja continuar com a inicialização do servidor, isso pode causar problemas?
+
+ Discord Bot Error
+ O discord bot requer um token válido para que possa se conectar ao servidor discord\r\nIsso pode ser definido nas configurações globais.
+ O prefixo discord bot contém caracteres inválidos. Somente letras e números são permitidos.
+
+ O comando '{0}' não foi habilitado.
+ Comando desconhecido '{0}'.
+ Outro comando está sendo processado.
+ Outro comando '{0}' está em execução no perfil '{1}'.
+ O comando '{0}' foi desativado para o perfil '{1}'.
+
+ O comando '{0}' requer um id de perfil.
+ O perfil '{0}' não foi encontrado ou não está associado ao canal.
+ O perfil '{0}' está em um estado '{1}' que não pode executar este comando.
+ O perfil '{0}' está sendo atualizado.
+
+ A chamada para o servidor '{0}' falhou.
+ Uma solicitação de backup para o servidor '{0}' foi enviada.
+ Um pedido de reinicialização do servidor '{0}' foi enviado.
+ Um pedido de desligamento do servidor '{0}' foi enviado.
+ Uma solicitação de iníciar para o servidor '{0}' foi enviada.
+ Uma solicitação de parar o servidor '{0}' foi enviada.
+ Uma solicitação de atualização para o servidor '{0}' foi enviada.
+
+ Quantidade:
+ Mapa:
+
+
\ No newline at end of file
diff --git a/src/ARKServerManager/Globalization/ru-RU/ru-RU.xaml b/src/ARKServerManager/Globalization/ru-RU/ru-RU.xaml
index ca65a6da..63d3f224 100644
--- a/src/ARKServerManager/Globalization/ru-RU/ru-RU.xaml
+++ b/src/ARKServerManager/Globalization/ru-RU/ru-RU.xaml
@@ -9,11 +9,41 @@
Последнее обновление:
- 13.06.2021 от Varlonec
+ 09.12.2021 от Varlonec, Эдван
Ошибка
-
+
+ The Island
+ The Center
+ Scorched Earth
+ Ragnarok
+ Aberration
+ Extinction
+ Valguero
+ Genesis: Part 1
+ Crystal Isles
+ Genesis: Part 2
+
+
+
+ Primitive Plus
+
+
+
+ Основной ARK
+
+
+
+ None
+ Valentines Day
+ Easter
+ Fear Evolved (Halloween)
+ Turkey Trial
+ Winter Wonderland
+
+
+
All
Unknown
ARK Prime
@@ -51,6 +81,12 @@
Все
+
+ Обычный
+ По минимуму
+ По максимуму
+
+
Запустить в режиме Администратора.
Это приложение требует Административных привилегий для доступа ко всем функциям. Вы хотите запустить как из режима Администратора?
@@ -66,8 +102,9 @@
Выберите каталог данных
Подтвердить расположение
Ark Server Manager будет хранить профили и SteamCMD в следующих каталогах:\r\n\r\nПрофили: {0}\r\nSteamCMD: {1}\r\n\r\nВы подтверждаете?
- Выбор каталога данных ошибок
- Каталог, который вы выбрали, находится в папке установки менеджера сервера. Это не рекомендуется, пожалуйста, выберите другую папку.
+ Выбор каталога данных ошибок
+ Каталог, который вы выбрали, находится в папке установки менеджера сервера. Это не рекомендуется, пожалуйста, выберите другую папку.
+ Выбранный вами каталог находится на рабочем столе. Это не рекомендуется, пожалуйста, выберите другую папку.
Ошибка сохранения профиля
Ошибка сохранения профиля {0}. {1}\n{2}
@@ -128,6 +165,25 @@
Процессор
+
+ Выбор папки с данными
+ Похоже, у вас нет набора каталогов данных. Каталог данных - это место, где будут храниться ваши профили и SteamCMD. Это не то же самое, что каталог установки сервера, который вы можете выбрать для каждого профиля.
+ Выберите диск, на котором должна находиться папка с данными.
+ Имя папки данных:
+ Имя папки данных диспетчера сервера.
+ Локальный диск
+ {0} свободный от {1}
+
+ Ok
+ Отменить
+ Обновить
+
+ Ошибка выбора каталога данных
+ Введенное вами имя папки данных недействительно.
+ Требуется перезапуск ASM
+ Папка данных настроена, теперь необходимо перезапустить ASM, чтобы использовать новые настройки.
+
+
Закрыть
@@ -398,7 +454,7 @@
Выполнить проверку игрока онлайн
Если включено, процесс выключения будет проверять, находятся ли игроки в сети. Если ни один игрок не находится в сети, льготный период будет прерван, и отключение произойдет немедленно. В противном случае отключение будет ждать, пока не истечет таймер льготного периода.
Отправить сообщения о завершении работы в игровой клиент
- Если этот параметр включен, сообщения о завершении работы будут отправляться игровому клиенту через RCON. ПРИМЕЧАНИЕ. RCON должен быть включен на сервере.
+ Если этот параметр включен, сообщения о завершении работы будут отправляться игровому клиенту через RCON. ПРИМЕЧАНИЕ: RCON должен быть включен на сервере.
Сохранить сервер при выключении.
Если это разрешено, сервер будет сохранен после завершения работы.
Причина (необязательно):
@@ -421,6 +477,7 @@
Сброс
Это приведет к сбросу всех глобальных параметров пользователя в диспетчере сервера. Менеджер сервера будет закрыт, если сброс будет успешным.
Запускать программу в режиме Администратора
+ Режим запуска Главного окна:
Свернуть в трей
Управление параметрами брандмауэра автоматически
Автоматическое управление общедоступным IP-адресом
@@ -434,38 +491,40 @@
Языки
- Настройка перераспределения Настроек
- Включить пользовательские настройки Engine.ini
+ Пользовательские настройки
+ Вкл пользовательские настройки Engine.ini
Если включено, то настройки engine.ini будут менеджерами сервера.
- Включить Crafting Overrides
- Если включено, Crafting Overrides будут использовать настройки ASM.
- Включить переопределение размера стека
- Если включено, переопределение размера стека будет управляться ASM.
- Включить Map Spawner Overrides
- Если включено, Map Spawner Overrides будут использовать настройки ASM.
- Включить Supply Crate Overrides
- Если включено, Supply Crate Overrides будут использовать настройки ASM.
- Включить PGM Ark
- Если включено, процедурная генерация повятся в настройках ASM.
- Включить SotF
- Если включено, SotF появится в настройках ASM.
- ПРЕДУПРЕЖДЕНИЕ. Если любой из этих параметров отключен, ASM не будет читать или записывать связанные с этип параметры переопределения. Повторное включение любого из этих параметров приведет к удалению всех существующих связанных переопределений в файле конфигурации.
+ Вкл настройки Требований для крафта
+ Если включено, то требованием для крафта будет управлять ASM.
+ Вкл настройки Размеров стаков
+ Если включено, то переопределением размера стаков будет управляться ASM.
+ Вкл настройки Спавнов дино
+ Если включено, то спавнами дино будет управлять ASM.
+ Вкл настройки Лучей с дропами
+ Если включено, то настройки лучей с дропом будет управлять ASM.
+ Вкл настройки Запретов трансфера дино
+ Если включено, то настройками запретов трансфера дино будет управлять ASM.
+ Вкл PGM ARK
+ Если включено, то процедурная генерация карт появится в настройках ASM.
+ Вкл SotF
+ Если включено, Survival Of The Fittest появится в настройках ASM.
+ ПРЕДУПРЕЖДЕНИЕ: Если любой из этих параметров отключен, ASM не будет читать или записывать связанные с этип параметры переопределения. Повторное включение любого из этих параметров приведет к удалению всех существующих связанных переопределений в файле конфигурации.
Настройки активных иконок статуса сервера
- Включить активную иконку
+ Вкл активную иконку
Если включено, при нажатии на иконку активности сервера, можно вызвать функцию включения или выключения.
- Показать подтверждение действия
+ Показать подтверждения действий
Если включено, будет показан диалог подтверждения действия статуса сервера.
- Настройки запуска Сервера
+ Настройки запуска сервера
Увеличение уровня игрока:
Количество XP будет увеличено при добавлении нового настраиваемого уровня.
Увеличение уровня динозавров:
Количество XP, которое должно быть увеличено при добавлении нового настраиваемого уровня.
Проверить профиль при старте сервера
- Если включено, при ручном запуске сервера выполняется базовая проверка Сервера и файлов Модов. ПРИМЕЧАНИЕ. Не будет выполнено, если включено авто управление Ark Mod Management(Автоматическое управление Модами).
+ Если включено, при ручном запуске сервера выполняется базовая проверка сервера и файлов модов. ПРИМЕЧАНИЕ: Не будет выполнено, если включено авто-управление Ark Mod Management (автоматическое управление модами).
Выполнение обновления сервера и модов при запуске сервера
- Если включено, при ручном запуске сервера файлы сервера и мод будут обновлены до последней версии. ПРИМЕЧАНИЕ. Не будет выполнено, если включено управление Ark Mod Management(Автоматическое управление Модами).
+ Если включено, при ручном запуске сервера файлы сервера и мод будут обновлены до последней версии. ПРИМЕЧАНИЕ: Не будет выполнено, если включено управление Ark Mod Management(Автоматическое управление Модами).
Steam Настройки
Остановить и закрыть SteamCMD (используйте только для отладки)
@@ -476,7 +535,7 @@
Пароль пользователя учетной записи Steam аккаунта.
Авторизация
Вывести SteamCMD в окно выполнения
- Если включено, выход SteamCMD будет отображаться в окне выполнения, а не в окне команд. ПРИМЕЧАНИЕ. Если этот параметр включен, это может привести к сбою обновления вашего сервера и мод.
+ Если включено, выход SteamCMD будет отображаться в окне выполнения, а не в окне команд. ПРИМЕЧАНИЕ: Если этот параметр включен, это может привести к сбою обновления вашего сервера и мод.
Анонимная учетная запись
Используется анонимная учетная запись для загрузки из SteamCMD.
@@ -536,7 +595,7 @@
Выполнить проверку на Онлайн игроков
Если этот параметр включен, процесс выключения будет проверять, находятся ли игроки в сети. Если ни один игрок не находится в сети, льготный период будет пропущен и отключение произойдет немедленно. В противном случае завершение работы будет ждать, пока не истечет таймер льготного периода.
Отправить сообщения о завершении работы в игровой клиент
- Если этот параметр включен, сообщения о завершении работы будут отправляться игровому клиенту через RCON. ПРИМЕЧАНИЕ. RCON должен быть включен на сервере.
+ Если этот параметр включен, сообщения о завершении работы будут отправляться игровому клиенту через RCON. ПРИМЕЧАНИЕ: RCON должен быть включен на сервере.
Указать период:
Время в минутах через какое сервер будет выключен или обновлен.
Сообщение 1:
@@ -552,6 +611,23 @@
Показывать причину отключения со всеми сообщениями о завершении работы.
Если включено, причина отключения будет показана со всем сообщением о завершении работы; в противном случае это будет отображаться только в начале выключения сервера.
+ Включить Discord бота
+ Вам нужно будет перезапустить ASM, если вы измените какие-либо настройки для бота Discord.
+ Токен:
+ Токен, связанный с ботом Discord.
+ Сервер Id:
+ Идентификатор сервера Discord, который бот будет слушать.
+ Префикс:
+ Префикс, который необходимо использовать при отправке команды через Discord.
+ Получить токен ...
+ Помощь...
+ Если включено, команду резервного копирования можно отправить из Discord.
+ Если этот параметр включен, команда перезапуска может быть отправлена из Discord.
+ Если включено, команду выключения можно отправить из Discord.
+ Если этот параметр включен, команда запуска может быть отправлена из Discord.
+ Если этот параметр включен, команда остановки может быть отправлена из Discord.
+ Если включено, команду обновления можно отправить из Discord.
+
SMTP Настройки Email
Хост:
Имя или IP-адрес хоста, используемого для передач SMTP.
@@ -603,6 +679,8 @@
Изменение каталога данных приведет к перемещению любых существующих профилей в новое место, но оно не будет перемещать установки сервера. Вы все еще хотите изменить этот каталог?
Не удалось изменить каталог данных
При изменении каталога данных произошла ошибка: {0}\r\nПожалуйста, исправьте ошибку и повторите попытку или обратитесь в службу технической поддержки.
+ Подтвердить сброс каталога данных
+ Нажмите «Да», чтобы подтвердить, что вы хотите сбросить расположение каталога данных. После сброса ASM выключится, и вам нужно будет перезагрузить.
Выбрать Каталок Бекапов
Выберете директорию Авто-Обновления кеша
@@ -649,11 +727,11 @@
Это сообщение будет отображаться при изменении состояния сервера.
Обнаружено обновление мода:
Это сообщение будет отображаться, когда менеджер сервера обнаружит, что один или несколько модов устарели.
- Предупреждение о респавно динозавров:
+ Предупреждение о респавне динозавров:
Это сообщение будет отображаться при запуске сервера и оповещение о запланированном респе динозавров
-
+
ARK: Survival Evolved™ Server Manager
ARK: Survival Evolved™ Server Manager (Administrator)
ARK: Survival Evolved™ Server Manager
@@ -716,6 +794,9 @@
Ошибка переустановки SteamCMD
Произошла ошибка при попытке переустановки SteamCMD. Попробуйте повторно установить или сообщите об этом.\r\nException: {0}
+ Команды запуска бота Discord
+ У бота Discord есть одна или несколько запущенных команд, вы хотите продолжить выключение ASM?
+
Подтверждение запуска сервера
Вы собираетесь запустить сервер, хотите продолжить?
Подтверждение остановки сервера
@@ -754,6 +835,8 @@
+ ID профиля:
+ Уникальный ID, присвоенный профилю.
Профиль:
Имя профиля сервера. Это не публичное имя которое будут видеть пользователи в ARK. Для этого заполните поле "Имя сервера".
Установленная версия:
@@ -1004,10 +1087,10 @@
Использовать No Memory Bias
Если включено, будет использоваться старый метод, больше использования ОЗУ, но нет потенциальной потери производительности.
Stasis Keep Controllers
- Если это разрешено, сервер может получить производительность, сохранив AI в памяти о статусных существах. ПРИМЕЧАНИЕ. На вашем сервере должно быть много ОЗУ, иначе ваш сервер будет страдать с большими издержками памяти.
+ Если это разрешено, сервер может получить производительность, сохранив AI в памяти о статусных существах. ПРИМЕЧАНИЕ: На вашем сервере должно быть много ОЗУ, иначе ваш сервер будет страдать с большими издержками памяти.
Нет Hang Detection
Если включено, предотвращает появление некоторых типов сбоев путем зависания (может показаться, что сервер отстает, пока сервер висит).
- Нет Динозавров
+ Нет динозавров
Если включено, на карте не появятся динозавры.
Разрешить Ansel
Если включено, разрешает NVIDIA Ansel на серверах.
@@ -1018,55 +1101,55 @@
No Under Mesh Killing
Если включено, отключит убивание персонажей системой анти-меш под текстурами (но телепортирование все же останется)
Включить Vivox
- Если включено, включит Vivox. ПРИМЕЧАНИЕ. Только для серверов Steam.
+ Если включено, включит Vivox. ПРИМЕЧАНИЕ: Только для серверов Steam.
Разрешить общие подключения
Если отключено, семейный доступ будет отключен.
Включить Crossplay
Если включено, включит crossplay, так что игроки, использующие клиентов из разных магазинов, могут подключаться к выделенному серверу.
- Включить Epic Store
+ Разрешить только Epic Store
Если включено, разрешит подключение только игрокам, использующим клиент Epic store.
Включить публичный IP для Epic
Если включено, добавит аргумент сервера для общедоступного IP-адреса, к которому будут пытаться подключиться клиенты EPIC.
Перезаселить Мир во время Запуска сервера (Вызывает лаг после запуска Сервера)
Если включено, при запуске сервера все дикие существа будут уничтожены и обновлены (это уничтожит только диких существ, которые в настоящее время не приручены).
- Включить Авто Респаун Динозавров
- Если включено, принудительное возрождение диких Динозавтров через указанный интервал.
- Интервал Респауна Диких Дино
- Интервал между принудительным автоматическим респауном динозавров.
- Альтернативная папка Сохранения:
+ Включить Авто Респаун динозавров
+ Если включено, принудительное возрождение диких динозавтров через указанный интервал.
+ Интервал респауна диких дино
+ Интервал между автоматическим респауном динозавров.
+ Альтернативная папка сохранения:
(Необязательно)
Устанавливает имя каталога (под серверами «Сохраненная папка») для хранения файлов мира, игрока и племени.
- Установить КластерID Cross-ARK:
- Устанавливает идентификатор Кластера для этого сервера, который будет группировать серверы ARK вместе с помощью передачи данных Cross-ARK.
+ Установить айди кластера:
+ Устанавливает идентификатор, который будет объединять сервера в один общий кластер.
Установить каталог Кластера
Если это разрешено, вы можете использовать общее хранилище Кластера, которое работает между несколькими серверами, работающими на одном компьютере.
- Настройки Логов Сервера
- Сброс всех настроек Логов сервера по умолчанию.
- Вкл. лог Админа сервера
- Если опция включена, логи администратора сервера (включая поддержку RCON) будут задействован.
- Максимальный лог Племя:
- Устанавливает максимальное количество записей в лог Племя, которые хранятся в Племени (по умолчанию 100).
- Логи Администратора сервера включают Логи Племени
- Если включено, он будет записывать все Логи племени (для всех племен) в файлы Логов Shootergame.
- Вывод в RCON логов Племени.
- Если включено, он будет записывать все Логи Племени (для всех Племен) в окно RCON.
- Разрешить скрывать источник повреждений в логах
- Если включено, заставит Silencer скрыть имя игрока, который убил вас из сообщения об убийстве в журнале племени.
- Лог Админа в чат
- Если включен, команды администратора будут отображаться в чате
- Лог Админ команд в чате (только Админ)
- Если включено, команды администратора будут отображаться в чате для администраторов только для просмотра.
- Лог Племени об уничтожении строений Врагом
- Если включено, журнал уничтожения строений противником (для Племени жертвы) отобразит Племя злоумышленника в журналах Племени, а не общее сообщение об уничтожении строений.
+ Настройки логов сервера
+ Сброс всех настроек логов сервера по умолчанию.
+ Вкл логи администратора сервера
+ Если включено, то логи администратора сервера будут включены (включая поддержку RCON).
+ Размер логов трайба:
+ Устанавливает максимальное количество записей в логах трайба (по умолчанию 100).
+ Логи администратора сервера содержат логи трайбов
+ Если включено, то все логи трайбов на сервере будут записываться в файле ShooterGame\Saved\Logs\ShooterGame.log.
+ Показывать логи трайбов в RCON
+ Если включено, то все логи трайбов на сервере будут отображаться в окне RCON (окно RCON обязательно должно быть открыто!).
+ Разрешить скрыть источник повреждений в логах
+ Если включено, то в логах трайба не будет отображаться кто вас убил.
+ Вкл отображение логов администратора в чате (для всех)
+ Если включено, то логи введённых команд администратора будут отображаться в игровом чате (видны всем).
+ Вкл отображение логов администратора в чате (только для администраторов)
+ Если включено, то логи введённых команд администратора будут отображаться в игровом чате (видны только администраторам).
+ Вкл отображение в логах кто уничтожил структуры
+ Если включено, то в логах будет отображено кто или какой трайб уничтожил ваши структуры, а не общее сообщение об уничтожении структур (для пострадавшего трайба).
- Включить Web Alarms
+ Вкл Web Alarms
Если это разрешено, серверы теперь могут получать сетевые уведомления, размещенные где-то, когда важные вещи случаются с племенем.
Web Key
Ключ, который необязательно использовать в скрипте прослушивания, но должен быть в текстовом файле.
Web URL
Указывает URL-адрес, в котором хранится ваш скрипт прослушивания, ожидающий и готовый к отправке информации о вашем сервере.
- ПРИМЕЧАНИЕ. ASM не предоставляет функциональность Web Alarms. ASM позволяет вам включать/отключать Web Alarms и создавать необходимые файлы AlarmPostCredentials.
+ ПРИМЕЧАНИЕ: ASM не предоставляет функциональность Web Alarms. ASM позволяет вам включать/отключать Web Alarms и создавать необходимые файлы AlarmPostCredentials.
Web оповещение об ошибке
Детали веток
@@ -1077,7 +1160,7 @@
Clear Branch Error
Event детали
- NOTE: Включение события на вашем сервере должно выполняться только во время официального события. Если вы включите событие до или после официальных дат, событие может привести к нестабильной работе вашего сервера или вообще не работать.
+ ПРИМЕЧАНИЕ: Включение события на вашем сервере должно выполняться только во время официального события. Если вы включите событие до или после официальных дат, событие может привести к нестабильной работе вашего сервера или вообще не работать.
Активный Event:
Имя события, которое нужно включить (оставьте пустым, чтобы отключить событие).
@@ -1106,99 +1189,121 @@
Автоматически запускать сервер при включении компьютера.
Выключить сервер в
Укажите время выключения сервера (формат в ЧЧ:ММ)
- затем перезагрузить
- Если включено, перезагрузить сервер сразу после завершения работы
- Выполнять обновление
- Если включено, обновит сервер после завершения работы
- Включить периодический Авто-Бекап
+ Перезагрузить
+ Если включено, то сервер сразу перезапустится после завершения работы
+ Обновить
+ Если включено, запустится обновление сервере после завершения работы
+ Вкл периодический Авто-Бекап
Если этот параметр включен, сервер будет периодически Авто-Бекапиться. Смотреть и редактировать в "Глобальные настройки".
- Включить периодические Авто-Обновления
+ Вкл периодические Авто-Обновления
Автоматически проверяет наличие обновлений сервера и модов. Если они присутствуют, запускает их установку. Смотреть и редактировать в "Глобальные настройки"
Перезапустить сервер при завершении работы
Если этот параметр включен, сервер будет перезагружен, даже если вы отключите Автозапуск и Авто-Обновление.
+
+ Детали бота Discord
+ Канал Id:
+ ID канала сервера Discord, который будет слушать этот профиль.
+ Разрешить Бекап
+ Если этот параметр включен, профиль будет прослушивать команды Бекапа от Discord.
+ Разрешить Перезагрузку
+ Если этот параметр включен, профиль будет прослушивать команды перезапуска от Discord.
+ Разрешить Выключение
+ Если этот параметр включен, профиль будет прослушивать команды выключения из Discord.
+ Разрешить Запуск
+ Если этот параметр включен, профиль будет прислушиваться к командам запуска от Discord.
+ Разрешить Остановку
+ Если этот параметр включен, профиль будет прислушиваться к командам остановки от Discord.
+ Разрешить Обновление
+ Если этот параметр включен, профиль будет прослушивать команды обновления от Discord.
+
+
Правила сервера
- Включить Хардкор режим
- Включает Хардкор режим (игроки не могут возрождаться после смерти, должен быть создан новый персонаж).
- Включить PvP
- Включает PvP режим (игроки могут нанести повреждения или убить друг друга. В PvP игроки также могут повредить или разрушить здания другого племени или убить их Динозавров).
- Включить PvE постройки в пещерах
- Если этот параметр включен, позволяет строить в пещерах PvE режиме.
- Включить PvE Cryo Недомогание
- Если включено, при вытаскивании прирученного существо из криокапсулы, включится таймер крио-болезни. Для PvE серверов.
- Отключить огонь по своим в PvE
- Если этот параметр включен, игроки не могут нанести повреждения или убить других членов племени, Динозавров и разрушить структуры.
- Отключить Разграбление ящиков
- Если этот параметр включен из разграбленных ящиков не будет появляться лут (контейнеры артефактов по-прежнему работают).
- Лучи дропа, останавливаются на крыше строений
- Если включено, лучи останавливаются на верхней части строения, а не проходят сквозь него до земли.
- Рандомный респ Снабжения
- Если это разрешено, ящики снабжения респаются случайными образом.
- Запрещает строительство в зонах респа ресурсов.
+ Вкл режим Хардкор
+ Включает режим Хардкор (игроки не могут возрождаться после смерти, должен быть создан новый персонаж).
+ Вкл PvP
+ Включает PvP режим (игроки могут нанести повреждения или убить друг друга. В PvP игроки также могут повредить или разрушить структуры другого тарйба или убить их динозавров).
+ Включить Творческий Режим
+ Если включено, разрешает творческий режим.
+ Вкл строительство в пещерах в PvE
+ Если этот параметр включен, позволяет строить в пещерах в PvE режиме.
+ Вкл крио-недомогание в PvE
+ Если включено, при вытаскивании прирученного существа из криокапсулы, включится таймер крио-болезни (для PvE серверов).
+ Откл урон по своим в PvE
+ Если этот параметр включен, игроки не могут нанести повреждения или убить других членов трайба, динозавров и разрушить структуры.
+ Откл спавн лучей с дропом
+ Если включено, то лучи с дропом не будут появляться на сервере (артефакты по-прежнему будут появляться).
+ Вкл остановку лучей с дропом на крыше строений
+ Если включено, лучи с дропом останавливаются на верхней части строения, а не проходят сквозь него до земли.
+ Рандомный респ снабжения
+ Если это разрешено, то лучи спавнятся случайным образом.
+ Запретить строительство в зонах респауна ресурсов.
Если включено, полностью запрещает строительство в зонах с богатыми ресурсами, в частности настройка на карте TheIsland вокруг основных гор.
- Отключить огонь по своим в PvP
- Если этот параметр включен, игроки не могут нанести повреждения или убить других членов племени, Динозавров и разрушить структуры.
- Включить Луч для поиска Лута
- Если включено, после смерти луч света стреляет в небо, чтобы помочь игроку найти место, где он погиб.
- Отключит анимацию респауна.
- Если включено, отключит анимацию респауна(поднятие с кровати).
- Разрешить бесконечно использовать суп "Амнезия"
- Если включено, разрешает неограниченно использовать суп "Амнезия" на сервере.(по умолчанию 1 раз за уровень)
- Разрешает постройку на платформе нескольких уровней
- Если включено, разрешает постройку в несколько уровней под платформами.
+ Откл урон по своим в PvP
+ Если этот параметр включен, игроки не могут нанести повреждения или убить других членов трайба, динозавров и разрушить структуры.
+ Вкл луч для поиска трупа
+ Если включено, то после смерти над вашим трупом будет виден зелёный луч света, чтобы помочь игроку найти место, где он погиб.
+ Откл анимацию респауна
+ Если включено, то отключится анимация респауна (поднятие с кровати).
+ Разрешить бесконечно использовать тоник "Амнезия"
+ Если включено, разрешает неограниченно использовать тоник "Амнезия" на сервере (по умолчанию только 1 раз за уровень).
+ Разрешить постройку под платформами в несколько уровней
+ Если включено, разрешает постройку в несколько уровней под платформами (на плотах).
Увеличение зоны строительства на платформах
- Увеличение множителя позволяет размещать конструкции дальше от платформы.
- Максимальное кол. ворот на седлах-платформах
+ Увеличение множителя позволяет размещать структуры дальше от края платформы.
+ Макс количество ворот на седлах-платформах
Ограничивает количество ворот, которые можно разместить на седлах-платформах. Этот вариант не имеет обратной силы, поэтому применение этого изменения потребует некоторой ручной административной работы, чтобы очистить все существующие платформы, превышающие лимит.
Включить перераспределение сложности
Если включено, это позволит изменить максимальный уровень существ в мире.
- Максимальный уровень Динозавров:
+ Максимальный уровень динозавров:
Определяет максимальные уровни существ в мире. Чем выше значение, тем выше максимальный уровень существа.
Максимальные уровни существ:
Определяет максимальные уровни существ в мире. Чем выше значение, тем выше максимальный уровень существа.
+ Destroy Tames Over Level:
+ Tames that exceed this level will be deleted on server start. To disable deletion set to 0.
- Включить загрузку данных
- Если этот параметр включен, это позволит загружать Выживших/Предметов/Динозавров на ваш сервер.
- Не загружать Выживших
- Если включено, загрузка Выживших отключена.
- Не загружать Предметы
- Если включено, загрузка предметов отключена.
- Не загружать Динозавров
- Если включено, загрузка Динозавров отключена.
+ Вкл загрузку из данных кластера
+ Если включено, это позволит загружать выживших/предметов/динозавров на сервер.
+ Откл загрузку выживших на сервер
+ Если включено, загрузка выживших на сервер отключена.
+ Откл загрузку предметов на сервер
+ Если включено, загрузка предметов на сервер отключена.
+ Откл загрузку динозавров на сервер
+ Если включено, загрузка динозавров на сервер отключена.
- Включить выгрузку данных
- Не выгружать Выживших
- Если включено, выгрузка Выживших отключена.
- Не выгружать Предметы
- Если включено, выгрузка Предметов отключена.
- Не выгружать Динозавров
- Если включено, выгрузка Динозавров отключена.
- Максимум хранимых Дино
- Если включено, будет ограничено количество динозавров, которые игрок может хранить в обелисках. ПРИМЕЧАНИЕ. Установка этого значения может привести к повреждению кластера.
- Максимум хранимых Предметов
- Если включено, будет ограничено количество предметов, которые игрок может хранить в обелисках. ПРИМЕЧАНИЕ. Установка этого значения может привести к повреждению кластера.
+ Настройки выгрузки в данные с сервера
+ Откл выгрузку выживших в данные
+ Если включено, выгрузка выживших в данные (облако) отключена.
+ Откл выгрузку предметов в данные
+ Если включено, выгрузка предметов в данные (облако) отключена.
+ Откл выгрузку динозавров в данные
+ Если включено, выгрузка динозавров в данные (облако) отключена.
+ Макс хранимых дино в данных
+ Если включено, то можно изменить количество динозавров, которые игрок может хранить в данных (облаке). ПРИМЕЧАНИЕ: установка этого значения может привести к повреждению данных кластера.
+ Макс хранимых предметов в данных
+ Если включено, то можно изменить количество предметов, которые игрок может хранить в данных (облаке). ПРИМЕЧАНИЕ: установка этого значения может привести к повреждению данных кластера.
- Настройки работы Кластера
- Трансфер только по Фильтру (Кластер)
- Если включено, передача Выживших, предметов и Динозавров отключена, если сервер не находится в одном кластере.
- Изменить время хранения выгруженного Выжившего.
- Если включено, вы можете выставить время хранения Выжившего в Кластере.
- Изменить время хранения выгруженного Предмета.
- Если включено, вы можете выставить время хранения Предмета в Кластере.
- Изменить время хранения выгруженного Динозавра.
- Если включено, вы можете выставить время хранения Динозавра в Кластере.
- Установить время повторной выгрузки Динозавров
- Если включено, вы сможете указать интервал повторной выгрузки Динозавров.
- Разрешить загрузку дино на Aberration
- Если включено, позволит вам загружать на карту Aberration дино с других карт
+ Настройки работы кластера
+ Трансфер только по Фильтру (кластер)
+ Если включено, то трансфер Выживших, предметов и динозавров отключен, если сервер не находится в одном кластере.
+ Изменить время хранения выживших в данных
+ Если включено, вы можете изменить время хранения Выжившего в данных (облаке).
+ Изменить время хранения предметов в данных
+ Если включено, вы можете изменить время хранения предмета в данных (облаке).
+ Изменить время хранения дино в данных
+ Если включено, вы можете изменить время хранения динозавров в данных (облаке).
+ Установить время повторной выгрузки дино в данные
+ Если включено, вы сможете указать интервал повторной выгрузки динозавров в данные (облако).
+ Разрешить загрузку дино из данных на Аберрацию
+ Если включено, то это позволит вам загружать динозавров из данных на карту Aberration.
Увеличить интервал респауна в PvP
Если этот параметр включен, позволяет увеличить интервал респауна в PvP.
Время проверки интервала
- Проверка времени респауна продолжается после того, как игрок убит группой.
+ Проверка времени респауна продолжается после того, если игрок был убит группой игроков (макс время респауна, которое может настакаться при частых смертях).
секунд
Множитель интервала:
Множитель значения базовой суммы для определения времени респауна.
@@ -1206,13 +1311,13 @@
Базовая сумма интервала:
Период базового времени, используемый для определения времени респауна.
секунд
- Предотвратить Оффлайн PvP
+ Запретить Оффлайн PvP
Если включено, активируется опция предотвращения Оффлайн-Рейдов.
Время до активации защиты
- Период времени до того, как Выжившие / Динозавры / Структуры становятся неуязвимыми (ВСЕ игроки Племени должны быть оффлайн).
+ Время до того, как Выжившие, динозавры и структуры становятся неуязвимыми (ВСЕ игроки из трайба должны быть оффлайн).
секунд
- Баф бесмертия при входе в игру
- На сколько секунд при входе в игру, дается бафф бесмертия. Для предотвращения убийство персонажа сразу после входа.
+ Бафф бесмертия при входе в игру
+ На какое время при входе в игру, дается бафф бесмертия (в секундах). Настройка для предотвращения убийства персонажа сразу после входа на сервер.
Расписание PvE
Если этот параметр включен, позволяет переключаться между PvE и PvP в заранее определенное время в игре или предварительно заданные промежутки времени в реальном мире.
@@ -1226,21 +1331,21 @@
Максимальное число игроков в Племени:
Установите для 0 для неограниченного числа игроков в племени, установите число > 0, чтобы включить ограничение.
игроков
- Сменить название Трайба после перезагрузки
+ Сменить название трайба после перезагрузки
Изменения названия Трайба вступят в силу, после перезагрузки Сервера.
Повторное использование названия племени
Блокирует ячейку племени, поэтому, когда член племени покидает ее, ячейка не может быть использована повторно, пока не истечет время восстановления. Установите 0, чтобы отключить перезарядку.
- Разрешить Альянсы Племен
- Если включено, игроки могут создавать Альянсы с другими Племенами.
- Максимальное количество Альянсов в Трайбе
+ Разрешить альянсы
+ Если включено, игроки могут создавать альянсы с другими трайбами.
+ Максимальное количество альянсов в трайбе
Максимальное количество альянсов разрешено для каждого трайба.
Максимальное число Трайбов в Альянсе
Максимальное количество трайба, разрешенных в каждом альянсе.
- Параметры PvE "Войны Племен"
- Разрешить "Войны Племен"
- Если этот параметр включен, для племен есть возможность официально объявить войну друг другу и взаимно согласовать период времени военного положения.
- Разрешить отмену "Войны Племен"
- Если этот параметр включен, племена могут отменить согласованную войну, прежде чем она началась.
+ Параметры PvE "Война между трайбами"
+ Разрешить "Войну между трайбами"
+ Если этот параметр включен, для трайбов есть возможность официально объявить войну друг другу и взаимно согласовать период времени военного положения.
+ Разрешить отмену "Войны между трайбами"
+ Если этот параметр включен, трайбы могут отменить согласованную войну, прежде чем она началась.
Разрешить пользовательские рецепты
Если этот параметр включен, игроки могут использовать пользовательские RP-ориентированный Рецепт/Систему Кулинарии (в том числе на основе результатов навыка).
@@ -1249,67 +1354,74 @@
Множитель навыка
Определяет множитель для навыка пользовательского рецепта. Более высокие значения увеличивают навык рецепта.
- Включить Заболевания
+ Включить болезни
Если включено, на сервере появятся болезни и игроки будут болеть.
Непостоянные болезни
- Если включено, это сделает болезни не постоянными (они пропадут, если будет респаун).
+ Если включено, это сделает болезни не постоянными (они пропадут при смерти).
- Определить NPC заморозку при Онлайне
+ Определить NPC заморозку при онлайне
Если включено, вы можете переопределить настройки радиуса заморозки NPC от игроков.
Минимальное кол-во игроков для включения
- Минимальное количество онлайн-игроков при включенной шкале статуса.
+ Минимальное кол-во онлайн-игроков при включенной шкале статуса.
Максимальное кол-во игроков для выключения
- Максимальное количество онлайн-игроков при включенной шкале статуса.
+ Максимальное кол-во онлайн-игроков при включенной шкале статуса.
Максимальный процент
Максимальный процент масштабирования, используемый сервером при достижении конечного значения счетчика онлайн-игроков.
- Скорость расхода кислорода
+ Расход кислорода
Установить множитель, как скорость плавания влияет на трату кислорода.
Качества добычи в контейнерах
- Множитель для качества добычи в контейнерах (принимают значения от 1 до 5)
- Качества добычи с рыбалки
- Множитель для качества добычи с рыбалки (принимают значения от 1 до 5)
- Отключить Non-Meat Fish Loot
- Если включено, отключает сбор дропа кроме мяса с рыбы.
+ Множитель для качества добычи в лучах/ящиках (значения от 1 до 5)
+ Качества добычи при рыбалке
+ Множитель для качества добычи с рыбалки (значения от 1 до 5)
+ Откл. добычу предметов при рыбалке
+ Если включено, то это отключает добычу предметов (кроме мяса) во время рыбалки.
Множитель удаления трупа и дропа
Множитель времени до удаления трупов и выброшенных предметов
Долговечность заряда батареи
Определяет множитель скорости, с которой зарядные батареи расходуются в электрических приборах
Множитель интервала расхода топлива
Определяет множитель для интервала расхода топлива.
- Limit Non Player Dropped Items Range
- (Расстояние)Ограничить количество выбрасываемых предметов в области (вместе с LimitNonPlayerDroppedItemsCount).
- Limit Non Player Dropped Items Count
- (Колличество)Ограничить количество выбрасываемых предметов в области (вместе с LimitNonPlayerDroppedItemsRange).
+ Область кол-ва выброшенных предметов
+ Область, в которой может быть выброшено определённое количество предметов (связано с настройкой LimitNonPlayerDroppedItemsCount). На официальных серверах установлено значение 1600.
+ Ограничение кол-ва выброшенных предметов
+ Количество выброшенных предметов в области (связано с настройкой LimitNonPlayerDroppedItemsRange). На официальных серверах установлено значение 600.
- Включить работу Тек костюма
+ Вкл. криопод Nerf
+ Если включено, то можно будет настроить количество урона, которое наносит дино или которое будет получать в течение некоторого времени после того, как оно было выпущено из криопода.
+ Длительность
+ Время в секундах, в течение которого настройки урона, указанные ниже, будут применяться для дино, выпущенных из криопода.
+ Исходящий урон
+ Определяет множитель исходящего урона у дино, после того, как он был выпущен из криопода. Более низкие значения означают, что исходящий урон будет ниже (например, 0.01 означает, что урон дино будет понижен на 99%).
+ Входящий урон
+ Определяет процентное увеличение множителя входящего урона по дино, после того, как оно было выпущено из криопода. Более высокие значения означают, что дино будет получать больше входящего урона (например, 0.25 означает, что на 25% больше урона будет получать дино).
+
+ Вкл. работу Тек костюма
Если включено, позволит игроку использовать Тек костюм на карте Genesis.
- Отключить миссии
+ Откл. миссии
Если включено, отключит все миссии на карте Genesis.
- Отключить костюм TEK на Спавне
- Если включено, это предотвратит появление игрока в костюме TEK.
+ Откл. получение Тек костюма при возрождении
+ Если включено, это предотвратит появление Тек костюма на игроке после возрождения.
+
+ Откл. мировые баффы
+ Если включено, то полностью отключит мировые эффекты от миссий.
+ Вкл. масштабирование мирового баффа
+ Если включено, это приведет к тому, что мировые баффы будут мультипликативно масштабировать свои преимущества, а не добавлять/вычитать фиксированную сумму к значению во время выполнения.
+ Эффективность масштабирования мирового баффа
+ Задает глобальный скаляр для снижения/повышения эффективности мировых баффов (например, 1 по умолчанию, 0,5 будет на 50% менее эффективным, 2,0 будет в 2 раза эффективнее).
Шестигранники
- Отключить магазин Шестигранников
- Если включено, магазин Шестигранников будет отключён.
+ Откл. магазин шестигранников
+ Если включено, магазин шестигранников будет отключён.
Разрешить продажу только Энграммам
Если включено, только энграммы могут быть проданы в магазине шестигранников, отключает все остальное.
- Максимальное колличество шестигранников на игрока.
+ Максимальное кол-во шестигранников для игрока.
Задает максимальное количество шестигранников, которое может иметь каждый игрок.
Множитель награды шестигранниками
Задает множитель для наград в виде шестигранников.
- Множитель цены в магазине шестигранников
+ Множитель цены в магазине за шестигранники
Позволяет изменять стоимость предметов в магазине шестигранников
-
- Включить криопод Nerf
- Если этот параметр включен, он будет корректировать количество урона, которое наносит существо в течение некоторого времени после того, как оно было выпущено из криопода.
- Криопод Nerf Продолжительность
- Время в секундах, в течение которого корректировка урона будет действовать для существ, выпущенных из криопода.
- Криопод Nerf Множитель урона
- Определяет множитель урона, нанесенного существам после того, как они были выпущены из криопода. Более низкие значения означают, что нанесенный урон будет ниже (например, 0,01 означает, что 99% ущерба будет удалено).
- Процент множителя входящего урона
- Определяет процентное увеличение множителя входящего урона существа после того, как оно было выпущено из криопода. Более высокие значения означают больше входящего урона, нанесенного существу (например, 0.25 = 25% больше урона).
Item Stat Clamps
ПРЕДУПРЕЖДЕНИЕ: это навсегда изменит статистику любых существующих элементов, поэтому обязательно сделайте резервную копию вашего текущего сохранения, прежде чем изменять и играть с ограничивающими значениями.
@@ -1336,48 +1448,48 @@
- HUD и визуальные эффекты
- Разрешить прицел
- Если этот параметр включен, каждый игрок видит прицел.
- Разрешить HUD
- Если этот параметр включен, позволяет игроку видеть HUD.
- Разрешить вид от третьего лица
+ Интерфейс и визуальные эффекты
+ Вкл. прицел
+ Если этот параметр включен, позволяет игрок видит прицел.
+ Вкл. отображение интерфейса
+ Если этот параметр включен, позволяет игроку видеть интерфейс.
+ Вкл. вид от третьего лица
Если этот параметр включен, позволяет игрокам включать вид от третьего лица.
- Разрешить позицию игрока на карта
+ Вкл. местоположение на карта
Если этот параметр включен, показывает каждому игроку их положение на карте.
- Разрешить гамму в PvP
- Если этот параметр включен, позволяет изменять гамму в режиме PvP.
- Разрешить гамму в PvE
- Если этот параметр включен, позволяет изменять гамму в режиме PvE.
- Показывать урон
- Если этот параметр включен, урон будет показан в RPG-стиле, всплывающими сообщениями.
- Разрешить маркеры
- Если включено, отображает маркеры ударов для дальних атак.
+ Вкл. гамму в PvP
+ Если этот параметр включен, позволяет изменять гамму в PvP режиме.
+ Вкл. гамму в PvE
+ Если этот параметр включен, позволяет изменять гамму в PvE режиме.
+ Вкл. отображение урона
+ Если этот параметр включен, будет отображаться нанесённый и полученный урон в виде всплывающего текста.
+ Вкл маркеры попаданий
+ Если этот параметр включен, отображает маркеры попаданий для дальних атак.
Настройки игрока
- Включить "Захват"
- Если этот параметр включен, во время полета на летающих динозаврах, разрешено подбирать других динозавров и игроков режиме PvE.
- Множитель XP:
+ Вкл. "схватить в лапы"
+ Если этот параметр включен, во время полета на летающих динозаврах, разрешено подбирать других динозавров и игроков в PvE режиме.
+ Получение опыта:
Определяет коэффициент для опыта, полученного игроками. Более высокие значения увеличивают количество XP присужденных для различных мероприятий; более низкие значения уменьшают его.
- Сброс максимального значения XP Cap до официального значения по умолчанию
+ Сброс максимального значения опыта (XP Cap) до официального значения по умолчанию
Урон:
Задает коэффициент для повреждения, наносимые при нападении. Более высокие значения увеличивают урон. Более низкие значения уменьшить его.
- Сопротивление:
+ Сопротивление урону:
Определяет коэффициент для сопротивления получаемого урона при атаке. Более высокие значения уменьшают сопротивление, увеличивая урон в атаке. Более низкие значения увеличивают его, снижая урон в атаке.
Потребление воды:
Определяет коэффициент для потребления воды. Более высокие значения увеличение потребления воды (хочет пить чаще).
Потребление еды:
- Определяет коэффициент для потребления продуктов питания. Более высокие значения увеличивают потребление пищи (хочет есть чаще).
+ Множитель скорости потребления пищи. Более высокие значения увеличивают потребление пищи (быстрее голодает).
Расход выносливости:
Задает коэффициент для потребления выносливости. Более высокие значения увеличивают потребление выносливости (устает быстрее).
Восстановление здоровья:
Определяет коэффициент для восстановления здоровья. Более высокие значения увеличивают скорость восстановления (раны заживают быстрее).
- Урон при сборе:
+ Урон при сборе ресурсов:
Определяет коэффициент для степени повреждения во время сбора ресурсов. Более высокие значения увеличивают степень повреждения. Более низкие значения уменьшают его.
- Урон турелями:
- Определяет коэффициент урона турелью по Дино, на персонажей не распространяется (пули и снаряды турели). Более высокие значения увеличивают урон турелью. Более низкие значения уменьшают.
+ Урон турелей (дино):
+ Определяет коэффициент урона турелью по динозаврам, на персонажей не распространяется (пули и снаряды турели). Более высокие значения увеличивают урон турелей. Более низкие значения уменьшают.
Начальные параметры статов
Поуровневый множитель статов
@@ -1407,7 +1519,7 @@
Определяет множитель для переноса груза за каждый уровень. Более высокие значения увеличивают грузоподъемность быстрее; более низкие значения увеличивают грузоподъемность более медленно.
Определяет множитель для базового веса. Более высокие значения повышают базовый вес; Более низкие значения уменьшают базовый вес.
Урон:
- Определяет множитель для усиления урона на уровень. Более высокие значения увеличивают урон быстрее; более низкие значения увеличивают урон медленнее.
+ Определяет множитель для усиления урона за уровень. Более высокие значения увеличивают урон быстрее; более низкие значения увеличивают урон медленнее.
Определяет множитель для базового урона. Более высокие значения повышают базовый урон; Более низкие значения уменьшают базовый урон.
Скорость:
Определяет множитель для усиления скорости на уровне. Более высокие значения увеличивают скорость быстрее; более низкие значения увеличивают скорость медленнее.
@@ -1422,86 +1534,86 @@
Подтвердить сброс
Нажмите «Да», для подтверждения, что вы хотите сбросить Max XP.
- Бонус навыка Крафтинг
- Определяет множитель для бонуса навыка Крафтинг.
+ Бонус навыка крафта
+ Определяет множитель для бонуса навыка крафта.
Максимальная скорость падения
- Определяет множитель скорости падения, при котором игроки начинают получать урон от падения. Например, если установить значение 0,1, игроки больше не будут выживать при обычном прыжке, а его значение очень высокое, например 100,0, означает, что игроки переживут падение с предела неба.
+ Определяет множитель скорости падения, при котором игроки начинают получать урон от падения. Например, если установить значение 0.1, то игроки не переживут обычный прыжок. А если его значение очень высокое, например 100.0, то игроки переживут падение с неба.
- Максимально ручных:
- Установить максимальное количество домашних динозавров на сервере.
- Максимально ручных: (Племя):
- Установить максимальное количество домашних динозавров в Племени.
- Параметры Дино
- Урон домашними:
- Сопротивление домашними:
- Испражнения диких Дино:
- Определяет интервал испражнений диких динозавров. Более высокие значения увеличивают колличество испражнений. Более низкие значения уменьшают его.
- Испражнения прирученных Дино:
- Определяет интервал испражнений прирученных динозавров. Более высокие значения увеличивают колличество испражнений. Более низкие значения уменьшают его.
- Испражнение оглушенных диких Дино:
- Определяет интервал испражнений оглушенных диких Дино. Более высокие значения увеличивают колличество испражнений. Более низкие значения уменьшают его.
- Испражнение оглушенных прирученных Дино:
- Определяет интервал испражнений оглушенных прирученных Дино. Более высокие значения увеличивают колличество испражнений. Более низкие значения уменьшают его.
- Пассивный интервал испражнений:
- Определяет интервал испражнений между пассивными и по активации. Более высокие значения увеличивают колличество испражнений. Более низкие значения уменьшают его.
+ Макс прирученных дино (сервер):
+ Устанавливает максимальное количество прирученных динозавров на сервере.
+ Макс прирученных дино (трайб):
+ Устанавливает максимальное количество прирученных динозавров в трайбе.
+ Параметры динозавров
+ Урон прирученными:
+ Сопротивление прирученными:
+ Потребление еды у диких:
+ Множитель скорости потребления пищи у диких динозавров. Более высокие значения увеличивают потребление пищи (динозавры быстрее голодают). Это также влияет на время приручения.
+ Потребление еды у прирученных:
+ Множитель скорости потребления пищи у прирученных динозавров. Более высокие значения увеличивают потребление пищи (динозавры быстрее голодают). Это также влияет на время приручения.
+ Скорость спада оглушения у диких:
+ Множитель того, насколько быстро дикие динозавры теряют оглушение. Более высокие значения увеличивают скорость падения оглушения. А более низкие значения уменьшают.
+ Скорость спада оглушения у прирученных:
+ Множитель того, насколько быстро прирученные динозавры теряют оглушение. Более высокие значения увеличивают скорость падения оглушения. А более низкие значения уменьшают.
+ Интервал кормления при пассивном приручении:
+ Множитель того, как часто вы можете кормить динозавра при пассивном приручении. Более высокие значения уменьшают время между кормлением. А более низкие значения увеличивают.
- Колличество Седел платформ в Трайбе
- Количество прирученных динозавров седлами платформами (со структурами) разрешено в Трайбе.
- Использовать ограничитель только для структур
- если это разрешено, лимит на прирученных существ будет распространяться только на дино с постройками на седлах-платформах и плоты.
- Появление Дино:
- Определяет коэффициент для появления динозавров. Более высокие значения увеличивают колличество появляемых динозавров по всему ARК.
+ Количество Седел-платформ на трайб
+ Максимальное количество прирученных динозавров с седлами-платформами в трайбе, даже если на них нет структур.
+ Вкл ограничение для платформ со структурами
+ Если это включено, то лимит на прирученных динозавров с седлами-платформами будет распространяться только если на них есть структуры. Это настройка касается и плотов.
+ Появление дино:
+ Определяет коэффициент для появления динозавров. Более высокие значения увеличивают колличество появляемых динозавров на сервере.
Выкл голодание Титанов
Если это включено, то позволяет Титанам и Титанозавру быть постоянно прирученными (они перестают постепенно голодать)
- Потребление корма Рейд-Животными
- Определяет множитель потребления пищи Рейд-Животными. Более высокие значения увеличивают потребление еды; Более низкие значения уменьшают потребление еды.
- Включить полет в пещерах
- Если этот параметр включен, позволяет полет на динозаврах в пещерах.
+ Потребление еды у Титанов
+ Определяет множитель потребления пищи у Титанов. Более высокие значения увеличивают потребление еды. Более низкие значения уменьшают потребление еды.
+ Разрешить полет в пещерах
+ Если включено, то в пещерах на прирученных динозаврах можно летать.
Разрешить восстановление выносливости в воздухе
- Если включено, восстанавливает выносливость, в воздухе.
- Включить прокачку полёта
- Если включено, позволяет прокачивать скорость полёта.
- Отключить Dino Mate Boost
- Если включено, усиление Dino Mate Boost будет отключено.(Животные с более быстрыми кладками яиц)
- Отключить Посадку Летающих с бомбами
- Если включено, отключит приземление Летающих при наложении на них взрывчатых веществ.
+ Если включено, то выносливость у летающих динозавров восстанавливается в воздухе.
+ Разрешить прокачку скорости полёта
+ Если включено, то позволяет прокачивать скорость полёта.
+ Запретить бонус разнополости
+ Если включено, то бонус разнополости (Dino Mate Boost) будет отключен.
+ Выкл приземление летающих дино с C4
+ Если включено, то отключит приземление летающих динозавров, если на них есть C4.
Разрешить множественное присоединение C4
- Если включено, разрешено прикреплять более одного C4 на каждого динозавра.
- Выкл. Потерю прав на Дино в PvE
- Если этот параметр включен, отключается постепенная потеря права собственности на дино в PvE; в противном случае каждый Дино может быть заявлен как собственный, любым игроком.
- Отключить PvP Dino Decay
- Если включено, отключает снятие клейма с динозавров в PvP; В противном случае любой динозавр может быть заклеймен любым игроком, по истечению времени.
- Время потери прав на Дино в PvE:
- Множитель потери прав на Дино. Работает только если "Выкл. Потерю прав на Дино PvE" не активно.
- Отключить Baby Dino бонус
- Если включено, выращенные динозавры не будут получать бонусы от выращенного им персонажа. Бонус дамаги\резистов и т.д.
- Разрешить играть с Baby Dino всем
- Если включено, каждый в племени сможет позаботиться о Baby Dino (покормить и т. д.), А не только те, за кем он закреплен.
+ Если включено, то разрешено прикреплять более одного C4 на каждого динозавра.
+ Выкл потерю прав на дино в PvE
+ Если включено, то отключается постепенная потеря права собственности на динозавра в PvE; в противном случае по истечении таймера каждый динозавр может быть заклеймлен любым игроком.
+ Выкл потерю прав на дино в PvP
+ Если включено, то отключается постепенная потеря права собственности на динозавра в PvP; в противном случае по истечении таймера каждый динозавр может быть заклеймлен любым игроком.
+ Таймер потери прав на дино в PvE:
+ Множитель потери прав на динозавра. Работает только если у параметра "Выкл потерю прав на дино в PvE" не стоит галочка.
+ Выкл привязанность
+ Если включено, то выращенные динозавры не будут получать бонус привязанности от того, кто их заклеймил. Бонус урона, защиты и т.д.
+ Разрешить всем играть с растущим дино
+ Если включено, то любой выживший в трайбе сможет позаботиться о динозавре (приласкать, прогуляться и т.д.), А не только те, кто его заклеймил.
Авто-Уничтожение Разклейменных Существ
Если включено, все заклейменные динозавры будут автоматически уничтожаться при загрузке, если клеймо спало.
- Отключить езду на Динозаврах
- Если включено, запрещено ездить на прирученных динозаврах.
- Отключить приручение Диких
- Если включено, все дикие динозавры не смогут быть приручены.
- Изменить Flyer Riding
- Если включено, позволит вам изменить, можно ли летать на карте или нет; в противном случае по умолчанию будут использоваться настройки карты.
- Включить Flyer Riding
- Если включено, игроки могут исаользовать летунов; в противном случае игроки не могут Летать.
+ Выкл езду на дино
+ Если включено, то запрещено ездить на прирученных динозаврах.
+ Выкл приручение дино
+ Если включено, то все дикие динозавры не смогут быть приручены.
+ Изменить езду на летающих дино
+ Если включено, то позволит вам изменить, можно ли летать на карте. В противном случае по умолчанию будут использоваться настройки карты.
+ Вкл езду на летающих дино
+ Если включено, игроки могут использовать летающих животных. В противном случае игроки не смогут летать.
- Кастомизация Дино
+ Кастомизация дино
Множитель появления
Показать/Скрыть столбец Множитель появления.
- Урон домашними
- Показать/Скрыть столбец Урон домашними.
- Сопротивление домашними
- Показать/Скрыть столбец Сопротивление домашними.
+ Урон прирученными
+ Показать/Скрыть столбец Урон прирученными.
+ Сопротивление прирученными
+ Показать/Скрыть столбец Сопротивление прирученными.
Урон Дикими
Показать/Скрыть столбец Урон Дикими.
Сопротивление Дикими
Показать/Скрыть столбец Сопротивление Дикими.
- Сброс всех Кастомизаций Дино обратно по умолчанию.
+ Сброс всех Кастомизаций дино обратно по умолчанию.
Вставьте пользовательские данные динозавров.
Сохранить пользовательские данные динозавров.
Пользовательские настройки динозавров.
@@ -1513,25 +1625,29 @@
Вес появляемых
Перекрыть предел
Предел появления
- Урон домашними
- Сопротивление домашними
+ Урон прирученными
+ Сопротивление прирученными
Урон Дикими
Сопротивление Дикими
- Удалить этого Динозавра
+ Удалить этого динозавра
- Удалить Динозавра
- Нажмите «Да», для подтверждения, что вы хотите удалить запись Динозавра.
+ Удалить динозавра
+ Нажмите «Да», для подтверждения, что вы хотите удалить запись динозавра.
- По уровневый множитель (для домашних)
- Добавит по уровневый множитель статов (для домашних)
- По уровневый множитель влечения (для домашних)
- По уровневый множитель (для диких)
- Коэффициент размножения Динозавров
+ По уровневый множитель (прирученные)
+ Добавит по уровневый множитель статов (прирученные)
+ По уровневый множитель влечения (прирученные)
+ По уровневый множитель (дикие)
+ Mutagen Level Boost (Wild)
+ Mutagen Level Boost (Bred)
+ Настройки размножения динозавров
Если включено, позволяет изменять коэффициенты, которые будут применяться к базовому стату.
Если включено, позволяет изменять коэффициенты, которые будут применяться на каждый стат.
Если этот параметр включен, позволяет изменять факторы, которые должны применяться к добавлению Приручения для каждого стата.
Если этот параметр включен, позволяет изменять факторы, которые должны применяться к множителю Приручения для каждого стата.
Если этот параметр включен, позволит изменять коэффициенты приручения для "Одомашнивания" при каждом стате.
+ If enabled, allows scale factors to be applied to the Number of levels Mutagen adds to tames with wild ancestry.
+ If enabled, allows scale factors to be applied to the Number of levels Mutagen adds to tames with bred ancestry.
Сброс всех настроек обратно по умолчанию.
Сброс всех настроек обратно по умолчанию.
@@ -1539,24 +1655,24 @@
Определяет множитель зависящий от уровня и времени прирученного. Более низкие значения уменьшают время между спариванием.
Скорость спаривания:
Определяет множитель для скорости, с которой динозавры спариваются друг с другом. Более высокие значения увеличивают скорость спаривания.
- Созревание яйца:
+ Скорость инкубации яйц:
Определяет множитель время, созревания оплодотворенного яйца. Более высокие значения уменьшают время созревания яйца.
Скорость взросления:
Определяет множитель для времени, в которое детеныш динозавра вырастет во взрослую особь. Более высокие значения уменьшают время созревания во взрослую особь.
- Голод у "Baby Dino":
- Задает коэффициент скорости, с которым детеныш динозавра будет потреблять пищу. Более высокие значения сделают его более голодным (будет чаще хотеть есть).
+ Потребление еды у растущего дино:
+ Задает коэффициент скорости, с которым детеныш динозавра будет потреблять пищу. Более высокие значения повысят скорость голодания (будет чаще хотеть есть).
- Привязка Дино
- Качество привязки Дино:
- Насколько сильно влияет на статистику качество привязки. Установите значение 0, чтобы отключить систему.
- Качество игры с Дино
- Множитель применяется к проценту, предоставляемому каждым отпечатком. Например, если отпечаток обычно дает 10%, установка этого множителя на 0,5 означает, что теперь они будут давать по 5% каждый. В то время как установка его на 2,0 означает, что теперь они будут давать по 20% каждый и т.д.
- Интервал между играми с дино
- Как часто дети хотят обниматься. Более низкие значения означают, что вам нужно будет чаще обниматься с ними.
- Потеря качества приручения
- Множитель того, как быстро качество приручения уменьшается после льготного периода, если вы еще не обнимались с Baby Dino. Более низкие значения замедляют потерю качества приручения
- Скорость качества падения Приручения:
- Множитель того, насколько быстро снижается качество Приручения после льготного периода, если вы еще не играли с ребёнком. Более низкие значения замедляют потерю качества Приручения.
+ Настройки привязанности дино
+ Качество привязанности дино:
+ Насколько сильно привязанность влияет на характеристики дино. Установите значение 0, чтобы отключить.
+ Множитель уделения внимания:
+ Множитель применяется к проценту, предоставляемому каждым уделением внимания. Например, если уделение внимания обычно дает 10%, установка этого множителя на 0.5 означает, что теперь оно будет давать по 5% за раз. В то время как установка его на 2.0 означает, что теперь оно будет давать уже по 20% за раз и т.д.
+ Интервал между уделением внимания:
+ Как часто растущий дино хочет уделения внимания. Более низкие значения означают, что вам нужно будет чаще уделять ему внимание.
+ Время до начала потери привязанности:
+ Множитель того, через какое время начинает уменьшаться привязанность, если вы вовремя не уделяли внимание растущему дино. Более низкие значения замедляют потерю привязанности
+ Количество потери привязанности:
+ Множитель того, насколько быстро в процентах начинает уменьшаться привязанность, если вы вовремя не уделяли внимание растущему дино. Более низкие значения замедляют потерю привязанности.
Подтвердить сброс
Нажмите «Да», чтобы подтвердить, что вы хотите сбросить Max XP.
@@ -1566,25 +1682,25 @@
Окружающая среда
- Скорость Приручения:
- Изменяет скорость приручения Динозавров. При более высоком значении, приручение произойдет быстрее.
- Количество сбора ресурсов:
- Задает коэффициент урожайности для всех видов сбора ресурсов (вырубка деревьев, сбор ягод, разделка туши, добыча руды, и т.д.). Более высокие значения увеличивают количество материалов, полученых с каждым ударом.
+ Скорость приручения:
+ Изменяет скорость приручения динозавров. При более высоком значении, приручение произойдет быстрее.
+ Множитель сбора ресурсов:
+ Задает коэффициент урожайности для всех видов сбора ресурсов (вырубка деревьев, сбор ягод, разделка туши, добыча руды, и т.д.). Более высокие значения увеличивают количество материалов, полученых с каждым ударом (ВАЖНО: данная множитель умножается с множителем настройки "своя настройка сбора ресурсов").
Время до появления ресурсов:
- Определяет коэффициент скорости респауна для точек появления ресурсов (деревья, камни, кусты и т.д.). При более низких значениях скорость будет выше .
+ Определяет коэффициент скорости возобновления ресурсов (деревья, камни, кусты и т.д.). При более низких значениях скорость будет выше.
Радиус появления от игрока:
Определяет коэффициент расстояния возобновления ресурсов, ближе или дальше от игрока. Более низкие значения уменьшит растояние до игрока.
Радиус появления от структур:
Определяет коэффициент расстояния возобновления ресурсов, ближе или дальше от строений. Более низкие значения уменьшит растояние до строений.
- Фиксировать урон при сборке
+ Фиксировать урон при сборе
Если включено, Фиксирует количество повреждений которое вы можете нанести при сборе ресурсов.
Жизнь ресурса:
Определяет коэффициент здоровья элементов, которые могут быть собраны (деревья, скалы, туш и т.д.). Более высокие значения увеличивают количество повреждений (например, количество ударов) которое объекты могут выдержать, прежде чем разрушатся.
Оптимизировать сбор ресурсов на сервере
Если включено, вы получите более оптимизированный сервер с более высоким значение добычи обычных ресурсов, но с меньшим количеством редкими элементами.
- Своя настройка объемов сбора
- Если включено, вы сможете в ручную настроить добычу ресурсов.
+ Своя настройка сбора ресурсов
+ Если включено, вы сможете вручную настроить добычу каждого ресурса.
Сбросить все настройки сбора обратно по умолчанию.
Вставить пользовательские настройки.
Сохранить пользовательские настройки.
@@ -1596,7 +1712,7 @@
Нажмите «Да», для подтверждения, чтобы удалить запись ресурса.
Базовая температура:
- Определяет коэффициент масштабирования для базовой температуры карты. Более низкие значения уменьшают базовую температуру (делает ее холоднее); более высокие значения увеличивают базовую температуру (делает ее более горячей).
+ Определяет коэффициент масштабирования для базовой температуры на карте. Более низкие значения уменьшают базовую температуру (делает ее холоднее); более высокие значения увеличивают базовую температуру (делает ее более горячей).
Длительность суток:
Позволяет изменять скорость смены суток в ARK, контролирует как быстро день сменится в ночь, а ночь сменится в день. Значения ниже 1 замедлит цикл, более высокие значения ускорят.
Длительность дня:
@@ -1608,33 +1724,33 @@
Время порчи продуктов:
Позволяет изменить глобальные настройки время порчи продуктов. Более высокие значения увеличивают время.
Объединить время порчи продуктов
- Если включено, время портящихся продуктов будет объединено, для более длительного хранения. ВНИМАНИЕ! Если вы используете моды для стака ресурсов, могут быть проблемы.
+ Если включено, то время портящихся ресурсов изменится до максимального, для более длительного хранения. ВНИМАНИЕ! Если вы используете моды на стаки ресурсов, то могут возникнуть проблемы.
Время исчезновения лута:
- Позволяет изменить глобальные настройки время исчезновения выброшенных предметов, награбленных мешков и т.д. по всему миру. Более высокие значения увеличивают время.
+ Позволяет изменить глобальные настройки времени исчезновения выброшенных предметов, сумок с лутом и т.д. по всему миру. Более высокие значения увеличивают время.
Время разложения трупов:
- Позволяет изменить глобальные настройки время разложения трупов (игроков и Дино). Более высокие значения увеличивают время.
+ Позволяет изменить глобальные настройки времени разложения трупов (игроков и дино). Более высокие значения увеличивают время.
Время разложения растений:
- Позволяет изменить глобальные настройки время разложения растений. Более низкие значения продлевают разложение.
+ Позволяет изменить глобальные настройки времени разложения растений. Более низкие значения продлевают разложение.
Время роста растений:
- Позволяет изменить глобальные настройки время роста растений. Более высокие значения ускоряют рост растений.
+ Позволяет изменить глобальные настройки времени роста растений. Более высокие значения ускоряют рост растений.
Время кладки яиц:
- Позволяет изменить интервал времени кладки яиц динозавров. Более низкие значения заставят динозавров откладывать яйца чаще.
- Время дефекации:
- Позволяет изменить интервал времени дефекации персонажа и динозавров. Более низкие значения заставят персонажа и динозавров испражняться чаще.
+ Позволяет изменить интервал времени между кладками яиц. Более низкие значения заставят динозавров откладывать яйца чаще.
+ Интерфал испражнений:
+ Позволяет изменить интервал времени между испражнениями у персонажей и динозавров. Более низкие значения заставят персонажей и динозавров испражняться чаще.
Скорость роста волос:
Определяет множитель скорости роста волос. Более высокие значения увеличивают скорость роста. Более низкие значения уменьшают его.
- Множители XP
- Общий (с течением времени)
- Определяет коэффициент масштабирования для XP, полученный с течением времени. Более высокие значения увеличивают скорость XP.
- Крафт
- Определяет коэффициент масштабирования для XP, полученного во время Крафта. Более высокие значения увеличивают скорость XP.
- Сбор урожая
- Определяет коэффициент масштабирования для XP, полученного при уборке урожая. Более высокие значения увеличивают скорость XP.
- Убийство
- Определяет коэффициент масштабирования для XP, полученного при убийстве. Более высокие значения увеличивают скорость XP.
- Специальные Ивенты
- Определяет коэффициент масштабирования для XP, полученный для специальных Ивентов. Более высокие значения увеличивают скорость XP.
+ Множители опыта
+ Общий (с течением времени):
+ Определяет коэффициент масштабирования опыта, получаемого с течением времени. Более высокие значения увеличивают скорость получения опыта.
+ Крафт:
+ Определяет коэффициент масштабирования для опыта, получаемого во время крафта. Более высокие значения увеличивают скорость получения опыта.
+ Сбор урожая:
+ Определяет коэффициент масштабирования для опыта, получаемого при сборе ресурсов. Более высокие значения увеличивают скорость получения опыта.
+ Убийство:
+ Определяет коэффициент масштабирования для опыта, получаемого при убийстве диких дино. Более высокие значения увеличивают скорость получения опыта.
+ Специальные ивенты:
+ Определяет коэффициент масштабирования для опыта, получаемого во время специальных ивентов. Более высокие значения увеличивают скорость получения опыта.
Подтвердить сброс
Нажмите «Да», чтобы подтвердить, что вы хотите сбросить все изменения множителя суммы урожая ресурсов.
@@ -1642,120 +1758,120 @@
Структуры
- Включить игнорирование коллизий текстур
- Если включено, позволит игрокам размещать структуры, на неровной местности.
+ Откл. коллизию текстур
+ Если включено, позволит игрокам размещать структуры друг в друга, на неровной местности и частично в текстурах.
Сопротивление структур:
Определяет коэффициент устойчивости структур к повреждению получаемых при атаке. Более высокие значения уменьшают сопротивление, увеличивая урон в атаке. Более низкие значения увеличивают его, уменьшая урон в атаке.
Урон от структур:
- Определяет коэффициент урона от структур (например стены с шипами). Более высокие значения увеличивают урон. Более низкие значения уменьшают его.
+ Определяет коэффициент урона от структур (например от шипов). Более высокие значения увеличивают урон. Более низкие значения уменьшают его.
Время на ремонт:
- Опция сервера для времени на восстановление структур, когда можно будет провести ремонт с момента последнего повреждения. Установите 0, чтобы отключить его, по умолчанию составляет 180 секунд.
+ Опция сервера для времени на восстановление прочности структур, время когда можно будет провести ремонт с момента последнего повреждения. Установите 0, чтобы отключить, по умолчанию составляет 180 секунд.
Вкл. разрушение структур в PvP
Если этот параметр включен, структуры в PvP будут автоматически разрушаться если они не использовались какое то время.
Зона повреждения структур в PvP:
Определяет коэффициент повреждения структур получаемых в пределах пещер/и входа в пещеры в PvP режиме.
Максимум видимых структур:
- Максимальное количество структур, которые будут видны игроку. Более низкие значения могут помочь в скорости сервера.
- Структуры на платформах:
- Максимальное количество структур, которые позволено строить на одной платформе/седле.
- Максимум Платформ и Плотов:
+ Максимальное количество структур, которые будут видны игроку. Более низкие значения положительно повлияют на производительность сервера.
+ Кол-во структур на платформах:
+ Максимальное количество структур, которое позволено строить на одном седле-платформе.
+ Максимум платформ и плотов:
Максимальное количество платформ или плотов на сервере.
Разрешить установку турелей на платформах
Если включено, разрешает установку автоматических башен на седлах-платформах динозавров.
Вкл. Перенос нейтральных на платформах
Если этот параметр включен, нейтральные динозавры могут находится на платформах Кетцаля.
- Разрешить строительство в зонах респа Лучей
- Если включено, игроки могут строить здания на месте респа Лучей (дома не будут исчезать)
+ Разрешить строительство в зонах респа лучей
+ Если включено, игроки могут строить здания на месте респа лучей (дома не будут исчезать)
Вкл. разрушение структур в PvE
Если этот параметр включен, структуры в PvE будут автоматически разрушаться если они не использовались какое то время.
- Время разрушения структур:
+ Время до разрушения структур:
Определяет время, необходимое для автоматического разрушения структур игрока в режиме PvE.
Множитель время разрушения структур:
Определяет множитель для автоматического разрушения структур игрока в режиме PvE.
- Авто уничтожение заброшенных структур
+ Вкл. авто-разрушение заброшенных структур
Если включено, будет автоматически уничтожать структуры после истечения времени.
- Авто уничтожение заброшенных структур:
- После того, как прошло достаточно времени "и поблизости нет племени" структуры будут автоматически уничтожены. Полезно для сервера, чтобы очистить от брошенных структур. Установите значение 0, чтобы отключить функцию.
- Автоматическое разрушение только Основных структур
- Если включено, предотвратит автоматическое разрушение любых неосновных / не-фундаментных структур (однако они все равно будут автоматически уничтожены, если пол, на котором они находятся, автоматически разрушится).
- Автоматическое разрушение только НЕ-Основных структур
- Если включено, только разрозненные структуры будут уничтожены. Полезно для устранения одиночного столба / хлама на сервере.
- Быстрое разрушение НЕ-Основных структур
- Если включено, быстрое авто-разрушение отдельно стоящих фундаментов \ столбов.
- Разрушать не подключенные трубы
- Если включено, после двух дней в реальном времени трубы будут автоматически уничтожаться, если они не подключены к какой-либо трубе (воде или строению), и если игрок не находится поблизости.
- Включить быстрое разрушения.
+ Множитель разрушения заброшенных структур:
+ После того, как прошло достаточно времени "и поблизости нет трайба" структуры будут автоматически уничтожены. Полезно для сервера, чтобы очистить от заброшенных структур. Установите значение 0, чтобы отключить.
+ Авто-разрушение основных структур
+ Если включено, предотвратит автоматическое разрушение отдельно стоящих/несвязанных структур (однако они все равно будут уничтожены, если стояли на фундаменте).
+ Авто-разрушение несвязанных структур
+ Если включено, только отдельно стоящие структуры будут уничтожены. Полезно для устранения одиночных фундаментов/колонн (хлама на сервере).
+ Быстрое разрушение несвязанных структур
+ Если включено, быстрое авто-разрушение отдельно стоящих/несвязанных фундаментов или колонн.
+ Разрушать не соединенные трубы
+ Если включено, после двух дней реального времени трубы будут автоматически уничтожаться, если они не подключены к какой-либо трубе (воде или строению), и если игрок не находится поблизости.
+ Вкл. быстрое разрушения
Если включено, позволяет установить параметры быстрого разрушения.
- Интервал разрушения
+ Множитель быстрого разрушения:
Устанавливает фиксированный постоянный период исчезновения структур «быстрого разрушения» (например, столбов или одиночных фундаментов).
- Автозапирание структур
- Если этот параметр включен, все контейнеры будут закрыты по умолчанию.
+ Авто-запирание структур
+ Если этот параметр включен, все структуры будут заперты для других трайбов при установке.
Пассивный урон структурами
- Если этот параметр включен, стены с шипами наносят урон диким/ручным динозаврам.
- Ограничить кол-во Турелей в радиусе
+ Если этот параметр включен, шипы наносят урон диким и прирученным динозаврам.
+ Ограничить кол-во турелей в радиусе
Если включено, будет реализован ограничение на 100 турелей в определенном радиусе
- Радиус ограничения Турелей
- Устанавливает предельный радиус для всех АвтоТурелей и Живых Турелей.
- Ограничение количества Турелей
- Устанавливает максимальное количество Турелей, которые могут быть размещены в пределах определьного радиуса.
- Строгий лимит Башен в радиусе
- Если включено, будет реализован жесткий контроль за башнями. Это будет работать на Автотурелях, Тяжелые башни, ТЕК башни, Башни растений и больше не зависит от карты. Расчет жестких пределов выполняется при запуске, поэтому, если ваши башенки когда-либо превышают лимит, они будут случайным образом отключены, пока не достигнет предела. Чтобы восстановить отключенные башни, вы должны забрать все, что превышает количество, а также запорные башни и заменить их, чтобы они работали.
- Поднятие построек
- Всегда разрешать поднимать постройки
- Если включено, отключит таймер в системе.
- Время подбора постройки после размещения
+ Радиус ограничения турелей:
+ Устанавливает предельный радиус для всех авто-турелей и живых турелей в грядках.
+ Количество турелей в радиусе:
+ Устанавливает максимальное количество турелей, которые могут быть размещены в пределах определьного радиуса.
+ Строгий лимит турелей в радиусе
+ Если включено, будет реализован жесткий контроль за турелями. Работает для авто-туреляй, тяжелых авто-турелей, Тек турелей, растений в грядках и больше не зависит от карты. Расчет жестких пределов выполняется при запуске. Если ваши турели превышают лимит, то они будут случайным образом отключены. Чтобы восстановить работу отключенных турелей, вы должны подоборать лишние.
+ Подбор структур
+ Всегда разрешать поднимать структуры
+ Если включено, отключит таймер и подобрать структуру можно будет в любой мемонт.
+ Время для подбора структуры после размещения:
Определяет время в секундах после размещения, в течение которого доступен быстрый подбор.
- Продолжительность разрешения поднимать постройки
- Определяет количество времени удержания быстрого подбора, используйте 0, чтобы отключить подбор и иметь мгновенный захват.
+ Время удержания для подбора структуры:
+ Определяет количество времени для удержания при подборе. Используйте 0, чтобы включить мгновенный подбор.
Разрешить интегрированные Structures Plus
Если включено, добавит все новые структуры S+, в противном случае отключаются все новые структуры S+ (предназначенные главным образом для того, чтобы позволить неофициальным серверам, которые хотят продолжать использовать версию S+ mod, продолжать использовать это без тонны дополнительных дублирующих структур).
- Отключить строительство в зонах миссий (Genesis)
- Если включено, запрещает строительство в зонах миссии.
+ Откл. строительство в зонах миссий (Genesis)
+ Если включено, запрещает строительство в зонах миссий.
Энграммы
- Авто открытие всех Энграмм
- Если включено, энграммы автоматически разблокируются по мере того, какой уровень игрока.
- Включить перерасчет Энграмм
- Если параметр включен, позволит настраивать Энграммы.
- Сброс всех настроек Энграмм обратно по умолчанию.
+ Вкл. авто-открытие всех энграмм
+ Если включено, энграммы автоматически разблокируются по мере достижения необходимого уровня игрока.
+ Вкл. настройку энграмм
+ Если параметр включен, позволит настраивать энграммы.
+ Сброс всех настроек энграмм обратно по умолчанию.
Вставить пользовательские данные.
Сохранить пользовательские данные.
Импорт пользовательских данных инграмм.
Экспорт пользовательских данных инграмм.
Настройка пользовательских данных
- Разрешить только выбранные Энграммы
- Если включено, в игре будут доступны только выбранные Энграммы.
- Выделить все Энграммы.
- Отменить выделение всех Энграммы.
+ Разрешить только выбранные энграммы
+ Если включено, в игре будут доступны только выбранные энграммы.
+ Выделить все энграммы.
+ Отменить выделение всех энграммы.
Фильтровать только выбранные энграммы
Если включено, будет отображаться только выбранная энграмма.
Выбрать
Выбранный
- Имя
- Имя Engram (имя класса Engram).
+ Название
+ Название энграммы (название класса энграммы).
Мод
- Мод
- Это Tekgram
- Это Tekgram
+ Колонка с названием карты или мода (настривается в Gamedata файле)
+ Это Текграмма
+ Указывает что эта энграмма относится к Текграмме
Уровень
- Уровень игрока, когда Engram может быть разблокирована вручную.
+ Уровень игрока, который требуется для разблокировки энграммы.
Стоимость
- Количество очков Engram, необходимое для разблокировки вручную.
- Скрытый
- Если включено, инграмма будет удалена с экрана разблокировки Engram и не может быть изучена.
- Удалить Prereqs
- Если включено, удалит предпосылки, необходимые для разблокировки Engram.
- Автоматическая разблокировка
- Включено, Engram будет автоматически разблокирована на указанном уровне.
+ Количество очков энграмм, необходимое для её разблокировки.
+ Скрыть
+ Если включено, энграмма не будет отображаться в игре и её нельзя будет выучить.
+ Откл. требование
+ Если включено, отключит требование изучить другую энграмму для разблокировки энграммы.
+ Авто-разблокировка
+ Если включено, энграмма будет автоматически разблокирована на указанном уровне.
Уровень разблокировки
- Уровень игрока, когда Engram автоматически разблокируется. Автоматическая разблокировка должна быть включена.
- Удалить Энграмму
+ Уровень игрока, когда энграмма автоматически разблокируется. Должна быть включена "Авто-разблокировка".
+ Удалить энграмму
- Удалить Энграмму
+ Удалить энграмму
Нажмите «Да», чтобы подтвердить, что вы хотите удалить запись ресурса.
Подтвердить сброс
@@ -1781,46 +1897,46 @@
- Прогресс уровня Игрока и Дино
- Игрок Максимум XP:
- Установите максимальный лимит XP для игроков.
- Дино Максимум XP:
- Установите максимальное ограничение XP для динозавров.
- ПРИМЕЧАНИЕ. Последние уровни игроков {levels} используются для прохождения Вознесения и другого уровня и отображаются на цветном фоне. Если вы настраиваете свои собственные уровни игроков, убедитесь, что вы добавили дополнительные уровни {levels}.
- Вкл. Свои настройки уровня
+ Прогресс уровня игрока и дино
+ Максимальное количество опыта (персонаж):
+ Установите максимальный лимит опыта для игроков.
+ Максимальное количество опыта (дино):
+ Установите максимальное лимит опыта для динозавров.
+ ПРИМЕЧАНИЕ: Последние уровни игроков {levels} используются для прохождения Вознесения и другого уровня и отображаются на цветном фоне. Если вы настраиваете свои собственные уровни игроков, убедитесь, что вы добавили дополнительные уровни {levels}.
+ Вкл. настройки уровней
Если параметр включен, Вы сможете изменять прогресс для каждого уровня персонажа и динозавров самостоятельно.
- Включить прогрессию уровня Дино
- Если включено, включает настройки уровня Дино.
- Свои уровни персонажа
+ Вкл. настройки уровней дино
+ Если включено, включает настройки уровня дино.
+ Пользовательские уровни персонажа
Удалить все существующие уровни.
Сбросить все настройки уровня обратно к ASM по умолчанию.
Сбросить все настройки уровня обратно к официальным умолчанию.
Импортировать список настроек уровней в CSV файл.
Экспортировать список настроек уровней в CSV файл.
- Обновить максимальные значение XP до последнего уровня.
+ Обновить максимальные значение опыта до последнего уровня.
+
-
Уровень
- Требуется XP
- Очков Энграмм
- Общее Энграмм
- Ascension Level
- Добавить еще один уровень.
- Удалить этот уровень.
+ Требуется опыта
+ Очков энграмм
+ Общее кол-во очков энграмм
+ Уровень вознесения
+ Добавить уровень.
+ Удалить уровень.
- Пользовательские уровни Дино
+ Пользовательские уровни дино
Не могу удалить последний элемент
- Вы не можете удалить последний уровень. Если вы хотите отключить эту функцию, снимите флажок Включить прогрессии пользовательского уровня.
+ Вы не можете удалить последний уровень. Если вы хотите отключить эту функцию, снимите флажок Включить прогресс пользовательского уровня.
Подтвердите четкое действие
Нажмите «Да», чтобы подтвердить, что вы хотите очистить все текущие уровни игроков.
Подтвердите сброс действия
Нажмите «Да», чтобы подтвердить, что вы хотите сбросить все текущие уровни игроков.
Подтвердите четкое действие
- Нажмите «Да», чтобы подтвердить, что вы хотите очистить все текущие уровни Дино.
+ Нажмите «Да», чтобы подтвердить, что вы хотите очистить все текущие уровни дино.
Подтвердите сброс действия
- Нажмите «Да», чтобы подтвердить, что вы хотите сбросить все текущие уровни Дино.
+ Нажмите «Да», чтобы подтвердить, что вы хотите сбросить все текущие уровни дино.
Ошибка обновления
@@ -1862,7 +1978,7 @@
Детали сервера
- ПРИМЕЧАНИЕ. Любые изменения потребуют перезагрузки сервера.
+ ПРИМЕЧАНИЕ: Любые изменения потребуют перезагрузки сервера.
Ошибка загрузки
Ошибка сохранения
@@ -1894,7 +2010,7 @@
- Survival of the Fittest (Выживает сильнейший)
+ Survival of the Fittest (выживает сильнейший)
Включить Survival of the Fittest
Если этот параметр включен, выполняется настройка сервера в режиме "Survival of the Fittest".
Отключить "Мертвого зрителя"
@@ -1951,8 +2067,8 @@
X
Y
Z
- ПРЕДУПРЕЖДЕНИЕ. Процедурно созданная система Ark ВЫСОКО ЭКСПЕРИМЕНТАЛЬНАЯ. Ваши сохраненные обработанные процедурой Арки обязательно будут уничтожены в последующих обновлениях по мере дальнейшего развития динамических алгоритмов. Мы рекомендуем использовать эту систему только в настоящее время, если вы согласны принять частую очистку данных, сохраненных в процедуре, созданных Ark.
- ПРИМЕЧАНИЕ. После того, как вы запустили свой сервер, изменение этих параметров не будет иметь никакого эффекта. Чтобы создать ARK с новыми настройками, вы должны либо изменить имя файла MyPGArk1, либо удалить существующий файл сохранения мира. В обоих случаях вы потеряете ВЕСЬ прогресс.
+ ПРЕДУПРЕЖДЕНИЕ: Процедурно созданная система Ark ВЫСОКО ЭКСПЕРИМЕНТАЛЬНАЯ. Ваши сохраненные обработанные процедурой Арки обязательно будут уничтожены в последующих обновлениях по мере дальнейшего развития динамических алгоритмов. Мы рекомендуем использовать эту систему только в настоящее время, если вы согласны принять частую очистку данных, сохраненных в процедуре, созданных Ark.
+ ПРИМЕЧАНИЕ: После того, как вы запустили свой сервер, изменение этих параметров не будет иметь никакого эффекта. Чтобы создать ARK с новыми настройками, вы должны либо изменить имя файла MyPGArk1, либо удалить существующий файл сохранения мира. В обоих случаях вы потеряете ВЕСЬ прогресс.
Настройки ландшафта
Map Seed
@@ -2098,20 +2214,20 @@
- Map Spawner Overrides
- Containers
- Entries
- Map Spawner Settings
- NOTE: If you want to manage your overrides manually or with another application, you can disable the option that will prevent the server manager managing the overrides. See the 'Custom Override Options' in the global settings.
+ Спавны дино
+ Контейнеры
+ Записи
+ Настройки спавнов дино на сервере
+ ПРИМЕЧАНИЕ: Если вы хотите управлять своими переопределениями вручную или с помощью другого приложения, вы можете отключить параметр, который не позволит диспетчеру сервера управлять переопределениями. См. «Пользовательские параметры переопределения» в глобальных настройках.
- Type
+ Тип
Spawner Override Type
- Spawner
+ Спавн
Spawner Class String
- Name
+ Имя
Spawn Name
- Dino
+ Дино
Entity ID of the dino to be added
Weight
Weight Factor for this spawn
@@ -2130,21 +2246,21 @@
- Crafting Overrides
- Crafted Items
- Resource Items
- Crafting Override Settings
- NOTE: If you want to manage your overrides manually or with another application, you can disable the option that will prevent the server manager managing the overrides. See the 'Custom Override Options' in the global settings.
- NOTE: Changing the resources of a crafted item will require the Engram to be re-learnt. If the Engram is already known, a mindwipe tonic must be used so that it can be re-learnt.
+ Изменение требований для крафта
+ Предметы крафта
+ Ресурсы для крафта
+ Настройки Изменений требований для крафта
+ ПРИМЕЧАНИЕ: Если вы хотите управлять своими переопределениями вручную или с помощью другого приложения, вы можете отключить параметр, который не позволит диспетчеру сервера управлять переопределениями. См. «Пользовательские параметры переопределения» в глобальных настройках.
+ ПРИМЕЧАНИЕ: Изменение ресурсов скрафченного предмета потребует заново выучить энграмму. Если энграмма уже открыта, необходимо использовать тоник Амнезия для очистки памяти, чтобы её можно было заново выучить.
- Crafted Item
+ Предмет крафта
Crafted Item Class String
- Resource Item
+ Ресурс для крафта
Resource Item Class String.
- Quantity
- How much of the resource is required.
- Require Exact Resource Type
+ Количество
+ Какое количество ресурсов требуется для крафта.
+ Требовать точный тип ресурса
Determines if a logical check takes place on whether the production makes any sense at all.
Add crafting item
@@ -2159,64 +2275,64 @@
- Supply Crate Overrides
- Supply Crates
- Item Sets
- Item Set Entries
- Items
+ Лучи с дропами
+ Лучи с дропами (Supply Crates)
+ Наборы предметов (Item Sets)
+ Предметы в наборе (Item Set Entries)
+ Предметы (Items)
Supply Crate Override Settings
- NOTE: If you want to manage your overrides manually or with another application, you can disable the option that will prevent the server manager managing the overrides. See the 'Custom Override Options' in the global settings.
- WARNING: If you do not populate each grid properly, it could result in the Supply Crate not spawning into the world. Please ensure ALL sections are populated.
+ ПРИМЕЧАНИЕ: Если вы хотите управлять переопределениями вручную или с помощью другого приложения, вы можете отключить параметр, который не позволит ASM управлять переопределениями. См. «Пользовательские параметры переопределения» в общих настройках.
+ ПРЕДУПРЕЖДЕНИЕ: Если вы не заполните каждую сетку должным образом, это может привести к тому, что маяк/ящик/инвентарь босса с лутом вообще не появится на сервере. Убедитесь, что ВСЕ разделы заполнены.
- Supply Crate
+ Луч с дропом (Supply Crate)
Supply Crate class string of the crate to be overridden.
- Min ItemSets
- The minimum number of sets that will be in the supply crate.
- Max ItemSets
- The maximum number of sets that will be in the supply crate.
- Quality Multiplier
+ Мин наборов
+ Минимальное количество наборов, которое будет в ящике с дропом (The minimum number of sets that will be in the supply crate).
+ Макс наборов
+ Максимальное количество наборов, которое будет в ящике с дропом (The maximum number of sets that will be in the supply crate).
+ Множитель кач-ва
This is a multiplier to modify the item set quality. A value of 1.0 will result in a good mix of all quality levels (Wildcard recommends to keep it at 1.0).
- Prevent Duplicates
+ Запретить дубликат
If enabled, will ensure that only one item will be added to the same loot crate, if it was added to two different sets.
Append Item Sets
If enabled, will add item sets to supply crates, rather than totally overriding all their items.
Prevent Increasing
If enabled, will dynamically increase the amount of items dropped by however many additional itemsets you add (only applies when AppendItemSets=true).
- Description
+ Описание
A description to identify the item set.
- Min Items
+ Мин предметов
The minimum number of items from the set that will be in the supply crate.
- Max Items
+ Макс предметов
The maximum number of items from the set that will be in the supply crate.
- Quality Multiplier
+ Множитель кач-ва
This is a multiplier to modify the item quality. A value of 1.0 will result in a good mix of all quality levels (Wildcard recommends to keep it at 1.0).
- Weight
- Specifies the chance that the item set would make it into the loot crate.
- Prevent Duplicates
+ Приоритет
+ Задаёт приоритет для набора предметов, который выпадет из этого ящика с дропом. Чем выше значение, тем больше шанс на выпадение предмета именно из этого набора предметов (Specifies the chance that the item set would make it into the loot crate).
+ Запретить дубликат
If enabled, will ensure that only one item will be added to the same loot crate, if it was added to two different sets.
- Description
+ Описание
A description to identify the item set entry.
- Weight
- Specifies the chance that the item would make it into the loot crate.
- Min Quantity
+ Приоритет
+ Задаёт приоритет для предмета, который выпадет из этого набора предметов. Чем выше значение, тем больше шанс выпадения предмета (Specifies the chance that the item would make it into the loot crate).
+ Мин кол-во
The minimum quantity of the item that will be in the supply crate.
- Max Quantity
+ Макс кол-во
The maximum quantity of the item that will be in the supply crate.
- Min Quality
+ Мин кач-во
The minimum quality of the item that will be in the supply crate (Wildcard recommends to keep it at 1.0).
- Max Quality
+ Макс кач-во
The maximum quality of the item that will be in the supply crate (Wildcard recommends to keep it at 1.0).
- Force Blueprint
+ Только чертёж
If enabled, you will always generate a blueprint instead of the item.
- Blueprint Chance
+ Шанс на чертёж
Specifies the chance you will generate a blueprint instead of the item. Force Blueprint must be disabled.
- Item
+ Предмет
Item class string of the item.
- Weight
- Specifies the chance that the item would make it into the loot crate.
+ Приоритет
+ Задаёт приоритет для предмета, который выпадет из этого набора предметов. Чем выше значение, тем больше шанс выпадения предмета (Specifies the chance that the item would make it into the loot crate).
Add supply crate
Add item set
@@ -2236,16 +2352,16 @@
- Настроить размеры стаков
+ Размеры стаков
Множитель размера стака
Это глобальный модификатор, позволяющий увеличивать или уменьшать размеры стака предметов. ПРИМЕЧАНИЕ: это работает только для предметов, которые предназначены для штабелирования.
Стак предметов
Настройки переопределения размера стака
- ПРИМЕЧАНИЕ. Если вы хотите управлять переопределениями вручную или с помощью другого приложения, вы можете отключить параметр, который не позволит ASM управлять переопределениями. См. «Пользовательские параметры переопределения» в общих настройках.
+ ПРИМЕЧАНИЕ: Если вы хотите управлять переопределениями вручную или с помощью другого приложения, вы можете отключить параметр, который не позволит ASM управлять переопределениями. См. «Пользовательские параметры переопределения» в глобальных настройках.
Предмет
Класс предмета Строка
- Макс. Количество предметов
+ Макс. кол-во предметов в стаке
Новый размер стека указанного предмета
Игнорировать множитель
Если включено, установит значение размера стопки предметов в Макс. Количество предметов; в противном случае размер стека элементов равен (Множитель размера стека * Макс. Количество предметов).
@@ -2263,6 +2379,23 @@
+
+
+ Запрет трансфера
+ Запретить трансфер
+ Настройки запрета трансфера
+ ПРИМЕЧАНИЕ: Если вы хотите управлять данными настройками вручную или с помощью другого приложения, вы можете отключить опцию, которая не позволит ASM ими управлять. См. раздел "Пользовательские настройки" в глобальных настройках.
+ ПРЕДУПРЕЖДЕНИЕ: Добавление дино в этот список запретит их трансфер на сервер и с сервера.
+
+ Дино
+ Название класса дино (Пример: Allo_Character_BP_C)
+
+ Добавить запрет трансфера
+ Удалить все запреты трансфера
+ Вставить данные запретов
+ Удалить запрет
+ Сохранить
+
Детали игрока
@@ -2298,7 +2431,7 @@
Автопрокрутка
_Сервер
Сохранить мир
- Уничтожить диких Дино
+ Уничтожить диких дино
_Игроки
Сортировка
По онлайн
@@ -2436,36 +2569,6 @@
Настройки
-
- The Island
- The Center
- Scorched Earth
- Ragnarok
- Aberration
- Extinction
- Valguero
- Genesis: Part 1
- Crystal Isles
- Genesis: Part 2
-
-
-
- Primitive Plus
-
-
-
- Основной ARK
-
-
-
- None
- Valentines Day
- Easter
- Fear Evolved (Halloween)
- Turkey Trial
- Winter Wonderland
-
-
@@ -2542,7 +2645,7 @@
Мезопитек
Мозазавр
Мозазавр (Пещера)
- Alpha Мозазавр (Пещера)
+ Альфа Мозазавр (Пещера)
Мосхопс
Выдра
Овираптор
@@ -2768,25 +2871,25 @@
Скальный Дрейк
Королева безымянных
- Безымянный (Миньен)
+ Безымянный (Миньон)
Безымянный (Поверхность)
Альфа Василиск
Альфа Каркинос
- Альфа Surface Король Жнец
+ Альфа Король Жнец (Поверхность)
Искатель (Поверхность)
Королева Жнецов
Король Жнец
- Subterranean Король Жнец
- Elemental Король Жнец
- Surface Король Жнец
- Король Жнец Приручаемый
+ Король Жнец (Подземный)
+ Король Жнец (Миньон)
+ Король Жнец (Поверхность)
+ Король Жнец (Приручаемый)
Роквелл
- Роквелл (Легкий)
- Роквелл (Средний)
Роквелл (Сложный)
+ Роквелл (Средний)
+ Роквелл (Легкий)
Роквелл щупальце
Роквелл щупальце (Сложный)
Роквелл щупальце (Средний)
@@ -2794,25 +2897,25 @@
- Заражённая Артроплевра
- Заражённый Карнотавр
- Заражённый Халикотерий
- Заражённый Червь смерти
- Заражённый Дилофозавр
- Заражённый Диморфодон
- Заражённый Гиганотозавр
- Заражённый Разъяренный Рекс
- Разъяренный Трицератопс
- Заражённый Парацератерий
- Заражённый Птеранодон
- Заражённый Раптор
- Заражённый Рекс
- Заражённый Скальный Дрейк
- Заражённый Спинозавр
- Заражённый Стегозавр
- Заражённый Трицератопс
- Заражённый Жнец
- Заражённая Виверна
+ Corrupted Артроплевра
+ Corrupted Карнотавр
+ Corrupted Халикотерий
+ Corrupted Червь смерти
+ Corrupted Дилофозавр
+ Corrupted Диморфодон
+ Corrupted Гиганотозавр
+ Corrupted Enraged Рекс
+ Corrupted Enraged Трицератопс
+ Corrupted Парацератерий
+ Corrupted Птеранодон
+ Corrupted Раптор
+ Corrupted Рекс
+ Corrupted Скальный Дрейк
+ Corrupted Спинозавр
+ Corrupted Стегозавр
+ Corrupted Трицератопс
+ Corrupted Жнец
+ Corrupted Виверна
Пустыный Титан
Инфорсер
@@ -2836,9 +2939,10 @@
Король Титанов (Альфа)
-
+
Астроцетус
Бладсталкер
+ Король Жнец (Лунный)
Магмазавр
Мегахелон
Ферокс Маленький
@@ -2866,33 +2970,87 @@
Х-Саблезубый Лосось (Rare)
Х-Спинозавр
Х-Тапежара
- Х-Трайк
+ Х-Трицератопс
Х-Шерстистый Носорог
Х-Ютираннус
-
+
Модер, Хозяин Океана (Гамма)
Модер, Хозяин Океана (Бета)
Модер, Хозяин Океана (Альфа)
- Электрофорус Миньен (Гамма)
- Электрофорус Миньен (Бета)
- Электрофорус Миньен (Альфа)
+ Электрофорус Миньон (Гамма)
+ Электрофорус Миньон (Бета)
+ Электрофорус Миньон (Альфа)
Поврежденный Мастер Контроллер (Гамма)
Поврежденный Мастер Контроллер (Бета)
Поврежденный Мастер Контроллер (Альфа)
+
+ Астродельфис
+ Рой Макрофагов
+ Маевинг
+ Ноглин
+ R-Аллозавр
+ R-Бронтозавр
+ R-Карбонемис
+ R-Карнотавр
+ R-Деодон
+ R-Дилофозавр
+ R-Лютоволк
+ R-Эквус
+ R-Газбагс
+ R-Гиганотозавр
+ R-Мегатерий
+ R-Снежная сова
+ R-Паразавр
+ R-Прокоптодон
+ R-Кетцалькоатль
+ R-Король жнец
+ R-Королева жнецов
+ R-Сумчатый лев
+ R-Велоназавр
+ Призрачная грива
+ Суммонер
+ Тек Страйдер
+ Тек Виверна (Войдверна)
+
+
+
+
+
+
+
+ Кристальная виверна
+ Кристальная Кровавая виверна
+ Кристальная Угольная виверна
+ Кристальная Тропическая виверна
+ Альфа Кристальная Кровавая виверна
+ Кристальная Кровавая виверна (Миньон)
+ Кристальная Угольная виверна (Миньон)
+ Кристальная Тропическая виверна (Миньон)
+ Тропеогнат
+ Гигантская Рабочая пчела
+
+
+
+ Королева Кристальных Виверн
+ Королева Кристальных Виверн (Гамма)
+ Королева Кристальных Виверн (Бета)
+ Королева Кристальных Виверн (Альфа)
+
+
Улучшенная пуля
- Улучшенная пуля для винтовки
- Улучшенная пуля для снайперской винтовки
+ Пуля Штурмовой Винтовки
+ Пуля Снайперской Винтовки
Дротик с феромонами
Кондиционер
Натяжная сигнальная ловушка
@@ -3161,7 +3319,7 @@
Простая кровать
Простая пуля
Длинная винтовка
- Пуля простой винтовки
+ Пуля для длинной винтовки
Дробовик
Патрон для дробовика
Рогатка
@@ -3527,11 +3685,11 @@
Горшок соли
Пропелент
Самонаводящаяся ракета
- Седло для Мореллатопса (Scorched Earth)
- Седло для Богомола (Scorched Earth)
- Седло для Шелкопряда (Scorched Earth)
- Седло для Каменного Голема (Scorched Earth)
- Седло для Шипастого дракона (Scorched Earth)
+ Седло для Мореллатопса
+ Седло для Богомола
+ Седло для Шелкопряда
+ Седло для Горного Элементаля
+ Седло для Шипастого дракона
Шатер
Кувшин
Колодец
@@ -3576,7 +3734,7 @@
Криохолодильник
- Радио Загон для Дино
+ Радио Загон для дино
Криокапсула
Седло для Гачи (Extinction)
Седло для Газбагса (Extinction)
@@ -3645,50 +3803,50 @@
Рецепты Роквелла: Целебный отвар
Рецепты Роквелла: Вяленое мясо
Рецепты Роквелла: Киблы из Яйца
- Rockwell Recipes: Allosaurus Kibble
- Rockwell Recipes: Ankylosaurus Kibble
- Rockwell Recipes: Archaeopteryx Kibble
- Rockwell Recipes: Argentavis Kibble
- Rockwell Recipes: Baryonyx Kibble
- Rockwell Recipes: Brontosaurus Kibble
- Rockwell Recipes: Carbonemys Kibble
- Rockwell Recipes: Carnotaurus Kibble
- Rockwell Recipes: Compy Kibble
- Rockwell Recipes: Dilophosaur Kibble
- Rockwell Recipes: Dimetrodon Kibble
- Rockwell Recipes: Dimorphodon Kibble
- Rockwell Recipes: Diplodocus Kibble
- Rockwell Recipes: Dodo Kibble
- Rockwell Recipes: Gallimimus Kibble
- Rockwell Recipes: Ichthyornis Kibble
- Rockwell Recipes: Iguanodon Kibble
- Rockwell Recipes: Kairuku Kibble
- Rockwell Recipes: Kentrosaurus Kibble
- Rockwell Recipes: Lystrosaurus Kibble
- Rockwell Recipes: Megalania Kibble
- Rockwell Recipes: Megalosaurus Kibble
- Rockwell Recipes: Microraptor Kibble
- Rockwell Recipes: Moschops Kibble
- Rockwell Recipes: Oviraptor Kibble
- Rockwell Recipes: Pachycephalosaurus Kibble
- Rockwell Recipes: Pachyrhinosaurus Kibble
- Rockwell Recipes: Parasaur Kibble
- Rockwell Recipes: Pegomastax Kibble
- Rockwell Recipes: Pelagornis Kibble
- Rockwell Recipes: Pteranodon Kibble
- Rockwell Recipes: Pulmonoscorpius Kibble
- Rockwell Recipes: Quetzalcoatlus Kibble
- Rockwell Recipes: Raptor Kibble
- Rockwell Recipes: Tyrannosaurus Kibble
- Rockwell Recipes: Sarcosuchus Kibble
- Rockwell Recipes: Spinosaur Kibble
- Rockwell Recipes: Stegosaurus Kibble
- Rockwell Recipes: Tapejara Kibble
- Rockwell Recipes: Terror Bird Kibble
- Rockwell Recipes: Therizinosaur Kibble
- Rockwell Recipes: Titanoboa Kibble
- Rockwell Recipes: Triceratops Kibble
- Rockwell Recipes: Troodon Kibble
+ Рецепты Роквелла: Аллозавр Киблы
+ Рецепты Роквелла: Анкилозавр Киблы
+ Рецепты Роквелла: Археоптерикс Киблы
+ Рецепты Роквелла: Аргентавис Киблы
+ Рецепты Роквелла: Барионикс Киблы
+ Рецепты Роквелла: Бронтозавр Киблы
+ Рецепты Роквелла: Карбонемис Киблы
+ Рецепты Роквелла: Карнотавр Киблы
+ Рецепты Роквелла: Компи Киблы
+ Рецепты Роквелла: Дилофозавр Киблы
+ Рецепты Роквелла: Диметродон Киблы
+ Рецепты Роквелла: Диморфодон Киблы
+ Рецепты Роквелла: Диплодокус Киблы
+ Рецепты Роквелла: Додо Киблы
+ Рецепты Роквелла: Галимимус Киблы
+ Рецепты Роквелла: Ихтиорнис Киблы
+ Рецепты Роквелла: Игуанадон Киблы
+ Рецепты Роквелла: Кайруку Киблы
+ Rockwell Recipes: Кентрозавр Киблы
+ Rockwell Recipes: Листрозавр Киблы
+ Rockwell Recipes: Мегалания Киблы
+ Rockwell Recipes: Мегалозавр Киблы
+ Rockwell Recipes: Микрораптор Киблы
+ Rockwell Recipes: Мосхопс Киблы
+ Rockwell Recipes: Овираптор Киблы
+ Rockwell Recipes: Пахицефалозавр Киблы
+ Rockwell Recipes: Пахиринозавр Киблы
+ Rockwell Recipes: Парозавр Киблы
+ Rockwell Recipes: Пегомастакс Киблы
+ Rockwell Recipes: Пелагорнис Киблы
+ Rockwell Recipes: Птеранодон Киблы
+ Rockwell Recipes: Скорпион Киблы
+ Rockwell Recipes: Кетцалькоатль Киблы
+ Rockwell Recipes: Раптор Киблы
+ Rockwell Recipes: Тираннозавр Киблы
+ Rockwell Recipes: Саркозух Киблы
+ Rockwell Recipes: Спинозавр Киблы
+ Rockwell Recipes: Стегозавр Киблы
+ Rockwell Recipes: Тапежара Киблы
+ Rockwell Recipes: Ужасная птица Киблы
+ Rockwell Recipes: Теризинозавр Киблы
+ Rockwell Recipes: Титанобоа Киблы
+ Rockwell Recipes: Трицератопс Киблы
+ Rockwell Recipes: Троодон Киблы
Рецепты Роквелла: Кремовый деликатес
Примечания к рецептам Rockwell
Рецепты Роквелла: Тоник "Амнезия"
@@ -3723,7 +3881,7 @@
Кисть
Пика
Натяжная наркотическая ловушка
- Электрическое ружье
+ Электрошокер
Штурмовая винтовка
Гранатомет
Ножницы
@@ -3742,8 +3900,8 @@
Радиолокатор
Самодельное взрывное устройство
Улучшенная пуля
- Улучшенная пуля для винтовки
- Улучшенная пуля для снайперской винтовки
+ Пуля Штурмовой Винтовки
+ Пуля Снайперской Винтовки
Дротик с феромонами
Огненная стрела
Каменная стрела
@@ -3757,10 +3915,10 @@
Улучшенный транквилизирующий дротик
Реактивная граната
Простая пуля
- Пуля простой винтовки
+ Пуля для длинной винтовки
Патрон для дробовика
Транквилизирующий дротик
- Гарпун-транквилизатор
+ Гарпун Транквилизирующий
Седло для Аллозавра
Седло для Анкилозавра
Седло для Аргентависа
@@ -3789,23 +3947,23 @@
Седло для Эквуса
Меховые ботинки
Меховые перчатки
- Меховые шлем
+ Меховая шапка
Меховые штаны
- Меховые нагрудник
+ Меховой нагрудник
Седло для Галлимима
Противогаз
- Ботинки скрытности
- Перчатки скрытности
- Маска скрытности
- Штаны скрытности
- Нагрудник скрытности
+ Маскировочные ботинки
+ Маскировочные перчатки
+ Маскировочная маска
+ Маскировочные штаны
+ Маскировочный нагрудник
Седло для Гиганотозавра
- Кожаные ботинки
- Кожаные перчатки
- Кожаные шлем
+ Кожаные ботинки
+ Кожаные перчатки
+ Кожаные шлем
Шляпа охотника
- Кожаные штаны
- Кожаные нагрудник
+ Кожаные штаны
+ Кожаные нагрудник
Мясная Сумка для Гиенодона
Седло для Игуанодона
Седло для Капрозуха
@@ -3848,9 +4006,9 @@
Седло для Шерстистого Носорога
Штурмовые ботинки
Штурмовые перчатки
- Штурмовые шлем
+ Штурмовой шлем
Штурмовые штаны
- Штурмовые нагрудник
+ Штурмовой нагрудник
Седло для Саблезуба
Седло для Саркозуха
Седло для Бронтозавра
@@ -3991,6 +4149,12 @@
Охлажденная бутылка для воды (пустая)
Охлажденная бутылка для воды (полная)
Биотоксин
+ Базовый корм (серый)
+ Простой корм (зеленый)
+ Обычный корм (синий)
+ Отличный корм (фиолетовый)
+ Исключительный корм (желтый)
+ Экстраординарный корм (голубой)
Корм (Яйцо Аллозавра)
Корм (Яйцо Анкилозавра)
Корм (Яйцо Археоптерикса)
@@ -4044,7 +4208,7 @@
Семена Амарберри
Семена Азулберри
Семена лимона
- Семена Растения Икс
+ Семена Растения X
Семена кукурузы
Семена Межоберри
Семена Наркоберри
@@ -4064,32 +4228,32 @@
Стимулятор
Сладкий Кекс
Отвар Просвещения
- Эмоции - Зло
- Эмоции открыть - Сердце
- Эмоции открыть - Снежный ком
- Эмоции открыть - Индюк
- Лицо открыть - Кудрявая борода
- Лицо открыть - Страшная борода
- Лицо открыть - Эспаньолка
- Лицо открыть - Усы
- Лицо открыть - Mutton Chops
- Лицо открыть - Викинг Борода
- Прическа открыть - Афро
- Прическа открыть - Косы
- Прическа открыть - Дреды
- Прическа открыть - Мохаук
- Прическа открыть - Конский хвост
- Прическа открыть - Викинг
- Прическа открыть - Индюк
- Прическа открыть - Романтик
+ Эмоция - Зло
+ Эмоция - Сердце
+ Эмоция - Бросить снежок
+ Эмоция - Индейка
+ Лицо - Завитые усы
+ Лицо - Борода Дреды
+ Лицо - Борода Эспаньолка
+ Лицо - Усы
+ Лицо - Бакенбарды
+ Лицо - Борода викинга
+ Прическа - Афро
+ Прическа - Косы
+ Прическа - Дреды
+ Прическа - Ирокез
+ Прическа - Хвост
+ Прическа - Викинг
+ Лицо - Борода Романтический
+ Прическа - Романтический
Лимон
Кукуруза
Морковь
Картофель
Бутылка для воды (пустая)
Бутылка для воды (полная)
- Бурдюк (пустая)
- Бурдюк (полная)
+ Бурдюк (пустой)
+ Бурдюк (полный)
Молоко Виверны
Парашют
Чудо-удобрение
@@ -4097,7 +4261,7 @@
Мыло
Костюм Бионического Гигантозавра
Костюм Бионического Рекса
- Костюм Брачиосауруса
+ Костюм Брахиозавра
Костяной костюм Карнотавра
Костяной костюм Гиганотозавра
Костяной костюм Тушканчика
@@ -4110,8 +4274,8 @@
Костяной костюм Виверны
Костюм кролика Прокоптодона
Костюм Большерогово оленя
- Stygimoloch Costume
- Styracosaurus Costume
+ Костюм Стигомолоха
+ Костюм Стиракозавра
Пурпурный краситель
Черный краситель
Синий краситель
@@ -4191,8 +4355,8 @@
Металлический слиток
Обсидиан
Нефть
- Шерсть
- Шерсть или волосы
+ Шкура
+ Шкура или волосы
Полимер
Органический полимер
Редкий цветок
@@ -4225,12 +4389,12 @@
Пораженная броня
Маска Дило
Костюм кролика для Прокоптодона (скин)
- Dino Easter Chick Hat
- Милая Дино-шапка (скин)
- Dino Easter Egg Hat
+ Шапка Пасхальный цыпленок (скин)
+ Милая дино-шапка (скин)
+ Шапка Пасхальное яйцо (скин)
Шапка Пирамидка для дино (скин)
Шапка Санты для дино (скин)
- Очки для динозавра (скин)
+ Очки для дино (скин)
Шляпа ведьмы для дино (скин)
Маска ДодоРекса (скин)
Маска ДодоВиверны (скин)
@@ -4521,23 +4685,23 @@
Кнут
Боеприпас для огнемета
Самонаводящаяся ракета
- Седло для Мореллатопса (Scorched Earth)
- Сапоги из пустынной ткани
- Перчатки из пустынной ткани
+ Седло для Мореллатопса
+ Пустынные ботинки
+ Пустынные перчатки
Пустынные очки и шляпа
- Брюки из пустынной ткани
- Рубашка из пустынной ткани
- Седло для Богомола (Scorched Earth)
- Седло для Шелкопряда (Scorched Earth)
- Седло для Каменного Голема (Scorched Earth)
+ Пустынные штаны
+ Пустынная рубашка
+ Седло для Богомола
+ Седло для Шелкопряда
+ Седло для Горного Элементаля
Седло для Шипастого Дракона (скин)
- Седло для Шипастого Дракона (Scorched Earth)
+ Седло для Шипастого Дракона
Кактусовый сок
- Яйцо Мореллатопса (Scorched Earth)
- Яйцо Богомола (Scorched Earth)
- Яйцо Шелкопряда (Scorched Earth)
- Яйцо Шипастого Дракона (Scorched Earth)
- Яйцо Грифа (Scorched Earth)
+ Яйцо Мореллатопса
+ Яйцо Богомола
+ Яйцо Шелкопряда
+ Яйцо Шипастого Дракона
+ Яйцо Грифа
Корм (Яйцо Мореллатопса)
Корм (Яйцо Богомола)
Корм (Яйцо Шелкопряда)
@@ -4548,10 +4712,10 @@
Яйцо Ядовитой Виверны
Семена ловушка растения Y
Огненный коготь
- Электрический коготь
+ Грозовой коготь
Ядовитый коготь
Глина
- Рог червя смерти
+ Рог Червя смерти
Горшок соли
Пропелент
Сырая соль
@@ -4560,26 +4724,26 @@
Сера
Глиняное перекрытие
Гигантский глиняный люк
- Гигантская глиняная рама для люка
- Глиняное рама люка
+ Глиняная гигантская рама для люка
+ Глиняное рама для люка
Глиняная дверь
Глиняное основание для забора
Глиняный фундамент
- Глиняная большая рама
- Глиняное большие ворота
- Огромная глиняные ворота
- Огромная глиняная рама
- Глиняное лестница
+ Глиняная рама для ворот
+ Глиняные ворота
+ Глиняные огромные ворота
+ Глиняная рама для огромных ворот
+ Глиняная лестница
Глиняная колонна
- Глиняная перила
- Глиняное рампа
- Наклоненная глиняная крыша
+ Глиняные перила
+ Глиняная рампа
+ Глиняная наклонная крыша
Глиняная винтовая лестница
Глиняный люк
Глиняная стена
- Наклоненная вправо глиняная стена
- Наклоненная вправо глиняная стена
- Глиняная дверной проем
+ Глиняная наклоненная влево стена
+ Глиняная наклоненная вправо стена
+ Глиняный дверной проем
Глиняная оконная рама
Глиняное окно
Флаг Мантикоры
@@ -4592,10 +4756,10 @@
Ветряная турбина
Трофей Альфа Червя смерти
Трофей Альфа Виверны
- Трофей Мантикоры
- Трофей Мантикоры (Альфа)
- Трофей Мантикоры (Бета)
- Трофей Мантикоры (Гамма)
+ Голова Мантикоры
+ Голова Мантикоры (Альфа)
+ Голова Мантикоры (Бета)
+ Голова Мантикоры (Гамма)
@@ -4987,7 +5151,7 @@
Неразвернутый Инфорсер
Разобранный Мех
Криохолодильник
- Радио Загон для Дино
+ Радио Загон для дино
Флаг Короля Титанов
Флаг Короля Титанов (Mecha)
Ящик Доставки
@@ -5355,6 +5519,20 @@
Инвентарь босса (контейнер) - Король Титанов (Альфа)
Инвентарь босса (контейнер) - Король Титанов (Бета)
Инвентарь босса (контейнер) - Король Титанов (Гамма)
+
+ Бобровая плотина
+ Бобровая плотина (большая)
+ Сундук с сокровищами
+ Глубоководный ящик (пустыня)
+
+ Фиолетовый маяк
+ Фиолетовый маяк (Двойные предметы)
+ Желтый маяк
+ Желтый маяк (Двойные предметы)
+ Красный маяк
+ Красный маяк (Двойные предметы)
+
+ Кристальная виверна
@@ -5390,6 +5568,29 @@
Инвентарь босса - Королева Кристальных Виверн (Гамма)
Инвентарь босса - Королева Кристальных Виверн (Бета)
Инвентарь босса - Королева Кристальных Виверн (Альфа)
+
+ Инвентарь босса - Дракон (Легкий)
+ Инвентарь босса - Дракон (Средний)
+ Инвентарь босса - Дракон (Сложный)
+ Инвентарь босса - Мантикора (Легкая)
+ Инвентарь босса - Мантикора (Средняя)
+ Инвентарь босса - Мантикора (Сложная)
+ Инвентарь - Червь смерти
+ Инвентарь - Альфа Червь смерти
+
+
+
+ Инвентарь босса - Мегапитек (Легкий)
+ Инвентарь босса - Мегапитек (Средний)
+ Инвентарь босса - Мегапитек (Сложный)
+ Инвентарь босса - Дракон (Легкий)
+ Инвентарь босса - Дракон (Средний)
+ Инвентарь босса - Дракон (Сложный)
+ Инвентарь босса - Мантикора (Легкая)
+ Инвентарь босса - Мантикора (Средняя)
+ Инвентарь босса - Мантикора (Сложная)
+
+
@@ -5438,12 +5639,13 @@
Сохранение...
- Проверка игрока и Дино Макс ХР...
- Построение информации Дино...
+ Проверка игрока и дино Макс ХР...
+ Построение информации дино...
Построение информации инграммы...
Построение Map Spawner Информация...
Построение Supply Crate Информация...
Построение Stack Size Информация...
+ Создание информации о предотвращении передачи ...
Сохранение файла профиля...
Сохранение файлов конфигурации...
Сохранение файла запуска...
@@ -5463,4 +5665,32 @@
При обновлении сервера возникла проблема. Это может оставить ваш сервер в неполном состоянии.\r\n\r\nХотите продолжить запуск сервера, это может вызвать проблемы?
+
+ Ошибка бота Discord
+ Бот Discord требует действующий токен, чтобы он мог войти на сервер Discord\r\nЭто можно установить в глобальных настройках.
+ Префикс бота Discord содержит недопустимые символы. Разрешены только буквы и цифры.
+
+ Команда '{0}' не активирована.
+ Неизвестная команда '{0}'.
+ В настоящее время обрабатывается другая команда.
+ Другая команда '{0}' в настоящее время выполняется для профиля '{1}'.
+ Команда '{0}' отключена для профиля '{1}'.
+
+ Для команды '{0}' требуется идентификатор профиля.
+ Профиль '{0}' не найден или не связан с каналом.
+ Профиль '{0}' находится в состоянии '{1}', и эта команда не может быть запущена.
+ Профиль '{0}' в настоящее время обновляется.
+
+ Не удалось выполнить вызов сервера "{0}".
+ Отправлен запрос на резервное копирование для сервера "{0}".
+ Отправлен запрос на перезапуск сервера "{0}".
+ Отправлен запрос на завершение работы сервера "{0}".
+ Отправлен запрос на запуск сервера "{0}".
+ Отправлен запрос на остановку сервера "{0}".
+ Отправлен запрос на обновление для сервера "{0}".
+
+ Итог:
+ Карта:
+
+
\ No newline at end of file
diff --git a/src/ARKServerManager/Globalization/zh-CN/zh-CN.xaml b/src/ARKServerManager/Globalization/zh-CN/zh-CN.xaml
index e5d8a319..8a40b837 100644
--- a/src/ARKServerManager/Globalization/zh-CN/zh-CN.xaml
+++ b/src/ARKServerManager/Globalization/zh-CN/zh-CN.xaml
@@ -9,10 +9,40 @@
翻译:
- 晴天
+ 2021.12.09(龍柒)
错误
+
+ 孤岛(The Island)
+ 中心岛地图(The Center)
+ 焦土地图(Scorched Earth)
+ 仙境地图(Ragnarok)
+ 畸变地图(Aberration)
+ 灭绝地图(Extinction)
+ 瓦尔盖罗(Valguero)
+ 创世纪 1(Genesis: Part 1)
+ 创世纪 2(Genesis: Part 2)
+ 水晶岛(Crystal Isles)
+
+
+
+ 原始服(Primitive Plus)
+
+
+
+ 生存
+
+
+
+ 无节日
+ 情人节
+ 复活节
+ 恐惧进化(万圣节)
+ 土耳其审判(感恩节)
+ 冬季仙境(圣诞节)
+
+
所有
未知
@@ -23,13 +53,14 @@
仙境地图(Ragnarok)
畸变地图(Aberration)
灭绝地图(Extinction)
- 创世纪(Genesis)
+ 创世纪 1(Genesis: Part 1)
+ 创世纪 2(Genesis: Part 2)
水晶岛(Crystal Isles)
程序生成地图(PGM)
瓦尔盖罗(Valguero)
-
+
未知
未下载
地图
@@ -49,6 +80,12 @@
无效
所有
+
+
+
+ 正常
+ 最小化
+ 最大化
@@ -66,8 +103,8 @@
选择一个数据目录
确认位置
方舟服务器管理工具将存储配置文件和steamcmd以下目录:\r\n\r\n配置文件: {0}\r\nSteamCMD: {1}\r\n\r\n这样可以吗?
- 数据目录选择错误
- 您选择的目录在服务器管理器安装文件夹中。 不建议这样做,请选择另一个文件夹。
+ 数据目录选择错误
+ 您选择的目录在服务器管理器安装文件夹中。 不建议这样做,请选择另一个文件夹。
保存配置文件失败
保存配置文件失败 {0}. {1}\n{2}
@@ -126,6 +163,25 @@
选择
处理器
+
+
+
+ 数据文件夹选择
+ 您似乎没有数据目录集. 数据目录是存储配置文件和streamcmd的地方.它与服务器安装目录不同,您可以为每个配置文件选择.
+ 选择数据文件夹的硬盘号.
+ 数据文件夹名称:
+ 服务器管理器数据文件夹的名称.
+ 本地磁盘
+ {0} free of {1}
+
+ Ok
+ 取消
+ 刷新
+
+ 数据目录选择错误
+ 您输入的数据文件夹名称无效.
+ 需要重新启动服务器管理器
+ 数据文件夹已设置,现在必须重新启动服务器管理器才能使用新设置.
@@ -263,9 +319,11 @@
配置文件同步 - {0}
加载配置文件同步错误
配置文件同步进程
+ 您将使用当前配置文件的选定部分中的设置覆盖选定的配置文件。您将无法撤消,是否继续?
配置文件同步进程错误
您尚未选择任何配置文件来复制设置。
您没有选择任何部分复制设置。
+ 已成功将所选部分的设置从当前配置文件复制到所选配置文件.
选择所有
取消所有选择
处理
@@ -422,9 +480,11 @@
重置
这将重置服务器管理器的所有用户全局设置。 成功后,服务器管理器将关闭。
启用作为启动管理员提示符下运行
+ 窗口启动模式:
最小化到托盘
自动管理防火墙设置
- 数据目录:
+ 自动管理公共IP
+ 数据目录:
备份目录:
Steam WebApi 密钥:
设置位置...
@@ -434,7 +494,7 @@
语言
-自定义覆盖选项
+ 自定义覆盖选项
启用自定义Engine.ini设置
如果启用,Engine.ini设置将由服务器管理器进行管理器。
启用制作设置
@@ -443,7 +503,9 @@
如果启用,则叠加大小设置将由方舟服务器管理器进行管理。
启用地图刷新设置
如果启用,地图刷新设置将由方舟服务器管理器进行管理。
- 启用补给箱设置
+ 启用光柱/补给箱/战利品设置
+ 启用禁止恐龙传输覆盖
+ 如果启用,禁止传输覆盖将由服务器管理器管理.
如果启用,补给箱设置将由方舟服务器管理器进行管理。
启用程序生成方舟设置
如果启用,程序生成方舟设置将由方舟服务器管理器进行管理。
@@ -623,7 +685,8 @@
SteamCmd身份验证禁用
您已选择将SteamCMD输出重定向到进度窗口。 您无法使用Steam账户,您必须使用匿名账户。
使用Steam认证,必须关闭输出SteamCMD到进度窗口选项。
-
+ 在启动消息中包含公共IP和端口
+ 启动消息将包括公共IP和端口.
警告选项
服务器停止消息:
当服务器停止时,将显示此消息。
@@ -631,6 +694,7 @@
当服务器关闭时,将显示此消息。
服务器开始消息:
当服务器启动时,将显示此消息。
+
备份过程错误:
当自动备份过程遇到错误时,将显示此消息。
关机过程错误:
@@ -752,6 +816,8 @@
+ 配置文件ID:
+ 分配给配置文件的唯一ID.
配置名称:
服务器配置文件的名称。这不是方舟游戏服务器的名称,玩家无法查看.
安装的版本:
@@ -898,6 +964,8 @@
网络
服务器端口:
用户将用于连接到服务器的端口。默认值为7777。如果希望在一台计算机上托管多个服务器,请更改此端口并查询端口。
+ 对等端口:
+ 用于确定服务器可用性的Pinger端口。默认值为7778。
查询端口:
Steam用于与服务器通信的端口。默认值为27015。如果希望在一台计算机上托管多个服务器,请更改此端口并查询端口。
本地 IP:
@@ -1120,6 +1188,8 @@
开启极限模式(玩家死后无法重生,必须重新创建一个游戏角色才能进行游戏).
开启PVP
开启玩家与玩家模式(玩家可以处理伤害或杀死对方。在PVP玩家也可以破坏或摧毁另一个部落的建筑或杀死恐龙.
+ 启用创造模式
+ 如果启用,则允许创建模式.(地图里面玩家将拥有创造模式)
开启PVE洞穴建筑
如果启用,则在洞穴内的建筑将使用PVE模式.
启用PVE低温症
@@ -1154,6 +1224,8 @@
确定方舟生物的最大等级.该值越高,最大生物等级越高.
难度偏移:
确定世界上生物的最大水平。 值越高,最大生物等级越高。
+ 消灭驯服等级以上的龙:
+ 超过此等级的驯服龙将在服务器启动时删除. 要禁用删除,请将设置为0.
启用角色数据下载
如果启用,这将允许将外部幸存者/物品/恐龙下载到您的服务器中。
@@ -1290,7 +1362,40 @@
指生物从低温舱中释放后所造成伤害的倍数。 较低的值意味着该生物所造成的伤害将较低(如: 0.01意味着99% 的损伤被移除)。
伤害倍数百分比
指定生物从低温舱释放后,伤害增加的百分比。 较高的值意味着对生物造成更多的伤害(例如: 0.2525% 更多的伤害)。
-
+
+ 禁止重生TEK套装
+ 如果启用,将禁止玩家重生TEK套装.
+
+ 禁用世界buff
+ 如果启用,将完全禁用任务的世界效果.
+ 启用世界Buff效果
+ 如果启用,将使世界buff成倍地扩展其优势,而不是在运行时向该值添加/减去固定数量.
+ 世界Buff比例效果
+ 指定全局标量以降低/提高世界增益效果(例如,默认值为1,0.5将降低50%的效果,2.0将提高2倍的效果).
+
+ 六角币
+ 禁用六角币存储
+ 启用后,将无法存储六角币.
+ 只允许印痕点交易
+ 如果启用,只有印痕点数可以在六角币商店出售.
+ 六角币最大存储量
+ 指定玩家拥有的最大六角币数量.
+ 六角币奖励倍数
+ 设置六角币获得倍数.
+ 六角币消耗倍数
+ 设置六角币消耗倍数.
+
+ 物品品质设置
+ 注意:这将永久改变现有物品的品质.
+ 通用质量
+ 护甲
+ 最大耐久
+ 武器伤害
+ 武器弹药量
+ 次绝缘
+ 重量
+ 超绝缘
+
聊天和通知
@@ -1430,6 +1535,8 @@
如果启用,允许生物在洞穴内飞行.
允许飞行耐力恢复
如果启用,将允许玩家站在飞行单位上恢复耐力。
+ 允许加点飞行速度
+ 如果启用,允许加点飞行速度.
防止恐龙交配
如果启用,恐龙交配将被禁用。
禁用带爆炸物的飞行物强制地面
@@ -1494,12 +1601,16 @@
每级属性倍数 (驯服) - 增加
每级属性倍数 (驯服) - 姻亲
每级属性倍数 (野生)
+ 诱变剂等级提升(野生型)
+ 诱变剂等级提升(驯服型)
恐龙繁殖倍数设置
如果启用,允许将倍数应用于每个出生属性。(这个数值是根据官服倍数的一个调整).
如果启用,允许将倍数应用于每个属性。(这个数值是根据官服倍数的一个调整).
如果启用,则允许将倍数应用于每个属性的驯服加成。
如果启用,则允许将倍数应用于每个属性的驯服倍数。
如果启用,则允许将倍数应用于每个属性的驯服加点。
+ 如果启用,允许使用诱变剂提升野生恐龙等级(属性).
+ 如果启用,允许使用诱变剂提升驯服恐龙等级(属性).
重置所有倍数恢复到默认值.
重置所有倍数恢复到默认值.
@@ -2111,56 +2222,56 @@
保存制作项目
-
- 补给箱覆盖
- 补给箱
- 物品设置
- 设置加入物品
- 物品
- 补给箱覆盖设置
- 注意:如果要手动或者使用其他应用程序管理补给箱覆盖,可以禁用此服务器管理器补给箱覆盖。 详情在右上角全局设置“启用补给箱设置”选项。
- 警告:如果你不正确地填写每个参数,它可能导致补给箱和宝箱不产生。请确保所有部分填写正确。
+
+ 光柱/补给箱/战利品设置覆盖
+ 有关于光柱/补给箱/战利品/宝箱/河狸窝掉落的描述
+ 物品分类(温馨提示请看概率)
+ 分类内容(温馨提示请看概率)
+ 物品代码(温馨提示请看概率)
+ 光柱/补给箱/战利品/宝箱覆盖设置
+ 注意:如果要手动或者使用其他应用程序管理光柱/补给箱/战利品掉落覆盖,可以禁用此服务器管理器补给箱覆盖。 详情在右上角全局设置“启用补给箱设置”选项。
+ 警告:如果你不正确地填写每个参数,它可能导致光柱/补给箱/战利品/宝箱掉落不产生。请确保所有部分填写正确。
- 补给箱
- 提供需要覆盖的箱子的箱子类字符串
- 最少物品设置
- 设置补给箱最少物品数量.
+ 光柱/补给箱/战利品/宝箱/河狸窝
+ 提供需要覆盖的光柱/补给箱/战利品/宝箱/河狸窝的箱子类字符串
+ 最少物品分类
+ 设置光柱/补给箱/战利品最少物品数量.
最大物品设置
- 设置补给箱最大物品数量.
+ 设置光柱/补给箱/战利品最大物品数量.
品质倍率
这是用倍数来修改物品品质. 数值1.0将决定混合物品品质(通常设置保持为1.0).
防止重复
如果打开, 将确保只有一样同类型的物品被添加到补给箱中.
- 附加项目集
+ 设为追加
如果启用,将添加项目集到供应箱,而不是完全覆盖所有项目。
防止增加
如果启用,则会动态增加您添加的其他项目集所掉落的项目数量(仅在AppendItemSets = true时适用)。
描述
用于标识项目的描述。
- 最少物品
- 设置补给箱中最少物品.
+ 最少分类
+ 设置光柱/补给箱/战利品中最少物品.
最多物品
- 设置补给箱中最多物品.
+ 设置光柱/补给箱/战利品最多物品.
品质倍数
这是用倍率来修改物品品质.数值1.0将决定混合物品品质(通常设置保持为1.0)
- 重量
+ 概率
指定项目集合使其进入补给箱的几率。
防止重复
如果启用,将确保只有一个项目将添加到相同的补给箱,如果它被添加到两个不同的集合。
描述
描述设置加入的物品.
- 重量
- 指定几率物品进入补给箱.
+ 概率
+ 指定几率物品进入光柱/补给箱/战利品.
最低品质
- 最低品质物品将进入补给箱.
+ 最低品质物品将进入光柱/补给箱/战利品.
最高品质
- 最高品质物品将进入补给箱.
+ 最高品质物品将进入光柱/补给箱/战利品.
最低品质
- 最低品质的物品将进入补给箱 (通常建议保持在1.0).
+ 最低品质的物品将进入光柱/补给箱/战利品 (通常建议保持在1.0).
最高品质
- 最高品质的物品将进入补给箱 (通常建议保持在1.0).
+ 最高品质的物品将进入光柱/补给箱/战利品 (通常建议保持在1.0).
强制蓝图
如果开启, 你将会经常生成蓝图替换物品.
蓝图几率
@@ -2168,24 +2279,24 @@
物品
该物品的物品代码.
- 重量
+ 概率
指定物品进入战利品箱的几率。
- 增加补给箱
+ 增加光柱/补给箱/战利品
增加物品设置
设置加入物品
增加物品
- 删除所有补给箱
+ 删除所有光柱/补给箱/战利品
删除所有物品设置
删除所有加入的物品
删除所有物品
- 粘贴补给箱数据
- 删除补给箱
+ 粘贴光柱/补给箱/战利品数据
+ 删除光柱/补给箱/战利品
删除物品设置
删除设置加入的物品
删除物品
- 保存所有补给箱
- 保存补给箱
+ 保存所有光柱/补给箱/战利品
+ 保存光柱/补给箱/战利品
@@ -2217,6 +2328,23 @@
+
+ 禁止恐龙传输覆盖
+ 禁止传输
+ 禁止传输覆盖设置
+ 注意:如果您想手动或使用另一个应用程序管理您的覆盖,您可以禁用该选项,该选项将阻止服务器管理器管理覆盖。查看全局设置中的“自定义覆盖选项”.
+ 警告:将恐龙添加到这个列表将阻止它们被传输到服务器或从服务器.
+
+ 恐龙
+ 恐龙类的目录
+
+ 添加禁止传输
+ 删除所有禁止传输
+ 粘贴禁止传输数据
+ 删除禁止传输
+ 保存禁止传输数据
+
+
玩家设置
部落设置
@@ -2390,34 +2518,6 @@
设置
-
- 孤岛(The Island)
- 中心岛地图(The Center)
- 焦土地图(Scorched Earth)
- 仙境地图(Ragnarok)
- 畸变地图(Aberration)
- 灭绝地图(Extinction)
- 瓦尔盖罗(Valguero)
- 创世纪(Genesis)
- 水晶岛(Crystal Isles)
-
-
-
- 原始服(Primitive Plus)
-
-
-
- 生存
-
-
-
- 情人节
- 复活节
- 恐惧进化(万圣节)
- 土耳其审判(感恩节)
- 冬季仙境(圣诞节)
-
-
@@ -2632,10 +2732,11 @@
狮鹫
北极熊
冰飞龙
+ 死亡蠕虫
- 冰虫
+ 冰虫洞蠕虫女皇
熔岩石头人
喷火龙 (仙境传说简单难度)
@@ -2754,13 +2855,10 @@
腐化死神国王
腐化双足飞龙
- 沙漠泰坦
执行者
- 森林泰坦
嘎查
气囊虫
玛纳加尔姆
- 冰霜泰坦
大型机甲
机甲
雪鸮
@@ -2770,18 +2868,140 @@
- 腐化的肿瘤
- 国王泰坦 (简单难度)
- 国王泰坦 (困难难度)
- 国王泰坦 (中等难度)
+ 沙漠泰坦
+ 冰霜泰坦
+ 森林泰坦
+ 国王泰坦 (简单)
+ 国王泰坦 (困难)
+ 国王泰坦 (中等)
恐爪龙
岩石巨人(苔藓)
岩石巨人(冰)
-
+ 育母蜘蛛 (Lysrix)
+
+
+
+
+
+ 鲲
+ 血腥追猎者
+ 岩浆怪
+ 平台巨龟
+ 费洛克斯小
+ 费洛克斯大
+ 昆虫群
+ 鱼群
+ 泰克悬浮艇
+ Tek 三角龙
+ Tek 南方巨兽
+ X-金色条纹巨齿鲨
+ X-异特龙
+ X-甲龙
+ X-阿根廷巨鹰
+ X-龙王鲸
+ X-邓氏鱼
+ X-鱼龙
+ X-巨齿鲨
+ X-沧龙
+ X-水獺
+ X-副栉龙
+ X-迅猛龙
+ X-国王
+ X-石头人
+ X-剑齿虎
+ X-剑齿鲑
+ X-剑齿鲑(稀有)
+ X-棘背龙
+ X-古神翼龙
+ X-三角龙
+ X-披毛犀
+ X-羽暴龙
+
+
+
+ 精英水晶血飞龙
+ 水晶血飞龙
+ 灰烬水晶飞龙
+ 热带水晶飞龙
+ 喷气翼龙
+ 巨蜂
+
+
+
+ 水晶女王{BOSS}
+ 水晶飞龙女王(简单)
+ 水晶飞龙女王(中等)
+ 水晶飞龙女王(困难)
+
+
+
+ 鳗鱼BOSS (简单)
+ 鳗鱼BOSS (中等)
+ 鳗鱼BOSS (困难)
+
+ 鳗鱼爪牙 (简单)
+ 鳗鱼爪牙(中等)
+ 鳗鱼爪牙 (困难)
+
+ VR BOSS (简单)
+ VR BOSS (中等)
+ VR BOSS (困难)
+
+
+
+ 虚空海豚
+ 鸭嘴飞鼠
+ 诺格林
+ 影鬃
+ 跨步者
+ 虚空飞龙
+ 实验巨龙
+ 巨噬细胞
+ R-异特龙
+ R-牛龙
+ R-凶齿豨
+ R-恐熊
+ R-双脊龙
+ R-冰原狼
+ R-气囊虫
+ R-南巨
+ R-大地懒
+ R-雪鸮
+ R-副栉龙
+ R-巨型袋鼠
+ R-风神翼龙
+ R-雷龙
+ R-刺面龙
+ R-袋狮
+ R-碳水龟
+ 凶恶猿狐
+ R-庞马
+ R-死神王后
+ R-死神国王
+ R-死神国王(驯服)
+ 召唤师
+ 防御单元
+ 侦察机
+ 巨噬细胞
+ Exo-Mek机甲(做物品收物品)
+
+
+
+ 罗克韦尔 BOSS(全盛时期)
+ 罗克韦尔 BOSS(简单)
+ 罗克韦尔 BOSS(中等)
+ 罗克韦尔 BOSS(困难)
+
+ 罗克韦尔节点 BOSS
+ 罗克韦尔节点 BOSS(简单)
+ 罗克韦尔节点 BOSS(中等)
+ 罗克韦尔节点 BOSS(困难)
+
+
@@ -3499,9 +3719,55 @@
泰克桥梁
泰克重力手雷
-
+
+
+ 鞍-岩喉龙
+ 鞍-巨龟平台
+ 渔网
+ 木制海洋平台
+ 金属海洋平台
+ 压力板
+ 矿枪
+
+
+
+ 鲲-泰克鞍
+ 泰克光刃
+ 巡航导弹
+ TEK 榴弹发射器
+ 未组装的TEK悬停艇
+ 泰克弹射板
+ 泰克传感器
+ 泰克肩炮
+
+
+
+ 泰克悬停帆
+ 泰克相枪
+ 弹药箱
+ 泰克弓
+ 虚空海豚星翼-鞍
+ 网状射弹
+ 加特林机枪
+ 鸭嘴飞鼠-鞍
+ 皮划艇
+ 一罐沥青
+ 孵化器
+ 人体模型
+ 泰克水壶
+ 泰克监视控制台
+ 泰克耕地
+ 未组装的Exo-Mek机甲(做物品收物品)
+
+
鞍 - 恐爪龙
+
+
+
+ 脊颌翼龙的鞍
+
+
@@ -3790,6 +4056,9 @@
白色浆果
红色浆果
血包
+ 生成育母蜘蛛传送门
+ 生成喷火龙传送门
+ 生成大金刚传送门
驱虫剂
仙人掌汁液
水壶 (空)
@@ -3870,6 +4139,12 @@
冰水瓶 (空)
冰水瓶 (满)
生物毒素
+ 普通饲料
+ 基础饲料
+ 简单饲料
+ 上等饲料
+ 特殊饲料
+ 非凡饲料
饲料 (异特龙蛋)
饲料 (甲龙蛋)
饲料 (始祖鸟蛋)
@@ -4484,7 +4759,7 @@
长弓
金属锤
金属弯刀
- 黑曜石矛
+ 黑曜石矛
黑曜石镐
干草叉
燧发枪
@@ -4659,6 +4934,7 @@
打过
吊灯
水泥搅拌机
+
斜水泥屋顶
链条
混凝土天花板
@@ -4702,8 +4978,10 @@
木材窗框
木材墙
木材左山墙
- 木材右山墙
+ 木材右山墙
+ 通用神器
木材站
+ 土坯斜坡
APS邮箱
市场摊位
水池
@@ -4821,11 +5099,12 @@
森林泰坦鞍
嘎查鞍
气囊虫鞍
+ 腐化的肿瘤
玛纳加尔姆鞍
冰霜泰坦鞍
机甲火箭模块 (机甲可部署火箭模块)
机甲护盾模块 (机甲可部署屏障模块)
- 机甲重炮模块 (机甲可部署重炮模块)
+ 机甲重炮模块 (机甲可部署重炮模块)
力神转换接口 (机甲可部署力神变形模块)
雪鸮鞍
刺面龙鞍
@@ -4866,6 +5145,7 @@
未组装的执行者
未组装的机甲
低温冰箱
+ 未组装执行者蓝图
恐龙电子项圈
泰坦王旗帜
机械泰坦王旗帜
@@ -4886,8 +5166,93 @@
鞍-恐爪龙
-
-
+
+ 泰克光刃
+ 泰克榴弹发射器
+ 鱼网
+ 巡航导弹
+ 矿枪
+ 泰克肩炮
+ 泰克古神翼龙鞍
+ 岩喉龙鞍 (创世 1)
+ 巨龟平台鞍 (创世 1)
+ 资源包1 (创世 1)
+ 资源包2 (创世 1)
+ 资源包3 (创世 1)
+ 血蛛蛋 (创世 1)
+ 熔喉龙蛋 (创世 1)
+ 巨龟蛋 (创世 1)
+ 泰克三角龙蛋 (创世 1)
+ 龙涎香
+ 甲壳碎片
+ 优质花粉
+ 金块
+ 死神毒素 (创世 1)
+ 精英 X-三角龙
+ 未组装的泰克悬浮艇
+ 金属海洋平台
+ 主控制器头盔皮肤
+ 金纹巨齿
+ 压力板
+ 泰克传感器
+ 泰克弹跳器
+ 木制海洋平台
+
+
+
+ 诱变剂
+ 弹药箱
+ 独木舟
+ 加特林
+ 孵蛋器
+ 泰克耕地
+ 泰克悬停帆
+ 泰克弓
+ 泰克水壶
+ 泰克远程摄像头
+ 泰克监控控制台
+ 鸭嘴飞鼠-鞍
+ 虚空海豚星翼-鞍
+ 网状射弹
+ 网状弹药
+ 可以购买的印痕点
+ 网枪
+ 鱼叉枪
+ 沥青罐
+ 未组装Exo-mek机甲
+ 突变凝胶
+ 泰克相枪
+ 普通的造蛋
+ 简单的造蛋
+ 上等的造蛋
+ 服装变异幸存者
+ 特殊的造蛋
+ 非凡的造蛋
+ 基础的造蛋
+ 植物R-1 种子(生肉)
+ 植物R-2 种子(鱼肉)
+ 植物R-3 种子(腐肉)
+ 植物R-4 种子(优质生肉)
+ 植物R-5 种子(优质生鱼肉)
+
+
+
+ 恐龙洗点卡
+ 泰克一键解锁
+ 炮塔终端
+ 恐龙自定义等级升级卡
+ 一键解锁
+ 小姐姐保护罩
+ 管理员翅膀
+ 飞行背包
+ 金手指 2.0
+ 抽奖礼盒1
+ 抽奖礼盒2
+ 墓碑
+ 新手礼包
+
+
+
@@ -5137,6 +5502,7 @@
(老图孤岛) 上古神器强壮
(老图孤岛) 上古神器狡诈(新)
(老图孤岛) 上古神器残暴
+ 迅猛龙节日礼物(仅限活动)
(焦土) 洞穴战利品箱 1
(焦土) 洞穴战利品箱 2
@@ -5186,15 +5552,223 @@
(畸变) 神器容器潜行
(畸变) 神器容器失落
- 洞穴战利品箱 (蓝色)
- 洞穴战利品箱 (黄色)
- 洞穴战利品箱 (红色)
+ 钓鱼的鱼肉
+ 渔网奖励
+ 河狸窝战利品
+ 钓鱼的战利品
+
+ 洞穴补给箱 (蓝色)
+ 洞穴补给箱 (黄色)
+ 洞穴补给箱 (红色)
+ 蓝色空投
+ 黄色空投
+ 红色空投
+ 紫色空投
神器容器混乱
神器容器增长
神器容器虚空
- 神器容器国王泰坦 (困难)
- 神器容器国王泰坦 (中等)
- 神器容器国王泰坦 (简单)
+ 能量元素树(简单)
+ 能量元素树(中级)
+ 能量元素树(困难)
+ 能量元素树(传说)
+ 国王泰坦 (困难)
+ 国王泰坦 (中等)
+ 国王泰坦 (简单)
+
+ 紫色战利品箱
+ 紫色战利品箱 (双重物品)
+ 红色战利品箱
+ 红色战利品箱(双重物品)
+ 黄战利品箱
+ 黄战利品箱(双重物品)
+
+ 河狸窝
+ 深海战利品箱
+ 大型河狸窝
+ 百宝箱
+
+ 毒气树(创世1)
+ “摇摆之王”大奖赛(简单){任务}
+ “摇摆之王”大奖赛(中等){任务}
+ “摇摆之王”大奖赛(困难){任务}
+ 遇见花粉(简单){任务}
+ 遇见花粉{(中等){任务}
+ 遇见花粉(困难){任务}
+ 另一个沼泽狩猎(简单){任务}
+ 另一个沼泽狩猎(中等){任务}
+ 另一个沼泽狩猎(困难){任务}
+ 沼泽大擂台(简单){任务}
+ 沼泽大擂台(中等){任务}
+ 沼泽大擂台(困难){任务}
+ 沼泽钓鱼(简单){任务}
+ 沼泽钓鱼(中等){任务}
+ 沼泽钓鱼(困难){任务}
+ 沼泽拉力赛(简单){任务}
+ 沼泽拉力赛(中等){任务}
+ 沼泽拉力赛(困难){任务}
+ 加量不加价(简单){任务}
+ 加量不加价(中等){任务}
+ 加量不加价(困难){任务}
+ 渡渡球投篮(简单){任务}
+ 渡渡球投篮(中等){任务}
+ 渡渡球投篮(困难){任务}
+ 蹦蹦跳跳呱呱(简单){任务}
+ 蹦蹦跳跳呱呱(中等){任务}
+ 蹦蹦跳跳呱呱(困难){任务}
+ 间谍对棘背龙(简单){任务}
+ 间谍对棘背龙(中等){任务}
+ 间谍对棘背龙(困难){任务}
+ 平静沼泽(简单){任务}
+ 平静沼泽(中等){任务}
+ 平静沼泽(困难){任务}
+ 网络搜索(简单){任务}
+ 网络搜索(中等){任务}
+ 网络搜索(困难){任务}
+
+ 雪地大乱斗(简单){任务}
+ 雪地大乱斗(中等){任务}
+ 雪地大乱斗(困难){任务}
+ 迷路的鹿群(简单){任务}
+ 迷路的鹿群(中等){任务}
+ 迷路的鹿群(困难){任务}
+ 捉迷藏(简单){任务}
+ 捉迷藏(中等){任务}
+ 捉迷藏(困难){任务}
+ 袋子在哪里,家就在哪里(简单){任务}
+ 袋子在哪里,家就在哪里(中等){任务}
+ 袋子在哪里,家就在哪里(困难){任务}
+ 冰钓(简单){任务}
+ 冰钓(中等){任务}
+ 冰钓(困难){任务}
+ 万象奔腾(简单){任务}
+ 万象奔腾(中等){任务}
+ 万象奔腾(困难){任务}
+ 淘金狂热(简单){任务}
+ 淘金狂热(中等){任务}
+ 淘金狂热(困难){任务}
+ 怒羽冲冠(简单){任务}
+ 怒羽冲冠(中等){任务}
+ 怒羽冲冠(困难){任务}
+ 剑齿虎障碍滑雪(简单){任务}
+ 剑齿虎障碍滑雪(中等){任务}
+ 剑齿虎障碍滑雪(困难){任务}
+ 搜索冰冻区(简单){任务}
+ 搜索冰冻区(中等){任务}
+ 搜索冰冻区(困难){任务}
+ 犀牛-500(简单){任务}
+ 犀牛-500(中等){任务}
+ 犀牛-500(困难){任务}
+
+ 水下闪电赛(简单){任务}
+ 水下闪电赛(中等){任务}
+ 水下闪电赛(困难){任务}
+ 追逐大白鲸(简单){任务}
+ 追逐大白鲸(中等){任务}
+ 追逐大白鲸(困难){任务}
+ 经典的回声(简单){任务}
+ 经典的回声(中等){任务}
+ 经典的回声(困难){任务}
+ 捉迷藏(简单){任务}
+ 捉迷藏(中等){任务}
+ 捉迷藏(困难){任务}
+ 水怪寻踪(简单){任务}
+ 水怪寻踪(中等){任务}
+ 水怪寻踪(困难){任务}
+ 难缠的莫德尔(简单){任务}
+ 难缠的莫德尔(中等){任务}
+ 难缠的莫德尔(困难){任务}
+ 海龟总动员(简单){任务}
+ 海龟总动员(中等){任务}
+ 海龟总动员(困难){任务}
+ 沧龙的建议(简单){任务}
+ 沧龙的建议(中等){任务}
+ 沧龙的建议(困难){任务}
+ 深海巨牙(简单){任务}
+ 深海巨牙(中等){任务}
+ 深海巨牙(困难){任务}
+ 水上摩托(简单){任务}
+ 水上摩托(中等){任务}
+ 水上摩托(困难){任务}
+ 谁藏了鱿鱼?(简单){任务}
+ 谁藏了鱿鱼?(中等){任务}
+ 谁藏了鱿鱼?(困难){任务}
+
+ 你好,再见(简单){任务}
+ 你好,再见(中等){任务}
+ 你好,再见(困难){任务}
+ 热死人啦(简单){任务}
+ 热死人啦(中等){任务}
+ 热死人啦((困难){任务}
+ 得快点了(简单){任务}
+ 得快点了(中等){任务}
+ 得快点了(困难){任务}
+ 热力猎杀(简单){任务}
+ 热力猎杀(中等){任务}
+ 热力猎杀(困难){任务}
+ 弑君者(简单){任务}
+ 弑君者(中等){任务}
+ 弑君者(困难){任务}
+ 岩浆大混战(简单){任务}
+ 岩浆大混战(中等){任务}
+ 岩浆大混战(困难){任务}
+ 惊心动魄的寻宝之旅(简单){任务}
+ 惊心动魄的寻宝之旅(中等){任务}
+ 惊心动魄的寻宝之旅(困难){任务}
+ 铁板烧烤(简单){任务}
+ 铁板烧烤(中等){任务}
+ 铁板烧烤(困难){任务}
+ 取蛋大冒险(简单){任务}
+ 取蛋大冒险(中等){任务}
+ 取蛋大冒险(困难){任务}
+ 山顶之旅(简单){任务}
+ 山顶之旅(中等){任务}
+ 山顶之旅(困难){任务}
+ 将你震撼(简单){任务}
+ 将你震撼(中等){任务}
+ 将你震撼(困难){任务}
+
+ 船长的征服(简单){任务}
+ 船长的征服(中等){任务}
+ 船长的征服(困难){任务}
+ 无须畏惧死神国王(简单){任务}
+ 无须畏惧死神国王(中等){任务}
+ 无须畏惧死神国王(困难){任务}
+ 月光下的狩猎(简单){任务}
+ 月光下的狩猎(中等){任务}
+ 月光下的狩猎(困难){任务}
+ 这是一次猎虫行动(简单){任务}
+ 这是一次猎虫行动(中等){任务}
+ 这是一次猎虫行动(困难){任务}
+ 月球之王(简单){任务}
+ 月球之王(中等){任务}
+ 月球之王(困难){任务}
+ 空中大灌篮(简单){任务}
+ 空中大灌篮(中等){任务}
+ 空中大灌篮(困难){任务}
+ 泰克恐怖(简单){任务}
+ 泰克恐怖(中等){任务}
+ 泰克恐怖(困难){任务}
+ 这小小的光芒(简单){任务}
+ 这小小的光芒(中等){任务}
+ 这小小的光芒(困难){任务}
+ 勇往直前(简单){任务}
+ 勇往直前(中等){任务}
+ 勇往直前(困难){任务}
+ 极品飞艇(简单){任务}
+ 极品飞艇(中等){任务}
+ 极品飞艇(困难){任务}
+ 资源包1级
+ 资源包2级
+ 资源包3级
+
+ 空投_白色(创世2)
+ 空投_绿色(创世2)
+ 空投_蓝色(创世2)
+ 空投_紫色(创世2)
+ 空投_黄色(创世2)
+ 空投_红色(创世2)
+ 空投_青色(创世2)
+ 空投_橙色(创世2)
@@ -5211,6 +5785,16 @@
Boss 清单 - 喷火龙 (困难)
Boss 清单 - 最终BOSS爪牙
+ Boss 清单 - 喷火龙 (容易)
+ Boss 清单 - 喷火龙 (中等)
+ Boss 清单 - 喷火龙 (困难)
+ Boss 清单 - 狮身蝎尾 (容易)
+ Boss 清单 - 狮身蝎尾 (中等)
+ Boss 清单 - 狮身蝎尾 (困难)
+ Boss 清单 - 大金刚 (容易)
+ Boss 清单 - 大金刚 (中等)
+ Boss 清单 - 大金刚 (困难)
+
Boss 清单 - 狮蝎兽 (容易)
Boss 清单 - 狮蝎兽 (中等)
Boss 清单 - 狮蝎兽 (困难)
@@ -5226,6 +5810,17 @@
Boss 清单 - 沙漠泰坦
Boss 清单 - 森林泰坦
Boss 清单 - 冰霜泰坦
+
+ Boss 清单 - (水晶岛)水晶女王 (简单)
+ Boss 清单 - (水晶岛)水晶女王 (中等)
+ Boss 清单 - (水晶岛)水晶女王 (困难)
+
+ Boss 清单 - 喷火龙 (简单)
+ Boss 清单 - 喷火龙 (中等)
+ Boss 清单 - 喷火龙 (困难)
+ Boss 清单 - 狮身蝎尾 (简单)
+ Boss 清单 - 狮身蝎尾 (中等)
+ Boss 清单 - 狮身蝎尾 (困难)
@@ -6141,6 +6736,21 @@
S +泰克水下天花板
S +泰克倾斜密封舱
S +泰克真空隔离门
+ S+木质海洋平台
+ S+金属海洋平台
+ S+木崖平台
+ S+石崖平台
+ S+金属悬崖平台
+ S+玻璃悬崖平台
+ S+木树平台
+ S+石树平台
+ S+玻璃树平台
+ S+金属树平台
+ S+泰克树平台
+ S+金属平台楔
+ S+木平台楔
+ S+玻璃平台楔
+ S+泰克平台楔
@@ -6218,7 +6828,6 @@
大型木制墙
金属水管 - 弹性
石制水管 - 弹性
- 黏土斜坡
金属斜坡
石制斜坡
泰克斜坡
@@ -6243,4 +6852,19 @@
弹性电缆
+
+ 管理员翅膀
+ 飞行背包
+ 金手指 2.0
+ 抽奖礼盒 1
+ 抽奖礼盒 2
+ 墓碑
+ 新手礼包
+ 小姐姐罩子
+ 恐龙自定义等级升级卡
+ 一键解锁
+ 泰克一键解锁
+ 炮塔终端
+ 恐龙洗点卡
+
diff --git a/src/ARKServerManager/Lib/ServerBranchSnapshot.cs b/src/ARKServerManager/Lib/BranchSnapshot.cs
similarity index 52%
rename from src/ARKServerManager/Lib/ServerBranchSnapshot.cs
rename to src/ARKServerManager/Lib/BranchSnapshot.cs
index b9f34073..c3b0283d 100644
--- a/src/ARKServerManager/Lib/ServerBranchSnapshot.cs
+++ b/src/ARKServerManager/Lib/BranchSnapshot.cs
@@ -3,15 +3,37 @@ using System.Collections.Generic;
namespace ServerManagerTool.Lib
{
- public class ServerBranchSnapshot
+ public class BranchSnapshot
{
+ private BranchSnapshot()
+ {
+ }
+
public string BranchName = string.Empty;
public string BranchPassword = string.Empty;
+
+ public static BranchSnapshot Create(ServerProfile profile)
+ {
+ return new BranchSnapshot
+ {
+ BranchName = profile.BranchName,
+ BranchPassword = profile.BranchPassword
+ };
+ }
+
+ public static BranchSnapshot Create(ServerProfileSnapshot profile)
+ {
+ return new BranchSnapshot
+ {
+ BranchName = profile.BranchName,
+ BranchPassword = profile.BranchPassword
+ };
+ }
}
- public class ServerBranchSnapshotComparer : IEqualityComparer
+ public class BranchSnapshotComparer : IEqualityComparer
{
- public bool Equals(ServerBranchSnapshot x, ServerBranchSnapshot y)
+ public bool Equals(BranchSnapshot x, BranchSnapshot y)
{
//Check whether the compared objects reference the same data.
if (Object.ReferenceEquals(x, y)) return true;
@@ -24,7 +46,7 @@ namespace ServerManagerTool.Lib
return x.BranchName == y.BranchName;
}
- public int GetHashCode(ServerBranchSnapshot snapshot)
+ public int GetHashCode(BranchSnapshot snapshot)
{
//Check whether the object is null
if (snapshot is null) return 0;
diff --git a/src/ARKServerManager/Lib/GameData.cs b/src/ARKServerManager/Lib/GameData.cs
index c3c0612e..2f0117fe 100644
--- a/src/ARKServerManager/Lib/GameData.cs
+++ b/src/ARKServerManager/Lib/GameData.cs
@@ -86,14 +86,14 @@ namespace ServerManagerTool.Lib
}
// total conversion mods
- gameData.Mods.AddRange(userGameData.Mods);
+ gameData.TotalConversions.AddRange(userGameData.TotalConversions);
- if (gameData.Mods.Count > 0)
+ if (gameData.TotalConversions.Count > 0)
{
var mods1 = totalConversions.ToList();
- mods1.AddRange(gameData.Mods.Where(item => !item.IsSotF).ToList().ConvertAll(item => new ComboBoxItem { ValueMember = item.ClassName, DisplayMember = item.Description }));
+ mods1.AddRange(gameData.TotalConversions.Where(item => !item.IsSotF).ToList().ConvertAll(item => new ComboBoxItem { ValueMember = item.ClassName, DisplayMember = item.Description }));
var mods2 = totalConversionsSotF.ToList();
- mods2.AddRange(gameData.Mods.Where(item => item.IsSotF).ToList().ConvertAll(item => new ComboBoxItem { ValueMember = item.ClassName, DisplayMember = item.Description }));
+ mods2.AddRange(gameData.TotalConversions.Where(item => item.IsSotF).ToList().ConvertAll(item => new ComboBoxItem { ValueMember = item.ClassName, DisplayMember = item.Description }));
totalConversions = mods1.ToArray();
totalConversionsSotF = mods2.ToArray();
@@ -192,7 +192,7 @@ namespace ServerManagerTool.Lib
public static Engram GetEngramForClass(string className) => engrams.FirstOrDefault(e => e.EngramClassName.Equals(className));
- public static bool HasEngramForClass(string className) => engrams.Any(e => e.EngramClassName.Equals(className));
+ public static bool HasEngramForClass(string className) => !string.IsNullOrWhiteSpace(className) && engrams.Any(e => e.EngramClassName.Equals(className));
public static bool IsTekgram(string className) => engrams.Any(e => e.EngramClassName.Equals(className) && e.IsTekgram);
@@ -206,9 +206,11 @@ namespace ServerManagerTool.Lib
public static PrimalItem GetItemForClass(string className) => items.FirstOrDefault(e => e.ClassName.Equals(className));
- public static bool HasItemForClass(string className) => items.Any(e => e.ClassName.Equals(className));
+ public static bool HasItemForClass(string className) => !string.IsNullOrWhiteSpace(className) && items.Any(e => e.ClassName.Equals(className));
public static string FriendlyItemNameForClass(string className, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(className) ? string.Empty : GlobalizedApplication.Instance.GetResourceString(className) ?? gameData?.Items?.FirstOrDefault(i => i.ClassName.Equals(className))?.Description ?? (returnEmptyIfNotFound ? string.Empty : className);
+
+ public static string FriendlyItemModNameForClass(string className) => string.IsNullOrWhiteSpace(className) ? string.Empty : GameData.FriendlyNameForClass($"Mod_{gameData?.Items?.FirstOrDefault(i => i.ClassName.Equals(className))?.Mod}", true) ?? string.Empty;
#endregion
#region Resources
@@ -218,7 +220,7 @@ namespace ServerManagerTool.Lib
public static ResourceClassMultiplier GetResourceMultiplierForClass(string className) => resourceMultipliers.FirstOrDefault(e => e.ClassName.Equals(className));
- public static bool HasResourceMultiplierForClass(string className) => resourceMultipliers.Any(e => e.ClassName.Equals(className));
+ public static bool HasResourceMultiplierForClass(string className) => !string.IsNullOrWhiteSpace(className) && resourceMultipliers.Any(e => e.ClassName.Equals(className));
public static string FriendlyResourceNameForClass(string className) => string.IsNullOrWhiteSpace(className) ? string.Empty : GlobalizedApplication.Instance.GetResourceString(className) ?? gameData?.Items?.FirstOrDefault(i => i.ClassName.Equals(className) && i.IsHarvestable)?.Description ?? className;
#endregion
@@ -230,7 +232,7 @@ namespace ServerManagerTool.Lib
public static MapSpawner GetMapSpawnerForClass(string className) => mapSpawners.FirstOrDefault(e => e.ClassName.Equals(className));
- public static bool HasMapSpawnerForClass(string className) => mapSpawners.Any(e => e.ClassName.Equals(className));
+ public static bool HasMapSpawnerForClass(string className) => !string.IsNullOrWhiteSpace(className) && mapSpawners.Any(e => e.ClassName.Equals(className));
public static string FriendlyMapSpawnerNameForClass(string className, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(className) ? string.Empty : GlobalizedApplication.Instance.GetResourceString(className) ?? gameData?.MapSpawners?.FirstOrDefault(i => i.ClassName.Equals(className))?.Description ?? (returnEmptyIfNotFound ? string.Empty : className);
#endregion
@@ -242,9 +244,11 @@ namespace ServerManagerTool.Lib
public static SupplyCrate GetSupplyCrateForClass(string className) => supplyCrates.FirstOrDefault(e => e.ClassName.Equals(className));
- public static bool HasSupplyCrateForClass(string className) => supplyCrates.Any(e => e.ClassName.Equals(className));
+ public static bool HasSupplyCrateForClass(string className) => !string.IsNullOrWhiteSpace(className) && supplyCrates.Any(e => e.ClassName.Equals(className));
public static string FriendlySupplyCrateNameForClass(string className, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(className) ? string.Empty : GlobalizedApplication.Instance.GetResourceString(className) ?? gameData?.SupplyCrates?.FirstOrDefault(i => i.ClassName.Equals(className))?.Description ?? (returnEmptyIfNotFound ? string.Empty : className);
+
+ public static string FriendlySupplyCrateModNameForClass(string className) => string.IsNullOrWhiteSpace(className) ? string.Empty : GameData.FriendlyNameForClass($"Mod_{gameData?.SupplyCrates?.FirstOrDefault(i => i.ClassName.Equals(className))?.Mod}", true) ?? string.Empty;
#endregion
#region Game Maps
@@ -255,7 +259,7 @@ namespace ServerManagerTool.Lib
public static IEnumerable GetGameMaps() => gameMaps.Select(d => d.Duplicate());
- public static string FriendlyMapNameForClass(string className, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(className) ? string.Empty : GlobalizedApplication.Instance.GetResourceString(className) ?? gameData?.GameMaps?.FirstOrDefault(i => i.ClassName.Equals(className) && !i.IsSotF)?.Description ?? (returnEmptyIfNotFound ? string.Empty : className);
+ public static string FriendlyMapNameForClass(string className, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(className) ? string.Empty : GlobalizedApplication.Instance.GetResourceString("Map_" + className) ?? gameData?.GameMaps?.FirstOrDefault(i => i.ClassName.Equals(className) && !i.IsSotF)?.Description ?? (returnEmptyIfNotFound ? string.Empty : className);
private static ComboBoxItem[] gameMapsSotF = new[]
{
@@ -264,7 +268,7 @@ namespace ServerManagerTool.Lib
public static IEnumerable GetGameMapsSotF() => gameMapsSotF.Select(d => d.Duplicate());
- public static string FriendlyMapSotFNameForClass(string className, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(className) ? string.Empty : GlobalizedApplication.Instance.GetResourceString(className) ?? gameData?.GameMaps?.FirstOrDefault(i => i.ClassName.Equals(className) && i.IsSotF)?.Description ?? (returnEmptyIfNotFound ? string.Empty : className);
+ public static string FriendlyMapSotFNameForClass(string className, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(className) ? string.Empty : GlobalizedApplication.Instance.GetResourceString("Map_" + className) ?? gameData?.GameMaps?.FirstOrDefault(i => i.ClassName.Equals(className) && i.IsSotF)?.Description ?? (returnEmptyIfNotFound ? string.Empty : className);
#endregion
#region Total Conversions
@@ -275,7 +279,7 @@ namespace ServerManagerTool.Lib
public static IEnumerable GetTotalConversions() => totalConversions.Select(d => d.Duplicate());
- public static string FriendlyTotalConversionNameForClass(string className, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(className) ? string.Empty : GlobalizedApplication.Instance.GetResourceString(className) ?? gameData?.Mods?.FirstOrDefault(i => i.ClassName.Equals(className) && !i.IsSotF)?.Description ?? (returnEmptyIfNotFound ? string.Empty : className);
+ public static string FriendlyTotalConversionNameForClass(string className, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(className) ? string.Empty : GlobalizedApplication.Instance.GetResourceString("TotalConv_" + className) ?? gameData?.TotalConversions?.FirstOrDefault(i => i.ClassName.Equals(className) && !i.IsSotF)?.Description ?? (returnEmptyIfNotFound ? string.Empty : className);
private static ComboBoxItem[] totalConversionsSotF = new[]
{
@@ -284,7 +288,7 @@ namespace ServerManagerTool.Lib
public static IEnumerable GetTotalConversionsSotF() => totalConversionsSotF.Select(d => d.Duplicate());
- public static string FriendlyTotalConversionSotFNameForClass(string className, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(className) ? string.Empty : GlobalizedApplication.Instance.GetResourceString(className) ?? gameData?.Mods?.FirstOrDefault(i => i.ClassName.Equals(className) && i.IsSotF)?.Description ?? (returnEmptyIfNotFound ? string.Empty : className);
+ public static string FriendlyTotalConversionSotFNameForClass(string className, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(className) ? string.Empty : GlobalizedApplication.Instance.GetResourceString("TotalConv_" + className) ?? gameData?.TotalConversions?.FirstOrDefault(i => i.ClassName.Equals(className) && i.IsSotF)?.Description ?? (returnEmptyIfNotFound ? string.Empty : className);
#endregion
#region Stats Multipliers
@@ -318,6 +322,16 @@ namespace ServerManagerTool.Lib
return new float[] { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
}
+ internal static IEnumerable GetPerLevelMutagenLevelBoost_DinoWild()
+ {
+ return new int[] { 5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0 };
+ }
+
+ internal static IEnumerable GetPerLevelMutagenLevelBoost_DinoTamed()
+ {
+ return new int[] { 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 };
+ }
+
internal static bool[] GetStatMultiplierInclusions_DinoWildPerLevel()
{
return new bool[] { true, true, false, true, true, false, true, true, true, true, false, true };
@@ -347,6 +361,16 @@ namespace ServerManagerTool.Lib
{
return new bool[] { true, true, false, true, true, true, true, true, true, true, true, true };
}
+
+ internal static bool[] GetMutagenLevelBoostInclusions_DinoWild()
+ {
+ return new bool[] { true, true, true, true, true, true, true, true, true, true, true, true };
+ }
+
+ internal static bool[] GetMutagenLevelBoostInclusions_DinoTamed()
+ {
+ return new bool[] { true, true, true, true, true, true, true, true, true, true, true, true };
+ }
#endregion
#region Levels
@@ -375,7 +399,7 @@ namespace ServerManagerTool.Lib
public static IEnumerable GetBranches() => branches.Select(d => d.Duplicate());
- public static string FriendlyBranchName(string branchName, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(branchName) ? string.Empty : GlobalizedApplication.Instance.GetResourceString(branchName) ?? gameData?.Branches?.FirstOrDefault(i => i.BranchName.Equals(branchName) && !i.IsSotF)?.Description ?? (returnEmptyIfNotFound ? string.Empty : branchName);
+ public static string FriendlyBranchName(string branchName, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(branchName) ? string.Empty : GlobalizedApplication.Instance.GetResourceString("Branch_" + branchName) ?? gameData?.Branches?.FirstOrDefault(i => i.BranchName.Equals(branchName) && !i.IsSotF)?.Description ?? (returnEmptyIfNotFound ? string.Empty : branchName);
private static ComboBoxItem[] branchesSotF = new[]
{
@@ -384,7 +408,7 @@ namespace ServerManagerTool.Lib
public static IEnumerable GetBranchesSotF() => branchesSotF.Select(d => d.Duplicate());
- public static string FriendlyBranchSotFName(string branchName, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(branchName) ? string.Empty : GlobalizedApplication.Instance.GetResourceString(branchName) ?? gameData?.Branches?.FirstOrDefault(i => i.BranchName.Equals(branchName) && i.IsSotF)?.Description ?? (returnEmptyIfNotFound ? string.Empty : branchName);
+ public static string FriendlyBranchSotFName(string branchName, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(branchName) ? string.Empty : GlobalizedApplication.Instance.GetResourceString("Branch_" + branchName) ?? gameData?.Branches?.FirstOrDefault(i => i.BranchName.Equals(branchName) && i.IsSotF)?.Description ?? (returnEmptyIfNotFound ? string.Empty : branchName);
#endregion
#region Events
@@ -395,7 +419,7 @@ namespace ServerManagerTool.Lib
public static IEnumerable GetEvents() => events.Select(d => d.Duplicate());
- public static string FriendlyEventName(string eventName, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(eventName) ? string.Empty : GlobalizedApplication.Instance.GetResourceString(eventName) ?? gameData?.Events?.FirstOrDefault(i => i.EventName.Equals(eventName) && !i.IsSotF)?.Description ?? (returnEmptyIfNotFound ? string.Empty : eventName);
+ public static string FriendlyEventName(string eventName, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(eventName) ? string.Empty : GlobalizedApplication.Instance.GetResourceString("Event_" + eventName) ?? gameData?.Events?.FirstOrDefault(i => i.EventName.Equals(eventName) && !i.IsSotF)?.Description ?? (returnEmptyIfNotFound ? string.Empty : eventName);
private static ComboBoxItem[] eventsSotF = new[]
{
@@ -404,7 +428,7 @@ namespace ServerManagerTool.Lib
public static IEnumerable GetEventsSotF() => eventsSotF.Select(d => d.Duplicate());
- public static string FriendlyEventSotFName(string eventName, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(eventName) ? string.Empty : GlobalizedApplication.Instance.GetResourceString(eventName) ?? gameData?.Events?.FirstOrDefault(i => i.EventName.Equals(eventName) && i.IsSotF)?.Description ?? (returnEmptyIfNotFound ? string.Empty : eventName);
+ public static string FriendlyEventSotFName(string eventName, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(eventName) ? string.Empty : GlobalizedApplication.Instance.GetResourceString("Event_" + eventName) ?? gameData?.Events?.FirstOrDefault(i => i.EventName.Equals(eventName) && i.IsSotF)?.Description ?? (returnEmptyIfNotFound ? string.Empty : eventName);
#endregion
}
}
diff --git a/src/ARKServerManager/Lib/Model/StatsMultiplierArray.cs b/src/ARKServerManager/Lib/Model/StatsMultiplierFloatArray.cs
similarity index 82%
rename from src/ARKServerManager/Lib/Model/StatsMultiplierArray.cs
rename to src/ARKServerManager/Lib/Model/StatsMultiplierFloatArray.cs
index cab5087a..74365fb8 100644
--- a/src/ARKServerManager/Lib/Model/StatsMultiplierArray.cs
+++ b/src/ARKServerManager/Lib/Model/StatsMultiplierFloatArray.cs
@@ -5,29 +5,29 @@ using System.Linq;
namespace ServerManagerTool.Lib.Model
{
- public class StatsMultiplierArray : FloatIniValueArray
+ public class StatsMultiplierFloatArray : FloatIniValueArray
{
- protected StatsMultiplierArray(string iniKeyName, Func> resetFunc, bool[] inclusions)
+ protected StatsMultiplierFloatArray(string iniKeyName, Func> resetFunc, bool[] inclusions)
: base(iniKeyName, resetFunc)
{
Inclusions = inclusions;
}
- public StatsMultiplierArray(string iniKeyName, Func> resetFunc, bool[] inclusions, bool onlyWriteNonDefaults)
+ public StatsMultiplierFloatArray(string iniKeyName, Func> resetFunc, bool[] inclusions, bool onlyWriteNonDefaults)
: base(iniKeyName, resetFunc)
{
Inclusions = inclusions;
if (onlyWriteNonDefaults && resetFunc != null)
{
- DefaultValues = new StatsMultiplierArray(iniKeyName, null, inclusions);
+ DefaultValues = new StatsMultiplierFloatArray(iniKeyName, null, inclusions);
DefaultValues.AddRange(resetFunc());
}
}
public bool[] Inclusions { get; private set; } = null;
- private StatsMultiplierArray DefaultValues { get; set; } = null;
+ private StatsMultiplierFloatArray DefaultValues { get; set; } = null;
public override void FromIniValues(IEnumerable values)
{
diff --git a/src/ARKServerManager/Lib/Model/StatsMultiplierIntegerArray.cs b/src/ARKServerManager/Lib/Model/StatsMultiplierIntegerArray.cs
new file mode 100644
index 00000000..1d4b8554
--- /dev/null
+++ b/src/ARKServerManager/Lib/Model/StatsMultiplierIntegerArray.cs
@@ -0,0 +1,88 @@
+using ServerManagerTool.Common.Model;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace ServerManagerTool.Lib.Model
+{
+ public class StatsMultiplierIntegerArray : IntegerIniValueArray
+ {
+ protected StatsMultiplierIntegerArray(string iniKeyName, Func> resetFunc, bool[] inclusions)
+ : base(iniKeyName, resetFunc)
+ {
+ Inclusions = inclusions;
+ }
+
+ public StatsMultiplierIntegerArray(string iniKeyName, Func> resetFunc, bool[] inclusions, bool onlyWriteNonDefaults)
+ : base(iniKeyName, resetFunc)
+ {
+ Inclusions = inclusions;
+
+ if (onlyWriteNonDefaults && resetFunc != null)
+ {
+ DefaultValues = new StatsMultiplierIntegerArray(iniKeyName, null, inclusions);
+ DefaultValues.AddRange(resetFunc());
+ }
+ }
+
+ public bool[] Inclusions { get; private set; } = null;
+
+ private StatsMultiplierIntegerArray DefaultValues { get; set; } = null;
+
+ public override void FromIniValues(IEnumerable values)
+ {
+ this.Clear();
+
+ var list = new List();
+ if (this.ResetFunc != null)
+ list.AddRange(this.ResetFunc());
+
+ foreach (var v in values)
+ {
+ var indexStart = v.IndexOf('[');
+ var indexEnd = v.IndexOf(']');
+
+ if (indexStart >= indexEnd)
+ {
+ // Invalid format
+ continue;
+ }
+
+ if (!int.TryParse(v.Substring(indexStart + 1, indexEnd - indexStart - 1), out int index))
+ {
+ // Invalid index
+ continue;
+ }
+
+ if (index >= list.Count)
+ {
+ // Unexpected size
+ continue;
+ }
+
+ list[index] = this.FromIniValue(v.Substring(v.IndexOf('=') + 1).Trim());
+ this.IsEnabled = true;
+ }
+
+ this.AddRange(list);
+ }
+
+ public override IEnumerable ToIniValues()
+ {
+ var values = new List();
+ for (var i = 0; i < this.Count; i++)
+ {
+ if (!(Inclusions?.ElementAtOrDefault(i) ?? true))
+ continue;
+ if (DefaultValues != null && Equals(DefaultValues[i], this[i]))
+ continue;
+
+ if (string.IsNullOrWhiteSpace(IniCollectionKey))
+ values.Add(this.ToIniValue(this[i]));
+ else
+ values.Add($"{this.IniCollectionKey}[{i}]={this.ToIniValue(this[i])}");
+ }
+ return values;
+ }
+ }
+}
diff --git a/src/ARKServerManager/Lib/Model/SupplyCrateOverride.cs b/src/ARKServerManager/Lib/Model/SupplyCrateOverride.cs
index db6daa2d..16abf720 100644
--- a/src/ARKServerManager/Lib/Model/SupplyCrateOverride.cs
+++ b/src/ARKServerManager/Lib/Model/SupplyCrateOverride.cs
@@ -3,6 +3,7 @@ using ServerManagerTool.Common.Model;
using ServerManagerTool.Lib.ViewModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Linq;
using System.Runtime.Serialization;
using System.Windows;
@@ -37,14 +38,16 @@ namespace ServerManagerTool.Lib
errors.Add($"Missing Supply Crate Item Weight: Crate '{supplyCrate.SupplyCrateClassString}'; Set '{itemSet.SetName}'; Entry '{itemEntry.ItemEntryName}'; Item '{itemEntry.ItemClassStrings[index]}'.");
itemEntry.Items.Add(new SupplyCrateItemEntrySettings {
- ItemClassString = itemEntry.ItemClassStrings[index],
- ItemWeight = itemsWeight,
- });
+ ItemClassString = itemEntry.ItemClassStrings[index],
+ ItemWeight = itemsWeight,
+ });
}
}
}
}
+ Update();
+
return errors.ToArray();
}
@@ -72,6 +75,14 @@ namespace ServerManagerTool.Lib
public void UpdateForLocalization()
{
}
+
+ public void Update(bool recursive = true)
+ {
+ IsEnabled = this.Count > 0;
+
+ foreach (var supplyCrate in this)
+ supplyCrate.Update(recursive);
+ }
}
[DataContract]
@@ -167,7 +178,10 @@ namespace ServerManagerTool.Lib
public override void InitializeFromINIValue(string value)
{
if (string.IsNullOrWhiteSpace(value))
+ {
+ Update();
return;
+ }
var kvPair = value.Split(new[] { '=' }, 2);
var kvValue = kvPair[1].Trim(' ');
@@ -186,7 +200,34 @@ namespace ServerManagerTool.Lib
public string DisplayName => GameData.FriendlySupplyCrateNameForClass(SupplyCrateClassString);
- public bool IsValid => !string.IsNullOrWhiteSpace(SupplyCrateClassString) && ItemSets.Count > 0;
+ public string DisplayNameFull
+ {
+ get
+ {
+ var modName = GameData.FriendlySupplyCrateModNameForClass(SupplyCrateClassString); ;
+ return $"{(string.IsNullOrWhiteSpace(modName) ? string.Empty : $"({modName}) ")}{DisplayName}";
+ }
+ }
+
+ public bool IsViewValid => !string.IsNullOrWhiteSpace(SupplyCrateClassString) && (ItemSets?.Count ?? 0) > 0;
+
+ public static readonly DependencyProperty ValidStatusProperty = DependencyProperty.Register(nameof(ValidStatus), typeof(string), typeof(SupplyCrateOverride), new PropertyMetadata("N"));
+ public string ValidStatus
+ {
+ get { return (string)GetValue(ValidStatusProperty); }
+ set { SetValue(ValidStatusProperty, value); }
+ }
+
+ public void Update(bool recursive = true)
+ {
+ if (recursive && ItemSets != null)
+ {
+ foreach (var itemSet in ItemSets)
+ itemSet.Update(recursive);
+ }
+
+ ValidStatus = IsViewValid ? (ItemSets.Any(i => i.ValidStatus == "N") ? "N" : (ItemSets.Any(i => i.ValidStatus == "W") ? "W" : "Y")) : "N";
+ }
}
[DataContract]
@@ -280,7 +321,27 @@ namespace ServerManagerTool.Lib
return base.ToComplexINIValue(false);
}
- public bool IsValid => ItemEntries.Count > 0;
+ public string DisplayNameFull => SetName;
+
+ public bool IsViewValid => (ItemEntries?.Count ?? 0) > 0;
+
+ public static readonly DependencyProperty ValidStatusProperty = DependencyProperty.Register(nameof(ValidStatus), typeof(string), typeof(SupplyCrateItemSet), new PropertyMetadata("N"));
+ public string ValidStatus
+ {
+ get { return (string)GetValue(ValidStatusProperty); }
+ set { SetValue(ValidStatusProperty, value); }
+ }
+
+ public void Update(bool recursive = true)
+ {
+ if (recursive && ItemEntries != null)
+ {
+ foreach (var itemEntry in ItemEntries)
+ itemEntry.Update(recursive);
+ }
+
+ ValidStatus = IsViewValid ? (ItemEntries.Any(i => i.ValidStatus == "N") ? "N" : (ItemEntries.Any(i => i.ValidStatus == "W") ? "W" : "Y")) : "N";
+ }
}
[DataContract]
@@ -411,8 +472,30 @@ namespace ServerManagerTool.Lib
return base.ToComplexINIValue(false);
}
+ public string DisplayNameFull => ItemEntryName;
+
+ public float ChanceToBeBlueprint => ForceBlueprint ? 1 : ChanceToBeBlueprintOverride;
+
public bool IsModelValid => ItemClassStrings.Count > 0 && ItemClassStrings.Count == ItemsWeights.Count;
- public bool IsViewValid => Items.Count > 0;
+ public bool IsViewValid => (Items?.Count ?? 0) > 0;
+
+ public static readonly DependencyProperty ValidStatusProperty = DependencyProperty.Register(nameof(ValidStatus), typeof(string), typeof(SupplyCrateItemSetEntry), new PropertyMetadata("N"));
+ public string ValidStatus
+ {
+ get { return (string)GetValue(ValidStatusProperty); }
+ set { SetValue(ValidStatusProperty, value); }
+ }
+
+ public void Update(bool recursive = true)
+ {
+ if (recursive && Items != null)
+ {
+ foreach (var item in Items)
+ item.Update();
+ }
+
+ ValidStatus = IsViewValid ? (Items.Any(i => i.ValidStatus == "N") ? "N" : (Items.Any(i => i.ValidStatus == "W") ? "W" : "Y")) : "N";
+ }
}
}
diff --git a/src/ARKServerManager/Lib/Server.cs b/src/ARKServerManager/Lib/Server.cs
index bb934d88..06a7fcf9 100644
--- a/src/ARKServerManager/Lib/Server.cs
+++ b/src/ARKServerManager/Lib/Server.cs
@@ -94,7 +94,7 @@ namespace ServerManagerTool.Lib
await this.Runtime.StopAsync();
}
- public async Task UpgradeAsync(CancellationToken cancellationToken, bool updateServer, ServerBranchSnapshot branch, bool validate, bool updateMods, ProgressDelegate progressCallback)
+ public async Task UpgradeAsync(CancellationToken cancellationToken, bool updateServer, BranchSnapshot branch, bool validate, bool updateMods, ProgressDelegate progressCallback)
{
await this.Runtime.AttachToProfile(this.Profile);
var success = await this.Runtime.UpgradeAsync(cancellationToken, updateServer, branch, validate, updateMods, progressCallback);
diff --git a/src/ARKServerManager/Lib/ServerApp.cs b/src/ARKServerManager/Lib/ServerApp.cs
index 718376d3..0f433ad8 100644
--- a/src/ARKServerManager/Lib/ServerApp.cs
+++ b/src/ARKServerManager/Lib/ServerApp.cs
@@ -2,6 +2,7 @@
using ServerManagerTool.Common.Lib;
using ServerManagerTool.Common.Model;
using ServerManagerTool.Common.Utils;
+using ServerManagerTool.Delegates;
using ServerManagerTool.Enums;
using ServerManagerTool.Plugin.Common;
using ServerManagerTool.Utils;
@@ -105,6 +106,7 @@ namespace ServerManagerTool.Lib
public int ShutdownInterval = Config.Default.ServerShutdown_GracePeriod;
public ProgressDelegate ProgressCallback = null;
public ProcessWindowStyle SteamCMDProcessWindowStyle = ProcessWindowStyle.Minimized;
+ public ServerStatusChangeDelegate ServerStatusChangeCallback = null;
public ServerApp(bool resetStartTime = false)
{
@@ -112,7 +114,7 @@ namespace ServerManagerTool.Lib
_startTime = DateTime.Now;
}
- private void BackupServer()
+ private void BackupServer(CancellationToken cancellationToken)
{
if (_profile == null || _profile.SotFEnabled)
{
@@ -140,65 +142,65 @@ namespace ServerManagerTool.Lib
if (_serverRunning)
{
- // check if RCON is enabled
- if (_profile.RCONEnabled)
+ try
{
- try
+ emailMessage.AppendLine();
+
+ var sent = false;
+
+ // perform a world save
+ if (!string.IsNullOrWhiteSpace(Config.Default.ServerBackup_WorldSaveMessage))
{
- try
+ ProcessAlert(AlertType.Backup, Config.Default.ServerBackup_WorldSaveMessage);
+ sent = SendMessageAsync(Config.Default.ServerBackup_WorldSaveMessage, cancellationToken).Result;
+ if (sent)
{
- emailMessage.AppendLine();
-
- var sent = false;
-
- // perform a world save
- if (!string.IsNullOrWhiteSpace(Config.Default.ServerBackup_WorldSaveMessage))
- {
- ProcessAlert(AlertType.Backup, Config.Default.ServerBackup_WorldSaveMessage);
- sent = SendMessageAsync(Config.Default.ServerBackup_WorldSaveMessage, CancellationToken.None).Result;
- if (sent)
- {
- emailMessage.AppendLine("sent server save message.");
- }
- }
-
- sent = SendCommandAsync(Config.Default.ServerSaveCommand, false).Result;
- if (sent)
- {
- emailMessage.AppendLine("sent server save command.");
- Task.Delay(Config.Default.ServerShutdown_WorldSaveDelay * 1000).Wait();
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine($"RCON> {Config.Default.ServerSaveCommand} command.\r\n{ex.Message}");
+ emailMessage.AppendLine("sent server save message.");
}
}
- finally
+
+ sent = SendCommandAsync(Config.Default.ServerSaveCommand, false).Result;
+ if (sent)
{
- CloseRconConsole();
+ emailMessage.AppendLine("sent server save command.");
+ Task.Delay(Config.Default.ServerShutdown_WorldSaveDelay * 1000).Wait();
}
}
- else
+ catch (Exception ex)
{
- LogProfileMessage("RCON not enabled.");
+ Debug.WriteLine($"RCON> {Config.Default.ServerSaveCommand} command.\r\n{ex.Message}");
}
}
if (ExitCode != EXITCODE_NORMALEXIT)
return;
+ if (cancellationToken.IsCancellationRequested)
+ {
+ ExitCode = EXITCODE_CANCELLED;
+ return;
+ }
// make a backup of the current profile and config files.
CreateProfileBackupArchiveFile(_profile);
if (ExitCode != EXITCODE_NORMALEXIT)
return;
+ if (cancellationToken.IsCancellationRequested)
+ {
+ ExitCode = EXITCODE_CANCELLED;
+ return;
+ }
// make a backup of the current world file.
CreateServerBackupArchiveFile(emailMessage, _profile);
if (ExitCode != EXITCODE_NORMALEXIT)
return;
+ if (cancellationToken.IsCancellationRequested)
+ {
+ ExitCode = EXITCODE_CANCELLED;
+ return;
+ }
if (Config.Default.EmailNotify_AutoBackup)
{
@@ -264,7 +266,15 @@ namespace ServerManagerTool.Lib
if (updateServer)
{
- UpgradeLocal(true, cancellationToken, true);
+ try
+ {
+ ServerStatusChangeCallback?.Invoke(ServerStatus.Updating);
+ UpgradeLocal(true, true, cancellationToken);
+ }
+ finally
+ {
+ ServerStatusChangeCallback?.Invoke(ServerStatus.Stopped);
+ }
}
if (ExitCode != EXITCODE_NORMALEXIT)
@@ -300,17 +310,20 @@ namespace ServerManagerTool.Lib
return;
}
- // check if the server was previously running before the update.
- if (!_serverRunning && !_profile.AutoRestartIfShutdown)
+ // check if the server was previously running.
+ if (!_serverRunning)
{
- LogProfileMessage("Server was not running, server will not be started.");
+ if (_profile.AutoRestartIfShutdown)
+ {
+ LogProfileMessage("Server was not running, server will be started as the setting to restart if shutdown is TRUE.");
+ }
+ else
+ {
+ LogProfileMessage("Server was not running, server will not be started.");
- ExitCode = EXITCODE_NORMALEXIT;
- return;
- }
- if (!_serverRunning && _profile.AutoRestartIfShutdown)
- {
- LogProfileMessage("Server was not running, server will be started as the setting to restart if shutdown is TRUE.");
+ ExitCode = EXITCODE_NORMALEXIT;
+ return;
+ }
}
// Find the server process.
@@ -394,7 +407,7 @@ namespace ServerManagerTool.Lib
try
{
// create a connection to the server
- var endPoint = new IPEndPoint(IPAddress.Parse(_profile.ServerIP), _profile.QueryPort);
+ var endPoint = new IPEndPoint(_profile.ServerIPAddress, _profile.QueryPort);
gameServer = QueryMaster.ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endPoint);
// check if there is a shutdown reason
@@ -407,10 +420,6 @@ namespace ServerManagerTool.Lib
}
LogProfileMessage("Starting shutdown timer...");
- if (!CheckForOnlinePlayers)
- {
- LogProfileMessage("CheckForOnlinePlayers disabled, shutdown timer will not perform online player check.");
- }
var minutesLeft = ShutdownInterval;
while (minutesLeft > 0)
@@ -422,7 +431,7 @@ namespace ServerManagerTool.Lib
if (!string.IsNullOrWhiteSpace(Config.Default.ServerShutdown_CancelMessage))
{
ProcessAlert(AlertType.Shutdown, Config.Default.ServerShutdown_CancelMessage);
- SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, CancellationToken.None).Wait();
+ SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, cancellationToken).Wait();
}
ExitCode = EXITCODE_CANCELLED;
@@ -452,7 +461,8 @@ namespace ServerManagerTool.Lib
}
else
{
- Debug.WriteLine($"CheckForOnlinePlayers disabled");
+ Debug.WriteLine($"CheckForOnlinePlayers disabled, shutdown timer cancelled.");
+ break;
}
var message = string.Empty;
@@ -526,7 +536,7 @@ namespace ServerManagerTool.Lib
{
LogProfileMessage(Config.Default.ServerShutdown_WorldSaveMessage);
ProcessAlert(AlertType.ShutdownMessage, Config.Default.ServerShutdown_WorldSaveMessage);
- SendMessageAsync(Config.Default.ServerShutdown_WorldSaveMessage, cancellationToken).Wait();
+ SendMessageAsync(Config.Default.ServerShutdown_WorldSaveMessage, cancellationToken).Wait(cancellationToken);
}
if (SendCommandAsync(Config.Default.ServerSaveCommand, false).Result)
@@ -551,7 +561,7 @@ namespace ServerManagerTool.Lib
if (!string.IsNullOrWhiteSpace(Config.Default.ServerShutdown_CancelMessage))
{
ProcessAlert(AlertType.Shutdown, Config.Default.ServerShutdown_CancelMessage);
- SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, CancellationToken.None).Wait();
+ SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, cancellationToken).Wait();
}
ExitCode = EXITCODE_CANCELLED;
@@ -577,8 +587,6 @@ namespace ServerManagerTool.Lib
}
finally
{
- CloseRconConsole();
-
gameServer?.Dispose();
gameServer = null;
}
@@ -590,11 +598,9 @@ namespace ServerManagerTool.Lib
if (!string.IsNullOrWhiteSpace(Config.Default.ServerShutdown_CancelMessage))
{
ProcessAlert(AlertType.Shutdown, Config.Default.ServerShutdown_CancelMessage);
- SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, CancellationToken.None).Wait();
+ SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, cancellationToken).Wait();
}
- CloseRconConsole();
-
ExitCode = EXITCODE_CANCELLED;
return;
}
@@ -643,8 +649,6 @@ namespace ServerManagerTool.Lib
LogProfileMessage("Exiting server timed out, attempting to close the server.");
}
- CloseRconConsole();
-
// Method 2 - Close the process
sent = process.CloseMainWindow();
@@ -711,7 +715,7 @@ namespace ServerManagerTool.Lib
ExitCode = EXITCODE_SHUTDOWN_TIMEOUT;
}
- private void UpgradeLocal(bool validate, CancellationToken cancellationToken, bool updateMods)
+ private void UpgradeLocal(bool validate, bool updateMods, CancellationToken cancellationToken)
{
if (_profile == null)
{
@@ -1240,7 +1244,7 @@ namespace ServerManagerTool.Lib
{
// perform a steamcmd validate to confirm all the files
LogProfileMessage("Validating server files (*new*).");
- UpgradeLocal(true, CancellationToken.None, false);
+ UpgradeLocal(true, false, CancellationToken.None);
LogProfileMessage("Validated server files (*new*).");
}
@@ -1766,17 +1770,6 @@ namespace ServerManagerTool.Lib
ExitCode = EXITCODE_NORMALEXIT;
}
- private void CloseRconConsole()
- {
- if (_rconConsole != null)
- {
- _rconConsole.Dispose();
- _rconConsole = null;
-
- Task.Delay(1000).Wait();
- }
- }
-
public void CheckServerWorldFileExists(ServerProfileSnapshot profile = null)
{
// do nothing if profile is null or SotF
@@ -2568,39 +2561,42 @@ namespace ServerManagerTool.Lib
int rconRetries = 0;
int maxRetries = retryIfFailed ? RCON_MAXRETRIES : 1;
- while (retries < maxRetries && rconRetries < RCON_MAXRETRIES)
+ try
{
- SetupRconConsole();
-
- if (_rconConsole == null)
+ while (retries < maxRetries && rconRetries < RCON_MAXRETRIES)
{
- LogProfileMessage($"RCON> {command} - attempt {rconRetries + 1} (a).", false);
-#if DEBUG
- LogProfileMessage("RCON connection not created.", false);
-#endif
- rconRetries++;
- }
- else
- {
- rconRetries = 0;
- try
- {
- _rconConsole.SendCommand(command);
- LogProfileMessage($"RCON> {command}");
+ SetupRconConsole();
- return true;
- }
- catch (Exception ex)
+ if (_rconConsole == null)
{
- LogProfileMessage($"RCON> {command} - attempt {retries + 1} (b).", false);
-#if DEBUG
- LogProfileMessage($"{ex.Message}", false);
-#endif
+ LogProfileMessage($"RCON> {command} - attempt {rconRetries + 1} (a).", false);
+ LogProfileMessage("RCON connection not created.", false);
+ rconRetries++;
}
+ else
+ {
+ rconRetries = 0;
+ try
+ {
+ _rconConsole.SendCommand(command);
+ LogProfileMessage($"RCON> {command}");
- retries++;
+ return true;
+ }
+ catch (Exception ex)
+ {
+ LogProfileMessage($"RCON> {command} - attempt {retries + 1} (b).", false);
+ LogProfileMessage($"{ex.Message}", false);
+ }
+
+ retries++;
+ }
}
}
+ finally
+ {
+ CloseRconConsole();
+ }
return false;
}
@@ -2662,6 +2658,17 @@ namespace ServerManagerTool.Lib
}
}
+ private void CloseRconConsole()
+ {
+ if (_rconConsole != null)
+ {
+ _rconConsole.Dispose();
+ _rconConsole = null;
+
+ Task.Delay(1000).Wait();
+ }
+ }
+
private void SetupRconConsole()
{
CloseRconConsole();
@@ -2671,7 +2678,7 @@ namespace ServerManagerTool.Lib
try
{
- var endPoint = new IPEndPoint(IPAddress.Parse(_profile.ServerIP), _profile.RCONPort);
+ var endPoint = new IPEndPoint(_profile.ServerIPAddress, _profile.RCONPort);
var server = QueryMaster.ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endPoint, sendTimeOut: 10000, receiveTimeOut: 10000);
if (server == null)
{
@@ -2708,7 +2715,7 @@ namespace ServerManagerTool.Lib
}
}
- public int PerformProfileBackup(ServerProfileSnapshot profile)
+ public int PerformProfileBackup(ServerProfileSnapshot profile, CancellationToken cancellationToken)
{
_profile = profile;
@@ -2733,7 +2740,7 @@ namespace ServerManagerTool.Lib
// check if the mutex was established
if (createdNew)
{
- BackupServer();
+ BackupServer(cancellationToken);
if (ExitCode != EXITCODE_NORMALEXIT)
{
@@ -2869,7 +2876,7 @@ namespace ServerManagerTool.Lib
return ExitCode;
}
- public int PerformProfileUpdate(ServerBranchSnapshot branch, ServerProfileSnapshot profile)
+ public int PerformProfileUpdate(BranchSnapshot branch, ServerProfileSnapshot profile)
{
_profile = profile;
@@ -2945,7 +2952,7 @@ namespace ServerManagerTool.Lib
return ExitCode;
}
- public int PerformServerBranchUpdate(ServerBranchSnapshot branch)
+ public int PerformServerBranchUpdate(BranchSnapshot branch)
{
if (branch == null)
return EXITCODE_NORMALEXIT;
@@ -3089,7 +3096,7 @@ namespace ServerManagerTool.Lib
SendEmails = true,
ServerProcess = ServerProcessType.AutoBackup
};
- exitCodes.TryAdd(profile, app.PerformProfileBackup(profile));
+ exitCodes.TryAdd(profile, app.PerformProfileBackup(profile, CancellationToken.None));
});
foreach (var profile in _profiles.Keys)
@@ -3233,8 +3240,8 @@ namespace ServerManagerTool.Lib
if (exitCode == EXITCODE_NORMALEXIT)
{
- var branches = _profiles.Keys.Where(p => p.EnableAutoUpdate).Select(p => new ServerBranchSnapshot() { BranchName = p.BranchName, BranchPassword = p.BranchPassword}).Distinct(new ServerBranchSnapshotComparer()).ToArray();
- var exitCodes = new ConcurrentDictionary();
+ var branches = _profiles.Keys.Where(p => p.EnableAutoUpdate).Select(p => BranchSnapshot.Create(p)).Distinct(new BranchSnapshotComparer()).ToArray();
+ var exitCodes = new ConcurrentDictionary();
// update the server cache for each branch
if (Config.Default.AutoUpdate_ParallelUpdate)
diff --git a/src/ARKServerManager/Lib/ServerProfile.cs b/src/ARKServerManager/Lib/ServerProfile.cs
index 8d76d116..d8dbc0c3 100644
--- a/src/ARKServerManager/Lib/ServerProfile.cs
+++ b/src/ARKServerManager/Lib/ServerProfile.cs
@@ -78,12 +78,14 @@ namespace ServerManagerTool.Lib
this.DinoLevels = new LevelList();
this.PlayerLevels = new LevelList();
- this.PlayerBaseStatMultipliers = new StatsMultiplierArray(nameof(PlayerBaseStatMultipliers), GameData.GetBaseStatMultipliers_Player, GameData.GetStatMultiplierInclusions_PlayerBase(), true);
- this.PerLevelStatsMultiplier_Player = new StatsMultiplierArray(nameof(PerLevelStatsMultiplier_Player), GameData.GetPerLevelStatsMultipliers_Player, GameData.GetStatMultiplierInclusions_PlayerPerLevel(), true);
- this.PerLevelStatsMultiplier_DinoWild = new StatsMultiplierArray(nameof(PerLevelStatsMultiplier_DinoWild), GameData.GetPerLevelStatsMultipliers_DinoWild, GameData.GetStatMultiplierInclusions_DinoWildPerLevel(), true);
- this.PerLevelStatsMultiplier_DinoTamed = new StatsMultiplierArray(nameof(PerLevelStatsMultiplier_DinoTamed), GameData.GetPerLevelStatsMultipliers_DinoTamed, GameData.GetStatMultiplierInclusions_DinoTamedPerLevel(), true);
- this.PerLevelStatsMultiplier_DinoTamed_Add = new StatsMultiplierArray(nameof(PerLevelStatsMultiplier_DinoTamed_Add), GameData.GetPerLevelStatsMultipliers_DinoTamedAdd, GameData.GetStatMultiplierInclusions_DinoTamedAdd(), true);
- this.PerLevelStatsMultiplier_DinoTamed_Affinity = new StatsMultiplierArray(nameof(PerLevelStatsMultiplier_DinoTamed_Affinity), GameData.GetPerLevelStatsMultipliers_DinoTamedAffinity, GameData.GetStatMultiplierInclusions_DinoTamedAffinity(), true);
+ this.PlayerBaseStatMultipliers = new StatsMultiplierFloatArray(nameof(PlayerBaseStatMultipliers), GameData.GetBaseStatMultipliers_Player, GameData.GetStatMultiplierInclusions_PlayerBase(), true);
+ this.PerLevelStatsMultiplier_Player = new StatsMultiplierFloatArray(nameof(PerLevelStatsMultiplier_Player), GameData.GetPerLevelStatsMultipliers_Player, GameData.GetStatMultiplierInclusions_PlayerPerLevel(), true);
+ this.PerLevelStatsMultiplier_DinoWild = new StatsMultiplierFloatArray(nameof(PerLevelStatsMultiplier_DinoWild), GameData.GetPerLevelStatsMultipliers_DinoWild, GameData.GetStatMultiplierInclusions_DinoWildPerLevel(), true);
+ this.PerLevelStatsMultiplier_DinoTamed = new StatsMultiplierFloatArray(nameof(PerLevelStatsMultiplier_DinoTamed), GameData.GetPerLevelStatsMultipliers_DinoTamed, GameData.GetStatMultiplierInclusions_DinoTamedPerLevel(), true);
+ this.PerLevelStatsMultiplier_DinoTamed_Add = new StatsMultiplierFloatArray(nameof(PerLevelStatsMultiplier_DinoTamed_Add), GameData.GetPerLevelStatsMultipliers_DinoTamedAdd, GameData.GetStatMultiplierInclusions_DinoTamedAdd(), true);
+ this.PerLevelStatsMultiplier_DinoTamed_Affinity = new StatsMultiplierFloatArray(nameof(PerLevelStatsMultiplier_DinoTamed_Affinity), GameData.GetPerLevelStatsMultipliers_DinoTamedAffinity, GameData.GetStatMultiplierInclusions_DinoTamedAffinity(), true);
+ this.MutagenLevelBoost = new StatsMultiplierIntegerArray(nameof(MutagenLevelBoost), GameData.GetPerLevelMutagenLevelBoost_DinoWild, GameData.GetMutagenLevelBoostInclusions_DinoWild(), true);
+ this.MutagenLevelBoostBred = new StatsMultiplierIntegerArray(nameof(MutagenLevelBoostBred), GameData.GetPerLevelMutagenLevelBoost_DinoTamed, GameData.GetMutagenLevelBoostInclusions_DinoTamed(), true);
this.HarvestResourceItemAmountClassMultipliers = new ResourceClassMultiplierList(nameof(HarvestResourceItemAmountClassMultipliers), GameData.GetResourceMultipliers);
@@ -957,6 +959,64 @@ namespace ServerManagerTool.Lib
}
#endregion
+ #region Discord Bot
+ public static readonly DependencyProperty DiscordChannelIdProperty = DependencyProperty.Register(nameof(DiscordChannelId), typeof(string), typeof(ServerProfile), new PropertyMetadata(String.Empty));
+ [DataMember]
+ public string DiscordChannelId
+ {
+ get { return (string)GetValue(DiscordChannelIdProperty); }
+ set { SetValue(DiscordChannelIdProperty, value); }
+ }
+
+ public static readonly DependencyProperty AllowDiscordBackupProperty = DependencyProperty.Register(nameof(AllowDiscordBackup), typeof(bool), typeof(ServerProfile), new PropertyMetadata(true));
+ [DataMember]
+ public bool AllowDiscordBackup
+ {
+ get { return (bool)GetValue(AllowDiscordBackupProperty); }
+ set { SetValue(AllowDiscordBackupProperty, value); }
+ }
+
+ public static readonly DependencyProperty AllowDiscordRestartProperty = DependencyProperty.Register(nameof(AllowDiscordRestart), typeof(bool), typeof(ServerProfile), new PropertyMetadata(true));
+ [DataMember]
+ public bool AllowDiscordRestart
+ {
+ get { return (bool)GetValue(AllowDiscordRestartProperty); }
+ set { SetValue(AllowDiscordRestartProperty, value); }
+ }
+
+ public static readonly DependencyProperty AllowDiscordShutdownProperty = DependencyProperty.Register(nameof(AllowDiscordShutdown), typeof(bool), typeof(ServerProfile), new PropertyMetadata(true));
+ [DataMember]
+ public bool AllowDiscordShutdown
+ {
+ get { return (bool)GetValue(AllowDiscordShutdownProperty); }
+ set { SetValue(AllowDiscordShutdownProperty, value); }
+ }
+
+ public static readonly DependencyProperty AllowDiscordStartProperty = DependencyProperty.Register(nameof(AllowDiscordStart), typeof(bool), typeof(ServerProfile), new PropertyMetadata(true));
+ [DataMember]
+ public bool AllowDiscordStart
+ {
+ get { return (bool)GetValue(AllowDiscordStartProperty); }
+ set { SetValue(AllowDiscordStartProperty, value); }
+ }
+
+ public static readonly DependencyProperty AllowDiscordStopProperty = DependencyProperty.Register(nameof(AllowDiscordStop), typeof(bool), typeof(ServerProfile), new PropertyMetadata(true));
+ [DataMember]
+ public bool AllowDiscordStop
+ {
+ get { return (bool)GetValue(AllowDiscordStopProperty); }
+ set { SetValue(AllowDiscordStopProperty, value); }
+ }
+
+ public static readonly DependencyProperty AllowDiscordUpdateProperty = DependencyProperty.Register(nameof(AllowDiscordUpdate), typeof(bool), typeof(ServerProfile), new PropertyMetadata(true));
+ [DataMember]
+ public bool AllowDiscordUpdate
+ {
+ get { return (bool)GetValue(AllowDiscordUpdateProperty); }
+ set { SetValue(AllowDiscordUpdateProperty, value); }
+ }
+ #endregion
+
#region Rules
public static readonly DependencyProperty EnableHardcoreProperty = DependencyProperty.Register(nameof(EnableHardcore), typeof(bool), typeof(ServerProfile), new PropertyMetadata(false));
[IniFileEntry(IniFiles.GameUserSettings, IniSections.GUS_ServerSettings, ServerProfileCategory.Rules, "ServerHardcore")]
@@ -974,6 +1034,14 @@ namespace ServerManagerTool.Lib
set { SetValue(EnablePVPProperty, value); }
}
+ public static readonly DependencyProperty EnableCreativeModeProperty = DependencyProperty.Register(nameof(EnableCreativeMode), typeof(bool), typeof(ServerProfile), new PropertyMetadata(false));
+ [IniFileEntry(IniFiles.Game, IniSections.Game_ShooterGameMode, ServerProfileCategory.Rules, "bShowCreativeMode", WriteIfNotValue = false)]
+ public bool EnableCreativeMode
+ {
+ get { return (bool)GetValue(EnableCreativeModeProperty); }
+ set { SetValue(EnableCreativeModeProperty, value); }
+ }
+
public static readonly DependencyProperty AllowCaveBuildingPvEProperty = DependencyProperty.Register(nameof(AllowCaveBuildingPvE), typeof(bool), typeof(ServerProfile), new PropertyMetadata(false));
[IniFileEntry(IniFiles.GameUserSettings, IniSections.GUS_ServerSettings, ServerProfileCategory.Rules)]
public bool AllowCaveBuildingPvE
@@ -1045,6 +1113,15 @@ namespace ServerManagerTool.Lib
set { SetValue(DifficultyOffsetProperty, value); }
}
+ public static readonly DependencyProperty DestroyTamesOverLevelClampProperty = DependencyProperty.Register(nameof(DestroyTamesOverLevelClamp), typeof(int), typeof(ServerProfile), new PropertyMetadata(0));
+ [IniFileEntry(IniFiles.Game, IniSections.Game_ShooterGameMode, ServerProfileCategory.Rules, WriteIfNotValue = 0)]
+ public int DestroyTamesOverLevelClamp
+ {
+ get { return (int)GetValue(DestroyTamesOverLevelClampProperty); }
+ set { SetValue(DestroyTamesOverLevelClampProperty, value); }
+ }
+
+
public static readonly DependencyProperty EnableTributeDownloadsProperty = DependencyProperty.Register(nameof(EnableTributeDownloads), typeof(bool), typeof(ServerProfile), new PropertyMetadata(false));
[IniFileEntry(IniFiles.GameUserSettings, IniSections.GUS_ServerSettings, ServerProfileCategory.Rules, "NoTributeDownloads", InvertBoolean = true)]
public bool EnableTributeDownloads
@@ -1971,19 +2048,19 @@ namespace ServerManagerTool.Lib
- public static readonly DependencyProperty PlayerBaseStatMultipliersProperty = DependencyProperty.Register(nameof(PlayerBaseStatMultipliers), typeof(StatsMultiplierArray), typeof(ServerProfile), new PropertyMetadata(null));
+ public static readonly DependencyProperty PlayerBaseStatMultipliersProperty = DependencyProperty.Register(nameof(PlayerBaseStatMultipliers), typeof(StatsMultiplierFloatArray), typeof(ServerProfile), new PropertyMetadata(null));
[IniFileEntry(IniFiles.Game, IniSections.Game_ShooterGameMode, ServerProfileCategory.Players)]
- public StatsMultiplierArray PlayerBaseStatMultipliers
+ public StatsMultiplierFloatArray PlayerBaseStatMultipliers
{
- get { return (StatsMultiplierArray)GetValue(PlayerBaseStatMultipliersProperty); }
+ get { return (StatsMultiplierFloatArray)GetValue(PlayerBaseStatMultipliersProperty); }
set { SetValue(PlayerBaseStatMultipliersProperty, value); }
}
- public static readonly DependencyProperty PerLevelStatsMultiplier_PlayerProperty = DependencyProperty.Register(nameof(PerLevelStatsMultiplier_Player), typeof(StatsMultiplierArray), typeof(ServerProfile), new PropertyMetadata(null));
+ public static readonly DependencyProperty PerLevelStatsMultiplier_PlayerProperty = DependencyProperty.Register(nameof(PerLevelStatsMultiplier_Player), typeof(StatsMultiplierFloatArray), typeof(ServerProfile), new PropertyMetadata(null));
[IniFileEntry(IniFiles.Game, IniSections.Game_ShooterGameMode, ServerProfileCategory.Players)]
- public StatsMultiplierArray PerLevelStatsMultiplier_Player
+ public StatsMultiplierFloatArray PerLevelStatsMultiplier_Player
{
- get { return (StatsMultiplierArray)GetValue(PerLevelStatsMultiplier_PlayerProperty); }
+ get { return (StatsMultiplierFloatArray)GetValue(PerLevelStatsMultiplier_PlayerProperty); }
set { SetValue(PerLevelStatsMultiplier_PlayerProperty, value); }
}
#endregion
@@ -2356,38 +2433,54 @@ namespace ServerManagerTool.Lib
set { SetValue(PassiveTameIntervalMultiplierProperty, value); }
}
- public static readonly DependencyProperty PerLevelStatsMultiplier_DinoWildProperty = DependencyProperty.Register(nameof(PerLevelStatsMultiplier_DinoWild), typeof(StatsMultiplierArray), typeof(ServerProfile), new PropertyMetadata(null));
+ public static readonly DependencyProperty PerLevelStatsMultiplier_DinoWildProperty = DependencyProperty.Register(nameof(PerLevelStatsMultiplier_DinoWild), typeof(StatsMultiplierFloatArray), typeof(ServerProfile), new PropertyMetadata(null));
[IniFileEntry(IniFiles.Game, IniSections.Game_ShooterGameMode, ServerProfileCategory.Dinos)]
- public StatsMultiplierArray PerLevelStatsMultiplier_DinoWild
+ public StatsMultiplierFloatArray PerLevelStatsMultiplier_DinoWild
{
- get { return (StatsMultiplierArray)GetValue(PerLevelStatsMultiplier_DinoWildProperty); }
+ get { return (StatsMultiplierFloatArray)GetValue(PerLevelStatsMultiplier_DinoWildProperty); }
set { SetValue(PerLevelStatsMultiplier_DinoWildProperty, value); }
}
- public static readonly DependencyProperty PerLevelStatsMultiplier_DinoTamedProperty = DependencyProperty.Register(nameof(PerLevelStatsMultiplier_DinoTamed), typeof(StatsMultiplierArray), typeof(ServerProfile), new PropertyMetadata(null));
+ public static readonly DependencyProperty PerLevelStatsMultiplier_DinoTamedProperty = DependencyProperty.Register(nameof(PerLevelStatsMultiplier_DinoTamed), typeof(StatsMultiplierFloatArray), typeof(ServerProfile), new PropertyMetadata(null));
[IniFileEntry(IniFiles.Game, IniSections.Game_ShooterGameMode, ServerProfileCategory.Dinos)]
- public StatsMultiplierArray PerLevelStatsMultiplier_DinoTamed
+ public StatsMultiplierFloatArray PerLevelStatsMultiplier_DinoTamed
{
- get { return (StatsMultiplierArray)GetValue(PerLevelStatsMultiplier_DinoTamedProperty); }
+ get { return (StatsMultiplierFloatArray)GetValue(PerLevelStatsMultiplier_DinoTamedProperty); }
set { SetValue(PerLevelStatsMultiplier_DinoTamedProperty, value); }
}
- public static readonly DependencyProperty PerLevelStatsMultiplier_DinoTamed_AddProperty = DependencyProperty.Register(nameof(PerLevelStatsMultiplier_DinoTamed_Add), typeof(StatsMultiplierArray), typeof(ServerProfile), new PropertyMetadata(null));
+ public static readonly DependencyProperty PerLevelStatsMultiplier_DinoTamed_AddProperty = DependencyProperty.Register(nameof(PerLevelStatsMultiplier_DinoTamed_Add), typeof(StatsMultiplierFloatArray), typeof(ServerProfile), new PropertyMetadata(null));
[IniFileEntry(IniFiles.Game, IniSections.Game_ShooterGameMode, ServerProfileCategory.Dinos)]
- public StatsMultiplierArray PerLevelStatsMultiplier_DinoTamed_Add
+ public StatsMultiplierFloatArray PerLevelStatsMultiplier_DinoTamed_Add
{
- get { return (StatsMultiplierArray)GetValue(PerLevelStatsMultiplier_DinoTamed_AddProperty); }
+ get { return (StatsMultiplierFloatArray)GetValue(PerLevelStatsMultiplier_DinoTamed_AddProperty); }
set { SetValue(PerLevelStatsMultiplier_DinoTamed_AddProperty, value); }
}
- public static readonly DependencyProperty PerLevelStatsMultiplier_DinoTamed_AffinityProperty = DependencyProperty.Register(nameof(PerLevelStatsMultiplier_DinoTamed_Affinity), typeof(StatsMultiplierArray), typeof(ServerProfile), new PropertyMetadata(null));
+ public static readonly DependencyProperty PerLevelStatsMultiplier_DinoTamed_AffinityProperty = DependencyProperty.Register(nameof(PerLevelStatsMultiplier_DinoTamed_Affinity), typeof(StatsMultiplierFloatArray), typeof(ServerProfile), new PropertyMetadata(null));
[IniFileEntry(IniFiles.Game, IniSections.Game_ShooterGameMode, ServerProfileCategory.Dinos)]
- public StatsMultiplierArray PerLevelStatsMultiplier_DinoTamed_Affinity
+ public StatsMultiplierFloatArray PerLevelStatsMultiplier_DinoTamed_Affinity
{
- get { return (StatsMultiplierArray)GetValue(PerLevelStatsMultiplier_DinoTamed_AffinityProperty); }
+ get { return (StatsMultiplierFloatArray)GetValue(PerLevelStatsMultiplier_DinoTamed_AffinityProperty); }
set { SetValue(PerLevelStatsMultiplier_DinoTamed_AffinityProperty, value); }
}
+ public static readonly DependencyProperty MutagenLevelBoostProperty = DependencyProperty.Register(nameof(MutagenLevelBoost), typeof(StatsMultiplierIntegerArray), typeof(ServerProfile), new PropertyMetadata(null));
+ [IniFileEntry(IniFiles.Game, IniSections.Game_ShooterGameMode, ServerProfileCategory.Dinos)]
+ public StatsMultiplierIntegerArray MutagenLevelBoost
+ {
+ get { return (StatsMultiplierIntegerArray)GetValue(MutagenLevelBoostProperty); }
+ set { SetValue(MutagenLevelBoostProperty, value); }
+ }
+
+ public static readonly DependencyProperty MutagenLevelBoostBredProperty = DependencyProperty.Register(nameof(MutagenLevelBoostBred), typeof(StatsMultiplierIntegerArray), typeof(ServerProfile), new PropertyMetadata(null));
+ [IniFileEntry(IniFiles.Game, IniSections.Game_ShooterGameMode, ServerProfileCategory.Dinos)]
+ public StatsMultiplierIntegerArray MutagenLevelBoostBred
+ {
+ get { return (StatsMultiplierIntegerArray)GetValue(MutagenLevelBoostBredProperty); }
+ set { SetValue(MutagenLevelBoostBredProperty, value); }
+ }
+
public static readonly DependencyProperty DinoSpawnsProperty = DependencyProperty.Register(nameof(DinoSpawnWeightMultipliers), typeof(AggregateIniValueList), typeof(ServerProfile), new PropertyMetadata(null));
[IniFileEntry(IniFiles.Game, IniSections.Game_ShooterGameMode, ServerProfileCategory.Dinos)]
public AggregateIniValueList DinoSpawnWeightMultipliers
@@ -2727,12 +2820,12 @@ namespace ServerManagerTool.Lib
set { SetValue(PvPZoneStructureDamageMultiplierProperty, value); }
}
- public static readonly DependencyProperty MaxStructuresVisibleProperty = DependencyProperty.Register(nameof(MaxStructuresVisible), typeof(float), typeof(ServerProfile), new PropertyMetadata(10500f));
+ public static readonly DependencyProperty MaxStructuresInRangeProperty = DependencyProperty.Register(nameof(MaxStructuresInRange), typeof(int), typeof(ServerProfile), new PropertyMetadata(10500));
[IniFileEntry(IniFiles.GameUserSettings, IniSections.GUS_ServerSettings, ServerProfileCategory.Structures, "TheMaxStructuresInRange")]
- public float MaxStructuresVisible
+ public int MaxStructuresInRange
{
- get { return (float)GetValue(MaxStructuresVisibleProperty); }
- set { SetValue(MaxStructuresVisibleProperty, value); }
+ get { return (int)GetValue(MaxStructuresInRangeProperty); }
+ set { SetValue(MaxStructuresInRangeProperty, value); }
}
public static readonly DependencyProperty PerPlatformMaxStructuresMultiplierProperty = DependencyProperty.Register(nameof(PerPlatformMaxStructuresMultiplier), typeof(float), typeof(ServerProfile), new PropertyMetadata(1.0f));
@@ -3464,6 +3557,8 @@ namespace ServerManagerTool.Lib
settings.PerLevelStatsMultiplier_DinoTamed_Add.Reset();
settings.PerLevelStatsMultiplier_DinoTamed_Affinity.Reset();
settings.PerLevelStatsMultiplier_DinoWild.Reset();
+ settings.MutagenLevelBoost.Reset();
+ settings.MutagenLevelBoostBred.Reset();
settings.PerLevelStatsMultiplier_Player.Reset();
settings.PlayerBaseStatMultipliers.Reset();
settings.LoadServerFileAdministrators();
@@ -5233,10 +5328,12 @@ namespace ServerManagerTool.Lib
this.ClearValue(TamedDinoTorporDrainMultiplierProperty);
this.ClearValue(PassiveTameIntervalMultiplierProperty);
- this.PerLevelStatsMultiplier_DinoWild = new StatsMultiplierArray(nameof(PerLevelStatsMultiplier_DinoWild), GameData.GetPerLevelStatsMultipliers_DinoWild, GameData.GetStatMultiplierInclusions_DinoWildPerLevel(), true);
- this.PerLevelStatsMultiplier_DinoTamed = new StatsMultiplierArray(nameof(PerLevelStatsMultiplier_DinoTamed), GameData.GetPerLevelStatsMultipliers_DinoTamed, GameData.GetStatMultiplierInclusions_DinoTamedPerLevel(), true);
- this.PerLevelStatsMultiplier_DinoTamed_Add = new StatsMultiplierArray(nameof(PerLevelStatsMultiplier_DinoTamed_Add), GameData.GetPerLevelStatsMultipliers_DinoTamedAdd, GameData.GetStatMultiplierInclusions_DinoTamedAdd(), true);
- this.PerLevelStatsMultiplier_DinoTamed_Affinity = new StatsMultiplierArray(nameof(PerLevelStatsMultiplier_DinoTamed_Affinity), GameData.GetPerLevelStatsMultipliers_DinoTamedAffinity, GameData.GetStatMultiplierInclusions_DinoTamedAffinity(), true);
+ this.PerLevelStatsMultiplier_DinoWild = new StatsMultiplierFloatArray(nameof(PerLevelStatsMultiplier_DinoWild), GameData.GetPerLevelStatsMultipliers_DinoWild, GameData.GetStatMultiplierInclusions_DinoWildPerLevel(), true);
+ this.PerLevelStatsMultiplier_DinoTamed = new StatsMultiplierFloatArray(nameof(PerLevelStatsMultiplier_DinoTamed), GameData.GetPerLevelStatsMultipliers_DinoTamed, GameData.GetStatMultiplierInclusions_DinoTamedPerLevel(), true);
+ this.PerLevelStatsMultiplier_DinoTamed_Add = new StatsMultiplierFloatArray(nameof(PerLevelStatsMultiplier_DinoTamed_Add), GameData.GetPerLevelStatsMultipliers_DinoTamedAdd, GameData.GetStatMultiplierInclusions_DinoTamedAdd(), true);
+ this.PerLevelStatsMultiplier_DinoTamed_Affinity = new StatsMultiplierFloatArray(nameof(PerLevelStatsMultiplier_DinoTamed_Affinity), GameData.GetPerLevelStatsMultipliers_DinoTamedAffinity, GameData.GetStatMultiplierInclusions_DinoTamedAffinity(), true);
+ this.MutagenLevelBoost = new StatsMultiplierIntegerArray(nameof(MutagenLevelBoost), GameData.GetPerLevelMutagenLevelBoost_DinoWild, GameData.GetMutagenLevelBoostInclusions_DinoWild(), true);
+ this.MutagenLevelBoostBred = new StatsMultiplierIntegerArray(nameof(MutagenLevelBoostBred), GameData.GetPerLevelMutagenLevelBoost_DinoTamed, GameData.GetMutagenLevelBoostInclusions_DinoTamed(), true);
this.DinoSpawnWeightMultipliers = new AggregateIniValueList(nameof(DinoSpawnWeightMultipliers), GameData.GetDinoSpawns);
this.PreventDinoTameClassNames = new StringIniValueList(nameof(PreventDinoTameClassNames), () => new string[0]);
@@ -5349,8 +5446,8 @@ namespace ServerManagerTool.Lib
this.ClearValue(CraftingSkillBonusMultiplierProperty);
this.ClearValue(MaxFallSpeedMultiplierProperty);
- this.PlayerBaseStatMultipliers = new StatsMultiplierArray(nameof(PlayerBaseStatMultipliers), GameData.GetBaseStatMultipliers_Player, GameData.GetStatMultiplierInclusions_PlayerBase(), true);
- this.PerLevelStatsMultiplier_Player = new StatsMultiplierArray(nameof(PerLevelStatsMultiplier_Player), GameData.GetPerLevelStatsMultipliers_Player, GameData.GetStatMultiplierInclusions_PlayerPerLevel(), true);
+ this.PlayerBaseStatMultipliers = new StatsMultiplierFloatArray(nameof(PlayerBaseStatMultipliers), GameData.GetBaseStatMultipliers_Player, GameData.GetStatMultiplierInclusions_PlayerBase(), true);
+ this.PerLevelStatsMultiplier_Player = new StatsMultiplierFloatArray(nameof(PerLevelStatsMultiplier_Player), GameData.GetPerLevelStatsMultipliers_Player, GameData.GetStatMultiplierInclusions_PlayerPerLevel(), true);
}
public void ResetPreventTransferOverridesSection()
@@ -5363,6 +5460,7 @@ namespace ServerManagerTool.Lib
{
this.ClearValue(EnableHardcoreProperty);
this.ClearValue(EnablePVPProperty);
+ this.ClearValue(EnableCreativeModeProperty);
this.ClearValue(AllowCaveBuildingPvEProperty);
this.ClearValue(DisableFriendlyFirePvPProperty);
this.ClearValue(DisableFriendlyFirePvEProperty);
@@ -5373,6 +5471,7 @@ namespace ServerManagerTool.Lib
this.ClearValue(EnableDifficultyOverrideProperty);
this.ClearValue(OverrideOfficialDifficultyProperty);
this.ClearValue(DifficultyOffsetProperty);
+ this.ClearValue(DestroyTamesOverLevelClampProperty);
this.ClearValue(EnableTributeDownloadsProperty);
this.ClearValue(PreventDownloadSurvivorsProperty);
@@ -5512,7 +5611,7 @@ namespace ServerManagerTool.Lib
this.ClearValue(StructureDamageRepairCooldownProperty);
this.ClearValue(PvPStructureDecayProperty);
this.ClearValue(PvPZoneStructureDamageMultiplierProperty);
- this.ClearValue(MaxStructuresVisibleProperty);
+ this.ClearValue(MaxStructuresInRangeProperty);
this.ClearValue(PerPlatformMaxStructuresMultiplierProperty);
this.ClearValue(MaxPlatformSaddleStructureLimitProperty);
this.ClearValue(OverrideStructurePlatformPreventionProperty);
@@ -5857,22 +5956,30 @@ namespace ServerManagerTool.Lib
this.SetValue(TamedDinoTorporDrainMultiplierProperty, sourceProfile.TamedDinoTorporDrainMultiplier);
this.SetValue(PassiveTameIntervalMultiplierProperty, sourceProfile.PassiveTameIntervalMultiplier);
- this.PerLevelStatsMultiplier_DinoWild = new StatsMultiplierArray(nameof(PerLevelStatsMultiplier_DinoWild), GameData.GetPerLevelStatsMultipliers_DinoWild, GameData.GetStatMultiplierInclusions_DinoWildPerLevel(), true);
+ this.PerLevelStatsMultiplier_DinoWild = new StatsMultiplierFloatArray(nameof(PerLevelStatsMultiplier_DinoWild), GameData.GetPerLevelStatsMultipliers_DinoWild, GameData.GetStatMultiplierInclusions_DinoWildPerLevel(), true);
this.PerLevelStatsMultiplier_DinoWild.FromIniValues(sourceProfile.PerLevelStatsMultiplier_DinoWild.ToIniValues());
this.PerLevelStatsMultiplier_DinoWild.IsEnabled = sourceProfile.PerLevelStatsMultiplier_DinoWild.IsEnabled;
- this.PerLevelStatsMultiplier_DinoTamed = new StatsMultiplierArray(nameof(PerLevelStatsMultiplier_DinoTamed), GameData.GetPerLevelStatsMultipliers_DinoTamed, GameData.GetStatMultiplierInclusions_DinoTamedPerLevel(), true);
+ this.PerLevelStatsMultiplier_DinoTamed = new StatsMultiplierFloatArray(nameof(PerLevelStatsMultiplier_DinoTamed), GameData.GetPerLevelStatsMultipliers_DinoTamed, GameData.GetStatMultiplierInclusions_DinoTamedPerLevel(), true);
this.PerLevelStatsMultiplier_DinoTamed.FromIniValues(sourceProfile.PerLevelStatsMultiplier_DinoTamed.ToIniValues());
this.PerLevelStatsMultiplier_DinoTamed.IsEnabled = sourceProfile.PerLevelStatsMultiplier_DinoTamed.IsEnabled;
- this.PerLevelStatsMultiplier_DinoTamed_Add = new StatsMultiplierArray(nameof(PerLevelStatsMultiplier_DinoTamed_Add), GameData.GetPerLevelStatsMultipliers_DinoTamedAdd, GameData.GetStatMultiplierInclusions_DinoTamedAdd(), true);
+ this.PerLevelStatsMultiplier_DinoTamed_Add = new StatsMultiplierFloatArray(nameof(PerLevelStatsMultiplier_DinoTamed_Add), GameData.GetPerLevelStatsMultipliers_DinoTamedAdd, GameData.GetStatMultiplierInclusions_DinoTamedAdd(), true);
this.PerLevelStatsMultiplier_DinoTamed_Add.FromIniValues(sourceProfile.PerLevelStatsMultiplier_DinoTamed_Add.ToIniValues());
this.PerLevelStatsMultiplier_DinoTamed_Add.IsEnabled = sourceProfile.PerLevelStatsMultiplier_DinoTamed_Add.IsEnabled;
- this.PerLevelStatsMultiplier_DinoTamed_Affinity = new StatsMultiplierArray(nameof(PerLevelStatsMultiplier_DinoTamed_Affinity), GameData.GetPerLevelStatsMultipliers_DinoTamedAffinity, GameData.GetStatMultiplierInclusions_DinoTamedAffinity(), true);
+ this.PerLevelStatsMultiplier_DinoTamed_Affinity = new StatsMultiplierFloatArray(nameof(PerLevelStatsMultiplier_DinoTamed_Affinity), GameData.GetPerLevelStatsMultipliers_DinoTamedAffinity, GameData.GetStatMultiplierInclusions_DinoTamedAffinity(), true);
this.PerLevelStatsMultiplier_DinoTamed_Affinity.FromIniValues(sourceProfile.PerLevelStatsMultiplier_DinoTamed_Affinity.ToIniValues());
this.PerLevelStatsMultiplier_DinoTamed_Affinity.IsEnabled = sourceProfile.PerLevelStatsMultiplier_DinoTamed_Affinity.IsEnabled;
+ this.MutagenLevelBoost = new StatsMultiplierIntegerArray(nameof(MutagenLevelBoost), GameData.GetPerLevelMutagenLevelBoost_DinoWild, GameData.GetMutagenLevelBoostInclusions_DinoWild(), true);
+ this.MutagenLevelBoost.FromIniValues(sourceProfile.MutagenLevelBoost.ToIniValues());
+ this.MutagenLevelBoost.IsEnabled = sourceProfile.MutagenLevelBoost.IsEnabled;
+
+ this.MutagenLevelBoostBred = new StatsMultiplierIntegerArray(nameof(MutagenLevelBoostBred), GameData.GetPerLevelMutagenLevelBoost_DinoTamed, GameData.GetMutagenLevelBoostInclusions_DinoTamed(), true);
+ this.MutagenLevelBoostBred.FromIniValues(sourceProfile.MutagenLevelBoostBred.ToIniValues());
+ this.MutagenLevelBoostBred.IsEnabled = sourceProfile.MutagenLevelBoostBred.IsEnabled;
+
sourceProfile.DinoSettings.RenderToModel();
this.DinoSpawnWeightMultipliers.Clear();
@@ -6045,6 +6152,7 @@ namespace ServerManagerTool.Lib
{
this.SetValue(EnableHardcoreProperty, sourceProfile.EnableHardcore);
this.SetValue(EnablePVPProperty, sourceProfile.EnablePVP);
+ this.SetValue(EnableCreativeModeProperty, sourceProfile.EnableCreativeMode);
this.SetValue(AllowCaveBuildingPvEProperty, sourceProfile.AllowCaveBuildingPvE);
this.SetValue(DisableFriendlyFirePvPProperty, sourceProfile.DisableFriendlyFirePvP);
this.SetValue(DisableFriendlyFirePvEProperty, sourceProfile.DisableFriendlyFirePvE);
@@ -6055,6 +6163,7 @@ namespace ServerManagerTool.Lib
this.SetValue(EnableDifficultyOverrideProperty, sourceProfile.EnableDifficultyOverride);
this.SetValue(OverrideOfficialDifficultyProperty, sourceProfile.OverrideOfficialDifficulty);
this.SetValue(DifficultyOffsetProperty, sourceProfile.DifficultyOffset);
+ this.SetValue(DestroyTamesOverLevelClampProperty, sourceProfile.DestroyTamesOverLevelClamp);
this.SetValue(EnableTributeDownloadsProperty, sourceProfile.EnableTributeDownloads);
this.SetValue(PreventDownloadSurvivorsProperty, sourceProfile.PreventDownloadSurvivors);
@@ -6210,7 +6319,7 @@ namespace ServerManagerTool.Lib
this.SetValue(StructureDamageRepairCooldownProperty, sourceProfile.StructureDamageRepairCooldown);
this.SetValue(PvPStructureDecayProperty, sourceProfile.PvPStructureDecay);
this.SetValue(PvPZoneStructureDamageMultiplierProperty, sourceProfile.PvPZoneStructureDamageMultiplier);
- this.SetValue(MaxStructuresVisibleProperty, sourceProfile.MaxStructuresVisible);
+ this.SetValue(MaxStructuresInRangeProperty, sourceProfile.MaxStructuresInRange);
this.SetValue(PerPlatformMaxStructuresMultiplierProperty, sourceProfile.PerPlatformMaxStructuresMultiplier);
this.SetValue(MaxPlatformSaddleStructureLimitProperty, sourceProfile.MaxPlatformSaddleStructureLimit);
this.SetValue(OverrideStructurePlatformPreventionProperty, sourceProfile.OverrideStructurePlatformPrevention);
diff --git a/src/ARKServerManager/Lib/ServerProfileSnapshot.cs b/src/ARKServerManager/Lib/ServerProfileSnapshot.cs
index 940bf1e5..0d2238ec 100644
--- a/src/ARKServerManager/Lib/ServerProfileSnapshot.cs
+++ b/src/ARKServerManager/Lib/ServerProfileSnapshot.cs
@@ -7,6 +7,10 @@ namespace ServerManagerTool.Lib
{
public class ServerProfileSnapshot
{
+ private ServerProfileSnapshot()
+ {
+ }
+
public string ProfileId;
public string ProfileName;
public string InstallDirectory;
@@ -16,7 +20,7 @@ namespace ServerManagerTool.Lib
public string AdminPassword;
public string ServerName;
public string ServerArgs;
- public string ServerIP;
+ public IPAddress ServerIPAddress;
public int ServerPort;
public int ServerPeerPort;
public int QueryPort;
@@ -67,7 +71,7 @@ namespace ServerManagerTool.Lib
AdminPassword = profile.AdminPassword,
ServerName = profile.ServerName,
ServerArgs = profile.GetServerArgs(),
- ServerIP = string.IsNullOrWhiteSpace(profile.ServerIP) ? IPAddress.Loopback.ToString() : profile.ServerIP.Trim(),
+ ServerIPAddress = string.IsNullOrWhiteSpace(profile.ServerIP) ? IPAddress.Loopback : IPAddress.TryParse(profile.ServerIP.Trim(), out IPAddress ipAddress) ? ipAddress : IPAddress.Loopback,
ServerPort = profile.ServerPort,
ServerPeerPort = profile.ServerPeerPort,
QueryPort = profile.QueryPort,
diff --git a/src/ARKServerManager/Lib/ServerRuntime.cs b/src/ARKServerManager/Lib/ServerRuntime.cs
index 420cde9f..b1276696 100644
--- a/src/ARKServerManager/Lib/ServerRuntime.cs
+++ b/src/ARKServerManager/Lib/ServerRuntime.cs
@@ -33,7 +33,7 @@ namespace ServerManagerTool.Lib
public event EventHandler StatusUpdate;
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
- private readonly GlobalizedApplication _globalizer = GlobalizedApplication.Instance;
+ private static readonly GlobalizedApplication _globalizer = GlobalizedApplication.Instance;
private readonly List profileNotifiers = new List();
private Process serverProcess;
private IAsyncDisposable updateRegistration;
@@ -169,6 +169,9 @@ namespace ServerManagerTool.Lib
ServerProfile.ServerIPProperty,
ServerProfile.MaxPlayersProperty,
+ ServerProfile.ServerPasswordProperty,
+ ServerProfile.AdminPasswordProperty,
+
ServerProfile.ServerMapProperty,
ServerProfile.ServerModIdsProperty,
ServerProfile.TotalConversionModIdProperty,
@@ -177,7 +180,7 @@ namespace ServerManagerTool.Lib
},
(s, p) =>
{
- if (Status == ServerStatus.Stopped || Status == ServerStatus.Uninstalled || Status == ServerStatus.Unknown)
+ if (Status == ServerStatus.Stopped || Status == ServerStatus.Uninstalled || Status == ServerStatus.Unknown || Status == ServerStatus.Updating)
{
AttachToProfileCore(profile);
}
@@ -198,16 +201,7 @@ namespace ServerManagerTool.Lib
return;
}
- if (!String.IsNullOrWhiteSpace(this.ProfileSnapshot.ServerIP) && IPAddress.TryParse(this.ProfileSnapshot.ServerIP, out IPAddress localServerIpAddress))
- {
- // Use the explicit Server IP
- localServerQueryEndPoint = new IPEndPoint(localServerIpAddress, Convert.ToUInt16(this.ProfileSnapshot.QueryPort));
- }
- else
- {
- // No Server IP specified, use Loopback
- localServerQueryEndPoint = new IPEndPoint(IPAddress.Loopback, Convert.ToUInt16(this.ProfileSnapshot.QueryPort));
- }
+ localServerQueryEndPoint = new IPEndPoint(this.ProfileSnapshot.ServerIPAddress, Convert.ToUInt16(this.ProfileSnapshot.QueryPort));
//
// Get the public endpoint for querying Steam
@@ -281,13 +275,13 @@ namespace ServerManagerTool.Lib
case WatcherServerStatus.RunningLocalCheck:
if (oldStatus != ServerStatus.Stopping)
- UpdateServerStatus(ServerStatus.Running, this.Availability != AvailabilityStatus.Available ? AvailabilityStatus.WaitingForPublication : this.Availability, oldStatus != ServerStatus.Running && oldStatus != ServerStatus.Unknown);
+ UpdateServerStatus(ServerStatus.Running, this.Availability != AvailabilityStatus.Available ? AvailabilityStatus.Waiting : this.Availability, oldStatus != ServerStatus.Running && oldStatus != ServerStatus.Unknown);
if (this.ProfileSnapshot.MOTDIntervalEnabled && this.motdIntervalTimer != null && !this.motdIntervalTimer.Enabled) this.motdIntervalTimer.Start();
break;
case WatcherServerStatus.RunningExternalCheck:
if (oldStatus != ServerStatus.Stopping)
- UpdateServerStatus(ServerStatus.Running, AvailabilityStatus.WaitingForPublication, oldStatus != ServerStatus.Running && oldStatus != ServerStatus.Unknown);
+ UpdateServerStatus(ServerStatus.Running, AvailabilityStatus.Waiting, oldStatus != ServerStatus.Running && oldStatus != ServerStatus.Unknown);
if (this.ProfileSnapshot.MOTDIntervalEnabled && this.motdIntervalTimer != null && !this.motdIntervalTimer.Enabled) this.motdIntervalTimer.Start();
break;
@@ -439,7 +433,7 @@ namespace ServerManagerTool.Lib
}
CheckServerWorldFileExists();
- UpdateServerStatus(ServerStatus.Initializing, this.Availability, false);
+ UpdateServerStatus(ServerStatus.Initializing, false);
try
{
@@ -498,12 +492,12 @@ namespace ServerManagerTool.Lib
}
}
- public async Task UpgradeAsync(CancellationToken cancellationToken, bool updateServer, ServerBranchSnapshot branch, bool validate, bool updateMods, ProgressDelegate progressCallback)
+ public async Task UpgradeAsync(CancellationToken cancellationToken, bool updateServer, BranchSnapshot branch, bool validate, bool updateMods, ProgressDelegate progressCallback)
{
return await UpgradeAsync(cancellationToken, updateServer, branch, validate, updateMods, null, progressCallback);
}
- public async Task UpgradeAsync(CancellationToken cancellationToken, bool updateServer, ServerBranchSnapshot branch, bool validate, bool updateMods, string[] updateModIds, ProgressDelegate progressCallback)
+ public async Task UpgradeAsync(CancellationToken cancellationToken, bool updateServer, BranchSnapshot branch, bool validate, bool updateMods, string[] updateModIds, ProgressDelegate progressCallback)
{
if (updateServer && !Environment.Is64BitOperatingSystem)
{
@@ -520,7 +514,7 @@ namespace ServerManagerTool.Lib
bool isNewInstallation = this.Status == ServerStatus.Uninstalled;
- UpdateServerStatus(ServerStatus.Updating, Availability, false);
+ UpdateServerStatus(ServerStatus.Updating, false);
// Run the SteamCMD to install the server
var steamCmdFile = SteamCmdUpdater.GetSteamCmdFile(Config.Default.DataDir);
@@ -957,7 +951,7 @@ namespace ServerManagerTool.Lib
finally
{
this.lastModStatusQuery = DateTime.MinValue;
- UpdateServerStatus(ServerStatus.Stopped, Availability, false);
+ UpdateServerStatus(ServerStatus.Stopped, false);
}
}
@@ -993,6 +987,11 @@ namespace ServerManagerTool.Lib
this.lastModStatusQuery = DateTime.MinValue;
}
+ public void UpdateServerStatus(ServerStatus serverStatus, bool sendAlert)
+ {
+ UpdateServerStatus(serverStatus, Availability, sendAlert);
+ }
+
public void UpdateServerStatus(ServerStatus serverStatus, AvailabilityStatus availabilityStatus, bool sendAlert)
{
this.Status = serverStatus;
@@ -1006,32 +1005,29 @@ namespace ServerManagerTool.Lib
public void UpdateServerStatusString()
{
- switch (Status)
+ StatusString = GetServerStatusString(Status);
+ }
+
+ public static string GetServerStatusString(ServerStatus status)
+ {
+ switch (status)
{
case ServerStatus.Initializing:
- StatusString = _globalizer.GetResourceString("ServerSettings_RuntimeStatusInitializingLabel");
- break;
+ return _globalizer.GetResourceString("ServerSettings_RuntimeStatusInitializingLabel");
case ServerStatus.Running:
- StatusString = _globalizer.GetResourceString("ServerSettings_RuntimeStatusRunningLabel");
- break;
+ return _globalizer.GetResourceString("ServerSettings_RuntimeStatusRunningLabel");
case ServerStatus.Stopped:
- StatusString = _globalizer.GetResourceString("ServerSettings_RuntimeStatusStoppedLabel");
- break;
+ return _globalizer.GetResourceString("ServerSettings_RuntimeStatusStoppedLabel");
case ServerStatus.Stopping:
- StatusString = _globalizer.GetResourceString("ServerSettings_RuntimeStatusStoppingLabel");
- break;
+ return _globalizer.GetResourceString("ServerSettings_RuntimeStatusStoppingLabel");
case ServerStatus.Uninstalled:
- StatusString = _globalizer.GetResourceString("ServerSettings_RuntimeStatusUninstalledLabel");
- break;
+ return _globalizer.GetResourceString("ServerSettings_RuntimeStatusUninstalledLabel");
case ServerStatus.Unknown:
- StatusString = _globalizer.GetResourceString("ServerSettings_RuntimeStatusUnknownLabel");
- break;
+ return _globalizer.GetResourceString("ServerSettings_RuntimeStatusUnknownLabel");
case ServerStatus.Updating:
- StatusString = _globalizer.GetResourceString("ServerSettings_RuntimeStatusUpdatingLabel");
- break;
+ return _globalizer.GetResourceString("ServerSettings_RuntimeStatusUpdatingLabel");
default:
- StatusString = _globalizer.GetResourceString("ServerSettings_RuntimeStatusUnknownLabel");
- break;
+ return _globalizer.GetResourceString("ServerSettings_RuntimeStatusUnknownLabel");
}
}
@@ -1091,7 +1087,7 @@ namespace ServerManagerTool.Lib
try
{
- var endPoint = new IPEndPoint(IPAddress.Parse(this.ProfileSnapshot.ServerIP), this.ProfileSnapshot.RCONPort);
+ var endPoint = new IPEndPoint(this.ProfileSnapshot.ServerIPAddress, this.ProfileSnapshot.RCONPort);
var server = QueryMaster.ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endPoint, sendTimeOut: 10000, receiveTimeOut: 10000);
if (server == null)
diff --git a/src/ARKServerManager/Lib/ViewModel/SupplyCrateSettings.cs b/src/ARKServerManager/Lib/ViewModel/SupplyCrateSettings.cs
index a714d2aa..07d81387 100644
--- a/src/ARKServerManager/Lib/ViewModel/SupplyCrateSettings.cs
+++ b/src/ARKServerManager/Lib/ViewModel/SupplyCrateSettings.cs
@@ -18,8 +18,29 @@ namespace ServerManagerTool.Lib.ViewModel
set { SetValue(ItemWeightProperty, value); }
}
- public string DisplayName => GameData.FriendlySupplyCrateNameForClass(ItemClassString);
+ public string DisplayName => GameData.FriendlyItemNameForClass(ItemClassString);
- public bool IsValid => !string.IsNullOrWhiteSpace(ItemClassString);
+ public string DisplayNameFull
+ {
+ get
+ {
+ var modName = GameData.FriendlyItemModNameForClass(ItemClassString); ;
+ return $"{(string.IsNullOrWhiteSpace(modName) ? string.Empty : $"({modName}) ")}{DisplayName}";
+ }
+ }
+
+ public bool IsViewValid => !string.IsNullOrWhiteSpace(ItemClassString);
+
+ public static readonly DependencyProperty ValidStatusProperty = DependencyProperty.Register(nameof(ValidStatus), typeof(string), typeof(SupplyCrateItemEntrySettings), new PropertyMetadata("N"));
+ public string ValidStatus
+ {
+ get { return (string)GetValue(ValidStatusProperty); }
+ set { SetValue(ValidStatusProperty, value); }
+ }
+
+ public void Update()
+ {
+ ValidStatus = IsViewValid ? (GameData.HasItemForClass(ItemClassString) ? "Y" : "W") : "N";
+ }
}
}
diff --git a/src/ARKServerManager/Properties/AssemblyInfo.cs b/src/ARKServerManager/Properties/AssemblyInfo.cs
index 6a0b63d7..6888352a 100644
--- a/src/ARKServerManager/Properties/AssemblyInfo.cs
+++ b/src/ARKServerManager/Properties/AssemblyInfo.cs
@@ -2,54 +2,22 @@
using System.Runtime.InteropServices;
using System.Windows;
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
[assembly: AssemblyTitle("ARK: Survival Evolved™ Server Manager")]
[assembly: AssemblyDescription("The server manager makes it easy to setup and manage your ARK: Survival Evolved™ dedicated servers.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Bletch1971")]
[assembly: AssemblyProduct("Server Managers")]
-[assembly: AssemblyCopyright("Copyright © 2015-2020")]
+[assembly: AssemblyCopyright("Copyright © 2015-2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
-//In order to begin building localizable applications, set
-//CultureYouAreCodingWith in your .csproj file
-//inside a . For example, if you are using US english
-//in your source files, set the to en-US. Then uncomment
-//the NeutralResourceLanguage attribute below. Update the "en-US" in
-//the line below to match the UICulture setting in the project file.
-
-//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
-
-
[assembly: ThemeInfo(
- //where theme specific resource dictionaries are located
- //(used if a resource is not found in the page,
- // or application resource dictionaries)
ResourceDictionaryLocation.None,
- //where the generic resource dictionary is located
- //(used if a resource is not found in the page,
- // app, or any theme specific resource dictionaries)
ResourceDictionaryLocation.SourceAssembly
)]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0")]
+// include semantic versioning - ARKServerManager
[assembly: AssemblyVersion("1.0")]
-[assembly: AssemblyFileVersion("1.0.0.1")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/ARKServerManager/Styles/Default.xaml b/src/ARKServerManager/Styles/Default.xaml
index a0be2728..b509fe68 100644
--- a/src/ARKServerManager/Styles/Default.xaml
+++ b/src/ARKServerManager/Styles/Default.xaml
@@ -1,23 +1,51 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -50,6 +315,418 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/ARKServerManager/Windows/GlobalSettingsControl.xaml b/src/ARKServerManager/UserControls/GlobalSettingsControl.xaml
similarity index 90%
rename from src/ARKServerManager/Windows/GlobalSettingsControl.xaml
rename to src/ARKServerManager/UserControls/GlobalSettingsControl.xaml
index a6c44298..6919def4 100644
--- a/src/ARKServerManager/Windows/GlobalSettingsControl.xaml
+++ b/src/ARKServerManager/UserControls/GlobalSettingsControl.xaml
@@ -7,62 +7,18 @@
xmlns:cc="clr-namespace:ServerManagerTool.Common.Converters;assembly=ServerManager.Common"
xmlns:globcntrls="clr-namespace:WPFSharp.Globalizer.Controls;assembly=WPFSharp.Globalizer"
mc:Ignorable="d"
- d:DesignWidth="800">
+ d:DesignWidth="800"
+ x:Name="GlobalSettings">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -88,6 +44,7 @@
+
@@ -104,18 +61,22 @@
-
-
-
+
+
+
+
+
+
-
+
+
-
+
@@ -619,6 +580,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -661,7 +671,7 @@
-
+
@@ -685,7 +695,7 @@
-
+
diff --git a/src/ARKServerManager/Windows/GlobalSettingsControl.xaml.cs b/src/ARKServerManager/UserControls/GlobalSettingsControl.xaml.cs
similarity index 84%
rename from src/ARKServerManager/Windows/GlobalSettingsControl.xaml.cs
rename to src/ARKServerManager/UserControls/GlobalSettingsControl.xaml.cs
index d18a0611..9dd9dc78 100644
--- a/src/ARKServerManager/Windows/GlobalSettingsControl.xaml.cs
+++ b/src/ARKServerManager/UserControls/GlobalSettingsControl.xaml.cs
@@ -2,6 +2,7 @@
using NLog;
using ServerManagerTool.Common;
using ServerManagerTool.Common.Lib;
+using ServerManagerTool.Common.Model;
using ServerManagerTool.Common.Utils;
using System;
using System.Diagnostics;
@@ -11,6 +12,7 @@ using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
+using System.Windows.Input;
using System.Xml;
using WPFSharp.Globalizer;
@@ -27,6 +29,7 @@ namespace ServerManagerTool
public static readonly DependencyProperty IsAdministratorProperty = DependencyProperty.Register(nameof(IsAdministrator), typeof(bool), typeof(GlobalSettingsControl), new PropertyMetadata(false));
public static readonly DependencyProperty CurrentConfigProperty = DependencyProperty.Register(nameof(CurrentConfig), typeof(Config), typeof(GlobalSettingsControl), new PropertyMetadata(null));
public static readonly DependencyProperty CommonConfigProperty = DependencyProperty.Register(nameof(CommonConfig), typeof(CommonConfig), typeof(GlobalSettingsControl), new PropertyMetadata(null));
+ public static readonly DependencyProperty WindowStatesProperty = DependencyProperty.Register(nameof(WindowStates), typeof(ComboBoxItemList), typeof(GlobalSettingsControl), new PropertyMetadata(null));
public GlobalSettingsControl()
{
@@ -36,6 +39,8 @@ namespace ServerManagerTool
this.CommonConfig = CommonConfig.Default;
this.DataContext = this;
+ PopulateWindowsStatesComboBox();
+
InitializeComponent();
WindowUtils.RemoveDefaultResourceDictionary(this, Config.Default.DefaultGlobalizationFile);
@@ -66,6 +71,12 @@ namespace ServerManagerTool
set { SetValue(IsAdministratorProperty, value); }
}
+ public ComboBoxItemList WindowStates
+ {
+ get { return (ComboBoxItemList)GetValue(WindowStatesProperty); }
+ set { SetValue(WindowStatesProperty, value); }
+ }
+
private string GetDeployedVersion()
{
XmlDocument xmlDoc = new XmlDocument();
@@ -192,6 +203,21 @@ namespace ServerManagerTool
}
}
+ private void ResetDataDir_Click(object sender, RoutedEventArgs e)
+ {
+ // Confirm the reset with the user.
+ if (MessageBox.Show(_globalizer.GetResourceString("GlobalSettings_ResetDataDirectory_ConfirmLabel"), _globalizer.GetResourceString("GlobalSettings_ResetDataDirectory_ConfirmTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
+ return;
+
+ // Update the config
+ Config.Default.DataDir = string.Empty;
+ Config.Default.ConfigDirectory = string.Empty;
+
+ App.SaveConfigFiles(false);
+
+ Environment.Exit(0);
+ }
+
private void SetBackupDir_Click(object sender, RoutedEventArgs e)
{
var dialog = new CommonOpenFileDialog();
@@ -278,9 +304,35 @@ namespace ServerManagerTool
}
}
+ private void DiscordBotApply_Click(object sender, RoutedEventArgs e)
+ {
+ Process.Start(Config.Default.DiscordBotApplyUrl);
+ }
+
+ private void DiscordBotHelp_Click(object sender, RoutedEventArgs e)
+ {
+ Process.Start(Config.Default.DiscordBotHelpUrl);
+ }
+
+ 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 LanguageSelectionComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
CurrentConfig.CultureName = AvailableLanguages.Instance.SelectedLanguage;
+
+ PopulateWindowsStatesComboBox();
+
+ App.Instance.OnResourceDictionaryChanged(CurrentConfig.CultureName);
}
private void StyleSelectionComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
@@ -299,6 +351,8 @@ namespace ServerManagerTool
textBox = SteamAPIKeyTextBox;
if (Equals(hideTextBox, HideEmailPasswordTextBox))
textBox = EmailPasswordTextBox;
+ if (Equals(hideTextBox, HideDiscordBotTokenTextBox))
+ textBox = DiscordBotTokenTextBox;
if (textBox != null)
{
@@ -322,6 +376,8 @@ namespace ServerManagerTool
hideTextBox = HideSteamAPIKeyTextBox;
if (textBox == EmailPasswordTextBox)
hideTextBox = HideEmailPasswordTextBox;
+ if (textBox == DiscordBotTokenTextBox)
+ hideTextBox = HideDiscordBotTokenTextBox;
if (hideTextBox != null)
{
@@ -343,13 +399,11 @@ namespace ServerManagerTool
{
Config.Default.Reset();
Config.Default.UpgradeConfig = false;
- Config.Default.Save();
- Config.Default.Reload();
CommonConfig.Default.Reset();
CommonConfig.Default.UpgradeConfig = false;
- CommonConfig.Default.Save();
- CommonConfig.Default.Reload();
+
+ App.SaveConfigFiles(false);
}
catch (Exception ex)
{
@@ -359,7 +413,25 @@ namespace ServerManagerTool
}
finally
{
- App.Current.Shutdown(exitCode);
+ Environment.Exit(exitCode);
+ }
+ }
+
+ private void PopulateWindowsStatesComboBox()
+ {
+ var selectedValue = this.WindowStateComboBox?.SelectedValue ?? CurrentConfig.MainWindow_WindowState;
+ var windowStates = new ComboBoxItemList();
+
+ foreach (WindowState windowState in Enum.GetValues(typeof(WindowState)))
+ {
+ var displayMember = _globalizer.GetResourceString($"WindowState_{windowState}") ?? windowState.ToString();
+ windowStates.Add(new Common.Model.ComboBoxItem(windowState.ToString(), displayMember));
+ }
+
+ this.WindowStates = windowStates;
+ if (this.WindowStateComboBox != null)
+ {
+ this.WindowStateComboBox.SelectedValue = selectedValue;
}
}
}
diff --git a/src/ARKServerManager/Windows/ServerSettingsControl.xaml b/src/ARKServerManager/UserControls/ServerSettingsControl.xaml
similarity index 92%
rename from src/ARKServerManager/Windows/ServerSettingsControl.xaml
rename to src/ARKServerManager/UserControls/ServerSettingsControl.xaml
index ea21be43..c5475614 100644
--- a/src/ARKServerManager/Windows/ServerSettingsControl.xaml
+++ b/src/ARKServerManager/UserControls/ServerSettingsControl.xaml
@@ -24,23 +24,12 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
@@ -53,381 +42,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -586,6 +200,7 @@
+
@@ -593,14 +208,20 @@
+
-
+
+
+
+
+
+
+
+
-
-
@@ -619,10 +240,10 @@
-
-
+
+
-
+
@@ -683,7 +304,7 @@
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2007,6 +1680,7 @@
+
@@ -2047,6 +1721,8 @@
+
+
@@ -2741,8 +2417,15 @@
-
-
+
+
+
+
+
+
+
+
+
@@ -2751,7 +2434,7 @@
-
+
-
+
+
+
@@ -3189,6 +2874,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -3278,8 +3032,15 @@
-
-
+
+
+
+
+
+
+
+
+
@@ -3288,7 +3049,7 @@
-
+
@@ -3364,7 +3125,9 @@
-
+
+
+
@@ -3436,7 +3199,7 @@
-
+
@@ -3549,7 +3312,9 @@
-
+
+
+
@@ -3577,8 +3342,14 @@
-
-
+
+
+
+
+
+
+
+
@@ -3612,7 +3383,7 @@
-
+
@@ -3635,7 +3406,7 @@
-
+
-
-
+
+
+
@@ -3903,7 +3675,9 @@
-
+
+
+
@@ -3913,7 +3687,7 @@
-
+
@@ -4001,7 +3775,7 @@
-
+
@@ -4089,7 +3863,7 @@
-
+
@@ -4176,6 +3950,8 @@
+
+
@@ -4201,12 +3977,18 @@
+
+
+
+
+
-
-
+
+
+
-
+
@@ -4269,7 +4051,9 @@
-
+
+
+
@@ -4325,6 +4109,8 @@
+
+
@@ -4350,12 +4136,18 @@
+
+
+
+
+
-
-
+
+
+
-
+
@@ -4418,7 +4210,9 @@
-
+
+
+
@@ -4474,6 +4268,8 @@
+
+
@@ -4499,12 +4295,18 @@
+
+
+
+
+
-
-
+
+
+
-
+
@@ -4567,7 +4369,9 @@
-
+
+
+
@@ -4623,6 +4427,8 @@
+
+
@@ -4658,33 +4464,36 @@
-
+
+
+
-
-
+
+
+
-
+
-
+
-
+
-
+
@@ -4773,7 +4582,9 @@
-
+
+
+
@@ -4834,6 +4645,8 @@
+
+
@@ -4867,18 +4680,21 @@
-
+
+
+
-
-
+
+
+
-
+
-
+
-
+
@@ -4947,7 +4763,9 @@
-
+
+
+
@@ -5023,6 +4841,8 @@
+
+
@@ -5056,7 +4876,9 @@
-
+
+
+
@@ -5066,7 +4888,7 @@
-
+
@@ -5158,6 +4980,8 @@
+
+
@@ -5190,16 +5014,19 @@
-
+
+
+
-
-
+
+
+
-
+
-
+
@@ -5278,7 +5105,9 @@
-
+
+
+
@@ -5351,6 +5180,8 @@
+
+
@@ -5363,9 +5194,6 @@
Command="{Binding ResetActionCommand, ElementName=SettingsControl}" CommandParameter="{x:Static local:ServerSettingsResetAction.SupplyCrateOverridesSection}">
-
-
-
@@ -5387,10 +5215,15 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
@@ -5419,7 +5252,7 @@
-
+
+
+
+
+
+
@@ -5443,24 +5298,24 @@
-
+
-
-
+
+
-
-
+
+
-
-
+
+
@@ -5537,7 +5392,9 @@
-
+
+
+
@@ -5550,7 +5407,7 @@
-
+
+
+
+
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
@@ -5627,7 +5506,9 @@
-
+
+
+
@@ -5640,7 +5521,7 @@
-
+
+
+
+
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
@@ -5709,8 +5612,8 @@
-
-
+
+
@@ -5729,7 +5632,9 @@
-
+
+
+
@@ -5742,7 +5647,7 @@
-
+
+
+
+
+
+
@@ -5766,11 +5693,11 @@
-
+
-
+
@@ -5787,6 +5714,8 @@
+
+
@@ -5820,7 +5749,9 @@
-
+
+
+
@@ -5830,7 +5761,7 @@
-
+
@@ -5900,6 +5831,8 @@
+
+
diff --git a/src/ARKServerManager/Windows/ServerSettingsControl.xaml.cs b/src/ARKServerManager/UserControls/ServerSettingsControl.xaml.cs
similarity index 98%
rename from src/ARKServerManager/Windows/ServerSettingsControl.xaml.cs
rename to src/ARKServerManager/UserControls/ServerSettingsControl.xaml.cs
index 8cca3e4b..ffb9897e 100644
--- a/src/ARKServerManager/Windows/ServerSettingsControl.xaml.cs
+++ b/src/ARKServerManager/UserControls/ServerSettingsControl.xaml.cs
@@ -71,6 +71,8 @@ namespace ServerManagerTool
DinoTamedPerLevelStatMultipliers,
DinoTamedAddPerLevelStatMultipliers,
DinoTamedAffinityPerLevelStatMultipliers,
+ DinoWildMutagenLevelBoost,
+ DinoBredMutagenLevelBoost,
ItemStatClamps,
RCONWindowExtents,
ServerOptions,
@@ -917,6 +919,8 @@ namespace ServerManagerTool
comment.AppendLine($"IsAdministrator: {SecurityUtils.IsAdministrator()}");
comment.AppendLine($"RunAsAdministratorPrompt: {Config.Default.RunAsAdministratorPrompt}");
+ comment.AppendLine($"MainWindow_WindowState: {Config.Default.MainWindow_WindowState}");
+ comment.AppendLine($"MainWindow_MinimizeToTray: {Config.Default.MainWindow_MinimizeToTray}");
comment.AppendLine($"ManageFirewallAutomatically: {Config.Default.ManageFirewallAutomatically}");
comment.AppendLine($"ValidateProfileOnServerStart: {Config.Default.ValidateProfileOnServerStart}");
comment.AppendLine($"SteamCMD File: {SteamCmdUpdater.GetSteamCmdFile(Config.Default.DataDir)}");
@@ -961,6 +965,17 @@ namespace ServerManagerTool
comment.AppendLine($"ServerUpdate_ForceUpdateModsIfNoSteamInfo: {Config.Default.ServerUpdate_ForceUpdateModsIfNoSteamInfo}");
comment.AppendLine($"ServerUpdate_OnServerStart: {Config.Default.ServerUpdate_OnServerStart}");
+ comment.AppendLine($"DiscordBotEnabled: {Config.Default.DiscordBotEnabled}");
+ comment.AppendLine($"HasDiscordBotToken: {string.IsNullOrWhiteSpace(Config.Default.DiscordBotToken)}");
+ comment.AppendLine($"DiscordBotServerId: {Config.Default.DiscordBotServerId}");
+ comment.AppendLine($"DiscordBotPrefix: {Config.Default.DiscordBotPrefix}");
+ comment.AppendLine($"AllowDiscordBackup: {Config.Default.AllowDiscordBackup}");
+ comment.AppendLine($"AllowDiscordRestart: {Config.Default.AllowDiscordRestart}");
+ comment.AppendLine($"AllowDiscordShutdown: {Config.Default.AllowDiscordShutdown}");
+ comment.AppendLine($"AllowDiscordStart: {Config.Default.AllowDiscordStart}");
+ comment.AppendLine($"AllowDiscordStop: {Config.Default.AllowDiscordStop}");
+ comment.AppendLine($"AllowDiscordUpdate: {Config.Default.AllowDiscordUpdate}");
+
comment.AppendLine($"EmailNotify_AutoRestart: {Config.Default.EmailNotify_AutoRestart}");
comment.AppendLine($"EmailNotify_AutoBackup: {Config.Default.EmailNotify_AutoBackup}");
comment.AppendLine($"EmailNotify_AutoUpdate: {Config.Default.EmailNotify_AutoUpdate}");
@@ -1099,7 +1114,7 @@ namespace ServerManagerTool
var profile = ServerProfileSnapshot.Create(Server.Profile);
- var exitCode = await Task.Run(() => app.PerformProfileBackup(profile));
+ var exitCode = await Task.Run(() => app.PerformProfileBackup(profile, CancellationToken.None));
if (exitCode != ServerApp.EXITCODE_NORMALEXIT && exitCode != ServerApp.EXITCODE_CANCELLED)
throw new ApplicationException($"An error occured during the backup process - ExitCode: {exitCode}");
@@ -1288,6 +1303,11 @@ namespace ServerManagerTool
}
}
+ private void SupplyCratesGrids_SourceUpdated(object sender, DataTransferEventArgs e)
+ {
+ Settings.ConfigOverrideSupplyCrateItems.Update();
+ }
+
#region Dinos
private void DinoCustomization_Reset(object sender, RoutedEventArgs e)
{
@@ -3003,7 +3023,7 @@ namespace ServerManagerTool
private void AddSupplyCrate_Click(object sender, RoutedEventArgs e)
{
Settings.ConfigOverrideSupplyCrateItems.Add(new SupplyCrateOverride());
- Settings.ConfigOverrideSupplyCrateItems.IsEnabled = true;
+ Settings.ConfigOverrideSupplyCrateItems.Update();
}
private void AddSupplyCrateItemSet_Click(object sender, RoutedEventArgs e)
@@ -3015,6 +3035,7 @@ namespace ServerManagerTool
}
SelectedSupplyCrateOverride.ItemSets.Add(new SupplyCrateItemSet());
+ Settings.ConfigOverrideSupplyCrateItems.Update();
}
private void AddSupplyCrateItemSetEntry_Click(object sender, RoutedEventArgs e)
@@ -3026,6 +3047,7 @@ namespace ServerManagerTool
}
SelectedSupplyCrateItemSet.ItemEntries.Add(new SupplyCrateItemSetEntry());
+ Settings.ConfigOverrideSupplyCrateItems.Update();
}
private void AddSupplyCrateItem_Click(object sender, RoutedEventArgs e)
@@ -3037,6 +3059,7 @@ namespace ServerManagerTool
}
SelectedSupplyCrateItemSetEntry.Items.Add(new SupplyCrateItemEntrySettings());
+ Settings.ConfigOverrideSupplyCrateItems.Update();
}
private void ClearSupplyCrates_Click(object sender, RoutedEventArgs e)
@@ -3048,7 +3071,7 @@ namespace ServerManagerTool
SelectedSupplyCrateItemSet = null;
SelectedSupplyCrateOverride = null;
Settings.ConfigOverrideSupplyCrateItems.Clear();
- Settings.ConfigOverrideSupplyCrateItems.IsEnabled = false;
+ Settings.ConfigOverrideSupplyCrateItems.Update();
}
private void ClearSupplyCrateItemSets_Click(object sender, RoutedEventArgs e)
@@ -3059,6 +3082,7 @@ namespace ServerManagerTool
SelectedSupplyCrateItemSetEntry = null;
SelectedSupplyCrateItemSet = null;
SelectedSupplyCrateOverride?.ItemSets.Clear();
+ Settings.ConfigOverrideSupplyCrateItems.Update();
}
private void ClearSupplyCrateItemSetEntries_Click(object sender, RoutedEventArgs e)
@@ -3068,6 +3092,7 @@ namespace ServerManagerTool
SelectedSupplyCrateItemSetEntry = null;
SelectedSupplyCrateItemSet?.ItemEntries.Clear();
+ Settings.ConfigOverrideSupplyCrateItems.Update();
}
private void ClearSupplyCrateItems_Click(object sender, RoutedEventArgs e)
@@ -3076,6 +3101,7 @@ namespace ServerManagerTool
return;
SelectedSupplyCrateItemSetEntry?.Items.Clear();
+ Settings.ConfigOverrideSupplyCrateItems.Update();
}
private void PasteSupplyCrate_Click(object sender, RoutedEventArgs e)
@@ -3127,7 +3153,7 @@ namespace ServerManagerTool
var item = ((SupplyCrateOverride)((Button)e.Source).DataContext);
Settings.ConfigOverrideSupplyCrateItems.Remove(item);
- Settings.ConfigOverrideSupplyCrateItems.IsEnabled = Settings.ConfigOverrideSupplyCrateItems.Count > 0;
+ Settings.ConfigOverrideSupplyCrateItems.Update();
}
private void RemoveSupplyCrateItemSet_Click(object sender, RoutedEventArgs e)
@@ -3140,6 +3166,7 @@ namespace ServerManagerTool
var item = ((SupplyCrateItemSet)((Button)e.Source).DataContext);
SelectedSupplyCrateOverride.ItemSets.Remove(item);
+ Settings.ConfigOverrideSupplyCrateItems.Update();
}
private void RemoveSupplyCrateItemSetEntry_Click(object sender, RoutedEventArgs e)
@@ -3152,6 +3179,7 @@ namespace ServerManagerTool
var item = ((SupplyCrateItemSetEntry)((Button)e.Source).DataContext);
SelectedSupplyCrateItemSet.ItemEntries.Remove(item);
+ Settings.ConfigOverrideSupplyCrateItems.Update();
}
private void RemoveSupplyCrateItem_Click(object sender, RoutedEventArgs e)
@@ -3164,6 +3192,7 @@ namespace ServerManagerTool
var item = ((SupplyCrateItemEntrySettings)((Button)e.Source).DataContext);
SelectedSupplyCrateItemSetEntry.Items.Remove(item);
+ Settings.ConfigOverrideSupplyCrateItems.Update();
}
private void SaveSupplyCrates_Click(object sender, RoutedEventArgs e)
@@ -4113,6 +4142,14 @@ namespace ServerManagerTool
this.Settings.PerLevelStatsMultiplier_DinoTamed_Affinity.Reset();
break;
+ case ServerSettingsResetAction.DinoWildMutagenLevelBoost:
+ this.Settings.MutagenLevelBoost.Reset();
+ break;
+
+ case ServerSettingsResetAction.DinoBredMutagenLevelBoost:
+ this.Settings.MutagenLevelBoostBred.Reset();
+ break;
+
case ServerSettingsResetAction.ItemStatClamps:
break;
@@ -4252,7 +4289,7 @@ namespace ServerManagerTool
await Task.Delay(1000);
- var branch = new ServerBranchSnapshot() { BranchName = this.Server.Profile.BranchName, BranchPassword = this.Server.Profile.BranchPassword };
+ var branch = BranchSnapshot.Create(this.Server.Profile);
return await this.Server.UpgradeAsync(_upgradeCancellationSource.Token, updateServer, branch, true, updateMods, (p, m, n) => { TaskUtils.RunOnUIThreadAsync(() => { window?.AddMessage(m, n); }).DoNotWait(); });
}
else
@@ -4308,15 +4345,5 @@ namespace ServerManagerTool
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();
- }
}
}
diff --git a/src/ARKServerManager/Utils/DiscordBotHelper.cs b/src/ARKServerManager/Utils/DiscordBotHelper.cs
new file mode 100644
index 00000000..97abbec7
--- /dev/null
+++ b/src/ARKServerManager/Utils/DiscordBotHelper.cs
@@ -0,0 +1,735 @@
+using QueryMaster;
+using ServerManagerTool.Common.Utils;
+using ServerManagerTool.DiscordBot.Enums;
+using ServerManagerTool.Enums;
+using ServerManagerTool.Lib;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Net;
+using System.Threading;
+using System.Threading.Tasks;
+using WPFSharp.Globalizer;
+
+namespace ServerManagerTool.Utils
+{
+ internal static class DiscordBotHelper
+ {
+ private static readonly GlobalizedApplication _globalizer = GlobalizedApplication.Instance;
+ private static bool _runningCommand = false;
+
+ private static readonly Dictionary _currentProfileCommands = new Dictionary();
+
+ public static bool HasRunningCommands => _currentProfileCommands.Count > 0;
+
+ public static IList HandleDiscordCommand(CommandType commandType, string serverId, string channelId, string profileId, CancellationToken token)
+ {
+ // check if incoming values are valid
+ if (string.IsNullOrWhiteSpace(serverId) || string.IsNullOrWhiteSpace(channelId))
+ return null;
+
+ // check if the server ids match
+ if (!serverId.Equals(Config.Default.DiscordBotServerId))
+ return new List();
+
+ if (_runningCommand)
+ return new List { _globalizer.GetResourceString("DiscordBot_CommandRunning") };
+ _runningCommand = true;
+
+ try
+ {
+ switch (commandType)
+ {
+ case CommandType.Info:
+ return GetServerInfo(channelId, profileId);
+ case CommandType.List:
+ return GetServerList(channelId);
+ case CommandType.Status:
+ return GetServerStatus(channelId, profileId);
+
+ case CommandType.Backup:
+ if (Config.Default.AllowDiscordBackup)
+ return BackupServer(channelId, profileId, token);
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandNotEnabled"), commandType) };
+ case CommandType.Restart:
+ if (Config.Default.AllowDiscordRestart)
+ return RestartServer(channelId, profileId, token);
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandNotEnabled"), commandType) };
+ case CommandType.Shutdown:
+ if (Config.Default.AllowDiscordShutdown)
+ return ShutdownServer(channelId, profileId, token);
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandNotEnabled"), commandType) };
+ case CommandType.Stop:
+ if (Config.Default.AllowDiscordStop)
+ return StopServer(channelId, profileId, token);
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandNotEnabled"), commandType) };
+ case CommandType.Start:
+ if (Config.Default.AllowDiscordStart)
+ return StartServer(channelId, profileId, token);
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandNotEnabled"), commandType) };
+ case CommandType.Update:
+ if (Config.Default.AllowDiscordUpdate)
+ return UpdateServer(channelId, profileId, token);
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandNotEnabled"), commandType) };
+
+ default:
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), commandType) };
+ }
+ }
+ catch (Exception ex)
+ {
+ var message = ex.InnerException is null ? ex.Message : ex.InnerException.Message;
+ return new string[] { message };
+ }
+ finally
+ {
+ _runningCommand = false;
+ }
+ }
+
+ public static string HandleTranslation(string translationKey)
+ {
+ return string.IsNullOrWhiteSpace(translationKey) ? string.Empty : _globalizer.GetResourceString(translationKey) ?? translationKey;
+ }
+
+ private static IList GetServerInfo(string channelId, string profileId)
+ {
+ if (string.IsNullOrWhiteSpace(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Info) };
+ }
+
+ // check if another command is being run against the profile
+ if (_currentProfileCommands.ContainsKey(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
+ }
+ _currentProfileCommands.Add(profileId, CommandType.Info);
+
+ try
+ {
+ var serverName = string.Empty;
+ var serverIp = IPAddress.Loopback;
+ var queryPort = 0;
+
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+
+ if (server is null)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
+ }
+
+ switch (server.Runtime.Status)
+ {
+ case ServerStatus.Initializing:
+ case ServerStatus.Stopping:
+ case ServerStatus.Stopped:
+ case ServerStatus.Uninstalled:
+ case ServerStatus.Unknown:
+ case ServerStatus.Updating:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
+ }
+
+ serverName = server.Profile.ServerName;
+ if (!string.IsNullOrWhiteSpace(server.Profile.ServerIP))
+ {
+ IPAddress.TryParse(server.Profile.ServerIP, out serverIp);
+ }
+ queryPort = server.Profile.QueryPort;
+ }).Wait();
+
+ List response = new List();
+
+ try
+ {
+ using (var gameServer = ServerQuery.GetServerInstance(EngineType.Source, new IPEndPoint(serverIp, queryPort)))
+ {
+ var info = gameServer?.GetInfo();
+ if (info is null)
+ {
+ response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_InfoFailed"), serverName));
+ }
+ else
+ {
+ var mapName = _globalizer.GetResourceString($"Map_{info.Map}") ?? info.Map;
+ response.Add($"```{info.Name}\n{_globalizer.GetResourceString("DiscordBot_MapLabel")} {mapName}\n{_globalizer.GetResourceString("ServerSettings_PlayersLabel")} {info.Players} / {info.MaxPlayers}```");
+ }
+ }
+ }
+ catch (Exception)
+ {
+ response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_InfoFailed"), serverName));
+ }
+
+ return response;
+ }
+ finally
+ {
+ _currentProfileCommands.Remove(profileId);
+ }
+ }
+
+ private static IList GetServerList(string channelId)
+ {
+ List response = new List();
+
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var serverList = ServerManager.Instance.Servers.Where(s => Equals(channelId, s.Profile.DiscordChannelId));
+
+ response.Add($"**{_globalizer.GetResourceString("DiscordBot_CountLabel")}** {serverList.Count()}");
+ foreach (var server in serverList)
+ {
+ response.Add($"```{_globalizer.GetResourceString("ServerSettings_ProfileIdLabel")} {server.Profile.ProfileID}\n{_globalizer.GetResourceString("ServerSettings_ProfileLabel")} {server.Profile.ProfileName}\n{_globalizer.GetResourceString("ServerSettings_ServerNameLabel")} {server.Profile.ServerName}```");
+ }
+ }).Wait();
+
+ return response;
+ }
+
+ private static IList GetServerStatus(string channelId, string profileId)
+ {
+ List response = new List();
+
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var serverList = ServerManager.Instance.Servers.Where(s => Equals(channelId, s.Profile.DiscordChannelId) && (string.IsNullOrWhiteSpace(profileId) || Equals(profileId, s.Profile.ProfileID)));
+
+ response.Add($"**{_globalizer.GetResourceString("DiscordBot_CountLabel")}** {serverList.Count()}");
+ foreach (var server in serverList)
+ {
+ response.Add($"```{_globalizer.GetResourceString("ServerSettings_ProfileLabel")} {server.Profile.ProfileName}\n{_globalizer.GetResourceString("ServerSettings_ServerNameLabel")} {server.Profile.ServerName}\n{_globalizer.GetResourceString("ServerSettings_StatusLabel")} {server.Runtime.StatusString}\n{_globalizer.GetResourceString("ServerSettings_AvailabilityLabel")} {_globalizer.GetResourceString($"ServerSettings_Availability_{server.Runtime.Availability}")}```");
+ }
+ }).Wait();
+
+ return response;
+ }
+
+ private static IList BackupServer(string channelId, string profileId, CancellationToken token)
+ {
+ if (string.IsNullOrWhiteSpace(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Backup) };
+ }
+
+ // check if another command is being run against the profile
+ if (_currentProfileCommands.ContainsKey(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
+ }
+ _currentProfileCommands.Add(profileId, CommandType.Backup);
+
+ ServerProfileSnapshot profile = null;
+ Task task = null;
+
+ try
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+
+ if (server is null)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
+ }
+
+ if (!server.Profile.AllowDiscordBackup)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_CommandDisabledProfile"), CommandType.Backup, profileId));
+ }
+
+ switch (server.Runtime.Status)
+ {
+ case ServerStatus.Initializing:
+ case ServerStatus.Stopping:
+ case ServerStatus.Uninstalled:
+ case ServerStatus.Unknown:
+ case ServerStatus.Updating:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
+ }
+
+ profile = ServerProfileSnapshot.Create(server.Profile);
+ }).Wait();
+
+ List response = new List();
+
+ var app = new ServerApp(true)
+ {
+ DeleteOldServerBackupFiles = !Config.Default.AutoBackup_EnableBackup,
+ OutputLogs = false,
+ SendAlerts = true,
+ SendEmails = false,
+ ServerProcess = ServerProcessType.Backup,
+ ServerStatusChangeCallback = (ServerStatus serverStatus) =>
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+ server.Runtime.UpdateServerStatus(serverStatus, true);
+ }).Wait();
+ }
+ };
+
+ task = Task.Run(() =>
+ {
+ app.PerformProfileBackup(profile, token);
+ _currentProfileCommands.Remove(profileId);
+ });
+
+ response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_BackupRequested"), profile.ServerName));
+
+ return response;
+ }
+ finally
+ {
+ if (task is null)
+ {
+ _currentProfileCommands.Remove(profileId);
+ }
+ }
+ }
+
+ private static IList RestartServer(string channelId, string profileId, CancellationToken token)
+ {
+ if (string.IsNullOrWhiteSpace(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Restart) };
+ }
+
+ // check if another command is being run against the profile
+ if (_currentProfileCommands.ContainsKey(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
+ }
+ _currentProfileCommands.Add(profileId, CommandType.Restart);
+
+ ServerProfileSnapshot profile = null;
+ Task task = null;
+
+ try
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+
+ if (server is null)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
+ }
+
+ if (!server.Profile.AllowDiscordRestart)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_CommandDisabledProfile"), CommandType.Restart, profileId));
+ }
+
+ switch (server.Runtime.Status)
+ {
+ case ServerStatus.Initializing:
+ case ServerStatus.Stopping:
+ case ServerStatus.Uninstalled:
+ case ServerStatus.Unknown:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
+
+ case ServerStatus.Updating:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), profileId));
+ }
+
+ profile = ServerProfileSnapshot.Create(server.Profile);
+ profile.AutoRestartIfShutdown = true;
+ }).Wait();
+
+ List response = new List();
+
+ var app = new ServerApp(true)
+ {
+ DeleteOldServerBackupFiles = !Config.Default.AutoBackup_EnableBackup,
+ OutputLogs = false,
+ SendAlerts = true,
+ SendEmails = false,
+ ServerProcess = ServerProcessType.Restart,
+ ServerStatusChangeCallback = (ServerStatus serverStatus) =>
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+ server.Runtime.UpdateServerStatus(serverStatus, true);
+ }).Wait();
+ }
+ };
+
+ task = Task.Run(() =>
+ {
+ app.PerformProfileShutdown(profile, true, false, false, token);
+ _currentProfileCommands.Remove(profileId);
+ });
+
+ response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_RestartRequested"), profile.ServerName));
+
+ return response;
+ }
+ finally
+ {
+ if (task is null)
+ {
+ _currentProfileCommands.Remove(profileId);
+ }
+ }
+ }
+
+ private static IList ShutdownServer(string channelId, string profileId, CancellationToken token)
+ {
+ if (string.IsNullOrWhiteSpace(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Shutdown) };
+ }
+
+ // check if another command is being run against the profile
+ if (_currentProfileCommands.ContainsKey(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
+ }
+ _currentProfileCommands.Add(profileId, CommandType.Shutdown);
+
+ ServerProfileSnapshot profile = null;
+ Task task = null;
+
+ try
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+
+ if (server is null)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
+ }
+
+ if (!server.Profile.AllowDiscordShutdown)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_CommandDisabledProfile"), CommandType.Shutdown, profileId));
+ }
+
+ switch (server.Runtime.Status)
+ {
+ case ServerStatus.Initializing:
+ case ServerStatus.Stopping:
+ case ServerStatus.Stopped:
+ case ServerStatus.Uninstalled:
+ case ServerStatus.Unknown:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
+
+ case ServerStatus.Updating:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), profileId));
+ }
+
+ profile = ServerProfileSnapshot.Create(server.Profile);
+ }).Wait();
+
+ List response = new List();
+
+ var app = new ServerApp(true)
+ {
+ DeleteOldServerBackupFiles = !Config.Default.AutoBackup_EnableBackup,
+ OutputLogs = false,
+ SendAlerts = true,
+ SendEmails = false,
+ ServerProcess = ServerProcessType.Shutdown,
+ ServerStatusChangeCallback = (ServerStatus serverStatus) =>
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+ server.Runtime.UpdateServerStatus(serverStatus, true);
+ }).Wait();
+ }
+ };
+
+ task = Task.Run(() =>
+ {
+ app.PerformProfileShutdown(profile, false, false, false, token);
+ _currentProfileCommands.Remove(profileId);
+ });
+
+ response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_ShutdownRequested"), profile.ServerName));
+
+ return response;
+ }
+ finally
+ {
+ if (task is null)
+ {
+ _currentProfileCommands.Remove(profileId);
+ }
+ }
+ }
+
+ private static IList StopServer(string channelId, string profileId, CancellationToken token)
+ {
+ if (string.IsNullOrWhiteSpace(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Stop) };
+ }
+
+ // check if another command is being run against the profile
+ if (_currentProfileCommands.ContainsKey(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
+ }
+ _currentProfileCommands.Add(profileId, CommandType.Stop);
+
+ ServerProfileSnapshot profile = null;
+ Task task = null;
+
+ try
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+
+ if (server is null)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
+ }
+
+ if (!server.Profile.AllowDiscordStop)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_CommandDisabledProfile"), CommandType.Stop, profileId));
+ }
+
+ switch (server.Runtime.Status)
+ {
+ case ServerStatus.Initializing:
+ case ServerStatus.Stopping:
+ case ServerStatus.Stopped:
+ case ServerStatus.Uninstalled:
+ case ServerStatus.Unknown:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
+
+ case ServerStatus.Updating:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), profileId));
+ }
+
+ profile = ServerProfileSnapshot.Create(server.Profile);
+ }).Wait();
+
+ List response = new List();
+
+ var app = new ServerApp(true)
+ {
+ DeleteOldServerBackupFiles = !Config.Default.AutoBackup_EnableBackup,
+ OutputLogs = false,
+ SendAlerts = true,
+ SendEmails = false,
+ ServerProcess = ServerProcessType.Shutdown,
+ ShutdownInterval = 0,
+ ServerStatusChangeCallback = (ServerStatus serverStatus) =>
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+ server.Runtime.UpdateServerStatus(serverStatus, true);
+ }).Wait();
+ }
+ };
+
+ task = Task.Run(() =>
+ {
+ app.PerformProfileShutdown(profile, false, false, false, token);
+ _currentProfileCommands.Remove(profileId);
+ });
+
+ response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_StopRequested"), profile.ServerName));
+
+ return response;
+ }
+ finally
+ {
+ if (task is null)
+ {
+ _currentProfileCommands.Remove(profileId);
+ }
+ }
+ }
+
+ private static IList StartServer(string channelId, string profileId, CancellationToken token)
+ {
+ if (string.IsNullOrWhiteSpace(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Start) };
+ }
+
+ // check if another command is being run against the profile
+ if (_currentProfileCommands.ContainsKey(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
+ }
+ _currentProfileCommands.Add(profileId, CommandType.Start);
+
+ ServerProfileSnapshot profile = null;
+ Task task = null;
+
+ try
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+
+ if (server is null)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
+ }
+
+ if (!server.Profile.AllowDiscordStart)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_CommandDisabledProfile"), CommandType.Start, profileId));
+ }
+
+ switch (server.Runtime.Status)
+ {
+ case ServerStatus.Initializing:
+ case ServerStatus.Stopping:
+ case ServerStatus.Running:
+ case ServerStatus.Uninstalled:
+ case ServerStatus.Unknown:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
+
+ case ServerStatus.Updating:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), profileId));
+ }
+
+ profile = ServerProfileSnapshot.Create(server.Profile);
+ profile.AutoRestartIfShutdown = true;
+ }).Wait();
+
+ List response = new List();
+
+ var app = new ServerApp(true)
+ {
+ DeleteOldServerBackupFiles = !Config.Default.AutoBackup_EnableBackup,
+ OutputLogs = false,
+ SendAlerts = true,
+ SendEmails = false,
+ ServerProcess = ServerProcessType.Restart,
+ ServerStatusChangeCallback = (ServerStatus serverStatus) =>
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+ server.Runtime.UpdateServerStatus(serverStatus, true);
+ }).Wait();
+ }
+ };
+
+ task = Task.Run(() =>
+ {
+ app.PerformProfileShutdown(profile, true, false, false, token);
+ _currentProfileCommands.Remove(profileId);
+ });
+
+ response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_StartRequested"), profile.ServerName));
+
+ return response;
+ }
+ finally
+ {
+ if (task is null)
+ {
+ _currentProfileCommands.Remove(profileId);
+ }
+ }
+ }
+
+ private static IList UpdateServer(string channelId, string profileId, CancellationToken token)
+ {
+ if (string.IsNullOrWhiteSpace(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Update) };
+ }
+
+ // check if another command is being run against the profile
+ if (_currentProfileCommands.ContainsKey(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
+ }
+ _currentProfileCommands.Add(profileId, CommandType.Update);
+
+ ServerProfileSnapshot profile = null;
+ bool performRestart = false;
+ Task task = null;
+
+ try
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+
+ if (server is null)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
+ }
+
+ if (!server.Profile.AllowDiscordUpdate)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_CommandDisabledProfile"), CommandType.Update, profileId));
+ }
+
+ switch (server.Runtime.Status)
+ {
+ case ServerStatus.Initializing:
+ case ServerStatus.Stopping:
+ case ServerStatus.Unknown:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
+
+ case ServerStatus.Running:
+ performRestart = true;
+ break;
+
+ case ServerStatus.Updating:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), profileId));
+ }
+
+ profile = ServerProfileSnapshot.Create(server.Profile);
+ }).Wait();
+
+ List response = new List();
+
+ var app = new ServerApp(true)
+ {
+ DeleteOldServerBackupFiles = !Config.Default.AutoBackup_EnableBackup,
+ OutputLogs = false,
+ SendAlerts = true,
+ SendEmails = false,
+ ServerProcess = ServerProcessType.Update,
+ ServerStatusChangeCallback = (ServerStatus serverStatus) =>
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+ server.Runtime.UpdateServerStatus(serverStatus, true);
+ }).Wait();
+ }
+ };
+
+ task = Task.Run(() =>
+ {
+ app.PerformProfileShutdown(profile, performRestart, true, false, token);
+ _currentProfileCommands.Remove(profileId);
+ });
+
+ response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_UpdateRequested"), profile.ServerName));
+
+ return response;
+ }
+ finally
+ {
+ if (task is null)
+ {
+ _currentProfileCommands.Remove(profileId);
+ }
+ }
+ }
+ }
+}
diff --git a/src/ARKServerManager/Utils/DiscordPluginHelper.cs b/src/ARKServerManager/Utils/DiscordPluginHelper.cs
new file mode 100644
index 00000000..7ec9ee93
--- /dev/null
+++ b/src/ARKServerManager/Utils/DiscordPluginHelper.cs
@@ -0,0 +1,18 @@
+using ServerManagerTool.Lib;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace ServerManagerTool.Utils
+{
+ internal static class DiscordPluginHelper
+ {
+ public static IList FetchProfiles()
+ {
+ return ServerManager.Instance.Servers.Select(s => new ServerManagerTool.Plugin.Common.Lib.Profile()
+ {
+ ProfileName = s?.Profile?.ProfileName ?? string.Empty,
+ InstallationFolder = s?.Profile?.InstallDirectory ?? string.Empty
+ }).ToList();
+ }
+ }
+}
diff --git a/src/ARKServerManager/VersionFeed.xml b/src/ARKServerManager/VersionFeed.xml
index 4dffaeb5..50b77e95 100644
--- a/src/ARKServerManager/VersionFeed.xml
+++ b/src/ARKServerManager/VersionFeed.xml
@@ -5,7 +5,336 @@
Ark Server Manager Version Feed
This is the Ark Server Manager release version feed.
- 2021-06-19T03:00:00Z
+ 2021-12-12T00:00:00Z
+
+
+ urn:uuid:DBAFCE91-2235-4B6C-AE9B-5E4EF9FEC8F5
+ 1.1.411 (1.1.411.6)
+ 1.1.411.6
+
+ 2021-12-12T00:00:00Z
+
+
+
+ NEW
+
+
+
+ A new Discord Bot has been added to the server manager.
+ This new discord bot will allow you to send Start, Stop, Shutdown, Restart, Backup and Update commands to the server manager from within your discord client.
+ To setup the new discord bot, open the global settings and scroll down to the Discord section.
+
+ NOTE: This is long process to get the discord bot working, and I have created a forum post with detailed instructions how to do it.
+
+
+ Server Settings - Dino Section - Added MutagenLevelBoost and MutagenLevelBoostBred settings.
+ Added gamedata file for the Lost Island DLC - only contains the map name for the Map droplist - do not use until the DLC is officially released!
+
+
CHANGE
+
+
+ Global Settings - Added reset button to the Data Directory Location.
+ Server Monitor window now stores it's location.
+ fr-FR Translation file updated.
+ pt-BR Translation file updated.
+ ru-RU Translation file updated.
+ zh-CN Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:BE37B3FD-B498-4B1C-9D4D-754EA0F4A357
+ 1.1.410 (1.1.410.2)
+ 1.1.410.2
+
+ 2021-12-05T00:00:00Z
+
+
+
+ CHANGE
+
+
+ Changed some globalization key values (maps, branches, total conversions and events).
+ Changed the primitive plus gamedata header from Mods to TotalConversions.
+ Changed the way the data directory is selected and created on first startup of the server manager.
+ de-DE Translation file updated.
+ pt-BR Translation file updated.
+ ru-RU Translation file updated.
+ zh-CN Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:0B63D89E-0C36-41DE-96E7-BFB140250C02
+ 1.1.409 (1.1.409.3)
+ 1.1.409.3
+
+ 2021-12-01T00:00:00Z
+
+
+
+ NEW
+
+
+ Added the Profile ID to the top of the profile window.
+
+
CHANGE
+
+
+ Added globalization to the Main Window Start Mode setting in the Global Settings.
+ zh-CN Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:50F06456-861E-483C-82BB-6072A428C652
+ 1.1.408 (1.1.408.1)
+ 1.1.408.1
+
+ 2021-11-24T00:00:00Z
+
+
+
+ BUGFIX
+
+
+ Fixed a crashing bug when ASM closes and is unable to find the backup location to save the config settings.
+
+
NEW
+
+
+ Global Settings - added option to set the Main Window start mode - Normal, Maximized, Minimized.
+ Main Window - now stores the Left and Top positions of the window, when in Normal mode. Will restore the window position when started. Defaults to 50,50.
+
+
CHANGE
+
+
+ Fixed the steamcmd warning about 'Please use force_install_dir before login!'.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:2FF0893A-1412-4062-BF87-058F14E787FC
+ 1.1.407 (1.1.407.2)
+ 1.1.407.2
+
+ 2021-11-23T00:00:00Z
+
+
+
+ CHANGES
+
+
+ Server Status checks - a few code tweaks to the server status checks.
+ pt-BR Translation file updated.
+ zh-CN Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:CAE2A89D-B098-483C-B4D4-CFFE257C066C
+ 1.1.406 (1.1.406.1)
+ 1.1.406.1
+
+ 2021-11-20T01:00:00Z
+
+
+
+ NEW
+
+
+ Server Settings - Rules Section - added bShowCreativeMode setting.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:79020463-01A7-466D-9B4A-1B14941C9C32
+ 1.1.405 (1.1.405.1)
+ 1.1.405.1
+
+ 2021-11-20T00:00:00Z
+
+
+
+ NEW
+
+
+ Server Settings - Rules Section - added DestroyTamesOverLevelClamp setting.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:FE1BAB29-859F-4939-AC97-304772112929
+ 1.1.404 (1.1.404.1)
+ 1.1.404.1
+
+ 2021-11-14T00:00:00Z
+
+
+
+ BUGFIX
+
+
+ RCON Window - Fixed the tribe name missing from the player list.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:191D15BB-817E-407B-882A-7CF063DD79A0
+ 1.1.403 (1.1.403.1)
+ 1.1.403.1
+
+ 2021-11-11T00:00:00Z
+
+
+
+ NEW
+
+
+ Server Settings - added resizing to all the grids, so the height can be increased/decreased. The height is also remembered, so when you reopen ASM, it will size the grid correctly.
+
+
CHANGES
+
+
+ Server Settings - Supply Crate Section - Added indicator icons to each grid row, for better troubleshooting of possible issues.
+ ru-RU Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:49048180-FB6F-4D54-ACDF-6A79BF7354F8
+ 1.1.402 (1.1.402.1)
+ 1.1.402.1
+
+ 2021-09-01T00:00:00Z
+
+
+
+ CHANGES
+
+
+ ru-RU Translation file updated.
+ zh-CN Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:025F6C3D-F9D1-46A7-A0B5-680291F5B1D7
+ 1.1.401 (1.1.401.1)
+ 1.1.401.1
+
+ 2021-08-22T00:00:00Z
+
+
+
+ CHANGES
+
+
+ Ragnarok and Valguero gamedata files updated.
+ pt-BR Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:58A33D1B-6937-4092-87BE-C5DC4E0EB829
+ 1.1.400 (1.1.400.1)
+ 1.1.400.1
+
+ 2021-08-20T00:00:00Z
+
+
+
+ CHANGES
+
+
+ fr-FR Translation file updated.
+ ru-RU Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
urn:uuid:0A751BBA-54B5-40A6-AB09-C6B2539DAFE7
diff --git a/src/ARKServerManager/VersionFeedBeta.xml b/src/ARKServerManager/VersionFeedBeta.xml
index 7a6d4f28..559b5624 100644
--- a/src/ARKServerManager/VersionFeedBeta.xml
+++ b/src/ARKServerManager/VersionFeedBeta.xml
@@ -5,21 +5,106 @@
Ark Server Manager Version Feed
This is the Ark Server Manager beta version feed.
- 2021-06-19T03:00:00Z
+ 2021-12-12T00:00:00Z
- urn:uuid:C69AFC93-0532-4703-9917-0D4296CBD559
- 1.1.399 (1.1.399.3)
- 1.1.399.3
+ urn:uuid:C02D44F9-E3AA-4CA0-BF2F-110F8C83CC21
+ 1.1.411 (1.1.411.7)
+ 1.1.411.7
- 2021-06-19T03:00:00Z
+ 2021-12-12T00:00:00Z
+
+
+
+ NEW
+
+
+ Added gamedata file for the Lost Island DLC - only contains the map name for the Map droplist - do not use until the DLC is officially released!
+ Added Lost Island to the language files for translation.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:F75C6AFF-2A27-49BE-917A-7EAAACCCBF17
+ 1.1.411 (1.1.411.6)
+ 1.1.411.6
+
+ 2021-12-12T00:00:00Z
+
+
+
+ CHANGE
+
+
+ fr-FR Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:0BCB8BBA-330F-4063-8B7E-5B144589999A
+ 1.1.411 (1.1.411.5)
+ 1.1.411.5
+
+ 2021-12-10T00:00:00Z
+
+
+
+ CHANGE
+
+
+ Server Monitor window now stores it's location.
+ Reference library updates.
+ pt-BR Translation file updated.
+ ru-RU Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:7697EBD7-DEF6-422B-B9A6-D4B77F31D572
+ 1.1.411 (1.1.411.4)
+ 1.1.411.4
+
+ 2021-12-09T00:00:00Z
BUGFIX
- Server Settings - Prevent Transfer Section - Added valid check to prevent writing record if dino not selected.
+ Fixed a minor issue when clicking the data directory reset button - fringe case that I found during testing.
+
+
NEW
+
+
+ Server Settings - Dino Section - Added MutagenLevelBoost and MutagenLevelBoostBred settings.
+
+
CHANGE
+
+
+ pt-BR Translation file updated.
+ ru-RU Translation file updated.
+ zh-CN Translation file updated.
@@ -31,18 +116,18 @@
- urn:uuid:D9B9BAD5-5CAE-4A94-9229-516E8335ED34
- 1.1.399 (1.1.399.2)
- 1.1.399.2
+ urn:uuid:8290F43D-98F4-4F4D-8DD8-0A3EF5A45656
+ 1.1.411 (1.1.411.3)
+ 1.1.411.3
- 2021-06-19T01:00:00Z
+ 2021-12-08T00:00:00Z
- NEW
+ BUGFIX
- Server Settings - Prevent Transfer Section - Added new section to handle the PreventTransferForClassNames settings. This section can be enabled/disables from the global settings, if you want to management these manually.
+ Fixed language translation of Data Directory window.
@@ -54,18 +139,50 @@
- urn:uuid:0A751BBA-54B5-40A6-AB09-C6B2539DAFE7
- 1.1.399 (1.1.399.1)
- 1.1.399.1
+ urn:uuid:ADBF3FE0-017C-4E23-8FE8-EFE75E7C8BA1
+ 1.1.411 (1.1.411.2)
+ 1.1.411.2
- 2021-06-19T00:00:00Z
+ 2021-12-08T00:00:00Z
+
+
+
+ CHANGE
+
+
+ Global Settings - Added reset button to the Data Directory Location.
+ pt-BR Translation file updated.
+ zh-CN Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:DBAFCE91-2235-4B6C-AE9B-5E4EF9FEC8F5
+ 1.1.411 (1.1.411.1)
+ 1.1.411.1
+
+ 2021-12-06T00:00:00Z
NEW
- Server Settings - Rules Section - Added new Genesis: Part 2 settings, bDisableWorldBuffs, bEnableWorldBuffScaling and WorldBuffScalingEfficacy.
+
+ A new Discord Bot has been added to the server manager.
+ This new discord bot will allow you to send Start, Stop, Shutdown, Restart, Backup and Update commands to the server manager from within your discord client.
+ To setup the new discord bot, open the global settings and scroll down to the Discord section.
+
+ NOTE: This is long process to get the discord bot working, and I have created a forum post with detailed instructions how to do it.
+
+
diff --git a/src/ARKServerManager/Windows/AutoUpdateWindow.xaml b/src/ARKServerManager/Windows/AutoUpdateWindow.xaml
index 518d601f..0df8f2ca 100644
--- a/src/ARKServerManager/Windows/AutoUpdateWindow.xaml
+++ b/src/ARKServerManager/Windows/AutoUpdateWindow.xaml
@@ -1,10 +1,6 @@
diff --git a/src/ARKServerManager/Windows/CommandLineWindow.xaml b/src/ARKServerManager/Windows/CommandLineWindow.xaml
index f9832619..725807c4 100644
--- a/src/ARKServerManager/Windows/CommandLineWindow.xaml
+++ b/src/ARKServerManager/Windows/CommandLineWindow.xaml
@@ -1,10 +1,6 @@
diff --git a/src/ARKServerManager/Windows/CustomConfigDataWindow.xaml b/src/ARKServerManager/Windows/CustomConfigDataWindow.xaml
index 5432ce03..0c148ba1 100644
--- a/src/ARKServerManager/Windows/CustomConfigDataWindow.xaml
+++ b/src/ARKServerManager/Windows/CustomConfigDataWindow.xaml
@@ -1,10 +1,6 @@
diff --git a/src/ARKServerManager/Windows/DataDirectoryWindow.xaml b/src/ARKServerManager/Windows/DataDirectoryWindow.xaml
new file mode 100644
index 00000000..6a7e6bf3
--- /dev/null
+++ b/src/ARKServerManager/Windows/DataDirectoryWindow.xaml
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ARKServerManager/Windows/DataDirectoryWindow.xaml.cs b/src/ARKServerManager/Windows/DataDirectoryWindow.xaml.cs
new file mode 100644
index 00000000..ed1dd168
--- /dev/null
+++ b/src/ARKServerManager/Windows/DataDirectoryWindow.xaml.cs
@@ -0,0 +1,171 @@
+using ServerManagerTool.Common.Utils;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Windows;
+using WPFSharp.Globalizer;
+
+namespace ServerManagerTool.Windows
+{
+ ///
+ /// Interaction logic for DriveSelectionWindow.xaml
+ ///
+ public partial class DataDirectoryWindow : Window
+ {
+ private readonly GlobalizedApplication _globalizer = GlobalizedApplication.Instance;
+
+ public static readonly DependencyProperty DriveInformationProperty = DependencyProperty.Register(nameof(DriveInformation), typeof(List), typeof(DataDirectoryWindow), new PropertyMetadata(null));
+ public static readonly DependencyProperty FolderNameProperty = DependencyProperty.Register(nameof(FolderName), typeof(string), typeof(DataDirectoryWindow), new PropertyMetadata(null));
+
+ public DataDirectoryWindow()
+ {
+ InitializeComponent();
+ WindowUtils.RemoveDefaultResourceDictionary(this, Config.Default.DefaultGlobalizationFile);
+
+ PopulateDriveInformation();
+ }
+
+ public List DriveInformation
+ {
+ get { return (List)GetValue(DriveInformationProperty); }
+ set { SetValue(DriveInformationProperty, value); }
+ }
+
+ public string FolderName
+ {
+ get { return (string)GetValue(FolderNameProperty); }
+ set { SetValue(FolderNameProperty, value); }
+ }
+
+ private void PopulateDriveInformation()
+ {
+ this.FolderName = Config.Default.DefaultDataDirectoryName;
+ this.DriveInformation = DriveInfo.GetDrives().Where(d => d.IsReady && d.DriveType == DriveType.Fixed).Select(d => new DriveInfoDisplay(d)).ToList();
+
+ var installationFolder = Path.GetPathRoot(Assembly.GetEntryAssembly().Location);
+ if (!installationFolder.EndsWith(@"\"))
+ installationFolder += @"\";
+
+ foreach (var driveInfo in DriveInformation)
+ {
+ if (driveInfo.DriveInfo.RootDirectory.FullName.Equals(installationFolder))
+ {
+ this.DriveSelectionListBox.SelectedItem = driveInfo;
+ break;
+ }
+ }
+ }
+
+ private void Ok_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ var result = CreateDataDirectory();
+ if (result == MessageBoxResult.Yes)
+ {
+ MessageBox.Show(_globalizer.GetResourceString("DataDirectory_RestartLabel"), _globalizer.GetResourceString("DataDirectory_RestartTitle"), MessageBoxButton.OK, MessageBoxImage.Information);
+
+ this.DialogResult = true;
+ this.Close();
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message, _globalizer.GetResourceString("DataDirectory_ErrorTitle"));
+ }
+ }
+
+ private void Refresh_Click(object sender, RoutedEventArgs e)
+ {
+ PopulateDriveInformation();
+ }
+
+ private MessageBoxResult CreateDataDirectory()
+ {
+ var selectedDrive = this.DriveSelectionListBox.SelectedItem as DriveInfoDisplay;
+ if (selectedDrive is null)
+ {
+ return MessageBoxResult.None;
+ }
+
+ var invalidCharacters = Path.GetInvalidFileNameChars();
+ if (string.IsNullOrWhiteSpace(FolderName) || FolderName.Any(c => invalidCharacters.Contains(c)))
+ {
+ throw new Exception(_globalizer.GetResourceString("DataDirectory_FolderErrorLabel"));
+ }
+
+ var newDataFolder = Path.Combine(selectedDrive.DriveInfo.RootDirectory.FullName, FolderName);
+
+ var confirm = MessageBox.Show(string.Format(_globalizer.GetResourceString("Application_DataDirectory_ConfirmLabel"), Path.Combine(newDataFolder, Config.Default.ProfilesDir), Path.Combine(newDataFolder, Config.Default.SteamCmdDir)), _globalizer.GetResourceString("Application_DataDirectory_ConfirmTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question);
+ if (confirm == MessageBoxResult.Yes)
+ {
+ if (newDataFolder.EndsWith(@"\"))
+ newDataFolder = newDataFolder.Substring(0, newDataFolder.Length - 1);
+
+ Config.Default.DataDir = newDataFolder;
+ }
+
+ return confirm;
+ }
+ }
+
+ public class DriveInfoDisplay
+ {
+ private const decimal DIVISOR = 1024M;
+
+ // Load all suffixes in an array
+ private static readonly string[] suffixes = { "Bytes", "KB", "MB", "GB", "TB", "PB" };
+
+ private readonly GlobalizedApplication _globalizer = GlobalizedApplication.Instance;
+
+ public DriveInfoDisplay(DriveInfo driveInfo)
+ {
+ DriveInfo = driveInfo;
+ }
+
+ public DriveInfo DriveInfo
+ {
+ get;
+ set;
+ }
+
+ public string Line1
+ {
+ get
+ {
+ if (DriveInfo is null)
+ return string.Empty;
+
+ var volumeLabel = string.IsNullOrWhiteSpace(DriveInfo.VolumeLabel) ? _globalizer.GetResourceString("DataDirectory_LocalDiskLabel") : DriveInfo.VolumeLabel;
+ return $"{volumeLabel} ({DriveInfo.Name.Replace(@"\", string.Empty)})";
+ }
+ }
+
+ public string Line2
+ {
+ get
+ {
+ if (DriveInfo is null)
+ return string.Empty;
+
+ return string.Format(_globalizer.GetResourceString("DataDirectory_DriveLine2Label"), FormatSize(DriveInfo.TotalFreeSpace), FormatSize(DriveInfo.TotalSize));
+ }
+ }
+
+ public static string FormatSize(long bytes)
+ {
+ var counter = 0;
+ var number = (decimal)bytes;
+
+ while (number / DIVISOR >= 1)
+ {
+ number /= DIVISOR;
+ counter++;
+ }
+
+ return string.Format("{0:n2} {1}", number, suffixes[counter]);
+ }
+ }
+}
diff --git a/src/ARKServerManager/Windows/GameDataWindow.xaml b/src/ARKServerManager/Windows/GameDataWindow.xaml
index 6a532212..807ca961 100644
--- a/src/ARKServerManager/Windows/GameDataWindow.xaml
+++ b/src/ARKServerManager/Windows/GameDataWindow.xaml
@@ -11,18 +11,6 @@
-
-
-
-
-
-
-
-
diff --git a/src/ARKServerManager/Windows/MainWindow.xaml b/src/ARKServerManager/Windows/MainWindow.xaml
index f686aa7d..2c7bd445 100644
--- a/src/ARKServerManager/Windows/MainWindow.xaml
+++ b/src/ARKServerManager/Windows/MainWindow.xaml
@@ -2,16 +2,15 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:eo="http://schemas.essentialobjects.com/wpf/"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:tb="http://www.hardcodet.net/taskbar"
xmlns:tsk="clr-namespace:Microsoft.Win32.TaskScheduler;assembly=Microsoft.Win32.TaskScheduler"
xmlns:local="clr-namespace:ServerManagerTool"
- xmlns:cc="clr-namespace:ServerManagerTool.Common.Converters;assembly=ServerManager.Common"
+ xmlns:clib="clr-namespace:ServerManagerTool.Common.Lib;assembly=ServerManager.Common"
xmlns:cvr="clr-namespace:ServerManagerTool.Common.ValidationRules;assembly=ServerManager.Common"
xmlns:com="clr-namespace:ServerManagerTool.Common;assembly=ServerManager.Common"
- xmlns:clib="clr-namespace:ServerManagerTool.Common.Lib;assembly=ServerManager.Common"
xmlns:enum="clr-namespace:ServerManagerTool.Enums"
- xmlns:tb="http://www.hardcodet.net/taskbar"
- MinWidth="900" MinHeight="600" Width="1100" Height="900" Left="50" Top="50"
- Loaded="Window_Loaded" SizeChanged="Window_SizeChanged" StateChanged="Window_StateChanged"
+ MinWidth="900" MinHeight="600" Width="1100" Height="900" Left="50" Top="50" WindowState="Normal"
+ Loaded="MainWindow_Loaded" SizeChanged="MainWindow_SizeChanged" StateChanged="MainWindow_StateChanged" LocationChanged="MainWindow_LocationChanged"
Name="Main" Icon="../Art/favicon.ico" Title="{DynamicResource MainWindow_Title}">
@@ -19,53 +18,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/ARKServerManager/Windows/MainWindow.xaml.cs b/src/ARKServerManager/Windows/MainWindow.xaml.cs
index 0375d9c8..1b95b8ed 100644
--- a/src/ARKServerManager/Windows/MainWindow.xaml.cs
+++ b/src/ARKServerManager/Windows/MainWindow.xaml.cs
@@ -6,6 +6,7 @@ using ServerManagerTool.Common.Utils;
using ServerManagerTool.Enums;
using ServerManagerTool.Lib;
using ServerManagerTool.Plugin.Common;
+using ServerManagerTool.Utils;
using ServerManagerTool.Windows;
using System;
using System.Diagnostics;
@@ -159,14 +160,17 @@ namespace ServerManagerTool
}
}
+ this.Left = Config.Default.MainWindow_Left;
+ this.Top = Config.Default.MainWindow_Top;
this.Height = Config.Default.MainWindow_Height;
this.Width = Config.Default.MainWindow_Width;
+ this.WindowState = Config.Default.MainWindow_WindowState;
// hook into the language change event
GlobalizedApplication.Instance.GlobalizationManager.ResourceDictionaryChangedEvent += ResourceDictionaryChangedEvent;
}
- private void Window_Loaded(object sender, RoutedEventArgs e)
+ private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
//
// Kick off the initialization.
@@ -196,6 +200,32 @@ namespace ServerManagerTool
this.scheduledTaskChecker.PostAction(CheckForScheduledTasks).DoNotWait();
}
+ private void MainWindow_LocationChanged(object sender, EventArgs e)
+ {
+ if (this.WindowState == WindowState.Normal)
+ {
+ Config.Default.MainWindow_Left = Math.Max(0D, this.Left);
+ Config.Default.MainWindow_Top = Math.Max(0D, this.Top);
+ }
+ }
+
+ private void MainWindow_SizeChanged(object sender, SizeChangedEventArgs e)
+ {
+ if (this.WindowState == WindowState.Normal)
+ {
+ Config.Default.MainWindow_Height = e.NewSize.Height;
+ Config.Default.MainWindow_Width = e.NewSize.Width;
+ }
+ }
+
+ private void MainWindow_StateChanged(object sender, EventArgs e)
+ {
+ if (Config.Default.MainWindow_MinimizeToTray && this.WindowState == WindowState.Minimized)
+ {
+ this.Hide();
+ }
+ }
+
private void Window_Closed(object sender, EventArgs e)
{
if (sender is Window window)
@@ -204,37 +234,23 @@ namespace ServerManagerTool
this.Activate();
}
- private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
- {
- if (this.WindowState != WindowState.Minimized)
- {
- Config.Default.MainWindow_Height = e.NewSize.Height;
- Config.Default.MainWindow_Width = e.NewSize.Width;
- }
- }
-
- private void Window_StateChanged(object sender, EventArgs e)
- {
- if (Config.Default.MainWindow_MinimizeToTray && this.WindowState == WindowState.Minimized)
- {
- this.Hide();
- }
- }
-
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
+ if (DiscordBotHelper.HasRunningCommands)
+ {
+ var result = MessageBox.Show(_globalizer.GetResourceString("MainWindow_DiscordBot_RunningCommandsLabel"), _globalizer.GetResourceString("MainWindow_DiscordBot_RunningCommandsTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question);
+ if (result == MessageBoxResult.No)
+ {
+ e.Cancel = true;
+ return;
+ }
+ }
+
base.OnClosing(e);
RCONWindow.CloseAllWindows();
PlayerListWindow.CloseAllWindows();
ServerMonitorWindow.CloseAllWindows();
this.versionChecker.DisposeAsync().DoNotWait();
-
- var installFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
- var backupFolder = IOUtils.NormalizePath(string.IsNullOrWhiteSpace(Config.Default.BackupPath)
- ? Path.Combine(Config.Default.DataDir, Config.Default.BackupDir)
- : Path.Combine(Config.Default.BackupPath));
- SettingsUtils.BackupUserConfigSettings(Config.Default, "userconfig.json", installFolder, backupFolder);
- SettingsUtils.BackupUserConfigSettings(CommonConfig.Default, "commonconfig.json", installFolder, backupFolder);
}
private void ResourceDictionaryChangedEvent(object source, ResourceDictionaryChangedEventArgs e)
diff --git a/src/ARKServerManager/Windows/ModDetailsWindow.xaml b/src/ARKServerManager/Windows/ModDetailsWindow.xaml
index ca9a9f0b..ba109a84 100644
--- a/src/ARKServerManager/Windows/ModDetailsWindow.xaml
+++ b/src/ARKServerManager/Windows/ModDetailsWindow.xaml
@@ -1,7 +1,6 @@
-
-
-
-
-
-
-
-
diff --git a/src/ARKServerManager/Windows/OpenRCONWindow.xaml b/src/ARKServerManager/Windows/OpenRCONWindow.xaml
index 0306ff55..c8773e22 100644
--- a/src/ARKServerManager/Windows/OpenRCONWindow.xaml
+++ b/src/ARKServerManager/Windows/OpenRCONWindow.xaml
@@ -12,11 +12,6 @@
-
-
-
-
-
diff --git a/src/ARKServerManager/Windows/PlayerListWindow.xaml b/src/ARKServerManager/Windows/PlayerListWindow.xaml
index 3b3ed2d0..9d21cb5b 100644
--- a/src/ARKServerManager/Windows/PlayerListWindow.xaml
+++ b/src/ARKServerManager/Windows/PlayerListWindow.xaml
@@ -15,66 +15,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/ARKServerManager/Windows/PlayerProfileWindow.xaml b/src/ARKServerManager/Windows/PlayerProfileWindow.xaml
index 5ac759e2..97234942 100644
--- a/src/ARKServerManager/Windows/PlayerProfileWindow.xaml
+++ b/src/ARKServerManager/Windows/PlayerProfileWindow.xaml
@@ -1,7 +1,6 @@
@@ -10,77 +9,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/ARKServerManager/Windows/PluginsWindow.xaml b/src/ARKServerManager/Windows/PluginsWindow.xaml
index 985699d4..600b59f8 100644
--- a/src/ARKServerManager/Windows/PluginsWindow.xaml
+++ b/src/ARKServerManager/Windows/PluginsWindow.xaml
@@ -10,18 +10,6 @@
-
-
-
-
-
-
-
-
diff --git a/src/ARKServerManager/Windows/ProcessorAffinityWindow.xaml b/src/ARKServerManager/Windows/ProcessorAffinityWindow.xaml
index c6cb6ea4..b22ce845 100644
--- a/src/ARKServerManager/Windows/ProcessorAffinityWindow.xaml
+++ b/src/ARKServerManager/Windows/ProcessorAffinityWindow.xaml
@@ -1,7 +1,6 @@
@@ -10,8 +9,6 @@
-
-
diff --git a/src/ARKServerManager/Windows/ProgressWindow.xaml b/src/ARKServerManager/Windows/ProgressWindow.xaml
index 783905cd..9eebadf2 100644
--- a/src/ARKServerManager/Windows/ProgressWindow.xaml
+++ b/src/ARKServerManager/Windows/ProgressWindow.xaml
@@ -10,10 +10,6 @@
-
-
-
-
diff --git a/src/ARKServerManager/Windows/RCONWindow.xaml b/src/ARKServerManager/Windows/RCONWindow.xaml
index e73ade52..ce441b7c 100644
--- a/src/ARKServerManager/Windows/RCONWindow.xaml
+++ b/src/ARKServerManager/Windows/RCONWindow.xaml
@@ -20,81 +20,8 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -295,7 +222,7 @@
-
+
diff --git a/src/ARKServerManager/Windows/RCONWindow.xaml.cs b/src/ARKServerManager/Windows/RCONWindow.xaml.cs
index 05ef0af8..e2ec9fbf 100644
--- a/src/ARKServerManager/Windows/RCONWindow.xaml.cs
+++ b/src/ARKServerManager/Windows/RCONWindow.xaml.cs
@@ -664,7 +664,7 @@ namespace ServerManagerTool
ProfileId = server.Runtime.ProfileSnapshot.ProfileId,
ProfileName = server.Runtime.ProfileSnapshot.ProfileName,
MaxPlayers = server.Runtime.MaxPlayers,
- RCONHost = server.Runtime.ProfileSnapshot.ServerIP,
+ RCONHost = server.Runtime.ProfileSnapshot.ServerIPAddress.ToString(),
RCONPort = server.Runtime.ProfileSnapshot.RCONPort,
PGM_Enabled = server.Profile.PGM_Enabled,
diff --git a/src/ARKServerManager/Windows/ServerMonitorWindow.xaml b/src/ARKServerManager/Windows/ServerMonitorWindow.xaml
index e89e04f5..d2791ff9 100644
--- a/src/ARKServerManager/Windows/ServerMonitorWindow.xaml
+++ b/src/ARKServerManager/Windows/ServerMonitorWindow.xaml
@@ -3,15 +3,14 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:cc="clr-namespace:ServerManagerTool.Common.Converters;assembly=ServerManager.Common"
- xmlns:com="clr-namespace:ServerManagerTool.Common;assembly=ServerManager.Common"
+ xmlns:tb="http://www.hardcodet.net/taskbar"
xmlns:clib="clr-namespace:ServerManagerTool.Common.Lib;assembly=ServerManager.Common"
+ xmlns:com="clr-namespace:ServerManagerTool.Common;assembly=ServerManager.Common"
xmlns:enum="clr-namespace:ServerManagerTool.Enums"
xmlns:vm="clr-namespace:ServerManagerTool.Lib.ViewModel"
- xmlns:tb="http://www.hardcodet.net/taskbar"
mc:Ignorable="d"
MinWidth="600" MinHeight="500" Width="900" Height="500" Left="50" Top="50" ResizeMode="CanResize"
- Loaded="Window_Loaded" SizeChanged="Window_SizeChanged" StateChanged="Window_StateChanged"
+ Loaded="ServerMonitorWindow_Loaded" SizeChanged="ServerMonitorWindow_SizeChanged" StateChanged="ServerMonitorWindow_StateChanged" LocationChanged="ServerMonitorWindow_LocationChanged"
Name="ServerMonitorUI" Icon="../Art/favicon.ico" Title="{DynamicResource ServerMonitor_Title}">
@@ -19,17 +18,8 @@
-
-
-
-
+
-
-
-
-
-
-
diff --git a/src/ARKServerManager/Windows/ServerMonitorWindow.xaml.cs b/src/ARKServerManager/Windows/ServerMonitorWindow.xaml.cs
index 6e141131..887b909e 100644
--- a/src/ARKServerManager/Windows/ServerMonitorWindow.xaml.cs
+++ b/src/ARKServerManager/Windows/ServerMonitorWindow.xaml.cs
@@ -53,6 +53,8 @@ namespace ServerManagerTool.Windows
SetWindowTitle();
+ this.Left = Config.Default.ServerMonitorWindow_Left;
+ this.Top = Config.Default.ServerMonitorWindow_Top;
this.Height = Config.Default.ServerMonitorWindow_Height;
this.Width = Config.Default.ServerMonitorWindow_Width;
@@ -86,7 +88,7 @@ namespace ServerManagerTool.Windows
set { SetValue(IsStandAloneWindowProperty, value); }
}
- private void Window_Loaded(object sender, RoutedEventArgs e)
+ private void ServerMonitorWindow_Loaded(object sender, RoutedEventArgs e)
{
if (ServerManager == null)
{
@@ -120,12 +122,16 @@ namespace ServerManagerTool.Windows
}
}
- private void Window_Closed(object sender, EventArgs e)
+ private void ServerMonitorWindow_LocationChanged(object sender, EventArgs e)
{
- this.Activate();
+ if (this.WindowState == WindowState.Normal)
+ {
+ Config.Default.ServerMonitorWindow_Left = Math.Max(0D, this.Left);
+ Config.Default.ServerMonitorWindow_Top = Math.Max(0D, this.Top);
+ }
}
- private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
+ private void ServerMonitorWindow_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (this.WindowState != WindowState.Minimized)
{
@@ -134,7 +140,7 @@ namespace ServerManagerTool.Windows
}
}
- private void Window_StateChanged(object sender, EventArgs e)
+ private void ServerMonitorWindow_StateChanged(object sender, EventArgs e)
{
if (IsStandAloneWindow && Config.Default.MainWindow_MinimizeToTray && this.WindowState == WindowState.Minimized)
{
@@ -142,6 +148,11 @@ namespace ServerManagerTool.Windows
}
}
+ private void Window_Closed(object sender, EventArgs e)
+ {
+ this.Activate();
+ }
+
protected override void OnClosing(CancelEventArgs e)
{
if (this.OwnedWindows.OfType().Any())
@@ -182,7 +193,7 @@ namespace ServerManagerTool.Windows
var profile = ServerProfileSnapshot.Create(server.Profile);
- var exitCode = await Task.Run(() => app.PerformProfileBackup(profile));
+ var exitCode = await Task.Run(() => app.PerformProfileBackup(profile, CancellationToken.None));
if (exitCode != ServerApp.EXITCODE_NORMALEXIT && exitCode != ServerApp.EXITCODE_CANCELLED)
{
throw new ApplicationException($"An error occured during the backup process - ExitCode: {exitCode}");
@@ -623,7 +634,7 @@ namespace ServerManagerTool.Windows
await Task.Delay(1000);
- var branch = new ServerBranchSnapshot() { BranchName = serverProfile.BranchName, BranchPassword = serverProfile.BranchPassword };
+ var branch = BranchSnapshot.Create(serverProfile);
return await server.UpgradeAsync(_upgradeCancellationSource.Token, updateServer, branch, true, updateMods, (p, m, n) => { TaskUtils.RunOnUIThreadAsync(() => { window?.AddMessage(m, n); }).DoNotWait(); });
}
else
diff --git a/src/ARKServerManager/Windows/SettingsWindow.xaml b/src/ARKServerManager/Windows/SettingsWindow.xaml
index 5f4b0520..19e1b951 100644
--- a/src/ARKServerManager/Windows/SettingsWindow.xaml
+++ b/src/ARKServerManager/Windows/SettingsWindow.xaml
@@ -13,10 +13,6 @@
-
-
-
-
diff --git a/src/ARKServerManager/Windows/SettingsWindow.xaml.cs b/src/ARKServerManager/Windows/SettingsWindow.xaml.cs
index 0cb7b676..58c918b6 100644
--- a/src/ARKServerManager/Windows/SettingsWindow.xaml.cs
+++ b/src/ARKServerManager/Windows/SettingsWindow.xaml.cs
@@ -1,5 +1,4 @@
-using ServerManagerTool.Common;
-using ServerManagerTool.Common.Utils;
+using ServerManagerTool.Common.Utils;
using System;
using System.IO;
using System.Reflection;
@@ -84,11 +83,7 @@ namespace ServerManagerTool
Config.Default.SteamCmd_UseAnonymousCredentials = true;
}
- Config.Default.Save();
- CommonConfig.Default.Save();
-
- Config.Default.Reload();
- CommonConfig.Default.Reload();
+ App.SaveConfigFiles(false);
base.OnClosed(e);
}
diff --git a/src/ARKServerManager/Windows/ShutdownWindow.xaml b/src/ARKServerManager/Windows/ShutdownWindow.xaml
index 56f20237..8348c0e3 100644
--- a/src/ARKServerManager/Windows/ShutdownWindow.xaml
+++ b/src/ARKServerManager/Windows/ShutdownWindow.xaml
@@ -2,8 +2,6 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cctl="clr-namespace:ServerManagerTool.Common.Controls;assembly=ServerManager.Common"
- xmlns:cc="clr-namespace:ServerManagerTool.Common.Converters;assembly=ServerManager.Common"
- xmlns:com="clr-namespace:ServerManagerTool.Common;assembly=ServerManager.Common"
xmlns:en="clr-namespace:ServerManagerTool.Enums"
Width="600" ResizeMode="CanMinimize" SizeToContent="Height" WindowStyle="SingleBorderWindow" WindowStartupLocation="CenterOwner" ShowInTaskbar="True"
Closing="Window_Closing" Closed="Window_Closed"
@@ -14,49 +12,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -220,7 +175,7 @@
-
diff --git a/src/ARKServerManager/Windows/VersionFeedWindow.xaml b/src/ARKServerManager/Windows/VersionFeedWindow.xaml
index 64303492..af9fed0f 100644
--- a/src/ARKServerManager/Windows/VersionFeedWindow.xaml
+++ b/src/ARKServerManager/Windows/VersionFeedWindow.xaml
@@ -13,18 +13,6 @@
-
-
diff --git a/src/ARKServerManager/Windows/WorkshopFilesWindow.xaml b/src/ARKServerManager/Windows/WorkshopFilesWindow.xaml
index 87fb8dda..81f8b512 100644
--- a/src/ARKServerManager/Windows/WorkshopFilesWindow.xaml
+++ b/src/ARKServerManager/Windows/WorkshopFilesWindow.xaml
@@ -10,11 +10,6 @@
-
-
-
-
-
diff --git a/src/ARKServerManager/Windows/WorldSaveRestoreWindow.xaml b/src/ARKServerManager/Windows/WorldSaveRestoreWindow.xaml
index 37409409..fe28e951 100644
--- a/src/ARKServerManager/Windows/WorldSaveRestoreWindow.xaml
+++ b/src/ARKServerManager/Windows/WorldSaveRestoreWindow.xaml
@@ -11,11 +11,6 @@
-
-
-
-
-
diff --git a/src/ArkData/ArkData.csproj b/src/ArkData/ArkData.csproj
index ba820ea8..1482b2c3 100644
--- a/src/ArkData/ArkData.csproj
+++ b/src/ArkData/ArkData.csproj
@@ -1,9 +1,5 @@
- %24/Development/ServerManagers/Main/ArkData
- {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- https://dev.azure.com/bretthewitson
- .
Debug;Release;Debug - Beta
diff --git a/src/ArkData/Properties/AssemblyInfo.cs b/src/ArkData/Properties/AssemblyInfo.cs
index a266db5a..c715c7ac 100644
--- a/src/ArkData/Properties/AssemblyInfo.cs
+++ b/src/ArkData/Properties/AssemblyInfo.cs
@@ -1,35 +1,19 @@
using System.Reflection;
using System.Runtime.InteropServices;
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
[assembly: AssemblyTitle("ArkData SDK")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("AuthiQ")]
+[assembly: AssemblyCompany("AuthiQ, Bletch1971")]
[assembly: AssemblyProduct("ArkData SDK")]
-[assembly: AssemblyCopyright("Copyright © 2015")]
+[assembly: AssemblyCopyright("Copyright © 2015-2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(true)]
-// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("d2ee1483-021f-4900-bbe8-88338d1386f4")]
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.3.0")]
+// exclude from semantic versioning
+[assembly: AssemblyVersion("1.0")]
[assembly: AssemblyFileVersion("1.0.3.0")]
diff --git a/src/ConanData/ConanData.csproj b/src/ConanData/ConanData.csproj
index 8ee79662..431ddf30 100644
--- a/src/ConanData/ConanData.csproj
+++ b/src/ConanData/ConanData.csproj
@@ -1,9 +1,5 @@
- %24/Development/ServerManagers/Main/ConanData
- {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- https://dev.azure.com/bretthewitson
- .
Debug;Release;Debug - Beta
diff --git a/src/ConanData/Properties/AssemblyInfo.cs b/src/ConanData/Properties/AssemblyInfo.cs
index 5b490187..99ad74df 100644
--- a/src/ConanData/Properties/AssemblyInfo.cs
+++ b/src/ConanData/Properties/AssemblyInfo.cs
@@ -1,35 +1,19 @@
using System.Reflection;
using System.Runtime.InteropServices;
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
[assembly: AssemblyTitle("ConanData SDK")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Bletch1971")]
[assembly: AssemblyProduct("ConanData SDK")]
-[assembly: AssemblyCopyright("Copyright © 2018")]
+[assembly: AssemblyCopyright("Copyright © 2015-2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
-// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("96832688-29bd-464f-9dce-482e37bfc751")]
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
+// include semantic versioning - ConanServerManager
+[assembly: AssemblyVersion("1.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/ConanServerManager.Common/ConanServerManager.Common.csproj b/src/ConanServerManager.Common/ConanServerManager.Common.csproj
index 366ceca7..f932d07f 100644
--- a/src/ConanServerManager.Common/ConanServerManager.Common.csproj
+++ b/src/ConanServerManager.Common/ConanServerManager.Common.csproj
@@ -1,9 +1,5 @@
- %24/Development/ServerManagers/Main/ConanServerManager.Common
- {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- https://dev.azure.com/bretthewitson
- .
Debug;Release;Debug - Beta
@@ -15,14 +11,6 @@
none
false
-
-
-
-
-
-
-
-
diff --git a/src/ConanServerManager.Common/Properties/AssemblyInfo.cs b/src/ConanServerManager.Common/Properties/AssemblyInfo.cs
index fd9723cc..9f88930f 100644
--- a/src/ConanServerManager.Common/Properties/AssemblyInfo.cs
+++ b/src/ConanServerManager.Common/Properties/AssemblyInfo.cs
@@ -1,35 +1,19 @@
using System.Reflection;
using System.Runtime.InteropServices;
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
[assembly: AssemblyTitle("ConanServerManager Common Library")]
[assembly: AssemblyDescription("The library is used to provide common functionality to the conan server manager.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Bletch1971")]
[assembly: AssemblyProduct("Server Managers")]
-[assembly: AssemblyCopyright("Copyright © 2015-2020")]
+[assembly: AssemblyCopyright("Copyright © 2015-2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
-// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("630422ca-4bcc-4d1d-9701-87d8eaf0b209")]
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
+// include semantic versioning - ConanServerManager
[assembly: AssemblyVersion("1.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/ConanServerManager/App.config b/src/ConanServerManager/App.config
index 14b4dcec..bd610257 100644
--- a/src/ConanServerManager/App.config
+++ b/src/ConanServerManager/App.config
@@ -18,7 +18,7 @@
- +login {0} +force_install_dir "{1}" "+app_update {2} {3} {4}" +quit
+ +force_install_dir "{1}" +login {0} "+app_update {2} {3} {4}" +quit
Servers
@@ -132,7 +132,7 @@
server
-
+ https://servermanagers.azurewebsites.net/api/server/{0}/{1}/{2}/{3}
_backup_
@@ -168,7 +168,7 @@
https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=bletch1971%40hotmail%2ecom&lc=US&item_name=Server%20Manager¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted
- F2653C3D-BC83-440A-AD99-FD9D9466DE04
+ 03F9106D-2B7B-411A-B533-FB641C44218D
.zip
@@ -254,6 +254,15 @@
120000
+
+ csmdata
+
+
+ https://discord.com/developers/applications
+
+
+ https://servermanagers.freeforums.net/thread/99/get-own-discord-bot
+
@@ -552,6 +561,60 @@
True
+
+ 50
+
+
+ 50
+
+
+ Normal
+
+
+ 100
+
+
+ 250
+
+
+ False
+
+
+ csm
+
+
+
+
+
+
+
+
+ False
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ 50
+
+
+ 50
+
\ No newline at end of file
diff --git a/src/ConanServerManager/App.xaml.cs b/src/ConanServerManager/App.xaml.cs
index 5cc01d4b..f5ab9594 100644
--- a/src/ConanServerManager/App.xaml.cs
+++ b/src/ConanServerManager/App.xaml.cs
@@ -1,15 +1,15 @@
-using Microsoft.WindowsAPICodePack.Dialogs;
-using NLog;
+using NLog;
using NLog.Config;
using NLog.Targets;
using ServerManagerTool.Common;
using ServerManagerTool.Common.Utils;
+using ServerManagerTool.DiscordBot;
using ServerManagerTool.Enums;
using ServerManagerTool.Lib;
using ServerManagerTool.Plugin.Common;
+using ServerManagerTool.Utils;
using ServerManagerTool.Windows;
using System;
-using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
@@ -17,6 +17,7 @@ using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
+using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using WPFSharp.Globalizer;
@@ -36,6 +37,7 @@ namespace ServerManagerTool
public event PropertyChangedEventHandler PropertyChanged;
+ private CancellationTokenSource _tokenSource;
private GlobalizedApplication _globalizer;
private bool _applicationStarted;
private string _args;
@@ -174,11 +176,6 @@ namespace ServerManagerTool
}
}
- private IList FetchProfiles()
- {
- return ServerManager.Instance.Servers.Select(s => new ServerManagerTool.Plugin.Common.Lib.Profile() { ProfileName = s?.Profile?.ProfileName ?? string.Empty, InstallationFolder = s?.Profile?.InstallDirectory ?? string.Empty }).ToList();
- }
-
public static string GetLogFolder() => IOUtils.NormalizePath(Path.Combine(Config.Default.DataPath, Config.Default.LogsRelativePath));
public static string GetProfileLogFolder(string profileId) => IOUtils.NormalizePath(Path.Combine(Config.Default.DataPath, Config.Default.LogsRelativePath, profileId.ToLower()));
@@ -303,7 +300,8 @@ namespace ServerManagerTool
var installPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
PluginHelper.Instance.BetaEnabled = this.BetaVersion;
PluginHelper.Instance.LoadPlugins(installPath, true);
- PluginHelper.Instance.SetFetchProfileCallback(FetchProfiles);
+ PluginHelper.Instance.SetFetchProfileCallback(DiscordPluginHelper.FetchProfiles);
+ OnResourceDictionaryChanged(Thread.CurrentThread.CurrentCulture.Name);
// check if we are starting server manager for server shutdown
if (e.Args.Any(a => a.StartsWith(Constants.ARG_AUTOSHUTDOWN1, StringComparison.OrdinalIgnoreCase)))
@@ -393,68 +391,29 @@ namespace ServerManagerTool
this.ApplicationStarted = true;
- // Initial configuration setting
- if (String.IsNullOrWhiteSpace(Config.Default.DataPath))
+ var restartRequired = false;
+ if (string.IsNullOrWhiteSpace(Config.Default.DataPath))
{
- MessageBox.Show(_globalizer.GetResourceString("Application_DataDirectoryLabel"), _globalizer.GetResourceString("Application_DataDirectoryTitle"), MessageBoxButton.OK, MessageBoxImage.Information);
+ var dataDirectoryWindow = new DataDirectoryWindow();
+ dataDirectoryWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;
+ var result = dataDirectoryWindow.ShowDialog();
- var installationFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
- if (!installationFolder.EndsWith(@"\"))
- installationFolder += @"\";
-
- while (String.IsNullOrWhiteSpace(Config.Default.DataPath))
+ if (!result.HasValue || !result.Value)
{
- var dialog = new CommonOpenFileDialog
- {
- EnsureFileExists = true,
- IsFolderPicker = true,
- Multiselect = false,
- Title = _globalizer.GetResourceString("Application_DataDirectory_DialogTitle"),
- InitialDirectory = installationFolder
- };
-
- if (dialog.ShowDialog() != CommonFileDialogResult.Ok)
- {
- Environment.Exit(0);
- }
-
- MessageBoxResult confirm = MessageBoxResult.Cancel;
-
- // check if the folder is under the installation folder
- var newDataFolder = dialog.FileName;
- if (!newDataFolder.EndsWith(@"\"))
- newDataFolder += @"\";
-
- if (newDataFolder.StartsWith(installationFolder))
- {
- confirm = MessageBoxResult.No;
- MessageBox.Show(_globalizer.GetResourceString("Application_DataDirectory_WithinInstallFolderErrorLabel"), _globalizer.GetResourceString("Application_DataDirectory_WithinInstallFolderErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error);
- }
- else
- {
- confirm = MessageBox.Show(String.Format(_globalizer.GetResourceString("Application_DataDirectory_ConfirmLabel"), Path.Combine(newDataFolder, Config.Default.ProfilesRelativePath), Path.Combine(newDataFolder, CommonConfig.Default.SteamCmdRelativePath)), _globalizer.GetResourceString("Application_DataDirectory_ConfirmTitle"), MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
- }
-
- if (confirm == MessageBoxResult.Cancel)
- {
- Environment.Exit(0);
- }
- else if (confirm == MessageBoxResult.Yes)
- {
- if (newDataFolder.EndsWith(@"\"))
- newDataFolder = newDataFolder.Substring(0, newDataFolder.Length - 1);
-
- Config.Default.DataPath = newDataFolder;
- ReconfigureLogging();
- break;
- }
+ Environment.Exit(0);
}
+
+ restartRequired = true;
}
Config.Default.ConfigPath = Path.Combine(Config.Default.DataPath, Config.Default.ProfilesRelativePath);
System.IO.Directory.CreateDirectory(Config.Default.ConfigPath);
- Config.Default.Save();
- CommonConfig.Default.Save();
+ SaveConfigFiles();
+
+ if (restartRequired)
+ {
+ Environment.Exit(0);
+ }
if (e.Args.Any(a => a.StartsWith(Constants.ARG_SERVERMONITOR, StringComparison.OrdinalIgnoreCase)))
{
@@ -470,6 +429,25 @@ namespace ServerManagerTool
StartupUri = new Uri("Windows/AutoUpdateWindow.xaml", UriKind.RelativeOrAbsolute);
}
+
+ if (Config.Default.DiscordBotEnabled)
+ {
+ _tokenSource = new CancellationTokenSource();
+
+ Task discordTask = Task.Run(async () =>
+ {
+ await ServerManagerBotFactory.GetServerManagerBot()?.StartAsync(Config.Default.DiscordBotToken,Config.Default.DiscordBotPrefix, Config.Default.DataPath, DiscordBotHelper.HandleDiscordCommand, DiscordBotHelper.HandleTranslation, _tokenSource.Token);
+ }, _tokenSource.Token)
+ .ContinueWith(t => {
+ var message = t.Exception.InnerException is null ? t.Exception.Message : t.Exception.InnerException.Message;
+ if (message.StartsWith("#"))
+ {
+ message = _globalizer.GetResourceString(message.Substring(1)) ?? message.Substring(1);
+ }
+
+ MessageBox.Show(message, _globalizer.GetResourceString("DiscordBot_ErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error);
+ }, TaskContinuationOptions.OnlyOnFaulted);
+ }
}
protected override void OnExit(ExitEventArgs e)
@@ -484,6 +462,11 @@ namespace ServerManagerTool
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
+ public void OnResourceDictionaryChanged(string languageCode)
+ {
+ PluginHelper.Instance.OnResourceDictionaryChanged(languageCode);
+ }
+
public static void ReconfigureLogging()
{
string logDir = Path.Combine(Config.Default.DataPath, Config.Default.LogsRelativePath);
@@ -505,6 +488,12 @@ namespace ServerManagerTool
private void ShutDownApplication()
{
+ if (!(_tokenSource is null))
+ {
+ _tokenSource.Cancel();
+ _tokenSource.Dispose();
+ }
+
if (this.ApplicationStarted)
{
foreach (var server in ServerManager.Instance.Servers)
@@ -518,13 +507,31 @@ namespace ServerManagerTool
MessageBox.Show(String.Format(_globalizer.GetResourceString("Application_Profile_SaveFailedLabel"), server.Profile.ProfileName, ex.Message, ex.StackTrace), _globalizer.GetResourceString("Application_Profile_SaveFailedTitle"), MessageBoxButton.OK, MessageBoxImage.Error);
}
}
- Config.Default.Save();
- CommonConfig.Default.Save();
+ App.SaveConfigFiles();
}
PluginHelper.Instance?.Dispose();
this.ApplicationStarted = false;
}
+
+ public static void SaveConfigFiles(bool includeBackup = true)
+ {
+ Config.Default.Save();
+ CommonConfig.Default.Save();
+
+ Config.Default.Reload();
+ CommonConfig.Default.Reload();
+
+ var installFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ var backupFolder = includeBackup
+ ? IOUtils.NormalizePath(string.IsNullOrWhiteSpace(Config.Default.BackupPath)
+ ? Path.Combine(Config.Default.DataPath, Config.Default.BackupRelativePath)
+ : Path.Combine(Config.Default.BackupPath))
+ : null;
+
+ SettingsUtils.BackupUserConfigSettings(Config.Default, "userconfig.json", installFolder, backupFolder);
+ SettingsUtils.BackupUserConfigSettings(CommonConfig.Default, "commonconfig.json", installFolder, backupFolder);
+ }
}
}
diff --git a/src/ConanServerManager/ConanServerManager.csproj b/src/ConanServerManager/ConanServerManager.csproj
index d364d700..f9e040b3 100644
--- a/src/ConanServerManager/ConanServerManager.csproj
+++ b/src/ConanServerManager/ConanServerManager.csproj
@@ -37,7 +37,7 @@
Server Managers
false
1
- 1.1.51.%2a
+ 1.1.0.%2a
false
true
false
@@ -160,6 +160,7 @@
MSBuild:Compile
Designer
+
@@ -171,6 +172,8 @@
+
+
AddUserWindow.xaml
@@ -180,10 +183,13 @@
CommandLineWindow.xaml
+
+ DataDirectoryWindow.xaml
+
GameDataWindow.xaml
-
+
GlobalSettingsControl.xaml
@@ -216,7 +222,7 @@
ServerMonitorWindow.xaml
-
+
ServerSettingsControl.xaml
@@ -305,11 +311,15 @@
MSBuild:Compile
Designer
+
+ MSBuild:Compile
+ Designer
+
MSBuild:Compile
Designer
-
+
MSBuild:Compile
Designer
@@ -353,7 +363,7 @@
MSBuild:Compile
Designer
-
+
MSBuild:Compile
Designer
@@ -576,6 +586,10 @@
{7c99d9f7-0c65-4116-927a-94eb018c88fd}
ServerManager.Common
+
+ {c4c8000d-5e45-497c-a218-b95a1567010e}
+ ServerManager.Discord
+
{3e0c9ee6-780f-4fef-ba03-e38062a5fdb6}
ServerManager.Updater
diff --git a/src/ConanServerManager/Config.Designer.cs b/src/ConanServerManager/Config.Designer.cs
index 278d26ca..994ba21a 100644
--- a/src/ConanServerManager/Config.Designer.cs
+++ b/src/ConanServerManager/Config.Designer.cs
@@ -12,7 +12,7 @@ namespace ServerManagerTool {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.0.3.0")]
public sealed partial class Config : global::System.Configuration.ApplicationSettingsBase {
private static Config defaultInstance = ((Config)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Config())));
@@ -37,7 +37,7 @@ namespace ServerManagerTool {
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("+login {0} +force_install_dir \"{1}\" \"+app_update {2} {3} {4}\" +quit")]
+ [global::System.Configuration.DefaultSettingValueAttribute("+force_install_dir \"{1}\" +login {0} \"+app_update {2} {3} {4}\" +quit")]
public string SteamCmdInstallServerArgsFormat {
get {
return ((string)(this["SteamCmdInstallServerArgsFormat"]));
@@ -877,7 +877,7 @@ namespace ServerManagerTool {
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("")]
+ [global::System.Configuration.DefaultSettingValueAttribute("https://servermanagers.azurewebsites.net/api/server/{0}/{1}/{2}/{3}")]
public string ServerStatusUrlFormat {
get {
return ((string)(this["ServerStatusUrlFormat"]));
@@ -1264,7 +1264,7 @@ namespace ServerManagerTool {
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("F2653C3D-BC83-440A-AD99-FD9D9466DE04")]
+ [global::System.Configuration.DefaultSettingValueAttribute("03F9106D-2B7B-411A-B533-FB641C44218D")]
public string ServerManagerCode {
get {
return ((string)(this["ServerManagerCode"]));
@@ -1896,5 +1896,248 @@ namespace ServerManagerTool {
this["ManagePublicIPAutomatically"] = value;
}
}
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("50")]
+ public double MainWindow_Left {
+ get {
+ return ((double)(this["MainWindow_Left"]));
+ }
+ set {
+ this["MainWindow_Left"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("50")]
+ public double MainWindow_Top {
+ get {
+ return ((double)(this["MainWindow_Top"]));
+ }
+ set {
+ this["MainWindow_Top"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("Normal")]
+ public global::System.Windows.WindowState MainWindow_WindowState {
+ get {
+ return ((global::System.Windows.WindowState)(this["MainWindow_WindowState"]));
+ }
+ set {
+ this["MainWindow_WindowState"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("100")]
+ public global::System.Windows.GridLength MOTDHeight {
+ get {
+ return ((global::System.Windows.GridLength)(this["MOTDHeight"]));
+ }
+ set {
+ this["MOTDHeight"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("250")]
+ public global::System.Windows.GridLength ServerFilesGridHeight {
+ get {
+ return ((global::System.Windows.GridLength)(this["ServerFilesGridHeight"]));
+ }
+ set {
+ this["ServerFilesGridHeight"] = value;
+ }
+ }
+
+ [global::System.Configuration.ApplicationScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("csmdata")]
+ public string DefaultDataDirectoryName {
+ get {
+ return ((string)(this["DefaultDataDirectoryName"]));
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool DiscordBotEnabled {
+ get {
+ return ((bool)(this["DiscordBotEnabled"]));
+ }
+ set {
+ this["DiscordBotEnabled"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("csm")]
+ public string DiscordBotPrefix {
+ get {
+ return ((string)(this["DiscordBotPrefix"]));
+ }
+ set {
+ this["DiscordBotPrefix"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("")]
+ public string DiscordBotToken {
+ get {
+ return ((string)(this["DiscordBotToken"]));
+ }
+ set {
+ this["DiscordBotToken"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("")]
+ public string DiscordBotServerId {
+ get {
+ return ((string)(this["DiscordBotServerId"]));
+ }
+ set {
+ this["DiscordBotServerId"] = value;
+ }
+ }
+
+ [global::System.Configuration.ApplicationScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("https://discord.com/developers/applications")]
+ public string DiscordBotApplyUrl {
+ get {
+ return ((string)(this["DiscordBotApplyUrl"]));
+ }
+ }
+
+ [global::System.Configuration.ApplicationScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("https://servermanagers.freeforums.net/thread/99/get-own-discord-bot")]
+ public string DiscordBotHelpUrl {
+ get {
+ return ((string)(this["DiscordBotHelpUrl"]));
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool SectionDiscordBotIsExpanded {
+ get {
+ return ((bool)(this["SectionDiscordBotIsExpanded"]));
+ }
+ set {
+ this["SectionDiscordBotIsExpanded"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool AllowDiscordBackup {
+ get {
+ return ((bool)(this["AllowDiscordBackup"]));
+ }
+ set {
+ this["AllowDiscordBackup"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool AllowDiscordUpdate {
+ get {
+ return ((bool)(this["AllowDiscordUpdate"]));
+ }
+ set {
+ this["AllowDiscordUpdate"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool AllowDiscordStart {
+ get {
+ return ((bool)(this["AllowDiscordStart"]));
+ }
+ set {
+ this["AllowDiscordStart"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool AllowDiscordRestart {
+ get {
+ return ((bool)(this["AllowDiscordRestart"]));
+ }
+ set {
+ this["AllowDiscordRestart"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool AllowDiscordShutdown {
+ get {
+ return ((bool)(this["AllowDiscordShutdown"]));
+ }
+ set {
+ this["AllowDiscordShutdown"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool AllowDiscordStop {
+ get {
+ return ((bool)(this["AllowDiscordStop"]));
+ }
+ set {
+ this["AllowDiscordStop"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("50")]
+ public double ServerMonitorWindow_Left {
+ get {
+ return ((double)(this["ServerMonitorWindow_Left"]));
+ }
+ set {
+ this["ServerMonitorWindow_Left"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("50")]
+ public double ServerMonitorWindow_Top {
+ get {
+ return ((double)(this["ServerMonitorWindow_Top"]));
+ }
+ set {
+ this["ServerMonitorWindow_Top"] = value;
+ }
+ }
}
}
diff --git a/src/ConanServerManager/Config.settings b/src/ConanServerManager/Config.settings
index c6139d3c..90cf58e4 100644
--- a/src/ConanServerManager/Config.settings
+++ b/src/ConanServerManager/Config.settings
@@ -6,7 +6,7 @@
- +login {0} +force_install_dir "{1}" "+app_update {2} {3} {4}" +quit
+ +force_install_dir "{1}" +login {0} "+app_update {2} {3} {4}" +quit
Servers
@@ -243,7 +243,7 @@
server
-
+ https://servermanagers.azurewebsites.net/api/server/{0}/{1}/{2}/{3}
_backup_
@@ -348,7 +348,7 @@
https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=bletch1971%40hotmail%2ecom&lc=US&item_name=Server%20Manager¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted
- F2653C3D-BC83-440A-AD99-FD9D9466DE04
+ 03F9106D-2B7B-411A-B533-FB641C44218D
.zip
@@ -527,5 +527,68 @@
True
+
+ 50
+
+
+ 50
+
+
+ Normal
+
+
+ 100
+
+
+ 250
+
+
+ csmdata
+
+
+ False
+
+
+ csm
+
+
+
+
+
+
+
+
+ https://discord.com/developers/applications
+
+
+ https://servermanagers.freeforums.net/thread/99/get-own-discord-bot
+
+
+ False
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ 50
+
+
+ 50
+
\ No newline at end of file
diff --git a/src/ConanServerManager/Delegates/ServerStatusChangeDelegate.cs b/src/ConanServerManager/Delegates/ServerStatusChangeDelegate.cs
new file mode 100644
index 00000000..c7ab834a
--- /dev/null
+++ b/src/ConanServerManager/Delegates/ServerStatusChangeDelegate.cs
@@ -0,0 +1,6 @@
+using ServerManagerTool.Enums;
+
+namespace ServerManagerTool.Delegates
+{
+ public delegate void ServerStatusChangeDelegate(ServerStatus serverStatus);
+}
diff --git a/src/ConanServerManager/Enums/AvailabilityStatus.cs b/src/ConanServerManager/Enums/AvailabilityStatus.cs
index f2588330..81846709 100644
--- a/src/ConanServerManager/Enums/AvailabilityStatus.cs
+++ b/src/ConanServerManager/Enums/AvailabilityStatus.cs
@@ -3,9 +3,9 @@
public enum AvailabilityStatus
{
Unknown,
- NeedPublicIP,
+ SetPublicIP,
Unavailable,
- WaitingForPublication,
+ Waiting,
Available
}
}
diff --git a/src/ConanServerManager/Enums/ServerProcessType.cs b/src/ConanServerManager/Enums/ServerProcessType.cs
index 861e2081..7298dfd9 100644
--- a/src/ConanServerManager/Enums/ServerProcessType.cs
+++ b/src/ConanServerManager/Enums/ServerProcessType.cs
@@ -10,5 +10,6 @@
Backup,
Shutdown,
Restart,
+ Update,
}
}
diff --git a/src/ConanServerManager/Globalization/en-US/en-US.xaml b/src/ConanServerManager/Globalization/en-US/en-US.xaml
index 2b51a4ab..1a4dddf1 100644
--- a/src/ConanServerManager/Globalization/en-US/en-US.xaml
+++ b/src/ConanServerManager/Globalization/en-US/en-US.xaml
@@ -13,6 +13,15 @@
Error
+
+ The Exiled Lands
+ Isle of Siptah
+
+
+
+ Live
+
+
Unknown
Not Downloaded
@@ -26,10 +35,6 @@
Unknown
-
- Live
-
-
Europe
North America
@@ -39,11 +44,6 @@
Japan
-
- The Exiled Lands
- Isle of Siptah
-
-
Low
Below Normal
@@ -57,6 +57,12 @@
All
+
+ Normal
+ Minimized
+ Maximized
+
+
x
%
@@ -91,8 +97,9 @@
Select a Data Directory
Confirm location
The server manager will store profiles and SteamCMD in the following directories:\r\n\r\nProfiles: {0}\r\nSteamCMD: {1}\r\n\r\nIs this ok?
- Data Directory Selection Error
- The directory you have chosen is within the server manager installation folder. This is not recommended, please choose another folder.
+ Data Directory Selection Error
+ The directory you have chosen is within the server manager installation folder. This is not recommended, please choose another folder.
+ The directory you have chosen is on the desktop. This is not recommended, please choose another folder.
Failed to save profile
Failed to save profile {0}. {1}\n{2}
@@ -161,6 +168,25 @@
Processor
+
+ Data Folder Selection
+ It appears you do not have a data directory set. The data directory is where your profiles and SteamCMD will be stored. It is not the same as the server installation directory, which you can choose for each profile.
+ Select the drive where the data folder should be located.
+ Data Folder Name:
+ The name of the server manager data folder.
+ Local Disk
+ {0} free of {1}
+
+ Ok
+ Cancel
+ Refresh
+
+ Data Directory Selection Error
+ The data folder name you have entered is not valid.
+ Server Manager Restart Required
+ The data folder has been set, you must now restart the server manager to use the new settings.
+
+
Mod Details
Mod Details - {0}
@@ -602,6 +628,9 @@
Reinstall SteamCMD Error
An error occured while trying to reinstall SteamCMD. This has left SteamCmd in an unstable state, try reinstalling again or please report this.\r\nException: {0}
+ Discord Bot Running Commands
+ The discord bot has one or more running commands, do you want to continue shutting down the server manager?
+
Start Server Confirmation
You are about to start the server, do you want to continue?
Shutdown Server Confirmation
@@ -623,6 +652,7 @@
Reset
This will reset ALL the user global settings for the server manager. The server manager will be closed if successful.
Enable Run as Administrator Prompt on Startup
+ Main Window Start Mode:
Minimize To Tray
Manage firewall settings automatically
Manage Public IP automatically
@@ -741,6 +771,23 @@
Show shutdown reason with ALL shutdown messages
If enabled, the shutdown reason will be shown with all shutdown message; otherwise it will only be shown at the start of the server shutdown.
+ Enable Discord Bot
+ You will need to restart the server manager if you change any settings for the Discord Bot.
+ Token:
+ The token associated with the discord bot.
+ Server Id:
+ The id of the discord server the bot will listen to.
+ Prefix:
+ The prefix that must be used when sending a command via discord.
+ Get Token...
+ Help...
+ If enabled, the backup command can be sent from discord.
+ If enabled, the restart command can be sent from discord.
+ If enabled, the shutdown command can be sent from discord.
+ If enabled, the start command can be sent from discord.
+ If enabled, the stop command can be sent from discord.
+ If enabled, the update command can be sent from discord.
+
SMTP Email Settings
Host:
The name or IP address of the host used for SMTP transmissions.
@@ -788,6 +835,8 @@
Changing the data directory will move any existing profiles to the new location, but it will not move any server installations. Do you still want to change this directory?
Failed to change data directory
There was an error changing the data directory: {0}\r\nPlease correct the error and try again, or contact technical support for assistance.
+ Confirm Data Directory Reset
+ Click 'Yes' to confirm you want to reset the location of the data directory. Once reset, the server manager will shutdown and you will need to restart.
Select Backup Directory
Select Cache Directory
@@ -840,6 +889,8 @@
+ Profile ID:
+ The unique ID assigned to the profile.
Profile:
The name for the server profile. This is not the public name users will see in the game. For that, set the 'Server Name' field.
Installed Version:
@@ -1043,6 +1094,10 @@
Set the amount of AFK time before a character is kicked.
Server Region:
Selecting a server region will affect how your server is filtered in the list. Select your region to help players find a server that is close to them.
+ Enable Server Transfers
+ If enabled, will enable character server transfers.
+ Can Import Directly from Same Server
+ If enabled, will allow players to directly import characters that were exported from exactly the same server.
Branch Details
Branch Name:
@@ -1088,6 +1143,24 @@
If enabled, the server will be restarted even if shutdown for Auto-Restarts and Auto-Updates.
+
+ Discord Bot Details
+ Channel Id:
+ The id of the discord server channel this profile will listen to.
+ Allow Backup
+ If enabled, the profile will listen for backup commands from discord.
+ Allow Restart
+ If enabled, the profile will listen for restart commands from discord.
+ Allow Shutdown
+ If enabled, the profile will listen for shutdown commands from discord.
+ Allow Start
+ If enabled, the profile will listen for start commands from discord.
+ Allow Stop
+ If enabled, the profile will listen for stop commands from discord.
+ Allow Update
+ If enabled, the profile will listen for update commands from discord.
+
+
Server File Details
NOTE: Any changes will require a server restart to take effect.
@@ -1160,4 +1233,32 @@
There was a problem while performing the server update. This may leave your server in a incomplete state.\r\n\r\nDo you want to continue with the server start, this could cause problems?
+
+ Discord Bot Error
+ The discord bot requires a valid token so it can log into the discord server\r\nThis can be set in the global settings.
+ The discord bot prefix contains invalid characters. Only letters and numbers are allowed.
+
+ Command '{0}' has not been enabled.
+ Unknown command '{0}'.
+ Another command is currently being processed.
+ Another command '{0}' is currently running against profile '{1}'.
+ Command '{0}' has been disabled for profile '{1}'.
+
+ The '{0}' command requires a profile id.
+ Profile '{0}' was not found or is not associated with the channel.
+ Profile '{0}' is in a state '{1}' that cannot run this command.
+ Profile '{0}' is currently being updated.
+
+ Call to server '{0}' failed.
+ A backup request for server '{0}' has been sent.
+ A restart request for server '{0}' has been sent.
+ A shutdown request for server '{0}' has been sent.
+ A start request for server '{0}' has been sent.
+ A stop request for server '{0}' has been sent.
+ An update request for server '{0}' has been sent.
+
+ Count:
+ Map:
+
+
\ No newline at end of file
diff --git a/src/ConanServerManager/Globalization/fr-FR/fr-FR.xaml b/src/ConanServerManager/Globalization/fr-FR/fr-FR.xaml
index d484cd4c..b598f7dd 100644
--- a/src/ConanServerManager/Globalization/fr-FR/fr-FR.xaml
+++ b/src/ConanServerManager/Globalization/fr-FR/fr-FR.xaml
@@ -12,6 +12,14 @@
Erreur
+
+ Les terres exilées
+
+
+
+ Version Steam (Défaut)
+
+
Tout
Conan Exiles
@@ -989,12 +997,4 @@
Vérification des tâches planifiées...
-
- Version Steam (Défaut)
-
-
-
- Les terres exilées
-
-
\ No newline at end of file
diff --git a/src/ConanServerManager/Globalization/pt-BR/pt-BR.xaml b/src/ConanServerManager/Globalization/pt-BR/pt-BR.xaml
index 60c33d02..df0c6e73 100644
--- a/src/ConanServerManager/Globalization/pt-BR/pt-BR.xaml
+++ b/src/ConanServerManager/Globalization/pt-BR/pt-BR.xaml
@@ -12,6 +12,14 @@
Error
+
+ The Exiled Lands
+
+
+
+ Live
+
+
Todos
Conan
@@ -1033,12 +1041,4 @@
Verificando tarefas agendadas ...
-
- Live
-
-
-
- The Exiled Lands
-
-
\ No newline at end of file
diff --git a/src/ConanServerManager/Lib/BranchSnapshot.cs b/src/ConanServerManager/Lib/BranchSnapshot.cs
index 2b81437d..c3b0283d 100644
--- a/src/ConanServerManager/Lib/BranchSnapshot.cs
+++ b/src/ConanServerManager/Lib/BranchSnapshot.cs
@@ -5,8 +5,30 @@ namespace ServerManagerTool.Lib
{
public class BranchSnapshot
{
+ private BranchSnapshot()
+ {
+ }
+
public string BranchName = string.Empty;
public string BranchPassword = string.Empty;
+
+ public static BranchSnapshot Create(ServerProfile profile)
+ {
+ return new BranchSnapshot
+ {
+ BranchName = profile.BranchName,
+ BranchPassword = profile.BranchPassword
+ };
+ }
+
+ public static BranchSnapshot Create(ServerProfileSnapshot profile)
+ {
+ return new BranchSnapshot
+ {
+ BranchName = profile.BranchName,
+ BranchPassword = profile.BranchPassword
+ };
+ }
}
public class BranchSnapshotComparer : IEqualityComparer
diff --git a/src/ConanServerManager/Lib/GameData.cs b/src/ConanServerManager/Lib/GameData.cs
index bd96fbac..bd2282e8 100644
--- a/src/ConanServerManager/Lib/GameData.cs
+++ b/src/ConanServerManager/Lib/GameData.cs
@@ -71,7 +71,7 @@ namespace ServerManagerTool.Lib
public static IEnumerable GetGameMaps() => gameMaps.Select(m => m.Duplicate());
- public static string FriendlyMapNameForClass(string className, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(className) ? string.Empty : GlobalizedApplication.Instance.GetResourceString(className) ?? gameData?.GameMaps?.FirstOrDefault(i => i.ClassName.Equals(className))?.Description ?? (returnEmptyIfNotFound ? string.Empty : className);
+ public static string FriendlyMapNameForClass(string className, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(className) ? string.Empty : GlobalizedApplication.Instance.GetResourceString("Map_" + className) ?? gameData?.GameMaps?.FirstOrDefault(i => i.ClassName.Equals(className))?.Description ?? (returnEmptyIfNotFound ? string.Empty : className);
public static string MapSaveNameForClass(string className, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(className) ? string.Empty : gameData?.GameMaps?.FirstOrDefault(i => i.ClassName.Equals(className))?.SaveFileName ?? (returnEmptyIfNotFound ? string.Empty : className);
#endregion
@@ -84,7 +84,7 @@ namespace ServerManagerTool.Lib
public static IEnumerable GetBranches() => branches.Select(d => d.Duplicate());
- public static string FriendlyBranchName(string branchName, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(branchName) ? string.Empty : GlobalizedApplication.Instance.GetResourceString(branchName) ?? gameData?.Branches?.FirstOrDefault(i => i.BranchName.Equals(branchName))?.Description ?? (returnEmptyIfNotFound ? string.Empty : branchName);
+ public static string FriendlyBranchName(string branchName, bool returnEmptyIfNotFound = false) => string.IsNullOrWhiteSpace(branchName) ? string.Empty : GlobalizedApplication.Instance.GetResourceString("Branch_" + branchName) ?? gameData?.Branches?.FirstOrDefault(i => i.BranchName.Equals(branchName))?.Description ?? (returnEmptyIfNotFound ? string.Empty : branchName);
#endregion
#region Server Regions
diff --git a/src/ConanServerManager/Lib/ServerApp.cs b/src/ConanServerManager/Lib/ServerApp.cs
index 7d745a88..7b5be7cb 100644
--- a/src/ConanServerManager/Lib/ServerApp.cs
+++ b/src/ConanServerManager/Lib/ServerApp.cs
@@ -3,6 +3,7 @@ using ServerManagerTool.Common;
using ServerManagerTool.Common.Lib;
using ServerManagerTool.Common.Model;
using ServerManagerTool.Common.Utils;
+using ServerManagerTool.Delegates;
using ServerManagerTool.Enums;
using ServerManagerTool.Plugin.Common;
using ServerManagerTool.Utils;
@@ -108,6 +109,7 @@ namespace ServerManagerTool.Lib
public int ShutdownInterval = Config.Default.ServerShutdown_GracePeriod;
public ProgressDelegate ProgressCallback = null;
public ProcessWindowStyle SteamCMDProcessWindowStyle = ProcessWindowStyle.Minimized;
+ public ServerStatusChangeDelegate ServerStatusChangeCallback = null;
public ServerApp(bool resetStartTime = false)
{
@@ -115,7 +117,7 @@ namespace ServerManagerTool.Lib
_startTime = DateTime.Now;
}
- private void BackupServer()
+ private void BackupServer(CancellationToken cancellationToken)
{
if (_profile == null)
{
@@ -144,58 +146,67 @@ namespace ServerManagerTool.Lib
if (_serverRunning)
{
- // check if RCON is enabled
- //if (_profile.RconEnabled)
- //{
- // try
- // {
- // emailMessage.AppendLine();
+ try
+ {
+ emailMessage.AppendLine();
- // // perform a world save
- // if (!string.IsNullOrWhiteSpace(Config.Default.ServerBackup_WorldSaveMessage))
- // {
- // ProcessAlert(AlertType.Backup, Config.Default.ServerBackup_WorldSaveMessage);
- // sent = SendMessage(Config.Default.ServerBackup_WorldSaveMessage, CancellationToken.None);
- // if (sent)
- // {
- // emailMessage.AppendLine("sent server save message.");
- // }
- // }
+ var sent = false;
- // sent = SendCommand(Config.Default.ServerSaveCommand, false);
- // if (sent)
- // {
- // emailMessage.AppendLine("sent server save command.");
- // Task.Delay(Config.Default.ServerShutdown_WorldSaveDelay * 1000).Wait();
- // }
- // }
- // catch (Exception ex)
- // {
- // CloseRconConsole();
+ // perform a world save
+ if (!string.IsNullOrWhiteSpace(Config.Default.ServerBackup_WorldSaveMessage))
+ {
+ ProcessAlert(AlertType.Backup, Config.Default.ServerBackup_WorldSaveMessage);
+ sent = SendMessageAsync(Config.Default.ServerBackup_WorldSaveMessage, CancellationToken.None).Result;
+ if (sent)
+ {
+ emailMessage.AppendLine("sent server save message.");
+ }
+ }
- // Debug.WriteLine($"RCON> {Config.Default.ServerSaveCommand} command.\r\n{ex.Message}");
- // }
- //}
- //else
- //{
- // LogProfileMessage("RCON not enabled.");
- //}
+ sent = SendCommandAsync(Config.Default.ServerSaveCommand, false).Result;
+ if (sent)
+ {
+ emailMessage.AppendLine("sent server save command.");
+ Task.Delay(Config.Default.ServerShutdown_WorldSaveDelay * 1000).Wait();
+ }
+ }
+ catch (Exception ex)
+ {
+ CloseRconConsole();
+
+ Debug.WriteLine($"RCON> {Config.Default.ServerSaveCommand} command.\r\n{ex.Message}");
+ }
}
if (ExitCode != EXITCODE_NORMALEXIT)
return;
+ if (cancellationToken.IsCancellationRequested)
+ {
+ ExitCode = EXITCODE_CANCELLED;
+ return;
+ }
// make a backup of the current profile and config files.
CreateProfileBackupArchiveFile();
if (ExitCode != EXITCODE_NORMALEXIT)
return;
+ if (cancellationToken.IsCancellationRequested)
+ {
+ ExitCode = EXITCODE_CANCELLED;
+ return;
+ }
// make a backup of the current world file.
CreateServerBackupArchiveFile(emailMessage);
if (ExitCode != EXITCODE_NORMALEXIT)
return;
+ if (cancellationToken.IsCancellationRequested)
+ {
+ ExitCode = EXITCODE_CANCELLED;
+ return;
+ }
if (Config.Default.EmailNotify_AutoBackup)
{
@@ -261,7 +272,15 @@ namespace ServerManagerTool.Lib
if (updateServer)
{
- UpgradeLocal(true, steamCmdRemoveQuit, cancellationToken, true);
+ try
+ {
+ ServerStatusChangeCallback?.Invoke(ServerStatus.Updating);
+ UpgradeLocal(true, true, steamCmdRemoveQuit, cancellationToken);
+ }
+ finally
+ {
+ ServerStatusChangeCallback?.Invoke(ServerStatus.Stopped);
+ }
}
if (ExitCode != EXITCODE_NORMALEXIT)
@@ -297,17 +316,20 @@ namespace ServerManagerTool.Lib
return;
}
- // check if the server was previously running before the update.
- if (!_serverRunning && !_profile.AutoRestartIfShutdown)
+ // check if the server was previously running.
+ if (!_serverRunning)
{
- LogProfileMessage("Server was not running, server will not be started.");
+ if (_profile.AutoRestartIfShutdown)
+ {
+ LogProfileMessage("Server was not running, server will be started as the setting to restart if shutdown is TRUE.");
+ }
+ else
+ {
+ LogProfileMessage("Server was not running, server will not be started.");
- ExitCode = EXITCODE_NORMALEXIT;
- return;
- }
- if (!_serverRunning && _profile.AutoRestartIfShutdown)
- {
- LogProfileMessage("Server was not running, server will be started as the setting to restart if shutdown is TRUE.");
+ ExitCode = EXITCODE_NORMALEXIT;
+ return;
+ }
}
// Find the server process.
@@ -380,10 +402,15 @@ namespace ServerManagerTool.Lib
_serverRunning = true;
LogProfileMessage($"Server process found PID {process.Id}.");
+ QueryMaster.Server gameServer = null;
bool sent = false;
try
{
+ // create a connection to the server
+ var endPoint = new IPEndPoint(_profile.ServerIPAddress, _profile.QueryPort);
+ gameServer = QueryMaster.ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endPoint);
+
// check if there is a shutdown reason
if (!string.IsNullOrWhiteSpace(ShutdownReason) && !Config.Default.ServerShutdown_AllMessagesShowReason)
{
@@ -394,10 +421,6 @@ namespace ServerManagerTool.Lib
}
LogProfileMessage("Starting shutdown timer...");
- if (!CheckForOnlinePlayers)
- {
- LogProfileMessage("CheckForOnlinePlayers disabled, shutdown timer will not perform online player check.");
- }
var minutesLeft = ShutdownInterval;
while (minutesLeft > 0)
@@ -420,8 +443,11 @@ namespace ServerManagerTool.Lib
{
try
{
- var gameFile = GetServerWorldFile();
- var playerCount = DataContainer.GetOnlinePlayerCount(gameFile);
+ // BH - commented out until Funcom fix the Online player status column in the world save database
+ //var gameFile = GetServerWorldFile();
+ //var playerCount = DataContainer.GetOnlinePlayerCount(gameFile);
+ var playerInfo = gameServer?.GetPlayers()?.Where(p => !string.IsNullOrWhiteSpace(p.Name?.Trim())).ToList();
+ var playerCount = playerInfo?.Count ?? -1;
// check if anyone is logged into the server
if (playerCount <= 0)
@@ -439,7 +465,8 @@ namespace ServerManagerTool.Lib
}
else
{
- Debug.WriteLine($"CheckForOnlinePlayers disabled");
+ Debug.WriteLine($"CheckForOnlinePlayers disabled, shutdown timer cancelled.");
+ break;
}
var message = string.Empty;
@@ -506,7 +533,7 @@ namespace ServerManagerTool.Lib
// BH - commented out until funcom provide a way to send a save command
// check if we need to perform a world save
- //if (_profile.RconEnabled && Config.Default.ServerShutdown_EnableWorldSave)
+ //if (Config.Default.ServerShutdown_EnableWorldSave)
//{
// try
// {
@@ -515,10 +542,10 @@ namespace ServerManagerTool.Lib
// {
// LogProfileMessage(Config.Default.ServerShutdown_WorldSaveMessage);
// ProcessAlert(AlertType.ShutdownMessage, Config.Default.ServerShutdown_WorldSaveMessage);
- // SendMessage(Config.Default.ServerShutdown_WorldSaveMessage, cancellationToken);
+ // SendMessageAsync(Config.Default.ServerShutdown_WorldSaveMessage, cancellationToken).Wait(cancellationToken);
// }
- // if (SendCommand(Config.Default.ServerSaveCommand, false))
+ // if (SendCommandAsync(Config.Default.ServerSaveCommand, false).Result)
// {
// try
// {
@@ -566,7 +593,8 @@ namespace ServerManagerTool.Lib
}
finally
{
- CloseRconConsole();
+ gameServer?.Dispose();
+ gameServer = null;
}
if (cancellationToken.IsCancellationRequested)
@@ -579,8 +607,6 @@ namespace ServerManagerTool.Lib
SendMessageAsync(Config.Default.ServerShutdown_CancelMessage, CancellationToken.None).Wait();
}
- CloseRconConsole();
-
ExitCode = EXITCODE_CANCELLED;
return;
}
@@ -654,7 +680,7 @@ namespace ServerManagerTool.Lib
ExitCode = EXITCODE_SHUTDOWN_TIMEOUT;
}
- private void UpgradeLocal(bool validate, bool steamCmdRemoveQuit, CancellationToken cancellationToken, bool updateMods)
+ private void UpgradeLocal(bool validate, bool updateMods, bool steamCmdRemoveQuit, CancellationToken cancellationToken)
{
if (_profile == null)
{
@@ -1172,7 +1198,7 @@ namespace ServerManagerTool.Lib
{
// perform a steamcmd validate to confirm all the files
LogProfileMessage("Validating server files (*new*).");
- UpgradeLocal(true, false, CancellationToken.None, false);
+ UpgradeLocal(true, false, false, CancellationToken.None);
LogProfileMessage("Validated server files (*new*).");
}
@@ -1693,17 +1719,6 @@ namespace ServerManagerTool.Lib
ExitCode = EXITCODE_NORMALEXIT;
}
- private void CloseRconConsole()
- {
- if (_rconConsole != null)
- {
- _rconConsole.Dispose();
- _rconConsole = null;
-
- Task.Delay(1000).Wait();
- }
- }
-
public void CreateProfileBackupArchiveFile(ServerProfileSnapshot profile = null)
{
var oldProfile = _profile;
@@ -2403,36 +2418,43 @@ namespace ServerManagerTool.Lib
int rconRetries = 0;
int maxRetries = retryIfFailed ? RCON_MAXRETRIES : 1;
- while (retries < maxRetries && rconRetries < RCON_MAXRETRIES)
+ try
{
- SetupRconConsole();
-
- if (_rconConsole == null)
+ while (retries < maxRetries && rconRetries < RCON_MAXRETRIES)
{
- LogProfileMessage($"RCON> {command} - attempt {rconRetries + 1} (a).", false);
- LogProfileMessage("RCON connection could not be created.", false);
- rconRetries++;
- }
- else
- {
- rconRetries = 0;
- try
- {
- _rconConsole.SendCommand(command);
- LogProfileMessage($"RCON> {command}");
+ SetupRconConsole();
- return true;
- }
- catch (Exception ex)
+ if (_rconConsole == null)
{
- LogProfileMessage($"RCON> {command} - attempt {retries + 1} (b).", false);
- LogProfileMessage($"{ex.Message}", false);
- LogProfileMessage($"{ex.StackTrace}", false);
+ LogProfileMessage($"RCON> {command} - attempt {rconRetries + 1} (a).", false);
+ LogProfileMessage("RCON connection could not be created.", false);
+ rconRetries++;
}
+ else
+ {
+ rconRetries = 0;
+ try
+ {
+ _rconConsole.SendCommand(command);
+ LogProfileMessage($"RCON> {command}");
- retries++;
+ return true;
+ }
+ catch (Exception ex)
+ {
+ LogProfileMessage($"RCON> {command} - attempt {retries + 1} (b).", false);
+ LogProfileMessage($"{ex.Message}", false);
+ LogProfileMessage($"{ex.StackTrace}", false);
+ }
+
+ retries++;
+ }
}
}
+ finally
+ {
+ CloseRconConsole();
+ }
return false;
}
@@ -2494,6 +2516,17 @@ namespace ServerManagerTool.Lib
}
}
+ private void CloseRconConsole()
+ {
+ if (_rconConsole != null)
+ {
+ _rconConsole.Dispose();
+ _rconConsole = null;
+
+ Task.Delay(1000).Wait();
+ }
+ }
+
private void SetupRconConsole()
{
CloseRconConsole();
@@ -2503,7 +2536,7 @@ namespace ServerManagerTool.Lib
try
{
- var endPoint = new IPEndPoint(IPAddress.Parse(_profile.ServerIP), _profile.RconPort);
+ var endPoint = new IPEndPoint(_profile.ServerIPAddress, _profile.RconPort);
var server = QueryMaster.ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endPoint, sendTimeOut: 10000, receiveTimeOut: 10000);
if (server == null)
{
@@ -2541,7 +2574,7 @@ namespace ServerManagerTool.Lib
}
}
- public int PerformProfileBackup(ServerProfileSnapshot profile)
+ public int PerformProfileBackup(ServerProfileSnapshot profile, CancellationToken cancellationToken)
{
_profile = profile;
@@ -2563,7 +2596,7 @@ namespace ServerManagerTool.Lib
// check if the mutex was established
if (createdNew)
{
- BackupServer();
+ BackupServer(cancellationToken);
if (ExitCode != EXITCODE_NORMALEXIT)
{
@@ -2916,7 +2949,7 @@ namespace ServerManagerTool.Lib
SendEmails = true,
ServerProcess = ServerProcessType.AutoBackup
};
- exitCodes.TryAdd(profile, app.PerformProfileBackup(profile));
+ exitCodes.TryAdd(profile, app.PerformProfileBackup(profile, CancellationToken.None));
});
foreach (var profile in _profiles.Keys)
@@ -3060,7 +3093,7 @@ namespace ServerManagerTool.Lib
if (exitCode == EXITCODE_NORMALEXIT)
{
- var branches = _profiles.Keys.Where(p => p.EnableAutoUpdate).Select(p => new BranchSnapshot() { BranchName = p.BranchName, BranchPassword = p.BranchPassword }).Distinct(new BranchSnapshotComparer()).ToArray();
+ var branches = _profiles.Keys.Where(p => p.EnableAutoUpdate).Select(p => BranchSnapshot.Create(p)).Distinct(new BranchSnapshotComparer()).ToArray();
var exitCodes = new ConcurrentDictionary();
// update the server cache for each branch
diff --git a/src/ConanServerManager/Lib/ServerProfile.cs b/src/ConanServerManager/Lib/ServerProfile.cs
index 946c03b3..9e6531e3 100644
--- a/src/ConanServerManager/Lib/ServerProfile.cs
+++ b/src/ConanServerManager/Lib/ServerProfile.cs
@@ -380,6 +380,22 @@ namespace ServerManagerTool.Lib
set { SetValue(KickIdlePlayersPeriodProperty, value); }
}
+ public static readonly DependencyProperty ServerTransferEnabledProperty = DependencyProperty.Register(nameof(ServerTransferEnabled), typeof(bool), typeof(ServerProfile), new PropertyMetadata(true));
+ [IniFileEntry(IniFiles.ServerSettings, IniSections.ServerSettings_ServerSettings, ServerProfileCategory.Administration)]
+ public bool ServerTransferEnabled
+ {
+ get { return (bool)GetValue(ServerTransferEnabledProperty); }
+ set { SetValue(ServerTransferEnabledProperty, value); }
+ }
+
+ public static readonly DependencyProperty CanImportDirectlyFromSameServerProperty = DependencyProperty.Register(nameof(CanImportDirectlyFromSameServer), typeof(bool), typeof(ServerProfile), new PropertyMetadata(false));
+ [IniFileEntry(IniFiles.ServerSettings, IniSections.ServerSettings_ServerSettings, ServerProfileCategory.Administration)]
+ public bool CanImportDirectlyFromSameServer
+ {
+ get { return (bool)GetValue(CanImportDirectlyFromSameServerProperty); }
+ set { SetValue(CanImportDirectlyFromSameServerProperty, value); }
+ }
+
public static readonly DependencyProperty BranchNameProperty = DependencyProperty.Register(nameof(BranchName), typeof(string), typeof(ServerProfile), new PropertyMetadata(String.Empty));
[DataMember]
public string BranchName
@@ -551,6 +567,64 @@ namespace ServerManagerTool.Lib
}
#endregion
+ #region Discord Bot
+ public static readonly DependencyProperty DiscordChannelIdProperty = DependencyProperty.Register(nameof(DiscordChannelId), typeof(string), typeof(ServerProfile), new PropertyMetadata(String.Empty));
+ [DataMember]
+ public string DiscordChannelId
+ {
+ get { return (string)GetValue(DiscordChannelIdProperty); }
+ set { SetValue(DiscordChannelIdProperty, value); }
+ }
+
+ public static readonly DependencyProperty AllowDiscordBackupProperty = DependencyProperty.Register(nameof(AllowDiscordBackup), typeof(bool), typeof(ServerProfile), new PropertyMetadata(true));
+ [DataMember]
+ public bool AllowDiscordBackup
+ {
+ get { return (bool)GetValue(AllowDiscordBackupProperty); }
+ set { SetValue(AllowDiscordBackupProperty, value); }
+ }
+
+ public static readonly DependencyProperty AllowDiscordRestartProperty = DependencyProperty.Register(nameof(AllowDiscordRestart), typeof(bool), typeof(ServerProfile), new PropertyMetadata(true));
+ [DataMember]
+ public bool AllowDiscordRestart
+ {
+ get { return (bool)GetValue(AllowDiscordRestartProperty); }
+ set { SetValue(AllowDiscordRestartProperty, value); }
+ }
+
+ public static readonly DependencyProperty AllowDiscordShutdownProperty = DependencyProperty.Register(nameof(AllowDiscordShutdown), typeof(bool), typeof(ServerProfile), new PropertyMetadata(true));
+ [DataMember]
+ public bool AllowDiscordShutdown
+ {
+ get { return (bool)GetValue(AllowDiscordShutdownProperty); }
+ set { SetValue(AllowDiscordShutdownProperty, value); }
+ }
+
+ public static readonly DependencyProperty AllowDiscordStartProperty = DependencyProperty.Register(nameof(AllowDiscordStart), typeof(bool), typeof(ServerProfile), new PropertyMetadata(true));
+ [DataMember]
+ public bool AllowDiscordStart
+ {
+ get { return (bool)GetValue(AllowDiscordStartProperty); }
+ set { SetValue(AllowDiscordStartProperty, value); }
+ }
+
+ public static readonly DependencyProperty AllowDiscordStopProperty = DependencyProperty.Register(nameof(AllowDiscordStop), typeof(bool), typeof(ServerProfile), new PropertyMetadata(true));
+ [DataMember]
+ public bool AllowDiscordStop
+ {
+ get { return (bool)GetValue(AllowDiscordStopProperty); }
+ set { SetValue(AllowDiscordStopProperty, value); }
+ }
+
+ public static readonly DependencyProperty AllowDiscordUpdateProperty = DependencyProperty.Register(nameof(AllowDiscordUpdate), typeof(bool), typeof(ServerProfile), new PropertyMetadata(true));
+ [DataMember]
+ public bool AllowDiscordUpdate
+ {
+ get { return (bool)GetValue(AllowDiscordUpdateProperty); }
+ set { SetValue(AllowDiscordUpdateProperty, value); }
+ }
+ #endregion
+
#region Server Files
public static readonly DependencyProperty ServerFilesBlacklistedProperty = DependencyProperty.Register(nameof(ServerFilesBlacklisted), typeof(PlayerUserList), typeof(ServerProfile), new PropertyMetadata(null));
[DataMember]
diff --git a/src/ConanServerManager/Lib/ServerProfileSnapshot.cs b/src/ConanServerManager/Lib/ServerProfileSnapshot.cs
index 543aa4c2..e74521b8 100644
--- a/src/ConanServerManager/Lib/ServerProfileSnapshot.cs
+++ b/src/ConanServerManager/Lib/ServerProfileSnapshot.cs
@@ -7,13 +7,17 @@ namespace ServerManagerTool.Lib
{
public class ServerProfileSnapshot
{
+ private ServerProfileSnapshot()
+ {
+ }
+
public string ProfileId;
public string ProfileName;
public string ServerName;
public string InstallDirectory;
public string GameFile;
public string AdminPassword;
- public string ServerIP;
+ public IPAddress ServerIPAddress;
public int ServerPort;
public int ServerPeerPort;
public int QueryPort;
@@ -56,7 +60,7 @@ namespace ServerManagerTool.Lib
InstallDirectory = profile.InstallDirectory,
GameFile = profile.GetServerWorldFile(),
AdminPassword = profile.AdminPassword,
- ServerIP = string.IsNullOrWhiteSpace(profile.ServerIP) ? IPAddress.Loopback.ToString() : profile.ServerIP.Trim(),
+ ServerIPAddress = string.IsNullOrWhiteSpace(profile.ServerIP) || !IPAddress.TryParse(profile.ServerIP.Trim(), out IPAddress ipAddress) ? IPAddress.Loopback : ipAddress,
ServerPort = profile.ServerPort,
ServerPeerPort = profile.ServerPeerPort,
QueryPort = profile.QueryPort,
diff --git a/src/ConanServerManager/Lib/ServerRuntime.cs b/src/ConanServerManager/Lib/ServerRuntime.cs
index 44ff0e60..d2370360 100644
--- a/src/ConanServerManager/Lib/ServerRuntime.cs
+++ b/src/ConanServerManager/Lib/ServerRuntime.cs
@@ -32,7 +32,7 @@ namespace ServerManagerTool.Lib
public event EventHandler StatusUpdate;
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
- private readonly GlobalizedApplication _globalizer = GlobalizedApplication.Instance;
+ private static readonly GlobalizedApplication _globalizer = GlobalizedApplication.Instance;
private readonly List profileNotifiers = new List();
private Process serverProcess;
private IAsyncDisposable updateRegistration;
@@ -167,13 +167,19 @@ namespace ServerManagerTool.Lib
ServerProfile.QueryPortProperty,
ServerProfile.ServerIPProperty,
ServerProfile.MaxPlayersProperty,
+
+ ServerProfile.ServerPasswordProperty,
+ ServerProfile.AdminPasswordProperty,
+
ServerProfile.ServerMapProperty,
ServerProfile.ServerMapSaveFileNameProperty,
ServerProfile.ServerModIdsProperty,
+
+ ServerProfile.MOTDIntervalProperty,
},
(s, p) =>
{
- if (Status == ServerStatus.Stopped || Status == ServerStatus.Uninstalled || Status == ServerStatus.Unknown)
+ if (Status == ServerStatus.Stopped || Status == ServerStatus.Uninstalled || Status == ServerStatus.Unknown || Status == ServerStatus.Updating)
{
AttachToProfileCore(profile);
}
@@ -194,16 +200,7 @@ namespace ServerManagerTool.Lib
return;
}
- if (!String.IsNullOrWhiteSpace(this.ProfileSnapshot.ServerIP) && IPAddress.TryParse(this.ProfileSnapshot.ServerIP, out IPAddress localServerIpAddress))
- {
- // Use the explicit Server IP
- localServerQueryEndPoint = new IPEndPoint(localServerIpAddress, Convert.ToUInt16(this.ProfileSnapshot.QueryPort));
- }
- else
- {
- // No Server IP specified, use Loopback
- localServerQueryEndPoint = new IPEndPoint(IPAddress.Loopback, Convert.ToUInt16(this.ProfileSnapshot.QueryPort));
- }
+ localServerQueryEndPoint = new IPEndPoint(this.ProfileSnapshot.ServerIPAddress, Convert.ToUInt16(this.ProfileSnapshot.QueryPort));
//
// Get the public endpoint for querying Steam
@@ -277,13 +274,13 @@ namespace ServerManagerTool.Lib
case WatcherServerStatus.RunningLocalCheck:
if (oldStatus != ServerStatus.Stopping)
- UpdateServerStatus(ServerStatus.Running, this.Availability != AvailabilityStatus.Available ? AvailabilityStatus.WaitingForPublication : this.Availability, oldStatus != ServerStatus.Running && oldStatus != ServerStatus.Unknown);
+ UpdateServerStatus(ServerStatus.Running, this.Availability != AvailabilityStatus.Available ? AvailabilityStatus.Waiting : this.Availability, oldStatus != ServerStatus.Running && oldStatus != ServerStatus.Unknown);
if (this.ProfileSnapshot.MOTDIntervalEnabled && this.motdIntervalTimer != null && !this.motdIntervalTimer.Enabled) this.motdIntervalTimer.Start();
break;
case WatcherServerStatus.RunningExternalCheck:
if (oldStatus != ServerStatus.Stopping)
- UpdateServerStatus(ServerStatus.Running, AvailabilityStatus.WaitingForPublication, oldStatus != ServerStatus.Running && oldStatus != ServerStatus.Unknown);
+ UpdateServerStatus(ServerStatus.Running, AvailabilityStatus.Waiting, oldStatus != ServerStatus.Running && oldStatus != ServerStatus.Unknown);
if (this.ProfileSnapshot.MOTDIntervalEnabled && this.motdIntervalTimer != null && !this.motdIntervalTimer.Enabled) this.motdIntervalTimer.Start();
break;
@@ -442,7 +439,7 @@ namespace ServerManagerTool.Lib
}
}
- UpdateServerStatus(ServerStatus.Initializing, this.Availability, false);
+ UpdateServerStatus(ServerStatus.Initializing, false);
try
{
@@ -516,7 +513,7 @@ namespace ServerManagerTool.Lib
bool isNewInstallation = this.Status == ServerStatus.Uninstalled;
- UpdateServerStatus(ServerStatus.Updating, Availability, false);
+ UpdateServerStatus(ServerStatus.Updating, false);
// Run the SteamCMD to install the server
var steamCmdFile = SteamCmdUpdater.GetSteamCmdFile(Config.Default.DataPath);
@@ -938,7 +935,7 @@ namespace ServerManagerTool.Lib
finally
{
this.lastModStatusQuery = DateTime.MinValue;
- UpdateServerStatus(ServerStatus.Stopped, Availability, false);
+ UpdateServerStatus(ServerStatus.Stopped, false);
}
}
@@ -961,6 +958,11 @@ namespace ServerManagerTool.Lib
this.lastModStatusQuery = DateTime.MinValue;
}
+ public void UpdateServerStatus(ServerStatus serverStatus, bool sendAlert)
+ {
+ UpdateServerStatus(serverStatus, Availability, sendAlert);
+ }
+
public void UpdateServerStatus(ServerStatus serverStatus, AvailabilityStatus availabilityStatus, bool sendAlert)
{
this.Status = serverStatus;
@@ -974,32 +976,29 @@ namespace ServerManagerTool.Lib
public void UpdateServerStatusString()
{
- switch (Status)
+ StatusString = GetServerStatusString(Status);
+ }
+
+ public static string GetServerStatusString(ServerStatus status)
+ {
+ switch (status)
{
case ServerStatus.Initializing:
- StatusString = _globalizer.GetResourceString("ServerSettings_RuntimeStatusInitializingLabel");
- break;
+ return _globalizer.GetResourceString("ServerSettings_RuntimeStatusInitializingLabel");
case ServerStatus.Running:
- StatusString = _globalizer.GetResourceString("ServerSettings_RuntimeStatusRunningLabel");
- break;
+ return _globalizer.GetResourceString("ServerSettings_RuntimeStatusRunningLabel");
case ServerStatus.Stopped:
- StatusString = _globalizer.GetResourceString("ServerSettings_RuntimeStatusStoppedLabel");
- break;
+ return _globalizer.GetResourceString("ServerSettings_RuntimeStatusStoppedLabel");
case ServerStatus.Stopping:
- StatusString = _globalizer.GetResourceString("ServerSettings_RuntimeStatusStoppingLabel");
- break;
+ return _globalizer.GetResourceString("ServerSettings_RuntimeStatusStoppingLabel");
case ServerStatus.Uninstalled:
- StatusString = _globalizer.GetResourceString("ServerSettings_RuntimeStatusUninstalledLabel");
- break;
+ return _globalizer.GetResourceString("ServerSettings_RuntimeStatusUninstalledLabel");
case ServerStatus.Unknown:
- StatusString = _globalizer.GetResourceString("ServerSettings_RuntimeStatusUnknownLabel");
- break;
+ return _globalizer.GetResourceString("ServerSettings_RuntimeStatusUnknownLabel");
case ServerStatus.Updating:
- StatusString = _globalizer.GetResourceString("ServerSettings_RuntimeStatusUpdatingLabel");
- break;
+ return _globalizer.GetResourceString("ServerSettings_RuntimeStatusUpdatingLabel");
default:
- StatusString = _globalizer.GetResourceString("ServerSettings_RuntimeStatusUnknownLabel");
- break;
+ return _globalizer.GetResourceString("ServerSettings_RuntimeStatusUnknownLabel");
}
}
@@ -1059,7 +1058,7 @@ namespace ServerManagerTool.Lib
try
{
- var endPoint = new IPEndPoint(IPAddress.Parse(this.ProfileSnapshot.ServerIP), this.ProfileSnapshot.RconPort);
+ var endPoint = new IPEndPoint(this.ProfileSnapshot.ServerIPAddress, this.ProfileSnapshot.RconPort);
var server = QueryMaster.ServerQuery.GetServerInstance(QueryMaster.EngineType.Source, endPoint, sendTimeOut: 10000, receiveTimeOut: 10000);
if (server == null)
diff --git a/src/ConanServerManager/Properties/AssemblyInfo.cs b/src/ConanServerManager/Properties/AssemblyInfo.cs
index 329694f2..0e3e60e5 100644
--- a/src/ConanServerManager/Properties/AssemblyInfo.cs
+++ b/src/ConanServerManager/Properties/AssemblyInfo.cs
@@ -2,54 +2,22 @@
using System.Runtime.InteropServices;
using System.Windows;
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
[assembly: AssemblyTitle("Conan Exiles™ Server Manager")]
[assembly: AssemblyDescription("The server manager makes it easy to setup and manage your Conan Exiles™ dedicated servers.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Bletch1971")]
[assembly: AssemblyProduct("Server Managers")]
-[assembly: AssemblyCopyright("Copyright © 2015-2020")]
+[assembly: AssemblyCopyright("Copyright © 2015-2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
-//In order to begin building localizable applications, set
-//CultureYouAreCodingWith in your .csproj file
-//inside a . For example, if you are using US english
-//in your source files, set the to en-US. Then uncomment
-//the NeutralResourceLanguage attribute below. Update the "en-US" in
-//the line below to match the UICulture setting in the project file.
-
-//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
-
-
[assembly: ThemeInfo(
- //where theme specific resource dictionaries are located
- //(used if a resource is not found in the page,
- // or application resource dictionaries)
ResourceDictionaryLocation.None,
- //where the generic resource dictionary is located
- //(used if a resource is not found in the page,
- // app, or any theme specific resource dictionaries)
ResourceDictionaryLocation.SourceAssembly
)]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0")]
+// include semantic versioning - ConanServerManager
[assembly: AssemblyVersion("1.0")]
-[assembly: AssemblyFileVersion("1.0.0.1")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/ConanServerManager/Styles/Default.xaml b/src/ConanServerManager/Styles/Default.xaml
index a0be2728..53d07ec7 100644
--- a/src/ConanServerManager/Styles/Default.xaml
+++ b/src/ConanServerManager/Styles/Default.xaml
@@ -1,16 +1,53 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -18,11 +55,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -52,4 +507,184 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/ConanServerManager/Windows/GlobalSettingsControl.xaml b/src/ConanServerManager/UserControls/GlobalSettingsControl.xaml
similarity index 88%
rename from src/ConanServerManager/Windows/GlobalSettingsControl.xaml
rename to src/ConanServerManager/UserControls/GlobalSettingsControl.xaml
index 383e06f1..1a6f3909 100644
--- a/src/ConanServerManager/Windows/GlobalSettingsControl.xaml
+++ b/src/ConanServerManager/UserControls/GlobalSettingsControl.xaml
@@ -7,82 +7,18 @@
xmlns:cc="clr-namespace:ServerManagerTool.Common.Converters;assembly=ServerManager.Common"
xmlns:gctl="clr-namespace:WPFSharp.Globalizer.Controls;assembly=WPFSharp.Globalizer"
mc:Ignorable="d"
- d:DesignWidth="800">
+ d:DesignWidth="800"
+ x:Name="GlobalSettings">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -112,6 +48,7 @@
+
@@ -128,14 +65,18 @@
-
-
-
+
+
+
-
-
-
+
+
+
+
+
+
+
@@ -587,6 +528,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -598,13 +588,13 @@
-
+
-
+
-
+
@@ -629,7 +619,7 @@
-
+
@@ -653,7 +643,7 @@
-
+
diff --git a/src/ConanServerManager/Windows/GlobalSettingsControl.xaml.cs b/src/ConanServerManager/UserControls/GlobalSettingsControl.xaml.cs
similarity index 84%
rename from src/ConanServerManager/Windows/GlobalSettingsControl.xaml.cs
rename to src/ConanServerManager/UserControls/GlobalSettingsControl.xaml.cs
index ac139066..dd9587f4 100644
--- a/src/ConanServerManager/Windows/GlobalSettingsControl.xaml.cs
+++ b/src/ConanServerManager/UserControls/GlobalSettingsControl.xaml.cs
@@ -2,6 +2,7 @@
using NLog;
using ServerManagerTool.Common;
using ServerManagerTool.Common.Lib;
+using ServerManagerTool.Common.Model;
using ServerManagerTool.Common.Utils;
using System;
using System.Diagnostics;
@@ -11,6 +12,7 @@ using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
+using System.Windows.Input;
using System.Xml;
using WPFSharp.Globalizer;
@@ -26,6 +28,7 @@ namespace ServerManagerTool
public static readonly DependencyProperty AppInstanceProperty = DependencyProperty.Register(nameof(AppInstance), typeof(App), typeof(GlobalSettingsControl), new PropertyMetadata(null));
public static readonly DependencyProperty IsAdministratorProperty = DependencyProperty.Register(nameof(IsAdministrator), typeof(bool), typeof(GlobalSettingsControl), new PropertyMetadata(false));
+ public static readonly DependencyProperty WindowStatesProperty = DependencyProperty.Register(nameof(WindowStates), typeof(ComboBoxItemList), typeof(GlobalSettingsControl), new PropertyMetadata(null));
public GlobalSettingsControl()
{
@@ -35,6 +38,8 @@ namespace ServerManagerTool
this.IsAdministrator = SecurityUtils.IsAdministrator();
this.Version = GetDeployedVersion();
+ PopulateWindowsStatesComboBox();
+
InitializeComponent();
WindowUtils.RemoveDefaultResourceDictionary(this, Config.Default.DefaultGlobalizationFile);
@@ -65,6 +70,12 @@ namespace ServerManagerTool
set { SetValue(IsAdministratorProperty, value); }
}
+ public ComboBoxItemList WindowStates
+ {
+ get { return (ComboBoxItemList)GetValue(WindowStatesProperty); }
+ set { SetValue(WindowStatesProperty, value); }
+ }
+
public string Version
{
get;
@@ -202,6 +213,21 @@ namespace ServerManagerTool
}
}
+ private void ResetDataDir_Click(object sender, RoutedEventArgs e)
+ {
+ // Confirm the reset with the user.
+ if (MessageBox.Show(_globalizer.GetResourceString("GlobalSettings_ResetDataDirectory_ConfirmLabel"), _globalizer.GetResourceString("GlobalSettings_ResetDataDirectory_ConfirmTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
+ return;
+
+ // Update the config
+ Config.Default.DataPath = string.Empty;
+ Config.Default.ConfigPath = string.Empty;
+
+ App.SaveConfigFiles(false);
+
+ Environment.Exit(0);
+ }
+
private void SetBackupDir_Click(object sender, RoutedEventArgs e)
{
var dialog = new CommonOpenFileDialog();
@@ -246,6 +272,16 @@ namespace ServerManagerTool
Process.Start(Config.Default.SteamWebAPIKeyHelpUrl);
}
+ private void DiscordBotApply_Click(object sender, RoutedEventArgs e)
+ {
+ Process.Start(Config.Default.DiscordBotApplyUrl);
+ }
+
+ private void DiscordBotHelp_Click(object sender, RoutedEventArgs e)
+ {
+ Process.Start(Config.Default.DiscordBotHelpUrl);
+ }
+
private async void SteamCMDAuthenticate_Click(object sender, RoutedEventArgs e)
{
var cursor = this.Cursor;
@@ -287,9 +323,25 @@ namespace ServerManagerTool
}
}
+ 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 LanguageSelectionComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Config.CultureName = AvailableLanguages.Instance.SelectedLanguage;
+
+ PopulateWindowsStatesComboBox();
+
+ App.Instance.OnResourceDictionaryChanged(Config.CultureName);
}
private void StyleSelectionComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
@@ -308,6 +360,8 @@ namespace ServerManagerTool
textBox = SteamAPIKeyTextBox;
if (Equals(hideTextBox, HideEmailPasswordTextBox))
textBox = EmailPasswordTextBox;
+ if (Equals(hideTextBox, HideDiscordBotTokenTextBox))
+ textBox = DiscordBotTokenTextBox;
if (textBox != null)
{
@@ -331,6 +385,8 @@ namespace ServerManagerTool
hideTextBox = HideSteamAPIKeyTextBox;
if (textBox == EmailPasswordTextBox)
hideTextBox = HideEmailPasswordTextBox;
+ if (textBox == DiscordBotTokenTextBox)
+ hideTextBox = HideDiscordBotTokenTextBox;
if (hideTextBox != null)
{
@@ -352,13 +408,11 @@ namespace ServerManagerTool
{
Config.Default.Reset();
Config.Default.UpgradeConfig = false;
- Config.Default.Save();
- Config.Default.Reload();
CommonConfig.Default.Reset();
CommonConfig.Default.UpgradeConfig = false;
- CommonConfig.Default.Save();
- CommonConfig.Default.Reload();
+
+ App.SaveConfigFiles(false);
}
catch (Exception ex)
{
@@ -368,7 +422,25 @@ namespace ServerManagerTool
}
finally
{
- App.Current.Shutdown(exitCode);
+ Environment.Exit(exitCode);
+ }
+ }
+
+ private void PopulateWindowsStatesComboBox()
+ {
+ var selectedValue = this.WindowStateComboBox?.SelectedValue ?? Config.MainWindow_WindowState;
+ var windowStates = new ComboBoxItemList();
+
+ foreach (WindowState windowState in Enum.GetValues(typeof(WindowState)))
+ {
+ var displayMember = _globalizer.GetResourceString($"WindowState_{windowState}") ?? windowState.ToString();
+ windowStates.Add(new Common.Model.ComboBoxItem(windowState.ToString(), displayMember));
+ }
+
+ this.WindowStates = windowStates;
+ if (this.WindowStateComboBox != null)
+ {
+ this.WindowStateComboBox.SelectedValue = selectedValue;
}
}
}
diff --git a/src/ConanServerManager/Windows/ServerSettingsControl.xaml b/src/ConanServerManager/UserControls/ServerSettingsControl.xaml
similarity index 79%
rename from src/ConanServerManager/Windows/ServerSettingsControl.xaml
rename to src/ConanServerManager/UserControls/ServerSettingsControl.xaml
index e1e98fa9..bfa7cb8f 100644
--- a/src/ConanServerManager/Windows/ServerSettingsControl.xaml
+++ b/src/ConanServerManager/UserControls/ServerSettingsControl.xaml
@@ -1,15 +1,15 @@
@@ -20,377 +20,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -433,6 +62,7 @@
+
@@ -440,14 +70,20 @@
+
-
+
+
+
+
+
+
+
+
-
-
@@ -466,10 +102,10 @@
-
-
+
+
-
+
@@ -530,7 +166,7 @@
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1436,7 +1119,9 @@
-
+
+
+
@@ -1445,7 +1130,7 @@
-
+
@@ -1533,7 +1218,7 @@
-
+
@@ -1620,6 +1305,8 @@
+
+
diff --git a/src/ConanServerManager/Windows/ServerSettingsControl.xaml.cs b/src/ConanServerManager/UserControls/ServerSettingsControl.xaml.cs
similarity index 98%
rename from src/ConanServerManager/Windows/ServerSettingsControl.xaml.cs
rename to src/ConanServerManager/UserControls/ServerSettingsControl.xaml.cs
index 24825056..0ca8ddce 100644
--- a/src/ConanServerManager/Windows/ServerSettingsControl.xaml.cs
+++ b/src/ConanServerManager/UserControls/ServerSettingsControl.xaml.cs
@@ -657,6 +657,8 @@ namespace ServerManagerTool
comment.AppendLine($"IsAdministrator: {SecurityUtils.IsAdministrator()}");
comment.AppendLine($"RunAsAdministratorPrompt: {Config.Default.RunAsAdministratorPrompt}");
+ comment.AppendLine($"MainWindow_WindowState: {Config.Default.MainWindow_WindowState}");
+ comment.AppendLine($"MainWindow_MinimizeToTray: {Config.Default.MainWindow_MinimizeToTray}");
comment.AppendLine($"ManageFirewallAutomatically: {Config.Default.ManageFirewallAutomatically}");
comment.AppendLine($"ValidateProfileOnServerStart: {Config.Default.ValidateProfileOnServerStart}");
comment.AppendLine($"SteamCMD File: {SteamCmdUpdater.GetSteamCmdFile(Config.Default.DataPath)}");
@@ -693,6 +695,17 @@ namespace ServerManagerTool
comment.AppendLine($"ServerUpdate_ForceUpdateModsIfNoSteamInfo: {Config.Default.ServerUpdate_ForceUpdateModsIfNoSteamInfo}");
comment.AppendLine($"ServerUpdate_OnServerStart: {Config.Default.ServerUpdate_OnServerStart}");
+ comment.AppendLine($"DiscordBotEnabled: {Config.Default.DiscordBotEnabled}");
+ comment.AppendLine($"HasDiscordBotToken: {string.IsNullOrWhiteSpace(Config.Default.DiscordBotToken)}");
+ comment.AppendLine($"DiscordBotServerId: {Config.Default.DiscordBotServerId}");
+ comment.AppendLine($"DiscordBotPrefix: {Config.Default.DiscordBotPrefix}");
+ comment.AppendLine($"AllowDiscordBackup: {Config.Default.AllowDiscordBackup}");
+ comment.AppendLine($"AllowDiscordRestart: {Config.Default.AllowDiscordRestart}");
+ comment.AppendLine($"AllowDiscordShutdown: {Config.Default.AllowDiscordShutdown}");
+ comment.AppendLine($"AllowDiscordStart: {Config.Default.AllowDiscordStart}");
+ comment.AppendLine($"AllowDiscordStop: {Config.Default.AllowDiscordStop}");
+ comment.AppendLine($"AllowDiscordUpdate: {Config.Default.AllowDiscordUpdate}");
+
comment.AppendLine($"EmailNotify_AutoRestart: {Config.Default.EmailNotify_AutoRestart}");
comment.AppendLine($"EmailNotify_AutoBackup: {Config.Default.EmailNotify_AutoBackup}");
comment.AppendLine($"EmailNotify_AutoUpdate: {Config.Default.EmailNotify_AutoUpdate}");
@@ -834,7 +847,7 @@ namespace ServerManagerTool
var profile = ServerProfileSnapshot.Create(Server.Profile);
- var exitCode = await Task.Run(() => app.PerformProfileBackup(profile));
+ var exitCode = await Task.Run(() => app.PerformProfileBackup(profile, CancellationToken.None));
if (exitCode != ServerApp.EXITCODE_NORMALEXIT && exitCode != ServerApp.EXITCODE_CANCELLED)
throw new ApplicationException($"An error occured during the backup process - ExitCode: {exitCode}");
@@ -1449,7 +1462,7 @@ namespace ServerManagerTool
await Task.Delay(1000);
- var branch = new BranchSnapshot() { BranchName = this.Server.Profile.BranchName, BranchPassword = this.Server.Profile.BranchPassword };
+ var branch = BranchSnapshot.Create(this.Server.Profile);
return await this.Server.UpgradeAsync(_upgradeCancellationSource.Token, updateServer, branch, true, updateMods, (p, m, n) => { TaskUtils.RunOnUIThreadAsync(() => { window?.AddMessage(m, n); }).DoNotWait(); });
}
else
diff --git a/src/ConanServerManager/Utils/DiscordBotHelper.cs b/src/ConanServerManager/Utils/DiscordBotHelper.cs
new file mode 100644
index 00000000..727ac5f0
--- /dev/null
+++ b/src/ConanServerManager/Utils/DiscordBotHelper.cs
@@ -0,0 +1,735 @@
+using QueryMaster;
+using ServerManagerTool.Common.Utils;
+using ServerManagerTool.DiscordBot.Enums;
+using ServerManagerTool.Enums;
+using ServerManagerTool.Lib;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Net;
+using System.Threading;
+using System.Threading.Tasks;
+using WPFSharp.Globalizer;
+
+namespace ServerManagerTool.Utils
+{
+ internal static class DiscordBotHelper
+ {
+ private static readonly GlobalizedApplication _globalizer = GlobalizedApplication.Instance;
+ private static bool _runningCommand = false;
+
+ private static readonly Dictionary _currentProfileCommands = new Dictionary();
+
+ public static bool HasRunningCommands => _currentProfileCommands.Count > 0;
+
+ public static IList HandleDiscordCommand(CommandType commandType, string serverId, string channelId, string profileId, CancellationToken token)
+ {
+ // check if incoming values are valid
+ if (string.IsNullOrWhiteSpace(serverId) || string.IsNullOrWhiteSpace(channelId))
+ return null;
+
+ // check if the server ids match
+ if (!serverId.Equals(Config.Default.DiscordBotServerId))
+ return new List();
+
+ if (_runningCommand)
+ return new List { _globalizer.GetResourceString("DiscordBot_CommandRunning") };
+ _runningCommand = true;
+
+ try
+ {
+ switch (commandType)
+ {
+ case CommandType.Info:
+ return GetServerInfo(channelId, profileId);
+ case CommandType.List:
+ return GetServerList(channelId);
+ case CommandType.Status:
+ return GetServerStatus(channelId, profileId);
+
+ case CommandType.Backup:
+ if (Config.Default.AllowDiscordBackup)
+ return BackupServer(channelId, profileId, token);
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandNotEnabled"), commandType) };
+ case CommandType.Restart:
+ if (Config.Default.AllowDiscordRestart)
+ return RestartServer(channelId, profileId, token);
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandNotEnabled"), commandType) };
+ case CommandType.Shutdown:
+ if (Config.Default.AllowDiscordShutdown)
+ return ShutdownServer(channelId, profileId, token);
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandNotEnabled"), commandType) };
+ case CommandType.Stop:
+ if (Config.Default.AllowDiscordStop)
+ return StopServer(channelId, profileId, token);
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandNotEnabled"), commandType) };
+ case CommandType.Start:
+ if (Config.Default.AllowDiscordStart)
+ return StartServer(channelId, profileId, token);
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandNotEnabled"), commandType) };
+ case CommandType.Update:
+ if (Config.Default.AllowDiscordUpdate)
+ return UpdateServer(channelId, profileId, token);
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandNotEnabled"), commandType) };
+
+ default:
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), commandType) };
+ }
+ }
+ catch (Exception ex)
+ {
+ var message = ex.InnerException is null ? ex.Message : ex.InnerException.Message;
+ return new string[] { message };
+ }
+ finally
+ {
+ _runningCommand = false;
+ }
+ }
+
+ public static string HandleTranslation(string translationKey)
+ {
+ return string.IsNullOrWhiteSpace(translationKey) ? string.Empty : _globalizer.GetResourceString(translationKey) ?? translationKey;
+ }
+
+ private static IList GetServerInfo(string channelId, string profileId)
+ {
+ if (string.IsNullOrWhiteSpace(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Info) };
+ }
+
+ // check if another command is being run against the profile
+ if (_currentProfileCommands.ContainsKey(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
+ }
+ _currentProfileCommands.Add(profileId, CommandType.Info);
+
+ try
+ {
+ var serverName = string.Empty;
+ var serverIp = IPAddress.Loopback;
+ var queryPort = 0;
+
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+
+ if (server is null)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
+ }
+
+ switch (server.Runtime.Status)
+ {
+ case ServerStatus.Initializing:
+ case ServerStatus.Stopping:
+ case ServerStatus.Stopped:
+ case ServerStatus.Uninstalled:
+ case ServerStatus.Unknown:
+ case ServerStatus.Updating:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
+ }
+
+ serverName = server.Profile.ServerName;
+ if (!string.IsNullOrWhiteSpace(server.Profile.ServerIP))
+ {
+ IPAddress.TryParse(server.Profile.ServerIP, out serverIp);
+ }
+ queryPort = server.Profile.QueryPort;
+ }).Wait();
+
+ List response = new List();
+
+ try
+ {
+ using (var gameServer = ServerQuery.GetServerInstance(EngineType.Source, new IPEndPoint(serverIp, queryPort)))
+ {
+ var info = gameServer?.GetInfo();
+ if (info is null)
+ {
+ response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_InfoFailed"), serverName));
+ }
+ else
+ {
+ var mapName = _globalizer.GetResourceString($"Map_{info.Map}") ?? info.Map;
+ response.Add($"```{info.Name}\n{_globalizer.GetResourceString("DiscordBot_MapLabel")} {mapName}\n{_globalizer.GetResourceString("ServerSettings_PlayersLabel")} {info.Players} / {info.MaxPlayers}```");
+ }
+ }
+ }
+ catch (Exception)
+ {
+ response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_InfoFailed"), serverName));
+ }
+
+ return response;
+ }
+ finally
+ {
+ _currentProfileCommands.Remove(profileId);
+ }
+ }
+
+ private static IList GetServerList(string channelId)
+ {
+ List response = new List();
+
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var serverList = ServerManager.Instance.Servers.Where(s => Equals(channelId, s.Profile.DiscordChannelId));
+
+ response.Add($"**{_globalizer.GetResourceString("DiscordBot_CountLabel")}** {serverList.Count()}");
+ foreach (var server in serverList)
+ {
+ response.Add($"```{_globalizer.GetResourceString("ServerSettings_ProfileIdLabel")} {server.Profile.ProfileID}\n{_globalizer.GetResourceString("ServerSettings_ProfileLabel")} {server.Profile.ProfileName}\n{_globalizer.GetResourceString("ServerSettings_ServerNameLabel")} {server.Profile.ServerName}```");
+ }
+ }).Wait();
+
+ return response;
+ }
+
+ private static IList GetServerStatus(string channelId, string profileId)
+ {
+ List response = new List();
+
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var serverList = ServerManager.Instance.Servers.Where(s => Equals(channelId, s.Profile.DiscordChannelId) && (string.IsNullOrWhiteSpace(profileId) || Equals(profileId, s.Profile.ProfileID)));
+
+ response.Add($"**{_globalizer.GetResourceString("DiscordBot_CountLabel")}** {serverList.Count()}");
+ foreach (var server in serverList)
+ {
+ response.Add($"```{_globalizer.GetResourceString("ServerSettings_ProfileLabel")} {server.Profile.ProfileName}\n{_globalizer.GetResourceString("ServerSettings_ServerNameLabel")} {server.Profile.ServerName}\n{_globalizer.GetResourceString("ServerSettings_StatusLabel")} {server.Runtime.StatusString}\n{_globalizer.GetResourceString("ServerSettings_AvailabilityLabel")} {_globalizer.GetResourceString($"ServerSettings_Availability_{server.Runtime.Availability}")}```");
+ }
+ }).Wait();
+
+ return response;
+ }
+
+ private static IList BackupServer(string channelId, string profileId, CancellationToken token)
+ {
+ if (string.IsNullOrWhiteSpace(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Backup) };
+ }
+
+ // check if another command is being run against the profile
+ if (_currentProfileCommands.ContainsKey(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
+ }
+ _currentProfileCommands.Add(profileId, CommandType.Backup);
+
+ ServerProfileSnapshot profile = null;
+ Task task = null;
+
+ try
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+
+ if (server is null)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
+ }
+
+ if (!server.Profile.AllowDiscordBackup)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_CommandDisabledProfile"), CommandType.Backup, profileId));
+ }
+
+ switch (server.Runtime.Status)
+ {
+ case ServerStatus.Initializing:
+ case ServerStatus.Stopping:
+ case ServerStatus.Uninstalled:
+ case ServerStatus.Unknown:
+ case ServerStatus.Updating:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
+ }
+
+ profile = ServerProfileSnapshot.Create(server.Profile);
+ }).Wait();
+
+ List response = new List();
+
+ var app = new ServerApp(true)
+ {
+ DeleteOldServerBackupFiles = !Config.Default.AutoBackup_EnableBackup,
+ OutputLogs = false,
+ SendAlerts = true,
+ SendEmails = false,
+ ServerProcess = ServerProcessType.Backup,
+ ServerStatusChangeCallback = (ServerStatus serverStatus) =>
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+ server.Runtime.UpdateServerStatus(serverStatus, true);
+ }).Wait();
+ }
+ };
+
+ task = Task.Run(() =>
+ {
+ app.PerformProfileBackup(profile, token);
+ _currentProfileCommands.Remove(profileId);
+ });
+
+ response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_BackupRequested"), profile.ServerName));
+
+ return response;
+ }
+ finally
+ {
+ if (task is null)
+ {
+ _currentProfileCommands.Remove(profileId);
+ }
+ }
+ }
+
+ private static IList RestartServer(string channelId, string profileId, CancellationToken token)
+ {
+ if (string.IsNullOrWhiteSpace(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Restart) };
+ }
+
+ // check if another command is being run against the profile
+ if (_currentProfileCommands.ContainsKey(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
+ }
+ _currentProfileCommands.Add(profileId, CommandType.Restart);
+
+ ServerProfileSnapshot profile = null;
+ Task task = null;
+
+ try
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+
+ if (server is null)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
+ }
+
+ if (!server.Profile.AllowDiscordRestart)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_CommandDisabledProfile"), CommandType.Restart, profileId));
+ }
+
+ switch (server.Runtime.Status)
+ {
+ case ServerStatus.Initializing:
+ case ServerStatus.Stopping:
+ case ServerStatus.Uninstalled:
+ case ServerStatus.Unknown:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
+
+ case ServerStatus.Updating:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), profileId));
+ }
+
+ profile = ServerProfileSnapshot.Create(server.Profile);
+ profile.AutoRestartIfShutdown = true;
+ }).Wait();
+
+ List response = new List();
+
+ var app = new ServerApp(true)
+ {
+ DeleteOldServerBackupFiles = !Config.Default.AutoBackup_EnableBackup,
+ OutputLogs = false,
+ SendAlerts = true,
+ SendEmails = false,
+ ServerProcess = ServerProcessType.Restart,
+ ServerStatusChangeCallback = (ServerStatus serverStatus) =>
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+ server.Runtime.UpdateServerStatus(serverStatus, true);
+ }).Wait();
+ }
+ };
+
+ task = Task.Run(() =>
+ {
+ app.PerformProfileShutdown(profile, true, false, false, false, token);
+ _currentProfileCommands.Remove(profileId);
+ });
+
+ response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_RestartRequested"), profile.ServerName));
+
+ return response;
+ }
+ finally
+ {
+ if (task is null)
+ {
+ _currentProfileCommands.Remove(profileId);
+ }
+ }
+ }
+
+ private static IList ShutdownServer(string channelId, string profileId, CancellationToken token)
+ {
+ if (string.IsNullOrWhiteSpace(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Shutdown) };
+ }
+
+ // check if another command is being run against the profile
+ if (_currentProfileCommands.ContainsKey(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
+ }
+ _currentProfileCommands.Add(profileId, CommandType.Shutdown);
+
+ ServerProfileSnapshot profile = null;
+ Task task = null;
+
+ try
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+
+ if (server is null)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
+ }
+
+ if (!server.Profile.AllowDiscordShutdown)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_CommandDisabledProfile"), CommandType.Shutdown, profileId));
+ }
+
+ switch (server.Runtime.Status)
+ {
+ case ServerStatus.Initializing:
+ case ServerStatus.Stopping:
+ case ServerStatus.Stopped:
+ case ServerStatus.Uninstalled:
+ case ServerStatus.Unknown:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
+
+ case ServerStatus.Updating:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), profileId));
+ }
+
+ profile = ServerProfileSnapshot.Create(server.Profile);
+ }).Wait();
+
+ List response = new List();
+
+ var app = new ServerApp(true)
+ {
+ DeleteOldServerBackupFiles = !Config.Default.AutoBackup_EnableBackup,
+ OutputLogs = false,
+ SendAlerts = true,
+ SendEmails = false,
+ ServerProcess = ServerProcessType.Shutdown,
+ ServerStatusChangeCallback = (ServerStatus serverStatus) =>
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+ server.Runtime.UpdateServerStatus(serverStatus, true);
+ }).Wait();
+ }
+ };
+
+ task = Task.Run(() =>
+ {
+ app.PerformProfileShutdown(profile, false, false, false, false, token);
+ _currentProfileCommands.Remove(profileId);
+ });
+
+ response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_ShutdownRequested"), profile.ServerName));
+
+ return response;
+ }
+ finally
+ {
+ if (task is null)
+ {
+ _currentProfileCommands.Remove(profileId);
+ }
+ }
+ }
+
+ private static IList StopServer(string channelId, string profileId, CancellationToken token)
+ {
+ if (string.IsNullOrWhiteSpace(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Stop) };
+ }
+
+ // check if another command is being run against the profile
+ if (_currentProfileCommands.ContainsKey(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
+ }
+ _currentProfileCommands.Add(profileId, CommandType.Stop);
+
+ ServerProfileSnapshot profile = null;
+ Task task = null;
+
+ try
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+
+ if (server is null)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
+ }
+
+ if (!server.Profile.AllowDiscordStop)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_CommandDisabledProfile"), CommandType.Stop, profileId));
+ }
+
+ switch (server.Runtime.Status)
+ {
+ case ServerStatus.Initializing:
+ case ServerStatus.Stopping:
+ case ServerStatus.Stopped:
+ case ServerStatus.Uninstalled:
+ case ServerStatus.Unknown:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
+
+ case ServerStatus.Updating:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), profileId));
+ }
+
+ profile = ServerProfileSnapshot.Create(server.Profile);
+ }).Wait();
+
+ List response = new List();
+
+ var app = new ServerApp(true)
+ {
+ DeleteOldServerBackupFiles = !Config.Default.AutoBackup_EnableBackup,
+ OutputLogs = false,
+ SendAlerts = true,
+ SendEmails = false,
+ ServerProcess = ServerProcessType.Shutdown,
+ ShutdownInterval = 0,
+ ServerStatusChangeCallback = (ServerStatus serverStatus) =>
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+ server.Runtime.UpdateServerStatus(serverStatus, true);
+ }).Wait();
+ }
+ };
+
+ task = Task.Run(() =>
+ {
+ app.PerformProfileShutdown(profile, false, false, false, false, token);
+ _currentProfileCommands.Remove(profileId);
+ });
+
+ response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_StopRequested"), profile.ServerName));
+
+ return response;
+ }
+ finally
+ {
+ if (task is null)
+ {
+ _currentProfileCommands.Remove(profileId);
+ }
+ }
+ }
+
+ private static IList StartServer(string channelId, string profileId, CancellationToken token)
+ {
+ if (string.IsNullOrWhiteSpace(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Start) };
+ }
+
+ // check if another command is being run against the profile
+ if (_currentProfileCommands.ContainsKey(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
+ }
+ _currentProfileCommands.Add(profileId, CommandType.Start);
+
+ ServerProfileSnapshot profile = null;
+ Task task = null;
+
+ try
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+
+ if (server is null)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
+ }
+
+ if (!server.Profile.AllowDiscordStart)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_CommandDisabledProfile"), CommandType.Start, profileId));
+ }
+
+ switch (server.Runtime.Status)
+ {
+ case ServerStatus.Initializing:
+ case ServerStatus.Stopping:
+ case ServerStatus.Running:
+ case ServerStatus.Uninstalled:
+ case ServerStatus.Unknown:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
+
+ case ServerStatus.Updating:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), profileId));
+ }
+
+ profile = ServerProfileSnapshot.Create(server.Profile);
+ profile.AutoRestartIfShutdown = true;
+ }).Wait();
+
+ List response = new List();
+
+ var app = new ServerApp(true)
+ {
+ DeleteOldServerBackupFiles = !Config.Default.AutoBackup_EnableBackup,
+ OutputLogs = false,
+ SendAlerts = true,
+ SendEmails = false,
+ ServerProcess = ServerProcessType.Restart,
+ ServerStatusChangeCallback = (ServerStatus serverStatus) =>
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+ server.Runtime.UpdateServerStatus(serverStatus, true);
+ }).Wait();
+ }
+ };
+
+ task = Task.Run(() =>
+ {
+ app.PerformProfileShutdown(profile, true, false, false, false, token);
+ _currentProfileCommands.Remove(profileId);
+ });
+
+ response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_StartRequested"), profile.ServerName));
+
+ return response;
+ }
+ finally
+ {
+ if (task is null)
+ {
+ _currentProfileCommands.Remove(profileId);
+ }
+ }
+ }
+
+ private static IList UpdateServer(string channelId, string profileId, CancellationToken token)
+ {
+ if (string.IsNullOrWhiteSpace(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_ProfileMissing"), CommandType.Update) };
+ }
+
+ // check if another command is being run against the profile
+ if (_currentProfileCommands.ContainsKey(profileId))
+ {
+ return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandRunningProfile"), _currentProfileCommands[profileId], profileId) };
+ }
+ _currentProfileCommands.Add(profileId, CommandType.Update);
+
+ ServerProfileSnapshot profile = null;
+ bool performRestart = false;
+ Task task = null;
+
+ try
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+
+ if (server is null)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileNotFound"), profileId));
+ }
+
+ if (!server.Profile.AllowDiscordUpdate)
+ {
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_CommandDisabledProfile"), CommandType.Update, profileId));
+ }
+
+ switch (server.Runtime.Status)
+ {
+ case ServerStatus.Initializing:
+ case ServerStatus.Stopping:
+ case ServerStatus.Unknown:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileBadStatus"), profileId, server.Runtime.StatusString));
+
+ case ServerStatus.Running:
+ performRestart = true;
+ break;
+
+ case ServerStatus.Updating:
+ throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_ProfileUpdating"), profileId));
+ }
+
+ profile = ServerProfileSnapshot.Create(server.Profile);
+ }).Wait();
+
+ List response = new List();
+
+ var app = new ServerApp(true)
+ {
+ DeleteOldServerBackupFiles = !Config.Default.AutoBackup_EnableBackup,
+ OutputLogs = false,
+ SendAlerts = true,
+ SendEmails = false,
+ ServerProcess = ServerProcessType.Update,
+ ServerStatusChangeCallback = (ServerStatus serverStatus) =>
+ {
+ TaskUtils.RunOnUIThreadAsync(() =>
+ {
+ var server = ServerManager.Instance.Servers.FirstOrDefault(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID));
+ server.Runtime.UpdateServerStatus(serverStatus, true);
+ }).Wait();
+ }
+ };
+
+ task = Task.Run(() =>
+ {
+ app.PerformProfileShutdown(profile, performRestart, true, false, false, token);
+ _currentProfileCommands.Remove(profileId);
+ });
+
+ response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_UpdateRequested"), profile.ServerName));
+
+ return response;
+ }
+ finally
+ {
+ if (task is null)
+ {
+ _currentProfileCommands.Remove(profileId);
+ }
+ }
+ }
+ }
+}
diff --git a/src/ConanServerManager/Utils/DiscordPluginHelper.cs b/src/ConanServerManager/Utils/DiscordPluginHelper.cs
new file mode 100644
index 00000000..7ec9ee93
--- /dev/null
+++ b/src/ConanServerManager/Utils/DiscordPluginHelper.cs
@@ -0,0 +1,18 @@
+using ServerManagerTool.Lib;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace ServerManagerTool.Utils
+{
+ internal static class DiscordPluginHelper
+ {
+ public static IList FetchProfiles()
+ {
+ return ServerManager.Instance.Servers.Select(s => new ServerManagerTool.Plugin.Common.Lib.Profile()
+ {
+ ProfileName = s?.Profile?.ProfileName ?? string.Empty,
+ InstallationFolder = s?.Profile?.InstallDirectory ?? string.Empty
+ }).ToList();
+ }
+ }
+}
diff --git a/src/ConanServerManager/VersionFeed.xml b/src/ConanServerManager/VersionFeed.xml
index b4419727..ea8301b2 100644
--- a/src/ConanServerManager/VersionFeed.xml
+++ b/src/ConanServerManager/VersionFeed.xml
@@ -5,7 +5,176 @@
Conan Server Manager Version Feed
This is the Conan Server Manager release version feed.
- 2020-11-25T00:00:00Z
+ 2021-12-12T00:00:00Z
+
+
+ urn:uuid:F8A08616-749B-48E7-87D5-D97E86AB3926
+ 1.1.56 (1.1.56.6)
+ 1.1.56.6
+
+ 2021-12-12T00:00:00Z
+
+
+
+ NEW
+
+
+
+ A new Discord Bot has been added to the server manager.
+ This new discord bot will allow you to send Start, Stop, Shutdown, Restart, Backup and Update commands to the server manager from within your discord client.
+ To setup the new discord bot, open the global settings and scroll down to the Discord section.
+
+ NOTE: This is long process to get the discord bot working, and I have created a forum post with detailed instructions how to do it.
+
+
+
+
CHANGE
+
+
+ Global Settings - Added reset button to the Data Directory Location.
+ Server Monitor window now stores it's location.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:A3A790A9-D511-4CE8-AC15-A36B3DAB4385
+ 1.1.55 (1.1.55.2)
+ 1.1.55.2
+
+ 2021-12-05T00:00:00Z
+
+
+
+ CHANGE
+
+
+ Changed some globalization key values (maps and branches).
+ Changed the way the data directory is selected and created on first startup of the server manager.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:38961ED8-0964-4C1A-B09C-8AE2C5FCF76E
+ 1.1.54 (1.1.54.3)
+ 1.1.54.3
+
+ 2021-12-01T00:00:00Z
+
+
+
+ NEW
+
+
+ Added the Profile ID to the top of the profile window.
+
+
CHANGE
+
+
+ Added globalization to the Main Window Start Mode setting in the Global Settings.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:80B2DFDC-E9BE-4B56-A1FE-DD57E64647D1
+ 1.1.53 (1.1.53.1)
+ 1.1.53.1
+
+ 2021-11-24T00:00:00Z
+
+
+
+ BUGFIX
+
+
+ Fixed a crashing bug when CSM closes and is unable to find the backup location to save the config settings.
+
+
NEW
+
+
+ Global Settings - added option to set the Main Window start mode - Normal, Maximized, Minimized.
+ Main Window - now stores the Left and Top positions of the window, when in Normal mode. Will restore the window position when started. Defaults to 50,50.
+ Server Settings - added resizing to all the grids, so the height can be increased/decreased. The height is also remembered, so when you reopen, it will size the grid correctly.
+
+
CHANGE
+
+
+ Fixed the steamcmd warning about 'Please use force_install_dir before login!'.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:285E9972-4FC6-49EA-8FAD-1086F7FC5354
+ 1.1.52 (1.1.52.1)
+ 1.1.52.1
+
+ 2021-11-21T00:00:00Z
+
+
+
+ CHANGE
+
+
+ Server Status checks - a few code tweaks to the server status checks.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:2B49A030-A742-476B-B811-6F0D7780B117
+ 1.1.51 (1.1.51.1)
+ 1.1.51.1
+
+ 2021-08-22T00:00:00Z
+
+
+
+ NEW
+
+
+ Server Settings - Added new server transfer options (server whitelist option in future version).
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
urn:uuid:6914861A-2D4E-4F08-89A3-D3D7A77F74C1
diff --git a/src/ConanServerManager/VersionFeedBeta.xml b/src/ConanServerManager/VersionFeedBeta.xml
index 3d356bef..102fa702 100644
--- a/src/ConanServerManager/VersionFeedBeta.xml
+++ b/src/ConanServerManager/VersionFeedBeta.xml
@@ -5,21 +5,144 @@
Conan Server Manager Version Feed
This is the Conan Server Manager beta version feed.
- 2020-11-25T00:00:00Z
+ 2021-12-12T00:00:00Z
- urn:uuid:6914861A-2D4E-4F08-89A3-D3D7A77F74C1
- 1.1.50 (1.1.50.1)
- 1.1.50.1
+ urn:uuid:4C15C7A9-317C-4A9B-B426-6E885B918D3B
+ 1.1.56 (1.1.56.6)
+ 1.1.56.6
- 2020-11-25T00:00:00Z
+ 2021-12-12T00:00:00Z
+
+
+
+ BUGFIX
+
+
+ Reference library updates.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:126E8E9F-7FF2-4239-88D6-5FFC89925463
+ 1.1.56 (1.1.56.5)
+ 1.1.56.5
+
+ 2021-12-10T00:00:00Z
+
+
+
+ BUGFIX
+
+
+ Server Monitor window now stores it's location.
+ Reference library updates.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:BECA74AB-1107-40B0-932A-A851E978EABF
+ 1.1.56 (1.1.56.4)
+ 1.1.56.4
+
+ 2021-12-09T00:00:00Z
+
+
+
+ BUGFIX
+
+
+ Fixed a minor issue when clicking the data directory reset button - fringe case that I found during testing.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:8C834060-F20F-4ACE-8F49-0B459531BA3C
+ 1.1.56 (1.1.56.3)
+ 1.1.56.3
+
+ 2021-12-08T00:00:00Z
+
+
+
+ BUGFIX
+
+
+ Fixed language translation of Data Directory window.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:339F72FC-920A-4425-AF86-AF9B34611A21
+ 1.1.56 (1.1.56.2)
+ 1.1.56.2
+
+ 2021-12-08T00:00:00Z
+
+
+
+ CHANGE
+
+
+ Global Settings - Added reset button to the Data Directory Location.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:F8A08616-749B-48E7-87D5-D97E86AB3926
+ 1.1.56 (1.1.56.1)
+ 1.1.56.1
+
+ 2021-12-06T00:00:00Z
NEW
- Global Settings - Added option to automatically manage the Public IP, default to True. If disabled, then the Public IP must be updated manually.
+
+ A new Discord Bot has been added to the server manager.
+ This new discord bot will allow you to send Start, Stop, Shutdown, Restart, Backup and Update commands to the server manager from within your discord client.
+ To setup the new discord bot, open the global settings and scroll down to the Discord section.
+
+ NOTE: This is long process to get the discord bot working, and I have created a forum post with detailed instructions how to do it.
+
+
diff --git a/src/ConanServerManager/Windows/DataDirectoryWindow.xaml b/src/ConanServerManager/Windows/DataDirectoryWindow.xaml
new file mode 100644
index 00000000..6a7e6bf3
--- /dev/null
+++ b/src/ConanServerManager/Windows/DataDirectoryWindow.xaml
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ConanServerManager/Windows/DataDirectoryWindow.xaml.cs b/src/ConanServerManager/Windows/DataDirectoryWindow.xaml.cs
new file mode 100644
index 00000000..01e00bb8
--- /dev/null
+++ b/src/ConanServerManager/Windows/DataDirectoryWindow.xaml.cs
@@ -0,0 +1,172 @@
+using ServerManagerTool.Common;
+using ServerManagerTool.Common.Utils;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Windows;
+using WPFSharp.Globalizer;
+
+namespace ServerManagerTool.Windows
+{
+ ///
+ /// Interaction logic for DriveSelectionWindow.xaml
+ ///
+ public partial class DataDirectoryWindow : Window
+ {
+ private readonly GlobalizedApplication _globalizer = GlobalizedApplication.Instance;
+
+ public static readonly DependencyProperty DriveInformationProperty = DependencyProperty.Register(nameof(DriveInformation), typeof(List), typeof(DataDirectoryWindow), new PropertyMetadata(null));
+ public static readonly DependencyProperty FolderNameProperty = DependencyProperty.Register(nameof(FolderName), typeof(string), typeof(DataDirectoryWindow), new PropertyMetadata(null));
+
+ public DataDirectoryWindow()
+ {
+ InitializeComponent();
+ WindowUtils.RemoveDefaultResourceDictionary(this, Config.Default.DefaultGlobalizationFile);
+
+ PopulateDriveInformation();
+ }
+
+ public List DriveInformation
+ {
+ get { return (List)GetValue(DriveInformationProperty); }
+ set { SetValue(DriveInformationProperty, value); }
+ }
+
+ public string FolderName
+ {
+ get { return (string)GetValue(FolderNameProperty); }
+ set { SetValue(FolderNameProperty, value); }
+ }
+
+ private void PopulateDriveInformation()
+ {
+ this.FolderName = Config.Default.DefaultDataDirectoryName;
+ this.DriveInformation = DriveInfo.GetDrives().Where(d => d.IsReady && d.DriveType == DriveType.Fixed).Select(d => new DriveInfoDisplay(d)).ToList();
+
+ var installationFolder = Path.GetPathRoot(Assembly.GetEntryAssembly().Location);
+ if (!installationFolder.EndsWith(@"\"))
+ installationFolder += @"\";
+
+ foreach (var driveInfo in DriveInformation)
+ {
+ if (driveInfo.DriveInfo.RootDirectory.FullName.Equals(installationFolder))
+ {
+ this.DriveSelectionListBox.SelectedItem = driveInfo;
+ break;
+ }
+ }
+ }
+
+ private void Ok_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ var result = CreateDataDirectory();
+ if (result == MessageBoxResult.Yes)
+ {
+ MessageBox.Show(_globalizer.GetResourceString("DataDirectory_RestartLabel"), _globalizer.GetResourceString("DataDirectory_RestartTitle"), MessageBoxButton.OK, MessageBoxImage.Information);
+
+ this.DialogResult = true;
+ this.Close();
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message, _globalizer.GetResourceString("DataDirectory_ErrorTitle"));
+ }
+ }
+
+ private void Refresh_Click(object sender, RoutedEventArgs e)
+ {
+ PopulateDriveInformation();
+ }
+
+ private MessageBoxResult CreateDataDirectory()
+ {
+ var selectedDrive = this.DriveSelectionListBox.SelectedItem as DriveInfoDisplay;
+ if (selectedDrive is null)
+ {
+ return MessageBoxResult.None;
+ }
+
+ var invalidCharacters = Path.GetInvalidFileNameChars();
+ if (string.IsNullOrWhiteSpace(FolderName) || FolderName.Any(c => invalidCharacters.Contains(c)))
+ {
+ throw new Exception(_globalizer.GetResourceString("DataDirectory_FolderErrorLabel"));
+ }
+
+ var newDataFolder = Path.Combine(selectedDrive.DriveInfo.RootDirectory.FullName, FolderName);
+
+ var confirm = MessageBox.Show(string.Format(_globalizer.GetResourceString("Application_DataDirectory_ConfirmLabel"), Path.Combine(newDataFolder, Config.Default.ProfilesRelativePath), Path.Combine(newDataFolder, CommonConfig.Default.SteamCmdRelativePath)), _globalizer.GetResourceString("Application_DataDirectory_ConfirmTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question);
+ if (confirm == MessageBoxResult.Yes)
+ {
+ if (newDataFolder.EndsWith(@"\"))
+ newDataFolder = newDataFolder.Substring(0, newDataFolder.Length - 1);
+
+ Config.Default.DataPath = newDataFolder;
+ }
+
+ return confirm;
+ }
+ }
+
+ public class DriveInfoDisplay
+ {
+ private const decimal DIVISOR = 1024M;
+
+ // Load all suffixes in an array
+ private static readonly string[] suffixes = { "Bytes", "KB", "MB", "GB", "TB", "PB" };
+
+ private readonly GlobalizedApplication _globalizer = GlobalizedApplication.Instance;
+
+ public DriveInfoDisplay(DriveInfo driveInfo)
+ {
+ DriveInfo = driveInfo;
+ }
+
+ public DriveInfo DriveInfo
+ {
+ get;
+ set;
+ }
+
+ public string Line1
+ {
+ get
+ {
+ if (DriveInfo is null)
+ return string.Empty;
+
+ var volumeLabel = string.IsNullOrWhiteSpace(DriveInfo.VolumeLabel) ? _globalizer.GetResourceString("DataDirectory_LocalDiskLabel") : DriveInfo.VolumeLabel;
+ return $"{volumeLabel} ({DriveInfo.Name.Replace(@"\", string.Empty)})";
+ }
+ }
+
+ public string Line2
+ {
+ get
+ {
+ if (DriveInfo is null)
+ return string.Empty;
+
+ return string.Format(_globalizer.GetResourceString("DataDirectory_DriveLine2Label"), FormatSize(DriveInfo.TotalFreeSpace), FormatSize(DriveInfo.TotalSize));
+ }
+ }
+
+ public static string FormatSize(long bytes)
+ {
+ var counter = 0;
+ var number = (decimal)bytes;
+
+ while (number / DIVISOR >= 1)
+ {
+ number /= DIVISOR;
+ counter++;
+ }
+
+ return string.Format("{0:n2} {1}", number, suffixes[counter]);
+ }
+ }
+}
diff --git a/src/ConanServerManager/Windows/GameDataWindow.xaml b/src/ConanServerManager/Windows/GameDataWindow.xaml
index cbdb970e..1b85df48 100644
--- a/src/ConanServerManager/Windows/GameDataWindow.xaml
+++ b/src/ConanServerManager/Windows/GameDataWindow.xaml
@@ -11,18 +11,6 @@
-
-
-
-
-
-
-
-
diff --git a/src/ConanServerManager/Windows/GuildProfileWindow.xaml b/src/ConanServerManager/Windows/GuildProfileWindow.xaml
index 950b56f5..32485905 100644
--- a/src/ConanServerManager/Windows/GuildProfileWindow.xaml
+++ b/src/ConanServerManager/Windows/GuildProfileWindow.xaml
@@ -1,7 +1,6 @@
@@ -10,26 +9,6 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/ConanServerManager/Windows/MainWindow.xaml b/src/ConanServerManager/Windows/MainWindow.xaml
index 46aefc45..8a4cd1d7 100644
--- a/src/ConanServerManager/Windows/MainWindow.xaml
+++ b/src/ConanServerManager/Windows/MainWindow.xaml
@@ -1,17 +1,16 @@
@@ -19,54 +18,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/ConanServerManager/Windows/MainWindow.xaml.cs b/src/ConanServerManager/Windows/MainWindow.xaml.cs
index 6eb014eb..d901db40 100644
--- a/src/ConanServerManager/Windows/MainWindow.xaml.cs
+++ b/src/ConanServerManager/Windows/MainWindow.xaml.cs
@@ -6,6 +6,7 @@ using ServerManagerTool.Common.Utils;
using ServerManagerTool.Enums;
using ServerManagerTool.Lib;
using ServerManagerTool.Plugin.Common;
+using ServerManagerTool.Utils;
using ServerManagerTool.Windows;
using System;
using System.Diagnostics;
@@ -152,14 +153,17 @@ namespace ServerManagerTool
}
}
+ this.Left = Config.Default.MainWindow_Left;
+ this.Top = Config.Default.MainWindow_Top;
this.Height = Config.Default.MainWindow_Height;
this.Width = Config.Default.MainWindow_Width;
+ this.WindowState = Config.Default.MainWindow_WindowState;
// hook into the language change event
GlobalizedApplication.Instance.GlobalizationManager.ResourceDictionaryChangedEvent += ResourceDictionaryChangedEvent;
}
- private void Window_Loaded(object sender, RoutedEventArgs e)
+ private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
//
// Kick off the initialization.
@@ -189,6 +193,32 @@ namespace ServerManagerTool
this.scheduledTaskChecker.PostAction(CheckForScheduledTasks).DoNotWait();
}
+ private void MainWindow_LocationChanged(object sender, EventArgs e)
+ {
+ if (this.WindowState == WindowState.Normal)
+ {
+ Config.Default.MainWindow_Left = Math.Max(0D, this.Left);
+ Config.Default.MainWindow_Top = Math.Max(0D, this.Top);
+ }
+ }
+
+ private void MainWindow_SizeChanged(object sender, SizeChangedEventArgs e)
+ {
+ if (this.WindowState == WindowState.Normal)
+ {
+ Config.Default.MainWindow_Height = e.NewSize.Height;
+ Config.Default.MainWindow_Width = e.NewSize.Width;
+ }
+ }
+
+ private void MainWindow_StateChanged(object sender, EventArgs e)
+ {
+ if (Config.Default.MainWindow_MinimizeToTray && this.WindowState == WindowState.Minimized)
+ {
+ this.Hide();
+ }
+ }
+
private void Window_Closed(object sender, EventArgs e)
{
if (sender is Window window)
@@ -197,37 +227,23 @@ namespace ServerManagerTool
this.Activate();
}
- private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
- {
- if (this.WindowState != WindowState.Minimized)
- {
- Config.Default.MainWindow_Height = e.NewSize.Height;
- Config.Default.MainWindow_Width = e.NewSize.Width;
- }
- }
-
- private void Window_StateChanged(object sender, EventArgs e)
- {
- if (Config.Default.MainWindow_MinimizeToTray && this.WindowState == WindowState.Minimized)
- {
- this.Hide();
- }
- }
-
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
+ if (DiscordBotHelper.HasRunningCommands)
+ {
+ var result = MessageBox.Show(_globalizer.GetResourceString("MainWindow_DiscordBot_RunningCommandsLabel"), _globalizer.GetResourceString("MainWindow_DiscordBot_RunningCommandsTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question);
+ if (result == MessageBoxResult.No)
+ {
+ e.Cancel = true;
+ return;
+ }
+ }
+
base.OnClosing(e);
RconWindow.CloseAllWindows();
PlayerListWindow.CloseAllWindows();
ServerMonitorWindow.CloseAllWindows();
this.versionChecker.DisposeAsync().DoNotWait();
-
- var installFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
- var backupFolder = IOUtils.NormalizePath(string.IsNullOrWhiteSpace(Config.Default.BackupPath)
- ? Path.Combine(Config.Default.DataPath, Config.Default.BackupRelativePath)
- : Path.Combine(Config.Default.BackupPath));
- SettingsUtils.BackupUserConfigSettings(Config.Default, "userconfig.json", installFolder, backupFolder);
- SettingsUtils.BackupUserConfigSettings(CommonConfig.Default, "commonconfig.json", installFolder, backupFolder);
}
private void ResourceDictionaryChangedEvent(object source, ResourceDictionaryChangedEventArgs e)
diff --git a/src/ConanServerManager/Windows/ModDetailsWindow.xaml b/src/ConanServerManager/Windows/ModDetailsWindow.xaml
index efde95b6..80256ad4 100644
--- a/src/ConanServerManager/Windows/ModDetailsWindow.xaml
+++ b/src/ConanServerManager/Windows/ModDetailsWindow.xaml
@@ -2,7 +2,6 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:com="clr-namespace:ServerManagerTool.Common;assembly=ServerManager.Common"
- xmlns:cc="clr-namespace:ServerManagerTool.Common.Converters;assembly=ServerManager.Common"
MinWidth="600" MinHeight="480" Width="900" Height="480" ResizeMode="CanResize" WindowStyle="ToolWindow" WindowStartupLocation="CenterOwner" ShowInTaskbar="False"
Loaded="Window_Loaded" Closing="Window_Closing"
Name="ModDetailsUI" Icon="../Art/favicon.ico" Title="{DynamicResource ModDetails_Title}">
@@ -12,14 +11,6 @@
-
-
-
-
-
-
-
-
diff --git a/src/ConanServerManager/Windows/PlayerListWindow.xaml b/src/ConanServerManager/Windows/PlayerListWindow.xaml
index 35b7b0ea..743e26c4 100644
--- a/src/ConanServerManager/Windows/PlayerListWindow.xaml
+++ b/src/ConanServerManager/Windows/PlayerListWindow.xaml
@@ -1,11 +1,11 @@
@@ -15,51 +15,6 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/ConanServerManager/Windows/PlayerProfileWindow.xaml b/src/ConanServerManager/Windows/PlayerProfileWindow.xaml
index 4ed1c7ae..cce112bd 100644
--- a/src/ConanServerManager/Windows/PlayerProfileWindow.xaml
+++ b/src/ConanServerManager/Windows/PlayerProfileWindow.xaml
@@ -1,7 +1,6 @@
@@ -10,77 +9,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/ConanServerManager/Windows/PluginsWindow.xaml b/src/ConanServerManager/Windows/PluginsWindow.xaml
index 48481d0f..5be9e94b 100644
--- a/src/ConanServerManager/Windows/PluginsWindow.xaml
+++ b/src/ConanServerManager/Windows/PluginsWindow.xaml
@@ -10,18 +10,6 @@
-
-
-
-
-
-
-
-
diff --git a/src/ConanServerManager/Windows/ProcessorAffinityWindow.xaml b/src/ConanServerManager/Windows/ProcessorAffinityWindow.xaml
index f676442e..b22ce845 100644
--- a/src/ConanServerManager/Windows/ProcessorAffinityWindow.xaml
+++ b/src/ConanServerManager/Windows/ProcessorAffinityWindow.xaml
@@ -1,11 +1,6 @@
@@ -14,8 +9,6 @@
-
-
diff --git a/src/ConanServerManager/Windows/ProgressWindow.xaml b/src/ConanServerManager/Windows/ProgressWindow.xaml
index bc231fad..687fdecf 100644
--- a/src/ConanServerManager/Windows/ProgressWindow.xaml
+++ b/src/ConanServerManager/Windows/ProgressWindow.xaml
@@ -10,11 +10,6 @@
-
-
-
-
-
diff --git a/src/ConanServerManager/Windows/RconWindow.xaml b/src/ConanServerManager/Windows/RconWindow.xaml
index d7c4a88e..98c0374e 100644
--- a/src/ConanServerManager/Windows/RconWindow.xaml
+++ b/src/ConanServerManager/Windows/RconWindow.xaml
@@ -1,14 +1,14 @@
@@ -20,54 +20,8 @@
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/src/ConanServerManager/Windows/RconWindow.xaml.cs b/src/ConanServerManager/Windows/RconWindow.xaml.cs
index f426ad8c..50690dde 100644
--- a/src/ConanServerManager/Windows/RconWindow.xaml.cs
+++ b/src/ConanServerManager/Windows/RconWindow.xaml.cs
@@ -316,7 +316,6 @@ namespace ServerManagerTool
inputBox.Visibility = Visibility.Collapsed;
dockPanel.IsEnabled = true;
- PlayerInfo player;
var inputText = inputTextBox.Text;
switch (this.CurrentInputWindowMode)
@@ -542,7 +541,7 @@ namespace ServerManagerTool
ProfileId = server.Runtime.ProfileSnapshot.ProfileId,
ProfileName = server.Runtime.ProfileSnapshot.ProfileName,
MaxPlayers = server.Runtime.MaxPlayers,
- RconHost = server.Runtime.ProfileSnapshot.ServerIP,
+ RconHost = server.Runtime.ProfileSnapshot.ServerIPAddress.ToString(),
RconPort = server.Runtime.ProfileSnapshot.RconPort,
RconPassword = server.Runtime.ProfileSnapshot.RconPassword,
});
diff --git a/src/ConanServerManager/Windows/ServerMonitorWindow.xaml b/src/ConanServerManager/Windows/ServerMonitorWindow.xaml
index e5c5ab6d..8d28adf1 100644
--- a/src/ConanServerManager/Windows/ServerMonitorWindow.xaml
+++ b/src/ConanServerManager/Windows/ServerMonitorWindow.xaml
@@ -3,15 +3,14 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:cc="clr-namespace:ServerManagerTool.Common.Converters;assembly=ServerManager.Common"
- xmlns:com="clr-namespace:ServerManagerTool.Common;assembly=ServerManager.Common"
+ xmlns:tb="http://www.hardcodet.net/taskbar"
xmlns:clib="clr-namespace:ServerManagerTool.Common.Lib;assembly=ServerManager.Common"
+ xmlns:com="clr-namespace:ServerManagerTool.Common;assembly=ServerManager.Common"
xmlns:enum="clr-namespace:ServerManagerTool.Enums"
xmlns:vm="clr-namespace:ServerManagerTool.Lib.ViewModel"
- xmlns:tb="http://www.hardcodet.net/taskbar"
mc:Ignorable="d"
MinWidth="600" MinHeight="500" Width="900" Height="500" Left="50" Top="50" ResizeMode="CanResize"
- Loaded="Window_Loaded" SizeChanged="Window_SizeChanged" StateChanged="Window_StateChanged"
+ Loaded="ServerMonitorWindow_Loaded" SizeChanged="ServerMonitorWindow_SizeChanged" StateChanged="ServerMonitorWindow_StateChanged" LocationChanged="ServerMonitorWindow_LocationChanged"
Name="ServerMonitorUI" Icon="../Art/favicon.ico" Title="{DynamicResource ServerMonitor_Title}">
@@ -20,16 +19,7 @@
-
-
-
-
-
-
-
-
-
diff --git a/src/ConanServerManager/Windows/ServerMonitorWindow.xaml.cs b/src/ConanServerManager/Windows/ServerMonitorWindow.xaml.cs
index 7b7990c4..6048faa7 100644
--- a/src/ConanServerManager/Windows/ServerMonitorWindow.xaml.cs
+++ b/src/ConanServerManager/Windows/ServerMonitorWindow.xaml.cs
@@ -53,6 +53,8 @@ namespace ServerManagerTool.Windows
SetWindowTitle();
+ this.Left = Config.Default.ServerMonitorWindow_Left;
+ this.Top = Config.Default.ServerMonitorWindow_Top;
this.Height = Config.Default.ServerMonitorWindow_Height;
this.Width = Config.Default.ServerMonitorWindow_Width;
@@ -86,7 +88,7 @@ namespace ServerManagerTool.Windows
set { SetValue(IsStandAloneWindowProperty, value); }
}
- private void Window_Loaded(object sender, RoutedEventArgs e)
+ private void ServerMonitorWindow_Loaded(object sender, RoutedEventArgs e)
{
if (ServerManager == null)
{
@@ -120,12 +122,16 @@ namespace ServerManagerTool.Windows
}
}
- private void Window_Closed(object sender, EventArgs e)
+ private void ServerMonitorWindow_LocationChanged(object sender, EventArgs e)
{
- this.Activate();
+ if (this.WindowState == WindowState.Normal)
+ {
+ Config.Default.ServerMonitorWindow_Left = Math.Max(0D, this.Left);
+ Config.Default.ServerMonitorWindow_Top = Math.Max(0D, this.Top);
+ }
}
- private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
+ private void ServerMonitorWindow_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (this.WindowState != WindowState.Minimized)
{
@@ -134,7 +140,7 @@ namespace ServerManagerTool.Windows
}
}
- private void Window_StateChanged(object sender, EventArgs e)
+ private void ServerMonitorWindow_StateChanged(object sender, EventArgs e)
{
if (IsStandAloneWindow && Config.Default.MainWindow_MinimizeToTray && this.WindowState == WindowState.Minimized)
{
@@ -142,6 +148,11 @@ namespace ServerManagerTool.Windows
}
}
+ private void Window_Closed(object sender, EventArgs e)
+ {
+ this.Activate();
+ }
+
protected override void OnClosing(CancelEventArgs e)
{
if (this.OwnedWindows.OfType().Any())
@@ -182,7 +193,7 @@ namespace ServerManagerTool.Windows
var profile = ServerProfileSnapshot.Create(server.Profile);
- var exitCode = await Task.Run(() => app.PerformProfileBackup(profile));
+ var exitCode = await Task.Run(() => app.PerformProfileBackup(profile, CancellationToken.None));
if (exitCode != ServerApp.EXITCODE_NORMALEXIT && exitCode != ServerApp.EXITCODE_CANCELLED)
{
throw new ApplicationException($"An error occured during the backup process - ExitCode: {exitCode}");
@@ -620,7 +631,7 @@ namespace ServerManagerTool.Windows
await Task.Delay(1000);
- var branch = new BranchSnapshot() { BranchName = serverProfile.BranchName, BranchPassword = serverProfile.BranchPassword };
+ var branch = BranchSnapshot.Create(serverProfile);
return await server.UpgradeAsync(_upgradeCancellationSource.Token, updateServer, branch, true, updateMods, (p, m, n) => { TaskUtils.RunOnUIThreadAsync(() => { window?.AddMessage(m, n); }).DoNotWait(); });
}
else
diff --git a/src/ConanServerManager/Windows/SettingsWindow.xaml b/src/ConanServerManager/Windows/SettingsWindow.xaml
index 29a26c4f..5bdfcd27 100644
--- a/src/ConanServerManager/Windows/SettingsWindow.xaml
+++ b/src/ConanServerManager/Windows/SettingsWindow.xaml
@@ -14,11 +14,6 @@
-
-
-
-
-
diff --git a/src/ConanServerManager/Windows/SettingsWindow.xaml.cs b/src/ConanServerManager/Windows/SettingsWindow.xaml.cs
index 572a8365..d989298b 100644
--- a/src/ConanServerManager/Windows/SettingsWindow.xaml.cs
+++ b/src/ConanServerManager/Windows/SettingsWindow.xaml.cs
@@ -1,5 +1,4 @@
-using ServerManagerTool.Common;
-using ServerManagerTool.Common.Utils;
+using ServerManagerTool.Common.Utils;
using System;
using System.ComponentModel;
using System.IO;
@@ -101,11 +100,7 @@ namespace ServerManagerTool
Config.Default.SteamCmd_UseAnonymousCredentials = true;
}
- Config.Default.Save();
- CommonConfig.Default.Save();
-
- Config.Default.Reload();
- CommonConfig.Default.Reload();
+ App.SaveConfigFiles(false);
base.OnClosed(e);
}
diff --git a/src/ConanServerManager/Windows/ShutdownWindow.xaml b/src/ConanServerManager/Windows/ShutdownWindow.xaml
index c2f7b22d..e1c5cb14 100644
--- a/src/ConanServerManager/Windows/ShutdownWindow.xaml
+++ b/src/ConanServerManager/Windows/ShutdownWindow.xaml
@@ -2,8 +2,6 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cctl="clr-namespace:ServerManagerTool.Common.Controls;assembly=ServerManager.Common"
- xmlns:cc="clr-namespace:ServerManagerTool.Common.Converters;assembly=ServerManager.Common"
- xmlns:com="clr-namespace:ServerManagerTool.Common;assembly=ServerManager.Common"
xmlns:enum="clr-namespace:ServerManagerTool.Enums"
Width="600" ResizeMode="CanMinimize" SizeToContent="Height" WindowStyle="SingleBorderWindow" WindowStartupLocation="CenterOwner" ShowInTaskbar="True"
Closing="Window_Closing" Closed="Window_Closed"
@@ -14,49 +12,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -221,7 +176,7 @@
diff --git a/src/ConanServerManager/Windows/WorkshopFilesWindow.xaml b/src/ConanServerManager/Windows/WorkshopFilesWindow.xaml
index 8c8d6141..de878895 100644
--- a/src/ConanServerManager/Windows/WorkshopFilesWindow.xaml
+++ b/src/ConanServerManager/Windows/WorkshopFilesWindow.xaml
@@ -11,11 +11,6 @@
-
-
-
-
-
diff --git a/src/ConanServerManager/Windows/WorldSaveRestoreWindow.xaml b/src/ConanServerManager/Windows/WorldSaveRestoreWindow.xaml
index 980ba86f..4f6f9332 100644
--- a/src/ConanServerManager/Windows/WorldSaveRestoreWindow.xaml
+++ b/src/ConanServerManager/Windows/WorldSaveRestoreWindow.xaml
@@ -11,11 +11,6 @@
-
-
-
-
-
diff --git a/src/NeXtVdf/NeXt.Vdf.csproj b/src/NeXtVdf/NeXt.Vdf.csproj
index 23c1c7c0..abf53c66 100644
--- a/src/NeXtVdf/NeXt.Vdf.csproj
+++ b/src/NeXtVdf/NeXt.Vdf.csproj
@@ -1,9 +1,5 @@
- %24/Development/ServerManagers/Main/NeXtVdf
- {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- https://dev.azure.com/bretthewitson
- .
Debug;Release;Debug - Beta
diff --git a/src/NeXtVdf/Properties/AssemblyInfo.cs b/src/NeXtVdf/Properties/AssemblyInfo.cs
index ef1cded9..a02fe98c 100644
--- a/src/NeXtVdf/Properties/AssemblyInfo.cs
+++ b/src/NeXtVdf/Properties/AssemblyInfo.cs
@@ -1,9 +1,6 @@
using System.Reflection;
using System.Runtime.InteropServices;
-// Allgemeine Informationen über eine Assembly werden über die folgenden
-// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
-// die mit einer Assembly verknüpft sind.
[assembly: AssemblyTitle("NeXt.Vdf")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
@@ -13,23 +10,10 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
-// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
-// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
[assembly: ComVisible(false)]
-// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
[assembly: Guid("4a5c4314-a7bc-48a6-938e-58e224bd0879")]
-// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
-//
-// Hauptversion
-// Nebenversion
-// Buildnummer
-// Revision
-//
-// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
-// übernehmen, indem Sie "*" eingeben:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
+// exclude from semantic versioning
+[assembly: AssemblyVersion("1.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/Plugin.Common.UnitTests/Plugin.Common.UnitTests.csproj b/src/Plugin.Common.UnitTests/Plugin.Common.UnitTests.csproj
new file mode 100644
index 00000000..8ecf1e0f
--- /dev/null
+++ b/src/Plugin.Common.UnitTests/Plugin.Common.UnitTests.csproj
@@ -0,0 +1,23 @@
+
+
+ net462
+ false
+ ServerManagerTool.Plugin.Common.UnitTests
+ ServerManager.Plugin.Common.UnitTests
+
+
+ none
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Plugin.Common.UnitTests/PluginHelperUnitTest.cs b/src/Plugin.Common.UnitTests/PluginHelperUnitTest.cs
new file mode 100644
index 00000000..afac442e
--- /dev/null
+++ b/src/Plugin.Common.UnitTests/PluginHelperUnitTest.cs
@@ -0,0 +1,36 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using ServerManagerTool.Plugin.Common;
+using ServerManagerTool.Plugin.Common.Lib;
+using System.Collections.Generic;
+
+namespace Plugin.Common.UnitTests
+{
+ [TestClass]
+ public class PluginHelperUnitTest
+ {
+ [TestMethod]
+ public void PluginHelper_HandleAlert_When_SingleLineMessage_Then_Valid()
+ {
+ // Arrange
+ PluginHelper.Instance.SetFetchProfileCallback(FetchProfiles);
+
+ // Act
+ var profileList = PluginHelper.Instance.FetchProfileList();
+
+ // Assert
+ Assert.IsNotNull(profileList);
+ Assert.IsTrue(profileList.Count == 3);
+ }
+
+ public IList FetchProfiles()
+ {
+ return new List()
+ {
+ new Profile() { ProfileName = "Profile 1", InstallationFolder = @"d:\asmdata\servers\server1" },
+ new Profile() { ProfileName = "Profile 2", InstallationFolder = @"d:\asmdata\servers\server2" },
+ new Profile() { ProfileName = "Profile 3", InstallationFolder = @"d:\asmdata\servers\server3" },
+ };
+ }
+
+ }
+}
diff --git a/src/Plugin.Common.UnitTests/Properties/AssemblyInfo.cs b/src/Plugin.Common.UnitTests/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..b75e0d13
--- /dev/null
+++ b/src/Plugin.Common.UnitTests/Properties/AssemblyInfo.cs
@@ -0,0 +1,19 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Plugin.Common.UnitTests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Bletch1971")]
+[assembly: AssemblyProduct("Plugin.Common.UnitTests")]
+[assembly: AssemblyCopyright("Copyright © 2015-2021")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+
+[assembly: Guid("8d13fc88-9508-4c3a-8ed0-f7bd46e343cc")]
+
+// exclude from semantic versioning
+[assembly: AssemblyVersion("1.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/Plugin.Common/Plugin.Common.csproj b/src/Plugin.Common/Plugin.Common.csproj
index f77c2699..bd7566f4 100644
--- a/src/Plugin.Common/Plugin.Common.csproj
+++ b/src/Plugin.Common/Plugin.Common.csproj
@@ -1,9 +1,5 @@
- %24/Development/ServerManagers/Main/Plugin.Common
- {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- https://dev.azure.com/bretthewitson
- .
Debug;Release;Debug - Beta
diff --git a/src/Plugin.Common/PluginHelper.cs b/src/Plugin.Common/PluginHelper.cs
index 20c1ea03..8f66f984 100644
--- a/src/Plugin.Common/PluginHelper.cs
+++ b/src/Plugin.Common/PluginHelper.cs
@@ -15,6 +15,7 @@ namespace ServerManagerTool.Plugin.Common
{
private const string PLUGINFILE_FOLDER = "Plugins";
private const string PLUGINFILE_EXTENSION = "dll";
+ public const string LANGUAGECODE_FALLBACK = "en-US";
private static volatile PluginHelper _instance;
private static readonly object _syncLock = new object();
@@ -27,6 +28,7 @@ namespace ServerManagerTool.Plugin.Common
private PluginHelper()
{
BetaEnabled = false;
+ LanguageCode = LANGUAGECODE_FALLBACK;
Plugins = new ObservableCollection();
}
@@ -61,6 +63,12 @@ namespace ServerManagerTool.Plugin.Common
set;
}
+ public string LanguageCode
+ {
+ get;
+ set;
+ }
+
public ObservableCollection Plugins
{
get;
@@ -236,6 +244,11 @@ namespace ServerManagerTool.Plugin.Common
}
}
+ public void OnResourceDictionaryChanged(string languageCode)
+ {
+ LanguageCode = languageCode;
+ }
+
internal void OpenConfigForm(string pluginCode, Window owner)
{
if (Plugins == null)
diff --git a/src/Plugin.Common/Properties/AssemblyInfo.cs b/src/Plugin.Common/Properties/AssemblyInfo.cs
index 6341e078..98970ca1 100644
--- a/src/Plugin.Common/Properties/AssemblyInfo.cs
+++ b/src/Plugin.Common/Properties/AssemblyInfo.cs
@@ -2,37 +2,21 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
[assembly: AssemblyTitle("ServerManager Common Plugin Library")]
[assembly: AssemblyDescription("The library is used to provide common plugin functionality to the server managers.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Bletch1971")]
[assembly: AssemblyProduct("Server Managers")]
-[assembly: AssemblyCopyright("Copyright © 2015-2020")]
+[assembly: AssemblyCopyright("Copyright © 2015-2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
-// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("679fe859-9a82-4ffb-a758-c1e8df915f58")]
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-[assembly: AssemblyVersion("1.0.1.0")]
-[assembly: AssemblyFileVersion("1.0.1.0")]
+[assembly: AssemblyVersion("1.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: InternalsVisibleTo("ARK Server Manager")]
[assembly: InternalsVisibleTo("ConanServerManager")]
diff --git a/src/Plugin.Common/Utils/ResourceUtils.cs b/src/Plugin.Common/Utils/ResourceUtils.cs
index 18b9ae62..649219d6 100644
--- a/src/Plugin.Common/Utils/ResourceUtils.cs
+++ b/src/Plugin.Common/Utils/ResourceUtils.cs
@@ -1,5 +1,10 @@
using System;
+using System.IO;
+using System.Linq;
+using System.Reflection;
using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Markup;
namespace ServerManagerTool.Plugin.Common
{
@@ -21,5 +26,111 @@ namespace ServerManagerTool.Plugin.Common
}
return null;
}
+
+ public static void RemoveExceptResourceDictionary(Window window, string dictionaryName)
+ {
+ if (window == null || string.IsNullOrWhiteSpace(dictionaryName))
+ return;
+
+ var dictionariesToRemove = window.Resources.MergedDictionaries.Where(d => !d.Source.OriginalString.Contains(dictionaryName)).ToList();
+ if (dictionariesToRemove != null)
+ {
+ foreach (var dictionaryToRemove in dictionariesToRemove)
+ {
+ window.Resources.MergedDictionaries.Remove(dictionaryToRemove);
+ }
+ }
+ }
+
+ public static void RemoveExceptResourceDictionary(UserControl control, string dictionaryName)
+ {
+ if (control == null || string.IsNullOrWhiteSpace(dictionaryName))
+ return;
+
+ var dictionariesToRemove = control.Resources.MergedDictionaries.Where(d => !d.Source.OriginalString.Contains(dictionaryName)).ToList();
+ if (dictionariesToRemove != null)
+ {
+ foreach (var dictionaryToRemove in dictionariesToRemove)
+ {
+ control.Resources.MergedDictionaries.Remove(dictionaryToRemove);
+ }
+ }
+ }
+
+ public static void RemoveResourceDictionary(Window window, string dictionaryName)
+ {
+ if (window == null || string.IsNullOrWhiteSpace(dictionaryName))
+ return;
+
+ var dictionaryToRemove = window.Resources.MergedDictionaries.FirstOrDefault(d => d.Source.OriginalString.Contains(dictionaryName));
+ if (dictionaryToRemove != null)
+ {
+ window.Resources.MergedDictionaries.Remove(dictionaryToRemove);
+ }
+ }
+
+ public static void RemoveResourceDictionary(UserControl control, string dictionaryName)
+ {
+ if (control == null || string.IsNullOrWhiteSpace(dictionaryName))
+ return;
+
+ var dictionaryToRemove = control.Resources.MergedDictionaries.FirstOrDefault(d => d.Source.OriginalString.Contains(dictionaryName));
+ if (dictionaryToRemove != null)
+ {
+ control.Resources.MergedDictionaries.Remove(dictionaryToRemove);
+ }
+ }
+
+ public static void UpdateResourceDictionary(Window window, string languageCode)
+ {
+ if (window == null)
+ return;
+
+ RemoveExceptResourceDictionary(window, PluginHelper.LANGUAGECODE_FALLBACK);
+
+ var assembly = Assembly.GetCallingAssembly();
+
+ var resourcePath = assembly.GetManifestResourceNames().FirstOrDefault(r => r.EndsWith($"{languageCode}.xaml"));
+ if (string.IsNullOrWhiteSpace(resourcePath))
+ return;
+
+ using (Stream stream = assembly.GetManifestResourceStream(resourcePath))
+ {
+ using (StreamReader reader = new StreamReader(stream))
+ {
+ var resourceDictionary = XamlReader.Load(reader.BaseStream) as ResourceDictionary;
+ if (resourceDictionary != null)
+ {
+ window.Resources.MergedDictionaries.Add(resourceDictionary);
+ }
+ }
+ }
+ }
+
+ public static void UpdateResourceDictionary(UserControl control, string languageCode)
+ {
+ if (control == null)
+ return;
+
+ RemoveExceptResourceDictionary(control, PluginHelper.LANGUAGECODE_FALLBACK);
+
+ var assembly = Assembly.GetCallingAssembly();
+
+ var resourcePath = assembly.GetManifestResourceNames().FirstOrDefault(r => r.EndsWith($"{languageCode}.xaml"));
+ if (string.IsNullOrWhiteSpace(resourcePath))
+ return;
+
+ using (Stream stream = assembly.GetManifestResourceStream(resourcePath))
+ {
+ using (StreamReader reader = new StreamReader(stream))
+ {
+ var resourceDictionary = XamlReader.Load(reader.BaseStream) as ResourceDictionary;
+ if (resourceDictionary != null)
+ {
+ control.Resources.MergedDictionaries.Add(resourceDictionary);
+ }
+ }
+ }
+ }
}
}
diff --git a/src/Plugin.Discord.Guide/Capture.PNG b/src/Plugin.Discord.Guide/Capture.PNG
new file mode 100644
index 00000000..abceaf74
Binary files /dev/null and b/src/Plugin.Discord.Guide/Capture.PNG differ
diff --git a/src/Plugin.Discord.Guide/Capture1.PNG b/src/Plugin.Discord.Guide/Capture1.PNG
new file mode 100644
index 00000000..b18ec1e4
Binary files /dev/null and b/src/Plugin.Discord.Guide/Capture1.PNG differ
diff --git a/src/Plugin.Discord.Guide/Capture2.PNG b/src/Plugin.Discord.Guide/Capture2.PNG
new file mode 100644
index 00000000..5e5dea3d
Binary files /dev/null and b/src/Plugin.Discord.Guide/Capture2.PNG differ
diff --git a/src/Plugin.Discord.Guide/Capture3.PNG b/src/Plugin.Discord.Guide/Capture3.PNG
new file mode 100644
index 00000000..310e903a
Binary files /dev/null and b/src/Plugin.Discord.Guide/Capture3.PNG differ
diff --git a/src/Plugin.Discord.Guide/Capture4.PNG b/src/Plugin.Discord.Guide/Capture4.PNG
new file mode 100644
index 00000000..98965219
Binary files /dev/null and b/src/Plugin.Discord.Guide/Capture4.PNG differ
diff --git a/src/Plugin.Discord.Guide/Capture5.PNG b/src/Plugin.Discord.Guide/Capture5.PNG
new file mode 100644
index 00000000..a8863e82
Binary files /dev/null and b/src/Plugin.Discord.Guide/Capture5.PNG differ
diff --git a/src/Plugin.Discord.Guide/Capture6.PNG b/src/Plugin.Discord.Guide/Capture6.PNG
new file mode 100644
index 00000000..59b010dd
Binary files /dev/null and b/src/Plugin.Discord.Guide/Capture6.PNG differ
diff --git a/src/Plugin.Discord.Guide/Capture7.PNG b/src/Plugin.Discord.Guide/Capture7.PNG
new file mode 100644
index 00000000..fa4ef3cf
Binary files /dev/null and b/src/Plugin.Discord.Guide/Capture7.PNG differ
diff --git a/src/Plugin.Discord.Guide/Capture8.PNG b/src/Plugin.Discord.Guide/Capture8.PNG
new file mode 100644
index 00000000..7ddfd3d3
Binary files /dev/null and b/src/Plugin.Discord.Guide/Capture8.PNG differ
diff --git a/src/Plugin.Discord.Guide/Capture9.PNG b/src/Plugin.Discord.Guide/Capture9.PNG
new file mode 100644
index 00000000..178a5bfd
Binary files /dev/null and b/src/Plugin.Discord.Guide/Capture9.PNG differ
diff --git a/src/Plugin.Discord.Guide/CaptureA.PNG b/src/Plugin.Discord.Guide/CaptureA.PNG
new file mode 100644
index 00000000..af7c77c1
Binary files /dev/null and b/src/Plugin.Discord.Guide/CaptureA.PNG differ
diff --git a/src/Plugin.Discord.Guide/CaptureB.PNG b/src/Plugin.Discord.Guide/CaptureB.PNG
new file mode 100644
index 00000000..5facfe43
Binary files /dev/null and b/src/Plugin.Discord.Guide/CaptureB.PNG differ
diff --git a/src/Plugin.Discord.Guide/Discord Plugin Guide.docx b/src/Plugin.Discord.Guide/Discord Plugin Guide.docx
new file mode 100644
index 00000000..e9725ba8
Binary files /dev/null and b/src/Plugin.Discord.Guide/Discord Plugin Guide.docx differ
diff --git a/src/Plugin.Discord.UnitTests/DiscordPluginUnitTest.cs b/src/Plugin.Discord.UnitTests/DiscordPluginUnitTest.cs
new file mode 100644
index 00000000..f71c99c1
--- /dev/null
+++ b/src/Plugin.Discord.UnitTests/DiscordPluginUnitTest.cs
@@ -0,0 +1,361 @@
+using ServerManagerTool.Plugin.Discord;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Text;
+using System.Threading.Tasks;
+using System.Collections.Generic;
+using ServerManagerTool.Plugin.Common.Lib;
+
+namespace Plugin.Discord.UnitTests
+{
+ [TestClass]
+ public class DiscordPluginUnitTest
+ {
+ [TestMethod]
+ public void DiscordPlugin_HandleAlert_When_SingleLineMessage_Then_Valid()
+ {
+ // Arrange
+ var plugin = new DiscordPlugin();
+ plugin.Initialize();
+
+ var alertMessage = new StringBuilder();
+ alertMessage.AppendLine("The server has been started.");
+
+ // Act
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.Startup, "Server 1", alertMessage.ToString());
+
+ // Assert
+ Assert.IsTrue(true);
+ }
+
+ [TestMethod]
+ public void DiscordPlugin_HandleAlert_When_SingleLineUnicodeMessage_Then_Valid()
+ {
+ // Arrange
+ var plugin = new DiscordPlugin();
+ plugin.Initialize();
+
+ var alertMessage = new StringBuilder();
+ alertMessage.AppendLine("Требуется перезагрузка сервера. Сейчас сервер будет выключен.");
+
+ // Act
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.Startup, "Server 1", alertMessage.ToString());
+
+ // Assert
+ Assert.IsTrue(true);
+ }
+
+ [TestMethod]
+ public void DiscordPlugin_HandleAlert_When_SingleLineSpecialCharacterMessage_Then_Valid()
+ {
+ // Arrange
+ var plugin = new DiscordPlugin();
+ plugin.Initialize();
+
+ var alertMessage = new StringBuilder();
+ alertMessage.AppendLine("Update performed, includes: Structures Plus (S+) (731604991)");
+
+ // Act
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.Startup, "Server 1", alertMessage.ToString());
+
+ // Assert
+ Assert.IsTrue(true);
+ }
+
+ [TestMethod]
+ public void DiscordPlugin_HandleAlert_When_MultipleLineMessage_Then_Valid()
+ {
+ // Arrange
+ var plugin = new DiscordPlugin();
+ plugin.Initialize();
+
+ var alertMessage = new StringBuilder();
+ alertMessage.AppendLine("The server is being shutdown.");
+ alertMessage.AppendLine("Please logout to avoid profile corruption.");
+
+ // Act
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.Shutdown, "Server 2", alertMessage.ToString());
+
+ // Assert
+ Assert.IsTrue(true);
+ }
+
+ [TestMethod]
+ public void DiscordPlugin_HandleAlert_When_MultipleLineMessageInOneLine_Then_Valid()
+ {
+ // Arrange
+ var plugin = new DiscordPlugin();
+ plugin.Initialize();
+
+ //var alertMessage = new StringBuilder();
+ //alertMessage.AppendLine("The server is being shutdown.\r\nPlease logout to avoid profile corruption.");
+ var alertMessage = "Server restart required.\r\n\r\nServer will restart in {minutes} minutes. \r\n\r\nPlease logout before restart to prevent character corruption.";
+
+ // Act
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.Shutdown, "Server 2", alertMessage);
+
+ // Assert
+ Assert.IsTrue(true);
+ }
+
+ [TestMethod]
+ public void DiscordPlugin_HandleAlert_When_ErrorAlertType_Then_Valid()
+ {
+ // Arrange
+ var plugin = new DiscordPlugin();
+ plugin.Initialize();
+
+ var alertMessage = new StringBuilder();
+ alertMessage.AppendLine("The server encountered an error while starting.");
+
+ // Act
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.Error, "Server 1", alertMessage.ToString());
+
+ // Assert
+ Assert.IsTrue(true);
+ }
+
+ [TestMethod]
+ public void DiscordPlugin_HandleAlert_When_SingleLineMessageToUnknownProfileName_Then_NoAlertSent()
+ {
+ // Arrange
+ var plugin = new DiscordPlugin();
+ plugin.Initialize();
+
+ var alertMessage = new StringBuilder();
+ alertMessage.AppendLine("The server has been started.");
+
+ // Act
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.Startup, "", alertMessage.ToString());
+
+ // Assert
+ Assert.IsTrue(true);
+ }
+
+ [TestMethod]
+ public void DiscordPlugin_HandleAlert_When_ExtraLongMessage_Then_AlertTruncated()
+ {
+ // Arrange
+ var plugin = new DiscordPlugin();
+ plugin.Initialize();
+
+ var alertMessage = new StringBuilder();
+ alertMessage.AppendLine("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus ac lorem pretium, volutpat massa ut, iaculis augue. Aenean condimentum gravida laoreet. Morbi mattis leo non enim imperdiet dignissim. Donec et consectetur est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur leo ipsum, commodo sed ante eu, vulputate maximus nulla. In sollicitudin, magna ut fringilla scelerisque, neque nulla semper nunc, at tempus nibh mi quis diam. Nunc quis tortor neque. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.");
+ alertMessage.AppendLine("Maecenas ultrices in est a iaculis.Sed eget pharetra nibh.Duis luctus neque id iaculis vestibulum.Duis condimentum sapien metus, at pretium dui aliquam ullamcorper.Sed at efficitur tellus.Praesent eget ex blandit orci venenatis fringilla et in ex.Curabitur id mauris sed augue pharetra ornare.Integer at malesuada nisl, id blandit orci.");
+ alertMessage.AppendLine("Ut ac dolor non ex porta lobortis.Aliquam sollicitudin nec justo ac finibus.Aliquam condimentum malesuada luctus.Nam ut ornare justo, a scelerisque sapien.Vivamus eget nisi risus.Morbi ut tellus ultricies arcu sagittis eleifend.Praesent eu augue in eros egestas rhoncus eu sed quam.");
+ alertMessage.AppendLine("Quisque quis facilisis ipsum.In egestas pulvinar urna, id maximus lorem vehicula nec.Fusce vel nibh tincidunt, semper risus a, consectetur nunc.Morbi at lorem libero.Donec diam eros, aliquet in enim vitae, ornare malesuada nisi.Donec a mi pharetra dolor dignissim dapibus at vel velit.Praesent tincidunt, ipsum eget finibus cursus, ex turpis accumsan dui, ut hendrerit ante tortor vitae urna.Nulla faucibus ipsum nec tellus congue rhoncus.Maecenas sed tortor placerat, lobortis arcu sit amet, pellentesque sapien.Praesent sit amet feugiat massa.");
+ alertMessage.AppendLine("Vestibulum eu felis accumsan, vehicula metus ut, gravida nulla.Sed pharetra sed ex vel sodales.In vestibulum, nisl vitae ultricies mattis, lacus massa maximus nunc, id suscipit lorem ligula id tortor.Donec porttitor diam ac turpis posuere aliquam.Phasellus non sed.");
+
+ // Act
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.Shutdown, "Server 3", alertMessage.ToString());
+
+ // Assert
+ Assert.IsTrue(true);
+ }
+
+ [TestMethod]
+ public void DiscordPlugin_HandleAlert_When_SendingMultipleMessagesSingleServer_Then_Valid()
+ {
+ var plugin = new DiscordPlugin();
+ plugin.Initialize();
+
+ SendMultipleMessages(plugin, "Server 1");
+ }
+
+ [TestMethod]
+ public void DiscordPlugin_HandleAlert_When_SendingMultipleMessagesMultipleServers_Sync_Then_Valid()
+ {
+ // Arrange
+ var plugin = new DiscordPlugin();
+ plugin.Initialize();
+
+ var alertMessage1 = new StringBuilder();
+ alertMessage1.AppendLine("Message 1 - shutdown 1.");
+ var alertMessage2 = new StringBuilder();
+ alertMessage2.AppendLine("Message 2 - shutdown 2.");
+ var alertMessage3 = new StringBuilder();
+ alertMessage3.AppendLine("Message 3 - start.");
+ var alertMessage4 = new StringBuilder();
+ alertMessage4.AppendLine("Message 4 - update reason.");
+
+ // Act
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.ShutdownMessage, "Server 1", alertMessage1.ToString());
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.ShutdownMessage, "Server 2", alertMessage1.ToString());
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.ShutdownMessage, "Server 3", alertMessage1.ToString());
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.ShutdownMessage, "Server 4", alertMessage1.ToString());
+ Task.Delay(2000).Wait();
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.ShutdownMessage, "Server 1", alertMessage2.ToString());
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.ShutdownMessage, "Server 2", alertMessage2.ToString());
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.ShutdownMessage, "Server 3", alertMessage2.ToString());
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.ShutdownMessage, "Server 4", alertMessage2.ToString());
+ Task.Delay(2000).Wait();
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.Startup, "Server 1", alertMessage3.ToString());
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.Startup, "Server 2", alertMessage3.ToString());
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.Startup, "Server 3", alertMessage3.ToString());
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.Startup, "Server 4", alertMessage3.ToString());
+ Task.Delay(2000).Wait();
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.UpdateResults, "Server 1", alertMessage4.ToString());
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.UpdateResults, "Server 2", alertMessage4.ToString());
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.UpdateResults, "Server 3", alertMessage4.ToString());
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.UpdateResults, "Server 4", alertMessage4.ToString());
+
+ // Assert
+ Assert.IsTrue(true);
+ }
+
+ [TestMethod]
+ public void DiscordPlugin_HandleAlert_When_SendingMultipleMessagesMultipleServers_ASync_Then_Valid()
+ {
+ var plugin = new DiscordPlugin();
+ plugin.Initialize();
+
+ Parallel.For(1, 9, (i) => {
+ switch (i)
+ {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ SendMultipleMessages(plugin, $"Server {i}");
+ break;
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ SendMultipleErrors(plugin, $"Server {i-4}");
+ break;
+ }
+ });
+ }
+
+ private void SendMultipleMessages(DiscordPlugin plugin, string profileName)
+ {
+ // Arrange
+ Random rnd = new Random();
+ var alertMessage1 = new StringBuilder();
+ alertMessage1.AppendLine("Message 1 - shutdown 1.");
+ var alertMessage2 = new StringBuilder();
+ alertMessage2.AppendLine("Message 2 - shutdown 2.");
+ var alertMessage3 = new StringBuilder();
+ alertMessage3.AppendLine("Message 3 - start.");
+ var alertMessage4 = new StringBuilder();
+ alertMessage4.AppendLine("Message 4 - update reason.");
+
+ // Act
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.ShutdownMessage, profileName, alertMessage1.ToString());
+ Task.Delay(rnd.Next(1000, 5000)).Wait();
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.ShutdownMessage, profileName, alertMessage2.ToString());
+ Task.Delay(rnd.Next(1000, 5000)).Wait();
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.Startup, profileName, alertMessage3.ToString());
+ Task.Delay(rnd.Next(1000, 5000)).Wait();
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.UpdateResults, profileName, alertMessage4.ToString());
+
+ // Assert
+ Assert.IsTrue(true);
+ }
+
+ private void SendMultipleErrors(DiscordPlugin plugin, string profileName)
+ {
+ // Arrange
+ Random rnd = new Random();
+ var alertMessage1 = new StringBuilder();
+ alertMessage1.AppendLine("Error 1.");
+ var alertMessage2 = new StringBuilder();
+ alertMessage2.AppendLine("Error 2.");
+
+ // Act
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.Error, profileName, alertMessage1.ToString());
+ Task.Delay(rnd.Next(1000, 5000)).Wait();
+ plugin.HandleAlert(ServerManagerTool.Plugin.Common.AlertType.Error, profileName, alertMessage2.ToString());
+
+ // Assert
+ Assert.IsTrue(true);
+ }
+
+ [TestMethod]
+ public void DiscordPlugin_OpenConfigForm()
+ {
+ // Arrange
+ ServerManagerTool.Plugin.Common.PluginHelper.Instance.SetFetchProfileCallback(FetchProfiles);
+
+ var plugin = new DiscordPlugin();
+ plugin.Initialize();
+
+ // Act
+ plugin.OpenConfigForm(null);
+
+ // Assert
+ Assert.IsTrue(true);
+ }
+
+ [TestMethod]
+ public void DiscordPlugin_OpenConfigForm_DebugMode()
+ {
+ // Arrange
+ ServerManagerTool.Plugin.Common.PluginHelper.Instance.SetFetchProfileCallback(FetchProfiles);
+
+ var plugin = new DiscordPlugin();
+ plugin.BetaEnabled = true;
+ plugin.Initialize();
+
+ // Act
+ plugin.OpenConfigForm(null);
+
+ // Assert
+ Assert.IsTrue(true);
+ }
+
+ [TestMethod]
+ public void DiscordPlugin_OpenConfigForm_SwitchingLanguages()
+ {
+ // Arrange
+ ServerManagerTool.Plugin.Common.PluginHelper.Instance.SetFetchProfileCallback(FetchProfiles);
+
+ var plugin = new DiscordPlugin();
+ plugin.BetaEnabled = true;
+ plugin.Initialize();
+
+ // Act
+ plugin.OpenConfigForm(null);
+
+ // Assert
+ Assert.IsTrue(true);
+
+ // Arrange
+ ServerManagerTool.Plugin.Common.PluginHelper.Instance.OnResourceDictionaryChanged("zh-CN");
+
+ // Act
+ plugin.OpenConfigForm(null);
+
+ // Assert
+ Assert.IsTrue(true);
+ }
+
+ [TestMethod]
+ public void DiscordPlugin_OpenConfigForm_WithDifferentLanguage()
+ {
+ // Arrange
+ ServerManagerTool.Plugin.Common.PluginHelper.Instance.OnResourceDictionaryChanged("pt-BR");
+
+ var plugin = new DiscordPlugin();
+ plugin.BetaEnabled = true;
+ plugin.Initialize();
+
+ // Act
+ plugin.OpenConfigForm(null);
+
+ // Assert
+ Assert.IsTrue(true);
+ }
+
+ private IList FetchProfiles()
+ {
+ return new List()
+ {
+ new Profile() { ProfileName = "Profile 1", InstallationFolder = @"d:\asmdata\servers\server1" },
+ new Profile() { ProfileName = "Profile 2", InstallationFolder = @"d:\asmdata\servers\server2" },
+ new Profile() { ProfileName = "Profile 3", InstallationFolder = @"d:\asmdata\servers\server3" },
+ };
+ }
+ }
+}
diff --git a/src/Plugin.Discord.UnitTests/Plugin.Discord.UnitTests.csproj b/src/Plugin.Discord.UnitTests/Plugin.Discord.UnitTests.csproj
new file mode 100644
index 00000000..e5b324a3
--- /dev/null
+++ b/src/Plugin.Discord.UnitTests/Plugin.Discord.UnitTests.csproj
@@ -0,0 +1,25 @@
+
+
+ net462
+ false
+ ServerManagerTool.Plugin.Discord.UnitTests
+ ServerManager.Plugin.Discord.UnitTests
+
+
+ none
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Plugin.Discord.UnitTests/Properties/AssemblyInfo.cs b/src/Plugin.Discord.UnitTests/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..7176e82a
--- /dev/null
+++ b/src/Plugin.Discord.UnitTests/Properties/AssemblyInfo.cs
@@ -0,0 +1,19 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Plugin.Discord.UnitTests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Bletch1971")]
+[assembly: AssemblyProduct("Plugin.Discord.UnitTests")]
+[assembly: AssemblyCopyright("Copyright © 2015-2021")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+
+[assembly: Guid("8d13fc88-9508-4c3a-8ed0-f7bd46e343cc")]
+
+// exclude from semantic versioning
+[assembly: AssemblyVersion("1.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/Plugin.Discord/DiscordPlugin.cs b/src/Plugin.Discord/DiscordPlugin.cs
index f3d3cb91..26f59402 100644
--- a/src/Plugin.Discord/DiscordPlugin.cs
+++ b/src/Plugin.Discord/DiscordPlugin.cs
@@ -38,6 +38,8 @@ namespace ServerManagerTool.Plugin.Discord
public bool Enabled => true;
+ public string ConfigFile => Path.Combine(PluginHelper.PluginFolder, Config.Default.ConfigFile);
+
public string PluginCode => Config.Default.PluginCode;
public string PluginName => Config.Default.PluginName;
@@ -59,6 +61,28 @@ namespace ServerManagerTool.Plugin.Discord
public bool HasConfigForm => true;
+ public string LanguageCode
+ {
+ get
+ {
+ var assembly = typeof(PluginHelper).Assembly;
+ if (assembly != null)
+ {
+ var pluginHelperType = assembly.GetType(typeof(PluginHelper).FullName, false, true);
+ if (pluginHelperType != null)
+ {
+ var property = pluginHelperType.GetProperty(nameof(LanguageCode));
+ if (property != null)
+ {
+ return property.GetValue(PluginHelper.Instance).ToString();
+ }
+ }
+ }
+
+ return "en-US";
+ }
+ }
+
private async Task CallHomeAsync()
{
try
@@ -205,56 +229,50 @@ namespace ServerManagerTool.Plugin.Discord
}
}
- private void LoadConfig()
+ internal void BackupConfig()
{
- try
+ if (!File.Exists(ConfigFile))
+ return;
+
+ var backupFile = Path.ChangeExtension(ConfigFile, "bak");
+ File.Copy(ConfigFile, backupFile, true);
+ }
+
+ internal void LoadConfig()
+ {
+ PluginConfig = null;
+
+ if (File.Exists(ConfigFile))
{
- PluginConfig = null;
-
- var configFile = Path.Combine(PluginHelper.PluginFolder, Config.Default.ConfigFile);
- PluginConfig = JsonUtils.DeserializeFromFile(configFile);
-
- if ((PluginConfig?.ConfigProfiles?.Count ?? 0) == 0)
- {
- PluginConfig = new DiscordPluginConfig();
-
- SaveConfig();
- }
-
- PluginConfig?.CommitChanges();
+ PluginConfig = JsonUtils.DeserializeFromFile(ConfigFile);
}
- catch (Exception ex)
+ else
{
PluginConfig = new DiscordPluginConfig();
- Debug.WriteLine($"ERROR: {nameof(LoadConfig)}\r\n{ex.Message}");
+ SaveConfig();
}
+
+ if (PluginConfig is null)
+ {
+ throw new Exception("Profile config file could not be loaded.");
+ }
+
+ PluginConfig.CommitChanges();
}
public void OpenConfigForm(Window owner)
{
- var window = new ConfigWindow(this, this.PluginConfig);
+ var window = new ConfigWindow(this, PluginConfig);
window.Owner = owner;
+ window.ShowDialog();
- var dialogResult = window.ShowDialog();
- if (dialogResult.HasValue && dialogResult.Value)
- {
- SaveConfig();
- LoadConfig();
- }
+ LoadConfig();
}
- private void SaveConfig()
+ internal void SaveConfig()
{
- try
- {
- var configFile = Path.Combine(PluginHelper.PluginFolder, Config.Default.ConfigFile);
- JsonUtils.SerializeToFile(PluginConfig, configFile);
- PluginConfig?.CommitChanges();
- }
- catch (Exception ex)
- {
- Debug.WriteLine($"ERROR: {nameof(SaveConfig)}\r\n{ex.Message}");
- }
+ JsonUtils.SerializeToFile(PluginConfig, ConfigFile);
+ PluginConfig.CommitChanges();
}
}
}
diff --git a/src/Plugin.Discord/Globalization/de-DE/de-DE.xaml b/src/Plugin.Discord/Globalization/de-DE/de-DE.xaml
new file mode 100644
index 00000000..fdf42138
--- /dev/null
+++ b/src/Plugin.Discord/Globalization/de-DE/de-DE.xaml
@@ -0,0 +1,131 @@
+
+
+
+ Sicherung
+ Fehler
+ Mod Update Entdeckt
+ Herunterfahren
+ Herunterfahren Nachricht
+ Herunterfahren Grund
+ Server Status Änderung
+ Gestartet
+ Update Ergebnisse
+
+
+
+ Abbrechen
+ Schließen
+ OK
+ Speichern
+
+ (Beta Modus)
+ Eine neue Version des Plugins ist verfügbar.
+ Lade die neueste Version herunter.
+
+
+
+ Discord Plugin Konfiguration
+
+ Zeigen Sie die Patch Notes.
+ Profil hinzufügen
+ Alle Profile löschen
+ Profil löschen
+ Profil bearbeiten
+
+ Name
+
+ Aktion Fehler hinzufügen
+ Beim Versuch, ein Profil hinzuzufügen, ist ein Fehler aufgetreten.
+ Bestätigen Sie das Löschen aller Aktionen
+ Klicken Sie auf "Ja", um zu bestätigen, dass Sie alles löschen möchten.
+ Löschen Sie alle Fehler Aktion
+ Beim Versuch, alle Profile zu löschen, ist ein Fehler aufgetreten.
+ Bestätigen Sie Aktion schließen
+ Klicken Sie auf "Ja", um zu bestätigen, dass Sie das Formular schließen möchten. Eventuell noch nicht gespeicherte Änderungen gehen dabei verloren.
+ Bestätigen Sie die Löschaktion
+ Klicken Sie auf "Ja", um zu bestätigen, dass Sie die Löschung durchführen möchten.
+ Fehler Aktion löschen
+ Beim Versuch, das Profil zu löschen, ist ein Fehler aufgetreten.
+ Aktion Fehler herunterladen
+ Bei dem Versuch, den Download durchzuführen, ist ein Fehler aufgetreten.
+ Download Erfolgreich
+ Die neueste Version wurde auf Ihrem Desktop gespeichert.
+ Fehler Aktion bearbeiten
+ Beim Versuch, ein Profil zu bearbeiten, ist ein Fehler aufgetreten.
+ Fehler beim Speichern von Aktionen
+ Beim Versuch, die Speicherung durchzuführen, ist ein Fehler aufgetreten.
+
+
+
+ Profil Konfiguration
+
+ Name:
+ Der Name Ihres Konfigurationsprofils.
+ Aktiviert
+ Konfigurationsprofil aktiviern.
+ Webhook Url:
+ Dies ist Ihre Webhook Url, die von discord bereitgestellt wird.
+ Bot Name:
+ Damit wird der Name, den Sie in Ihrem Webhook vergeben haben, überschrieben. Lassen Sie ihn leer, um den Standard zu verwenden.
+ Text zu Sprache (TTS) verwenden
+ Wenn diese Option aktiviert ist, wird der Bot mit Text zu Sprache angesagt, andernfalls wird Text zu Sprache deaktiviert.
+ Präfix Nachricht mit Profilname
+ Wenn diese Option aktiviert ist, wird dem Alarm der Name des Server Manager Profils vorangestellt.
+ Nachrichten Optionen
+ Fett
+ Wenn diese Option aktiviert ist, wird die Nachricht in Fetter Schrift angezeigt.
+ Unterstrich
+ Wenn diese Option aktiviert ist, wird die Nachricht mit einem Unterstrich angezeigt.
+ Kursiv
+ Wenn diese Option aktiviert ist, wird die Nachricht kursiv dargestellt.
+ Eingebetteter Code Block
+ Wenn diese Option aktiviert ist, wird die Nachricht in einem eingebetteten Code Block angezeigt.
+ Profil Namen
+ Meldungsarten
+
+ Server Manager Profil Name hinzufügen
+ Alle Server Manager Profil Namen löschen
+ Server Manager Profil Name löschen
+
+ Meldungsart hinzufügen
+ Alle Meldungsarten löschen
+ Meldungsart löschen
+
+ Server Manager Profil Name
+ Meldungsart
+
+ Test
+
+ Aktion Fehler hinzufügen
+ Beim Versuch, eine Meldungsart hinzuzufügen, ist ein Fehler aufgetreten.
+ Beim Versuch, einen Profil Namen hinzuzufügen, ist ein Fehler aufgetreten.
+ Bestätigen Sie die Aktion Alle löschen
+ Klicken Sie auf "Ja", um zu bestätigen, dass Sie alles löschen möchten.
+ Lösche alle Action Fehler
+ Beim Versuch, alle Meldungsarten zu löschen, ist ein Fehler aufgetreten.
+ Beim Versuch, alle Profil Namen zu löschen, ist ein Fehler aufgetreten.
+ Bestätigen Sie Aktion schließen
+ Klicken Sie auf "Ja", um zu bestätigen, dass Sie das Formular schließen möchten. Eventuell noch nicht gespeicherte Änderungen gehen dabei verloren.
+ Bestätigen Sie die Löschaktion
+ Klicken Sie auf "Ja", um zu bestätigen, dass Sie die Löschung durchführen möchten.
+ Lösche Aktion Fehler
+ Beim Versuch, die Meldungsart zu löschen, ist ein Fehler aufgetreten.
+ Beim Versuch, den Profil Namen zu löschen, ist ein Fehler aufgetreten.
+ Test Aktion Fehler
+ Beim Versuch, das Konfigurationsprofil zu testen, ist ein Fehler aufgetreten.
+ Das Profil ist nicht aktiviert und kann nicht getestet werden.
+
+
+
+ Discord Plugin Version Details
+ Fehler beim Laden des Feeds
+
+ Version:
+ Wählen Sie die Version aus, um Details anzuzeigen.
+
+
+
\ No newline at end of file
diff --git a/src/Plugin.Discord/Globalization/en-US/en-US.xaml b/src/Plugin.Discord/Globalization/en-US/en-US.xaml
index 7e86cb25..db83bd89 100644
--- a/src/Plugin.Discord/Globalization/en-US/en-US.xaml
+++ b/src/Plugin.Discord/Globalization/en-US/en-US.xaml
@@ -4,6 +4,18 @@
xmlns:sys="clr-namespace:System;assembly=mscorlib"
>
+
+ Backup
+ Error
+ Mod Update Detected
+ Shutdown
+ Shutdown Message
+ Shutdown Reason
+ Server Status Change
+ Startup
+ Update Results
+
+
Cancel
Close
@@ -106,6 +118,8 @@
Test Action Error
An error occurred while trying to test the config profile.
The profile is not enabled and cannot be tested.
+
+ Test '{0}' alert type message for profile name '{1}'
diff --git a/src/Plugin.Discord/Globalization/fr-FR/fr-FR.xaml b/src/Plugin.Discord/Globalization/fr-FR/fr-FR.xaml
new file mode 100644
index 00000000..f47b41c7
--- /dev/null
+++ b/src/Plugin.Discord/Globalization/fr-FR/fr-FR.xaml
@@ -0,0 +1,131 @@
+
+
+
+ Sauvegarde
+ Erreur
+ Mise à jour Mod détectée
+ Eteindre
+ Message d'arrêt
+ Raison d'arrêt
+ Changement d'état du serveur
+ Démarrage
+ Mettre à jour les résultats
+
+
+
+ Sortie
+ Fermer
+ OK
+ Sauvegarder
+
+ (Mode Beta)
+ Une nouvelle version du plugin est disponible.
+ Téléchargez la dernière version.
+
+
+
+ Configuration du plug-in Discord
+
+ Voir les notes Patch.
+ Ajouter un profil
+ Supprimer tous les profils
+ Supprimer le profil
+ Editer le profil
+
+ Nom
+
+ Ajouter une erreur d'action
+ Une erreur s'est produite lors de la tentative d'ajout d'un profil.
+ Confirmer Supprimer toute action
+ Cliquez sur "Oui" pour confirmer que vous souhaitez supprimer tout.
+ Supprimer toute erreur d'action
+ Une erreur s'est produite lors de la tentative de supprimer tous les profils.
+ Confirmer Fermeture de l'Action
+ Cliquez sur "Oui" pour confirmer que vous souhaitez fermer le formulaire. Si vous avez des modifications non sauvegardées, elles seront perdues.
+ Confirmer Supprimer l'action
+ Cliquez sur "Oui" pour confirmer que vous souhaitez effectuer la suppression..
+ Supprimer l'erreur d'action
+ Une erreur s'est produite lors de la tentative de suppression du profil.
+ Télécharger l'erreur d'action
+ Une erreur s'est produite lors de la tentative d'exécution du téléchargement.
+ Téléchargement réussi
+ La dernière version a été enregistrée sur votre bureau.
+ Edité l'erreur d'action
+ Une erreur s'est produite lors de la tentative de modification d'un profil.
+ Enregistrer l'erreur d'action
+ Une erreur s'est produite lors de la tentative d'exécution de la sauvegarde.
+
+
+
+ Configuration du profil
+
+ Nom:
+ Le nom de votre profil de configuration.
+ Activée
+ La configuration du profil est-il activé?.
+ URL webhook:
+ Ceci est votre URL WebHook fournie par Discord.
+ Nom de bot:
+ Cela remplacera le nom que vous configurez dans votre webhook. Laisser blanc en utilisation par défaut.
+ Utilisez Text to Speech (TTS)
+ Si activé, fera annoncer le bot avec le texte à la parole, sinon coupera le texte au discours.
+ Préfixe du Message avec nom de profil
+ Si activé, le message d'alerte prédéterminé sera envoyé avec le nom du profil au gestionnaire de serveur..
+ Options de message
+ Gras
+ Si activé, affichera le message en gras.
+ Souligner
+ Si activé, affichera le message avec un soulignement.
+ Italique
+ Si activé, affichera le message en italique.
+ Bloc de code intégré
+ Si activé, affichera le message dans un bloc de code intégré.
+ Noms de profil
+ Types d'alerte
+
+ Ajouter le nom du profil de gestionnaire de serveur
+ Supprimer tous les noms de profil du gestionnaire de serveurs
+ Supprimer le nom du profil du gestionnaire de serveur
+
+ Ajouter un type d'alerte
+ Supprimer tous les types d'alertes
+ Supprimer le type d'alerte
+
+ Nom du profil Manager de serveur
+ Type d'alerte
+
+ Test
+
+ Ajouter une erreur d'action
+ Une erreur s'est produite lors de la tentative d'ajout d'un type d'alerte.
+ Une erreur s'est produite lors de la tentative d'ajout d'un nom de profil.
+ Confirmer Supprimer toute action
+ Cliquez sur "Oui" pour confirmer que vous souhaitez supprimer tout.
+ Supprimer toute erreur d'action
+ Une erreur s'est produite lors de la tentative de suppression de tous les types d'alertes.
+ Une erreur s'est produite lors de la tentative de suppression de tous les noms de profil.
+ Confirmer fermeture de l'action
+ Cliquez sur "Oui" pour confirmer que vous souhaitez fermer le formulaire. Si vous avez des modifications non sauvegardées, elles seront perdues.
+ Confirmer Supprimer l'action
+ Cliquez sur "Oui" pour confirmer que vous souhaitez effectuer la suppression..
+ Supprimer l'erreur d'action
+ Une erreur s'est produite lors de la tentative de suppression du type d'alerte.
+ Une erreur s'est produite lors de la tentative de suppression du nom du profil.
+ Erreur du test de l'action
+ Une erreur s'est produite lors de la tentative de test du profil de configuration.
+ Le profil n'est pas activé et ne peut pas être testé.
+
+
+
+ Détails de la version du Plugin Discord
+ Erreur du chargement du flux
+
+ Version:
+ Sélectionnez la version pour afficher les détails.
+
+
+
\ No newline at end of file
diff --git a/src/Plugin.Discord/Globalization/pt-BR/pt-BR.xaml b/src/Plugin.Discord/Globalization/pt-BR/pt-BR.xaml
index 732051e7..27029fa5 100644
--- a/src/Plugin.Discord/Globalization/pt-BR/pt-BR.xaml
+++ b/src/Plugin.Discord/Globalization/pt-BR/pt-BR.xaml
@@ -4,8 +4,20 @@
xmlns:sys="clr-namespace:System;assembly=mscorlib"
>
+
+ Backup
+ Erro
+ Mod Update Detectado
+ Desligar
+ Mensagem de desligamento
+ Motivo de desligamento
+ Mudança de status do servidor
+ Ligar
+ Resultados da atualização
+
+
- Cancela
+ Cancelar
Fechar
OK
Salva
@@ -61,7 +73,7 @@
Isso substituirá o nome que você configurou no seu webhook. Deixe em branco para usar o padrão.
Usar texto para fala (TTS)
Se ativado, fará o bot anunciar com Texto e Voz, caso contrário, desativará Texto e Voz.
- Mensagem de prefixo com nome do perfil do Serve Manager
+ Mensagem em prefixo do perfil
Se ativada, a mensagem de alerta será enviada com o prefixo do nome do perfil do Serve Manager.
Opções de mensagem
Negrito
@@ -86,7 +98,7 @@
Nome do perfil do Serve Manager
Tipo de alerta
- Teste
+ Testar
Erro ao adicionar
Ocorreu um erro ao tentar adicionar um tipo de alerta.
@@ -106,6 +118,8 @@
Erro no teste
Ocorreu um erro ao tentar testar o perfil de configuração.
O perfil não está ativado e não pode ser testado.
+
+ Teste '{0}' tipo de alerta para nome do perfil '{1}'
diff --git a/src/Plugin.Discord/Globalization/zh-CN/zh-CN.xaml b/src/Plugin.Discord/Globalization/zh-CN/zh-CN.xaml
new file mode 100644
index 00000000..3d7a7034
--- /dev/null
+++ b/src/Plugin.Discord/Globalization/zh-CN/zh-CN.xaml
@@ -0,0 +1,119 @@
+
+
+
+ 取消
+ 关
+ OK
+ 保存
+
+ (中等模式)
+ 该插件的新版本可用.
+ 下载最新版本.
+
+
+
+ Discord(开黑)插件配置
+
+ 查看修补程序说明.
+ 添加配置文件
+ 删除所有配置文件
+ 删除配置文件
+ 编辑配置文件
+
+ 名称
+
+ 添加操作错误
+ 尝试添加配置文件时出错.
+ 确认删除所有操作
+ 单击“是”确认要删除所有.
+ 删除所有操作错误
+ 尝试删除所有配置文件时出错.
+ 确认关闭操作
+ 单击“是”确认要关闭表单。如果您有任何未保存的更改,它们将丢失.
+ 确认删除操作
+ 单击“是”确认要执行删除.
+ 单击“是”确认要执行删除操作错误
+ 尝试删除配置文件时出错.
+ 下载操作错误
+ 尝试执行下载时出错.
+ 下载成功
+ 最新版本已保存到您的桌面.
+ 最新版本已保存到桌面编辑操作错误
+ 尝试编辑配置文件时出错.
+ 保存操作错误
+ 尝试执行保存时出错.
+
+
+
+ 配置文件配置
+
+ 名称:
+ 配置配置文件的名称.
+ 启用
+ 配置配置文件是否已启用.
+ Webhook Url:
+ 这是你的 Webhook Url 由discord(开黑)提供.
+ 机器人名称:
+ 这将覆盖您在webhook中设置的名称。留空以使用默认值.
+ 使用文本到语音 (TTS)
+ 如果启用,将使bot通过文本到语音进行公告,否则将关闭文本到语音.
+ 为消息添加配置文件名前缀
+ 如果启用,将发送以服务器管理器配置文件名称为前缀的警报消息.
+ 消息选项
+ 黑体
+ 如果启用,将以黑体显示消息.
+ 下划线
+ 如果启用,将显示带有下划线的消息.
+ 斜体
+ 如果启用,将以斜体显示消息.
+ 以代码的方式
+ 启用CIf后,将以代码的方式.
+ 配置文件名称
+ 警报类型
+
+ 添加服务器管理器配置文件名
+ 删除所有服务器管理器配置文件名称
+ 删除服务器管理器配置文件名
+
+ 添加警报类型
+ 删除所有警报类型
+ 删除警报类型
+
+ 服务器管理器配置文件名称
+ 警报类型
+
+ 测试
+
+ 添加操作错误
+ 尝试添加警报类型时出错.
+ 尝试添加配置文件名时出错.
+ 确认删除所有操作
+ 单击“是”确认要删除所有.
+ 删除所有操作错误
+ 尝试删除所有警报类型时出错.
+ 尝试删除所有配置文件名称时出错.
+ 确认关闭操作
+ 单击“是”确认要关闭表单。如果您有任何未保存的更改,它们将丢失.
+ 确认删除操作
+ 单击“是”确认要执行删除.
+ 删除操作错误
+ 尝试删除警报类型时出错.
+ 尝试删除配置文件名时出错.
+ 测试时错误
+ 尝试测试配置配置文件时出错.
+ 配置文件未启用,无法测试.
+
+
+
+ Discord(开黑)插件版本详细信息
+ 加载进给错误
+
+ 版本:
+ 选择要查看详细信息的版本.
+
+
+
\ No newline at end of file
diff --git a/src/Plugin.Discord/Models/ComboBoxItemList.cs b/src/Plugin.Discord/Models/ComboBoxItemList.cs
index eb0c490c..bc4a4ebd 100644
--- a/src/Plugin.Discord/Models/ComboBoxItemList.cs
+++ b/src/Plugin.Discord/Models/ComboBoxItemList.cs
@@ -2,7 +2,7 @@
namespace ServerManagerTool.Plugin.Discord
{
- public class ComboBoxItemList : ObservableCollection
+ public class ComboBoxItemList : SortableObservableCollection
{
public ComboBoxItemList()
{
diff --git a/src/Plugin.Discord/Models/DiscordPluginConfig.cs b/src/Plugin.Discord/Models/DiscordPluginConfig.cs
index b0705f91..fbea383b 100644
--- a/src/Plugin.Discord/Models/DiscordPluginConfig.cs
+++ b/src/Plugin.Discord/Models/DiscordPluginConfig.cs
@@ -24,12 +24,9 @@ namespace ServerManagerTool.Plugin.Discord
public ObservableList ConfigProfiles
{
get { return Get>(); }
- set { Set(value); }
+ private set { Set(value); }
}
- public override bool HasAnyChanges
- {
- get => base.HasChanges || (ConfigProfiles?.HasAnyChanges ?? false);
- }
+ public override bool HasAnyChanges => base.HasChanges || ConfigProfiles.HasAnyChanges;
}
}
diff --git a/src/Plugin.Discord/Models/SortableObservableCollection.cs b/src/Plugin.Discord/Models/SortableObservableCollection.cs
new file mode 100644
index 00000000..f9221664
--- /dev/null
+++ b/src/Plugin.Discord/Models/SortableObservableCollection.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+
+namespace ServerManagerTool.Plugin.Discord
+{
+ ///
+ /// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed and allows sorting.
+ ///
+ /// The type of elements in the collection.
+ public class SortableObservableCollection : ObservableCollection
+ {
+ public SortableObservableCollection()
+ {
+ }
+
+ public SortableObservableCollection(List list)
+ : base(list)
+ {
+ }
+
+ public SortableObservableCollection(IEnumerable collection)
+ : base(collection)
+ {
+ }
+
+ ///
+ /// Sorts the items of the collection in ascending order according to a key.
+ ///
+ /// The type of the key returned by .
+ /// A function to extract a key from an item.
+ public void Sort(Func keySelector)
+ {
+ InternalSort(Items.OrderBy(keySelector));
+ }
+
+ ///
+ /// Sorts the items of the collection in ascending order according to a key.
+ ///
+ /// The type of the key returned by .
+ /// A function to extract a key from an item.
+ /// An to compare keys.
+ public void Sort(Func keySelector, IComparer comparer)
+ {
+ InternalSort(Items.OrderBy(keySelector, comparer));
+ }
+
+ ///
+ /// Sorts the items of the collection in descending order according to a key.
+ ///
+ /// The type of the key returned by .
+ /// A function to extract a key from an item.
+ public void SortDescending(Func keySelector)
+ {
+ InternalSort(Items.OrderByDescending(keySelector));
+ }
+
+ ///
+ /// Sorts the items of the collection in descending order according to a key.
+ ///
+ /// The type of the key returned by .
+ /// A function to extract a key from an item.
+ /// An to compare keys.
+ public void SortDescending(Func keySelector, IComparer comparer)
+ {
+ InternalSort(Items.OrderByDescending(keySelector, comparer));
+ }
+
+ ///
+ /// Moves the items of the collection so that their orders are the same as those of the items provided.
+ ///
+ /// An to provide item orders.
+ private void InternalSort(IEnumerable sortedItems)
+ {
+ var sortedItemsList = sortedItems.ToList();
+
+ foreach (var item in sortedItemsList)
+ {
+ Move(IndexOf(item), sortedItemsList.IndexOf(item));
+ }
+ }
+ }
+}
diff --git a/src/Plugin.Discord/Plugin.Discord.csproj b/src/Plugin.Discord/Plugin.Discord.csproj
index e018afa0..59b5f303 100644
--- a/src/Plugin.Discord/Plugin.Discord.csproj
+++ b/src/Plugin.Discord/Plugin.Discord.csproj
@@ -1,9 +1,5 @@
- %24/Development/ServerManagers/Main/Plugin.Discord
- {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
- https://dev.azure.com/bretthewitson
- .
Debug;Release;Debug - Beta
@@ -30,8 +26,15 @@
+
+
+
+
+
+
+
@@ -60,9 +63,10 @@
-
-
-
+
+
+
+
diff --git a/src/Plugin.Discord/Properties/AssemblyInfo.cs b/src/Plugin.Discord/Properties/AssemblyInfo.cs
index d7975adb..1b8d55e6 100644
--- a/src/Plugin.Discord/Properties/AssemblyInfo.cs
+++ b/src/Plugin.Discord/Properties/AssemblyInfo.cs
@@ -1,34 +1,19 @@
using System.Reflection;
using System.Runtime.InteropServices;
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
[assembly: AssemblyTitle("ServerManager Discord Plugin")]
[assembly: AssemblyDescription("A Discord plugin that can be used with the server managers.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Bletch1971")]
[assembly: AssemblyProduct("Server Managers")]
-[assembly: AssemblyCopyright("Copyright © 2015-2020")]
+[assembly: AssemblyCopyright("Copyright © 2015-2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
-// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("936ef260-fecf-4e9e-a21e-092d65931c7d")]
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-[assembly: AssemblyVersion("1.0.17.2")]
-[assembly: AssemblyFileVersion("1.0.17.2")]
+// include semantic versioning - Plugin.Discord
+[assembly: AssemblyVersion("1.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/Plugin.Discord/Utils/WindowUtils.cs b/src/Plugin.Discord/Utils/WindowUtils.cs
index 6c765945..239efa66 100644
--- a/src/Plugin.Discord/Utils/WindowUtils.cs
+++ b/src/Plugin.Discord/Utils/WindowUtils.cs
@@ -1,4 +1,4 @@
-using System.Linq;
+using ServerManagerTool.Plugin.Common;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
@@ -8,27 +8,37 @@ namespace ServerManagerTool.Plugin.Discord
{
public static class WindowUtils
{
- public static void RemoveDefaultResourceDictionary(Window window, string defaultDictionary)
+ public static void UpdateResourceDictionary(Window window, string languageCode)
{
- if (window == null)
- return;
-
- var dictToRemove = window.Resources.MergedDictionaries.FirstOrDefault(d => d.Source.OriginalString.Contains(defaultDictionary));
- if (dictToRemove != null)
+ var assembly = typeof(ResourceUtils).Assembly;
+ if (assembly != null)
{
- window.Resources.MergedDictionaries.Remove(dictToRemove);
+ var resourceUtilsType = assembly.GetType(typeof(ResourceUtils).FullName, false, true);
+ if (resourceUtilsType != null)
+ {
+ var method = resourceUtilsType.GetMethod(nameof(UpdateResourceDictionary), new System.Type[] { typeof(Window), typeof(string) });
+ if (method != null)
+ {
+ method.Invoke(null, new object[] { window, languageCode });
+ }
+ }
}
}
- public static void RemoveDefaultResourceDictionary(UserControl control, string defaultDictionary)
+ public static void UpdateResourceDictionary(UserControl control, string languageCode)
{
- if (control == null)
- return;
-
- var dictToRemove = control.Resources.MergedDictionaries.FirstOrDefault(d => d.Source.OriginalString.Contains(defaultDictionary));
- if (dictToRemove != null)
+ var assembly = typeof(ResourceUtils).Assembly;
+ if (assembly != null)
{
- control.Resources.MergedDictionaries.Remove(dictToRemove);
+ var resourceUtilsType = assembly.GetType(typeof(ResourceUtils).FullName, false, true);
+ if (resourceUtilsType != null)
+ {
+ var method = resourceUtilsType.GetMethod(nameof(UpdateResourceDictionary), new System.Type[] { typeof(UserControl), typeof(string) });
+ if (method != null)
+ {
+ method.Invoke(null, new object[] { control, languageCode });
+ }
+ }
}
}
diff --git a/src/Plugin.Discord/VersionFeed.xml b/src/Plugin.Discord/VersionFeed.xml
index 82e77d98..fae47834 100644
--- a/src/Plugin.Discord/VersionFeed.xml
+++ b/src/Plugin.Discord/VersionFeed.xml
@@ -5,7 +5,68 @@
Discord Plugin Version Feed
This is the Discord Plugin release version feed.
- 2020-07-13T00:00:00Z
+ 2021-12-12T00:00:00Z
+
+
+ urn:uuid:A9EC2F32-E026-485F-BD7B-C657DBA95B54
+ 1.0.19 (1.0.19.3)
+ 1.0.19.3
+
+ 2021-12-12T00:00:00Z
+
+
+
+ BUGFIX
+
+
+ Fixed alert test message to support globalization.
+
+
CHANGE
+
+
+ Changed the plugin initialization so it throws an exception if unable to load config file, rather than creating a new config file.
+ de-DE Translation file updated.
+ fr-FR Translation file added.
+ pt-BR Translation file updated.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:C01A4AA0-D839-4732-9814-301DAC6EB094
+ 1.0.18 (1.0.18.1)
+ 1.0.18.1
+
+ 2021-12-03T00:00:00Z
+
+
+
+ NEW
+
+
+ de-DE Translation file added.
+ pt-BR Translation file added.
+ zh-CN Translation file added.
+
+
CHANGE
+
+
+ Have enabled globalization support for the plugin.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
urn:uuid:D8974ABF-8444-4D40-A594-D4443921B3B8
diff --git a/src/Plugin.Discord/VersionFeedBeta.xml b/src/Plugin.Discord/VersionFeedBeta.xml
index de95f6f5..731453ee 100644
--- a/src/Plugin.Discord/VersionFeedBeta.xml
+++ b/src/Plugin.Discord/VersionFeedBeta.xml
@@ -5,21 +5,22 @@
Discord Plugin Version Feed
This is the Discord Plugin beta version feed.
- 2020-07-12T02:00:00Z
+ 2021-12-12T00:00:00Z
- urn:uuid:4750D17C-2C8F-4D8C-AA17-B3512F002170
- 1.0.17 (1.0.17.2)
- 1.0.17.2
+ urn:uuid:DDB25735-1D20-4580-B5FE-1AD4BD107376
+ 1.0.19 (1.0.19.3)
+ 1.0.19.3
- 2020-07-12T02:00:00Z
+ 2021-12-12T00:00:00Z
CHANGE
- Added drag/drop feature to the config window.
+ fr-FR Translation file added.
+ pt-BR Translation file updated.
@@ -31,18 +32,47 @@
- urn:uuid:D8974ABF-8444-4D40-A594-D4443921B3B8
- 1.0.17 (1.0.17.1)
- 1.0.17.1
+ urn:uuid:FD4F56C3-9E44-4422-A761-87E7F957454F
+ 1.0.19 (1.0.19.2)
+ 1.0.19.2
- 2020-07-12T00:00:00Z
+ 2021-12-09T00:00:00Z
CHANGE
- Profile name has been converted to a droplist and is now populated with the Server Manager Profile Names for selection.
+ Changed the plugin initialization so it throws an exception if unable to load config file, rather than creating a new config file.
+
+
+
+
+
+ bletch
+ bletch1971@hotmail.com
+
+
+
+
+ urn:uuid:A9EC2F32-E026-485F-BD7B-C657DBA95B54
+ 1.0.19 (1.0.19.1)
+ 1.0.19.1
+
+ 2021-12-09T00:00:00Z
+
+
+
+ BUGFIX
+
+
+ Fixed alert test message to support globalization.
+
+
CHANGE
+
+
+ de-DE Translation file updated.
+ pt-BR Translation file updated.
diff --git a/src/Plugin.Discord/Windows/ConfigProfileWindow.xaml b/src/Plugin.Discord/Windows/ConfigProfileWindow.xaml
index d1ce9835..f11bbbd7 100644
--- a/src/Plugin.Discord/Windows/ConfigProfileWindow.xaml
+++ b/src/Plugin.Discord/Windows/ConfigProfileWindow.xaml
@@ -1,11 +1,11 @@
+ Width="640" Height="520" MinWidth="640" MinHeight="480" ResizeMode="CanResizeWithGrip" WindowStyle="ToolWindow" WindowStartupLocation="CenterOwner" ShowInTaskbar="False"
+ Closing="ConfigProfileWindow_Closing">
@@ -18,12 +18,6 @@
-
-
-
-
-
-