├── package.json
├── MMS_Files
├── java_latest.ini
├── bedrock_latest.ini
└── java_beta_latest.ini
├── MinecraftService
├── Client
│ ├── SpellingExclusions.dic
│ ├── Configs
│ │ └── Config.conf
│ ├── mc_icon.ico
│ ├── Properties
│ │ ├── launchSettings.json
│ │ ├── Settings.settings
│ │ ├── PublishProfiles
│ │ │ └── FolderProfile.pubxml
│ │ ├── Settings.Designer.cs
│ │ ├── AssemblyInfo.cs
│ │ └── Resources.Designer.cs
│ ├── App.config
│ ├── Networking
│ │ ├── INetworkMessage.cs
│ │ ├── NetworkStrategies
│ │ │ ├── UnlockUI.cs
│ │ │ ├── Backup.cs
│ │ │ ├── BackupCallback.cs
│ │ │ ├── ClientReject.cs
│ │ │ ├── LevelEditFile.cs
│ │ │ ├── EnumBackups.cs
│ │ │ ├── PlayersRequest.cs
│ │ │ ├── ExportFile.cs
│ │ │ ├── PackList.cs
│ │ │ ├── VersionListRequest.cs
│ │ │ ├── ConsoleLogUpdate.cs
│ │ │ ├── ClientConnect.cs
│ │ │ └── ServerStatusRequest.cs
│ │ └── NetworkMessageLookup.cs
│ ├── Forms
│ │ ├── RemoveServerControl.cs
│ │ ├── ExporterControl.cs
│ │ ├── NewPlayerRegistrationForm.cs
│ │ ├── ProgressDialog.cs
│ │ ├── ManagePacksForms.resx
│ │ ├── ProgressDialog.resx
│ │ ├── RemoveServerControl.resx
│ │ ├── NewPlayerRegistrationForm.resx
│ │ ├── ClientConfigForm.cs
│ │ ├── PropEditorForm.cs
│ │ └── ClientConfigForm.resx
│ └── Management
│ │ └── FormManager.cs
├── Service
│ ├── mc_icon.ico
│ ├── Properties
│ │ ├── launchSettings.json
│ │ ├── PublishProfiles
│ │ │ └── FolderProfile.pubxml
│ │ └── AssemblyInfo.cs
│ ├── app.config
│ ├── Core
│ │ └── Interfaces
│ │ │ └── IService.cs
│ ├── appsettings.Development.json
│ ├── appsettings.json
│ ├── Networking
│ │ ├── Interfaces
│ │ │ ├── IMessageParser.cs
│ │ │ ├── IFlaggedMessageParser.cs
│ │ │ └── ITCPObject.cs
│ │ ├── NetworkStrategies
│ │ │ ├── CheckUpdates.cs
│ │ │ ├── ServerRestart.cs
│ │ │ ├── ServerBackup.cs
│ │ │ ├── ServerBackupAll.cs
│ │ │ ├── ServerCommand.cs
│ │ │ ├── EnumBackups.cs
│ │ │ ├── PlayerRequest.cs
│ │ │ ├── BackupRollback.cs
│ │ │ ├── Connect.cs
│ │ │ ├── StartStopServer.cs
│ │ │ ├── DeleteBackups.cs
│ │ │ ├── StartCmdUpdate.cs
│ │ │ ├── LevelEditRequest.cs
│ │ │ ├── RemoveServer.cs
│ │ │ ├── ServerStatusRequest.cs
│ │ │ ├── ImportFileRequest.cs
│ │ │ ├── LevelEditFile.cs
│ │ │ ├── VersionListRequest.cs
│ │ │ ├── RemovePack.cs
│ │ │ ├── AddNewServer.cs
│ │ │ ├── ServerPropUpdate.cs
│ │ │ ├── PackList.cs
│ │ │ ├── PlayersUpdate.cs
│ │ │ ├── ConsoleLogUpdate.cs
│ │ │ └── PackFile.cs
│ │ └── NetworkStrategyLookup.cs
│ ├── Server
│ │ ├── Interfaces
│ │ │ └── IConsoleFilter.cs
│ │ ├── ServerTypeLookup.cs
│ │ ├── ConsoleFilters
│ │ │ ├── SaveIncompleteFilter.cs
│ │ │ ├── ServerRescErrorFilter.cs
│ │ │ ├── StartupFlagFilter.cs
│ │ │ ├── JavaBackupDetectFilter.cs
│ │ │ ├── BackupStringFilter.cs
│ │ │ ├── JavaPlayerConnectedFilter.cs
│ │ │ ├── JavaPlayerDisconnectedFilter.cs
│ │ │ ├── BedrockPlayerDisconnectedFilter.cs
│ │ │ ├── BedrockPlayerConnectedFilter.cs
│ │ │ ├── JavaPlayerLostConnectionFilter.cs
│ │ │ └── JavaVersionFilter.cs
│ │ └── TimerService.cs
│ └── Program.cs
├── ServiceTests
│ ├── SharedTests
│ │ ├── MinecraftPackTests.cs
│ │ ├── ExportImportFileModelTests.cs
│ │ ├── MinecraftUpdatePackageProcessorTests.cs
│ │ ├── JsonModelTests.cs
│ │ └── UtilitiesTests
│ │ │ └── FileUtilitiesTests.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── MMS_Tests.csproj
│ └── ServiceTests
│ │ └── ServiceTests.cs
├── ClientUnitTests
│ ├── packages.config
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ └── FormTests.cs
├── MinecraftService.Shared
│ ├── Classes
│ │ ├── Service
│ │ │ ├── Core
│ │ │ │ ├── StartCmdEntry.cs
│ │ │ │ ├── ProgressModel.cs
│ │ │ │ ├── SimpleVersionModel.cs
│ │ │ │ └── Property.cs
│ │ │ └── Configuration
│ │ │ │ ├── ServiceInfo.cs
│ │ │ │ └── ClientSideServiceConfiguration.cs
│ │ ├── Server
│ │ │ ├── Updaters
│ │ │ │ └── UpdaterContainer.cs
│ │ │ ├── ServerInfo.cs
│ │ │ ├── ProcessInfo.cs
│ │ │ └── Configurations
│ │ │ │ └── CommonDefaults.cs
│ │ └── Networking
│ │ │ ├── NetworkEnums.cs
│ │ │ └── Message.cs
│ ├── Interfaces
│ │ ├── IBackupManager.cs
│ │ ├── IUpdater.cs
│ │ ├── IBaseConfiguration.cs
│ │ ├── IServerController.cs
│ │ └── IServerConfiguration.cs
│ ├── JsonModels
│ │ ├── Service
│ │ │ ├── IFileProcessor.cs
│ │ │ ├── JavaVersionHistoryModel.cs
│ │ │ ├── BedrockVersionHistoryModel.cs
│ │ │ └── FileProcessors
│ │ │ │ └── BedrockServerArchive.cs
│ │ └── Minecraft
│ │ │ ├── MinecraftVersionHistoryJson.cs
│ │ │ ├── PermissionsEntryJsonModel.cs
│ │ │ ├── WorldPackEntryJsonModel.cs
│ │ │ ├── WhitelistEntryJsonModel.cs
│ │ │ └── PackManifestJsonModel.cs
│ ├── SerializeModels
│ │ ├── LogEntry.cs
│ │ ├── ServerCombinedPropModel.cs
│ │ ├── ConsoleLogUpdateCallback.cs
│ │ ├── ConsoleLogUpdateRequest.cs
│ │ ├── StatusModels.cs
│ │ └── BackupInfoModel.cs
│ ├── FileModels
│ │ ├── MinecraftFileModels
│ │ │ ├── PackManifestFileModel.cs
│ │ │ ├── WhitelistFileModel.cs
│ │ │ ├── PermissionsFileModel.cs
│ │ │ └── WorldPackFileModel.cs
│ │ └── BaseJsonFile.cs
│ ├── PackParser
│ │ └── MinecraftPackContainer.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ └── MinecraftService.Shared.csproj
└── packages.config
├── .github
└── workflows
│ ├── changelog.yml
│ ├── BMSBuild.yml
│ └── BMSBuildStable.yml
├── BMS_Files
└── plugin_repo.json
├── CHANGELOG.md
├── .gitattributes
└── BdsVersionCheckTest.ps1
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | }
--------------------------------------------------------------------------------
/MMS_Files/java_latest.ini:
--------------------------------------------------------------------------------
1 | 1.21.11
2 |
--------------------------------------------------------------------------------
/MMS_Files/bedrock_latest.ini:
--------------------------------------------------------------------------------
1 | 1.21.131.1
2 |
--------------------------------------------------------------------------------
/MinecraftService/Client/SpellingExclusions.dic:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/MMS_Files/java_beta_latest.ini:
--------------------------------------------------------------------------------
1 | 26.1-snapshot-1
2 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Configs/Config.conf:
--------------------------------------------------------------------------------
1 | [Hosts]
2 | host1=127.0.0.1:19134
3 |
--------------------------------------------------------------------------------
/MinecraftService/Client/mc_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/crowbarmaster/BedrockManagementService/HEAD/MinecraftService/Client/mc_icon.ico
--------------------------------------------------------------------------------
/MinecraftService/Service/mc_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/crowbarmaster/BedrockManagementService/HEAD/MinecraftService/Service/mc_icon.ico
--------------------------------------------------------------------------------
/MinecraftService/ServiceTests/SharedTests/MinecraftPackTests.cs:
--------------------------------------------------------------------------------
1 | namespace MMS_Tests.SharedTests {
2 | public class MinecraftPackTests {
3 |
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "MinecraftService.Client": {
4 | "commandName": "Project"
5 | }
6 | }
7 | }
--------------------------------------------------------------------------------
/MinecraftService/ServiceTests/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "WSL": {
4 | "commandName": "WSL2",
5 | "distributionName": ""
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/MinecraftService/Service/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "MinecraftService.Service": {
4 | "commandName": "Project",
5 | "nativeDebugging": true
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/MinecraftService/Service/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Core/Interfaces/IService.cs:
--------------------------------------------------------------------------------
1 | namespace MinecraftService.Service.Core.Interfaces {
2 | public interface IService : IHostedService {
3 | Task InitializeHost();
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/MinecraftService/Client/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/MinecraftService/Service/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/MinecraftService/Service/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | },
9 | "AllowedHosts": "*"
10 | }
11 |
--------------------------------------------------------------------------------
/MinecraftService/ClientUnitTests/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/Interfaces/IMessageParser.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.Classes.Networking;
2 |
3 | namespace MinecraftService.Service.Networking.Interfaces
4 | {
5 | public interface IMessageParser {
6 | Message ParseMessage(Message message);
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/Classes/Service/Core/StartCmdEntry.cs:
--------------------------------------------------------------------------------
1 | namespace MinecraftService.Shared.Classes.Service.Core
2 | {
3 | public class StartCmdEntry
4 | {
5 | public string Command = "help 1";
6 |
7 | public StartCmdEntry(string entry)
8 | {
9 | Command = entry;
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/MinecraftService/Service/Server/Interfaces/IConsoleFilter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace MinecraftService.Service.Server.Interfaces {
8 | public interface IConsoleFilter {
9 | public void Filter(string input);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/Interfaces/IBackupManager.cs:
--------------------------------------------------------------------------------
1 | namespace MinecraftService.Shared.Interfaces {
2 | public interface IBackupManager {
3 | bool BackupRunning();
4 | void InitializeBackup();
5 | bool PerformBackup(string unused);
6 | void PerformRollback(string zipFilePath);
7 | bool SetBackupComplete();
8 | }
9 | }
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/Interfaces/IFlaggedMessageParser.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.Classes.Networking;
2 |
3 | namespace MinecraftService.Service.Networking.Interfaces
4 | {
5 | public interface IFlaggedMessageParser {
6 | (byte[] data, byte srvIndex, MessageTypes type) ParseMessage(byte[] data, byte serverIndex, MessageFlags flag);
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/JsonModels/Service/IFileProcessor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace MinecraftService.Shared.JsonModels.Service {
9 | public interface IFileProcessor {
10 | void Process(byte[] fileBytes);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/SerializeModels/LogEntry.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace MinecraftService.Shared.SerializeModels {
4 | public class LogEntry {
5 | public DateTime TimeStamp { get; set; }
6 | public string Text { get; set; }
7 |
8 |
9 | public LogEntry(string entryText) {
10 | Text = entryText;
11 | TimeStamp = DateTime.Now;
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/Interfaces/ITCPObject.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.Classes.Networking;
2 |
3 | namespace MinecraftService.Service.Networking.Interfaces
4 | {
5 | public interface ITCPObject {
6 | void Initialize();
7 | Task CancelAllTasks();
8 | void SetStrategies(Dictionary strategies);
9 | void SetServiceStarted();
10 | void SetServiceStopped();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/SerializeModels/ServerCombinedPropModel.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.Classes.Service.Core;
2 | using System.Collections.Generic;
3 |
4 | namespace MinecraftService.Shared.SerializeModels
5 | {
6 | public class ServerCombinedPropModel {
7 | public List ServerPropList { get; set; }
8 | public List ServicePropList { get; set; }
9 | public List VersionList { get; set; }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/JsonModels/Service/JavaVersionHistoryModel.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | namespace MinecraftService.Shared.JsonModels.Service
6 | {
7 | public class JavaVersionHistoryModel
8 | {
9 | public string Version { get; set; }
10 | public bool IsBeta { get; set; }
11 | public string DownloadUrl { get; set; }
12 | public List PropList { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Networking/INetworkMessage.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Threading.Tasks;
6 | using MinecraftService.Shared.Classes.Networking;
7 |
8 | namespace MinecraftService.Client.Networking {
9 | internal interface INetworkMessage {
10 | Task ProcessMessage(Message message);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/JsonModels/Minecraft/MinecraftVersionHistoryJson.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace MinecraftService.Shared.JsonModels.Minecraft {
4 | public class MinecraftVersionHistoryJson {
5 | [JsonPropertyName("version")]
6 | public string Version { get; set; }
7 | [JsonPropertyName("winurl")]
8 | public string WindowsBinUrl { get; set; }
9 | [JsonPropertyName("linurl")]
10 | public string LinuxBinUrl { get; set; }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/CheckUpdates.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Core;
2 | using MinecraftService.Service.Networking.Interfaces;
3 | using MinecraftService.Shared.Classes.Networking;
4 |
5 | namespace MinecraftService.Service.Networking.NetworkStrategies
6 | {
7 | public class CheckUpdates(MmsService service) : IMessageParser {
8 |
9 | public Message ParseMessage(Message message) {
10 | service.GetServerByIndex(message.ServerIndex).CheckUpdates();
11 | return Message.EmptyUICallback;
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/FileModels/MinecraftFileModels/PackManifestFileModel.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.JsonModels.Minecraft;
2 |
3 | namespace MinecraftService.Shared.FileModels.MinecraftFileModels
4 | {
5 | public class PackManifestFileModel : BaseJsonFile {
6 | public PackManifestJsonModel Contents { get; set; } = new();
7 |
8 | public PackManifestFileModel(string fullPath) : base(fullPath) {
9 | Contents = LoadJsonFile();
10 | }
11 |
12 | public PackManifestFileModel() { }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/ServerRestart.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Core;
2 | using MinecraftService.Service.Networking.Interfaces;
3 | using MinecraftService.Shared.Classes.Networking;
4 |
5 | namespace MinecraftService.Service.Networking.NetworkStrategies
6 | {
7 | public class ServerRestart(MmsService service) : IMessageParser {
8 |
9 | public Message ParseMessage(Message message) {
10 | service.GetServerByIndex(message.ServerIndex).RestartServer().Wait();
11 | return Message.EmptyUICallback;
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/SerializeModels/ConsoleLogUpdateCallback.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace MinecraftService.Shared.SerializeModels {
8 | public class ConsoleLogUpdateCallback {
9 | public byte LogTarget { get; set; } = 0xFE;
10 | public List LogEntries { get; set; }
11 | public int CurrentCount { get; set; }
12 |
13 | public ConsoleLogUpdateCallback() {
14 | LogEntries = [];
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/FileModels/MinecraftFileModels/WhitelistFileModel.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.JsonModels.Minecraft;
2 | using System.Collections.Generic;
3 |
4 | namespace MinecraftService.Shared.FileModels.MinecraftFileModels
5 | {
6 | public class WhitelistFileModel : BaseJsonFile {
7 | public List Contents { get; set; } = new();
8 |
9 | public WhitelistFileModel(string fullPath) : base(fullPath) {
10 | Contents = LoadJsonFile>();
11 | }
12 |
13 | public WhitelistFileModel() { }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/SerializeModels/ConsoleLogUpdateRequest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace MinecraftService.Shared.SerializeModels {
8 | public class ConsoleLogUpdateRequest {
9 | public byte LogTarget { get; set; } = 0xFE;
10 | public int CurrentCount { get; set; }
11 |
12 | public ConsoleLogUpdateRequest(byte logTarget, int currentCount) {
13 | LogTarget = logTarget;
14 | CurrentCount = currentCount;
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/FileModels/MinecraftFileModels/PermissionsFileModel.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.JsonModels.Minecraft;
2 | using System.Collections.Generic;
3 |
4 | namespace MinecraftService.Shared.FileModels.MinecraftFileModels
5 | {
6 | public class PermissionsFileModel : BaseJsonFile {
7 | public List Contents { get; set; } = new();
8 |
9 | public PermissionsFileModel(string fullPath) : base(fullPath) {
10 | Contents = LoadJsonFile>();
11 | }
12 |
13 | public PermissionsFileModel() { }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/MinecraftService/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/Classes/Service/Core/ProgressModel.cs:
--------------------------------------------------------------------------------
1 | namespace MinecraftService.Shared.Classes.Service.Core
2 | {
3 | public class ProgressModel
4 | {
5 | public string Message;
6 | public double Progress;
7 |
8 | public ProgressModel(string message, double progress)
9 | {
10 | Message = message;
11 | Progress = progress;
12 | }
13 |
14 | public ProgressModel UpdateProgress(string message, double progress)
15 | {
16 | Message = message;
17 | Progress = progress;
18 | return this;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/MinecraftService/ClientUnitTests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | [assembly: AssemblyTitle("ClientUnitTests")]
5 | [assembly: AssemblyDescription("")]
6 | [assembly: AssemblyConfiguration("")]
7 | [assembly: AssemblyCompany("")]
8 | [assembly: AssemblyProduct("ClientUnitTests")]
9 | [assembly: AssemblyCopyright("Copyright © 2021")]
10 | [assembly: AssemblyTrademark("")]
11 | [assembly: AssemblyCulture("")]
12 |
13 | [assembly: ComVisible(false)]
14 |
15 | [assembly: Guid("550b6a98-60c3-4765-bfed-2caa0affaebb")]
16 |
17 | // [assembly: AssemblyVersion("1.0.*")]
18 | [assembly: AssemblyVersion("1.0.0.0")]
19 | [assembly: AssemblyFileVersion("1.0.0.0")]
20 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Networking/NetworkStrategies/UnlockUI.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Threading.Tasks;
6 | using MinecraftService.Client.Management;
7 | using MinecraftService.Shared.Classes.Networking;
8 |
9 | namespace MinecraftService.Client.Networking.NetworkStrategies {
10 | public class UnlockUI : INetworkMessage {
11 |
12 | public Task ProcessMessage(Message _) => Task.Run(() => {
13 | FormManager.MainWindow.ServerBusy = false;
14 | return true;
15 | });
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/ServerBackup.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Core;
2 | using MinecraftService.Service.Networking.Interfaces;
3 | using MinecraftService.Service.Server.Interfaces;
4 | using MinecraftService.Shared.Classes.Networking;
5 |
6 | namespace MinecraftService.Service.Networking.NetworkStrategies
7 | {
8 | public class ServerBackup(MmsService service) : IMessageParser {
9 |
10 | public Message ParseMessage(Message message) {
11 | IServerController server = service.GetServerByIndex(message.ServerIndex);
12 | server.SetServerModified(true);
13 | server.GetBackupManager().InitializeBackup();
14 | return Message.EmptyUICallback;
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Properties/PublishProfiles/FolderProfile.pubxml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | Release
8 | Any CPU
9 | ..\bin\Published\
10 | FileSystem
11 | net9.0
12 | win-x64
13 | false
14 | True
15 | False
16 |
17 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Properties/PublishProfiles/FolderProfile.pubxml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | Release
8 | Any CPU
9 | ..\bin\Published\
10 | FileSystem
11 | net9.0-windows
12 | win-x64
13 | false
14 | True
15 | False
16 |
17 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/ServerBackupAll.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Core;
2 | using MinecraftService.Service.Networking.Interfaces;
3 | using MinecraftService.Service.Server.Interfaces;
4 | using MinecraftService.Shared.Classes.Networking;
5 |
6 | namespace MinecraftService.Service.Networking.NetworkStrategies
7 | {
8 | class ServerBackupAll(MmsService service) : IMessageParser {
9 |
10 | public Message ParseMessage(Message message) {
11 | foreach (IServerController server in service.GetAllServers()) {
12 | server.SetServerModified(true);
13 | server.GetBackupManager().InitializeBackup();
14 | }
15 | return Message.EmptyUICallback;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/FileModels/MinecraftFileModels/WorldPackFileModel.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.JsonModels.Minecraft;
2 | using System.Collections.Generic;
3 |
4 | namespace MinecraftService.Shared.FileModels.MinecraftFileModels
5 | {
6 | public class WorldPackFileModel : BaseJsonFile {
7 | public List Contents { get; set; } = new();
8 |
9 | public WorldPackFileModel(string fullPath) : base(fullPath) {
10 | Contents = LoadJsonFile>();
11 | if (Contents == null) {
12 | Contents = new();
13 | }
14 | }
15 |
16 | public WorldPackFileModel() { }
17 |
18 | public void SaveFile() => SaveToFile(Contents);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/JsonModels/Minecraft/PermissionsEntryJsonModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace MinecraftService.Shared.JsonModels.Minecraft {
4 | public class PermissionsEntryJsonModel {
5 | public string xuid { get; set; }
6 | public string permission { get; set; }
7 |
8 | public PermissionsEntryJsonModel(string permission, string xuid) {
9 | this.permission = permission;
10 | this.xuid = xuid;
11 | }
12 |
13 | public override bool Equals(object obj) {
14 | return obj is PermissionsEntryJsonModel model &&
15 | xuid == model.xuid;
16 | }
17 |
18 | public override int GetHashCode() {
19 | return HashCode.Combine(xuid);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/JsonModels/Minecraft/WorldPackEntryJsonModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace MinecraftService.Shared.JsonModels.Minecraft {
5 | public class WorldPackEntryJsonModel {
6 | public string pack_id { get; set; }
7 | public List version { get; set; }
8 |
9 | public WorldPackEntryJsonModel(string id, List ver) {
10 | pack_id = id;
11 | version = ver;
12 | }
13 |
14 | public override bool Equals(object obj) {
15 | return obj is WorldPackEntryJsonModel model &&
16 | pack_id == model.pack_id;
17 | }
18 |
19 | public override int GetHashCode() {
20 | return HashCode.Combine(pack_id);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/MinecraftService/ServiceTests/SharedTests/ExportImportFileModelTests.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.SerializeModels;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using Xunit;
9 |
10 | namespace MMS_Tests.SharedTests {
11 | public class ExportImportFileModelTests {
12 |
13 | [Fact]
14 | public void Can_Detect_Bedrock_Zip() {
15 | string _testFilePath = @"..\..\..\..\TestFiles\BedrockTest.zip";
16 | Assert.True(File.Exists(_testFilePath));
17 | ExportImportFileModel model = new(File.ReadAllBytes(_testFilePath));
18 | Assert.NotNull(model);
19 | Assert.Equal(FileTypes.BedrockServer, model.Manifest.FileType);
20 | }
21 |
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/ServerCommand.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Core;
2 | using MinecraftService.Service.Networking.Interfaces;
3 | using MinecraftService.Shared.Classes.Networking;
4 | using MinecraftService.Shared.Classes.Service.Core;
5 | using System.Text;
6 |
7 | namespace MinecraftService.Service.Networking.NetworkStrategies
8 | {
9 | public class ServerCommand(MmsService service, MmsLogger logger) : IMessageParser {
10 |
11 | public Message ParseMessage(Message message) {
12 | string stringData = Encoding.UTF8.GetString(message.Data);
13 | service.GetServerByIndex(message.ServerIndex).WriteToStandardIn(stringData);
14 | logger.AppendLine($"Sent command {stringData} to stdInput stream");
15 | return Message.EmptyUICallback;
16 | }
17 | }
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Networking/NetworkStrategies/Backup.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Threading.Tasks;
6 | using MinecraftService.Shared.Classes.Networking;
7 | using MinecraftService.Shared.Classes.Service.Core;
8 | using MinecraftService.Shared.Interfaces;
9 |
10 | namespace MinecraftService.Client.Networking.NetworkStrategies {
11 | public class Backup(MmsLogger logger) : INetworkMessage {
12 |
13 | public Task ProcessMessage(Message message) => Task.Run(() => {
14 | MessageFlags msgStatus = (MessageFlags)message.Data[4];
15 | logger.AppendLine(msgStatus.ToString());
16 | return true;
17 | });
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/Interfaces/IUpdater.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.Classes.Service.Core;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 |
5 | namespace MinecraftService.Shared.Interfaces
6 | {
7 | public interface IUpdater {
8 | Task Initialize();
9 | void SetNewLogger(MmsLogger logger);
10 | bool IsInitialized();
11 | Task CheckLatestVersion();
12 | List GetVersionPropList(string version);
13 | List GetDefaultVersionPropList();
14 | string GetBaseVersion(string version);
15 | bool ValidateBuildExists(string version);
16 | Task FetchBuild(string version);
17 | Task ReplaceBuild(IServerConfiguration serverConfiguration, string versionOverride = "");
18 | List GetSimpleVersionList();
19 | }
20 | }
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/PackParser/MinecraftPackContainer.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.JsonModels.Minecraft;
2 |
3 | namespace MinecraftService.Shared.PackParser {
4 | public class MinecraftPackContainer {
5 | public PackManifestJsonModel JsonManifest;
6 | public string PackContentLocation;
7 | public string ManifestType;
8 | public string FolderName;
9 | public byte[] IconBytes;
10 |
11 | public override string ToString() {
12 | return JsonManifest != null ? $"{JsonManifest.header.name} ({JsonManifest.modules[0].type})" : "WorldPack";
13 | }
14 |
15 | public string GetFixedManifestType() {
16 | return ManifestType == "data" ?
17 | "behavior" : ManifestType == "resources" ?
18 | "resource" : ManifestType;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/EnumBackups.cs:
--------------------------------------------------------------------------------
1 |
2 | using MinecraftService.Service.Networking.Interfaces;
3 | using MinecraftService.Shared.Classes.Networking;
4 | using Newtonsoft.Json;
5 | using System.Text;
6 |
7 | namespace MinecraftService.Service.Networking.NetworkStrategies
8 | {
9 | public class EnumBackups(UserConfigManager configurator) : IMessageParser {
10 |
11 | public Message ParseMessage(Message message) {
12 | try {
13 | string jsonString = JsonConvert.SerializeObject(configurator.EnumerateBackupsForServer(message.ServerIndex).Result, Formatting.Indented);
14 | byte[] serializeToBytes = Encoding.UTF8.GetBytes(jsonString);
15 | return new(serializeToBytes, 0, MessageTypes.EnumBackups);
16 | } catch { }
17 | return Message.Empty();
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/JsonModels/Minecraft/WhitelistEntryJsonModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace MinecraftService.Shared.JsonModels.Minecraft {
4 | public class WhitelistEntryJsonModel {
5 | public string xuid { get; set; }
6 | public string name { get; set; }
7 | public bool ignoresPlayerLimit { get; set; }
8 |
9 | public WhitelistEntryJsonModel(bool IgnoreLimits, string XUID, string username) {
10 | ignoresPlayerLimit = IgnoreLimits;
11 | xuid = XUID;
12 | name = username;
13 | }
14 |
15 | public override bool Equals(object obj) {
16 | return obj is WhitelistEntryJsonModel model &&
17 | xuid == model.xuid;
18 | }
19 |
20 | public override int GetHashCode() {
21 | return HashCode.Combine(xuid);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/PlayerRequest.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Core;
2 | using MinecraftService.Service.Networking.Interfaces;
3 | using MinecraftService.Shared.Classes.Networking;
4 | using MinecraftService.Shared.Classes.Service.Configuration;
5 | using MinecraftService.Shared.Classes.Service.Core;
6 | using Newtonsoft.Json;
7 | using System.Text;
8 |
9 | namespace MinecraftService.Service.Networking.NetworkStrategies
10 | {
11 | public class PlayerRequest(MmsService service) : IMessageParser {
12 |
13 | public Message ParseMessage(Message message) {
14 | message.Data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(service.GetServerByIndex(message.ServerIndex).GetPlayerManager().GetPlayerList(), Formatting.Indented, SharedStringBase.GlobalJsonSerialierSettings));
15 | return message;
16 | }
17 | }
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Networking/NetworkStrategies/BackupCallback.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Threading.Tasks;
6 | using MinecraftService.Client.Management;
7 | using MinecraftService.Shared.Classes.Networking;
8 |
9 | namespace MinecraftService.Client.Networking.NetworkStrategies {
10 | public class BackupCallback : INetworkMessage {
11 |
12 | public Task ProcessMessage(Message message) => Task.Run(() => {
13 | bool rollbackPassed = message.Flag == MessageFlags.Passed;
14 | FormManager.MainWindow.BackupRollbackCompleted(rollbackPassed);
15 | FormManager.MainWindow.ServerBusy = false;
16 | return true;
17 | });
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/BackupRollback.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Core;
2 | using MinecraftService.Service.Networking.Interfaces;
3 | using MinecraftService.Shared.Classes.Networking;
4 | using System.Text;
5 |
6 | namespace MinecraftService.Service.Networking.NetworkStrategies
7 | {
8 | public class BackupRollback(MmsService service) : IMessageParser {
9 |
10 | public Message ParseMessage(Message message) {
11 | string stringData = Encoding.UTF8.GetString(message.Data);
12 | byte[] sendBytes = new byte[1];
13 |
14 | if (service.GetServerByIndex(message.ServerIndex).RollbackToBackup(stringData)) {
15 | sendBytes[0] = 1;
16 | } else {
17 | sendBytes[0] = 0;
18 | }
19 | return new(sendBytes, message.ServerIndex, MessageTypes.BackupCallback);
20 | }
21 | }
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/Classes/Server/Updaters/UpdaterContainer.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.Interfaces;
2 | using System.Collections.Generic;
3 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
4 |
5 | namespace MinecraftService.Shared.Classes.Server.Updaters
6 | {
7 | public class UpdaterContainer
8 | {
9 | private Dictionary _updatersByArch = [];
10 |
11 | public UpdaterContainer() { }
12 |
13 | public IUpdater GetUpdaterByArch(MinecraftServerArch arch) => _updatersByArch[arch];
14 |
15 | public IUpdater GetUpdaterByArch(string archName) => _updatersByArch[GetArchFromString(archName)];
16 |
17 | public Dictionary GetUpdaterTable() => _updatersByArch;
18 |
19 | public void SetUpdaterTable(Dictionary updaters) => _updatersByArch = updaters;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/Classes/Service/Configuration/ServiceInfo.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.Classes.Server;
2 | using MinecraftService.Shared.Classes.Service.Core;
3 | using MinecraftService.Shared.Interfaces;
4 | using MinecraftService.Shared.SerializeModels;
5 | using System.Collections.Generic;
6 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
7 |
8 | namespace MinecraftService.Shared.Classes.Service.Configuration
9 | {
10 | public class ServiceInfo
11 | {
12 | public PlayerManager PlayerManager { get; set; }
13 | public List serviceLog = [];
14 | public List ServerList = [];
15 | public List globals = [];
16 | public Dictionary> DefaultServerPropsByArch = [];
17 | public int TotalBackupsServiceWide { get; set; }
18 | public int TotalBackupSizeServiceWideMegabytes { get; set; }
19 | }
20 | }
--------------------------------------------------------------------------------
/MinecraftService/Client/Networking/NetworkStrategies/ClientReject.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Threading.Tasks;
6 | using System.Windows.Forms;
7 | using MinecraftService.Client.Management;
8 |
9 | namespace MinecraftService.Client.Networking.NetworkStrategies {
10 | public class ClientReject : INetworkMessage {
11 |
12 | public Task ProcessMessage(Shared.Classes.Networking.Message _) => Task.Run(() => {
13 | FormManager.MainWindow.Invoke((MethodInvoker)delegate {
14 | FormManager.MainWindow.ServerInfoBox.Text = "Connection attempt rejected by Service!";
15 | FormManager.MainWindow.HostInfoLabel.Text = "Connection attempt rejected by Service!";
16 | });
17 | return true;
18 | });
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/Connect.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Networking.Interfaces;
2 | using MinecraftService.Shared.Classes.Networking;
3 | using MinecraftService.Shared.Classes.Service;
4 | using MinecraftService.Shared.Classes.Service.Configuration;
5 | using MinecraftService.Shared.Classes.Service.Core;
6 | using Newtonsoft.Json;
7 | using System.Text;
8 |
9 | namespace MinecraftService.Service.Networking.NetworkStrategies
10 | {
11 | public class Connect(ServiceConfigurator serviceConfiguration) : IMessageParser {
12 |
13 | public Message ParseMessage(Message message) {
14 | Formatting indented = Formatting.Indented;
15 | string jsonString = JsonConvert.SerializeObject(serviceConfiguration, indented, SharedStringBase.GlobalJsonSerialierSettings);
16 | byte[] serializeToBytes = Encoding.UTF8.GetBytes(jsonString);
17 | return new(serializeToBytes, 0, MessageTypes.Connect);
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/Classes/Service/Configuration/ClientSideServiceConfiguration.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.Interfaces;
2 |
3 | namespace MinecraftService.Shared.Classes.Service.Configuration
4 | {
5 | public class ClientSideServiceConfiguration
6 | {
7 | private readonly string _hostName;
8 | private readonly string _address;
9 | private readonly string _port;
10 | private readonly string _displayName;
11 |
12 | public ClientSideServiceConfiguration(string hostName, string address, string port)
13 | {
14 | _hostName = hostName;
15 | _address = address;
16 | _port = port;
17 | _displayName = $@"{hostName}@{address}:{port}";
18 | }
19 |
20 | public string GetHostName() => _hostName;
21 |
22 | public string GetAddress() => _address;
23 |
24 | public string GetPort() => _port;
25 |
26 | public string GetDisplayName() => _displayName;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Networking/NetworkStrategies/LevelEditFile.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.IO;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using MinecraftService.Client.Management;
10 | using MinecraftService.Shared.Classes.Networking;
11 | using MinecraftService.Shared.Classes.Service.Core;
12 |
13 | namespace MinecraftService.Client.Networking.NetworkStrategies {
14 | public class LevelEditFile : INetworkMessage {
15 |
16 | public Task ProcessMessage(Message message) => Task.Run(() => {
17 | string pathToLevelDat = $@"{SharedStringBase.GetNewTempDirectory("LevelEdit")}\level.dat";
18 | File.WriteAllBytes(pathToLevelDat, message.Data);
19 | FormManager.MainWindow.LevelDatReceived(pathToLevelDat);
20 | return true;
21 | });
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/StartStopServer.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Core;
2 | using MinecraftService.Service.Networking.Interfaces;
3 | using MinecraftService.Service.Server.Interfaces;
4 | using MinecraftService.Shared.Classes.Networking;
5 | using MinecraftService.Shared.SerializeModels;
6 |
7 | namespace MinecraftService.Service.Networking.NetworkStrategies
8 | {
9 | public class StartStopServer(MmsService service) : IMessageParser {
10 |
11 | public Message ParseMessage(Message message) {
12 | IServerController server = service.GetServerByIndex(message.ServerIndex);
13 | if (server.GetServerStatus().ServerStatus == ServerStatus.Started) {
14 | server.ServerStop(true).Wait();
15 | } else if (server.GetServerStatus().ServerStatus == ServerStatus.Stopped) {
16 | server.ServerStart().Wait();
17 | server.StartWatchdog();
18 | }
19 | return Message.EmptyUICallback;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/.github/workflows/changelog.yml:
--------------------------------------------------------------------------------
1 | name: Create changelog
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | FromTag:
7 | description: 'Starting tag'
8 | required: false
9 | type: string
10 | ToTag:
11 | description: 'Ending tag'
12 | required: false
13 | type: string
14 |
15 | jobs:
16 | build:
17 |
18 | runs-on: windows-2022
19 | steps:
20 | - name: Checkout repository
21 | uses: actions/checkout@v3
22 | - name: Remove old changelog
23 | run: rm CHANGELOG.md
24 | - name: Update CHANGELOG
25 | id: changelog
26 | uses: requarks/changelog-action@v1
27 | with:
28 | token: ${{ github.token }}
29 | tag: ${{ inputs.FromTag }}
30 | includeInvalidCommits: true
31 | excludeTypes: build
32 | reverseOrder: true
33 | - name: Upload changelog artifact
34 | uses: actions/upload-artifact@v3
35 | with:
36 | name: changelog-output
37 | path: ./CHANGELOG.md
38 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/Interfaces/IBaseConfiguration.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.Classes;
2 | using MinecraftService.Shared.Classes.Service.Core;
3 | using MinecraftService.Shared.SerializeModels;
4 | using System.Collections.Generic;
5 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
6 |
7 | namespace MinecraftService.Shared.Interfaces {
8 | public interface IBaseConfiguration {
9 | bool InitializeDefaults();
10 | void ProcessUserConfiguration(List configEntries);
11 | bool SetProp(Property propToSet);
12 | Property GetProp(string keyName);
13 | Property GetProp(ServicePropertyKeys key);
14 | Property GetSettingsProp(ServerPropertyKeys key);
15 | Property GetProp(MmsDependServerPropKeys key);
16 | void SetProp(MmsDependServerPropKeys key, string value);
17 | List GetAllProps();
18 | void SetAllProps(List newPropList);
19 | List GetLog();
20 | void SetLog(List newLog);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/DeleteBackups.cs:
--------------------------------------------------------------------------------
1 |
2 | using MinecraftService.Service.Networking.Interfaces;
3 | using MinecraftService.Shared.Classes.Networking;
4 | using MinecraftService.Shared.Classes.Service;
5 | using MinecraftService.Shared.Classes.Service.Configuration;
6 | using MinecraftService.Shared.Classes.Service.Core;
7 | using System.Text;
8 |
9 | namespace MinecraftService.Service.Networking.NetworkStrategies
10 | {
11 | class DeleteBackups(MmsLogger logger, ServiceConfigurator service) : IMessageParser {
12 |
13 | public Message ParseMessage(Message message) {
14 | string stringData = Encoding.UTF8.GetString(message.Data);
15 | FileInfo file = new FileInfo(stringData);
16 | try {
17 | service.DeleteBackupForServer(message.ServerIndex, stringData);
18 | logger.AppendLine($"Deleted backup {file.Name}.");
19 | } catch (Exception ex) {
20 | logger.AppendLine(ex.Message);
21 | }
22 | return new();
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Networking/NetworkStrategies/EnumBackups.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using MinecraftService.Client.Management;
9 | using MinecraftService.Shared.Classes.Networking;
10 | using MinecraftService.Shared.SerializeModels;
11 | using Newtonsoft.Json;
12 |
13 | namespace MinecraftService.Client.Networking.NetworkStrategies {
14 | public class EnumBackups : INetworkMessage {
15 |
16 | public Task ProcessMessage(Message message) => Task.Run(() => {
17 | string data = Encoding.UTF8.GetString(message.Data);
18 | List list = JsonConvert.DeserializeObject>(data);
19 | FormManager.MainWindow.Invoke(() => FormManager.MainWindow.UpdateBackupManagerData(list));
20 | return true;
21 | });
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/StartCmdUpdate.cs:
--------------------------------------------------------------------------------
1 |
2 | using MinecraftService.Service.Networking.Interfaces;
3 | using MinecraftService.Shared.Classes.Networking;
4 | using MinecraftService.Shared.Classes.Service;
5 | using MinecraftService.Shared.Classes.Service.Configuration;
6 | using MinecraftService.Shared.Classes.Service.Core;
7 | using Newtonsoft.Json;
8 | using System.Text;
9 |
10 | namespace MinecraftService.Service.Networking.NetworkStrategies
11 | {
12 | public class StartCmdUpdate(UserConfigManager configurator, ServiceConfigurator serviceConfiguration) : IMessageParser {
13 | public Message ParseMessage(Message message) {
14 | List entries = JsonConvert.DeserializeObject>(Encoding.UTF8.GetString(message.Data), SharedStringBase.GlobalJsonSerialierSettings);
15 | serviceConfiguration.GetServerInfoByIndex(message.ServerIndex).SetStartCommands(entries);
16 | configurator.SaveServerConfiguration(serviceConfiguration.GetServerInfoByIndex(message.ServerIndex));
17 | return Message.EmptyUICallback;
18 | }
19 | }
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/Classes/Server/ServerInfo.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.Classes.Service.Core;
2 | using MinecraftService.Shared.SerializeModels;
3 | using System.Collections.Generic;
4 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
5 |
6 | namespace MinecraftService.Shared.Classes.Server
7 | {
8 | public class ServerInfo
9 | {
10 | public MinecraftServerArch ServerArch { get; set; }
11 | public int ProcessID { get; set; }
12 | public PlayerManager PlayerManager { get; set; }
13 | public Property ServersPath { get; set; }
14 | public int TotalBackupSizeKilobytes { get; set; }
15 | public int TotalBackupsStored { get; set; }
16 | public ServerStatusModel ServerStatus { get; set; } = new();
17 | public List ServerLogs = new();
18 | public List ServicePropList = new();
19 | public List ServerPropList = new();
20 | public List DefaultPropList = new();
21 | public List StartCmds = new();
22 |
23 | public ServerInfo()
24 | {
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/FileModels/BaseJsonFile.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System.IO;
3 |
4 | namespace MinecraftService.Shared.FileModels
5 | {
6 | public abstract class BaseJsonFile
7 | {
8 | private readonly JsonSerializerSettings defaultJsonSettings = new() { DefaultValueHandling = DefaultValueHandling.Ignore };
9 | public string FilePath { get; set; }
10 |
11 | public BaseJsonFile(string fullPath) => FilePath = fullPath;
12 |
13 | public BaseJsonFile() { }
14 |
15 | public T LoadJsonFile()
16 | {
17 | if (!File.Exists(FilePath))
18 | {
19 | return default;
20 | }
21 | return JsonConvert.DeserializeObject(File.ReadAllText(FilePath));
22 | }
23 |
24 | public void SaveToFile(T value, JsonSerializerSettings settings = null)
25 | {
26 | if (settings == null)
27 | {
28 | settings = defaultJsonSettings;
29 | }
30 | File.WriteAllText(FilePath, JsonConvert.SerializeObject(value, Formatting.Indented, settings));
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/LevelEditRequest.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Networking.Interfaces;
2 | using MinecraftService.Shared.Classes.Networking;
3 | using MinecraftService.Shared.Classes.Service;
4 | using MinecraftService.Shared.Classes.Service.Configuration;
5 | using MinecraftService.Shared.Classes.Service.Core;
6 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
7 |
8 | namespace MinecraftService.Service.Networking.NetworkStrategies
9 | {
10 | public class LevelEditRequest(ServiceConfigurator serviceConfiguration) : IMessageParser {
11 |
12 | public Message ParseMessage(Message message) {
13 | IServerConfiguration server = serviceConfiguration.GetServerInfoByIndex(message.ServerIndex);
14 | string pathToLevelDat = $@"{serviceConfiguration.GetServerInfoByIndex(message.ServerIndex).GetSettingsProp(ServerPropertyKeys.ServerPath)}\worlds\{server.GetProp(MmsDependServerPropKeys.LevelName)}\level.dat";
15 | byte[] levelDatToBytes = File.ReadAllBytes(pathToLevelDat);
16 | return new(levelDatToBytes, 0, MessageTypes.LevelEditFile);
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Networking/NetworkStrategies/PlayersRequest.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using MinecraftService.Client.Management;
9 | using MinecraftService.Shared.Classes.Server;
10 | using MinecraftService.Shared.Classes.Service.Core;
11 | using MinecraftService.Shared.Classes.Networking;
12 | using Newtonsoft.Json;
13 |
14 | namespace MinecraftService.Client.Networking.NetworkStrategies {
15 | public class PlayersRequest : INetworkMessage {
16 |
17 | public Task ProcessMessage(Message message) => Task.Run(() => {
18 | string data = Encoding.UTF8.GetString(message.Data);
19 | List fetchedPlayers = JsonConvert.DeserializeObject>(data, SharedStringBase.GlobalJsonSerialierSettings);
20 | FormManager.MainWindow.ReceivePlayerData(message.ServerIndex, fetchedPlayers);
21 | return true;
22 | });
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/JsonModels/Service/BedrockVersionHistoryModel.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Text.Json.Serialization;
3 |
4 | namespace MinecraftService.Shared.JsonModels.Service
5 | {
6 | public class LegacyBedrockVersionModel
7 | {
8 | [JsonPropertyName("version")]
9 | public string Version { get; set; }
10 | [JsonPropertyName("winurl")]
11 | public string WindowsBinUrl { get; set; }
12 | [JsonPropertyName("linurl")]
13 | public string LinuxBinUrl { get; set; }
14 | }
15 |
16 | public class BedrockVersionHistoryModel
17 | {
18 | [JsonPropertyName("version")]
19 | public string Version { get; set; }
20 | [JsonPropertyName("winurl")]
21 | public string WindowsBinUrl { get; set; }
22 | [JsonPropertyName("linurl")]
23 | public string LinuxBinUrl { get; set; }
24 | [JsonPropertyName("proplist")]
25 | public List PropList { get; set; } = new();
26 | }
27 |
28 | public class PropInfoEntry
29 | {
30 | public string Key { get; set; }
31 | public string Value { get; set; }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Networking/NetworkStrategies/ExportFile.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using MinecraftService.Client.Management;
8 | using MinecraftService.Shared.Classes.Networking;
9 | using MinecraftService.Shared.Classes.Service.Core;
10 | using MinecraftService.Shared.SerializeModels;
11 | using Newtonsoft.Json;
12 |
13 | namespace MinecraftService.Client.Networking.NetworkStrategies {
14 | public class ExportFile : INetworkMessage {
15 |
16 | public Task ProcessMessage(Message message) => Task.Run(() => {
17 | string data = Encoding.UTF8.GetString(message.Data);
18 | ExportImportFileModel exportModel = JsonConvert.DeserializeObject(data, SharedStringBase.GlobalJsonSerialierSettings);
19 | if (exportModel != null) {
20 | FormManager.MainWindow.RecieveExportData(exportModel).Wait();
21 | }
22 | return true;
23 | });
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace MinecraftService.Client.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.14.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/BMS_Files/plugin_repo.json:
--------------------------------------------------------------------------------
1 | {
2 | "PluginRepo": [
3 | {
4 | "Name": "CrowbarTools",
5 | "Description": "A toolbox of commands for LLBDS",
6 | "PluginVersion": "1.0.0.21",
7 | "ProtoVersion": 568,
8 | "ExtendedInfo": "Currently contains comands for inventory manipulation, multiple commands truncated to one, and tele2server control.",
9 | "ProtectedFiles": [
10 | "CrowbarTools.ini"
11 | ],
12 | "ProtoBlacklist": [
13 | 0
14 | ],
15 | "RepoURL": "https://github.com/crowbarmaster/CrowbarsLLBDSPlugins/releases/download/Latest/CrowbarTools.zip"
16 | },
17 | {
18 | "Name": "BETweaker",
19 | "Description": "Adds features to the game, giving survival players a very rich and useful feature set. By dreamguxiang.",
20 | "PluginVersion": "2.0.0.2",
21 | "ProtoVersion": 568,
22 | "ExtendedInfo": "Current version stripped of a few functions, but is mostly complete.",
23 | "ProtectedFiles": [
24 | "BETweaker\\*.*"
25 | ],
26 | "ProtoBlacklist": [
27 | 0
28 | ],
29 | "RepoURL": "https://github.com/crowbarmaster/BETweaker/releases/download/2.0.0.2/BETweaker.zip"
30 | }
31 | ]
32 | }
33 |
--------------------------------------------------------------------------------
/MinecraftService/ServiceTests/MMS_Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net9.0
5 | win-x64
6 | enable
7 |
8 | false
9 |
10 | Debug;Release;Publish
11 |
12 | AnyCPU;x64
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | all
21 | runtime; build; native; contentfiles; analyzers; buildtransitive
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Networking/NetworkStrategies/PackList.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using MinecraftService.Client.Management;
9 | using MinecraftService.Shared.Classes.Networking;
10 | using MinecraftService.Shared.PackParser;
11 | using Newtonsoft.Json.Linq;
12 |
13 | namespace MinecraftService.Client.Networking.NetworkStrategies {
14 | public class PackList : INetworkMessage {
15 |
16 | public Task ProcessMessage(Message message) => Task.Run(() => {
17 | byte serverIndex = message.ServerIndex;
18 | string data = Encoding.UTF8.GetString(message.Data);
19 | List temp = new();
20 | JArray jArray = JArray.Parse(data);
21 | foreach (JToken token in jArray)
22 | temp.Add(token.ToObject());
23 | Task.Run(() => FormManager.MainWindow.Invoke(() => FormManager.MainWindow.ReceivePackData(serverIndex, temp)));
24 | return true;
25 | });
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/MinecraftService/ServiceTests/SharedTests/MinecraftUpdatePackageProcessorTests.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.Classes;
2 | using MinecraftService.Shared.Classes.Server;
3 | using MinecraftService.Shared.Classes.Server.Updaters;
4 | using MinecraftService.Shared.Classes.Service.Configuration;
5 | using MinecraftService.Shared.Interfaces;
6 | using System.IO;
7 | using Xunit;
8 |
9 | namespace MMS_Tests.SharedTests
10 | {
11 | public class MinecraftUpdatePackageProcessorTests {
12 | const string _testFilePath = @"..\..\..\..\..\TestFiles";
13 | private readonly DirectoryInfo _directory = new(_testFilePath);
14 | [Fact]
15 | public void Can_Create_JsonFiles() {
16 | _directory.Create();
17 | DirectoryInfo outDir = new DirectoryInfo(_testFilePath + @"\Output");
18 | outDir.Create();
19 | ProcessInfo processInfo = new ProcessInfo("TestHost", _directory.FullName, 0, true, true);
20 | BedrockUpdatePackageProcessor processor = new(new MinecraftService.Shared.Classes.Service.Core.MmsLogger(processInfo, new ServiceConfigurator(processInfo, new())), "1.0", outDir.FullName);
21 | processor.ExtractCoreFiles();
22 | Assert.True(File.Exists(@$"{_testFilePath}\Output\stock_props.conf"));
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/Classes/Networking/NetworkEnums.cs:
--------------------------------------------------------------------------------
1 | namespace MinecraftService.Shared.Classes.Networking
2 | {
3 | public enum MessageTypes
4 | {
5 | None,
6 | Connect,
7 | AddNewServer,
8 | RemoveServer,
9 | ConsoleLogUpdate,
10 | PropUpdate,
11 | PlayersRequest,
12 | PlayersUpdate,
13 | StartCmdUpdate,
14 | CheckUpdates,
15 | PackFile,
16 | PackList,
17 | LLPluginFile,
18 | ExportFile,
19 | ImportFile,
20 | VersionListRequest,
21 | LevelEditRequest,
22 | LevelEditFile,
23 | RemovePack,
24 | Command,
25 | Backup,
26 | BackupRollback,
27 | BackupAll,
28 | DelBackups,
29 | EnumBackups,
30 | Restart,
31 | StartStop,
32 | ServerStatusRequest,
33 | Heartbeat,
34 | Disconnect,
35 | ClientReject,
36 | UICallback,
37 | BackupCallback
38 | }
39 |
40 | public enum MessageFlags
41 | {
42 | Failed,
43 | Passed,
44 | RemoveBackups,
45 | RemoveSrv,
46 | RemovePlayers,
47 | RemoveBckSrv,
48 | RemoveBckPly,
49 | RemovePlySrv,
50 | RemoveAll,
51 | None
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/RemoveServer.cs:
--------------------------------------------------------------------------------
1 |
2 | using MinecraftService.Service.Core;
3 | using MinecraftService.Service.Networking.Interfaces;
4 | using MinecraftService.Shared.Classes.Networking;
5 | using MinecraftService.Shared.Classes.Service;
6 | using MinecraftService.Shared.Classes.Service.Configuration;
7 | using MinecraftService.Shared.Classes.Service.Core;
8 | using Newtonsoft.Json;
9 | using System.Text;
10 |
11 | namespace MinecraftService.Service.Networking.NetworkStrategies
12 | {
13 | public class RemoveServer(UserConfigManager configurator, ServiceConfigurator serviceConfiguration, MmsService minecraftService) : IMessageParser {
14 |
15 | public Message ParseMessage(Message message) {
16 | minecraftService.GetServerByIndex(message.ServerIndex).ServerStop(true).Wait();
17 | configurator.RemoveServerConfigs(serviceConfiguration.GetServerInfoByIndex(message.ServerIndex), message.Flag).Wait();
18 | minecraftService.RemoveServerInfoByIndex(message.ServerIndex);
19 | byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(serviceConfiguration, Formatting.Indented, SharedStringBase.GlobalJsonSerialierSettings));
20 | return new(serializeToBytes, 0, MessageTypes.Connect);
21 | }
22 | }
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Networking/NetworkStrategies/VersionListRequest.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using MinecraftService.Client.Management;
10 | using MinecraftService.Shared.Classes.Networking;
11 | using MinecraftService.Shared.Classes.Service.Core;
12 | using Newtonsoft.Json;
13 |
14 | namespace MinecraftService.Client.Networking.NetworkStrategies {
15 | public class VersionListRequest : INetworkMessage {
16 |
17 | public Task ProcessMessage(Message message) => Task.Run(() => {
18 | string data = Encoding.UTF8.GetString(message.Data);
19 | FormManager.Logger.AppendLine("Received version list data from Service.");
20 | Dictionary versionLists = JsonConvert.DeserializeObject>(data, SharedStringBase.GlobalJsonSerialierSettings);
21 | FormManager.MainWindow.VersionListArrived(versionLists);
22 | return true;
23 | });
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Server/ServerTypeLookup.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Server.ServerControllers;
2 | using MinecraftService.Shared.Classes.Server;
3 | using MinecraftService.Shared.Classes.Service;
4 | using MinecraftService.Shared.Classes.Service.Configuration;
5 | using MinecraftService.Shared.Classes.Service.Core;
6 | using MinecraftService.Shared.Interfaces;
7 | using System;
8 | using System.Collections.Generic;
9 | using System.Linq;
10 | using System.Text;
11 | using System.Threading.Tasks;
12 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
13 |
14 | namespace MinecraftService.Shared.Classes
15 | {
16 | public static class ServerTypeLookup {
17 | public static IServerController PrepareNewServerController(MinecraftServerArch serverArch, IServerConfiguration server, UserConfigManager configurator, MmsLogger logger, ServiceConfigurator service, ProcessInfo processInfo) {
18 | switch (serverArch) {
19 | case MinecraftServerArch.Bedrock:
20 | return new BedrockServer(server, configurator, logger, service, processInfo);
21 | case MinecraftServerArch.Java:
22 | return new JavaServer(server, configurator, logger, service, processInfo);
23 | }
24 | return null;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/ServerStatusRequest.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Core;
2 | using MinecraftService.Service.Networking.Interfaces;
3 | using MinecraftService.Shared.Classes.Networking;
4 | using MinecraftService.Shared.Classes.Service;
5 | using MinecraftService.Shared.Classes.Service.Configuration;
6 | using MinecraftService.Shared.Classes.Service.Core;
7 | using MinecraftService.Shared.SerializeModels;
8 | using Newtonsoft.Json;
9 | using System.Text;
10 |
11 | namespace MinecraftService.Service.Networking.NetworkStrategies
12 | {
13 | public class ServerStatusRequest(MmsService service) : IMessageParser {
14 |
15 | public Message ParseMessage(Message message) {
16 | StatusUpdateModel model = new();
17 | model.ServiceStatusModel = service.GetServiceStatus();
18 | byte[] serializeToBytes = Array.Empty();
19 | if (message.ServerIndex != 255) {
20 | model.ServerStatusModel = service.GetServerByIndex(message.ServerIndex).GetServerStatus();
21 | }
22 | serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(model, Formatting.Indented, SharedStringBase.GlobalJsonSerialierSettings));
23 | return new(serializeToBytes, message.ServerIndex, MessageTypes.ServerStatusRequest);
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/Classes/Server/ProcessInfo.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.Interfaces;
2 |
3 | namespace MinecraftService.Shared.Classes.Server
4 | {
5 | public class ProcessInfo
6 | {
7 | private readonly string _declaredType;
8 | private readonly string _serviceDirectory;
9 | private readonly int _processPid;
10 | private readonly bool _debugEnabled;
11 |
12 | public ProcessInfo(string declaredType, string serviceDirectory, int processPid, bool debugEnabled, bool shouldStartService, string serverName = null)
13 | {
14 | _declaredType = declaredType;
15 | _serviceDirectory = serviceDirectory;
16 | _processPid = processPid;
17 | _debugEnabled = debugEnabled;
18 | }
19 |
20 | public ProcessInfo(ProcessInfo spi)
21 | {
22 | _declaredType = spi.DeclaredType();
23 | _serviceDirectory = spi.GetDirectory();
24 | _processPid = spi.GetProcessPID();
25 | _debugEnabled = spi.IsDebugEnabled();
26 | }
27 |
28 | public string DeclaredType() => _declaredType;
29 |
30 | public string GetDirectory() => _serviceDirectory;
31 |
32 | public int GetProcessPID() => _processPid;
33 |
34 | public bool IsDebugEnabled() => _debugEnabled;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/ImportFileRequest.cs:
--------------------------------------------------------------------------------
1 |
2 | using MinecraftService.Service.Networking.Interfaces;
3 | using MinecraftService.Shared.Classes.Networking;
4 | using MinecraftService.Shared.Classes.Server;
5 | using MinecraftService.Shared.Classes.Service;
6 | using MinecraftService.Shared.Classes.Service.Configuration;
7 | using MinecraftService.Shared.Classes.Service.Core;
8 | using MinecraftService.Shared.PackParser;
9 | using MinecraftService.Shared.SerializeModels;
10 | using Newtonsoft.Json;
11 | using System.IO.Compression;
12 | using System.Text;
13 |
14 | namespace MinecraftService.Service.Networking.NetworkStrategies
15 | {
16 | public class ImportFileRequest(UserConfigManager configurator, MmsLogger logger, ServiceConfigurator serviceConfig) : IMessageParser {
17 |
18 | public Message ParseMessage(Message message) {
19 | ExportImportFileModel fileModel = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(message.Data));
20 | ExportImportManifestModel manifest = fileModel.Manifest;
21 | if (fileModel == null || manifest == null) return new();
22 | MemoryStream memStream = new(fileModel.Data);
23 | ZipArchive zip = new(memStream);
24 |
25 | if (manifest.FileType.HasFlag(FileTypes.BedrockWorld)) {
26 |
27 | }
28 | return message;
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/JsonModels/Service/FileProcessors/BedrockServerArchive.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.Classes.Service.Core;
2 | using MinecraftService.Shared.Utilities;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.IO;
6 | using System.IO.Compression;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 |
11 | namespace MinecraftService.Shared.JsonModels.Service.FileProcessors {
12 | public class BedrockServerArchive(MmsLogger logger) : IFileProcessor {
13 | public void Process(byte[] fileBytes) {
14 | if (fileBytes == null) throw new ArgumentNullException(nameof(fileBytes));
15 | MemoryStream stream = new MemoryStream(fileBytes);
16 | string tempPath = SharedStringBase.GetNewTempDirectory("BedrockImport");
17 | Progress progress = new Progress((progress) => {
18 | string prog = string.Format("{0:N2}", progress.Progress);
19 | logger.AppendLine($"Extracting bedrock server contents... {prog}% completed.");
20 | });
21 | ZipUtilities.ExtractToDirectory(stream, tempPath, progress);
22 |
23 | List serverProps = MinecraftFileUtilities.FilterLinesFromPropFile($"{tempPath}\\{SharedStringBase.GetServerFileName(SharedStringBase.ServerFileNameKeys.ServerProps)}");
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Networking/NetworkStrategies/ConsoleLogUpdate.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using MinecraftService.Client.Management;
10 | using MinecraftService.Shared.Classes.Networking;
11 | using MinecraftService.Shared.Classes.Service.Core;
12 | using MinecraftService.Shared.Interfaces;
13 | using MinecraftService.Shared.SerializeModels;
14 | using Newtonsoft.Json;
15 |
16 | namespace MinecraftService.Client.Networking.NetworkStrategies {
17 | public class ConsoleLogUpdate(MmsLogger logger) : INetworkMessage {
18 | public Task ProcessMessage(Message message) => Task.Run(() => {
19 | string data = Encoding.UTF8.GetString(message.Data);
20 | try {
21 | List callbacks = JsonConvert.DeserializeObject>(data);
22 | FormManager.MainWindow.GetLogManager().ProcessIncomingLogData(callbacks);
23 | } catch (Exception e) {
24 | logger.AppendLine($"Error updating logs: {e.Message}");
25 | return false;
26 | }
27 | return true;
28 | });
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | // General Information about an assembly is controlled through the following
4 | // set of attributes. Change these attribute values to modify the information
5 | // associated with an assembly.
6 | [assembly: AssemblyTitle("MinecraftService")]
7 | [assembly: AssemblyDescription("")]
8 | [assembly: AssemblyConfiguration("")]
9 | [assembly: AssemblyCompany("CrowbarWares")]
10 | [assembly: AssemblyProduct("MinecraftService")]
11 | [assembly: AssemblyCopyright("Copyright © 2021")]
12 | [assembly: AssemblyTrademark("")]
13 | [assembly: AssemblyCulture("")]
14 |
15 | // Setting ComVisible to false makes the types in this assembly not visible
16 | // to COM components. If you need to access a type in this assembly from
17 | // COM, set the ComVisible attribute to true on that type.
18 | [assembly: ComVisible(false)]
19 |
20 | // The following GUID is for the ID of the typelib if this project is exposed to COM
21 | [assembly: Guid("f4b1f910-30b0-4f94-a49f-94142e790c9d")]
22 |
23 | // Version information for an assembly consists of the following four values:
24 | //
25 | // Major Version
26 | // Minor Version
27 | // Build Number
28 | // Revision
29 | //
30 | // You can specify all the values or you can default the Build and Revision Numbers
31 | // by using the '*' as shown below:
32 | // [assembly: AssemblyVersion("1.0.*")]
33 | [assembly: AssemblyVersion("3.1.*")]
34 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/Interfaces/IServerController.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.Classes.Server;
2 | using MinecraftService.Shared.Classes.Service.Core;
3 | using MinecraftService.Shared.SerializeModels;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Threading.Tasks;
7 |
8 | namespace MinecraftService.Shared.Interfaces
9 | {
10 | public interface IServerController {
11 | void Initialize();
12 | void StartWatchdog();
13 | Task ServerStart();
14 | Task ServerStop(bool stopWatchdog);
15 | void ForceKillServer();
16 | Task RestartServer();
17 | string GetServerName();
18 | void WriteToStandardIn(string command);
19 | bool RollbackToBackup(string targetZip);
20 | MmsLogger GetLogger();
21 | MmsLogger GetServiceLogger();
22 | PlayerManager GetPlayerManager();
23 | List GetActivePlayerList();
24 | bool IsServerModified();
25 | void SetServerModified(bool isModified);
26 | bool ServerAutostartEnabled();
27 | ServerStatusModel GetServerStatus();
28 | void SetStartupStatus(ServerStatus status);
29 | void RunStartupCommands();
30 | bool IsPrimaryServer();
31 | bool IsServerStarted();
32 | bool IsServerStopped();
33 | void CheckUpdates();
34 | IBackupManager GetBackupManager();
35 | void PerformOfflineServerTask(Action methodToRun);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("MinecraftService.Shared")]
8 | [assembly: AssemblyDescription("")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("CrowbarWares")]
11 | [assembly: AssemblyProduct("MinecraftService.Shared")]
12 | [assembly: AssemblyCopyright("Copyright © 2021")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("f146d5e8-ef1f-4785-9150-182631f059b7")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("3.1.*")]
35 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Server/ConsoleFilters/SaveIncompleteFilter.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Server.Interfaces;
2 | using MinecraftService.Shared.Classes.Service;
3 | using MinecraftService.Shared.Classes.Service.Configuration;
4 | using MinecraftService.Shared.Classes.Service.Core;
5 | using MinecraftService.Shared.Interfaces;
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
12 |
13 | namespace MinecraftService.Service.Server.ConsoleFilters
14 | {
15 | public class SaveIncompleteFilter : IConsoleFilter {
16 | IServerConfiguration _serverConfiguration;
17 | MmsLogger _logger;
18 | UserConfigManager _configurator;
19 | IServerController _bedrockServer;
20 | ServiceConfigurator _serviceConfiguration;
21 |
22 | public SaveIncompleteFilter(MmsLogger logger, UserConfigManager configurator, IServerConfiguration serverConfiguration, IServerController bedrockServer, ServiceConfigurator mineraftService) {
23 | _serverConfiguration = serverConfiguration;
24 | _logger = logger;
25 | _configurator = configurator;
26 | _bedrockServer = bedrockServer;
27 | _serviceConfiguration = mineraftService;
28 | }
29 |
30 | public void Filter(string input) {
31 | Task.Delay(1000).Wait();
32 | _bedrockServer.WriteToStandardIn("save query");
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/LevelEditFile.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Core;
2 | using MinecraftService.Service.Networking.Interfaces;
3 | using MinecraftService.Shared.Classes.Networking;
4 | using MinecraftService.Shared.Classes.Service;
5 | using MinecraftService.Shared.Classes.Service.Configuration;
6 | using MinecraftService.Shared.Classes.Service.Core;
7 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
8 |
9 | namespace MinecraftService.Service.Networking.NetworkStrategies
10 | {
11 | public class LevelEditFile(ServiceConfigurator serviceConfiguration, MmsService mineraftService, MmsLogger logger) : IMessageParser {
12 |
13 | public Message ParseMessage(Message message) {
14 | byte[] stripHeaderFromBuffer = new byte[message.Data.Length - 5];
15 | Buffer.BlockCopy(message.Data, 5, stripHeaderFromBuffer, 0, stripHeaderFromBuffer.Length);
16 | IServerConfiguration server = serviceConfiguration.GetServerInfoByIndex(message.ServerIndex);
17 | string pathToLevelDat = $@"{serviceConfiguration.GetProp(ServicePropertyKeys.ServersPath)}\{server.GetProp(MmsDependServerPropKeys.ServerName)}\worlds\{server.GetProp(MmsDependServerPropKeys.LevelName)}\level.dat";
18 | mineraftService.GetServerByIndex(message.ServerIndex).PerformOfflineServerTask(() => {
19 | File.WriteAllBytes(pathToLevelDat, stripHeaderFromBuffer);
20 | logger.AppendLine($"level.dat writen to server {server.GetServerName()}");
21 | });
22 | return new();
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Server/ConsoleFilters/ServerRescErrorFilter.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Server.Interfaces;
2 | using MinecraftService.Shared.Classes.Service;
3 | using MinecraftService.Shared.Classes.Service.Configuration;
4 | using MinecraftService.Shared.Classes.Service.Core;
5 | using MinecraftService.Shared.Interfaces;
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
12 |
13 | namespace MinecraftService.Service.Server.ConsoleFilters
14 | {
15 | public class ServerRescErrorFilter : IConsoleFilter {
16 | IServerConfiguration _serverConfiguration;
17 | MmsLogger _logger;
18 | UserConfigManager _configurator;
19 | IServerController _bedrockServer;
20 | ServiceConfigurator _serviceConfiguration;
21 |
22 | public ServerRescErrorFilter(MmsLogger logger, UserConfigManager configurator, IServerConfiguration serverConfiguration, IServerController bedrockServer, ServiceConfigurator mineraftService) {
23 | _serverConfiguration = serverConfiguration;
24 | _logger = logger;
25 | _configurator = configurator;
26 | _bedrockServer = bedrockServer;
27 | _serviceConfiguration = mineraftService;
28 | }
29 |
30 | public void Filter(string input) {
31 | _bedrockServer.PerformOfflineServerTask(() => {
32 | _serverConfiguration.GetUpdater().ReplaceBuild(_serverConfiguration).Wait();
33 | });
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/MinecraftService/ClientUnitTests/FormTests.cs:
--------------------------------------------------------------------------------
1 | using BedrockService.Client.Forms;
2 | using BedrockService.Client.Management;
3 | using BedrockService.Shared.Classes;
4 | using BedrockService.Shared.Interfaces;
5 | using Microsoft.VisualStudio.TestTools.UnitTesting;
6 | using System.Collections.Generic;
7 | using System.Diagnostics;
8 | using System.IO;
9 | using System.Reflection;
10 | using System.Threading.Tasks;
11 |
12 | namespace ClientUnitTests
13 | {
14 | [TestClass]
15 | public class FormTests
16 | {
17 | [TestMethod]
18 | public void TestClientConfigForm()
19 | {
20 | List clientSideServiceConfigurations = new List();
21 | clientSideServiceConfigurations.Add(new ClientSideServiceConfiguration("test1", "address1", "1234"));
22 | clientSideServiceConfigurations.Add(new ClientSideServiceConfiguration("test2", "4ddr3552", "3456"));
23 | clientSideServiceConfigurations.Add(new ClientSideServiceConfiguration("test3", "address3", "5678"));
24 |
25 | using (ClientConfigForm form = new ClientConfigForm(new ConfigManager(new ClientLogger(new ServiceProcessInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Path.GetFileName(Assembly.GetExecutingAssembly().Location), Process.GetCurrentProcess().Id, false, true)))))
26 | {
27 | form.Show();
28 | System.Timers.Timer timer = new System.Timers.Timer(6000);
29 | form.SimulateTests();
30 | Task.Delay(6000).Wait();
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/Classes/Service/Core/SimpleVersionModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace MinecraftService.Shared.Classes.Service.Core
5 | {
6 | public class SimpleVersionModel : IEquatable
7 | {
8 | public string Version { get; set; }
9 | public List DefaultProps { get; set; }
10 | public bool IsBeta { get; set; }
11 |
12 | public SimpleVersionModel(string version, bool isBeta, List props)
13 | {
14 | Version = version;
15 | IsBeta = isBeta;
16 | DefaultProps = props;
17 | }
18 |
19 | public override string ToString()
20 | {
21 | return Version;
22 | }
23 |
24 | public override bool Equals(object obj)
25 | {
26 | return obj is SimpleVersionModel model &&
27 | Version == model.Version &&
28 | IsBeta == model.IsBeta;
29 | }
30 |
31 | public override int GetHashCode()
32 | {
33 | return HashCode.Combine(Version, IsBeta);
34 | }
35 |
36 | public bool Equals(SimpleVersionModel other)
37 | {
38 | return Equals(other);
39 | }
40 |
41 | public static bool operator ==(SimpleVersionModel left, SimpleVersionModel right)
42 | {
43 | return EqualityComparer.Default.Equals(left, right);
44 | }
45 |
46 | public static bool operator !=(SimpleVersionModel left, SimpleVersionModel right)
47 | {
48 | return !(left == right);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## [2.6](https://github.com/crowbarmaster/BedrockManagementService/tree/2.6) (2022-01-07)
4 |
5 | [Full Changelog](https://github.com/crowbarmaster/BedrockManagementService/compare/2.56Beta...2.6)
6 |
7 | **Implemented enhancements:**
8 |
9 | - Enhancement: Add client setting for auto-scroll on client start [\#43](https://github.com/crowbarmaster/BedrockManagementService/issues/43)
10 | - Backups should include installed packs. [\#35](https://github.com/crowbarmaster/BedrockManagementService/issues/35)
11 |
12 | **Fixed bugs:**
13 |
14 | - Backup limit issue, not deleting oldest versions, overwriting newest backup [\#42](https://github.com/crowbarmaster/BedrockManagementService/issues/42)
15 | - Second client start and connect crashes service [\#41](https://github.com/crowbarmaster/BedrockManagementService/issues/41)
16 | - Duplicate resource pack references [\#32](https://github.com/crowbarmaster/BedrockManagementService/issues/32)
17 | - Mojang license [\#25](https://github.com/crowbarmaster/BedrockManagementService/issues/25)
18 | - Need to include pack enabler json files with backups. [\#19](https://github.com/crowbarmaster/BedrockManagementService/issues/19)
19 |
20 | **Closed issues:**
21 |
22 | - Service no longer allows client connections [\#31](https://github.com/crowbarmaster/BedrockManagementService/issues/31)
23 | - Deletion of a backup does not refresh the listing [\#23](https://github.com/crowbarmaster/BedrockManagementService/issues/23)
24 | - Service crashes on Stop [\#21](https://github.com/crowbarmaster/BedrockManagementService/issues/21)
25 | - Service does not appear to use conf files [\#20](https://github.com/crowbarmaster/BedrockManagementService/issues/20)
26 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Reflection;
6 | using System.Runtime.InteropServices;
7 |
8 | // General Information about an assembly is controlled through the following
9 | // set of attributes. Change these attribute values to modify the information
10 | // associated with an assembly.
11 | [assembly: AssemblyTitle("MMSClientGUI")]
12 | [assembly: AssemblyDescription("")]
13 | [assembly: AssemblyConfiguration("")]
14 | [assembly: AssemblyCompany("CrowbarWares")]
15 | [assembly: AssemblyProduct("MMSClientGUI")]
16 | [assembly: AssemblyCopyright("Copyright © 2021")]
17 | [assembly: AssemblyTrademark("")]
18 | [assembly: AssemblyCulture("")]
19 |
20 | // Setting ComVisible to false makes the types in this assembly not visible
21 | // to COM components. If you need to access a type in this assembly from
22 | // COM, set the ComVisible attribute to true on that type.
23 | [assembly: ComVisible(false)]
24 |
25 | // The following GUID is for the ID of the typelib if this project is exposed to COM
26 | [assembly: Guid("a2daf70a-925a-4f4b-b7ee-caace75d6740")]
27 |
28 | // Version information for an assembly consists of the following four values:
29 | //
30 | // Major Version
31 | // Minor Version
32 | // Build Number
33 | // Revision
34 | //
35 | // You can specify all the values or you can default the Build and Revision Numbers
36 | // by using the '*' as shown below:
37 | // [assembly: AssemblyVersion("1.0.*")]
38 | [assembly: AssemblyVersion("3.1.*")]
39 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Networking/NetworkStrategies/ClientConnect.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using MinecraftService.Client.Management;
9 | using MinecraftService.Shared.Classes.Networking;
10 | using MinecraftService.Shared.Classes.Service.Configuration;
11 | using MinecraftService.Shared.Classes.Service.Core;
12 | using MinecraftService.Shared.Interfaces;
13 | using Newtonsoft.Json;
14 |
15 | namespace MinecraftService.Client.Networking.NetworkStrategies {
16 | public class ClientConnect(MmsLogger logger, TCPClient client) : INetworkMessage {
17 |
18 | public Task ProcessMessage(Message message) => Task.Run(() => {
19 | try {
20 | string data = Encoding.UTF8.GetString(message.Data);
21 | if (!string.IsNullOrEmpty(data)) {
22 | logger.AppendLine("Connection to Host successful!");
23 | FormManager.MainWindow.connectedHost = JsonConvert.DeserializeObject(data, SharedStringBase.GlobalJsonSerialierSettings);
24 | FormManager.MainWindow.ConnectedCallback();
25 | return true;
26 | }
27 | } catch (Exception e) {
28 | logger.AppendLine($"Error: ConnectMan reported error: {e.Message}\n{e.StackTrace}");
29 | client.CloseConnection();
30 | client.Cancel();
31 | return false;
32 | }
33 | return false;
34 | });
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/VersionListRequest.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Networking.Interfaces;
2 | using MinecraftService.Shared.Classes;
3 | using MinecraftService.Shared.Classes.Networking;
4 | using MinecraftService.Shared.Classes.Service;
5 | using MinecraftService.Shared.Classes.Service.Configuration;
6 | using MinecraftService.Shared.Classes.Service.Core;
7 | using Newtonsoft.Json;
8 | using System.Text;
9 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
10 |
11 | namespace MinecraftService.Service.Networking.NetworkStrategies
12 | {
13 | public class VersionListRequest(MmsLogger logger, ServiceConfigurator serviceConfiguration) : IMessageParser {
14 |
15 | public Message ParseMessage(Message message) {
16 | logger.AppendLine("Client requested version list data...");
17 | Dictionary resultDictionary = new();
18 | foreach (KeyValuePair updaterKvp in serviceConfiguration.GetUpdaterTable()) {
19 | if (!updaterKvp.Value.IsInitialized())
20 | updaterKvp.Value.Initialize().Wait();
21 | List verStrings = updaterKvp.Value.GetSimpleVersionList();
22 | verStrings.Reverse();
23 | resultDictionary.Add(updaterKvp.Key, verStrings.ToArray());
24 | }
25 | string jsonString = JsonConvert.SerializeObject(resultDictionary, SharedStringBase.GlobalJsonSerialierSettings);
26 | byte[] resultBytes = Encoding.UTF8.GetBytes(jsonString);
27 | return new(resultBytes, message.ServerIndex, MessageTypes.VersionListRequest);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Server/ConsoleFilters/StartupFlagFilter.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Server.Interfaces;
2 | using MinecraftService.Shared.Classes.Service;
3 | using MinecraftService.Shared.Classes.Service.Configuration;
4 | using MinecraftService.Shared.Classes.Service.Core;
5 | using MinecraftService.Shared.Interfaces;
6 | using MinecraftService.Shared.SerializeModels;
7 | using System;
8 | using System.Collections.Generic;
9 | using System.Linq;
10 | using System.Text;
11 | using System.Threading.Tasks;
12 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
13 |
14 | namespace MinecraftService.Service.Server.ConsoleFilters
15 | {
16 | public class StartupFlagFilter : IConsoleFilter {
17 | IServerConfiguration _serverConfiguration;
18 | MmsLogger _logger;
19 | UserConfigManager _configurator;
20 | IServerController _bedrockServer;
21 | ServiceConfigurator _serviceConfiguration;
22 |
23 | public StartupFlagFilter(MmsLogger logger, UserConfigManager configurator, IServerConfiguration serverConfiguration, IServerController bedrockServer, ServiceConfigurator mineraftService) {
24 | _serverConfiguration = serverConfiguration;
25 | _logger = logger;
26 | _configurator = configurator;
27 | _bedrockServer = bedrockServer;
28 | _serviceConfiguration = mineraftService;
29 | }
30 |
31 | public void Filter(string input) {
32 | _bedrockServer.SetStartupStatus(ServerStatus.Started);
33 | Task.Delay(3000).Wait();
34 | if (_serverConfiguration.GetStartCommands().Count > 0) {
35 | _bedrockServer.RunStartupCommands();
36 | }
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/RemovePack.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Networking.Interfaces;
2 | using MinecraftService.Shared.Classes.Networking;
3 | using MinecraftService.Shared.Classes.Service;
4 | using MinecraftService.Shared.Classes.Service.Configuration;
5 | using MinecraftService.Shared.Classes.Service.Core;
6 | using MinecraftService.Shared.FileModels.MinecraftFileModels;
7 | using MinecraftService.Shared.PackParser;
8 | using Newtonsoft.Json;
9 | using System.Text;
10 | using System.Text.Json;
11 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
12 |
13 | namespace MinecraftService.Service.Networking.NetworkStrategies {
14 | public class RemovePack(ServiceConfigurator serviceConfiguration, MmsLogger logger) : IMessageParser {
15 |
16 | public Message ParseMessage(Message message) {
17 | string stringData = Encoding.UTF8.GetString(message.Data);
18 | string worldDirectory = $@"{serviceConfiguration.GetServerInfoByIndex(message.ServerIndex).GetSettingsProp(ServerPropertyKeys.ServerPath)}\worlds\{serviceConfiguration.GetServerInfoByIndex(message.ServerIndex).GetProp(MmsDependServerPropKeys.LevelName)}";
19 | List? container = JsonConvert.DeserializeObject>(stringData, SharedStringBase.GlobalJsonSerialierSettings);
20 | foreach (MinecraftPackContainer content in container) {
21 | MinecraftFileUtilities.RemovePackFromServer(serviceConfiguration.GetServerInfoByIndex(message.ServerIndex), content);
22 | logger.AppendLine($@"{content.JsonManifest.header.name} removed from server.");
23 | }
24 | return Message.EmptyUICallback;
25 | }
26 | }
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/MinecraftService/ServiceTests/SharedTests/JsonModelTests.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.FileModels.MinecraftFileModels;
2 | using System.IO;
3 | using Xunit;
4 |
5 | namespace MMS_Tests.SharedTests {
6 | public class JsonModelTests {
7 |
8 | [Fact]
9 | public void Can_Create_Pack_Manifest_File_Model() {
10 | string sampleJson = "{\"format_version\": 1, \"header\": { \"name\": \"Miniguns and Landmines (behavior)\"," +
11 | "\"description\": \"Miniguns and Landmines. Oh ho ho.\", \"uuid\": \"9edcd542-0ce1-4a00-b28d-c6d0be1fa0dc\"," +
12 | "\"version\": [2, 6, 31] }, \"modules\": [ { \"description\": \"Mech Suit\", \"type\": \"data\", \"uuid\":" +
13 | "\"5a159687-5d39-4449-b6a3-c2514a1962f3\", \"version\": [2, 6, 31] } ], \"dependencies\": [ { \"uuid\":" +
14 | "\"0a4ea708-dedc-4185-b1c1-398a9cea8a32\", \"version\": [2, 6, 31] }]}";
15 | File.WriteAllText(".\\sample_pack_model.json", sampleJson);
16 | PackManifestFileModel fileModel = new(".\\sample_pack_model.json");
17 | Assert.NotNull(fileModel.Contents);
18 | }
19 |
20 | [Fact]
21 | public void Can_Create_Permission_File_Model() {
22 | string sampleJson = "[{\"permission\": \"member\",\"xuid\": \"1234567801234567\"}," +
23 | "{\"permission\": \"operator\",\"xuid\": \"1234567890123456\"}," +
24 | "{\"permission\": \"operator\",\"xuid\": \"2098765432112345\"}]";
25 | File.WriteAllText(".\\sample_permissions_model.json", sampleJson);
26 | PermissionsFileModel fileModel = new(".\\sample_permissions_model.json");
27 | Assert.NotNull(fileModel.Contents);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/Classes/Server/Configurations/CommonDefaults.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using MinecraftService.Shared.Classes.Service.Core;
3 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
4 |
5 | namespace MinecraftService.Shared.Classes.Server.Configurations
6 | {
7 | public static class CommonConfigDefaults
8 | {
9 | public static List PropList = new List() {
10 | new Property(ServerPropertyStrings[ServerPropertyKeys.ServerAutostartEnabled], "true"),
11 | new Property(ServerPropertyStrings[ServerPropertyKeys.AutoBackupEnabled], "false"),
12 | new Property(ServerPropertyStrings[ServerPropertyKeys.AutoRestartEnabled], "false"),
13 | new Property(ServerPropertyStrings[ServerPropertyKeys.BackupCron], "0 1 * * *"),
14 | new Property(ServerPropertyStrings[ServerPropertyKeys.MaxBackupCount], "25"),
15 | new Property(ServerPropertyStrings[ServerPropertyKeys.AutoBackupsContainPacks], "false"),
16 | new Property(ServerPropertyStrings[ServerPropertyKeys.IgnoreInactiveBackups], "true"),
17 | new Property(ServerPropertyStrings[ServerPropertyKeys.CheckUpdatesEnabled], "true"),
18 | new Property(ServerPropertyStrings[ServerPropertyKeys.AutoDeployUpdates], "true"),
19 | new Property(ServerPropertyStrings[ServerPropertyKeys.UpdateCron], "0 2 * * *"),
20 | new Property(ServerPropertyStrings[ServerPropertyKeys.RestartCron], "0 2 * * *"),
21 | new Property(ServerPropertyStrings[ServerPropertyKeys.ServerVersion], "None"),
22 | new Property(ServerPropertyStrings[ServerPropertyKeys.UseBetaVersions], "false"),
23 | new Property(ServerPropertyStrings[ServerPropertyKeys.UseErrorFilter], "true")
24 | };
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/MinecraftService/ServiceTests/SharedTests/UtilitiesTests/FileUtilitiesTests.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.Utilities;
2 | using System.IO;
3 | using Xunit;
4 |
5 | namespace MMS_Tests.SharedTests.UtilitiesTests {
6 | public class FileUtilitiesTests {
7 | private readonly string _testDir = @".\TestDir";
8 | private readonly string _testCopyDir = @".\CopyDir";
9 | private readonly string _testFile = @".\TestDir\File.file";
10 | private readonly string _testCopyFile = @".\CopyDir\File.file";
11 |
12 | [Fact]
13 | public void Can_Create_Inexistant_Directory() {
14 | if (Directory.Exists(@".\TestDir")) {
15 | Directory.Delete(_testDir, true);
16 | }
17 | FileUtilities.CreateInexistentDirectory(_testDir);
18 | Assert.True(Directory.Exists(_testDir));
19 | }
20 |
21 | [Fact]
22 | public void Can_Create_Inexistant_File() {
23 | if (File.Exists(_testFile)) {
24 | File.Delete(_testFile);
25 | }
26 | FileUtilities.CreateInexistentFile(_testFile);
27 | Assert.True(File.Exists(_testFile));
28 | }
29 |
30 | [Fact]
31 | public void CreateInexistantDirectory_Does_Not_Modify_Existing() {
32 | Can_Create_Inexistant_File();
33 | FileUtilities.CreateInexistentDirectory(_testDir);
34 | Assert.True(File.Exists(_testFile));
35 | }
36 |
37 | [Fact]
38 | public void Can_Copy_Folder_Tree() {
39 | FileUtilities.CreateInexistentDirectory(_testCopyDir);
40 | FileUtilities.CreateInexistentFile(_testCopyFile);
41 | FileUtilities.CopyFolderTree(new(_testCopyDir), new(@".\CopyTestDir"));
42 | Assert.True(File.Exists(@$".\CopyTestDir{_testCopyFile.Substring(1)}"));
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/Interfaces/IServerConfiguration.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.Classes.Server;
2 | using MinecraftService.Shared.Classes.Service.Core;
3 | using MinecraftService.Shared.SerializeModels;
4 | using System.Collections.Generic;
5 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
6 |
7 | namespace MinecraftService.Shared.Interfaces
8 | {
9 | public interface IServerConfiguration : IBaseConfiguration {
10 | int GetRunningPid();
11 | void SetRunningPid(int runningPid);
12 | string GetServerName();
13 | string GetConfigFileName();
14 | void AddStartCommand(string command);
15 | bool DeleteStartCommand(string command);
16 | List GetStartCommands();
17 | void SetStartCommands(List newEntries);
18 | List GetPlayerList();
19 | void SetPlayerList(List playerList);
20 | Player GetOrCreatePlayer(string xuid, string username = null);
21 | IServerConfiguration GetServerInfo();
22 | MinecraftServerArch GetServerArch();
23 | void SetServerVersion(string newVersion);
24 | string GetServerVersion();
25 | void SetStatus(ServerStatusModel status);
26 | bool IsPrimaryServer();
27 | ServerStatusModel GetStatus();
28 | void SetBackupTotals(int totalBackups, int totalSize);
29 | void SetSettingsProp(ServerPropertyKeys key, string value);
30 | void SetSettingsProp(string key, string value);
31 | List GetSettingsList();
32 | void SetAllSettings(List settingsList);
33 | void ProcessNewServerConfiguration();
34 | string GetDeployedVersion();
35 | void SetDeployedVersion(string version);
36 | IUpdater GetUpdater();
37 | PlayerManager GetPlayerManager();
38 | void ValidateDeployedServer();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Networking/NetworkMessageLookup.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using MinecraftService.Client.Networking.NetworkStrategies;
7 | using MinecraftService.Shared.Classes.Networking;
8 | using MinecraftService.Shared.Classes.Service.Core;
9 | using MinecraftService.Shared.Interfaces;
10 |
11 | namespace MinecraftService.Client.Networking {
12 | internal class NetworkMessageLookup {
13 | public Dictionary MessageLookupContainer { get; set; }
14 |
15 | public NetworkMessageLookup(MmsLogger logger, TCPClient client) {
16 | MessageLookupContainer = new Dictionary() {
17 | { MessageTypes.Connect, new ClientConnect(logger, client) },
18 | { MessageTypes.EnumBackups, new EnumBackups() },
19 | { MessageTypes.CheckUpdates, new UnlockUI() },
20 | { MessageTypes.UICallback, new UnlockUI() },
21 | { MessageTypes.BackupCallback, new BackupCallback() },
22 | { MessageTypes.VersionListRequest, new VersionListRequest() },
23 | { MessageTypes.ConsoleLogUpdate, new ConsoleLogUpdate(logger) },
24 | { MessageTypes.Backup, new Backup(logger) },
25 | { MessageTypes.PackList, new PackList() },
26 | { MessageTypes.PlayersRequest, new PlayersRequest() },
27 | { MessageTypes.LevelEditFile, new LevelEditFile() },
28 | { MessageTypes.ServerStatusRequest, new ServerStatusRequest() },
29 | { MessageTypes.ClientReject, new ClientReject() },
30 | { MessageTypes.ExportFile, new ExportFile() }
31 | };
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/JsonModels/Minecraft/PackManifestJsonModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace MinecraftService.Shared.JsonModels.Minecraft {
5 | public class PackManifestJsonModel {
6 | public int format_version { get; set; }
7 | public Header header { get; set; }
8 | public List modules { get; set; }
9 | public List dependencies { get; set; }
10 |
11 | public override bool Equals(object obj) {
12 | return obj is PackManifestJsonModel model &&
13 | EqualityComparer.Default.Equals(header, model.header);
14 | }
15 |
16 | public override int GetHashCode() {
17 | return HashCode.Combine(header);
18 | }
19 |
20 | public class Header {
21 | public string description { get; set; }
22 | public string name { get; set; }
23 | public string uuid { get; set; }
24 | public List version { get; set; }
25 |
26 | public override bool Equals(object obj) {
27 | return obj is Header header &&
28 | uuid == header.uuid;
29 | }
30 |
31 | public override int GetHashCode() {
32 | return HashCode.Combine(uuid);
33 | }
34 | }
35 |
36 | public class Module {
37 | public string description { get; set; }
38 | public string type { get; set; }
39 | public string uuid { get; set; }
40 | public List version { get; set; }
41 | public string language { get; set; }
42 | public string entry { get; set; }
43 | }
44 |
45 | public class Dependency {
46 | public string uuid { get; set; }
47 | public object version { get; set; }
48 | public string module_name { get; set; }
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Networking/NetworkStrategies/ServerStatusRequest.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using MinecraftService.Client.Management;
8 | using MinecraftService.Shared.Classes.Networking;
9 | using MinecraftService.Shared.Classes.Service.Core;
10 | using MinecraftService.Shared.SerializeModels;
11 | using Newtonsoft.Json;
12 |
13 | namespace MinecraftService.Client.Networking.NetworkStrategies {
14 | public class ServerStatusRequest : INetworkMessage {
15 |
16 | public Task ProcessMessage(Message message) => Task.Run(() => {
17 | StatusUpdateModel status = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(message.Data), SharedStringBase.GlobalJsonSerialierSettings);
18 | if (status != null && status.ServerStatusModel != null && status.ServerStatusModel.ServerIndex != 255 && FormManager.MainWindow.SelectedServer != null) {
19 | ServerStatusModel formerServerStatus = FormManager.MainWindow.SelectedServer.GetStatus();
20 | if (!status.ServerStatusModel.Equals(formerServerStatus)) {
21 | FormManager.MainWindow.connectedHost.GetServerInfoByIndex(status.ServerStatusModel.ServerIndex).SetStatus(status.ServerStatusModel);
22 | FormManager.MainWindow.Invoke(() => FormManager.MainWindow.RefreshAllCompenentStates());
23 | FormManager.TCPClient.SendData(new() {
24 | ServerIndex = message.ServerIndex,
25 | Type = MessageTypes.EnumBackups
26 | });
27 | }
28 | FormManager.MainWindow.ServiceStatus = status.ServiceStatusModel;
29 | }
30 | return true;
31 | });
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Forms/RemoveServerControl.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Windows.Forms;
7 | using MinecraftService.Shared.Classes.Networking;
8 |
9 | namespace MinecraftService.Client.Forms {
10 | public partial class RemoveServerControl : Form {
11 | public MessageFlags SelectedFlag;
12 | public RemoveServerControl() {
13 | InitializeComponent();
14 | }
15 |
16 | private void saveBtn_Click(object sender, EventArgs e) {
17 | if (checkedListBox1.CheckedItems.Count == 0) {
18 | return;
19 | }
20 | foreach (var item in checkedListBox1.CheckedItems) {
21 | if (item.ToString() == "Remove server files") {
22 | SelectedFlag = MessageFlags.RemoveSrv;
23 | }
24 | if (item.ToString() == "Remove server's backups") {
25 | if (SelectedFlag == MessageFlags.RemoveSrv) {
26 | SelectedFlag = MessageFlags.RemoveBckSrv;
27 | } else {
28 | SelectedFlag = MessageFlags.RemoveBackups;
29 | }
30 | }
31 | if (item.ToString() == "Remove player record files") {
32 | if (SelectedFlag == MessageFlags.RemoveSrv) {
33 | SelectedFlag = MessageFlags.RemovePlySrv;
34 | }
35 | if (SelectedFlag == MessageFlags.RemoveBckSrv) {
36 | SelectedFlag = MessageFlags.RemoveAll;
37 | }
38 | if (SelectedFlag == MessageFlags.RemoveBackups) {
39 | SelectedFlag = MessageFlags.RemoveBckPly;
40 | }
41 | }
42 | }
43 | DialogResult = DialogResult.OK;
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Server/ConsoleFilters/JavaBackupDetectFilter.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Server.Interfaces;
2 | using MinecraftService.Shared.Classes.Service;
3 | using MinecraftService.Shared.Classes.Service.Configuration;
4 | using MinecraftService.Shared.Classes.Service.Core;
5 | using MinecraftService.Shared.Interfaces;
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
12 |
13 | namespace MinecraftService.Service.Server.ConsoleFilters
14 | {
15 | public class JavaBackupDetectFilter : IConsoleFilter {
16 | IServerConfiguration _serverConfiguration;
17 | MmsLogger _logger;
18 | UserConfigManager _configurator;
19 | IServerController _javaServer;
20 | ServiceConfigurator _serviceConfiguration;
21 |
22 | public JavaBackupDetectFilter(MmsLogger logger, UserConfigManager configurator, IServerConfiguration serverConfiguration, IServerController javaServer, ServiceConfigurator mineraftService) {
23 | _serverConfiguration = serverConfiguration;
24 | _logger = logger;
25 | _configurator = configurator;
26 | _javaServer = javaServer;
27 | _serviceConfiguration = mineraftService;
28 | }
29 |
30 | public void Filter(string input) {
31 | _logger.AppendLine($"Save data signal for server {_serverConfiguration.GetServerName()} detected! Performing backup now!");
32 | if (_javaServer.GetBackupManager().PerformBackup(input)) {
33 | _logger.AppendLine($"Backup for server {_serverConfiguration.GetServerName()} Completed.");
34 | if (_javaServer.GetActivePlayerList().Count == 0) {
35 | _javaServer.SetServerModified(false);
36 | }
37 | return;
38 | }
39 | _logger.AppendLine($"Backup for server {_serverConfiguration.GetServerName()} Failed. Check logs!");
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/MinecraftService/Service/Server/ConsoleFilters/BackupStringFilter.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Server.Interfaces;
2 | using MinecraftService.Shared.Classes.Service;
3 | using MinecraftService.Shared.Classes.Service.Configuration;
4 | using MinecraftService.Shared.Classes.Service.Core;
5 | using MinecraftService.Shared.Interfaces;
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
12 |
13 | namespace MinecraftService.Service.Server.ConsoleFilters
14 | {
15 | public class BackupStringFilter : IConsoleFilter {
16 | IServerConfiguration _serverConfiguration;
17 | MmsLogger _logger;
18 | UserConfigManager _configurator;
19 | IServerController _minecraftServer;
20 | ServiceConfigurator _serviceConfiguration;
21 |
22 | public BackupStringFilter(MmsLogger logger, UserConfigManager configurator, IServerConfiguration serverConfiguration, IServerController minecraftServer, ServiceConfigurator minecraftService) {
23 | _serverConfiguration = serverConfiguration;
24 | _logger = logger;
25 | _configurator = configurator;
26 | _minecraftServer = minecraftServer;
27 | _serviceConfiguration = minecraftService;
28 | }
29 |
30 | public void Filter(string input) {
31 | if (input.Contains("[Server]")) {
32 | input = input.Substring(input.IndexOf(']') + 2);
33 | }
34 | _logger.AppendLine($"Save data string {_serverConfiguration.GetServerName()} detected! Performing backup now!");
35 | if (_minecraftServer.GetBackupManager().PerformBackup(input)) {
36 | _logger.AppendLine($"Backup for server {_serverConfiguration.GetServerName()} Completed.");
37 | if (_minecraftServer.GetActivePlayerList().Count == 0) {
38 | _minecraftServer.SetServerModified(false);
39 | }
40 | return;
41 | }
42 | _logger.AppendLine($"Backup for server {_serverConfiguration.GetServerName()} Failed. Check logs!");
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/SerializeModels/StatusModels.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Shared.Classes.Server;
2 | using MinecraftService.Shared.Interfaces;
3 | using System;
4 | using System.Collections.Generic;
5 |
6 |
7 | namespace MinecraftService.Shared.SerializeModels {
8 | public enum ServiceStatus {
9 | Stopped,
10 | Starting,
11 | Stopping,
12 | Started
13 | }
14 |
15 | public enum ServerStatus {
16 | Stopped,
17 | Starting,
18 | Stopping,
19 | Started
20 | }
21 |
22 | public class StatusUpdateModel {
23 | public ServiceStatusModel ServiceStatusModel { get; set; }
24 | public ServerStatusModel ServerStatusModel { get; set; }
25 | }
26 |
27 | public class ServiceStatusModel {
28 | public DateTime ServiceUptime { get; set; }
29 | public ServiceStatus ServiceStatus { get; set; }
30 | public List ActivePlayerList { get; set; } = new List();
31 | public int TotalBackups { get; set; }
32 | public int TotalBackupSize { get; set; }
33 | public string LatestVersion { get; set; }
34 | }
35 |
36 | public class ServerStatusModel {
37 | public DateTime ServerUptime { get; set; }
38 | public byte ServerIndex { get; set; }
39 | public ServerStatus ServerStatus { get; set; }
40 | public List ActivePlayerList { get; set; } = new List();
41 | public int TotalBackups { get; set; }
42 | public int TotalSizeOfBackups { get; set; }
43 | public string DeployedVersion { get; set; }
44 |
45 | public override bool Equals(object obj) {
46 | return obj is ServerStatusModel model &&
47 | ServerStatus == model.ServerStatus &&
48 | ServerIndex == model.ServerIndex &&
49 | TotalBackups == model.TotalBackups &&
50 | TotalSizeOfBackups == model.TotalSizeOfBackups &&
51 | DeployedVersion == model.DeployedVersion;
52 | }
53 |
54 | public override int GetHashCode() {
55 | return HashCode.Combine(ServerStatus, TotalBackups, ServerIndex, TotalSizeOfBackups, DeployedVersion);
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Forms/ExporterControl.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Windows.Forms;
7 | using MinecraftService.Shared.Classes.Networking;
8 |
9 | namespace MinecraftService.Client.Forms {
10 | public partial class ExporterControl : Form {
11 | public MessageFlags SelectedFlag;
12 | public ExporterControl() {
13 | InitializeComponent();
14 | }
15 |
16 | private void saveBtn_Click(object sender, EventArgs e) {
17 | if (checkedListBox1.CheckedItems.Count == 0) {
18 | return;
19 | }
20 | foreach (var item in checkedListBox1.CheckedItems) {
21 | if (item.ToString() == "Remove server files") {
22 | SelectedFlag = MessageFlags.RemoveSrv;
23 | }
24 | if (item.ToString() == "Remove server's backups") {
25 | if (SelectedFlag == MessageFlags.RemoveSrv) {
26 | SelectedFlag = MessageFlags.RemoveBckSrv;
27 | } else {
28 | SelectedFlag = MessageFlags.RemoveBackups;
29 | }
30 | }
31 | if (item.ToString() == "Remove player record files") {
32 | if (SelectedFlag == MessageFlags.RemoveSrv) {
33 | SelectedFlag = MessageFlags.RemovePlySrv;
34 | }
35 | if (SelectedFlag == MessageFlags.RemoveBckSrv) {
36 | SelectedFlag = MessageFlags.RemoveAll;
37 | }
38 | if (SelectedFlag == MessageFlags.RemoveBackups) {
39 | SelectedFlag = MessageFlags.RemoveBckPly;
40 | }
41 | }
42 | }
43 | DialogResult = DialogResult.OK;
44 | }
45 |
46 | private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e) {
47 |
48 | }
49 |
50 | private void label1_Click(object sender, EventArgs e) {
51 |
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/AddNewServer.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Core;
2 | using MinecraftService.Service.Networking.Interfaces;
3 | using MinecraftService.Shared.Classes.Networking;
4 | using MinecraftService.Shared.Classes.Server;
5 | using MinecraftService.Shared.Classes.Service;
6 | using MinecraftService.Shared.Classes.Service.Configuration;
7 | using MinecraftService.Shared.Classes.Service.Core;
8 | using MinecraftService.Shared.SerializeModels;
9 | using Newtonsoft.Json;
10 | using System.Text;
11 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
12 |
13 | namespace MinecraftService.Service.Networking.NetworkStrategies
14 | {
15 | public class AddNewServer(MmsLogger logger, ProcessInfo processInfo, UserConfigManager configurator, ServiceConfigurator serviceConfiguration, MmsService minecraftService) : IMessageParser {
16 |
17 | public Message ParseMessage(Message message) {
18 | string stringData = Encoding.UTF8.GetString(message.Data);
19 | ServerCombinedPropModel propModel = JsonConvert.DeserializeObject(stringData, GlobalJsonSerialierSettings);
20 | Property? archProp = propModel?.ServicePropList?.First(x => x.KeyName == ServerPropertyStrings[ServerPropertyKeys.MinecraftType]);
21 | MinecraftServerArch selectedArch = GetArchFromString(archProp.StringValue);
22 | configurator.VerifyServerArchInit(selectedArch);
23 | IServerConfiguration newServer = serviceConfiguration.PrepareNewServerConfig(selectedArch, processInfo, logger);
24 | newServer.InitializeDefaults();
25 | newServer.SetAllSettings(propModel?.ServicePropList);
26 | newServer.SetAllProps(propModel?.ServerPropList);
27 | newServer.ProcessNewServerConfiguration();
28 | configurator.SaveServerConfiguration(newServer);
29 | minecraftService.InitializeNewServer(newServer);
30 |
31 |
32 | byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(serviceConfiguration, Formatting.Indented, GlobalJsonSerialierSettings));
33 | return new Message {
34 | Data = serializeToBytes,
35 | Type = MessageTypes.Connect
36 | };
37 | }
38 | }
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Management/FormManager.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 | using System.IO;
7 | using System.Windows.Forms;
8 | using MinecraftService.Client.Forms;
9 | using MinecraftService.Client.Networking;
10 | using MinecraftService.Shared.Classes.Server;
11 | using MinecraftService.Shared.Classes.Service.Configuration;
12 | using MinecraftService.Shared.Classes.Service.Core;
13 | using MinecraftService.Shared.Interfaces;
14 |
15 | namespace MinecraftService.Client.Management {
16 | public sealed class FormManager {
17 | public static readonly ProcessInfo processInfo = new ProcessInfo("Client", Path.GetDirectoryName(Application.ExecutablePath), Process.GetCurrentProcess().Id, false, true);
18 | public static readonly ServiceConfigurator ClientLogContainer;
19 | public static readonly MmsLogger Logger;
20 | private static MainWindow main;
21 | private static TCPClient client;
22 |
23 | static FormManager() {
24 | ClientLogContainer = new ServiceConfigurator(processInfo, new());
25 | ClientLogContainer.InitializeDefaults();
26 | Logger = new MmsLogger(processInfo, ClientLogContainer);
27 | Logger.AppendLine($"Bedrock Client version {Application.ProductVersion} has started.");
28 | Logger.AppendLine($"Working directory: {processInfo.GetDirectory()}");
29 | SharedStringBase.SetWorkingDirectory(processInfo);
30 | client = new TCPClient(Logger);
31 | main = new MainWindow(processInfo, Logger);
32 | }
33 |
34 | public static MainWindow MainWindow {
35 | get {
36 | if (main == null || main.IsDisposed) {
37 | main = new MainWindow(processInfo, Logger);
38 | }
39 | return main;
40 | }
41 | }
42 |
43 | public static TCPClient TCPClient {
44 | get {
45 | if (client == null) {
46 | client = new TCPClient(Logger);
47 | }
48 | return client;
49 | }
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/ServerPropUpdate.cs:
--------------------------------------------------------------------------------
1 |
2 | using MinecraftService.Service.Core;
3 | using MinecraftService.Service.Networking.Interfaces;
4 | using MinecraftService.Shared.Classes.Networking;
5 | using MinecraftService.Shared.Classes.Service;
6 | using MinecraftService.Shared.Classes.Service.Configuration;
7 | using MinecraftService.Shared.Classes.Service.Core;
8 | using Newtonsoft.Json;
9 | using System.Text;
10 |
11 | namespace MinecraftService.Service.Networking.NetworkStrategies
12 | {
13 | public class ServerPropUpdate(MmsLogger logger, UserConfigManager configurator, ServiceConfigurator serviceConfiguration, MmsService mineraftService) : IMessageParser {
14 |
15 | public Message ParseMessage(Message message) {
16 | string stringData = Encoding.UTF8.GetString(message.Data);
17 | List propList = JsonConvert.DeserializeObject>(stringData, SharedStringBase.GlobalJsonSerialierSettings);
18 | Property prop = propList.FirstOrDefault(p => p.KeyName == "AcceptedMojangLic");
19 | if (prop != null) {
20 | serviceConfiguration.SetAllProps(propList);
21 | configurator.SaveGlobalFile();
22 | logger.AppendLine("Successfully wrote service configuration to file! Restarting service to apply changes!");
23 | mineraftService.RestartService();
24 | return new();
25 | }
26 | prop = propList.FirstOrDefault(p => p.KeyName == "server-name");
27 | if (prop != null) {
28 | foreach (Property property in propList) {
29 | serviceConfiguration.GetServerInfoByIndex(message.ServerIndex).SetProp(property);
30 | }
31 | } else {
32 | foreach (Property property in propList) {
33 | serviceConfiguration.GetServerInfoByIndex(message.ServerIndex).SetSettingsProp(property.KeyName, property.StringValue);
34 | }
35 | }
36 | configurator.SaveServerConfiguration(serviceConfiguration.GetServerInfoByIndex(message.ServerIndex));
37 | logger.AppendLine("Successfully wrote server configuration to file! Restart server to apply changes!");
38 | return Message.EmptyUICallback;
39 | }
40 | }
41 | }
42 |
43 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/MinecraftService.Shared.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net9.0
4 | win-x64
5 | Library
6 | false
7 | Debug;Release;Publish
8 | AnyCPU;x64
9 |
10 |
11 | 2
12 | False
13 |
14 |
15 | 2
16 | False
17 |
18 |
19 | 2
20 | False
21 |
22 |
23 | 2
24 | False
25 |
26 |
27 | False
28 |
29 |
30 | False
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | all
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/.github/workflows/BMSBuild.yml:
--------------------------------------------------------------------------------
1 | name: Build BMS
2 |
3 | on:
4 | workflow_dispatch:
5 | pull_request:
6 | types: [closed]
7 |
8 | jobs:
9 | build:
10 |
11 | runs-on: windows-2022
12 |
13 | steps:
14 | - uses: actions/checkout@v2
15 |
16 | - name: Setup .NET
17 | uses: actions/setup-dotnet@v3.2.0
18 | with:
19 | dotnet-version: 9.0.x
20 |
21 | - name: Setup MSBuild
22 | uses: microsoft/setup-msbuild@v1.3.1
23 |
24 | - name: Restore NuGet packages
25 | run: dotnet restore "MinecraftService\MinecraftService.sln"
26 |
27 | - name: Publish with MSBuild
28 | run: msbuild "MinecraftService\MinecraftService.sln" -property:Configuration=Release /t:publish -p:PublishProfile=FolderProfile
29 |
30 | - name: Set version string
31 | run: |
32 | $TMP = (get-item MinecraftService\bin\Published\MinecraftService.Service.exe).VersionInfo.FileVersion;
33 | echo "PROJ_VER=$TMP" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append;
34 | echo "${{ env.PROJ_VER }}"
35 |
36 | - name: Push Automatic Release
37 | uses: crowbarmaster/GH-Automatic-Releases@latest
38 | with:
39 | repo_token: "${{ secrets.REPO_TOKEN }}"
40 | automatic_release_tag: "${{ env.PROJ_VER }}"
41 | prerelease: true
42 | title: "Development Build: Version ${{ env.PROJ_VER }}"
43 |
44 | - name: Update CHANGELOG
45 | continue-on-error: true
46 | uses: requarks/changelog-action@v1
47 | id: changelog
48 | with:
49 | token: ${{ github.token }}
50 | tag: ${{ env.PROJ_VER }}
51 | includeInvalidCommits: true
52 | excludeTypes: build
53 | reverseOrder: true
54 |
55 | - name: Compress published files
56 | run: |
57 | Remove-item MinecraftService\bin\Published\Launcher.exe;
58 | Compress-Archive -path MinecraftService\bin\Published\*.exe* ".\MMS_${{ env.PROJ_VER }}.zip" -Force;
59 |
60 | - name: Push Automatic Release
61 | uses: crowbarmaster/GH-Automatic-Releases@latest
62 | with:
63 | repo_token: "${{ secrets.GITHUB_TOKEN }}"
64 | automatic_release_tag: "${{ env.PROJ_VER }}"
65 | prerelease: true
66 | title: "Development Build: Version ${{ env.PROJ_VER }}"
67 | body: ${{ steps.changelog.outputs.changes }}
68 | files: |
69 | MMS_*.zip
70 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Forms/NewPlayerRegistrationForm.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Windows.Forms;
7 | using MinecraftService.Client.Management;
8 | using MinecraftService.Shared.Classes.Server;
9 | using MinecraftService.Shared.Classes.Service.Core;
10 | using MinecraftService.Shared.Interfaces;
11 |
12 | namespace MinecraftService.Client.Forms {
13 | public partial class NewPlayerRegistrationForm : Form {
14 | public Player PlayerToAdd;
15 | private readonly IServerConfiguration _serverConfiguration;
16 |
17 | public NewPlayerRegistrationForm() {
18 | InitializeComponent();
19 | _serverConfiguration = FormManager.MainWindow.SelectedServer;
20 | }
21 |
22 | private void saveClick(object sender, EventArgs e) {
23 | long curTime = DateTime.Now.Ticks;
24 | if (usernameTextBox.TextLength > 0 && xuidTextBox.TextLength == 16 || xuidTextBox.TextLength == 36 || xuidTextBox.TextLength == 32) {
25 | PlayerToAdd =
26 | new Player(xuidTextBox.Text, usernameTextBox.Text, curTime, curTime, curTime, whitelistedChkBox.Checked,
27 | _serverConfiguration.GetServerArch() == SharedStringBase.MinecraftServerArch.Java ?
28 | TranslatePermLevel(permissionComboBox.SelectedItem.ToString()) :
29 | permissionComboBox.SelectedItem.ToString(),
30 | ignoreLimitChkBox.Checked);
31 | DialogResult = DialogResult.OK;
32 | }
33 | }
34 |
35 | private string TranslatePermLevel(string permLevel) {
36 | switch (permLevel) {
37 | case "visitor":
38 | return "2";
39 | case "member":
40 | return "3";
41 | case "operator":
42 | return "4";
43 | case "2":
44 | return "visitor";
45 | case "3":
46 | return "member";
47 | case "4":
48 | return "operator";
49 | default:
50 | return "";
51 | }
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Forms/ProgressDialog.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Threading.Tasks;
7 | using System.Windows.Forms;
8 | using MinecraftService.Shared.Classes.Service.Core;
9 |
10 | namespace MinecraftService.Client.Forms {
11 | public partial class ProgressDialog : Form {
12 | private readonly IProgress _progress;
13 | private Task _onCompletion;
14 | private int _closeTimeout = 1500;
15 | private System.Timers.Timer _closeTimer;
16 |
17 | public ProgressDialog(Task callbackAction) {
18 | InitializeComponent();
19 | _closeTimer = new System.Timers.Timer(_closeTimeout);
20 | _onCompletion = callbackAction;
21 | progressBar.Minimum = 0;
22 | progressBar.Maximum = 100;
23 | _closeTimer.AutoReset = false;
24 | _progress = new Progress((currentProgress) => {
25 | progressBar.Value = (int)currentProgress.Progress;
26 | progressLabel.Text = $"{currentProgress.Message}";
27 | string formattedPercent = string.Format("{0:N2}", currentProgress.Progress);
28 | if (currentProgress.Progress != 0) {
29 | percentLabel.Text = $"{formattedPercent}% completed...";
30 | }
31 | Refresh();
32 | });
33 | }
34 |
35 | public IProgress GetDialogProgress() {
36 | return _progress;
37 | }
38 |
39 | public void EndProgress(Task closingActions, int closeTimeout = 1500) {
40 | _closeTimeout = closeTimeout;
41 | _closeTimer.Elapsed += (s, e) => {
42 | if (closingActions != null && closingActions.Status == TaskStatus.Created) {
43 | closingActions.Start();
44 | }
45 | if (_onCompletion != null && _onCompletion.Status == TaskStatus.Created) {
46 | _onCompletion.Start();
47 | }
48 | };
49 | _closeTimer.Start();
50 | }
51 |
52 | public void SetCallback(Task action) {
53 | _onCompletion = action;
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Server/ConsoleFilters/JavaPlayerConnectedFilter.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Server.Interfaces;
2 | using MinecraftService.Shared.Classes.Service;
3 | using MinecraftService.Shared.Classes.Service.Configuration;
4 | using MinecraftService.Shared.Classes.Service.Core;
5 | using MinecraftService.Shared.Interfaces;
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
12 |
13 | namespace MinecraftService.Service.Server.ConsoleFilters
14 | {
15 | public class JavaPlayerConnectedFilter : IConsoleFilter {
16 | IServerConfiguration _serverConfiguration;
17 | MmsLogger _logger;
18 | UserConfigManager _configurator;
19 | IServerController _javaServer;
20 | ServiceConfigurator _serviceConfiguration;
21 |
22 | public JavaPlayerConnectedFilter(MmsLogger logger, UserConfigManager configurator, IServerConfiguration serverConfiguration, IServerController javaServer, ServiceConfigurator mineraftService) {
23 | _serverConfiguration = serverConfiguration;
24 | _logger = logger;
25 | _configurator = configurator;
26 | _javaServer = javaServer;
27 | _serviceConfiguration = mineraftService;
28 | }
29 |
30 | public void Filter(string input) {
31 | var playerInfo = ExtractPlayerInfoFromString(input);
32 | _logger.AppendLine($"Player {playerInfo.username} connected to server {_serverConfiguration.GetServerName()}.");
33 | _javaServer.SetServerModified(true);
34 | _javaServer.GetActivePlayerList().Add(_javaServer.GetPlayerManager().PlayerConnected(playerInfo.username, playerInfo.uuid));
35 | _configurator.SavePlayerDatabase(_serverConfiguration);
36 | }
37 |
38 | private (string username, string uuid) ExtractPlayerInfoFromString(string input) {
39 | int msgStartIndex = input.IndexOf("]:") + 3;
40 | int userStart = msgStartIndex + "UUID of player ".Length;
41 | int uuidLength = 36;
42 | int uuidStart = input.Length - uuidLength;
43 | int userEnd = uuidStart - 4;
44 | int userLength = userEnd - userStart;
45 | return (input.Substring(userStart, userLength), input.Substring(uuidStart, uuidLength));
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/MinecraftService/Service/Server/ConsoleFilters/JavaPlayerDisconnectedFilter.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Server.Interfaces;
2 | using MinecraftService.Shared.Classes.Service;
3 | using MinecraftService.Shared.Classes.Service.Configuration;
4 | using MinecraftService.Shared.Classes.Service.Core;
5 | using MinecraftService.Shared.Interfaces;
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
12 |
13 | namespace MinecraftService.Service.Server.ConsoleFilters
14 | {
15 | public class JavaPlayerDisconnectedFilter : IConsoleFilter {
16 | IServerConfiguration _serverConfiguration;
17 | MmsLogger _logger;
18 | UserConfigManager _configurator;
19 | IServerController _bedrockServer;
20 | ServiceConfigurator _serviceConfiguration;
21 |
22 | public JavaPlayerDisconnectedFilter(MmsLogger logger, UserConfigManager configurator, IServerConfiguration serverConfiguration, IServerController bedrockServer, ServiceConfigurator mineraftService) {
23 | _serverConfiguration = serverConfiguration;
24 | _logger = logger;
25 | _configurator = configurator;
26 | _bedrockServer = bedrockServer;
27 | _serviceConfiguration = mineraftService;
28 | }
29 |
30 | public void Filter(string input) {
31 | var playerInfo = ExtractPlayerInfoFromString(input);
32 | if (_bedrockServer.GetActivePlayerList().Any()) {
33 | if(_bedrockServer.GetActivePlayerList().Remove(_bedrockServer.GetActivePlayerList().Where(x => x.GetPlayerID() == _bedrockServer.GetPlayerManager().PlayerDisconnected(playerInfo.username, playerInfo.xuid).GetPlayerID()).FirstOrDefault())) {
34 | _logger.AppendLine($"Player {playerInfo.username} disconnected from server {_serverConfiguration.GetServerName()}.");
35 | }
36 | }
37 | _configurator.SavePlayerDatabase(_serverConfiguration);
38 | }
39 |
40 | private (string username, string xuid) ExtractPlayerInfoFromString(string input) {
41 | int msgStartIndex = input.IndexOf("]:") + 3;
42 | int usernameEnd = input.IndexOf(" left the game", msgStartIndex);
43 | int usernameLength = usernameEnd - msgStartIndex;
44 | return (input.Substring(msgStartIndex, usernameLength), "");
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/PackList.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Networking.Interfaces;
2 | using MinecraftService.Shared.Classes.Networking;
3 | using MinecraftService.Shared.Classes.Server;
4 | using MinecraftService.Shared.Classes.Service;
5 | using MinecraftService.Shared.Classes.Service.Configuration;
6 | using MinecraftService.Shared.Classes.Service.Core;
7 | using MinecraftService.Shared.JsonModels.Minecraft;
8 | using MinecraftService.Shared.PackParser;
9 | using Newtonsoft.Json;
10 | using NLog.LayoutRenderers;
11 | using System.Text;
12 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
13 |
14 | namespace MinecraftService.Service.Networking.NetworkStrategies
15 | {
16 | public class PackList(ProcessInfo processInfo, ServiceConfigurator serviceConfiguration, MmsLogger logger) : IMessageParser {
17 |
18 | public Message ParseMessage(Message message) {
19 | IServerConfiguration server = serviceConfiguration.GetServerInfoByIndex(message.ServerIndex);
20 | string serverPath = server.GetSettingsProp(ServerPropertyKeys.ServerPath).StringValue;
21 | string levelName = server.GetProp(MmsDependServerPropKeys.LevelName).StringValue;
22 | string pathToWorldFolder = $@"{serverPath}\worlds\{levelName}";
23 | List combinedList = new List();
24 | IProgress progress = new Progress((progress) => {
25 | string percent = string.Format("{0:N2}", progress.Progress);
26 | logger.AppendLine($"{progress.Message} {percent}%");
27 | });
28 | MinecraftPackParser resourceParser = new(logger, progress);
29 | MinecraftPackParser behaviorParser = new(logger, progress);
30 | resourceParser.ParseDirectory(GetServerDirectory(ServerDirectoryKeys.ResourcePacksDir_LevelName, serverPath, levelName), 0);
31 | behaviorParser.ParseDirectory(GetServerDirectory(ServerDirectoryKeys.BehaviorPacksDir_LevelName, serverPath, levelName), 0);
32 | MinecraftFileUtilities.ValidateFixWorldPackFiles(serverPath, levelName).Wait();
33 | combinedList.AddRange(resourceParser.FoundPacks);
34 | combinedList.AddRange(behaviorParser.FoundPacks);
35 |
36 | string arrayString = JsonConvert.SerializeObject(combinedList);
37 | return new(Encoding.UTF8.GetBytes(arrayString), 0, MessageTypes.PackList);
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/SerializeModels/BackupInfoModel.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 | using System.Drawing;
4 | using System.Globalization;
5 | using System.IO;
6 |
7 | namespace MinecraftService.Shared.SerializeModels {
8 | public class BackupInfoModel {
9 | public DateTime Timestamp { get; set; }
10 | public string Filename { get; set; }
11 | public int SizeInKb { get; set; }
12 | private const string _backupStringTemplate = "Backup-yyyyMMdd_HHmmssff.zip";
13 | private const string _backupFilenamePrefix = "Backup-";
14 | private const string _timestampTemplate = "yyyyMMdd_HHmmssff";
15 |
16 | public BackupInfoModel(FileInfo backupFileInfo) {
17 | Filename = backupFileInfo.Name;
18 | if (backupFileInfo.Exists) {
19 | SizeInKb = (int)(backupFileInfo.Length / 1000);
20 | } else {
21 | SizeInKb = 0;
22 | }
23 | if (backupFileInfo.Name.Length != _backupStringTemplate.Length) {
24 | throw new ArgumentOutOfRangeException($"File name length of file {backupFileInfo.Name} was not as expected! Omitted from backup enumeration.");
25 | }
26 | string timeStampFromName = backupFileInfo.Name.Substring(_backupFilenamePrefix.Length, _timestampTemplate.Length);
27 | if (!DateTime.TryParseExact(timeStampFromName, "yyyyMMdd_HHmmssff", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime parsedTime)) {
28 | throw new FormatException($"DateTime format of file {backupFileInfo.Name} did not match! Omitted from backup enumeration.");
29 | }
30 | Timestamp = parsedTime;
31 | }
32 |
33 | public BackupInfoModel() {
34 | Filename = "-----.zip";
35 | SizeInKb = 0;
36 | Timestamp = DateTime.MinValue;
37 | }
38 |
39 | [JsonConstructor]
40 | public BackupInfoModel(string filename, int size, DateTime stamp) {
41 | Filename = filename;
42 | SizeInKb = size;
43 | Timestamp = stamp;
44 | }
45 |
46 | public string[] GetBackupInfo() {
47 | return new string[5] { $"Filename: {Filename}", $"Created on: {Timestamp.ToString("G")}", $"Size of backup: {SizeInKb / 1000f} MB", "", "-----------------------------------------------------------" };
48 | }
49 |
50 | public override string ToString() {
51 | return Filename;
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/.github/workflows/BMSBuildStable.yml:
--------------------------------------------------------------------------------
1 | name: Build BMS (Stable)
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | lastTag:
7 | description: 'Beginning of changelog history starts at this tag name.'
8 | required: true
9 |
10 | jobs:
11 | build:
12 |
13 | runs-on: windows-2022
14 |
15 | steps:
16 | - uses: actions/checkout@v2
17 |
18 | - name: Setup .NET
19 | uses: actions/setup-dotnet@v3.2.0
20 | with:
21 | dotnet-version: 9.0.x
22 |
23 | - name: Setup MSBuild
24 | uses: microsoft/setup-msbuild@v1.3.1
25 |
26 | - name: Restore NuGet packages
27 | run: dotnet restore "MinecraftService\MinecraftService.sln"
28 |
29 | - name: Publish with MSBuild
30 | run: msbuild "MinecraftService\MinecraftService.sln" -property:Configuration=Release /t:publish -p:PublishProfile=FolderProfile
31 |
32 | - name: Set version string
33 | run: |
34 | $TMP = (get-item MinecraftService\bin\Published\MinecraftService.Service.exe).VersionInfo.FileVersion;
35 | echo "PROJ_VER=$TMP" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append;
36 | echo "${{ env.PROJ_VER }}"
37 |
38 | - name: Push Automatic Release
39 | uses: crowbarmaster/GH-Automatic-Releases@latest
40 | with:
41 | repo_token: "${{ secrets.GITHUB_TOKEN }}"
42 | automatic_release_tag: "${{ env.PROJ_VER }}"
43 | prerelease: true
44 | title: "Development Build: Version ${{ env.PROJ_VER }}"
45 |
46 | - name: Update CHANGELOG
47 | continue-on-error: true
48 | uses: requarks/changelog-action@v1
49 | id: changelog
50 | with:
51 | token: ${{ github.token }}
52 | fromtag: ${{ env.PROJ_VER }}
53 | totag: ${{ inputs.lastTag }}
54 | includeInvalidCommits: true
55 | excludeTypes: build
56 | reverseOrder: true
57 |
58 | - name: Compress published files
59 | run: |
60 | Remove-item MinecraftService\bin\Published\Launcher.exe;
61 | Compress-Archive -path MinecraftService\bin\Published\*.exe* ".\MMS_${{ env.PROJ_VER }}.zip" -Force;
62 |
63 | - name: Push Automatic Release
64 | uses: crowbarmaster/GH-Automatic-Releases@latest
65 | with:
66 | repo_token: "${{ secrets.GITHUB_TOKEN }}"
67 | automatic_release_tag: "${{ env.PROJ_VER }}"
68 | prerelease: false
69 | title: "Stable Build: Version ${{ env.PROJ_VER }}"
70 | body: ${{ steps.changelog.outputs.changes }}
71 | files: |
72 | MMS_*.zip
73 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Server/ConsoleFilters/BedrockPlayerDisconnectedFilter.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Server.Interfaces;
2 | using MinecraftService.Shared.Classes.Service;
3 | using MinecraftService.Shared.Classes.Service.Configuration;
4 | using MinecraftService.Shared.Classes.Service.Core;
5 | using MinecraftService.Shared.Interfaces;
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
12 |
13 | namespace MinecraftService.Service.Server.ConsoleFilters
14 | {
15 | public class BedrockPlayerDisconnectedFilter : IConsoleFilter {
16 | IServerConfiguration _serverConfiguration;
17 | MmsLogger _logger;
18 | UserConfigManager _configurator;
19 | IServerController _bedrockServer;
20 | ServiceConfigurator _serviceConfiguration;
21 |
22 | public BedrockPlayerDisconnectedFilter(MmsLogger logger, UserConfigManager configurator, IServerConfiguration serverConfiguration, IServerController bedrockServer, ServiceConfigurator mineraftService) {
23 | _serverConfiguration = serverConfiguration;
24 | _logger = logger;
25 | _configurator = configurator;
26 | _bedrockServer = bedrockServer;
27 | _serviceConfiguration = mineraftService;
28 | }
29 |
30 | public void Filter(string input) {
31 | var playerInfo = ExtractPlayerInfoFromString(input);
32 | _logger.AppendLine($"Player {playerInfo.username} disconnected from server {_serverConfiguration.GetServerName()}.");
33 | _bedrockServer.GetActivePlayerList().Remove(_bedrockServer.GetActivePlayerList().Where(x => x.GetPlayerID() == _bedrockServer.GetPlayerManager().PlayerDisconnected(null, playerInfo.xuid).GetPlayerID()).FirstOrDefault());
34 | _configurator.SavePlayerDatabase(_serverConfiguration);
35 | }
36 |
37 |
38 | private (string username, string xuid) ExtractPlayerInfoFromString(string input) {
39 | string playerDisconnected = "Player disconnected: ";
40 | string xuid = "xuid: ";
41 | int usernameStart = input.IndexOf(playerDisconnected);
42 | int xuidStart = input.IndexOf(xuid);
43 | int usernameLength = (xuidStart - 1) - (usernameStart + playerDisconnected.Length);
44 | return (input.Substring(usernameStart + playerDisconnected.Length, usernameLength), input.Substring(xuidStart + xuid.Length, 16));
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/PlayersUpdate.cs:
--------------------------------------------------------------------------------
1 |
2 | using MinecraftService.Service.Core;
3 | using MinecraftService.Service.Networking.Interfaces;
4 | using MinecraftService.Shared.Classes.Networking;
5 | using MinecraftService.Shared.Classes.Server;
6 | using MinecraftService.Shared.Classes.Service;
7 | using MinecraftService.Shared.Classes.Service.Configuration;
8 | using MinecraftService.Shared.Classes.Service.Core;
9 | using Newtonsoft.Json;
10 | using System.Text;
11 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
12 |
13 | namespace MinecraftService.Service.Networking.NetworkStrategies
14 | {
15 | public class PlayersUpdate(UserConfigManager configurator, ServiceConfigurator serviceConfiguration, MmsService service) : IMessageParser {
16 |
17 | public Message ParseMessage(Message message) {
18 | string stringData = Encoding.UTF8.GetString(message.Data);
19 | List fetchedPlayers = JsonConvert.DeserializeObject>(stringData, GlobalJsonSerialierSettings);
20 | foreach (Player player in fetchedPlayers) {
21 | try {
22 | service.GetServerByIndex(message.ServerIndex).GetPlayerManager().AddUpdatePlayer(player);
23 | } catch (Exception) {
24 | }
25 | }
26 | if (serviceConfiguration.GetProp(ServicePropertyKeys.GlobalizedPlayerDatabase).GetBoolValue()) {
27 | foreach (IServerConfiguration server in serviceConfiguration.GetServerList()) {
28 | configurator.SavePlayerDatabase(server);
29 | configurator.WriteJSONFiles(server);
30 | Task.Delay(500).Wait();
31 | service.GetServerByIndex(serviceConfiguration.GetServerIndex(server)).WriteToStandardIn("ops reload");
32 | service.GetServerByIndex(serviceConfiguration.GetServerIndex(server)).WriteToStandardIn("whitelist reload");
33 | }
34 | } else {
35 | configurator.SavePlayerDatabase(serviceConfiguration.GetServerInfoByIndex(message.ServerIndex));
36 | configurator.WriteJSONFiles(serviceConfiguration.GetServerInfoByIndex(message.ServerIndex));
37 | Task.Delay(500).Wait();
38 | service.GetServerByIndex(message.ServerIndex).WriteToStandardIn("ops reload");
39 | service.GetServerByIndex(message.ServerIndex).WriteToStandardIn("whitelist reload");
40 | }
41 | return Message.EmptyUICallback;
42 | }
43 | }
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Server/ConsoleFilters/BedrockPlayerConnectedFilter.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Server.Interfaces;
2 | using MinecraftService.Shared.Classes.Service;
3 | using MinecraftService.Shared.Classes.Service.Configuration;
4 | using MinecraftService.Shared.Classes.Service.Core;
5 | using MinecraftService.Shared.Interfaces;
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
12 |
13 | namespace MinecraftService.Service.Server.ConsoleFilters
14 | {
15 | public class BedrockPlayerConnectedFilter : IConsoleFilter {
16 | IServerConfiguration _serverConfiguration;
17 | MmsLogger _logger;
18 | UserConfigManager _configurator;
19 | IServerController _bedrockServer;
20 | ServiceConfigurator _serviceConfiguration;
21 |
22 | public BedrockPlayerConnectedFilter(MmsLogger logger, UserConfigManager configurator, IServerConfiguration serverConfiguration, IServerController bedrockServer, ServiceConfigurator mineraftService) {
23 | _serverConfiguration = serverConfiguration;
24 | _logger = logger;
25 | _configurator = configurator;
26 | _bedrockServer = bedrockServer;
27 | _serviceConfiguration = mineraftService;
28 | }
29 |
30 | public void Filter(string input) {
31 | var playerInfo = ExtractPlayerInfoFromString(input);
32 | _logger.AppendLine($"Player {playerInfo.username} connected with XUID: {playerInfo.xuid} to server {_serverConfiguration.GetServerName()}.");
33 | _bedrockServer.SetServerModified(true);
34 | _bedrockServer.GetActivePlayerList().Add(_bedrockServer.GetPlayerManager().PlayerConnected(playerInfo.username, playerInfo.xuid));
35 | _configurator.SavePlayerDatabase(_serverConfiguration);
36 | }
37 |
38 | // Player Spawned: Crowbarmast3r xuid: 0123456789012345, pfid: 0a1b2c3d4e5f6g7h
39 | private (string username, string xuid) ExtractPlayerInfoFromString(string input) {
40 | string playerConnected = "Player Spawned: ";
41 | string xuid = "xuid: ";
42 | int usernameStart = input.IndexOf(playerConnected);
43 | int xuidStart = input.IndexOf(xuid);
44 | int usernameLength = (xuidStart - 1) - (usernameStart + playerConnected.Length);
45 | return (input.Substring(usernameStart + playerConnected.Length, usernameLength), input.Substring(xuidStart + xuid.Length, 16));
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/ConsoleLogUpdate.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Core;
2 | using MinecraftService.Service.Networking.Interfaces;
3 | using MinecraftService.Shared.Classes.Networking;
4 | using MinecraftService.Shared.Classes.Service;
5 | using MinecraftService.Shared.Classes.Service.Configuration;
6 | using MinecraftService.Shared.Classes.Service.Core;
7 | using MinecraftService.Shared.SerializeModels;
8 | using Newtonsoft.Json;
9 | using System.Text;
10 |
11 | namespace MinecraftService.Service.Networking.NetworkStrategies
12 | {
13 | public class ConsoleLogUpdate(MmsLogger logger, ServiceConfigurator serviceConfiguration, MmsService service) : IMessageParser {
14 |
15 | public Message ParseMessage(Message message) {
16 | string stringData = Encoding.UTF8.GetString(message.Data);
17 | List requests = JsonConvert.DeserializeObject>(stringData);
18 | List callbackList = [];
19 | int localCount = 0;
20 | List log;
21 | foreach (ConsoleLogUpdateRequest request in requests) {
22 | ConsoleLogUpdateCallback callback = new ConsoleLogUpdateCallback();
23 | if (request.LogTarget == 0xFF) {
24 | callback.LogTarget = 0xFF;
25 | log = serviceConfiguration.GetLog();
26 | localCount = log.Count;
27 | while (request.CurrentCount < localCount) {
28 | callback.LogEntries.Add(log[request.CurrentCount++].Text);
29 | }
30 | callback.CurrentCount = log.Count;
31 | callbackList.Add(callback);
32 | continue;
33 | }
34 | IServerConfiguration server = serviceConfiguration.GetServerInfoByIndex(request.LogTarget);
35 | log = server.GetLog();
36 | localCount = log.Count;
37 | callback.LogTarget = serviceConfiguration.GetServerIndex(server);
38 | while (request.CurrentCount < localCount) {
39 | callback.LogEntries.Add(log[request.CurrentCount++].Text);
40 | }
41 | callback.CurrentCount = log.Count;
42 | callbackList.Add(callback);
43 | }
44 | string jsonData = JsonConvert.SerializeObject(callbackList);
45 | byte[] jsonBytes = Encoding.UTF8.GetBytes(jsonData);
46 | return new(jsonBytes, 0, MessageTypes.ConsoleLogUpdate);
47 | }
48 | }
49 | }
50 |
51 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Server/TimerService.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Server.Interfaces;
2 | using MinecraftService.Shared.Classes.Service;
3 | using MinecraftService.Shared.Classes.Service.Configuration;
4 | using MinecraftService.Shared.Classes.Service.Core;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
11 |
12 | namespace MinecraftService.Service.Server
13 | {
14 | public class TimerService {
15 | public List ActiveTimers { get; set; } = new();
16 | private IServerController _runningServer;
17 | private IServerConfiguration _parentServerConfig;
18 | private ServiceConfigurator _serviceConfiguration;
19 |
20 | public TimerService(IServerController runningServer, IServerConfiguration serverConfiguration, ServiceConfigurator service) {
21 | _runningServer = runningServer;
22 | _parentServerConfig = serverConfiguration;
23 | _serviceConfiguration = service;
24 | }
25 |
26 | public void StartTimerService() {
27 | for (int i = 0; i < Enum.GetNames(typeof(MmsTimerTypes)).Length; i++) {
28 | StartTimer((MmsTimerTypes)i);
29 | }
30 | }
31 |
32 | public void StopTimerService() {
33 | foreach (TimerWorker worker in ActiveTimers) {
34 | worker.Stop().Wait();
35 | }
36 | ActiveTimers.Clear();
37 | }
38 |
39 | public void StartTimer(MmsTimerTypes timerType) {
40 | foreach (TimerWorker entry in ActiveTimers) {
41 | if (entry.GetTimerType() == timerType) {
42 | return;
43 | }
44 | }
45 | TimerWorker worker;
46 | worker = CreateTimer(timerType);
47 |
48 | if (worker.Start().Result) {
49 | ActiveTimers.Add(worker);
50 | }
51 | }
52 |
53 | public void StopTimer(MmsTimerTypes timerType) {
54 | TimerWorker removeWorker = null;
55 | foreach (TimerWorker worker in ActiveTimers) {
56 | if (worker.GetTimerType() == timerType) {
57 | worker.Stop().Wait();
58 | removeWorker = worker;
59 | }
60 | }
61 | if (removeWorker != null) {
62 | ActiveTimers.Remove(removeWorker);
63 | }
64 | }
65 |
66 | private TimerWorker CreateTimer(MmsTimerTypes timerType) => new TimerWorker(_runningServer, _parentServerConfig, _serviceConfiguration, timerType);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Server/ConsoleFilters/JavaPlayerLostConnectionFilter.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Server.Interfaces;
2 | using MinecraftService.Shared.Classes.Service;
3 | using MinecraftService.Shared.Classes.Service.Configuration;
4 | using MinecraftService.Shared.Classes.Service.Core;
5 | using MinecraftService.Shared.Interfaces;
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
12 |
13 | namespace MinecraftService.Service.Server.ConsoleFilters
14 | {
15 | public class JavaPlayerLostConnectionFilter : IConsoleFilter {
16 | IServerConfiguration _serverConfiguration;
17 | MmsLogger _logger;
18 | UserConfigManager _configurator;
19 | IServerController _bedrockServer;
20 | ServiceConfigurator _serviceConfiguration;
21 |
22 | public JavaPlayerLostConnectionFilter(MmsLogger logger, UserConfigManager configurator, IServerConfiguration serverConfiguration, IServerController bedrockServer, ServiceConfigurator mineraftService) {
23 | _serverConfiguration = serverConfiguration;
24 | _logger = logger;
25 | _configurator = configurator;
26 | _bedrockServer = bedrockServer;
27 | _serviceConfiguration = mineraftService;
28 | }
29 |
30 | public void Filter(string input) {
31 | var playerInfo = ExtractPlayerInfoFromString(input);
32 | if (_bedrockServer.GetActivePlayerList().Any()) {
33 | if(_bedrockServer.GetActivePlayerList().Remove(_bedrockServer.GetActivePlayerList().Where(x => x.GetPlayerID() == _bedrockServer.GetPlayerManager().PlayerDisconnected(playerInfo.username, playerInfo.xuid).GetPlayerID()).FirstOrDefault())) {
34 | _logger.AppendLine($"Player {playerInfo.username} has lost connection from server {_serverConfiguration.GetServerName()}, and has been removed from active players.");
35 | }
36 | }
37 | _configurator.SavePlayerDatabase(_serverConfiguration);
38 | }
39 |
40 | private (string username, string xuid) ExtractPlayerInfoFromString(string input) {
41 | int msgStartIndex = input.IndexOf("]:") + 3;
42 | int usernameEnd = 0;
43 | if (input.Contains(" (/")) {
44 | usernameEnd = input.IndexOf(" (/", msgStartIndex);
45 | } else {
46 | usernameEnd = input.IndexOf(" lost connection", msgStartIndex);
47 | }
48 | int usernameLength = usernameEnd - msgStartIndex;
49 | return (input.Substring(msgStartIndex, usernameLength), "");
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/MinecraftService/ServiceTests/ServiceTests/ServiceTests.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using Microsoft.Extensions.Hosting;
3 | using MinecraftService.Service;
4 | using MinecraftService.Service.Core;
5 | using MinecraftService.Service.Core.Interfaces;
6 | using MinecraftService.Shared.SerializeModels;
7 | using Newtonsoft.Json;
8 | using System;
9 | using System.Threading.Tasks;
10 | using Xunit;
11 |
12 | namespace MMS_Tests.ServiceTests {
13 | public class ServiceTests {
14 | public class TestFixture : IDisposable {
15 |
16 | public IHost Host;
17 | public MmsService MinecraftService;
18 | public JsonSerializerSettings SerializerSettings = new() { TypeNameHandling = TypeNameHandling.All };
19 |
20 | public TestFixture() {
21 | Host = Program.CreateHostBuilder(new string[] { }).Build();
22 | MinecraftService = Host.Services.GetRequiredService();
23 | }
24 |
25 | public async Task StartFixture() {
26 | await Task.Run(() => {
27 | if (MinecraftService.Start(null)) {
28 | while (MinecraftService != null && MinecraftService.GetServiceStatus().ServiceStatus != ServiceStatus.Started) {
29 | Task.Delay(100).Wait();
30 | }
31 | }
32 | });
33 | }
34 |
35 | public void Dispose() {
36 | if (MinecraftService.Stop(null)) {
37 | while (MinecraftService != null && MinecraftService.GetServiceStatus().ServiceStatus != ServiceStatus.Stopped) {
38 | Task.Delay(100).Wait();
39 | }
40 | }
41 | }
42 | }
43 |
44 | public class RunningServiceTests : IClassFixture {
45 | readonly TestFixture _testFixture;
46 |
47 | public RunningServiceTests() {
48 | _testFixture = new();
49 | }
50 |
51 | [Fact]
52 | public async Task Verify_Service_Startup() {
53 | Assert.Equal(ServiceStatus.Stopped, _testFixture.MinecraftService.GetServiceStatus().ServiceStatus);
54 | await _testFixture.StartFixture();
55 | Assert.Equal(ServiceStatus.Started, _testFixture.MinecraftService.GetServiceStatus().ServiceStatus);
56 | }
57 |
58 | [Fact]
59 | public void Verify_Service_Stop() {
60 | Assert.Equal(ServiceStatus.Started, _testFixture.MinecraftService.GetServiceStatus().ServiceStatus);
61 | _testFixture.Dispose();
62 | Assert.Equal(ServiceStatus.Stopped, _testFixture.MinecraftService.GetServiceStatus().ServiceStatus);
63 | }
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/Classes/Service/Core/Property.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 |
4 | namespace MinecraftService.Shared.Classes.Service.Core
5 | {
6 | public class Property
7 | {
8 | public string KeyName { get; set; } = string.Empty;
9 | public string StringValue { get; set; } = string.Empty;
10 | public string DefaultValue { get; set; } = string.Empty;
11 |
12 | [JsonConstructor]
13 | public Property(string key, string defaultValue)
14 | {
15 | KeyName = key;
16 | StringValue = defaultValue;
17 | DefaultValue = defaultValue;
18 | }
19 |
20 | public Property(Property newProp)
21 | {
22 | KeyName = newProp.KeyName;
23 | StringValue = newProp.StringValue;
24 | DefaultValue = newProp.DefaultValue;
25 | }
26 |
27 | public override string ToString() => StringValue;
28 |
29 |
30 | public string PropFileFormatString() => $"{KeyName}={StringValue}";
31 |
32 |
33 | public void SetValue(string newValue)
34 | {
35 | StringValue = newValue;
36 | }
37 |
38 | public void SetValue(int newValue)
39 | {
40 | StringValue = newValue.ToString();
41 | }
42 |
43 | public void SetValue(bool newValue)
44 | {
45 | StringValue = newValue.ToString();
46 | }
47 |
48 | public bool GetBoolValue()
49 | {
50 | try
51 | {
52 | if (bool.TryParse(StringValue, out bool result))
53 | {
54 | return result;
55 | }
56 | }
57 | catch (Exception e)
58 | {
59 | throw new FormatException($"Value for property {KeyName} tried to parse as a bool and failed! Check configs!", e);
60 | }
61 | return false;
62 | }
63 |
64 | public int GetIntValue()
65 | {
66 | try
67 | {
68 | if (int.TryParse(StringValue, out int result))
69 | {
70 | return result;
71 | }
72 | }
73 | catch (Exception e)
74 | {
75 | throw new FormatException($"Value for property {KeyName} tried to parse as a bool and failed! Check configs!", e);
76 | }
77 | return 0;
78 | }
79 |
80 | public override bool Equals(object obj)
81 | {
82 | return obj is Property property &&
83 | KeyName == property.KeyName &&
84 | StringValue == property.StringValue &&
85 | DefaultValue == property.DefaultValue;
86 | }
87 |
88 | public override int GetHashCode()
89 | {
90 | return HashCode.Combine(KeyName, StringValue, DefaultValue);
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Forms/ManagePacksForms.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | text/microsoft-resx
50 |
51 |
52 | 2.0
53 |
54 |
55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
56 |
57 |
58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
59 |
60 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Forms/ProgressDialog.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | text/microsoft-resx
50 |
51 |
52 | 2.0
53 |
54 |
55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
56 |
57 |
58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
59 |
60 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Forms/RemoveServerControl.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | text/microsoft-resx
50 |
51 |
52 | 2.0
53 |
54 |
55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
56 |
57 |
58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
59 |
60 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Forms/NewPlayerRegistrationForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | text/microsoft-resx
50 |
51 |
52 | 2.0
53 |
54 |
55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
56 |
57 |
58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
59 |
60 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Server/ConsoleFilters/JavaVersionFilter.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Server.Interfaces;
2 | using MinecraftService.Shared.Classes.Service;
3 | using MinecraftService.Shared.Classes.Service.Configuration;
4 | using MinecraftService.Shared.Classes.Service.Core;
5 | using MinecraftService.Shared.Interfaces;
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
12 |
13 | namespace MinecraftService.Service.Server.ConsoleFilters
14 | {
15 | public class JavaVersionFilter : IConsoleFilter {
16 | IServerConfiguration _serverConfiguration;
17 | MmsLogger _logger;
18 | UserConfigManager _configurator;
19 | IServerController _javaServer;
20 | ServiceConfigurator _serviceConfiguration;
21 |
22 | public JavaVersionFilter(MmsLogger logger, UserConfigManager configurator, IServerConfiguration serverConfiguration, IServerController javaServer, ServiceConfigurator mineraftService) {
23 | _serverConfiguration = serverConfiguration;
24 | _logger = logger;
25 | _configurator = configurator;
26 | _javaServer = javaServer;
27 | _serviceConfiguration = mineraftService;
28 | }
29 |
30 | public void Filter(string input) {
31 | int msgStartIndex = input.IndexOf("version ") + 8;
32 | string versionString = input.Substring(msgStartIndex, input.Length - msgStartIndex);
33 | if (_serverConfiguration.GetSettingsProp(ServerPropertyKeys.ServerVersion).StringValue == "None") {
34 | _logger.AppendLine("Service detected version, restarting server to apply correct configuration.");
35 |
36 | _javaServer.ForceKillServer();
37 | _serverConfiguration.GetSettingsProp(ServerPropertyKeys.ServerVersion).SetValue(versionString);
38 | _configurator.LoadServerConfigurations().Wait();
39 | _configurator.SaveServerConfiguration(_serverConfiguration);
40 | _javaServer.ServerStart().Wait();
41 | }
42 | if (_serverConfiguration.GetServerVersion() != versionString) {
43 | if (_serverConfiguration.GetSettingsProp(ServerPropertyKeys.AutoDeployUpdates).GetBoolValue()) {
44 | _logger.AppendLine($"Server {_serverConfiguration.GetServerName()} decected incorrect or out of date version! Replacing build...");
45 | _javaServer.PerformOfflineServerTask(() => {
46 | _javaServer.ForceKillServer();
47 | _serverConfiguration.GetUpdater().ReplaceBuild(_serverConfiguration).Wait();
48 | });
49 | } else {
50 | _logger.AppendLine($"Server {_serverConfiguration.GetServerName()} is out of date, Enable AutoDeployUpdates option to update to latest!");
51 | }
52 | }
53 |
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace MinecraftService.Client.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MinecraftService.Client.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/BdsVersionCheckTest.ps1:
--------------------------------------------------------------------------------
1 | class BedrockInfo {
2 | [string]$version;
3 | [string]$winurl;
4 | [string]$linurl;
5 | [PropInfoEntry[]]$proplist;
6 | }
7 |
8 | class PropInfoEntry {
9 | [string]$Key;
10 | [string]$Value;
11 | }
12 |
13 | $ConnectionHeaders = @{
14 | "Accept"="text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7";
15 | "Accept-Encoding"="gzip, deflate, br, zstd";
16 | "Accept-Language"="en-US,en;q=0.9";
17 | "User-Agent"="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36"
18 | };
19 | [Net.ServicePointManager]::SecurityProtocol = "tls12", "tls11";
20 | $reply = Invoke-WebRequest -UseBasicParsing -Headers $ConnectionHeaders -Uri "https://net-secondary.web.minecraft-services.net/api/v1.0/download/links";
21 | $versionJson = $reply.Content | ConvertFrom-Json;
22 | $bedrockWinUrl = "";
23 | $bedrockLinuxUrl = "";
24 | foreach ($entry in $versionJson.result.links) {
25 | if($entry.downloadType -eq "serverBedrockWindows") {
26 | $bedrockWinUrl = $entry.downloadUrl;
27 | }
28 | if($entry.downloadType -eq "serverBedrockLinux") {
29 | $bedrockLinuxUrl = $entry.downloadUrl;
30 | }
31 | }
32 | $propMftFile = get-content 'MMS_Files\\bedrock_version_prop_manifest.json';
33 | if ($bedrockWinUrl -match 'bedrock-server-(?.+)\.zip') {
34 | $version = $Matches.version;
35 | if ($propMftFile) {
36 | $propMftJson = $propMftFile | ConvertFrom-Json;
37 | $latestVer = $propMftJson | Select-Object -Last 1;
38 | $entryVer = $latestVer.version;
39 | if($entryVer -ne $version) {
40 | mkdir 'BedrockTemp';
41 | $curDir = Get-Location;
42 | $zipPath = $curDir.Path + '\\BedrockTemp\\Server.zip'
43 | Invoke-WebRequest -UseBasicParsing -Headers $ConnectionHeaders -Uri $latestVer.winurl -OutFile $zipPath;
44 | $zipStream = New-Object IO.FileStream $zipPath, 'Open', 'Read', 'Read';
45 | $zipArchive = New-Object IO.Compression.ZipArchive $zipStream, "Read";
46 | $propList = @();
47 | foreach ($file in $zipArchive.Entries) {
48 | if ($file.Name -eq 'server.properties') {
49 | $fileStream = $file.Open();
50 | $reader = New-Object IO.StreamReader $fileStream;
51 | while (($line = $reader.ReadLine()) -ne $null) {
52 | if ($line -ne "" -And !$line.StartsWith('#')) {
53 | $kvp = $line.Split('=');
54 | if ($kvp.Length -lt 2) {
55 | $temp = [string[]];
56 | $temp[0] = $kvp[0];
57 | $temp[1] = "";
58 | $kvp = $temp;
59 | }
60 | $newProp = [PropInfoEntry]@{
61 | Key = $kvp[0];
62 | Value = $kvp[1];
63 | }
64 | $propList += $newProp;
65 | }
66 | }
67 | }
68 | }
69 | $zipArchive.Dispose();
70 | $zipStream.Close();
71 | $newListEntry = [BedrockInfo]@{
72 | version=$version;
73 | winurl=$bedrockWinUrl;
74 | linurl=$bedrockLinuxUrl;
75 | proplist= $propList;
76 | }
77 | $propMftJson += $newListEntry;
78 | $propMftJson | ConvertTo-Json -depth 100 | Out-File "MMS_Files\\bedrock_version_prop_manifest.json";
79 | }
80 | }
81 | }
--------------------------------------------------------------------------------
/MinecraftService/Service/Program.cs:
--------------------------------------------------------------------------------
1 | // This application entry point is based on ASP.NET Core new project templates and is included
2 | // as a starting point for app host configuration.
3 | // This file may need updated according to the specific scenario of the application being upgraded.
4 | // For more information on ASP.NET Core hosting, see https://docs.microsoft.com/aspnet/core/fundamentals/host/web-host
5 |
6 | global using Microsoft.Extensions.DependencyInjection;
7 | global using Microsoft.Extensions.Hosting;
8 | global using MinecraftService.Service.Core.Interfaces;
9 | global using MinecraftService.Service.Management;
10 | global using MinecraftService.Service.Networking;
11 | global using MinecraftService.Shared.Classes;
12 | global using MinecraftService.Shared.Interfaces;
13 | global using MinecraftService.Shared.Utilities;
14 | global using System;
15 | global using System.Collections.Generic;
16 | global using System.Diagnostics;
17 | global using System.IO;
18 | global using System.Linq;
19 | global using System.Reflection;
20 | global using System.Threading;
21 | global using System.Threading.Tasks;
22 | global using Topshelf;
23 | using MinecraftService.Service.Core;
24 | using MinecraftService.Service.Networking.Interfaces;
25 | using MinecraftService.Shared.Classes.Server;
26 | using MinecraftService.Shared.Classes.Server.Updaters;
27 | using MinecraftService.Shared.Classes.Service;
28 | using MinecraftService.Shared.Classes.Service.Configuration;
29 | using MinecraftService.Shared.Classes.Service.Core;
30 |
31 | namespace MinecraftService.Service
32 | {
33 | public class Program {
34 | public static bool IsExiting = false;
35 | private static readonly string _declaredType = "Service";
36 | private static bool _isDebugEnabled = false;
37 | private static bool _shouldStartService = true;
38 | public static void Main(string[] args) {
39 | if (args.Length > 0) {
40 | _isDebugEnabled = args[0].ToLower() == "--debug";
41 | }
42 | CreateHostBuilder(args).Build().Run();
43 | }
44 |
45 | public static IHostBuilder CreateHostBuilder(string[] args) =>
46 | Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args)
47 | .ConfigureServices((hostContext, services) => {
48 | ProcessInfo processInfo = new ProcessInfo(_declaredType, Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName), Process.GetCurrentProcess().Id, _isDebugEnabled, _shouldStartService);
49 | SharedStringBase.SetWorkingDirectory(processInfo);
50 | services.AddHostedService()
51 | .AddSingleton(processInfo)
52 | .AddTransient()
53 | .AddTransient()
54 | .AddSingleton()
55 | .AddSingleton()
56 | .AddSingleton()
57 | .AddSingleton()
58 | .AddSingleton()
59 | .AddSingleton();
60 | });
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Forms/ClientConfigForm.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Windows.Forms;
8 | using MinecraftService.Client.Management;
9 | using MinecraftService.Shared.Classes.Service.Configuration;
10 | using MinecraftService.Shared.Interfaces;
11 |
12 | namespace MinecraftService.Client.Forms {
13 | public partial class ClientConfigForm : Form {
14 | private readonly List _clientConfigs;
15 | private readonly ConfigManager _configManager;
16 | public ClientConfigForm(ConfigManager configManager) {
17 | InitializeComponent();
18 | _configManager = configManager;
19 | _clientConfigs = _configManager.HostConnectList;
20 | scrollLockCheckbox.Checked = _configManager.DefaultScrollLock;
21 | displayTimestampCheckbox.Checked = _configManager.DisplayTimestamps;
22 | debugNetworkCheckbox.Checked = _configManager.DebugNetworkOutput;
23 | if (!string.IsNullOrEmpty(_configManager.NBTStudioPath)) {
24 | nbtPathLabel.Text = $"NBT Studio path: {_configManager.NBTStudioPath}";
25 | }
26 | foreach (ClientSideServiceConfiguration config in _clientConfigs) {
27 | serverGridView.Rows.Add(new string[3] { config.GetHostName(), config.GetAddress(), config.GetPort() });
28 | }
29 | }
30 |
31 | public void SimulateTests() {
32 | nbtButton.PerformClick();
33 | }
34 |
35 | private void nbtButton_Click(object sender, EventArgs e) {
36 | using (OpenFileDialog fileDialog = new()) {
37 | fileDialog.Filter = "EXE Files|*.exe";
38 | fileDialog.FileName = "NbtStudio.exe";
39 | fileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
40 | if (fileDialog.ShowDialog() == DialogResult.OK) {
41 | _configManager.NBTStudioPath = fileDialog.FileName;
42 | nbtPathLabel.Text = $"NBT Studio path: {_configManager.NBTStudioPath}";
43 | }
44 | }
45 | }
46 |
47 | private void saveBtn_Click(object sender, EventArgs e) {
48 | List newConfigs = new();
49 | foreach (DataGridViewRow row in serverGridView.Rows) {
50 | if (!string.IsNullOrEmpty((string)row.Cells[0].Value)) {
51 | newConfigs.Add(new ClientSideServiceConfiguration((string)row.Cells[0].Value, (string)row.Cells[1].Value, (string)row.Cells[2].Value));
52 | }
53 | }
54 | _configManager.HostConnectList = newConfigs;
55 | _configManager.DefaultScrollLock = scrollLockCheckbox.Checked;
56 | _configManager.DisplayTimestamps = displayTimestampCheckbox.Checked;
57 | _configManager.DebugNetworkOutput = debugNetworkCheckbox.Checked;
58 | _configManager.SaveConfigFile();
59 | DialogResult = DialogResult.OK;
60 | Close();
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Forms/PropEditorForm.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Windows.Forms;
8 | using MinecraftService.Shared.Classes.Service.Core;
9 |
10 | namespace MinecraftService.Client.Forms {
11 | public partial class PropEditorForm : Form {
12 | readonly DataGridView dataGrid;
13 | public List workingProps;
14 | public List startCmds;
15 | public string RollbackFolderName = "";
16 |
17 | public PropEditorForm() {
18 | InitializeComponent();
19 | dataGrid = gridView;
20 | }
21 |
22 | public void PopulateBoxes(List propList) {
23 | int index = 0;
24 | workingProps = propList;
25 | this.Text = "Properties Editor";
26 | foreach (Property prop in workingProps) {
27 | dataGrid.Rows.Add(new string[2] { prop.KeyName, prop.StringValue });
28 | if (prop.KeyName == "server-name" || prop.KeyName == "server-port" || prop.KeyName == "server-portv6") {
29 | dataGrid.Rows[index].ReadOnly = true;
30 | dataGrid.Rows[index].DefaultCellStyle.BackColor = System.Drawing.Color.FromArgb(225, 225, 225);
31 | }
32 | index++;
33 | }
34 | gridView.AllowUserToAddRows = false;
35 | }
36 |
37 | public void PopulateStartCmds(List list) {
38 | this.Text = "Start Command Editor";
39 | startCmds = list;
40 | gridView.Columns.RemoveAt(0);
41 | gridView.AllowUserToDeleteRows = true;
42 | foreach (StartCmdEntry entry in startCmds) {
43 | dataGrid.Rows.Add(new string[1] { entry.Command });
44 | }
45 | }
46 |
47 | private void CancelBtn_Click(object sender, EventArgs e) {
48 | Close();
49 | Dispose();
50 | }
51 |
52 | private void SaveBtn_Click(object sender, EventArgs e) {
53 | startCmds = new List();
54 | foreach (DataGridViewRow row in dataGrid.Rows) {
55 | if (workingProps != null) {
56 | foreach (Property prop in workingProps) {
57 | if ((string)row.Cells[0].Value == prop.KeyName) {
58 | prop.StringValue = (string)row.Cells[1].Value;
59 | }
60 | }
61 | } else {
62 | if ((string)row.Cells[0].Value != null)
63 | startCmds.Add(new StartCmdEntry((string)row.Cells[0].Value));
64 | }
65 |
66 | }
67 | DialogResult = DialogResult.OK;
68 | Close();
69 | }
70 |
71 | private void gridView_NewRowNeeded(object sender, DataGridViewRowEventArgs e) {
72 | DataGridViewRow focusedRow = gridView.CurrentRow;
73 | focusedRow.Cells[0].Value = "Cmd:";
74 | gridView.Refresh();
75 | }
76 |
77 | internal void PopulateBoxes(object p) {
78 | throw new NotImplementedException();
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/MinecraftService/MinecraftService.Shared/Classes/Networking/Message.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Security.Cryptography.X509Certificates;
6 | using System.Text;
7 | using System.Text.Json;
8 | using System.Threading.Tasks;
9 |
10 | namespace MinecraftService.Shared.Classes.Networking {
11 | public struct Message : IEquatable {
12 | public byte[] Data { get; set; }
13 | public byte ServerIndex { get; set; }
14 | public MessageTypes Type { get; set; }
15 | public MessageFlags Flag { get; set; }
16 |
17 | public Message() {
18 | Data = [];
19 | ServerIndex = 0;
20 | }
21 |
22 | public Message(byte[] data) {
23 | string dataString = "";
24 | try {
25 | dataString = Encoding.UTF8.GetString(data);
26 | this = JsonConvert.DeserializeObject(dataString);
27 | } catch (JsonReaderException jre) {
28 | throw new Exception($"Json failure: line {jre.LineNumber}, pos {jre.LinePosition}. Message: {jre.Message}\r\nData: {dataString}");
29 | } catch (Exception ex) {
30 | throw new Exception($"Error creating message from byte array: {ex.Message}");
31 | }
32 | }
33 |
34 | public Message(byte[] data, byte serverIndex, MessageTypes messageType) {
35 | Data = data;
36 | ServerIndex = serverIndex;
37 | Type = messageType;
38 | }
39 |
40 | public byte[] GetMessageBytes() {
41 | byte[] jsonData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(this));
42 | byte[] packetData = new byte[jsonData.Length + sizeof(int)];
43 | Buffer.BlockCopy(BitConverter.GetBytes(jsonData.Length), 0, packetData, 0, sizeof(int));
44 | Buffer.BlockCopy(jsonData, 0, packetData, sizeof(int), jsonData.Length);
45 | return packetData;
46 | }
47 |
48 | public readonly string GetDataString() => Encoding.UTF8.GetString(Data);
49 |
50 | public static Message Empty(MessageTypes type) => new() { Type = type };
51 | public static Message Empty() => new();
52 |
53 | public static readonly Message EmptyUICallback = new() { Type = MessageTypes.UICallback };
54 | public static readonly Message Heartbeat = new() { Type = MessageTypes.Heartbeat };
55 | public static readonly Message Connect = new() { Type = MessageTypes.Connect };
56 |
57 | public override bool Equals(object obj) {
58 | return obj is Message message && Equals(message);
59 | }
60 |
61 | public bool Equals(Message other) {
62 | return EqualityComparer.Default.Equals(Data, other.Data) &&
63 | ServerIndex == other.ServerIndex &&
64 | Type == other.Type &&
65 | Flag == other.Flag;
66 | }
67 |
68 | public override int GetHashCode() {
69 | return HashCode.Combine(Data, ServerIndex, Type, Flag);
70 | }
71 |
72 | public static bool operator ==(Message left, Message right) {
73 | return left.Equals(right);
74 | }
75 |
76 | public static bool operator !=(Message left, Message right) {
77 | return !(left == right);
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategies/PackFile.cs:
--------------------------------------------------------------------------------
1 | using MinecraftService.Service.Networking.Interfaces;
2 | using MinecraftService.Shared.Classes.Networking;
3 | using MinecraftService.Shared.Classes.Service;
4 | using MinecraftService.Shared.Classes.Service.Configuration;
5 | using MinecraftService.Shared.Classes.Service.Core;
6 | using MinecraftService.Shared.PackParser;
7 | using static MinecraftService.Shared.Classes.Service.Core.SharedStringBase;
8 |
9 | namespace MinecraftService.Service.Networking.NetworkStrategies
10 | {
11 | public class PackFile(ServiceConfigurator serviceConfiguration, MmsLogger logger) : IMessageParser {
12 |
13 | public Message ParseMessage(Message message) {
14 | Progress progress = new Progress((progress) => {
15 | string prog = string.Format("{0:N2}", progress.Progress);
16 | logger.AppendLine($"Extracting pack contents... {prog}% completed.");
17 | });
18 | MinecraftPackParser archiveParser = new(logger, progress);
19 | archiveParser.ProcessServerData(message.Data, () => {
20 | foreach (MinecraftPackContainer container in archiveParser.FoundPacks) {
21 | IServerConfiguration server = serviceConfiguration.GetServerInfoByIndex(message.ServerIndex);
22 | string serverPath = server.GetSettingsProp(ServerPropertyKeys.ServerPath).ToString();
23 | string levelName = server.GetProp(MmsDependServerPropKeys.LevelName).ToString();
24 | string filePath;
25 |
26 | if (container.ManifestType == MinecraftPackTypeStrings[MinecraftPackTypes.WorldPack]) {
27 | FileUtilities.CopyFolderTree(new DirectoryInfo(container.PackContentLocation), new DirectoryInfo(GetServerDirectory(ServerDirectoryKeys.ServerWorldDir_LevelName, serverPath, container.FolderName)));
28 | }
29 | if (container.ManifestType == MinecraftPackTypeStrings[MinecraftPackTypes.Behavior]) {
30 | filePath = GetServerFilePath(ServerFileNameKeys.WorldBehaviorPacks, server, levelName);
31 | if (MinecraftFileUtilities.UpdateWorldPackFile(filePath, container.JsonManifest)) {
32 | FileUtilities.CopyFolderTree(new DirectoryInfo(container.PackContentLocation), new DirectoryInfo($"{GetServerDirectory(ServerDirectoryKeys.BehaviorPacksDir_LevelName, serverPath, levelName)}\\{container.FolderName}"));
33 | }
34 | }
35 | if (container.ManifestType == MinecraftPackTypeStrings[MinecraftPackTypes.Resource]) {
36 | filePath = GetServerFilePath(ServerFileNameKeys.WorldResourcePacks, server, levelName);
37 | if (MinecraftFileUtilities.UpdateWorldPackFile(filePath, container.JsonManifest)) {
38 | FileUtilities.CopyFolderTree(new DirectoryInfo(container.PackContentLocation), new DirectoryInfo($"{GetServerDirectory(ServerDirectoryKeys.ResourcePacksDir_LevelName, serverPath, levelName)}\\{container.FolderName}"));
39 | }
40 | }
41 | logger.AppendLine($@"{container.GetFixedManifestType()} pack installed to server: {container.JsonManifest.header.name}.");
42 | }
43 | });
44 | return Message.EmptyUICallback;
45 | }
46 | }
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/MinecraftService/Client/Forms/ClientConfigForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | text/microsoft-resx
50 |
51 |
52 | 2.0
53 |
54 |
55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
56 |
57 |
58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
59 |
60 |
61 | True
62 |
63 |
64 | True
65 |
66 |
67 | True
68 |
69 |
--------------------------------------------------------------------------------
/MinecraftService/Service/Networking/NetworkStrategyLookup.cs:
--------------------------------------------------------------------------------
1 |
2 | using MinecraftService.Service.Core;
3 | using MinecraftService.Service.Networking.Interfaces;
4 | using MinecraftService.Service.Networking.NetworkStrategies;
5 | using MinecraftService.Shared.Classes.Networking;
6 | using MinecraftService.Shared.Classes.Server;
7 | using MinecraftService.Shared.Classes.Service;
8 | using MinecraftService.Shared.Classes.Service.Configuration;
9 | using MinecraftService.Shared.Classes.Service.Core;
10 |
11 | namespace MinecraftService.Service.Networking
12 | {
13 | public class NetworkStrategyLookup {
14 | private readonly Dictionary _standardMessageLookup;
15 | private readonly Dictionary _flaggedMessageLookup;
16 |
17 | public NetworkStrategyLookup(ITCPObject listener, MmsService service, MmsLogger logger, UserConfigManager configurator, ServiceConfigurator serviceConfiguration, ProcessInfo processInfo, FileUtilities fileUtils) {
18 | _standardMessageLookup = new Dictionary()
19 | {
20 | {MessageTypes.Connect, new Connect(serviceConfiguration) },
21 | {MessageTypes.AddNewServer, new AddNewServer(logger, processInfo, configurator, serviceConfiguration, service) },
22 | {MessageTypes.RemoveServer, new RemoveServer(configurator, serviceConfiguration, service) },
23 | {MessageTypes.Command, new ServerCommand(service, logger) },
24 | {MessageTypes.Restart, new ServerRestart(service) },
25 | {MessageTypes.StartStop, new StartStopServer(service) },
26 | {MessageTypes.ServerStatusRequest, new ServerStatusRequest(service) },
27 | {MessageTypes.Backup, new ServerBackup(service) },
28 | {MessageTypes.BackupAll, new ServerBackupAll(service) },
29 | {MessageTypes.EnumBackups, new EnumBackups(configurator) },
30 | {MessageTypes.BackupRollback, new BackupRollback(service) },
31 | {MessageTypes.DelBackups, new DeleteBackups(logger, serviceConfiguration) },
32 | {MessageTypes.PropUpdate, new ServerPropUpdate(logger, configurator, serviceConfiguration, service) },
33 | {MessageTypes.StartCmdUpdate, new StartCmdUpdate(configurator, serviceConfiguration) },
34 | {MessageTypes.ConsoleLogUpdate, new ConsoleLogUpdate(logger, serviceConfiguration, service) },
35 | {MessageTypes.VersionListRequest, new VersionListRequest(logger, serviceConfiguration) },
36 | {MessageTypes.PackList, new PackList(processInfo, serviceConfiguration, logger) },
37 | {MessageTypes.PackFile, new PackFile(serviceConfiguration, logger) },
38 | {MessageTypes.RemovePack, new RemovePack(serviceConfiguration, logger) },
39 | {MessageTypes.CheckUpdates, new CheckUpdates(service) },
40 | {MessageTypes.PlayersRequest, new PlayerRequest(service) },
41 | {MessageTypes.PlayersUpdate, new PlayersUpdate(configurator, serviceConfiguration, service) },
42 | {MessageTypes.LevelEditRequest, new LevelEditRequest(serviceConfiguration) },
43 | {MessageTypes.LevelEditFile, new LevelEditFile(serviceConfiguration, service, logger) },
44 | {MessageTypes.ExportFile, new ExportFileRequest(configurator, service, serviceConfiguration, logger) },
45 | };
46 | listener.SetStrategies(_standardMessageLookup);
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------