diff --git a/BedrockService.backup/BedrockService.Shared/BedrockService.Shared.csproj b/BedrockService.backup/BedrockService.Shared/BedrockService.Shared.csproj new file mode 100644 index 00000000..470a5013 --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/BedrockService.Shared.csproj @@ -0,0 +1,80 @@ + + + + + Debug + AnyCPU + {F146D5E8-EF1F-4785-9150-182631F059B7} + Library + Properties + BedrockService.Shared + BedrockService.Shared + v4.7.2 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 2 + + + + ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll + + + + + + + ..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll + True + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BedrockService.backup/BedrockService.Shared/Classes/ClientSideServiceConfiguration.cs b/BedrockService.backup/BedrockService.Shared/Classes/ClientSideServiceConfiguration.cs new file mode 100644 index 00000000..f1936fa2 --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/Classes/ClientSideServiceConfiguration.cs @@ -0,0 +1,28 @@ +using BedrockService.Shared.Interfaces; + +namespace BedrockService.Shared.Classes +{ + public class ClientSideServiceConfiguration : IClientSideServiceConfiguration + { + private readonly string _hostName; + private readonly string _address; + private readonly string _port; + private readonly string _displayName; + + public ClientSideServiceConfiguration(string hostName, string address, string port) + { + this._hostName = hostName; + this._address = address; + this._port = port; + _displayName = $@"{hostName}@{address}:{port}"; + } + + public string GetHostName() => _hostName; + + public string GetAddress() => _address; + + public string GetPort() => _port; + + public string GetDisplayName() => _displayName; + } +} diff --git a/BedrockService.backup/BedrockService.Shared/Classes/CommsKeyContainer.cs b/BedrockService.backup/BedrockService.Shared/Classes/CommsKeyContainer.cs new file mode 100644 index 00000000..2df98f77 --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/Classes/CommsKeyContainer.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Security.Cryptography; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BedrockService.Shared.Classes +{ + [Serializable] + public class RSAContainer + { + public byte[] D; + public byte[] DP; + public byte[] DQ; + public byte[] Exponent; + public byte[] InverseQ; + public byte[] Modulus; + public byte[] P; + public byte[] Q; + + public RSAContainer(RSAParameters input) + { + D = input.D; + P = input.DP; + DP = input.DP; + Q = input.DQ; + DQ = input.DQ; + InverseQ = input.InverseQ; + Modulus = input.Modulus; + Exponent = input.Exponent; + } + + public RSAParameters GetPrivateKey() + { + return new RSAParameters() + { + D = this.D, + P = this.P, + DP = this.DP, + Q = this.Q, + DQ = this.DQ, + InverseQ = this.InverseQ, + Exponent = this.Exponent, + Modulus = this.Modulus + }; + } + + public RSAParameters GetPublicKey() + { + return new RSAParameters() + { + Modulus = this.Modulus, + Exponent = this.Exponent + }; + } + + public void SetPrivateKey(RSAParameters privateKey) + { + this.D = privateKey.D; + this.DP = privateKey.DP; + this.P = privateKey.P; + this.DQ = privateKey.DQ; + this.Q = privateKey.Q; + this.InverseQ = privateKey.InverseQ; + this.Modulus = privateKey.Modulus; + this.Exponent = privateKey.Exponent; + } + + public void SetPublicKey(RSAParameters publicKey) + { + this.Exponent = publicKey.Exponent; + this.Modulus = publicKey.Modulus; + } + } + + [Serializable] + public class CommsKeyContainer + { + public RSAContainer LocalPrivateKey = new RSAContainer(new RSAParameters()); + public RSAContainer RemotePublicKey = new RSAContainer(new RSAParameters()); + public byte[] AesKey; + public byte[] AesIV; + + public CommsKeyContainer() { } + + public CommsKeyContainer (RSAParameters priv, RSAParameters pub, byte[] key, byte[] IV) + { + LocalPrivateKey = new RSAContainer(priv); + RemotePublicKey = new RSAContainer(pub); + AesKey = key; + AesIV = IV; + } + } +} diff --git a/BedrockService.backup/BedrockService.Shared/Classes/NetworkEnums.cs b/BedrockService.backup/BedrockService.Shared/Classes/NetworkEnums.cs new file mode 100644 index 00000000..3cc62590 --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/Classes/NetworkEnums.cs @@ -0,0 +1,59 @@ +namespace BedrockService.Shared.Classes +{ + public enum NetworkMessageSource + { + Client, + Server, + Service + } + + + public enum NetworkMessageDestination + { + Client, + Server, + Service + } + + public enum NetworkMessageTypes + { + Connect, + AddNewServer, + RemoveServer, + ConsoleLogUpdate, + PropUpdate, + PlayersRequest, + PlayersUpdate, + StartCmdUpdate, + CheckUpdates, + PackFile, + PackList, + LevelEditRequest, + LevelEditFile, + RemovePack, + Command, + Backup, + BackupRollback, + BackupAll, + DelBackups, + EnumBackups, + Restart, + Heartbeat, + Disconnect, + UICallback + } + + public enum NetworkMessageFlags + { + Failed, + Passed, + RemoveBackups, + RemoveSrv, + RemovePlayers, + RemoveBckSrv, + RemoveBckPly, + RemovePlySrv, + RemoveAll, + None + } +} diff --git a/BedrockService.backup/BedrockService.Shared/Classes/Player.cs b/BedrockService.backup/BedrockService.Shared/Classes/Player.cs new file mode 100644 index 00000000..93b318b3 --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/Classes/Player.cs @@ -0,0 +1,124 @@ +using BedrockService.Shared.Interfaces; +using Newtonsoft.Json; +using System; + +namespace BedrockService.Shared.Classes +{ + public class Player : IPlayer + { + [JsonProperty] + private string Username { get; set; } + [JsonProperty] + private string XUID { get; set; } + [JsonProperty] + private string PermissionLevel; + [JsonProperty] + private string FirstConnectedTime { get; set; } + [JsonProperty] + private string LastConnectedTime { get; set; } + [JsonProperty] + private string LastDisconnectTime { get; set; } + [JsonProperty] + private string ServerDefaultPerm { get; set; } + [JsonProperty] + private bool Whitelisted { get; set; } + [JsonProperty] + private bool IgnorePlayerLimits { get; set; } + [JsonProperty] + private bool FromConfig { get; set; } + + [JsonConstructor] + public Player(string xuid, string username, string firstConn, string lastConn, string lastDiscon, bool whtlist, string perm, bool ignoreLimit) + { + Username = username; + XUID = xuid; + FirstConnectedTime = firstConn; + LastConnectedTime = lastConn; + LastDisconnectTime = lastDiscon; + Whitelisted = whtlist; + PermissionLevel = perm; + IgnorePlayerLimits = ignoreLimit; + } + + public Player(string serverDefaultPermission) + { + ServerDefaultPerm = serverDefaultPermission; + PermissionLevel = serverDefaultPermission; + } + + public void Initialize(string xuid, string username) + { + XUID = xuid; + Username = username; + } + + public string GetUsername() => Username; + + public string SearchForProperty(string input) + { + if (input == "name" || input == "username" || input == "un") + return Username; + if (input == "xuid" || input == "id") + return XUID; + if (input == "perm" || input == "permission" || input == "pl") + return PermissionLevel; + if (input == "whitelist" || input == "white" || input == "wl") + return Whitelisted.ToString(); + if (input == "ignoreslimit" || input == "il") + return IgnorePlayerLimits.ToString(); + return null; + } + + public string GetXUID() => XUID; + + public void UpdateTimes(string lastConn, string lastDiscon) + { + if (FirstConnectedTime == "") + FirstConnectedTime = DateTime.Now.Ticks.ToString(); + LastConnectedTime = lastConn; + LastDisconnectTime = lastDiscon; + } + + public void UpdateRegistration(string whtlist, string perm, string ignoreLimit) + { + Whitelisted = bool.Parse(whtlist); + PermissionLevel = perm; + IgnorePlayerLimits = bool.Parse(ignoreLimit); + } + + public string[] GetTimes() + { + return new string[] { FirstConnectedTime, LastConnectedTime, LastDisconnectTime }; + } + + public string[] GetRegistration() + { + return new string[] { Whitelisted.ToString(), PermissionLevel, IgnorePlayerLimits.ToString() }; + } + + public bool IsDefaultRegistration() + { + return Whitelisted == false && IgnorePlayerLimits == false && PermissionLevel == ServerDefaultPerm; + } + + public string ToString(string format) + { + if (format == "Known") + { + return $"{XUID},{Username},{FirstConnectedTime},{LastConnectedTime},{LastDisconnectTime}"; + } + if (format == "Registered") + { + return $"{XUID},{Username},{PermissionLevel},{Whitelisted},{IgnorePlayerLimits}"; + } + return null; + } + + public bool IsPlayerWhitelisted() => Whitelisted; + + public bool PlayerIgnoresLimit() => IgnorePlayerLimits; + + public string GetPermissionLevel() => PermissionLevel; + } + +} \ No newline at end of file diff --git a/BedrockService.backup/BedrockService.Shared/Classes/Property.cs b/BedrockService.backup/BedrockService.Shared/Classes/Property.cs new file mode 100644 index 00000000..ffc64a7a --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/Classes/Property.cs @@ -0,0 +1,29 @@ +using Newtonsoft.Json; + +namespace BedrockService.Shared.Classes +{ + public class Property + { + public string KeyName { get; set; } + public string Value { get; set; } + public string DefaultValue { get; set; } + + [JsonConstructor] + public Property(string key, string defaultValue) + { + KeyName = key; + Value = defaultValue; + DefaultValue = defaultValue; + } + + public override string ToString() + { + return Value; + } + + public void SetValue(string newValue) + { + Value = newValue; + } + } +} diff --git a/BedrockService.backup/BedrockService.Shared/Classes/ServerInfo.cs b/BedrockService.backup/BedrockService.Shared/Classes/ServerInfo.cs new file mode 100644 index 00000000..969d0a0a --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/Classes/ServerInfo.cs @@ -0,0 +1,223 @@ +using BedrockService.Shared.Interfaces; +using System.Collections.Generic; +using System.Linq; + +namespace BedrockService.Shared.Classes +{ + public class ServerInfo : IServerConfiguration + { + public string serversPath; + public string ServerName { get; set; } + public string FileName { get; set; } + public List ConsoleBuffer = new List(); + public Property ServerPath { get; set; } + public Property ServerExeName { get; set; } + public List PlayersList = new List(); + public List ServerPropList = new List(); + public List StartCmds = new List(); + + public ServerInfo(string[] configEntries, string coreServersPath) + { + serversPath = coreServersPath; + InitializeDefaults(); + ProcessConfiguration(configEntries); + } + + public void InitializeDefaults() + { + ServerName = "Default"; + FileName = "Default.conf"; + ServerPath = new Property("ServerPath", $@"{serversPath}\{ServerName}"); + ServerExeName = new Property("ServerExeName", $"BedrockService.{ServerName}.exe"); + + ServerPropList.Clear(); + ServerPropList.Add(new Property("server-name", "Default")); + ServerPropList.Add(new Property("gamemode", "creative")); + ServerPropList.Add(new Property("difficulty", "easy")); + ServerPropList.Add(new Property("allow-cheats", "false")); + ServerPropList.Add(new Property("max-players", "10")); + ServerPropList.Add(new Property("online-mode", "true")); + ServerPropList.Add(new Property("white-list", "false")); + ServerPropList.Add(new Property("server-port", "19132")); + ServerPropList.Add(new Property("server-portv6", "19133")); + ServerPropList.Add(new Property("view-distance", "32")); + ServerPropList.Add(new Property("tick-distance", "4")); + ServerPropList.Add(new Property("player-idle-timeout", "30")); + ServerPropList.Add(new Property("max-threads", "8")); + ServerPropList.Add(new Property("level-name", "Bedrock Level")); + ServerPropList.Add(new Property("level-seed", "")); + ServerPropList.Add(new Property("default-player-permission-level", "member")); + ServerPropList.Add(new Property("texturepack-required", "false")); + ServerPropList.Add(new Property("content-log-file-enabled", "false")); + ServerPropList.Add(new Property("compression-threshold", "1")); + ServerPropList.Add(new Property("server-authoritative-movement", "server-auth")); + ServerPropList.Add(new Property("player-movement-score-threshold", "20")); + ServerPropList.Add(new Property("player-movement-distance-threshold", "0.3")); + ServerPropList.Add(new Property("player-movement-duration-threshold-in-ms", "500")); + ServerPropList.Add(new Property("correct-player-movement", "false")); + } + + + public void SetStartCommands(List newEntries) => StartCmds = newEntries; + + public void ProcessConfiguration(string[] fileEntries) + { + if (fileEntries == null) + return; + foreach (string line in fileEntries) + { + if (!line.StartsWith("#") && !string.IsNullOrEmpty(line)) + { + string[] split = line.Split('='); + if (split.Length == 1) + { + split = new string[] { split[0], "" }; + } + Property SrvProp = ServerPropList.FirstOrDefault(prop => prop.KeyName == split[0]); + if (SrvProp != null) + { + SetProp(split[0], split[1]); + } + switch (split[0]) + { + case "server-name": + ServerName = split[1]; + ServerPath.SetValue($@"{serversPath}\{ServerName}"); + ServerExeName.SetValue($"BedrockService.{ServerName}.exe"); + FileName = $@"{ServerName}.conf"; + break; + + case "AddStartCmd": + StartCmds.Add(new StartCmdEntry(split[1])); + break; + } + } + } + } + + public bool SetProp(string name, string newValue) + { + try + { + Property serverProp = ServerPropList.First(prop => prop.KeyName == name); + ServerPropList[ServerPropList.IndexOf(serverProp)].SetValue(newValue); + return true; + } + catch + { + + } + return false; + } + + public bool SetProp(Property propToSet) + { + try + { + Property serverProp = ServerPropList.First(prop => prop.KeyName == propToSet.KeyName); + ServerPropList[ServerPropList.IndexOf(serverProp)] = propToSet; + return true; + } + catch + { + + } + return false; + } + + public Property GetProp(string name) + { + Property foundProp = ServerPropList.FirstOrDefault(prop => prop.KeyName == name); + if (foundProp == null) + { + switch (name) + { + case "ServerPath": + return ServerPath; + case "ServerExeName": + return ServerExeName; + } + } + return foundProp; + } + + public void SetAllInfos() => throw new System.NotImplementedException(); + + public void AddStartCommand(string command) + { + StartCmds.Add(new StartCmdEntry(command)); + } + + public bool DeleteStartCommand(string command) + { + StartCmdEntry entry = StartCmds.FirstOrDefault(prop => prop.Command == command); + return StartCmds.Remove(entry); + } + + public List GetStartCommands() => StartCmds; + + public override string ToString() + { + return ServerName; + } + + public override int GetHashCode() + { + int hashCode = -298215838; + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(ServerName); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(FileName); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(ServerPath); + return hashCode; + } + + public override bool Equals(object obj) + { + return obj is ServerInfo info && + ServerName == info.ServerName && + EqualityComparer.Default.Equals(ServerPath, info.ServerPath); + } + + public string GetServerName() => ServerName; + + public List GetAllProps() => ServerPropList; + + public void SetAllProps(List newPropList) => ServerPropList = newPropList; + + public void AddUpdatePlayer(IPlayer player) + { + IPlayer foundPlayer = PlayersList.FirstOrDefault(p => p.GetXUID() == player.GetXUID()); + if (foundPlayer == null) + { + PlayersList.Add(player); + return; + } + PlayersList[PlayersList.IndexOf(foundPlayer)] = player; + } + + public IPlayer GetPlayerByXuid(string xuid) + { + IPlayer foundPlayer = PlayersList.FirstOrDefault(p => p.GetXUID() == xuid); + if (foundPlayer == null) + { + return null; + } + return foundPlayer; + } + + public string GetFileName() + { + return FileName; + } + + public List GetLog() => ConsoleBuffer = ConsoleBuffer ?? new List(); + + public void SetLog(List newLog) => ConsoleBuffer = newLog; + + public List GetPlayerList() => PlayersList ?? new List(); + + public void SetPlayerList(List newList) => PlayersList = newList; + + public IServerConfiguration GetServerInfo() => this; + } + +} \ No newline at end of file diff --git a/BedrockService.backup/BedrockService.Shared/Classes/ServerLogger.cs b/BedrockService.backup/BedrockService.Shared/Classes/ServerLogger.cs new file mode 100644 index 00000000..83fa2495 --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/Classes/ServerLogger.cs @@ -0,0 +1,102 @@ +using BedrockService.Shared.Interfaces; +using Newtonsoft.Json; +using System; +using System.IO; +using System.Text; + +namespace BedrockService.Shared.Classes +{ + public class ServerLogger : ILogger + { + private StringBuilder OutString = new StringBuilder(); + [NonSerialized] + private readonly StreamWriter _logWriter; + private readonly bool _logToFile = false; + private readonly bool _logToConsole = false; + private readonly string _parent; + private readonly string _logDir; + private readonly IServerConfiguration _serverConfiguration; + + public ServerLogger(IProcessInfo processInfo, IServiceConfiguration serviceConfiguration, IServerConfiguration serverConfiguration, string parent) + { + _serverConfiguration = serverConfiguration; + _logDir = $@"{processInfo.GetDirectory()}\Server\Logs"; + _logToFile = bool.Parse(serviceConfiguration.GetProp("LogServersToFile").ToString()); + _parent = parent; + _logToConsole = true; + if (_logToFile) + { + if (!Directory.Exists(_logDir)) + Directory.CreateDirectory(_logDir); + _logWriter = new StreamWriter($@"{_logDir}\ServerLog_{parent}_{DateTime.Now:yyyymmddhhmmss}.log", true); + } + } + + [JsonConstructor] + public ServerLogger(string serverName) + { + _parent = serverName; + _logToFile = false; + _logToConsole = false; + } + + public void AppendLine(string text) + { + try + { + _serverConfiguration.GetLog().Add(text); + if (_logToFile && _logWriter != null) + { + _logWriter.WriteLine(text); + _logWriter.Flush(); + } + if (_logToConsole) + Console.WriteLine(text); + } + catch + { + } + } + + public void AppendText(string text) + { + try + { + _serverConfiguration.GetLog().Add(text); + if (_logToFile && _logWriter != null) + { + _logWriter.Write(text); + _logWriter.Flush(); + } + if (_logToConsole) + { + Console.Write(text); + Console.Out.Flush(); + } + } + catch + { + } + } + + public int Count() + { + return _serverConfiguration.GetLog().Count; + } + + public string FromIndex(int index) + { + return _serverConfiguration.GetLog()[index]; + } + + public override string ToString() + { + OutString = new StringBuilder(); + foreach (string s in _serverConfiguration.GetLog()) + { + OutString.Append(s); + } + return OutString.ToString(); + } + } +} diff --git a/BedrockService.backup/BedrockService.Shared/Classes/ServiceInfo.cs b/BedrockService.backup/BedrockService.Shared/Classes/ServiceInfo.cs new file mode 100644 index 00000000..b7fea589 --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/Classes/ServiceInfo.cs @@ -0,0 +1,156 @@ +using BedrockService.Shared.Interfaces; +using Newtonsoft.Json; +using System.Collections.Generic; +using System.Linq; + +namespace BedrockService.Shared.Classes +{ + public class ServiceInfo : IServiceConfiguration + { + private string hostName { get; set; } + private string address { get; set; } + private string hostDisplayName { get; set; } + [JsonProperty] + private string serverVersion { get; set; } + [JsonProperty] + private List serviceLog = new List(); + [JsonProperty] + private List ServerList = new List(); + [JsonProperty] + private List globals = new List(); + private readonly IProcessInfo _processInfo; + + public ServiceInfo(IProcessInfo processInfo) + { + _processInfo = processInfo; + InitializeDefaults(); + } + + public void InitializeDefaults() + { + globals.Clear(); + globals.Add(new Property("ServersPath", @"C:\MCBedrockService")); + globals.Add(new Property("AcceptedMojangLic", "false")); + globals.Add(new Property("ClientPort", "19134")); + globals.Add(new Property("BackupEnabled", "false")); + globals.Add(new Property("BackupPath", "Default")); + globals.Add(new Property("BackupCron", "0 1 * * *")); + globals.Add(new Property("MaxBackupCount", "25")); + globals.Add(new Property("EntireBackups", "false")); + globals.Add(new Property("CheckUpdates", "false")); + globals.Add(new Property("UpdateCron", "0 2 * * *")); + globals.Add(new Property("LogServersToFile", "true")); + globals.Add(new Property("LogServiceToFile", "true")); + } + + public void ProcessConfiguration(string[] fileEntries) + { + foreach (string line in fileEntries) + { + if (!line.StartsWith("#") && !string.IsNullOrEmpty(line)) + { + string[] split = line.Split('='); + if (split.Length == 1) + { + split[1] = ""; + } + if (split[0] == "BackupPath") + { + if (split[1] == "Default") + split[1] = $@"{_processInfo.GetDirectory()}\Server\Backups"; + } + if (!SetProp(split[0], split[1])) + { + //Logger.AppendLine($"Error! Key \"{split[0]}\" was not found! Check configs!"); + } + } + } + } + + public bool SetProp(string name, string newValue) + { + try + { + Property GlobalToEdit = globals.First(glob => glob.KeyName == name); + globals[globals.IndexOf(GlobalToEdit)].SetValue(newValue); + return true; + } + catch + { + // handle soon. + return false; + } + } + + public bool SetProp(Property propToSet) + { + try + { + Property GlobalToEdit = globals.First(glob => glob.KeyName == propToSet.KeyName); + globals[globals.IndexOf(GlobalToEdit)] = propToSet; + } + catch + { + // handle soon. + return false; + } + return true; + } + + public Property GetProp(string name) + { + return globals.FirstOrDefault(prop => prop.KeyName == name); + } + + public List GetAllProps() => globals; + + public void SetAllProps(List props) => globals = props; + + public IServerConfiguration GetServerInfoByName(string serverName) + { + return ServerList.FirstOrDefault(info => info.GetServerName() == serverName); + } + + public IServerConfiguration GetServerInfoByIndex(int index) + { + return ServerList[index]; + } + + public void RemoveServerInfo(IServerConfiguration serverConfiguration) + { + ServerList.Remove(serverConfiguration.GetServerInfo()); + } + + public void SetServerInfo(IServerConfiguration newInfo) + { + ServerList[ServerList.IndexOf(newInfo.GetServerInfo())] = newInfo.GetServerInfo(); + } + + public List GetServerList() => ServerList; + + public void SetAllServerInfos(List newInfos) + { + ServerList = newInfos; + } + + public void AddNewServerInfo(IServerConfiguration serverConfiguration) + { + ServerList.Add(serverConfiguration); + } + + public void RemoveServerInfoByIndex(int serverIndex) + { + ServerList.RemoveAt(serverIndex); + } + + public void SetServerVersion(string newVersion) => serverVersion = newVersion; + + public string GetServerVersion() => serverVersion; + + public List GetLog() => serviceLog ?? new List(); + + public void SetLog(List newLog) => serviceLog = newLog; + + public byte GetServerIndex(IServerConfiguration server) => (byte)ServerList.IndexOf(server); + } +} \ No newline at end of file diff --git a/BedrockService.backup/BedrockService.Shared/Classes/ServiceProcessInfo.cs b/BedrockService.backup/BedrockService.Shared/Classes/ServiceProcessInfo.cs new file mode 100644 index 00000000..9f9e0645 --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/Classes/ServiceProcessInfo.cs @@ -0,0 +1,38 @@ +using BedrockService.Shared.Interfaces; + +namespace BedrockService.Shared.Classes +{ + public class ServiceProcessInfo : IProcessInfo + { + private readonly string _serviceDirectory; + private readonly string _serviceExeName; + private readonly int _processPid; + private bool _debugEnabled; + private bool _isConsoleMode; + + public ServiceProcessInfo(string serviceDirectory, string serviceExeName, int processPid, bool debugEnabled, bool isConsoleMode) + { + _serviceDirectory = serviceDirectory; + _serviceExeName = serviceExeName; + _processPid = processPid; + _debugEnabled = debugEnabled; + _isConsoleMode = isConsoleMode; + } + + public string GetDirectory() => _serviceDirectory; + + public string GetExecutableName() => _serviceExeName; + + public int GetProcessPID() => _processPid; + + public bool IsDebugEnabled() => _debugEnabled; + + public bool IsConsoleMode() => _isConsoleMode; + + public void SetArguments(bool isDebug, bool isConsole) + { + _debugEnabled = isDebug; + _isConsoleMode = isConsole; + } + } +} diff --git a/BedrockService.backup/BedrockService.Shared/Classes/StartCmdEntry.cs b/BedrockService.backup/BedrockService.Shared/Classes/StartCmdEntry.cs new file mode 100644 index 00000000..5200e2d8 --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/Classes/StartCmdEntry.cs @@ -0,0 +1,12 @@ +namespace BedrockService.Shared.Classes +{ + public class StartCmdEntry + { + public string Command = "help 1"; + + public StartCmdEntry(string entry) + { + Command = entry; + } + } +} \ No newline at end of file diff --git a/BedrockService.backup/BedrockService.Shared/Interfaces/IClientSideServiceConfiguration.cs b/BedrockService.backup/BedrockService.Shared/Interfaces/IClientSideServiceConfiguration.cs new file mode 100644 index 00000000..4d4c8f7a --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/Interfaces/IClientSideServiceConfiguration.cs @@ -0,0 +1,10 @@ +namespace BedrockService.Shared.Interfaces +{ + public interface IClientSideServiceConfiguration + { + string GetAddress(); + string GetDisplayName(); + string GetHostName(); + string GetPort(); + } +} \ No newline at end of file diff --git a/BedrockService/BedrockService.Shared/Interfaces/IConfiguration.cs b/BedrockService.backup/BedrockService.Shared/Interfaces/IConfiguration.cs similarity index 100% rename from BedrockService/BedrockService.Shared/Interfaces/IConfiguration.cs rename to BedrockService.backup/BedrockService.Shared/Interfaces/IConfiguration.cs diff --git a/BedrockService/BedrockService.Shared/Interfaces/ILogger.cs b/BedrockService.backup/BedrockService.Shared/Interfaces/ILogger.cs similarity index 100% rename from BedrockService/BedrockService.Shared/Interfaces/ILogger.cs rename to BedrockService.backup/BedrockService.Shared/Interfaces/ILogger.cs diff --git a/BedrockService.backup/BedrockService.Shared/Interfaces/IPlayer.cs b/BedrockService.backup/BedrockService.Shared/Interfaces/IPlayer.cs new file mode 100644 index 00000000..f4a4876e --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/Interfaces/IPlayer.cs @@ -0,0 +1,19 @@ +namespace BedrockService.Shared.Interfaces +{ + public interface IPlayer + { + void Initialize(string xuid, string username); + void UpdateTimes(string lastConn, string lastDiscon); + void UpdateRegistration(string permission, string whitelisted, string ignoreMaxPlayerLimit); + string SearchForProperty(string input); + string GetUsername(); + string GetXUID(); + string[] GetTimes(); + string[] GetRegistration(); + bool IsPlayerWhitelisted(); + bool PlayerIgnoresLimit(); + string GetPermissionLevel(); + bool IsDefaultRegistration(); + string ToString(string format); + } +} diff --git a/BedrockService.backup/BedrockService.Shared/Interfaces/IProcessInfo.cs b/BedrockService.backup/BedrockService.Shared/Interfaces/IProcessInfo.cs new file mode 100644 index 00000000..b6af2a12 --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/Interfaces/IProcessInfo.cs @@ -0,0 +1,17 @@ +namespace BedrockService.Shared.Interfaces +{ + public interface IProcessInfo + { + string GetDirectory(); + + string GetExecutableName(); + + int GetProcessPID(); + + bool IsDebugEnabled(); + + bool IsConsoleMode(); + + void SetArguments(bool isDebug, bool isConsole); + } +} diff --git a/BedrockService.backup/BedrockService.Shared/Interfaces/IServerConfiguration.cs b/BedrockService.backup/BedrockService.Shared/Interfaces/IServerConfiguration.cs new file mode 100644 index 00000000..ed5c41bb --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/Interfaces/IServerConfiguration.cs @@ -0,0 +1,30 @@ +using BedrockService.Shared.Classes; +using System.Collections.Generic; + +namespace BedrockService.Shared.Interfaces +{ + public interface IServerConfiguration : IConfiguration + { + string GetServerName(); + + string GetFileName(); + + void AddStartCommand(string command); + + bool DeleteStartCommand(string command); + + List GetStartCommands(); + + void SetStartCommands(List newEntries); + + void AddUpdatePlayer(IPlayer player); + + IPlayer GetPlayerByXuid(string xuid); + + List GetPlayerList(); + + void SetPlayerList(List newList); + + IServerConfiguration GetServerInfo(); + } +} diff --git a/BedrockService.backup/BedrockService.Shared/Interfaces/IServiceConfiguration.cs b/BedrockService.backup/BedrockService.Shared/Interfaces/IServiceConfiguration.cs new file mode 100644 index 00000000..836d530b --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/Interfaces/IServiceConfiguration.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; + +namespace BedrockService.Shared.Interfaces +{ + public interface IServiceConfiguration : IConfiguration + { + IServerConfiguration GetServerInfoByName(string serverName); + + IServerConfiguration GetServerInfoByIndex(int index); + + byte GetServerIndex(IServerConfiguration server); + + List GetServerList(); + + void SetAllServerInfos(List newInfos); + + void AddNewServerInfo(IServerConfiguration serverConfiguration); + + void RemoveServerInfoByIndex(int serverIndex); + + void RemoveServerInfo(IServerConfiguration serverConfiguration); + + void SetServerVersion(string newVersion); + + string GetServerVersion(); + } +} diff --git a/BedrockService.backup/BedrockService.Shared/PackParser/MinecraftKnownPacksClass.cs b/BedrockService.backup/BedrockService.Shared/PackParser/MinecraftKnownPacksClass.cs new file mode 100644 index 00000000..68f1dfc8 --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/PackParser/MinecraftKnownPacksClass.cs @@ -0,0 +1,67 @@ +using Newtonsoft.Json.Linq; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace BedrockService.Shared.PackParser +{ + public class MinecraftKnownPacksClass + { + public List KnownPacks = new List(); + private readonly List _stockPacks = new List(); + public class KnownPack + { + public int file_version { get; set; } + public string file_system { get; set; } + public bool? from_disk { get; set; } + public List hashes { get; set; } + public string path { get; set; } + public string uuid { get; set; } + public string version { get; set; } + + public override string ToString() + { + return path; + } + } + + public MinecraftKnownPacksClass(string serverFile, string stockFile) + { + KnownPacks = ParseJsonArray(serverFile); + _stockPacks = ParseJsonArray(stockFile); + KnownPacks.RemoveAt(0); // Strip file version entry. + foreach (KnownPack pack in _stockPacks) + { + KnownPack packToRemove = new KnownPack(); + if (pack.uuid == null) + continue; + packToRemove = KnownPacks.First(p => p.uuid != null && p.uuid == pack.uuid); + KnownPacks.Remove(packToRemove); + } + } + + public void RemovePackFromServer(string serverPath, MinecraftPackContainer pack) + { + if (pack.ManifestType == "WorldPack") + Directory.Delete($@"{serverPath}\worlds\{pack.FolderName}", true); + if (pack.ManifestType == "data") + Directory.Delete($@"{serverPath}\behavior_packs\{pack.FolderName}", true); + if (pack.ManifestType == "resources") + Directory.Delete($@"{serverPath}\resource_packs\{ pack.FolderName}", true); + KnownPacks.Remove(KnownPacks.First(p => p.uuid != null || p.uuid == pack.JsonManifest.header.uuid)); + List packsToWrite = new List(_stockPacks); + if (KnownPacks.Count > 0) + packsToWrite.AddRange(KnownPacks); + File.WriteAllText($@"{serverPath}\valid_known_packs.json", JArray.FromObject(packsToWrite).ToString()); + } + + private List ParseJsonArray(string jsonFile) + { + JArray packList = JArray.Parse(File.ReadAllText(jsonFile)); + List parsedPackInfos = new List(); + foreach (JToken token in packList) + parsedPackInfos.Add(token.ToObject()); + return parsedPackInfos; + } + } +} diff --git a/BedrockService.backup/BedrockService.Shared/PackParser/MinecraftPackParser.cs b/BedrockService.backup/BedrockService.Shared/PackParser/MinecraftPackParser.cs new file mode 100644 index 00000000..c6c4127e --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/PackParser/MinecraftPackParser.cs @@ -0,0 +1,174 @@ +using BedrockService.Shared.Interfaces; +using BedrockService.Shared.Utilities; +using Newtonsoft.Json; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; + +namespace BedrockService.Shared.PackParser +{ + public class Header + { + public string description { get; set; } + public string name { get; set; } + public string uuid { get; set; } + public List version { get; set; } + } + + public class Module + { + public string description { get; set; } + public string type { get; set; } + public string uuid { get; set; } + public List version { get; set; } + } + + public class Dependency + { + public string uuid { get; set; } + public List version { get; set; } + } + + public class Manifest + { + public int format_version { get; set; } + public Header header { get; set; } + public List modules { get; set; } + public List dependencies { get; set; } + } + + public class MinecraftPackContainer + { + public Manifest JsonManifest; + public DirectoryInfo PackContentLocation; + public string ManifestType; + public string FolderName; + public byte[] IconBytes; + + public override string ToString() + { + return JsonManifest != null ? JsonManifest.header.name : "WorldPack"; + } + } + + public class MinecraftPackParser + { + private readonly IProcessInfo _processInfo; + private readonly ILogger _logger; + public DirectoryInfo PackExtractDirectory; + public List FoundPacks = new List(); + + [JsonConstructor] + public MinecraftPackParser(ILogger logger, IProcessInfo processInfo) + { + _processInfo = processInfo; + _logger = logger; + } + + public MinecraftPackParser(byte[] fileContents, ILogger logger, IProcessInfo processInfo) + { + _logger = logger; + PackExtractDirectory = new DirectoryInfo($@"{processInfo.GetDirectory()}\Temp"); + _processInfo = processInfo; + new FileUtils(processInfo.GetDirectory()).ClearTempDir(); + using (MemoryStream fileStream = new MemoryStream(fileContents, 5, fileContents.Length - 5)) + { + using (ZipArchive zipArchive = new ZipArchive(fileStream, ZipArchiveMode.Read)) + { + zipArchive.ExtractToDirectory(PackExtractDirectory.FullName); + } + } + ParseDirectory(PackExtractDirectory); + } + + public MinecraftPackParser(string[] files, DirectoryInfo extractDir, ILogger logger, IProcessInfo processInfo) + { + PackExtractDirectory = extractDir; + _logger = logger; + _processInfo = processInfo; + new FileUtils(_processInfo.GetDirectory()).ClearTempDir(); + if (Directory.Exists($@"{PackExtractDirectory.FullName}\ZipTemp")) + { + Directory.CreateDirectory($@"{PackExtractDirectory.FullName}\ZipTemp"); + } + foreach (string file in files) + { + FileInfo fInfo = new FileInfo(file); + string zipFilePath = $@"{PackExtractDirectory.FullName}\{fInfo.Name.Replace(fInfo.Extension, "")}"; + ZipFile.ExtractToDirectory(file, zipFilePath); + foreach (FileInfo extractedFile in new DirectoryInfo(zipFilePath).GetFiles()) + { + if (extractedFile.Extension == ".mcpack") + { + Directory.CreateDirectory($@"{zipFilePath}\{extractedFile.Name.Replace(extractedFile.Extension, "")}"); + ZipFile.ExtractToDirectory(extractedFile.FullName, $@"{zipFilePath}\{fInfo.Name.Replace(fInfo.Extension, "")}_{extractedFile.Name.Replace(extractedFile.Extension, "")}"); + } + } + } + foreach (DirectoryInfo directory in PackExtractDirectory.GetDirectories()) + ParseDirectory(directory); + } + + public void ParseDirectory(DirectoryInfo directoryToParse) + { + _logger.AppendLine($"Parsing directory {directoryToParse.Name}"); + if (directoryToParse.Exists) + { + foreach (FileInfo file in directoryToParse.GetFiles("*", SearchOption.AllDirectories)) + { + if (file.Name == "levelname.txt") + { + byte[] iconBytes; + try + { + if (File.Exists($@"{file.Directory.FullName}\world_icon.jpeg")) + iconBytes = File.ReadAllBytes($@"{file.Directory.FullName}\world_icon.jpeg"); + else + iconBytes = File.ReadAllBytes($@"{file.Directory.FullName}\world_icon.png"); + } + catch + { + iconBytes = null; + } + + FoundPacks.Add(new MinecraftPackContainer + { + JsonManifest = null, + PackContentLocation = file.Directory, + ManifestType = "WorldPack", + FolderName = file.Directory.Name, + IconBytes = iconBytes + }); + _logger.AppendLine("Pack was detected as MCWorld"); + return; + } + if (file.Name == "manifest.json") + { + byte[] iconBytes; + if (File.Exists($@"{file.Directory.FullName}\pack_icon.jpeg")) + iconBytes = File.ReadAllBytes($@"{file.Directory.FullName}\pack_icon.jpeg"); + else + iconBytes = File.ReadAllBytes($@"{file.Directory.FullName}\pack_icon.png"); + + MinecraftPackContainer container = new MinecraftPackContainer + { + JsonManifest = new Manifest(), + PackContentLocation = file.Directory, + ManifestType = "", + FolderName = file.Directory.Name, + IconBytes = iconBytes + }; + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + container.JsonManifest = JsonConvert.DeserializeObject(File.ReadAllText(file.FullName), settings); + container.ManifestType = container.JsonManifest.modules[0].type; + _logger.AppendLine($"{container.ManifestType} pack found, name: {container.JsonManifest.header.name}, path: {container.PackContentLocation.Name}"); + FoundPacks.Add(container); + } + } + } + } + } +} diff --git a/BedrockService.backup/BedrockService.Shared/Properties/AssemblyInfo.cs b/BedrockService.backup/BedrockService.Shared/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..0b64fbcf --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("BedrockService.Shared")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("BedrockService.Shared")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("f146d5e8-ef1f-4785-9150-182631f059b7")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/BedrockService.backup/BedrockService.Shared/Utilities/FileUtils.cs b/BedrockService.backup/BedrockService.Shared/Utilities/FileUtils.cs new file mode 100644 index 00000000..6ef8cebb --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/Utilities/FileUtils.cs @@ -0,0 +1,62 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace BedrockService.Shared.Utilities +{ + public class FileUtils + { + readonly string _servicePath; + public FileUtils(string servicePath) + { + this._servicePath = servicePath; + } + public void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target) + { + foreach (DirectoryInfo dir in source.GetDirectories()) + CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name)); + foreach (FileInfo file in source.GetFiles()) + file.CopyTo(Path.Combine(target.FullName, file.Name), true); + } + + public void DeleteFilesRecursively(DirectoryInfo source, bool removeSourceFolder) + { + foreach (DirectoryInfo dir in source.GetDirectories()) + DeleteFilesRecursively(dir, removeSourceFolder); + foreach (FileInfo file in source.GetFiles()) + file.Delete(); + foreach (DirectoryInfo emptyDir in source.GetDirectories()) + emptyDir.Delete(true); + if (removeSourceFolder) + source.Delete(true); + } + + public void ClearTempDir() + { + DirectoryInfo tempDirectory = new DirectoryInfo($@"{_servicePath}\Temp"); + if (!tempDirectory.Exists) + tempDirectory.Create(); + foreach (FileInfo file in tempDirectory.GetFiles("*", SearchOption.AllDirectories)) + file.Delete(); + foreach (DirectoryInfo directory in tempDirectory.GetDirectories()) + directory.Delete(true); + } + + public void DeleteFilelist(string[] fileList, string serverPath) + { + foreach (string file in fileList) + try + { + File.Delete($@"{serverPath}\{file}"); + } + catch { } + List exesInPath = Directory.EnumerateFiles(serverPath, "*.exe", SearchOption.AllDirectories).ToList(); + foreach (string exe in exesInPath) + File.Delete(exe); + foreach (string dir in Directory.GetDirectories(serverPath)) + if (Directory.EnumerateFiles(dir, "*", SearchOption.AllDirectories).Count() == 0) + Directory.Delete(dir, true); + } + + } +} diff --git a/BedrockService/BedrockService.Shared/packages.config b/BedrockService.backup/BedrockService.Shared/packages.config similarity index 100% rename from BedrockService/BedrockService.Shared/packages.config rename to BedrockService.backup/BedrockService.Shared/packages.config diff --git a/BedrockService.backup/BedrockService.Shared/upgrade.backup b/BedrockService.backup/BedrockService.Shared/upgrade.backup new file mode 100644 index 00000000..a39f2887 --- /dev/null +++ b/BedrockService.backup/BedrockService.Shared/upgrade.backup @@ -0,0 +1 @@ +Backup created at 1636641895 (11/11/2021 2:44:55 PM +00:00) \ No newline at end of file diff --git a/BedrockService.backup/Client/App.config b/BedrockService.backup/Client/App.config new file mode 100644 index 00000000..56efbc7b --- /dev/null +++ b/BedrockService.backup/Client/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/BedrockService.backup/Client/BedrockService.Client.csproj b/BedrockService.backup/Client/BedrockService.Client.csproj new file mode 100644 index 00000000..3627b532 --- /dev/null +++ b/BedrockService.backup/Client/BedrockService.Client.csproj @@ -0,0 +1,186 @@ + + + + + Debug + AnyCPU + {A2DAF70A-925A-4F4B-B7EE-CAACE75D6740} + WinExe + BedrockService.Client + BedrockService.Client + v4.7.2 + 512 + true + true + false + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + x86 + true + full + false + ..\bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + x86 + pdbonly + true + ..\bin\Release\ + TRACE + prompt + 4 + + + BedrockService.Client.Forms.MainWindow + + + + ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll + + + + + + + + + + + + + + + + + + Form + + + AddNewServerForm.cs + + + Form + + + ClientConfigForm.cs + + + Form + + + ManagePacksForms.cs + + + Form + + + NewPlayerRegistrationForm.cs + + + Form + + + PlayerManagerForm.cs + + + + + + Form + + + PropEditorForm.cs + + + Form + + + MainWindow.cs + + + + + + AddNewServerForm.cs + + + ClientConfigForm.cs + + + ManagePacksForms.cs + + + NewPlayerRegistrationForm.cs + + + PlayerManagerForm.cs + + + PropEditorForm.cs + + + MainWindow.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + False + Microsoft .NET Framework 4.7.2 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + + + {f146d5e8-ef1f-4785-9150-182631f059b7} + BedrockService.Shared + + + + \ No newline at end of file diff --git a/BedrockService.backup/Client/Configs/Config.conf b/BedrockService.backup/Client/Configs/Config.conf new file mode 100644 index 00000000..86398eeb --- /dev/null +++ b/BedrockService.backup/Client/Configs/Config.conf @@ -0,0 +1,2 @@ +[Hosts] +host1=127.0.0.1:19134 diff --git a/BedrockService.backup/Client/Forms/AddNewServerForm.Designer.cs b/BedrockService.backup/Client/Forms/AddNewServerForm.Designer.cs new file mode 100644 index 00000000..1291703f --- /dev/null +++ b/BedrockService.backup/Client/Forms/AddNewServerForm.Designer.cs @@ -0,0 +1,158 @@ + +namespace BedrockService.Client.Forms +{ + partial class AddNewServerForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.srvNameBox = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.ipV4Box = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.ipV6Box = new System.Windows.Forms.TextBox(); + this.editPropsBtn = new System.Windows.Forms.Button(); + this.saveBtn = new System.Windows.Forms.Button(); + this.label4 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // srvNameBox + // + this.srvNameBox.Location = new System.Drawing.Point(106, 56); + this.srvNameBox.Name = "srvNameBox"; + this.srvNameBox.Size = new System.Drawing.Size(100, 20); + this.srvNameBox.TabIndex = 0; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(30, 59); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(70, 13); + this.label1.TabIndex = 1; + this.label1.Text = "Server name:"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(30, 85); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(56, 13); + this.label2.TabIndex = 3; + this.label2.Text = "IP v4 port:"; + // + // ipV4Box + // + this.ipV4Box.Location = new System.Drawing.Point(106, 82); + this.ipV4Box.Name = "ipV4Box"; + this.ipV4Box.Size = new System.Drawing.Size(100, 20); + this.ipV4Box.TabIndex = 2; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(30, 111); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(56, 13); + this.label3.TabIndex = 5; + this.label3.Text = "IP v6 port:"; + // + // ipV6Box + // + this.ipV6Box.Location = new System.Drawing.Point(106, 108); + this.ipV6Box.Name = "ipV6Box"; + this.ipV6Box.Size = new System.Drawing.Size(100, 20); + this.ipV6Box.TabIndex = 4; + // + // editPropsBtn + // + this.editPropsBtn.Location = new System.Drawing.Point(33, 149); + this.editPropsBtn.Name = "editPropsBtn"; + this.editPropsBtn.Size = new System.Drawing.Size(173, 23); + this.editPropsBtn.TabIndex = 6; + this.editPropsBtn.Text = "Edit server settings..."; + this.editPropsBtn.UseVisualStyleBackColor = true; + this.editPropsBtn.Click += new System.EventHandler(this.editPropsBtn_Click); + // + // saveBtn + // + this.saveBtn.Location = new System.Drawing.Point(106, 191); + this.saveBtn.Name = "saveBtn"; + this.saveBtn.Size = new System.Drawing.Size(100, 23); + this.saveBtn.TabIndex = 7; + this.saveBtn.Text = "Save Server"; + this.saveBtn.UseVisualStyleBackColor = true; + this.saveBtn.Click += new System.EventHandler(this.saveBtn_Click); + // + // label4 + // + this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.label4.Location = new System.Drawing.Point(30, 9); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(176, 44); + this.label4.TabIndex = 8; + this.label4.Text = "Add a new server to the service. Note: Requires a Global restart to run new serve" + + "r!"; + // + // AddNewServerForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(238, 226); + this.Controls.Add(this.label4); + this.Controls.Add(this.saveBtn); + this.Controls.Add(this.editPropsBtn); + this.Controls.Add(this.label3); + this.Controls.Add(this.ipV6Box); + this.Controls.Add(this.label2); + this.Controls.Add(this.ipV4Box); + this.Controls.Add(this.label1); + this.Controls.Add(this.srvNameBox); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AddNewServerForm"; + this.ShowInTaskbar = false; + this.Text = "AddNewServerForm"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox srvNameBox; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox ipV4Box; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox ipV6Box; + private System.Windows.Forms.Button editPropsBtn; + private System.Windows.Forms.Button saveBtn; + private System.Windows.Forms.Label label4; + } +} \ No newline at end of file diff --git a/BedrockService.backup/Client/Forms/AddNewServerForm.cs b/BedrockService.backup/Client/Forms/AddNewServerForm.cs new file mode 100644 index 00000000..9b328bac --- /dev/null +++ b/BedrockService.backup/Client/Forms/AddNewServerForm.cs @@ -0,0 +1,69 @@ +using BedrockService.Client.Management; +using BedrockService.Shared.Classes; +using BedrockService.Shared.Interfaces; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; + +namespace BedrockService.Client.Forms +{ + public partial class AddNewServerForm : Form + { + public List DefaultProps = new List(); + private readonly List serverConfigurations; + private readonly IClientSideServiceConfiguration serviceConfiguration; + public AddNewServerForm(IClientSideServiceConfiguration serviceConfiguration, List serverConfigurations) + { + this.serviceConfiguration = serviceConfiguration; + this.serverConfigurations = serverConfigurations; + InitializeComponent(); + IServerConfiguration server = new ServerInfo(null, FormManager.MainWindow.connectedHost.GetProp("ServersPath").ToString()); + server.InitializeDefaults(); + DefaultProps = server.GetAllProps(); + } + + private void editPropsBtn_Click(object sender, System.EventArgs e) + { + PropEditorForm editSrvDialog = new PropEditorForm(); + if (srvNameBox.TextLength > 0) + DefaultProps.First(prop => prop.KeyName == "server-name").Value = srvNameBox.Text; + if (ipV4Box.TextLength > 0) + DefaultProps.First(prop => prop.KeyName == "server-port").Value = ipV4Box.Text; + if (ipV6Box.TextLength > 0) + DefaultProps.First(prop => prop.KeyName == "server-portv6").Value = ipV6Box.Text; + editSrvDialog.PopulateBoxes(DefaultProps); + if (editSrvDialog.ShowDialog() == DialogResult.OK) + { + DefaultProps = editSrvDialog.workingProps; + editSrvDialog.Close(); + editSrvDialog.Dispose(); + } + } + + private void saveBtn_Click(object sender, System.EventArgs e) + { + List usedPorts = new List(); + usedPorts.Add(serviceConfiguration.GetPort()); + foreach (IServerConfiguration serverConfiguration in serverConfigurations) + { + usedPorts.Add(serverConfiguration.GetProp("server-port").ToString()); + usedPorts.Add(serverConfiguration.GetProp("server-portv6").ToString()); + } + foreach(string port in usedPorts) + { + if(ipV4Box.Text == port || ipV6Box.Text == port) + { + MessageBox.Show($"You have selected port {port} to use, but this port is already used. Please select another port!"); + return; + } + } + if (srvNameBox.TextLength > 0) + DefaultProps.First(prop => prop.KeyName == "server-name").Value = srvNameBox.Text; + if (ipV4Box.TextLength > 0) + DefaultProps.First(prop => prop.KeyName == "server-port").Value = ipV4Box.Text; + if (ipV6Box.TextLength > 0) + DefaultProps.First(prop => prop.KeyName == "server-portv6").Value = ipV6Box.Text; + DialogResult = DialogResult.OK; + } + } +} diff --git a/BedrockService.backup/Client/Forms/AddNewServerForm.resx b/BedrockService.backup/Client/Forms/AddNewServerForm.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/BedrockService.backup/Client/Forms/AddNewServerForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BedrockService.backup/Client/Forms/ClientConfigForm.Designer.cs b/BedrockService.backup/Client/Forms/ClientConfigForm.Designer.cs new file mode 100644 index 00000000..bf9ac45d --- /dev/null +++ b/BedrockService.backup/Client/Forms/ClientConfigForm.Designer.cs @@ -0,0 +1,133 @@ + +namespace BedrockService.Client.Forms +{ + partial class ClientConfigForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.serverGridView = new System.Windows.Forms.DataGridView(); + this.HostName = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.HostAddress = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.Port = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.nbtPathLabel = new System.Windows.Forms.Label(); + this.nbtButton = new System.Windows.Forms.Button(); + this.saveBtn = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)(this.serverGridView)).BeginInit(); + this.SuspendLayout(); + // + // serverGridView + // + this.serverGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.serverGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.HostName, + this.HostAddress, + this.Port}); + this.serverGridView.Location = new System.Drawing.Point(12, 30); + this.serverGridView.Name = "serverGridView"; + this.serverGridView.RowHeadersWidth = 62; + this.serverGridView.RowTemplate.Height = 28; + this.serverGridView.Size = new System.Drawing.Size(1154, 381); + this.serverGridView.TabIndex = 0; + // + // HostName + // + this.HostName.HeaderText = "Host Name"; + this.HostName.MinimumWidth = 25; + this.HostName.Name = "HostName"; + this.HostName.Width = 250; + // + // HostAddress + // + this.HostAddress.HeaderText = "IP Address"; + this.HostAddress.MinimumWidth = 8; + this.HostAddress.Name = "HostAddress"; + this.HostAddress.Width = 250; + // + // Port + // + this.Port.HeaderText = "IP Port"; + this.Port.MinimumWidth = 8; + this.Port.Name = "Port"; + this.Port.Width = 200; + // + // nbtPathLabel + // + this.nbtPathLabel.AutoSize = true; + this.nbtPathLabel.Location = new System.Drawing.Point(12, 437); + this.nbtPathLabel.Name = "nbtPathLabel"; + this.nbtPathLabel.Size = new System.Drawing.Size(130, 20); + this.nbtPathLabel.TabIndex = 1; + this.nbtPathLabel.Text = "NBT Studio path:"; + // + // nbtButton + // + this.nbtButton.Location = new System.Drawing.Point(16, 473); + this.nbtButton.Name = "nbtButton"; + this.nbtButton.Size = new System.Drawing.Size(209, 37); + this.nbtButton.TabIndex = 2; + this.nbtButton.Text = "Set NBT Studio path"; + this.nbtButton.UseVisualStyleBackColor = true; + this.nbtButton.Click += new System.EventHandler(this.nbtButton_Click); + // + // saveBtn + // + this.saveBtn.Location = new System.Drawing.Point(957, 473); + this.saveBtn.Name = "saveBtn"; + this.saveBtn.Size = new System.Drawing.Size(209, 37); + this.saveBtn.TabIndex = 3; + this.saveBtn.Text = "Save settings"; + this.saveBtn.UseVisualStyleBackColor = true; + this.saveBtn.Click += new System.EventHandler(this.saveBtn_Click); + // + // ClientConfigForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1178, 544); + this.Controls.Add(this.saveBtn); + this.Controls.Add(this.nbtButton); + this.Controls.Add(this.nbtPathLabel); + this.Controls.Add(this.serverGridView); + this.Name = "ClientConfigForm"; + this.Text = "ClientConfigForm"; + ((System.ComponentModel.ISupportInitialize)(this.serverGridView)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.DataGridView serverGridView; + private System.Windows.Forms.DataGridViewTextBoxColumn HostName; + private System.Windows.Forms.DataGridViewTextBoxColumn HostAddress; + private System.Windows.Forms.DataGridViewTextBoxColumn Port; + private System.Windows.Forms.Label nbtPathLabel; + private System.Windows.Forms.Button nbtButton; + private System.Windows.Forms.Button saveBtn; + } +} \ No newline at end of file diff --git a/BedrockService.backup/Client/Forms/ClientConfigForm.cs b/BedrockService.backup/Client/Forms/ClientConfigForm.cs new file mode 100644 index 00000000..4d4c88b2 --- /dev/null +++ b/BedrockService.backup/Client/Forms/ClientConfigForm.cs @@ -0,0 +1,73 @@ +using BedrockService.Client.Management; +using BedrockService.Shared.Classes; +using BedrockService.Shared.Interfaces; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace BedrockService.Client.Forms +{ + public partial class ClientConfigForm : Form + { + private readonly List _clientConfigs; + private readonly ConfigManager _configManager; + public ClientConfigForm(ConfigManager configManager) + { + InitializeComponent(); + _configManager = configManager; + _clientConfigs = _configManager.HostConnectList; + if (!string.IsNullOrEmpty(_configManager.NBTStudioPath)) + { + nbtPathLabel.Text = $"NBT Studio path: {_configManager.NBTStudioPath}"; + } + foreach (IClientSideServiceConfiguration config in _clientConfigs) + { + serverGridView.Rows.Add(new string[3] { config.GetHostName(), config.GetAddress(), config.GetPort() }); + } + } + + public void SimulateTests() + { + nbtButton.PerformClick(); + } + + private void nbtButton_Click(object sender, EventArgs e) + { + using(OpenFileDialog fileDialog = new OpenFileDialog()) + { + fileDialog.Filter = "EXE Files|*.exe"; + fileDialog.FileName = "NbtStudio.exe"; + fileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); + if(fileDialog.ShowDialog() == DialogResult.OK) + { + _configManager.NBTStudioPath = fileDialog.FileName; + nbtPathLabel.Text = $"NBT Studio path: {_configManager.NBTStudioPath}"; + } + } + } + + private void saveBtn_Click(object sender, EventArgs e) + { + List newConfigs = new List(); + foreach(DataGridViewRow row in serverGridView.Rows) + { + if (!string.IsNullOrEmpty((string)row.Cells[0].Value)) + { + newConfigs.Add(new ClientSideServiceConfiguration((string)row.Cells[0].Value, (string)row.Cells[1].Value, (string)row.Cells[2].Value)); + } + } + _configManager.HostConnectList = newConfigs; + + _configManager.SaveConfigFile(); + DialogResult = DialogResult.OK; + Close(); + } + } +} diff --git a/BedrockService.backup/Client/Forms/ClientConfigForm.resx b/BedrockService.backup/Client/Forms/ClientConfigForm.resx new file mode 100644 index 00000000..2d8f1f02 --- /dev/null +++ b/BedrockService.backup/Client/Forms/ClientConfigForm.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + True + + + True + + + True + + \ No newline at end of file diff --git a/BedrockService.backup/Client/Forms/MainWindow.Designer.cs b/BedrockService.backup/Client/Forms/MainWindow.Designer.cs new file mode 100644 index 00000000..7b72ed20 --- /dev/null +++ b/BedrockService.backup/Client/Forms/MainWindow.Designer.cs @@ -0,0 +1,424 @@ +namespace BedrockService.Client.Forms +{ + partial class MainWindow + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.Connect = new System.Windows.Forms.Button(); + this.HostInfoLabel = new System.Windows.Forms.Label(); + this.HostListBox = new System.Windows.Forms.ComboBox(); + this.LogBox = new System.Windows.Forms.TextBox(); + this.ServerSelectBox = new System.Windows.Forms.ListBox(); + this.Disconn = new System.Windows.Forms.Button(); + this.EditGlobals = new System.Windows.Forms.Button(); + this.removeSrvBtn = new System.Windows.Forms.Button(); + this.ChkUpdates = new System.Windows.Forms.Button(); + this.GlobBackup = new System.Windows.Forms.Button(); + this.cmdTextBox = new System.Windows.Forms.TextBox(); + this.SendCmd = new System.Windows.Forms.Button(); + this.EditCfg = new System.Windows.Forms.Button(); + this.PlayerManagerBtn = new System.Windows.Forms.Button(); + this.EditStCmd = new System.Windows.Forms.Button(); + this.ManPacks = new System.Windows.Forms.Button(); + this.SingBackup = new System.Windows.Forms.Button(); + this.RestartSrv = new System.Windows.Forms.Button(); + this.BackupManagerBtn = new System.Windows.Forms.Button(); + this.SvcLog = new System.Windows.Forms.CheckBox(); + this.ServerInfoBox = new System.Windows.Forms.TextBox(); + this.newSrvBtn = new System.Windows.Forms.Button(); + this.scrollLockChkBox = new System.Windows.Forms.CheckBox(); + this.nbtStudioBtn = new System.Windows.Forms.Button(); + this.clientConfigBtn = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // Connect + // + this.Connect.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.Connect.Location = new System.Drawing.Point(622, 57); + this.Connect.Name = "Connect"; + this.Connect.Size = new System.Drawing.Size(170, 25); + this.Connect.TabIndex = 0; + this.Connect.Text = "Connect"; + this.Connect.UseVisualStyleBackColor = true; + this.Connect.Click += new System.EventHandler(this.Connect_Click); + // + // HostInfoLabel + // + this.HostInfoLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.HostInfoLabel.AutoSize = true; + this.HostInfoLabel.Location = new System.Drawing.Point(620, 12); + this.HostInfoLabel.Name = "HostInfoLabel"; + this.HostInfoLabel.Size = new System.Drawing.Size(87, 13); + this.HostInfoLabel.TabIndex = 1; + this.HostInfoLabel.Text = "HostConnectInfo"; + // + // HostListBox + // + this.HostListBox.AllowDrop = true; + this.HostListBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.HostListBox.FormattingEnabled = true; + this.HostListBox.Location = new System.Drawing.Point(622, 28); + this.HostListBox.Name = "HostListBox"; + this.HostListBox.Size = new System.Drawing.Size(355, 21); + this.HostListBox.TabIndex = 2; + this.HostListBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.HostListBox_KeyPress); + // + // LogBox + // + this.LogBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.LogBox.Location = new System.Drawing.Point(12, 28); + this.LogBox.Multiline = true; + this.LogBox.Name = "LogBox"; + this.LogBox.ReadOnly = true; + this.LogBox.ScrollBars = System.Windows.Forms.ScrollBars.Both; + this.LogBox.Size = new System.Drawing.Size(580, 361); + this.LogBox.TabIndex = 3; + this.LogBox.WordWrap = false; + // + // ServerSelectBox + // + this.ServerSelectBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Right))); + this.ServerSelectBox.FormattingEnabled = true; + this.ServerSelectBox.Location = new System.Drawing.Point(808, 96); + this.ServerSelectBox.Name = "ServerSelectBox"; + this.ServerSelectBox.Size = new System.Drawing.Size(170, 95); + this.ServerSelectBox.TabIndex = 4; + this.ServerSelectBox.SelectedIndexChanged += new System.EventHandler(this.ServerSelectBox_SelectedIndexChanged); + // + // Disconn + // + this.Disconn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.Disconn.Enabled = false; + this.Disconn.Location = new System.Drawing.Point(808, 57); + this.Disconn.Name = "Disconn"; + this.Disconn.Size = new System.Drawing.Size(170, 25); + this.Disconn.TabIndex = 5; + this.Disconn.Text = "Disconnect"; + this.Disconn.UseVisualStyleBackColor = true; + this.Disconn.Click += new System.EventHandler(this.Disconn_Click); + // + // EditGlobals + // + this.EditGlobals.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.EditGlobals.Enabled = false; + this.EditGlobals.Location = new System.Drawing.Point(808, 266); + this.EditGlobals.Name = "EditGlobals"; + this.EditGlobals.Size = new System.Drawing.Size(170, 23); + this.EditGlobals.TabIndex = 8; + this.EditGlobals.Text = "Edit global service settings"; + this.EditGlobals.UseVisualStyleBackColor = true; + this.EditGlobals.Click += new System.EventHandler(this.EditGlobals_Click); + // + // removeSrvBtn + // + this.removeSrvBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.removeSrvBtn.Enabled = false; + this.removeSrvBtn.Location = new System.Drawing.Point(808, 353); + this.removeSrvBtn.Name = "removeSrvBtn"; + this.removeSrvBtn.Size = new System.Drawing.Size(170, 23); + this.removeSrvBtn.TabIndex = 9; + this.removeSrvBtn.Text = "Remove selected server"; + this.removeSrvBtn.UseVisualStyleBackColor = true; + this.removeSrvBtn.Click += new System.EventHandler(this.RemoveSrvBtn_Click); + // + // ChkUpdates + // + this.ChkUpdates.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.ChkUpdates.Enabled = false; + this.ChkUpdates.Location = new System.Drawing.Point(808, 294); + this.ChkUpdates.Name = "ChkUpdates"; + this.ChkUpdates.Size = new System.Drawing.Size(170, 23); + this.ChkUpdates.TabIndex = 10; + this.ChkUpdates.Text = "Check for updates"; + this.ChkUpdates.UseVisualStyleBackColor = true; + this.ChkUpdates.Click += new System.EventHandler(this.ChkUpdates_Click); + // + // GlobBackup + // + this.GlobBackup.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.GlobBackup.Enabled = false; + this.GlobBackup.Location = new System.Drawing.Point(808, 237); + this.GlobBackup.Name = "GlobBackup"; + this.GlobBackup.Size = new System.Drawing.Size(170, 23); + this.GlobBackup.TabIndex = 11; + this.GlobBackup.Text = "Backup all servers"; + this.GlobBackup.UseVisualStyleBackColor = true; + this.GlobBackup.Click += new System.EventHandler(this.GlobBackup_Click); + // + // cmdTextBox + // + this.cmdTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.cmdTextBox.Enabled = false; + this.cmdTextBox.Location = new System.Drawing.Point(446, 429); + this.cmdTextBox.Name = "cmdTextBox"; + this.cmdTextBox.Size = new System.Drawing.Size(355, 20); + this.cmdTextBox.TabIndex = 12; + this.cmdTextBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.cmdTextBox_KeyPress); + // + // SendCmd + // + this.SendCmd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.SendCmd.Enabled = false; + this.SendCmd.Location = new System.Drawing.Point(808, 426); + this.SendCmd.Name = "SendCmd"; + this.SendCmd.Size = new System.Drawing.Size(170, 23); + this.SendCmd.TabIndex = 13; + this.SendCmd.Text = "Send command to server"; + this.SendCmd.UseVisualStyleBackColor = true; + this.SendCmd.Click += new System.EventHandler(this.SendCmd_Click); + // + // EditCfg + // + this.EditCfg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.EditCfg.Enabled = false; + this.EditCfg.Location = new System.Drawing.Point(622, 208); + this.EditCfg.Name = "EditCfg"; + this.EditCfg.Size = new System.Drawing.Size(170, 23); + this.EditCfg.TabIndex = 15; + this.EditCfg.Text = "Edit server config"; + this.EditCfg.UseVisualStyleBackColor = true; + this.EditCfg.Click += new System.EventHandler(this.EditCfg_Click); + // + // PlayerManagerBtn + // + this.PlayerManagerBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.PlayerManagerBtn.Enabled = false; + this.PlayerManagerBtn.Location = new System.Drawing.Point(622, 382); + this.PlayerManagerBtn.Name = "PlayerManagerBtn"; + this.PlayerManagerBtn.Size = new System.Drawing.Size(170, 23); + this.PlayerManagerBtn.TabIndex = 16; + this.PlayerManagerBtn.Text = "Player Manager"; + this.PlayerManagerBtn.UseVisualStyleBackColor = true; + this.PlayerManagerBtn.Click += new System.EventHandler(this.PlayerManager_Click); + // + // EditStCmd + // + this.EditStCmd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.EditStCmd.Enabled = false; + this.EditStCmd.Location = new System.Drawing.Point(622, 237); + this.EditStCmd.Name = "EditStCmd"; + this.EditStCmd.Size = new System.Drawing.Size(170, 23); + this.EditStCmd.TabIndex = 18; + this.EditStCmd.Text = "Edit start commands"; + this.EditStCmd.UseVisualStyleBackColor = true; + this.EditStCmd.Click += new System.EventHandler(this.EditStCmd_Click); + // + // ManPacks + // + this.ManPacks.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.ManPacks.Enabled = false; + this.ManPacks.Location = new System.Drawing.Point(622, 353); + this.ManPacks.Name = "ManPacks"; + this.ManPacks.Size = new System.Drawing.Size(170, 23); + this.ManPacks.TabIndex = 19; + this.ManPacks.Text = "R/B Pack Manager"; + this.ManPacks.UseVisualStyleBackColor = true; + this.ManPacks.Click += new System.EventHandler(this.ManPacks_Click); + // + // SingBackup + // + this.SingBackup.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.SingBackup.Enabled = false; + this.SingBackup.Location = new System.Drawing.Point(622, 266); + this.SingBackup.Name = "SingBackup"; + this.SingBackup.Size = new System.Drawing.Size(170, 23); + this.SingBackup.TabIndex = 20; + this.SingBackup.Text = "Backup selected server"; + this.SingBackup.UseVisualStyleBackColor = true; + this.SingBackup.Click += new System.EventHandler(this.SingBackup_Click); + // + // RestartSrv + // + this.RestartSrv.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.RestartSrv.Enabled = false; + this.RestartSrv.Location = new System.Drawing.Point(622, 294); + this.RestartSrv.Name = "RestartSrv"; + this.RestartSrv.Size = new System.Drawing.Size(170, 23); + this.RestartSrv.TabIndex = 21; + this.RestartSrv.Text = "Restart selected server"; + this.RestartSrv.UseVisualStyleBackColor = true; + this.RestartSrv.Click += new System.EventHandler(this.RestartSrv_Click); + // + // BackupManagerBtn + // + this.BackupManagerBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.BackupManagerBtn.Enabled = false; + this.BackupManagerBtn.Location = new System.Drawing.Point(622, 324); + this.BackupManagerBtn.Name = "BackupManagerBtn"; + this.BackupManagerBtn.Size = new System.Drawing.Size(170, 23); + this.BackupManagerBtn.TabIndex = 22; + this.BackupManagerBtn.Text = "Backup Manager"; + this.BackupManagerBtn.UseVisualStyleBackColor = true; + this.BackupManagerBtn.Click += new System.EventHandler(this.BackupManager_Click); + // + // SvcLog + // + this.SvcLog.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.SvcLog.Enabled = false; + this.SvcLog.Location = new System.Drawing.Point(17, 395); + this.SvcLog.Name = "SvcLog"; + this.SvcLog.RightToLeft = System.Windows.Forms.RightToLeft.No; + this.SvcLog.Size = new System.Drawing.Size(131, 26); + this.SvcLog.TabIndex = 24; + this.SvcLog.Text = "Switch to service logs"; + this.SvcLog.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + this.SvcLog.UseVisualStyleBackColor = true; + // + // ServerInfoBox + // + this.ServerInfoBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Right))); + this.ServerInfoBox.Location = new System.Drawing.Point(622, 96); + this.ServerInfoBox.Multiline = true; + this.ServerInfoBox.Name = "ServerInfoBox"; + this.ServerInfoBox.ReadOnly = true; + this.ServerInfoBox.Size = new System.Drawing.Size(170, 95); + this.ServerInfoBox.TabIndex = 25; + // + // newSrvBtn + // + this.newSrvBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.newSrvBtn.Enabled = false; + this.newSrvBtn.Location = new System.Drawing.Point(808, 208); + this.newSrvBtn.Name = "newSrvBtn"; + this.newSrvBtn.Size = new System.Drawing.Size(170, 23); + this.newSrvBtn.TabIndex = 26; + this.newSrvBtn.Text = "Deploy new server"; + this.newSrvBtn.UseVisualStyleBackColor = true; + this.newSrvBtn.Click += new System.EventHandler(this.newSrvBtn_Click); + // + // scrollLockChkBox + // + this.scrollLockChkBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.scrollLockChkBox.Enabled = false; + this.scrollLockChkBox.Location = new System.Drawing.Point(464, 395); + this.scrollLockChkBox.Name = "scrollLockChkBox"; + this.scrollLockChkBox.RightToLeft = System.Windows.Forms.RightToLeft.No; + this.scrollLockChkBox.Size = new System.Drawing.Size(131, 26); + this.scrollLockChkBox.TabIndex = 27; + this.scrollLockChkBox.Text = "Lock scrollbar to end"; + this.scrollLockChkBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + this.scrollLockChkBox.UseVisualStyleBackColor = true; + this.scrollLockChkBox.CheckedChanged += new System.EventHandler(this.scrollLockChkBox_CheckedChanged); + // + // nbtStudioBtn + // + this.nbtStudioBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.nbtStudioBtn.Enabled = false; + this.nbtStudioBtn.Location = new System.Drawing.Point(808, 324); + this.nbtStudioBtn.Name = "nbtStudioBtn"; + this.nbtStudioBtn.Size = new System.Drawing.Size(170, 23); + this.nbtStudioBtn.TabIndex = 28; + this.nbtStudioBtn.Text = "Edit world via NBTStudio"; + this.nbtStudioBtn.UseVisualStyleBackColor = true; + this.nbtStudioBtn.Click += new System.EventHandler(this.nbtStudioBtn_Click); + // + // clientConfigBtn + // + this.clientConfigBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.clientConfigBtn.Location = new System.Drawing.Point(808, 382); + this.clientConfigBtn.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.clientConfigBtn.Name = "clientConfigBtn"; + this.clientConfigBtn.Size = new System.Drawing.Size(170, 23); + this.clientConfigBtn.TabIndex = 29; + this.clientConfigBtn.Text = "Edit client config"; + this.clientConfigBtn.UseVisualStyleBackColor = true; + this.clientConfigBtn.Click += new System.EventHandler(this.clientConfigBtn_Click); + // + // MainWindow + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(989, 467); + this.Controls.Add(this.clientConfigBtn); + this.Controls.Add(this.nbtStudioBtn); + this.Controls.Add(this.scrollLockChkBox); + this.Controls.Add(this.newSrvBtn); + this.Controls.Add(this.ServerInfoBox); + this.Controls.Add(this.SvcLog); + this.Controls.Add(this.BackupManagerBtn); + this.Controls.Add(this.RestartSrv); + this.Controls.Add(this.SingBackup); + this.Controls.Add(this.ManPacks); + this.Controls.Add(this.EditStCmd); + this.Controls.Add(this.PlayerManagerBtn); + this.Controls.Add(this.EditCfg); + this.Controls.Add(this.SendCmd); + this.Controls.Add(this.cmdTextBox); + this.Controls.Add(this.GlobBackup); + this.Controls.Add(this.ChkUpdates); + this.Controls.Add(this.removeSrvBtn); + this.Controls.Add(this.EditGlobals); + this.Controls.Add(this.Disconn); + this.Controls.Add(this.ServerSelectBox); + this.Controls.Add(this.LogBox); + this.Controls.Add(this.HostListBox); + this.Controls.Add(this.HostInfoLabel); + this.Controls.Add(this.Connect); + this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.Name = "MainWindow"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Bedrock Service Management"; + this.Load += new System.EventHandler(this.MainWindow_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button Connect; + private System.Windows.Forms.Label HostInfoLabel; + public System.Windows.Forms.TextBox LogBox; + private System.Windows.Forms.ListBox ServerSelectBox; + private System.Windows.Forms.Button Disconn; + private System.Windows.Forms.Button EditGlobals; + private System.Windows.Forms.Button removeSrvBtn; + private System.Windows.Forms.Button ChkUpdates; + private System.Windows.Forms.Button GlobBackup; + private System.Windows.Forms.TextBox cmdTextBox; + private System.Windows.Forms.Button SendCmd; + private System.Windows.Forms.Button EditCfg; + private System.Windows.Forms.Button PlayerManagerBtn; + private System.Windows.Forms.Button EditStCmd; + private System.Windows.Forms.Button ManPacks; + private System.Windows.Forms.Button SingBackup; + private System.Windows.Forms.Button RestartSrv; + private System.Windows.Forms.Button BackupManagerBtn; + private System.Windows.Forms.CheckBox SvcLog; + private System.Windows.Forms.TextBox ServerInfoBox; + public System.Windows.Forms.ComboBox HostListBox; + private System.Windows.Forms.Button newSrvBtn; + private System.Windows.Forms.CheckBox scrollLockChkBox; + private System.Windows.Forms.Button nbtStudioBtn; + private System.Windows.Forms.Button clientConfigBtn; + } +} + diff --git a/BedrockService.backup/Client/Forms/MainWindow.cs b/BedrockService.backup/Client/Forms/MainWindow.cs new file mode 100644 index 00000000..2420abe2 --- /dev/null +++ b/BedrockService.backup/Client/Forms/MainWindow.cs @@ -0,0 +1,654 @@ +using BedrockService.Client.Management; +using BedrockService.Shared.Classes; +using BedrockService.Shared.Interfaces; +using Newtonsoft.Json; +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text; +using System.Timers; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace BedrockService.Client.Forms +{ + public partial class MainWindow : Form + { + public IServiceConfiguration connectedHost; + public IServerConfiguration selectedServer; + public IClientSideServiceConfiguration clientSideServiceConfiguration; + public bool ShowsSvcLog = false; + public bool ServerBusy = false; + private PropEditorForm _editDialog; + private int _connectTimeout; + private bool _followTail = false; + private const int _connectTimeoutLimit = 3; + private readonly ILogger _logger; + private readonly IProcessInfo _processInfo; + private readonly System.Timers.Timer _connectTimer = new System.Timers.Timer(100.0); + private readonly LogManager _logManager; + private readonly ConfigManager _configManager; + public MainWindow(IProcessInfo processInfo, ILogger logger) + { + _processInfo = processInfo; + _logger = logger; + _logManager = new LogManager(_logger); + _configManager = new ConfigManager(_logger); + InitializeComponent(); + InitForm(); + SvcLog.CheckedChanged += SvcLog_CheckedChanged; + _connectTimer.Elapsed += ConnectTimer_Elapsed; + } + + private void ConnectTimer_Elapsed(object sender, ElapsedEventArgs e) + { + if (_connectTimer.Enabled && !FormManager.TCPClient.Connected) + { + if (_connectTimer.Interval == 100.0) + _connectTimer.Interval = 5000.0; + Invoke((MethodInvoker)delegate { FormManager.TCPClient.ConnectHost(_configManager.HostConnectList.FirstOrDefault(host => host.GetHostName() == (string)HostListBox.SelectedItem)); }); + if (connectedHost != null && FormManager.TCPClient.Connected) + { + ServerBusy = false; + Invoke((MethodInvoker)delegate { ComponentEnableManager(); }); + _connectTimer.Enabled = false; + _connectTimer.Stop(); + _connectTimer.Close(); + return; + } + _connectTimeout++; + if (_connectTimeout >= _connectTimeoutLimit) + { + Invoke((MethodInvoker)delegate + { + RefreshServerContents(); + HostInfoLabel.Text = $"Failed to connect to host!"; + Connect.Enabled = true; + ComponentEnableManager(); + _connectTimer.Enabled = false; + _connectTimer.Stop(); + _connectTimer.Close(); + return; + }); + } + } + } + + #region Win32 API +#pragma warning disable 649 +#pragma warning disable 169 + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool GetScrollInfo(IntPtr hWnd, int scrollDirection, ref ScrollInfo si); //Thanks goes out to stever@GitHub for this! + + [DllImport("user32.dll")] + static extern int SetScrollInfo(IntPtr hWnd, int scrollDirection, [In] ref ScrollInfo si, bool redraw); + + [DllImport("user32.dll")] + static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); + + struct ScrollInfo + { + public uint Size; + public uint Mask; + public int Min; + public int Max; + public uint Page; + public int Pos; + public int TrackPos; + } + + enum ScrollInfoMask + { + Range = 0x1, + Page = 0x2, + Pos = 0x4, + DisableEndScroll = 0x8, + TrackPos = 0x10, + All = Range + Page + Pos + TrackPos + } + + enum ScrollBarDirection + { + Horizontal = 0, + Vertical = 1, + Ctl = 2, + Both = 3 + } + + new const int VerticalScroll = 277; + const int LineUp = 0; + const int LineDown = 1; + const int ThumbPosition = 4; + const int Thumbtrack = 5; + const int ScrollTop = 6; + const int ScrolBottom = 7; + const int EndScroll = 8; + + const int SetRedraw = 0x000B; + const int User = 0x400; + const int GetEventMask = (User + 59); + const int SetEventMask = (User + 69); + +#pragma warning restore 649 +#pragma warning restore 169 + #endregion + + + [STAThread] + public static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.ApplicationExit += OnExit; + Application.Run(FormManager.MainWindow); + } + + public void RefreshServerContents() + { + Invoke((MethodInvoker)delegate + { + Refresh(); + return; + }); + } + + public override void Refresh() + { + HostInfoLabel.Text = $"Connected to host:"; + ServerSelectBox.Items.Clear(); + if(connectedHost != null) + { + _logManager.InitLogThread(connectedHost); + foreach (ServerInfo server in connectedHost.GetServerList()) + ServerSelectBox.Items.Add(server.ServerName); + if(ServerSelectBox.Items.Count > 0) + { + ServerSelectBox.SelectedIndex = 0; + selectedServer = connectedHost.GetServerInfoByName((string)ServerSelectBox.SelectedItem); + } + } + ServerSelectBox.Refresh(); + base.Refresh(); + } + + public void InitForm() + { + _configManager.LoadConfigs(); + HostListBox.Items.Clear(); + foreach (IClientSideServiceConfiguration host in _configManager.HostConnectList) + { + HostListBox.Items.Add(host.GetHostName()); + } + if(HostListBox.Items.Count > 0) + { + HostListBox.SelectedIndex = 0; + } + HostListBox.Refresh(); + FormClosing += MainWindow_FormClosing; + } + + public void HeartbeatFailDisconnect() + { + Disconn_Click(null, null); + try + { + HostInfoLabel.Invoke((MethodInvoker)delegate { HostInfoLabel.Text = "Lost connection to host!"; }); + ServerInfoBox.Invoke((MethodInvoker)delegate { ServerInfoBox.Text = "Lost connection to host!"; }); + ServerBusy = false; + ComponentEnableManager(); + } + catch (InvalidOperationException) { } + + selectedServer = null; + connectedHost = null; + } + + public void UpdateLogBox(string contents) + { + int curPos = HorizontalScrollPosition; + LogBox.Text = contents; + HorizontalScrollPosition = curPos; + if (_followTail) + ScrollToEnd(); + } + + private static void OnExit(object sender, EventArgs e) + { + FormManager.TCPClient.Dispose(); + } + + private void SvcLog_CheckedChanged(object sender, EventArgs e) + { + ShowsSvcLog = SvcLog.Checked; + } + + private void MainWindow_FormClosing(object sender, FormClosingEventArgs e) + { + _logger.AppendLine("Stopping log thread..."); + if (_logManager.StopLogThread()) + { + _logger.AppendLine("Sending disconnect msg..."); + FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Service, NetworkMessageTypes.Disconnect); + _logger.AppendLine("Closing connection..."); + FormManager.TCPClient.CloseConnection(); + selectedServer = null; + connectedHost = null; + } + } + + private void Connect_Click(object sender, EventArgs e) + { + HostInfoLabel.Text = $"Connecting to host {(string)HostListBox.SelectedItem}..."; + Connect.Enabled = false; + _connectTimeout = 0; + _connectTimer.Interval = 100.0; + _connectTimer.Start(); + } + + private void ServerSelectBox_SelectedIndexChanged(object sender, EventArgs e) + { + if (connectedHost != null) + { + foreach (ServerInfo server in connectedHost.GetServerList()) + { + if (ServerSelectBox.SelectedItem != null && ServerSelectBox.SelectedItem.ToString() == server.GetServerName()) + { + selectedServer = server; + ServerInfoBox.Text = server.GetServerName(); + ComponentEnableManager(); + } + } + } + } + + private void SingBackup_Click(object sender, EventArgs e) + { + FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Server, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.Backup); + DisableUI(); + } + + private void EditCfg_Click(object sender, EventArgs e) + { + _editDialog = new PropEditorForm(); + _editDialog.PopulateBoxes(selectedServer.GetAllProps()); + if (_editDialog.ShowDialog() == DialogResult.OK) + { + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(_editDialog.workingProps, Formatting.Indented, settings)); + FormManager.TCPClient.SendData(serializeToBytes, NetworkMessageSource.Client, NetworkMessageDestination.Server, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.PropUpdate); + selectedServer.SetAllProps(_editDialog.workingProps); + _editDialog.Close(); + _editDialog.Dispose(); + RestartSrv_Click(null, null); + } + } + + private void RestartSrv_Click(object sender, EventArgs e) + { + FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Server, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.Restart); + DisableUI(); + } + + private void EditGlobals_Click(object sender, EventArgs e) + { + _editDialog = new PropEditorForm(); + _editDialog.PopulateBoxes(connectedHost.GetAllProps()); + if (_editDialog.ShowDialog() == DialogResult.OK) + { + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(_editDialog.workingProps, Formatting.Indented, settings)); + FormManager.TCPClient.SendData(serializeToBytes, NetworkMessageSource.Client, NetworkMessageDestination.Service, NetworkMessageTypes.PropUpdate); + connectedHost.SetAllProps(_editDialog.workingProps); + _editDialog.Close(); + _editDialog.Dispose(); + RestartSrv_Click(null, null); + } + } + + private void GlobBackup_Click(object sender, EventArgs e) + { + FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Service, NetworkMessageTypes.BackupAll); + DisableUI(); + } + + private void newSrvBtn_Click(object sender, EventArgs e) + { + if(clientSideServiceConfiguration == null) + { + clientSideServiceConfiguration = _configManager.HostConnectList.First(host => host.GetHostName() == HostListBox.Text); + } + AddNewServerForm newServerForm = new AddNewServerForm(clientSideServiceConfiguration, connectedHost.GetServerList()); + if (newServerForm.ShowDialog() == DialogResult.OK) + { + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(newServerForm.DefaultProps, Formatting.Indented, settings)); + FormManager.TCPClient.SendData(serializeToBytes, NetworkMessageSource.Client, NetworkMessageDestination.Service, NetworkMessageTypes.AddNewServer); + newServerForm.Close(); + newServerForm.Dispose(); + } + } + + private void RemoveSrvBtn_Click(object sender, EventArgs e) + { + FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Service, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.RemoveServer, NetworkMessageFlags.RemoveAll); + DisableUI(); + } + + private void PlayerManager_Click(object sender, EventArgs e) + { + FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Server, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.PlayersRequest); + WaitForServerData().Wait(); + FormManager.TCPClient.PlayerInfoArrived = false; + PlayerManagerForm form = new PlayerManagerForm(selectedServer); + form.Show(); + } + + private void Disconn_Click(object sender, EventArgs e) + { + if (_logManager.StopLogThread()) + { + try + { + if (FormManager.TCPClient.Connected) + { + FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Service, NetworkMessageTypes.Disconnect); + Thread.Sleep(500); + FormManager.TCPClient.CloseConnection(); + } + selectedServer = null; + connectedHost = null; + LogBox.Invoke((MethodInvoker)delegate { LogBox.Text = ""; }); + FormManager.MainWindow.Invoke((MethodInvoker)delegate + { + ComponentEnableManager(); + ServerSelectBox.Items.Clear(); + ServerSelectBox.SelectedIndex = -1; + ServerInfoBox.Text = ""; + HostInfoLabel.Text = $"Select a host below:"; + }); + } + catch (Exception) { } + + } + } + + private void SendCmd_Click(object sender, EventArgs e) + { + if (cmdTextBox.Text.Length > 0) + { + byte[] msg = Encoding.UTF8.GetBytes(cmdTextBox.Text); + FormManager.TCPClient.SendData(msg, NetworkMessageSource.Client, NetworkMessageDestination.Server, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.Command); + } + cmdTextBox.Text = ""; + } + + private void EditStCmd_Click(object sender, EventArgs e) + { + PropEditorForm editSrvDialog = new PropEditorForm(); + editSrvDialog.PopulateStartCmds(selectedServer.GetStartCommands()); + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(editSrvDialog.startCmds, Formatting.Indented, settings)); + if (editSrvDialog.ShowDialog() == DialogResult.OK) + { + DisableUI(); + FormManager.TCPClient.SendData(serializeToBytes, NetworkMessageSource.Client, NetworkMessageDestination.Service, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.StartCmdUpdate); + selectedServer.SetStartCommands(editSrvDialog.startCmds); + editSrvDialog.Close(); + editSrvDialog.Dispose(); + RestartSrv_Click(null, null); + } + } + + private void ChkUpdates_Click(object sender, EventArgs e) + { + FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Service, NetworkMessageTypes.CheckUpdates); + DisableUI(); + } + + private int HorizontalScrollPosition + { + get + { + ScrollInfo si = new ScrollInfo(); + si.Size = (uint)Marshal.SizeOf(si); + si.Mask = (uint)ScrollInfoMask.All; + GetScrollInfo(LogBox.Handle, (int)ScrollBarDirection.Vertical, ref si); + return si.Pos; + } + set + { + ScrollInfo si = new ScrollInfo(); + si.Size = (uint)Marshal.SizeOf(si); + si.Mask = (uint)ScrollInfoMask.All; + GetScrollInfo(LogBox.Handle, (int)ScrollBarDirection.Vertical, ref si); + si.Pos = value; + SetScrollInfo(LogBox.Handle, (int)ScrollBarDirection.Vertical, ref si, true); + SendMessage(LogBox.Handle, VerticalScroll, new IntPtr(Thumbtrack + 0x10000 * si.Pos), new IntPtr(0)); + } + } + + public void ScrollToEnd() + { + + // Get the current scroll info. + ScrollInfo si = new ScrollInfo(); + si.Size = (uint)Marshal.SizeOf(si); + si.Mask = (uint)ScrollInfoMask.All; + GetScrollInfo(LogBox.Handle, (int)ScrollBarDirection.Vertical, ref si); + + // Set the scroll position to maximum. + si.Pos = si.Max - (int)si.Page; + SetScrollInfo(LogBox.Handle, (int)ScrollBarDirection.Vertical, ref si, true); + SendMessage(LogBox.Handle, VerticalScroll, new IntPtr(Thumbtrack + 0x10000 * si.Pos), new IntPtr(0)); + + _followTail = true; + } + + public void PerformBackupTests() + { + HostListBox.SelectedIndex = 0; + Connect_Click(null, null); + GlobBackup_Click(null, null); + DisableUI(); + ServerSelectBox.SelectedIndex = 0; + FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Service, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.EnumBackups); + DisableUI().Wait(); + FormManager.TCPClient.EnumBackupsArrived = false; + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new string[] { FormManager.TCPClient.BackupList[0].ToString() }, Formatting.Indented, settings)); + FormManager.TCPClient.SendData(serializeToBytes, NetworkMessageSource.Client, NetworkMessageDestination.Service, FormManager.MainWindow.connectedHost.GetServerIndex(FormManager.MainWindow.selectedServer), NetworkMessageTypes.DelBackups); + } + + private void ComponentEnableManager() + { + Connect.Enabled = connectedHost == null; + Disconn.Enabled = connectedHost != null; + newSrvBtn.Enabled = connectedHost != null && !ServerBusy; + ChkUpdates.Enabled = connectedHost != null && !ServerBusy; + GlobBackup.Enabled = connectedHost != null && !ServerBusy; + EditGlobals.Enabled = connectedHost != null && !ServerBusy; + BackupManagerBtn.Enabled = (connectedHost != null && selectedServer != null && !ServerBusy); + nbtStudioBtn.Enabled = (connectedHost != null && selectedServer != null && !ServerBusy); + ManPacks.Enabled = (connectedHost != null && selectedServer != null && !ServerBusy); + scrollLockChkBox.Enabled = (connectedHost != null && selectedServer != null && !ServerBusy); + removeSrvBtn.Enabled = (connectedHost != null && selectedServer != null && !ServerBusy); + EditCfg.Enabled = (connectedHost != null && selectedServer != null && !ServerBusy); + PlayerManagerBtn.Enabled = (connectedHost != null && selectedServer != null && !ServerBusy); + EditStCmd.Enabled = (connectedHost != null && selectedServer != null && !ServerBusy); + SingBackup.Enabled = (connectedHost != null && selectedServer != null && !ServerBusy); + RestartSrv.Enabled = (connectedHost != null && selectedServer != null && !ServerBusy); + ServerInfoBox.Enabled = (connectedHost != null && selectedServer != null && !ServerBusy); + SendCmd.Enabled = (connectedHost != null && selectedServer != null && !ServerBusy); + cmdTextBox.Enabled = (connectedHost != null && selectedServer != null && !ServerBusy); + SvcLog.Enabled = (connectedHost != null && selectedServer != null && !ServerBusy); + } + + public Task DisableUI() + { + ServerBusy = true; + return Task.Run(() => + { + + Invoke((MethodInvoker)delegate { ComponentEnableManager(); }); + while (ServerBusy) + { + Task.Delay(250); + } + Invoke((MethodInvoker)delegate { ComponentEnableManager(); }); + }); + } + + public Task WaitForServerData() + { + return Task.Run(() => + { + while (!FormManager.TCPClient.EnumBackupsArrived && !FormManager.TCPClient.PlayerInfoArrived && FormManager.TCPClient.RecievedPacks == null) + { + Task.Delay(250); + } + }); + } + + public class ServerConnectException : Exception + { + public ServerConnectException() { } + + public ServerConnectException(string message) + : base(message) + { + + } + + public ServerConnectException(string message, Exception inner) + : base(message, inner) + { + + } + } + + private void scrollLockChkBox_CheckedChanged(object sender, EventArgs e) => _followTail = scrollLockChkBox.Checked; + + private void cmdTextBox_KeyPress(object sender, KeyPressEventArgs e) + { + if (e.KeyChar == (char)Keys.Enter) + { + SendCmd_Click(null, null); + } + } + + private void HostListBox_KeyPress(object sender, KeyPressEventArgs e) + { + if (e.KeyChar == (char)Keys.Enter) + { + Connect_Click(null, null); + } + } + + private void BackupManager_Click(object sender, EventArgs e) + { + using (PropEditorForm editDialog = new PropEditorForm()) + { + editDialog.EnableBackupManager(); + FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Service, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.EnumBackups); + DisableUI(); + WaitForServerData().Wait(); + FormManager.TCPClient.EnumBackupsArrived = false; + editDialog.PopulateBoxes(FormManager.TCPClient.BackupList); + if (editDialog.ShowDialog() == DialogResult.OK) + { + FormManager.TCPClient.SendData(Encoding.UTF8.GetBytes(editDialog.RollbackFolderName), NetworkMessageSource.Client, NetworkMessageDestination.Service, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.BackupRollback); + ServerBusy = true; + } + editDialog.Close(); + } + } + + private void ManPacks_Click(object sender, EventArgs e) + { + FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Server, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.PackList); + DisableUI(); + WaitForServerData().Wait(); + using (ManagePacksForms form = new ManagePacksForms(connectedHost.GetServerIndex(selectedServer), _logger, _processInfo)) + { + form.PopulateServerPacks(FormManager.TCPClient.RecievedPacks); + if (form.ShowDialog() == DialogResult.OK) + form.Close(); + } + FormManager.TCPClient.RecievedPacks = null; + } + + private void nbtStudioBtn_Click(object sender, EventArgs e) + { + if (string.IsNullOrEmpty(_configManager.NBTStudioPath)) + using (OpenFileDialog openFile = new OpenFileDialog()) + { + openFile.FileName = "NBTStudio.exe"; + openFile.Title = "Please locate NBT Studio executable..."; + openFile.Filter = "NBTStudio.exe|NBTStudio.exe"; + if (openFile.ShowDialog() == DialogResult.OK) + { + _configManager.NBTStudioPath = openFile.FileName; + _configManager.SaveConfigFile(); + } + } + ServerBusy = true; + FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Server, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.LevelEditRequest); + DisableUI(); + using (Process nbtStudioProcess = new Process()) + { + string tempPath = $@"{Path.GetTempPath()}level.dat"; + nbtStudioProcess.StartInfo = new ProcessStartInfo(_configManager.NBTStudioPath, tempPath); + nbtStudioProcess.Start(); + nbtStudioProcess.WaitForExit(); + FormManager.TCPClient.SendData(File.ReadAllBytes(tempPath), NetworkMessageSource.Client, NetworkMessageDestination.Server, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.LevelEditFile); + } + ServerBusy = false; + } + + private void HostListBox_SelectedIndexChanged(object sender, EventArgs e) + { + if(HostListBox.SelectedIndex != -1) + { + clientSideServiceConfiguration = _configManager.HostConnectList.FirstOrDefault(host => host.GetHostName() == (string)HostListBox.SelectedItem); + } + } + + private void MainWindow_Load(object sender, EventArgs e) + { + + } + + private void clientConfigBtn_Click(object sender, EventArgs e) + { + using (ClientConfigForm form = new ClientConfigForm(_configManager)) + { + if(form.ShowDialog() == DialogResult.OK) + { + form.Close(); + InitForm(); + } + } + } + } +} diff --git a/BedrockService.backup/Client/Forms/MainWindow.resx b/BedrockService.backup/Client/Forms/MainWindow.resx new file mode 100644 index 00000000..26b2a12a --- /dev/null +++ b/BedrockService.backup/Client/Forms/MainWindow.resx @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + \ No newline at end of file diff --git a/BedrockService.backup/Client/Forms/ManagePacksForms.Designer.cs b/BedrockService.backup/Client/Forms/ManagePacksForms.Designer.cs new file mode 100644 index 00000000..3e09ec3a --- /dev/null +++ b/BedrockService.backup/Client/Forms/ManagePacksForms.Designer.cs @@ -0,0 +1,215 @@ + +namespace BedrockService.Client.Forms +{ + partial class ManagePacksForms + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.serverListBox = new System.Windows.Forms.ListBox(); + this.parsedPacksListBox = new System.Windows.Forms.ListBox(); + this.sendPacksBtn = new System.Windows.Forms.Button(); + this.sendAllBtn = new System.Windows.Forms.Button(); + this.removePackBtn = new System.Windows.Forms.Button(); + this.removeAllPacksBtn = new System.Windows.Forms.Button(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.selectedPackIcon = new System.Windows.Forms.PictureBox(); + this.openFileBtn = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + ((System.ComponentModel.ISupportInitialize)(this.selectedPackIcon)).BeginInit(); + this.SuspendLayout(); + // + // serverListBox + // + this.serverListBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.serverListBox.FormattingEnabled = true; + this.serverListBox.Location = new System.Drawing.Point(12, 82); + this.serverListBox.Name = "serverListBox"; + this.serverListBox.Size = new System.Drawing.Size(189, 251); + this.serverListBox.TabIndex = 0; + this.serverListBox.Click += new System.EventHandler(this.ListBox_SelectedIndexChanged); + // + // parsedPacksListBox + // + this.parsedPacksListBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Right))); + this.parsedPacksListBox.FormattingEnabled = true; + this.parsedPacksListBox.Location = new System.Drawing.Point(599, 82); + this.parsedPacksListBox.Name = "parsedPacksListBox"; + this.parsedPacksListBox.SelectionMode = System.Windows.Forms.SelectionMode.MultiSimple; + this.parsedPacksListBox.Size = new System.Drawing.Size(189, 251); + this.parsedPacksListBox.TabIndex = 1; + this.parsedPacksListBox.Click += new System.EventHandler(this.ListBox_SelectedIndexChanged); + // + // sendPacksBtn + // + this.sendPacksBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.sendPacksBtn.Location = new System.Drawing.Point(468, 82); + this.sendPacksBtn.Name = "sendPacksBtn"; + this.sendPacksBtn.Size = new System.Drawing.Size(125, 23); + this.sendPacksBtn.TabIndex = 2; + this.sendPacksBtn.Text = "Send selected packs"; + this.sendPacksBtn.UseVisualStyleBackColor = true; + this.sendPacksBtn.Click += new System.EventHandler(this.sendPacksBtn_Click); + // + // sendAllBtn + // + this.sendAllBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.sendAllBtn.Location = new System.Drawing.Point(468, 111); + this.sendAllBtn.Name = "sendAllBtn"; + this.sendAllBtn.Size = new System.Drawing.Size(125, 23); + this.sendAllBtn.TabIndex = 3; + this.sendAllBtn.Text = "Send all packs"; + this.sendAllBtn.UseVisualStyleBackColor = true; + this.sendAllBtn.Click += new System.EventHandler(this.sendAllBtn_Click); + // + // removePackBtn + // + this.removePackBtn.Location = new System.Drawing.Point(207, 82); + this.removePackBtn.Name = "removePackBtn"; + this.removePackBtn.Size = new System.Drawing.Size(119, 23); + this.removePackBtn.TabIndex = 4; + this.removePackBtn.Text = "Remove pack"; + this.removePackBtn.UseVisualStyleBackColor = true; + this.removePackBtn.Click += new System.EventHandler(this.removePackBtn_Click); + // + // removeAllPacksBtn + // + this.removeAllPacksBtn.Location = new System.Drawing.Point(207, 111); + this.removeAllPacksBtn.Name = "removeAllPacksBtn"; + this.removeAllPacksBtn.Size = new System.Drawing.Size(119, 23); + this.removeAllPacksBtn.TabIndex = 5; + this.removeAllPacksBtn.Text = "Remove all packs"; + this.removeAllPacksBtn.UseVisualStyleBackColor = true; + this.removeAllPacksBtn.Click += new System.EventHandler(this.removeAllPacksBtn_Click); + // + // textBox1 + // + this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.textBox1.Location = new System.Drawing.Point(288, 211); + this.textBox1.Multiline = true; + this.textBox1.Name = "textBox1"; + this.textBox1.ReadOnly = true; + this.textBox1.Size = new System.Drawing.Size(219, 122); + this.textBox1.TabIndex = 6; + // + // selectedPackIcon + // + this.selectedPackIcon.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.selectedPackIcon.Location = new System.Drawing.Point(332, 75); + this.selectedPackIcon.Name = "selectedPackIcon"; + this.selectedPackIcon.Size = new System.Drawing.Size(130, 130); + this.selectedPackIcon.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; + this.selectedPackIcon.TabIndex = 7; + this.selectedPackIcon.TabStop = false; + // + // openFileBtn + // + this.openFileBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.openFileBtn.Location = new System.Drawing.Point(599, 29); + this.openFileBtn.Name = "openFileBtn"; + this.openFileBtn.Size = new System.Drawing.Size(189, 23); + this.openFileBtn.TabIndex = 8; + this.openFileBtn.Text = "Open pack file(s)"; + this.openFileBtn.UseVisualStyleBackColor = true; + this.openFileBtn.Click += new System.EventHandler(this.openFileBtn_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 66); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(153, 13); + this.label1.TabIndex = 9; + this.label1.Text = "Current packs found on server:"; + // + // label2 + // + this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(596, 66); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(146, 13); + this.label2.TabIndex = 10; + this.label2.Text = "Packs found in archive file(s):"; + // + // label3 + // + this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(204, 9); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(418, 13); + this.label3.TabIndex = 11; + this.label3.Text = "!! NOTICE !! Send map pack alone, do not send all! Not all packs will parse serve" + + "r-side!"; + // + // ManagePacksForms + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(800, 450); + this.Controls.Add(this.label3); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Controls.Add(this.openFileBtn); + this.Controls.Add(this.selectedPackIcon); + this.Controls.Add(this.textBox1); + this.Controls.Add(this.removeAllPacksBtn); + this.Controls.Add(this.removePackBtn); + this.Controls.Add(this.sendAllBtn); + this.Controls.Add(this.sendPacksBtn); + this.Controls.Add(this.parsedPacksListBox); + this.Controls.Add(this.serverListBox); + this.Name = "ManagePacksForms"; + this.Text = "Form1"; + ((System.ComponentModel.ISupportInitialize)(this.selectedPackIcon)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.ListBox serverListBox; + private System.Windows.Forms.ListBox parsedPacksListBox; + private System.Windows.Forms.Button sendPacksBtn; + private System.Windows.Forms.Button sendAllBtn; + private System.Windows.Forms.Button removePackBtn; + private System.Windows.Forms.Button removeAllPacksBtn; + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.PictureBox selectedPackIcon; + private System.Windows.Forms.Button openFileBtn; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + } +} \ No newline at end of file diff --git a/BedrockService.backup/Client/Forms/ManagePacksForms.cs b/BedrockService.backup/Client/Forms/ManagePacksForms.cs new file mode 100644 index 00000000..29fbfe9f --- /dev/null +++ b/BedrockService.backup/Client/Forms/ManagePacksForms.cs @@ -0,0 +1,135 @@ +using BedrockService.Client.Management; +using BedrockService.Shared.Classes; +using BedrockService.Shared.Interfaces; +using BedrockService.Shared.PackParser; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.IO.Compression; +using System.Text; +using System.Windows.Forms; + +namespace BedrockService.Client.Forms +{ + public partial class ManagePacksForms : Form + { + private readonly byte ServerIndex = 0x00; + private readonly ILogger Logger; + private readonly IProcessInfo ProcessInfo; + private readonly DirectoryInfo PackExtractDir; + public ManagePacksForms(byte serverIndex, ILogger logger, IProcessInfo processInfo) + { + Logger = logger; + PackExtractDir = new DirectoryInfo($@"{processInfo.GetDirectory()}\Temp"); + ProcessInfo = processInfo; + ServerIndex = serverIndex; + InitializeComponent(); + } + + public void PopulateServerPacks(List packList) + { + foreach (MinecraftPackParser pack in packList) + foreach (MinecraftPackContainer container in pack.FoundPacks) + serverListBox.Items.Add(container); + } + + private void ListBox_SelectedIndexChanged(object sender, EventArgs e) + { + ListBox thisBox = (ListBox)sender; + if (thisBox == serverListBox) + parsedPacksListBox.SelectedIndex = -1; + if (thisBox == parsedPacksListBox) + serverListBox.SelectedIndex = -1; + if (thisBox.SelectedIndex != -1) + { + MinecraftPackContainer selectedPack = (MinecraftPackContainer)thisBox.SelectedItem; + if (selectedPack.IconBytes != null) + using (MemoryStream ms = new MemoryStream(selectedPack.IconBytes)) + { + selectedPackIcon.Image = Image.FromStream(ms); + } + if (selectedPack.JsonManifest != null) + textBox1.Text = $"{selectedPack.JsonManifest.header.name}\r\n{selectedPack.JsonManifest.header.description}\r\n{selectedPack.JsonManifest.header.uuid}\r\n{selectedPack.JsonManifest.header.version[0]}"; + else + textBox1.Text = selectedPack.PackContentLocation.Name; + } + } + + private void removePackBtn_Click(object sender, EventArgs e) + { + if (serverListBox.SelectedIndex != -1) + { + List temp = new List(); + temp.Add((MinecraftPackContainer)serverListBox.SelectedItem); + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + FormManager.TCPClient.SendData(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(temp, Formatting.Indented, settings)), NetworkMessageSource.Client, NetworkMessageDestination.Server, ServerIndex, NetworkMessageTypes.RemovePack); + serverListBox.Items.Remove(temp[0]); + } + + } + + private void removeAllPacksBtn_Click(object sender, EventArgs e) + { + List temp = new List(); + foreach (object item in serverListBox.Items) + temp.Add((MinecraftPackContainer)item); + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + FormManager.TCPClient.SendData(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(temp, Formatting.Indented, settings)), NetworkMessageSource.Client, NetworkMessageDestination.Server, ServerIndex, NetworkMessageTypes.RemovePack); + serverListBox.Items.Clear(); + } + + private void sendPacksBtn_Click(object sender, EventArgs e) + { + if (parsedPacksListBox.SelectedIndex != -1) + { + object[] items = new object[parsedPacksListBox.SelectedItems.Count]; + parsedPacksListBox.SelectedItems.CopyTo(items, 0); + SendPacks(items); + } + } + + private void sendAllBtn_Click(object sender, EventArgs e) + { + object[] items = new object[parsedPacksListBox.Items.Count]; + parsedPacksListBox.Items.CopyTo(items, 0); + SendPacks(items); + } + + private void openFileBtn_Click(object sender, EventArgs e) + { + OpenFileDialog openFileDialog = new OpenFileDialog(); + openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + openFileDialog.Filter = "MC pack file (.MCWORLD, .MCPACK, .MCADDON, .Zip)|*.mcworld;*.mcpack;*.mcaddon;*.zip"; + openFileDialog.Title = "Select pack file(s)"; + openFileDialog.Multiselect = true; + if (openFileDialog.ShowDialog() == DialogResult.OK) + { + MinecraftPackParser parser = new MinecraftPackParser(openFileDialog.FileNames, PackExtractDir, Logger, ProcessInfo); + parsedPacksListBox.Items.Clear(); + foreach (MinecraftPackContainer container in parser.FoundPacks) + parsedPacksListBox.Items.Add(container); + } + } + + private void SendPacks(object[] packList) + { + foreach (MinecraftPackContainer container in packList) + { + Directory.CreateDirectory($@"{PackExtractDir.FullName}\ZipTemp"); + container.PackContentLocation.MoveTo($@"{PackExtractDir.FullName}\ZipTemp\{container.PackContentLocation.Name}"); + container.PackContentLocation = new DirectoryInfo($@"{PackExtractDir.FullName}\ZipTemp\{container.PackContentLocation.Name}"); + } + ZipFile.CreateFromDirectory($@"{PackExtractDir.FullName}\ZipTemp", $@"{PackExtractDir.FullName}\SendZip.zip"); + FormManager.TCPClient.SendData(File.ReadAllBytes($@"{PackExtractDir.FullName}\SendZip.zip"), NetworkMessageSource.Client, NetworkMessageDestination.Server, ServerIndex, NetworkMessageTypes.PackFile); + parsedPacksListBox.Items.Clear(); + } + } +} diff --git a/BedrockService.backup/Client/Forms/ManagePacksForms.resx b/BedrockService.backup/Client/Forms/ManagePacksForms.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/BedrockService.backup/Client/Forms/ManagePacksForms.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BedrockService.backup/Client/Forms/NewPlayerRegistrationForm.Designer.cs b/BedrockService.backup/Client/Forms/NewPlayerRegistrationForm.Designer.cs new file mode 100644 index 00000000..66d091df --- /dev/null +++ b/BedrockService.backup/Client/Forms/NewPlayerRegistrationForm.Designer.cs @@ -0,0 +1,182 @@ + +namespace BedrockService.Client.Forms +{ + partial class NewPlayerRegistrationForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label2 = new System.Windows.Forms.Label(); + this.xuidTextBox = new System.Windows.Forms.TextBox(); + this.usernameTextBox = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.permissionComboBox = new System.Windows.Forms.ComboBox(); + this.whitelistedChkBox = new System.Windows.Forms.CheckBox(); + this.ignoreLimitChkBox = new System.Windows.Forms.CheckBox(); + this.label6 = new System.Windows.Forms.Label(); + this.button1 = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(70, 33); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(36, 13); + this.label2.TabIndex = 1; + this.label2.Text = "XUID:"; + // + // xuidTextBox + // + this.xuidTextBox.Location = new System.Drawing.Point(111, 30); + this.xuidTextBox.Name = "xuidTextBox"; + this.xuidTextBox.Size = new System.Drawing.Size(185, 20); + this.xuidTextBox.TabIndex = 2; + // + // usernameTextBox + // + this.usernameTextBox.Location = new System.Drawing.Point(111, 56); + this.usernameTextBox.Name = "usernameTextBox"; + this.usernameTextBox.Size = new System.Drawing.Size(185, 20); + this.usernameTextBox.TabIndex = 4; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(48, 59); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(58, 13); + this.label3.TabIndex = 3; + this.label3.Text = "Username:"; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(46, 85); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(60, 13); + this.label4.TabIndex = 5; + this.label4.Text = "Permission:"; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(40, 109); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(65, 13); + this.label5.TabIndex = 6; + this.label5.Text = "Whitelisted?"; + // + // permissionComboBox + // + this.permissionComboBox.FormattingEnabled = true; + this.permissionComboBox.Items.AddRange(new object[] { + "visitor", + "member", + "operator"}); + this.permissionComboBox.Location = new System.Drawing.Point(111, 82); + this.permissionComboBox.Name = "permissionComboBox"; + this.permissionComboBox.Size = new System.Drawing.Size(185, 21); + this.permissionComboBox.TabIndex = 7; + // + // whitelistedChkBox + // + this.whitelistedChkBox.AutoSize = true; + this.whitelistedChkBox.Location = new System.Drawing.Point(111, 109); + this.whitelistedChkBox.Name = "whitelistedChkBox"; + this.whitelistedChkBox.Size = new System.Drawing.Size(15, 14); + this.whitelistedChkBox.TabIndex = 8; + this.whitelistedChkBox.UseVisualStyleBackColor = true; + // + // ignoreLimitChkBox + // + this.ignoreLimitChkBox.AutoSize = true; + this.ignoreLimitChkBox.Location = new System.Drawing.Point(111, 132); + this.ignoreLimitChkBox.Name = "ignoreLimitChkBox"; + this.ignoreLimitChkBox.Size = new System.Drawing.Size(15, 14); + this.ignoreLimitChkBox.TabIndex = 9; + this.ignoreLimitChkBox.UseVisualStyleBackColor = true; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(5, 132); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(101, 13); + this.label6.TabIndex = 10; + this.label6.Text = "Ignore max players?"; + // + // button1 + // + this.button1.Location = new System.Drawing.Point(221, 123); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(75, 25); + this.button1.TabIndex = 11; + this.button1.Text = "Save"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.saveClick); + // + // NewPlayerRegistrationForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(323, 171); + this.Controls.Add(this.button1); + this.Controls.Add(this.label6); + this.Controls.Add(this.ignoreLimitChkBox); + this.Controls.Add(this.whitelistedChkBox); + this.Controls.Add(this.permissionComboBox); + this.Controls.Add(this.label5); + this.Controls.Add(this.label4); + this.Controls.Add(this.usernameTextBox); + this.Controls.Add(this.label3); + this.Controls.Add(this.xuidTextBox); + this.Controls.Add(this.label2); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "NewPlayerRegistrationForm"; + this.Text = "New Player Registration Form"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox xuidTextBox; + private System.Windows.Forms.TextBox usernameTextBox; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.ComboBox permissionComboBox; + private System.Windows.Forms.CheckBox whitelistedChkBox; + private System.Windows.Forms.CheckBox ignoreLimitChkBox; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.Button button1; + } +} \ No newline at end of file diff --git a/BedrockService.backup/Client/Forms/NewPlayerRegistrationForm.cs b/BedrockService.backup/Client/Forms/NewPlayerRegistrationForm.cs new file mode 100644 index 00000000..2de19efc --- /dev/null +++ b/BedrockService.backup/Client/Forms/NewPlayerRegistrationForm.cs @@ -0,0 +1,26 @@ +using BedrockService.Shared.Classes; +using BedrockService.Shared.Interfaces; +using System; +using System.Windows.Forms; + +namespace BedrockService.Client.Forms +{ + public partial class NewPlayerRegistrationForm : Form + { + public IPlayer PlayerToAdd; + public NewPlayerRegistrationForm() + { + InitializeComponent(); + } + + private void saveClick(object sender, EventArgs e) + { + if (usernameTextBox.TextLength > 0 && xuidTextBox.TextLength == 16) + { + PlayerToAdd = new Player(xuidTextBox.Text, usernameTextBox.Text, DateTime.Now.Ticks.ToString(), "0", "0", whitelistedChkBox.Checked, permissionComboBox.SelectedItem.ToString(), ignoreLimitChkBox.Checked); + DialogResult = DialogResult.OK; + Close(); + } + } + } +} diff --git a/BedrockService.backup/Client/Forms/NewPlayerRegistrationForm.resx b/BedrockService.backup/Client/Forms/NewPlayerRegistrationForm.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/BedrockService.backup/Client/Forms/NewPlayerRegistrationForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BedrockService.backup/Client/Forms/PlayerManagerForm.Designer.cs b/BedrockService.backup/Client/Forms/PlayerManagerForm.Designer.cs new file mode 100644 index 00000000..d548d659 --- /dev/null +++ b/BedrockService.backup/Client/Forms/PlayerManagerForm.Designer.cs @@ -0,0 +1,153 @@ + +namespace BedrockService.Client.Forms +{ + partial class PlayerManagerForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle7 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle8 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle9 = new System.Windows.Forms.DataGridViewCellStyle(); + this.searchEntryBox = new System.Windows.Forms.TextBox(); + this.saveBtn = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.gridView = new System.Windows.Forms.DataGridView(); + this.registerPlayerBtn = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)(this.gridView)).BeginInit(); + this.SuspendLayout(); + // + // searchEntryBox + // + this.searchEntryBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.searchEntryBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.searchEntryBox.Location = new System.Drawing.Point(177, 390); + this.searchEntryBox.Name = "searchEntryBox"; + this.searchEntryBox.Size = new System.Drawing.Size(729, 26); + this.searchEntryBox.TabIndex = 4; + this.searchEntryBox.TextChanged += new System.EventHandler(this.searchEntryBox_TextChanged); + // + // saveBtn + // + this.saveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.saveBtn.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.saveBtn.Location = new System.Drawing.Point(912, 390); + this.saveBtn.Name = "saveBtn"; + this.saveBtn.Size = new System.Drawing.Size(87, 26); + this.saveBtn.TabIndex = 5; + this.saveBtn.Text = "Save"; + this.saveBtn.UseVisualStyleBackColor = true; + this.saveBtn.Click += new System.EventHandler(this.saveBtn_Click); + // + // label2 + // + this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label2.AutoSize = true; + this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label2.Location = new System.Drawing.Point(127, 393); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(44, 20); + this.label2.TabIndex = 6; + this.label2.Text = "Find:"; + // + // gridView + // + this.gridView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.gridView.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.AllCells; + this.gridView.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.AllCells; + dataGridViewCellStyle7.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle7.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle7.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle7.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle7.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle7.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle7.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.gridView.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle7; + this.gridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + dataGridViewCellStyle8.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle8.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle8.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle8.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle8.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle8.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle8.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.gridView.DefaultCellStyle = dataGridViewCellStyle8; + this.gridView.Location = new System.Drawing.Point(16, 27); + this.gridView.Name = "gridView"; + dataGridViewCellStyle9.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle9.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle9.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle9.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle9.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle9.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle9.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.gridView.RowHeadersDefaultCellStyle = dataGridViewCellStyle9; + this.gridView.Size = new System.Drawing.Size(983, 338); + this.gridView.TabIndex = 3; + this.gridView.CellBeginEdit += new System.Windows.Forms.DataGridViewCellCancelEventHandler(this.gridView_CellBeginEdit); + this.gridView.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.gridView_CellEndEdit); + // + // registerPlayerBtn + // + this.registerPlayerBtn.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.registerPlayerBtn.Location = new System.Drawing.Point(16, 390); + this.registerPlayerBtn.Name = "registerPlayerBtn"; + this.registerPlayerBtn.Size = new System.Drawing.Size(105, 26); + this.registerPlayerBtn.TabIndex = 7; + this.registerPlayerBtn.Text = "Register new..."; + this.registerPlayerBtn.UseVisualStyleBackColor = true; + this.registerPlayerBtn.Click += new System.EventHandler(this.registerPlayerBtn_Click); + // + // PlayerManagerForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1016, 435); + this.Controls.Add(this.registerPlayerBtn); + this.Controls.Add(this.gridView); + this.Controls.Add(this.label2); + this.Controls.Add(this.saveBtn); + this.Controls.Add(this.searchEntryBox); + this.Margin = new System.Windows.Forms.Padding(2); + this.Name = "PlayerManagerForm"; + this.Text = "Player Manager"; + ((System.ComponentModel.ISupportInitialize)(this.gridView)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + private System.Windows.Forms.TextBox searchEntryBox; + private System.Windows.Forms.Button saveBtn; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.DataGridView gridView; + private System.Windows.Forms.Button registerPlayerBtn; + } +} \ No newline at end of file diff --git a/BedrockService.backup/Client/Forms/PlayerManagerForm.cs b/BedrockService.backup/Client/Forms/PlayerManagerForm.cs new file mode 100644 index 00000000..ea819e69 --- /dev/null +++ b/BedrockService.backup/Client/Forms/PlayerManagerForm.cs @@ -0,0 +1,169 @@ +using BedrockService.Client.Management; +using BedrockService.Shared.Classes; +using BedrockService.Shared.Interfaces; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; + +namespace BedrockService.Client.Forms +{ + public partial class PlayerManagerForm : Form + { + private readonly IServerConfiguration _server; + private readonly string[] RegisteredPlayerColumnArray = new string[8] { "XUID:", "Username:", "Permission:", "Whitelisted:", "Ignores max players:", "First connected on:", "Last connected on:", "Time spent in game:" }; + private List playersFound = new List(); + private readonly List modifiedPlayers = new List(); + private IPlayer playerToEdit; + + public PlayerManagerForm(IServerConfiguration server) + { + InitializeComponent(); + _server = server; + playersFound = _server.GetPlayerList(); + + gridView.Columns.Clear(); + gridView.Rows.Clear(); + foreach (string s in RegisteredPlayerColumnArray) + { + gridView.Columns.Add(s.Replace(" ", "").Replace(":", ""), s); + } + gridView.Columns[5].ReadOnly = true; + gridView.Columns[6].ReadOnly = true; + gridView.Columns[7].ReadOnly = true; + gridView.Columns[5].CellTemplate.Style.BackColor = System.Drawing.Color.FromArgb(225, 225, 225); + gridView.Columns[6].CellTemplate.Style.BackColor = System.Drawing.Color.FromArgb(225, 225, 225); + gridView.Columns[7].CellTemplate.Style.BackColor = System.Drawing.Color.FromArgb(225, 225, 225); + gridView.AllowUserToAddRows = false; + RefreshGridContents(); + } + + private void RefreshGridContents() + { + gridView.Rows.Clear(); + foreach (IPlayer player in playersFound) + { + string[] playerReg = player.GetRegistration(); + string[] playerTimes = player.GetTimes(); + string playerFirstConnect = playerTimes[0]; + string playerConnectTime = playerTimes[1]; + string playerDisconnectTime = playerTimes[2]; + string playerWhitelist = playerReg[0]; + string playerPermission = player.GetPermissionLevel(); + string playerIgnoreLimit = playerReg[2]; + TimeSpan timeSpent = TimeSpan.FromTicks(long.Parse(playerConnectTime) - long.Parse(playerDisconnectTime)); + string[] list = new string[] { player.GetXUID(), player.GetUsername(), playerPermission, playerWhitelist, playerIgnoreLimit, playerFirstConnect, playerConnectTime, timeSpent.ToString("hhmmss") }; + gridView.Rows.Add(list); + } + gridView.Refresh(); + } + + private void saveBtn_Click(object sender, EventArgs e) + { + if (modifiedPlayers.Count > 0) + { + foreach (IPlayer player in modifiedPlayers) + { + _server.AddUpdatePlayer(player); + } + } + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + byte[] sendBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(modifiedPlayers, Formatting.Indented, settings)); + FormManager.TCPClient.SendData(sendBytes, NetworkMessageSource.Client, NetworkMessageDestination.Server, FormManager.MainWindow.connectedHost.GetServerIndex(_server), NetworkMessageTypes.PlayersUpdate); + FormManager.MainWindow.DisableUI(); + Close(); + Dispose(); + } + + private void searchEntryBox_TextChanged(object sender, EventArgs e) + { + playersFound = _server.GetPlayerList(); + string curText = searchEntryBox.Text; + List tempList = new List(); + string[] splitCommands; + string cmd; + string value; + + if (curText.Contains(":")) + { + splitCommands = curText.Split(','); + if (splitCommands.Length > 1) + { + foreach (string s in splitCommands) + { + if (s.Contains(":")) + { + string[] finalSplit = s.Split(':'); + cmd = finalSplit[0]; + value = finalSplit[1]; + tempList = new List(); + foreach (IPlayer player in playersFound) + { + if (player.SearchForProperty(cmd).Contains(value)) + { + tempList.Add(player); + } + } + playersFound = tempList; + gridView.Refresh(); + } + } + } + splitCommands = curText.Split(':'); + cmd = splitCommands[0]; + value = splitCommands[1]; + foreach (IPlayer player in playersFound) + { + if (player.SearchForProperty(cmd).Contains(value)) + { + tempList.Add(player); + } + } + playersFound = tempList; + gridView.Refresh(); + RefreshGridContents(); + } + } + + private void gridView_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) + { + DataGridViewRow focusedRow = gridView.Rows[e.RowIndex]; + playerToEdit = _server.GetPlayerByXuid((string)focusedRow.Cells[0].Value); + } + + private void gridView_CellEndEdit(object sender, DataGridViewCellEventArgs e) + { + DataGridViewRow focusedRow = gridView.Rows[e.RowIndex]; + string[] playerReg = playerToEdit.GetRegistration(); + string[] playerTimes = playerToEdit.GetTimes(); + string playerFirstConnect = playerTimes[0]; + string playerConnectTime = playerTimes[1]; + string playerDisconnectTime = playerTimes[2]; + string playerWhitelist = playerReg[0]; + string playerPermission = playerReg[1]; + string playerIgnoreLimit = playerReg[2]; + if ((string)focusedRow.Cells[0].Value != playerToEdit.GetXUID() || (string)focusedRow.Cells[1].Value != playerToEdit.GetUsername() || (string)focusedRow.Cells[2].Value != playerPermission || (string)focusedRow.Cells[3].Value != playerWhitelist || (string)focusedRow.Cells[4].Value != playerIgnoreLimit) + { + playerToEdit = new Player((string)focusedRow.Cells[0].Value, (string)focusedRow.Cells[1].Value, playerFirstConnect, playerConnectTime, playerDisconnectTime, bool.Parse((string)focusedRow.Cells[3].Value), (string)focusedRow.Cells[2].Value, bool.Parse((string)focusedRow.Cells[4].Value)); + modifiedPlayers.Add(playerToEdit); + } + } + + private void registerPlayerBtn_Click(object sender, EventArgs e) + { + using (NewPlayerRegistrationForm form = new NewPlayerRegistrationForm()) + { + if (form.ShowDialog() == DialogResult.OK) + { + _server.GetPlayerList().Add(form.PlayerToAdd); + modifiedPlayers.Add(form.PlayerToAdd); + RefreshGridContents(); + } + } + } + } +} diff --git a/BedrockService.backup/Client/Forms/PlayerManagerForm.resx b/BedrockService.backup/Client/Forms/PlayerManagerForm.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/BedrockService.backup/Client/Forms/PlayerManagerForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BedrockService.backup/Client/Forms/PropEditorForm.Designer.cs b/BedrockService.backup/Client/Forms/PropEditorForm.Designer.cs new file mode 100644 index 00000000..c27c8bd2 --- /dev/null +++ b/BedrockService.backup/Client/Forms/PropEditorForm.Designer.cs @@ -0,0 +1,132 @@ + +namespace BedrockService.Client.Forms +{ + partial class PropEditorForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.CancelBtn = new System.Windows.Forms.Button(); + this.SaveBtn = new System.Windows.Forms.Button(); + this.gridView = new System.Windows.Forms.DataGridView(); + this.EntryKey = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.EntryData = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.DelBackupBtn = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)(this.gridView)).BeginInit(); + this.SuspendLayout(); + // + // CancelBtn + // + this.CancelBtn.Anchor = System.Windows.Forms.AnchorStyles.Bottom; + this.CancelBtn.Location = new System.Drawing.Point(13, 362); + this.CancelBtn.Name = "CancelBtn"; + this.CancelBtn.Size = new System.Drawing.Size(200, 23); + this.CancelBtn.TabIndex = 48; + this.CancelBtn.Text = "Cancel"; + this.CancelBtn.UseVisualStyleBackColor = true; + this.CancelBtn.Click += new System.EventHandler(this.CancelBtn_Click); + // + // SaveBtn + // + this.SaveBtn.Anchor = System.Windows.Forms.AnchorStyles.Bottom; + this.SaveBtn.Location = new System.Drawing.Point(588, 362); + this.SaveBtn.Name = "SaveBtn"; + this.SaveBtn.Size = new System.Drawing.Size(200, 23); + this.SaveBtn.TabIndex = 49; + this.SaveBtn.Text = "Save"; + this.SaveBtn.UseVisualStyleBackColor = true; + this.SaveBtn.Click += new System.EventHandler(this.SaveBtn_Click); + // + // gridView + // + this.gridView.AllowUserToDeleteRows = false; + this.gridView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.gridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.gridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.EntryKey, + this.EntryData}); + this.gridView.Location = new System.Drawing.Point(13, 13); + this.gridView.MultiSelect = false; + this.gridView.Name = "gridView"; + this.gridView.Size = new System.Drawing.Size(775, 343); + this.gridView.TabIndex = 1; + this.gridView.NewRowNeeded += new System.Windows.Forms.DataGridViewRowEventHandler(this.gridView_NewRowNeeded); + // + // EntryKey + // + this.EntryKey.HeaderText = "Entry:"; + this.EntryKey.MinimumWidth = 20; + this.EntryKey.Name = "EntryKey"; + this.EntryKey.ReadOnly = true; + this.EntryKey.Width = 300; + // + // EntryData + // + this.EntryData.HeaderText = "Value:"; + this.EntryData.Name = "EntryData"; + this.EntryData.Width = 600; + // + // DelBackupBtn + // + this.DelBackupBtn.Anchor = System.Windows.Forms.AnchorStyles.Bottom; + this.DelBackupBtn.Enabled = false; + this.DelBackupBtn.Location = new System.Drawing.Point(301, 362); + this.DelBackupBtn.Name = "DelBackupBtn"; + this.DelBackupBtn.Size = new System.Drawing.Size(200, 23); + this.DelBackupBtn.TabIndex = 50; + this.DelBackupBtn.Text = "Delete Backup"; + this.DelBackupBtn.UseVisualStyleBackColor = true; + this.DelBackupBtn.Visible = false; + this.DelBackupBtn.Click += new System.EventHandler(this.DelBackupBtn_Click); + // + // EditSrv + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(800, 397); + this.Controls.Add(this.DelBackupBtn); + this.Controls.Add(this.gridView); + this.Controls.Add(this.SaveBtn); + this.Controls.Add(this.CancelBtn); + this.Name = "EditSrv"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Form1"; + ((System.ComponentModel.ISupportInitialize)(this.gridView)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + private System.Windows.Forms.Button CancelBtn; + private System.Windows.Forms.Button SaveBtn; + private System.Windows.Forms.DataGridView gridView; + private System.Windows.Forms.DataGridViewTextBoxColumn EntryKey; + private System.Windows.Forms.DataGridViewTextBoxColumn EntryData; + private System.Windows.Forms.Button DelBackupBtn; + } +} \ No newline at end of file diff --git a/BedrockService.backup/Client/Forms/PropEditorForm.cs b/BedrockService.backup/Client/Forms/PropEditorForm.cs new file mode 100644 index 00000000..2fc849e8 --- /dev/null +++ b/BedrockService.backup/Client/Forms/PropEditorForm.cs @@ -0,0 +1,133 @@ +using BedrockService.Client.Management; +using BedrockService.Shared.Classes; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; + +namespace BedrockService.Client.Forms +{ + public partial class PropEditorForm : Form + { + readonly DataGridView dataGrid; + public List workingProps; + public List startCmds; + public string RollbackFolderName = ""; + + public PropEditorForm() + { + InitializeComponent(); + dataGrid = gridView; + } + + public void PopulateBoxes(List propList) + { + int index = 0; + workingProps = propList; + foreach (Property prop in workingProps) + { + dataGrid.Rows.Add(new string[2] { prop.KeyName, prop.Value }); + if (prop.KeyName == "server-name" || prop.KeyName == "server-port" || prop.KeyName == "server-portv6") + { + dataGrid.Rows[index].ReadOnly = true; + dataGrid.Rows[index].DefaultCellStyle.BackColor = System.Drawing.Color.FromArgb(225, 225, 225); + } + index++; + } + gridView.AllowUserToAddRows = false; + } + + public void PopulateStartCmds(List list) + { + startCmds = list; + gridView.Columns.RemoveAt(0); + foreach (StartCmdEntry entry in startCmds) + { + dataGrid.Rows.Add(new string[1] { entry.Command }); + } + } + + public void EnableBackupManager() + { + gridView.MultiSelect = true; + DelBackupBtn.Enabled = true; + DelBackupBtn.Visible = true; + SaveBtn.Text = "Rollback this date"; + } + + private void CancelBtn_Click(object sender, EventArgs e) + { + Close(); + Dispose(); + } + + private void SaveBtn_Click(object sender, EventArgs e) + { + if (DelBackupBtn.Enabled) + { + if (dataGrid.SelectedRows.Count == 0) + { + if (dataGrid.SelectedCells.Count == 1) + { + dataGrid.SelectedCells[0].OwningRow.Selected = true; + } + } + if (dataGrid.SelectedRows.Count < 2) + RollbackFolderName = (string)dataGrid.CurrentRow.Cells[0].Value; + DialogResult = DialogResult.OK; + Close(); + } + startCmds = new List(); + foreach (DataGridViewRow row in dataGrid.Rows) + { + if (workingProps != null) + { + foreach (Property prop in workingProps) + { + if ((string)row.Cells[0].Value == prop.KeyName) + { + prop.Value = (string)row.Cells[1].Value; + } + } + } + else + { + if ((string)row.Cells[0].Value != null) + startCmds.Add(new StartCmdEntry((string)row.Cells[0].Value)); + } + + } + DialogResult = DialogResult.OK; + Close(); + } + + private void gridView_NewRowNeeded(object sender, DataGridViewRowEventArgs e) + { + DataGridViewRow focusedRow = gridView.CurrentRow; + focusedRow.Cells[0].Value = "Cmd:"; + gridView.Refresh(); + } + + private void DelBackupBtn_Click(object sender, EventArgs e) + { + if (dataGrid.SelectedRows.Count == 0) + { + if (dataGrid.SelectedCells.Count == 1) + { + dataGrid.SelectedCells[0].OwningRow.Selected = true; + } + } + List removeBackups = new List(); + if (dataGrid.SelectedRows.Count > 0) + foreach (DataGridViewRow viewRow in dataGrid.SelectedRows) + removeBackups.Add((string)viewRow.Cells[0].Value); + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(removeBackups, Formatting.Indented, settings)); + FormManager.TCPClient.SendData(serializeToBytes, NetworkMessageSource.Client, NetworkMessageDestination.Service, FormManager.MainWindow.connectedHost.GetServerIndex(FormManager.MainWindow.selectedServer), NetworkMessageTypes.DelBackups); + } + } +} diff --git a/BedrockService.backup/Client/Forms/PropEditorForm.resx b/BedrockService.backup/Client/Forms/PropEditorForm.resx new file mode 100644 index 00000000..6f35f1cd --- /dev/null +++ b/BedrockService.backup/Client/Forms/PropEditorForm.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + True + + \ No newline at end of file diff --git a/BedrockService.backup/Client/Management/ClientLogger.cs b/BedrockService.backup/Client/Management/ClientLogger.cs new file mode 100644 index 00000000..8e9a737e --- /dev/null +++ b/BedrockService.backup/Client/Management/ClientLogger.cs @@ -0,0 +1,57 @@ +using BedrockService.Shared.Interfaces; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace BedrockService.Client.Management +{ + public class ClientLogger : ILogger + { + public List Log = new List(); + public StringBuilder OutString = new StringBuilder(); + public StreamWriter LogWriter; + private readonly string LogDir; + + public ClientLogger(IProcessInfo processInfo) + { + LogDir = $@"{processInfo.GetDirectory()}\Client\ClientLogs"; + if (!Directory.Exists(LogDir)) + { + Directory.CreateDirectory(LogDir); + } + LogWriter = new StreamWriter($@"{LogDir}\ClientLog_{DateTime.Now:yyyymmddhhmmss}.log", true); + } + + public void AppendLine(string text) + { + string addText = $"Client: {text}\r\n"; + Log.Add(addText); + LogWriter.WriteLine(addText); + LogWriter.Flush(); + Console.WriteLine(text); + } + + public void AppendText(string text) => AppendLine(text); + + public int Count() + { + return Log.Count; + } + + public string FromIndex(int index) + { + return Log[index]; + } + + public override string ToString() + { + OutString = new StringBuilder(); + foreach (string s in Log) + { + OutString.Append(s); + } + return OutString.ToString(); + } + } +} diff --git a/BedrockService.backup/Client/Management/ConfigManager.cs b/BedrockService.backup/Client/Management/ConfigManager.cs new file mode 100644 index 00000000..837c0fa8 --- /dev/null +++ b/BedrockService.backup/Client/Management/ConfigManager.cs @@ -0,0 +1,89 @@ +using BedrockService.Shared.Classes; +using BedrockService.Shared.Interfaces; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace BedrockService.Client.Management +{ + public class ConfigManager + { + public string ConfigDir = $@"{Directory.GetCurrentDirectory()}\Client\Configs"; + public string ConfigFile; + public List HostConnectList = new List(); + public string NBTStudioPath; + private readonly ILogger Logger; + + public ConfigManager(ILogger logger) + { + Logger = logger; + ConfigFile = $@"{ConfigDir}\Config.conf"; + } + + public void LoadConfigs() + { + HostConnectList.Clear(); + if (!Directory.Exists(ConfigDir)) + { + Directory.CreateDirectory(ConfigDir); + } + if (!File.Exists(ConfigFile)) + { + Logger.AppendLine("Config file missing! Regenerating default file..."); + CreateDefaultConfig(); + LoadConfigs(); + return; + } + string[] lines = File.ReadAllLines(ConfigFile); + foreach (string line in lines) + { + string[] entrySplit = line.Split('='); + if (!string.IsNullOrEmpty(line) && !line.StartsWith("#")) + { + if (entrySplit[0] == "HostEntry") + { + string[] hostSplit = entrySplit[1].Split(';'); + string[] addressSplit = hostSplit[1].Split(':'); + IClientSideServiceConfiguration hostToList = new ClientSideServiceConfiguration(hostSplit[0], addressSplit[0], addressSplit[1]); + HostConnectList.Add(hostToList); + } + if (entrySplit[0] == "NBTStudioPath") + { + NBTStudioPath = entrySplit[1]; + } + } + } + } + + public void CreateDefaultConfig() + { + string[] Config = new string[] + { + "HostEntry=host1;127.0.0.1:19134" + }; + StringBuilder builder = new StringBuilder(); + builder.Append("# Hosts\n"); + foreach (string entry in Config) + { + builder.Append($"{entry}\n"); + } + builder.Append("\n# Settings\n"); + builder.Append("NBTStudioPath=\n"); + File.WriteAllText(ConfigFile, builder.ToString()); + } + + public void SaveConfigFile() + { + StringBuilder fileContent = new StringBuilder(); + fileContent.Append("# hosts\n\n"); + foreach (ClientSideServiceConfiguration host in HostConnectList) + { + fileContent.Append($"HostEntry={host.GetHostName()};{host.GetAddress()}:{host.GetPort()}\n"); + } + fileContent.Append("\n# Settings\n"); + fileContent.Append($"NBTStudioPath={NBTStudioPath}"); + File.WriteAllText(ConfigFile, fileContent.ToString()); + } + } +} diff --git a/BedrockService.backup/Client/Management/FormManager.cs b/BedrockService.backup/Client/Management/FormManager.cs new file mode 100644 index 00000000..37a2ca80 --- /dev/null +++ b/BedrockService.backup/Client/Management/FormManager.cs @@ -0,0 +1,41 @@ +using BedrockService.Client.Forms; +using BedrockService.Client.Networking; +using BedrockService.Shared.Classes; +using BedrockService.Shared.Interfaces; +using System.Diagnostics; +using System.IO; +using System.Reflection; + +namespace BedrockService.Client.Management +{ + public sealed class FormManager + { + private static readonly IProcessInfo processInfo = new ServiceProcessInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Path.GetFileName(Assembly.GetExecutingAssembly().Location), Process.GetCurrentProcess().Id, false, true); + private static readonly ILogger Logger = new ClientLogger(processInfo); + private static MainWindow main; + private static TCPClient client; + public static MainWindow MainWindow + { + get + { + if (main == null || main.IsDisposed) + { + main = new MainWindow(processInfo, Logger); + } + return main; + } + } + + public static TCPClient TCPClient + { + get + { + if (client == null) + { + client = new TCPClient(Logger); + } + return client; + } + } + } +} diff --git a/BedrockService.backup/Client/Management/LogManager.cs b/BedrockService.backup/Client/Management/LogManager.cs new file mode 100644 index 00000000..7e8a1d05 --- /dev/null +++ b/BedrockService.backup/Client/Management/LogManager.cs @@ -0,0 +1,123 @@ +using BedrockService.Shared.Classes; +using BedrockService.Shared.Interfaces; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Windows.Forms; + +namespace BedrockService.Client.Management +{ + class LogManager + { + public Thread LogThread; + public bool EnableFlag; + public bool Working = false; + public List ServiceLogs = new List(); + private IServiceConfiguration connectedHost; + private readonly ILogger Logger; + + public LogManager(ILogger logger) + { + Logger = logger; + } + + private void LogManagerTask() + { + while (FormManager.TCPClient.Connected) + { + try + { + Working = true; + StringBuilder sendString = new StringBuilder(); + foreach (ServerInfo server in connectedHost.GetServerList()) + { + server.ConsoleBuffer = server.ConsoleBuffer ?? new List(); + sendString.Append($"{server.ServerName};{server.ConsoleBuffer.Count}|"); + } + sendString.Append($"Service;{connectedHost.GetLog().Count}"); + byte[] stringsToBytes = Encoding.UTF8.GetBytes(sendString.ToString()); + FormManager.TCPClient.SendData(stringsToBytes, NetworkMessageSource.Client, NetworkMessageDestination.Service, NetworkMessageTypes.ConsoleLogUpdate); + Thread.Sleep(200); + int currentLogBoxLength = 0; + + if (FormManager.MainWindow.selectedServer == null) + { + UpdateLogBoxInvoked(""); + } + FormManager.MainWindow.LogBox.Invoke((MethodInvoker)delegate + { + currentLogBoxLength = FormManager.MainWindow.LogBox.TextLength; + }); + if (FormManager.MainWindow.ShowsSvcLog && connectedHost.GetLog().Count != currentLogBoxLength) + { + UpdateLogBoxInvoked(string.Join("\r\n", connectedHost.GetLog())); + } + else if (!FormManager.MainWindow.ShowsSvcLog && FormManager.MainWindow.selectedServer.GetLog() != null && FormManager.MainWindow.selectedServer.GetLog().Count != currentLogBoxLength) + { + UpdateLogBoxInvoked(string.Join("", FormManager.MainWindow.selectedServer.GetLog())); + } + + } + catch (Exception e) + { + Logger.AppendLine($"LogManager Error! Stacetrace: {e.StackTrace}"); + } + } + } + + public bool InitLogThread(IServiceConfiguration host) + { + connectedHost = host; + return StartLogThread(); + } + + public bool StartLogThread() + { + try + { + if (LogThread != null && LogThread.IsAlive) + LogThread.Abort(); + LogThread = new Thread(new ThreadStart(LogManagerTask)); + LogThread.Name = "LogThread"; + LogThread.IsBackground = true; + EnableFlag = true; + LogThread.Start(); + Logger.AppendLine("LogThread started"); + return true; + } + catch (Exception e) + { + Logger.AppendLine($"Error starting LogThread: {e.StackTrace}"); + } + return false; + } + + public bool StopLogThread() + { + if (LogThread == null) + { + return true; + } + try + { + LogThread.Abort(); + } + catch (ThreadAbortException e) + { + Logger.AppendLine(e.StackTrace); + } + Logger.AppendLine("LogThread stopped"); + LogThread = null; + return true; + } + + private static void UpdateLogBoxInvoked(string contents) + { + FormManager.MainWindow.LogBox.Invoke((MethodInvoker)delegate + { + FormManager.MainWindow.UpdateLogBox(contents); + }); + } + } +} diff --git a/BedrockService.backup/Client/Networking/TCPClient.cs b/BedrockService.backup/Client/Networking/TCPClient.cs new file mode 100644 index 00000000..15eb7cab --- /dev/null +++ b/BedrockService.backup/Client/Networking/TCPClient.cs @@ -0,0 +1,346 @@ +using BedrockService.Client.Management; +using BedrockService.Shared.Classes; +using BedrockService.Shared.Interfaces; +using BedrockService.Shared.PackParser; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Net.Sockets; +using System.Text; +using System.Threading; + +namespace BedrockService.Client.Networking +{ + public class TCPClient + { + public TcpClient OpenedTcpClient; + public string ClientName; + public NetworkStream stream; + public bool Connected; + public bool EnableRead; + public bool PlayerInfoArrived; + public bool EnumBackupsArrived; + public List BackupList; + public List RecievedPacks; + public Thread ClientReciever; + public Thread HeartbeatThread; + private int _heartbeatFailTimeout; + private const int _heartbeatFailTimeoutLimit = 250; + private bool _heartbeatRecieved; + private bool _keepAlive; + private readonly ILogger _logger; + + public TCPClient (ILogger logger) + { + _logger = logger; + } + + public void ConnectHost(IClientSideServiceConfiguration host) + { + if (EstablishConnection(host.GetAddress(), int.Parse(host.GetPort()))) + { + SendData(NetworkMessageSource.Client, NetworkMessageDestination.Service, NetworkMessageTypes.Connect); + return; + } + } + + public bool EstablishConnection(string addr, int port) + { + _logger.AppendLine("Connecting to Server"); + try + { + EnableRead = false; + OpenedTcpClient = new TcpClient(addr, port); + stream = OpenedTcpClient.GetStream(); + _keepAlive = true; + ClientReciever = new Thread(new ThreadStart(ReceiveListener)); + ClientReciever.Name = "ClientPacketReviever"; + ClientReciever.IsBackground = true; + ClientReciever.Start(); + } + catch + { + _logger.AppendLine("Could not connect to Server"); + if(ClientReciever != null) + ClientReciever.Abort(); + ClientReciever = null; + return false; + } + return _keepAlive; + } + + public void CloseConnection() + { + try + { + if (stream != null) + stream.Dispose(); + stream = null; + Connected = false; + _keepAlive = false; + } + catch (NullReferenceException) + { + Connected = false; + _keepAlive = false; + } + catch (Exception e) + { + _logger.AppendLine($"Error closing connection: {e.StackTrace}"); + } + } + + public void ReceiveListener() + { + List byteBlocks = new List(); + while (_keepAlive) + { + try + { + byte[] buffer = new byte[4]; + while (OpenedTcpClient.Client.Available > 0) + { + int byteCount = stream.Read(buffer, 0, 4); + int expectedLen = BitConverter.ToInt32(buffer, 0); + buffer = new byte[expectedLen]; + byteCount = stream.Read(buffer, 0, expectedLen); + NetworkMessageSource source = (NetworkMessageSource)buffer[0]; + NetworkMessageDestination destination = (NetworkMessageDestination)buffer[1]; + byte serverIndex = buffer[2]; + NetworkMessageTypes msgType = (NetworkMessageTypes)buffer[3]; + NetworkMessageFlags msgStatus = (NetworkMessageFlags)buffer[4]; + string data = ""; + if (msgType != NetworkMessageTypes.PackFile || msgType != NetworkMessageTypes.LevelEditFile) + data = GetOffsetString(buffer); + if (destination != NetworkMessageDestination.Client) + continue; + int srvCurLen = 0; + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + switch (source) + { + case NetworkMessageSource.Service: + switch (msgType) + { + case NetworkMessageTypes.Connect: + try + { + _logger.AppendLine("Connection to Host successful!"); + FormManager.MainWindow.connectedHost = null; + FormManager.MainWindow.connectedHost = JsonConvert.DeserializeObject(data, settings); + Connected = true; + FormManager.MainWindow.RefreshServerContents(); + _heartbeatFailTimeout = 0; + if (HeartbeatThread == null || !HeartbeatThread.IsAlive) + HeartbeatThread = new Thread(new ThreadStart(SendHeatbeatSignal)) + { + IsBackground = true, + Name = "HeartBeatThread" + }; + HeartbeatThread.Start(); + + } + catch (Exception e) + { + _logger.AppendLine($"Error: ConnectMan reported error: {e.Message}\n{e.StackTrace}"); + } + break; + case NetworkMessageTypes.Heartbeat: + _heartbeatRecieved = true; + if (!HeartbeatThread.IsAlive) + { + HeartbeatThread = new Thread(new ThreadStart(SendHeatbeatSignal)); + HeartbeatThread.IsBackground = true; + HeartbeatThread.Name = "HeartBeatThread"; + HeartbeatThread.Start(); + } + break; + + case NetworkMessageTypes.EnumBackups: + + BackupList = JsonConvert.DeserializeObject>(data, settings); + EnumBackupsArrived = true; + + break; + case NetworkMessageTypes.CheckUpdates: + + //TODO: Ask user if update now or perform later. + UnlockUI(); + + break; + case NetworkMessageTypes.UICallback: + + UnlockUI(); + + break; + } + break; + case NetworkMessageSource.Server: + switch (msgType) + { + case NetworkMessageTypes.ConsoleLogUpdate: + string[] strings = data.Split('|'); + for (int i = 0; i < strings.Length; i++) + { + string[] srvSplit = strings[i].Split(';'); + string srvName = srvSplit[0]; + string srvText = srvSplit[1]; + srvCurLen = int.Parse(srvSplit[2]); + if (srvName != "Service") + { + IServerConfiguration bedrockServer = FormManager.MainWindow.connectedHost.GetServerInfoByName(srvName); + int curCount = bedrockServer.GetLog().Count; + if (curCount == srvCurLen) + { + bedrockServer.GetLog().Add(srvText); + } + } + else + { + int curCount = FormManager.MainWindow.connectedHost.GetLog().Count; + if (curCount == srvCurLen) + { + FormManager.MainWindow.connectedHost.GetLog().Add(srvText); + } + } + } + break; + case NetworkMessageTypes.Backup: + + _logger.AppendLine(msgStatus.ToString()); + + break; + case NetworkMessageTypes.UICallback: + + UnlockUI(); + + break; + case NetworkMessageTypes.PackList: + + List temp = new List(); + JArray jArray = JArray.Parse(data); + foreach (JToken token in jArray) + temp.Add(token.ToObject()); + RecievedPacks = temp; + + break; + case NetworkMessageTypes.PlayersRequest: + + List fetchedPlayers = JsonConvert.DeserializeObject>(data, settings); + FormManager.MainWindow.connectedHost.GetServerInfoByIndex(serverIndex).SetPlayerList(fetchedPlayers); + PlayerInfoArrived = true; + + break; + case NetworkMessageTypes.LevelEditFile: + + byte[] stripHeaderFromBuffer = new byte[buffer.Length - 5]; + Buffer.BlockCopy(buffer, 5, stripHeaderFromBuffer, 0, stripHeaderFromBuffer.Length); + string pathToLevelDat = $@"{Path.GetTempPath()}\level.dat"; + File.WriteAllBytes(pathToLevelDat, stripHeaderFromBuffer); + UnlockUI(); + + break; + } + break; + } + } + } + catch (Exception e) + { + _logger.AppendLine($"TCPClient error! Stacktrace: {e.Message}\n{e.StackTrace}"); + } + Thread.Sleep(200); + } + } + + public void SendHeatbeatSignal() + { + _logger.AppendLine("HeartbeatThread started."); + while (_keepAlive) + { + _heartbeatRecieved = false; + SendData(NetworkMessageSource.Client, NetworkMessageDestination.Service, NetworkMessageTypes.Heartbeat); + while (!_heartbeatRecieved && _keepAlive) + { + Thread.Sleep(100); + _heartbeatFailTimeout++; + if (_heartbeatFailTimeout > _heartbeatFailTimeoutLimit) + { + FormManager.MainWindow.HeartbeatFailDisconnect(); + HeartbeatThread.Abort(); + _heartbeatFailTimeout = 0; + } + } + // Logger.AppendLine("ThumpThump"); + _heartbeatRecieved = false; + _heartbeatFailTimeout = 0; + Thread.Sleep(3000); + } + } + + public bool SendData(byte[] bytes, NetworkMessageSource source, NetworkMessageDestination destination, byte serverIndex, NetworkMessageTypes type, NetworkMessageFlags status) + { + byte[] compiled = new byte[9 + bytes.Length]; + byte[] len = BitConverter.GetBytes(5 + bytes.Length); + Buffer.BlockCopy(len, 0, compiled, 0, 4); + compiled[4] = (byte)source; + compiled[5] = (byte)destination; + compiled[6] = serverIndex; + compiled[7] = (byte)type; + compiled[8] = (byte)status; + Buffer.BlockCopy(bytes, 0, compiled, 9, bytes.Length); + if (_keepAlive) + { + try + { + stream.Write(compiled, 0, compiled.Length); + stream.Flush(); + return true; + + } + catch + { + _logger.AppendLine("Error writing to network stream!"); + return false; + } + } + return false; + } + + public void SendData(NetworkMessageSource source, NetworkMessageDestination destination, NetworkMessageTypes type) => SendData(new byte[0], source, destination, 0xFF, type, NetworkMessageFlags.None); + + public void SendData(NetworkMessageSource source, NetworkMessageDestination destination, byte serverIndex, NetworkMessageTypes type) => SendData(new byte[0], source, destination, serverIndex, type, NetworkMessageFlags.None); + + public void SendData(NetworkMessageSource source, NetworkMessageDestination destination, byte serverIndex, NetworkMessageTypes type, NetworkMessageFlags flag) => SendData(new byte[0], source, destination, serverIndex, type, flag); + + public void SendData(byte[] bytes, NetworkMessageSource source, NetworkMessageDestination destination, byte serverIndex, NetworkMessageTypes type) => SendData(bytes, source, destination, serverIndex, type, NetworkMessageFlags.None); + + public void SendData(byte[] bytes, NetworkMessageSource source, NetworkMessageDestination destination, NetworkMessageTypes type) => SendData(bytes, source, destination, 0xFF, type, NetworkMessageFlags.None); + + public void SendData(NetworkMessageSource source, NetworkMessageDestination destination, NetworkMessageTypes type, NetworkMessageFlags status) => SendData(new byte[0], source, destination, 0xFF, type, status); + + public void Dispose() + { + if (HeartbeatThread != null && HeartbeatThread.IsAlive) + HeartbeatThread.Abort(); + if (ClientReciever != null && ClientReciever.IsAlive) + ClientReciever.Abort(); + HeartbeatThread = null; + ClientReciever = null; + if (OpenedTcpClient != null) + { + OpenedTcpClient.Close(); + OpenedTcpClient.Dispose(); + } + + } + + private string GetOffsetString(byte[] array) => Encoding.UTF8.GetString(array, 5, array.Length - 5); + + private void UnlockUI() => FormManager.MainWindow.ServerBusy = false; + } +} diff --git a/BedrockService.backup/Client/Properties/AssemblyInfo.cs b/BedrockService.backup/Client/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..83c81492 --- /dev/null +++ b/BedrockService.backup/Client/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("BedrockClientGUI")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("BedrockClientGUI")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("a2daf70a-925a-4f4b-b7ee-caace75d6740")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/BedrockService.backup/Client/Properties/Resources.Designer.cs b/BedrockService.backup/Client/Properties/Resources.Designer.cs new file mode 100644 index 00000000..2764b906 --- /dev/null +++ b/BedrockService.backup/Client/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace BedrockService.Client.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BedrockService.Client.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/BedrockService.backup/Client/Properties/Resources.resx b/BedrockService.backup/Client/Properties/Resources.resx new file mode 100644 index 00000000..af7dbebb --- /dev/null +++ b/BedrockService.backup/Client/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BedrockService.backup/Client/Properties/Settings.Designer.cs b/BedrockService.backup/Client/Properties/Settings.Designer.cs new file mode 100644 index 00000000..609bb426 --- /dev/null +++ b/BedrockService.backup/Client/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace BedrockService.Client.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/BedrockService.backup/Client/Properties/Settings.settings b/BedrockService.backup/Client/Properties/Settings.settings new file mode 100644 index 00000000..39645652 --- /dev/null +++ b/BedrockService.backup/Client/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/BedrockService/Client/packages.config b/BedrockService.backup/Client/packages.config similarity index 100% rename from BedrockService/Client/packages.config rename to BedrockService.backup/Client/packages.config diff --git a/BedrockService.backup/Client/upgrade.backup b/BedrockService.backup/Client/upgrade.backup new file mode 100644 index 00000000..7f14ee63 --- /dev/null +++ b/BedrockService.backup/Client/upgrade.backup @@ -0,0 +1 @@ +Backup created at 1636645213 (11/11/2021 3:40:13 PM +00:00) \ No newline at end of file diff --git a/BedrockService.backup/Service/BedrockService.Service.csproj b/BedrockService.backup/Service/BedrockService.Service.csproj new file mode 100644 index 00000000..f0053119 --- /dev/null +++ b/BedrockService.backup/Service/BedrockService.Service.csproj @@ -0,0 +1,197 @@ + + + + + Debug + AnyCPU + {13B2B5A8-71E9-49F4-9BFB-3C3B3C0A054C} + Exe + BedrockService.Service + BedrockService.Service + v4.7.2 + 512 + true + true + true + C:\Users\crowbar\source\repos\BedrockManagementService\Releases\ + true + Web + true + Foreground + 7 + Days + false + false + true + http://Coming.soon/ + true + publish.htm + 4 + 1.0.0.%2a + false + true + true + + + x86 + true + full + false + ..\bin\Debug\ + DEBUG;TRACE + prompt + 2 + + + AnyCPU + pdbonly + true + ..\bin\Release\ + TRACE + prompt + 4 + + + EE2403F7477A35F08B98B0A8FB2404C95BE04FEB + + + BedrockService_TemporaryKey.pfx + + + true + + + false + + + false + + + + + + + + ..\packages\Microsoft.Bcl.AsyncInterfaces.5.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + False + True + + + ..\packages\Microsoft.Extensions.DependencyInjection.5.0.2\lib\net461\Microsoft.Extensions.DependencyInjection.dll + False + True + + + ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.5.0.0\lib\net461\Microsoft.Extensions.DependencyInjection.Abstractions.dll + False + True + + + ..\packages\NCrontab.Signed.3.3.2\lib\net35\NCrontab.Signed.dll + False + True + + + ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll + False + True + + + + False + + + + + False + + + + ..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll + True + True + + + ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll + True + False + + + + + ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + True + + + + + + False + + + + + + ..\packages\Topshelf.4.3.0\lib\net452\Topshelf.dll + False + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + Microsoft .NET Framework 4.7.2 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + + + + + + + {f146d5e8-ef1f-4785-9150-182631f059b7} + BedrockService.Shared + + + + \ No newline at end of file diff --git a/BedrockService.backup/Service/Configs/Default.conf b/BedrockService.backup/Service/Configs/Default.conf new file mode 100644 index 00000000..0379cdeb --- /dev/null +++ b/BedrockService.backup/Service/Configs/Default.conf @@ -0,0 +1,28 @@ +# Server +server-name=Default +gamemode=creative +difficulty=easy +allow-cheats=false +max-players=10 +online-mode=true +white-list=false +server-port=19132 +server-portv6=19133 +view-distance=32 +tick-distance=4 +player-idle-timeout=30 +max-threads=8 +level-name=Bedrock level +level-seed= +default-player-permission-level=member +texturepack-required=false +content-log-file-enabled=false +compression-threshold=1 +server-authoritative-movement=server-auth +player-movement-score-threshold=20 +player-movement-distance-threshold=0.3 +player-movement-duration-threshold-in-ms=500 +correct-player-movement=false + +# StartCmds +AddStartCmd=help 1 \ No newline at end of file diff --git a/BedrockService.backup/Service/Configs/Default.players b/BedrockService.backup/Service/Configs/Default.players new file mode 100644 index 00000000..b2ddaf2f --- /dev/null +++ b/BedrockService.backup/Service/Configs/Default.players @@ -0,0 +1,5 @@ +# Registered player list +# Register player entries: xuid,username,permission,isWhitelisted,ignoreMaxPlayers +# Example: TestUser,555111222333444,visitor,false,false + +1234111222333444,TestUser,visitor,false,false \ No newline at end of file diff --git a/BedrockService.backup/Service/Configs/Globals.conf b/BedrockService.backup/Service/Configs/Globals.conf new file mode 100644 index 00000000..3d3c6083 --- /dev/null +++ b/BedrockService.backup/Service/Configs/Globals.conf @@ -0,0 +1,16 @@ +#Globals +ServersPath=C:\MCBedrockService +AcceptedMojangLic=false +ClientPort=19134 +#Backups +BackupEnabled=false +BackupPath=Default +BackupCron=0 1 * * * +MaxBackupCount=25 +EntireBackups=false +#Updates +CheckUpdates=true +UpdateCron=38 19 * * * +#Logging +LogServersToFile=false +LogServiceToFile=false diff --git a/BedrockService.backup/Service/Core/BedrockService.cs b/BedrockService.backup/Service/Core/BedrockService.cs new file mode 100644 index 00000000..4aa17913 --- /dev/null +++ b/BedrockService.backup/Service/Core/BedrockService.cs @@ -0,0 +1,310 @@ +using BedrockService.Service.Core.Interfaces; +using BedrockService.Service.Management; +using BedrockService.Service.Networking; +using BedrockService.Service.Server; +using BedrockService.Shared.Interfaces; +using BedrockService.Service.Core.Threads; +using NCrontab; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Timers; +using Topshelf; + +namespace BedrockService.Service.Core +{ + public class BedrockService : ServiceControl, IBedrockService + { + private enum ServiceStatus + { + Stopped, + Starting, + Started, + Stopping + } + private readonly IServiceConfiguration _serviceConfiguration; + private readonly ILogger _logger; + private readonly IProcessInfo _processInfo; + private readonly IConfigurator _configurator; + private readonly IUpdater _updater; + private readonly ITCPListener _tCPListener; + private readonly CrontabSchedule _shed; + private readonly CrontabSchedule _updaterCron; + private HostControl _hostControl; + private readonly List _bedrockServers = new List(); + private System.Timers.Timer _updaterTimer; + private System.Timers.Timer _cronTimer; + + public BedrockService(IConfigurator configurator, IUpdater updater, ILogger logger, IServiceConfiguration serviceConfiguration, IProcessInfo serviceProcessInfo, ITCPListener tCPListener) + { + _tCPListener = tCPListener; + _configurator = configurator; + _serviceConfiguration = serviceConfiguration; + _processInfo = serviceProcessInfo; + _updater = updater; + _logger = logger; + _shed = CrontabSchedule.TryParse(serviceConfiguration.GetProp("BackupCron").ToString()); + _updaterCron = CrontabSchedule.TryParse(serviceConfiguration.GetProp("UpdateCron").ToString()); + Initialize(); + _tCPListener.SetKeyContainer(_configurator.GetKeyContainer()); + } + + public bool Start(HostControl hostControl) + { + _hostControl = hostControl; + try + { + ValidSettingsCheck(); + + foreach (var brs in _bedrockServers) + { + if(hostControl != null) + _hostControl.RequestAdditionalTime(TimeSpan.FromSeconds(30)); + brs.SetServerStatus(BedrockServer.ServerStatus.Starting); + brs.StartWatchdog(_hostControl); + } + return true; + } + catch (Exception e) + { + _logger.AppendLine($"Error Starting BedrockServiceWrapper {e.StackTrace}"); + return false; + } + } + + public bool Stop(HostControl hostControl) + { + _hostControl = hostControl; + try + { + foreach (var brs in _bedrockServers) + { + brs.SetServerStatus(BedrockServer.ServerStatus.Stopping); + while (brs.GetServerStatus() == BedrockServer.ServerStatus.Stopping && !Program.IsExiting) + Thread.Sleep(100); + } + return true; + } + catch (Exception e) + { + _logger.AppendLine($"Error Stopping BedrockServiceWrapper {e.StackTrace}"); + return false; + } + } + + public void RestartService() + { + try + { + foreach (IBedrockServer brs in _bedrockServers) + { + brs.SetServerStatus(BedrockServer.ServerStatus.Stopping); + while (brs.GetServerStatus() == BedrockServer.ServerStatus.Stopping && !Program.IsExiting) + Thread.Sleep(100); + } + foreach (IBedrockServer brs in _bedrockServers) + { + brs.StopWatchdog(); + } + try + { + _tCPListener.ResetListener(); + } + catch (ThreadAbortException) { } + _configurator.LoadAllConfigurations().Wait(); + Initialize(); + foreach (var brs in _bedrockServers) + { + brs.SetServerStatus(BedrockServer.ServerStatus.Starting); + } + Start(_hostControl); + } + catch (Exception e) + { + _logger.AppendLine($"Error Stopping BedrockServiceWrapper {e.StackTrace}"); + } + } + + public IBedrockServer GetBedrockServerByIndex(int serverIndex) + { + return _bedrockServers[serverIndex]; + } + + public IBedrockServer GetBedrockServerByName(string name) + { + return _bedrockServers.FirstOrDefault(brs => brs.GetServerName() == name); + } + + public List GetAllServers() => _bedrockServers; + + public void InitializeNewServer(IServerConfiguration server) + { + IBedrockServer bedrockServer = new BedrockServer(server, _configurator, _logger, _serviceConfiguration, _processInfo); + _bedrockServers.Add(bedrockServer); + _serviceConfiguration.AddNewServerInfo(server); + if (ValidSettingsCheck()) + { + bedrockServer.SetServerStatus(BedrockServer.ServerStatus.Starting); + bedrockServer.StartWatchdog(_hostControl); + } + } + + private void Initialize() + { + _bedrockServers.Clear(); + if (_serviceConfiguration.GetProp("BackupEnabled").ToString() == "true" && _shed != null) + { + _cronTimer = new System.Timers.Timer((_shed.GetNextOccurrence(DateTime.Now) - DateTime.Now).TotalMilliseconds); + _cronTimer.Elapsed += CronTimer_Elapsed; + _cronTimer.Start(); + } + if (_serviceConfiguration.GetProp("CheckUpdates").ToString() == "true" && _updaterCron != null) + { + _updaterTimer = new System.Timers.Timer((_updaterCron.GetNextOccurrence(DateTime.Now) - DateTime.Now).TotalMilliseconds); + _updaterTimer.Elapsed += UpdateTimer_Elapsed; + _logger.AppendLine($"Updates Enabled, will be checked in: {((float)_updaterTimer.Interval / 1000)} seconds."); + _updaterTimer.Start(); + } + try + { + List temp = _serviceConfiguration.GetServerList(); + foreach (IServerConfiguration server in temp) + { + IBedrockServer bedrockServer = new BedrockServer(server, _configurator, _logger, _serviceConfiguration, _processInfo); + _bedrockServers.Add(bedrockServer); + } + } + catch (Exception e) + { + _logger.AppendLine($"Error Instantiating BedrockServiceWrapper: {e.StackTrace}"); + } + } + + private void CronTimer_Elapsed(object sender, ElapsedEventArgs e) + { + try + { + if (_cronTimer != null) + { + _cronTimer.Stop(); + _cronTimer = null; + } + if (_serviceConfiguration.GetProp("BackupEnabled").ToString() == "true" && _shed != null) + { + Backup(); + + _cronTimer = new System.Timers.Timer((_shed.GetNextOccurrence(DateTime.Now) - DateTime.Now).TotalMilliseconds); + _cronTimer.Elapsed += CronTimer_Elapsed; + _cronTimer.Start(); + } + } + catch (Exception ex) + { + _logger.AppendLine($"Error in BackupTimer_Elapsed {ex}"); + } + } + + private void UpdateTimer_Elapsed(object sender, ElapsedEventArgs e) + { + try + { + if (_updaterTimer != null) + { + _updaterTimer.Stop(); + _updaterTimer = null; + } + _updater.CheckUpdates().Wait(); + if (_serviceConfiguration.GetProp("CheckUpdates").ToString() == "true" && _updater != null) + { + if (_updater.CheckVersionChanged()) + { + _logger.AppendLine("Version change detected! Restarting server(s) to apply update..."); + foreach(IBedrockServer server in _bedrockServers) + { + server.RestartServer(false); + } + } + + _updaterTimer = new System.Timers.Timer((_updaterCron.GetNextOccurrence(DateTime.Now) - DateTime.Now).TotalMilliseconds); + _updaterTimer.Elapsed += UpdateTimer_Elapsed; + _updaterTimer.Start(); + } + } + catch (Exception ex) + { + _logger.AppendLine($"Error in UpdateTimer_Elapsed {ex}"); + } + } + + private void Backup() + { + _logger.AppendLine("Service started backup manager."); + foreach (var brs in _bedrockServers) + { + brs.RestartServer(true); + } + _logger.AppendLine("Backups have been completed."); + } + + private bool ValidSettingsCheck() + { + bool validating = true; + bool dupedSettingsFound = false; + while (validating) + { + if (_serviceConfiguration.GetServerList().Count() < 1) + { + throw new Exception("No Servers Configured"); + } + else + { + foreach (IServerConfiguration server in _serviceConfiguration.GetServerList()) + { + foreach (IServerConfiguration compareServer in _serviceConfiguration.GetServerList()) + { + if (server != compareServer) + { + if (server.GetProp("server-port").Equals(compareServer.GetProp("server-port")) || + server.GetProp("server-portv6").Equals(compareServer.GetProp("server-portv6")) || + server.GetProp("server-name").Equals(compareServer.GetProp("server-name"))) + { + _logger.AppendLine($"Duplicate server settings between servers {server.GetFileName()} and {compareServer.GetFileName()}."); + dupedSettingsFound = true; + } + } + } + } + if (dupedSettingsFound) + { + throw new Exception("Duplicate settings found! Check logs."); + } + foreach (var server in _serviceConfiguration.GetServerList()) + { + if (_updater.CheckVersionChanged() || !File.Exists(server.GetProp("ServerPath") + "\\bedrock_server.exe")) + { + _configurator.ReplaceServerBuild(server).Wait(); + } + if (server.GetProp("ServerExeName").ToString() != "bedrock_server.exe" && File.Exists(server.GetProp("ServerPath") + "\\bedrock_server.exe") && !File.Exists(server.GetProp("ServerPath") + "\\" + server.GetProp("ServerExeName"))) + { + File.Copy(server.GetProp("ServerPath") + "\\bedrock_server.exe", server.GetProp("ServerPath") + "\\" + server.GetProp("ServerExeName")); + } + } + if (_updater.CheckVersionChanged()) + _updater.MarkUpToDate(); + else + { + validating = false; + } + } + } + return true; + } + + public void RemoveBedrockServerByIndex(int serverIndex) + { + _bedrockServers.RemoveAt(serverIndex); + } + } +} diff --git a/BedrockService.backup/Service/Core/Interfaces/IBedrockService.cs b/BedrockService.backup/Service/Core/Interfaces/IBedrockService.cs new file mode 100644 index 00000000..4fadcf8e --- /dev/null +++ b/BedrockService.backup/Service/Core/Interfaces/IBedrockService.cs @@ -0,0 +1,22 @@ +using BedrockService.Service.Server; +using BedrockService.Shared.Interfaces; +using System.Collections.Generic; +using Topshelf; + +namespace BedrockService.Service.Core +{ + public interface IBedrockService : ServiceControl + { + IBedrockServer GetBedrockServerByIndex(int index); + + void RemoveBedrockServerByIndex(int serverIndex); + + IBedrockServer GetBedrockServerByName(string name); + + List GetAllServers(); + + void InitializeNewServer(IServerConfiguration serverConfiguration); + + void RestartService(); + } +} diff --git a/BedrockService.backup/Service/Core/Interfaces/IService.cs b/BedrockService.backup/Service/Core/Interfaces/IService.cs new file mode 100644 index 00000000..b4ef9e09 --- /dev/null +++ b/BedrockService.backup/Service/Core/Interfaces/IService.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; + +namespace BedrockService.Service.Core +{ + public interface IService + { + Task InitializeHost(); + Topshelf.TopshelfExitCode Run(); + } +} diff --git a/BedrockService/Service/Core/Interfaces/IServiceThread.cs b/BedrockService.backup/Service/Core/Interfaces/IServiceThread.cs similarity index 100% rename from BedrockService/Service/Core/Interfaces/IServiceThread.cs rename to BedrockService.backup/Service/Core/Interfaces/IServiceThread.cs diff --git a/BedrockService.backup/Service/Core/Service.cs b/BedrockService.backup/Service/Core/Service.cs new file mode 100644 index 00000000..87decbd5 --- /dev/null +++ b/BedrockService.backup/Service/Core/Service.cs @@ -0,0 +1,74 @@ +using BedrockService.Service.Core.Interfaces; +using BedrockService.Service.Core.Threads; +using BedrockService.Service.Networking; +using BedrockService.Service.Server; +using BedrockService.Shared.Interfaces; +using System; +using System.Threading; +using System.Threading.Tasks; +using Topshelf; +using Topshelf.Runtime; + +namespace BedrockService.Service.Core +{ + public class Service : IService + { + private readonly IBedrockService _bedrockService; + private Host _host; + private readonly ILogger _logger; + + public Service(ILogger logger, IBedrockService bedrockService) + { + _logger = logger; + _bedrockService = bedrockService; + } + + public async Task InitializeHost() + { + await Task.Run(() => + { + _host = HostFactory.New(hostConfig => + { + hostConfig.SetStartTimeout(TimeSpan.FromSeconds(10)); + hostConfig.SetStopTimeout(TimeSpan.FromSeconds(10)); + hostConfig.UseAssemblyInfoForServiceInfo(); + hostConfig.Service(settings => _bedrockService, s => + { + s.BeforeStartingService(_ => _logger.AppendLine("Starting service...")); + s.BeforeStoppingService(_ => + { + _logger.AppendLine("Stopping service..."); + foreach (IBedrockServer server in _bedrockService.GetAllServers()) + { + server.SetServerStatus(BedrockServer.ServerStatus.Stopping); + while (server.GetServerStatus() != BedrockServer.ServerStatus.Stopped) + Thread.Sleep(100); + } + }); + }); + + hostConfig.RunAsLocalSystem(); + hostConfig.SetDescription("Windows Service Wrapper for Windows Bedrock Server"); + hostConfig.SetDisplayName("BedrockService"); + hostConfig.SetServiceName("BedrockService"); + hostConfig.UnhandledExceptionPolicy = UnhandledExceptionPolicyCode.LogErrorOnly; + + hostConfig.EnableServiceRecovery(src => + { + src.RestartService(delayInMinutes: 0); + src.RestartService(delayInMinutes: 1); + src.SetResetPeriod(days: 1); + }); + + hostConfig.OnException((ex) => + { + _logger.AppendLine("Exception occured Main : " + ex.Message); + }); + }); + + }); + } + + public TopshelfExitCode Run() => _host.Run(); + } +} diff --git a/BedrockService/Service/Core/Threads/ClientServiceThread.cs b/BedrockService.backup/Service/Core/Threads/ClientServiceThread.cs similarity index 100% rename from BedrockService/Service/Core/Threads/ClientServiceThread.cs rename to BedrockService.backup/Service/Core/Threads/ClientServiceThread.cs diff --git a/BedrockService/Service/Core/Threads/HeartbeatThread.cs b/BedrockService.backup/Service/Core/Threads/HeartbeatThread.cs similarity index 100% rename from BedrockService/Service/Core/Threads/HeartbeatThread.cs rename to BedrockService.backup/Service/Core/Threads/HeartbeatThread.cs diff --git a/BedrockService/Service/Core/Threads/ServerProcessThread.cs b/BedrockService.backup/Service/Core/Threads/ServerProcessThread.cs similarity index 100% rename from BedrockService/Service/Core/Threads/ServerProcessThread.cs rename to BedrockService.backup/Service/Core/Threads/ServerProcessThread.cs diff --git a/BedrockService/Service/Core/Threads/TCPThread.cs b/BedrockService.backup/Service/Core/Threads/TCPThread.cs similarity index 100% rename from BedrockService/Service/Core/Threads/TCPThread.cs rename to BedrockService.backup/Service/Core/Threads/TCPThread.cs diff --git a/BedrockService/Service/Core/Threads/WatchdogThread.cs b/BedrockService.backup/Service/Core/Threads/WatchdogThread.cs similarity index 100% rename from BedrockService/Service/Core/Threads/WatchdogThread.cs rename to BedrockService.backup/Service/Core/Threads/WatchdogThread.cs diff --git a/BedrockService.backup/Service/Logging/ServiceLogger.cs b/BedrockService.backup/Service/Logging/ServiceLogger.cs new file mode 100644 index 00000000..7d3237fe --- /dev/null +++ b/BedrockService.backup/Service/Logging/ServiceLogger.cs @@ -0,0 +1,102 @@ +using BedrockService.Shared.Interfaces; +using Newtonsoft.Json; +using System; +using System.IO; +using System.Text; + +namespace BedrockService.Service.Logging +{ + public class ServiceLogger : ILogger + { + private readonly IServiceConfiguration _serviceConfiguration; + private StringBuilder _outputString = new StringBuilder(); + [NonSerialized] + private readonly StreamWriter _logWriter; + private readonly bool _logToFile = false; + private readonly bool _logToConsole = false; + private readonly string _parent = "Service"; + private readonly string _logPath; + + public ServiceLogger(IProcessInfo processInfo, IServiceConfiguration serviceConfiguration) + { + _serviceConfiguration = serviceConfiguration; + _logPath = $@"{processInfo.GetDirectory()}\Service\Logs"; + _logToFile = bool.Parse(serviceConfiguration.GetProp("LogServiceToFile").ToString()); + _logToConsole = true; + if (_logToFile) + { + if (!Directory.Exists(_logPath)) + Directory.CreateDirectory(_logPath); + _logWriter = new StreamWriter($@"{_logPath}\ServiceLog_{_parent}_{DateTime.Now:yyyymmddhhmmss}.log", true); + } + } + + [JsonConstructor] + public ServiceLogger(IServiceConfiguration serviceConfiguration, string serverName) + { + _serviceConfiguration = serviceConfiguration; + _parent = serverName; + _logToFile = false; + _logToConsole = false; + } + + public void AppendLine(string text) + { + try + { + _serviceConfiguration.GetLog().Add(text); + if (_logToFile && _logWriter != null) + { + _logWriter.WriteLine(text); + _logWriter.Flush(); + } + if (_logToConsole) + Console.WriteLine(text); + } + catch + { + } + } + + public void AppendText(string text) + { + try + { + _serviceConfiguration.GetLog().Add(text); + if (_logToFile && _logWriter != null) + { + _logWriter.Write(text); + _logWriter.Flush(); + } + if (_logToConsole) + { + Console.Write(text); + Console.Out.Flush(); + } + } + catch + { + } + } + + public int Count() + { + return _serviceConfiguration.GetLog().Count; + } + + public string FromIndex(int index) + { + return _serviceConfiguration.GetLog()[index]; + } + + public override string ToString() + { + _outputString = new StringBuilder(); + foreach (string s in _serviceConfiguration.GetLog()) + { + _outputString.Append(s); + } + return _outputString.ToString(); + } + } +} diff --git a/BedrockService.backup/Service/Management/ConfigManager.cs b/BedrockService.backup/Service/Management/ConfigManager.cs new file mode 100644 index 00000000..9a8900e5 --- /dev/null +++ b/BedrockService.backup/Service/Management/ConfigManager.cs @@ -0,0 +1,540 @@ +using BedrockService.Service.Server; +using BedrockService.Shared.Classes; +using BedrockService.Shared.Interfaces; +using BedrockService.Shared.Utilities; +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; +using System.Runtime.Serialization.Formatters.Binary; + +namespace BedrockService.Service.Management +{ + public class ConfigManager : IConfigurator + { + private readonly string _configDir; + private readonly string _globalFile; + private readonly string _clientKeyPath; + private readonly string _commsKeyPath; + private string _loadedVersion; + private static readonly object _fileLock = new object(); + private readonly IServiceConfiguration _serviceConfiguration; + private readonly IProcessInfo _processInfo; + private readonly ILogger _logger; + private CommsKeyContainer _keyContainer; + private RSAParameters _serviceKey; + private RSAParameters _clientKey; + + public ConfigManager(IProcessInfo processInfo, IServiceConfiguration serviceConfiguration, ILogger logger) + { + _processInfo = processInfo; + _serviceConfiguration = serviceConfiguration; + _logger = logger; + _configDir = $@"{_processInfo.GetDirectory()}\Server\Configs"; + _globalFile = $@"{_processInfo.GetDirectory()}\Service\Globals.conf"; + _clientKeyPath = $@"{_processInfo.GetDirectory()}\Client\ClientKey.dat"; + _commsKeyPath = $@"{_processInfo.GetDirectory()}\Service\CommsKey.dat"; + } + + public async Task LoadAllConfigurations() + { + await Task.Run(() => + { + BinaryFormatter formatter = new BinaryFormatter(); + if (!Directory.Exists(_configDir)) + Directory.CreateDirectory(_configDir); + if (!Directory.Exists($@"{_configDir}\KnownPlayers\Backups")) + Directory.CreateDirectory($@"{_configDir}\KnownPlayers\Backups"); + if (!Directory.Exists($@"{_configDir}\RegisteredPlayers\Backups")) + Directory.CreateDirectory($@"{_configDir}\RegisteredPlayers\Backups"); + if (!Directory.Exists($@"{_configDir}\Backups")) + Directory.CreateDirectory($@"{_configDir}\Backups"); + if (File.Exists($@"{_configDir}\..\bedrock_ver.ini")) + _loadedVersion = File.ReadAllText($@"{_configDir}\..\bedrock_ver.ini"); + if(!File.Exists(_commsKeyPath)) + { + RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048); + using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider()) + { + CommsKeyContainer serviceKeys = new CommsKeyContainer(); + CommsKeyContainer clientKeys = new CommsKeyContainer(); + serviceKeys.LocalPrivateKey.SetPrivateKey(rsa.ExportParameters(true)); + clientKeys.RemotePublicKey.SetPublicKey(rsa.ExportParameters(false)); + rsa = new RSACryptoServiceProvider(2048); + clientKeys.LocalPrivateKey.SetPrivateKey(rsa.ExportParameters(true)); + serviceKeys.RemotePublicKey.SetPublicKey(rsa.ExportParameters(false)); + aes.GenerateKey(); + aes.GenerateIV(); + serviceKeys.AesKey = aes.Key; + clientKeys.AesKey = aes.Key; + serviceKeys.AesIV = aes.IV; + clientKeys.AesIV = aes.IV; + formatter.Serialize(File.Create(_clientKeyPath), clientKeys); + formatter.Serialize(File.Create(_commsKeyPath), serviceKeys); + } + rsa.Clear(); + rsa.Dispose(); + } + else + { + try + { + _keyContainer = (CommsKeyContainer)formatter.Deserialize(File.Open(_commsKeyPath, FileMode.Open)); + _serviceKey = _keyContainer.LocalPrivateKey.GetPrivateKey(); + _clientKey = _keyContainer.RemotePublicKey.GetPrivateKey(); + } + catch + { + _logger.AppendLine("Error loading Encryption keys!"); + } + } + + ServerInfo serverInfo; + LoadGlobals(); + _serviceConfiguration.GetServerList().Clear(); + string[] files = Directory.GetFiles(_configDir, "*.conf"); + foreach (string file in files) + { + FileInfo FInfo = new FileInfo(file); + string[] fileEntries = File.ReadAllLines(file); + serverInfo = new ServerInfo(fileEntries, _serviceConfiguration.GetProp("ServersPath").ToString()); + LoadPlayerDatabase(serverInfo); + LoadRegisteredPlayers(serverInfo); + _serviceConfiguration.AddNewServerInfo(serverInfo); + } + if (_serviceConfiguration.GetServerList().Count == 0) + { + serverInfo = new ServerInfo(null, _serviceConfiguration.GetProp("ServersPath").ToString()); + serverInfo.InitializeDefaults(); + SaveServerProps(serverInfo, true); + _serviceConfiguration.AddNewServerInfo(serverInfo); + } + }); + } + + public void SaveGlobalFile() + { + string[] output = new string[_serviceConfiguration.GetAllProps().Count + 3]; + int index = 0; + output[index++] = "#Globals"; + output[index++] = string.Empty; + foreach (Property prop in _serviceConfiguration.GetAllProps()) + { + output[index++] = $"{prop.KeyName}={prop}"; + } + output[index++] = string.Empty; + + File.WriteAllLines(_globalFile, output); + } + + public void LoadRegisteredPlayers(IServerConfiguration server) + { + string serverName = server.GetServerName(); + string filePath = $@"{_configDir}\RegisteredPlayers\{serverName}.preg"; + if (!File.Exists(filePath)) + { + File.Create(filePath).Close(); + return; + } + foreach (string entry in File.ReadLines(filePath)) + { + if (entry.StartsWith("#") || string.IsNullOrWhiteSpace(entry)) + continue; + string[] split = entry.Split(','); + _logger.AppendLine($"Server \"{server.GetServerName()}\" Loaded registered player: {split[1]}"); + IPlayer playerFound = server.GetPlayerByXuid(split[0]); + if (playerFound == null) + { + server.AddUpdatePlayer(new Player(split[0], split[1], DateTime.Now.Ticks.ToString(), "0", "0", split[3].ToLower() == "true", split[2], split[4].ToLower() == "true")); + continue; + } + string[] playerTimes = playerFound.GetTimes(); + server.AddUpdatePlayer(new Player(split[0], split[1], playerTimes[0], playerTimes[1], playerTimes[2], split[3].ToLower() == "true", split[2], split[4].ToLower() == "true")); + } + } + + private void LoadGlobals() + { + if (File.Exists(_globalFile)) + { + _logger.AppendLine("Loading Globals..."); + _serviceConfiguration.ProcessConfiguration(File.ReadAllLines(_globalFile)); + _serviceConfiguration.SetServerVersion(_loadedVersion); + return; + } + _serviceConfiguration.InitializeDefaults(); + _logger.AppendLine("Globals.conf was not found. Loaded defaults and saved to file."); + SaveGlobalFile(); + } + + private int RoundOff(int i) + { + return ((int)Math.Round(i / 10.0)) * 10; + } + + public async Task ReplaceServerBuild(IServerConfiguration server) + { + await Task.Run(() => + { + try + { + if (!Directory.Exists(server.GetProp("ServerPath").ToString())) + Directory.CreateDirectory(server.GetProp("ServerPath").ToString()); + while (_serviceConfiguration.GetServerVersion() == null || _serviceConfiguration.GetServerVersion() == "None") + { + Thread.Sleep(150); + } + using (ZipArchive archive = ZipFile.OpenRead($@"{_processInfo.GetDirectory()}\Server\MCSFiles\Update_{ _serviceConfiguration.GetServerVersion()}.zip")) + { + int fileCount = archive.Entries.Count; + for(int i=0; i 2) + { + sb.Remove(sb.Length - 2, 2); + } + sb.Append("\n]"); + File.WriteAllText($@"{server.GetProp("ServerPath")}\whitelist.json", sb.ToString()); + sb = new StringBuilder(); + sb.Append("[\n"); + + foreach (Player player in server.GetPlayerList()) + { + string[] playerReg = player.GetRegistration(); + if (!player.IsDefaultRegistration() && playerReg[0] == "False") + { + sb.Append("\t{\n"); + sb.Append($"\t\t\"permission\": \"{playerReg[1]}\",\n"); + sb.Append($"\t\t\"xuid\": \"{player.GetXUID()}\"\n"); + sb.Append("\t},\n"); + } + } + if (sb.Length > 2) + { + sb.Remove(sb.Length - 2, 2); + } + sb.Append("\n]"); + File.WriteAllText($@"{server.GetProp("ServerPath")}\permissions.json", sb.ToString()); + } + + public void SaveServerProps(IServerConfiguration server, bool SaveServerInfo) + { + int index = 0; + string[] output = new string[5 + server.GetAllProps().Count + server.GetStartCommands().Count]; + output[index++] = "#Server"; + foreach (Property prop in server.GetAllProps()) + { + output[index++] = $"{prop.KeyName}={prop}"; + } + if (!SaveServerInfo) + { + if (!Directory.Exists(server.GetProp("ServerPath").ToString())) + { + Directory.CreateDirectory(server.GetProp("ServerPath").ToString()); + } + File.WriteAllLines($@"{server.GetProp("ServerPath")}\server.properties", output); + } + else + { + output[index++] = string.Empty; + output[index++] = "#StartCmds"; + + foreach (StartCmdEntry startCmd in server.GetStartCommands()) + { + output[index++] = $"AddStartCmd={startCmd.Command}"; + } + output[index++] = string.Empty; + + File.WriteAllLines($@"{_configDir}\{server.GetFileName()}", output); + if (server.GetProp("ServerPath").ToString() == null) + server.GetProp("ServerPath").SetValue(server.GetProp("ServerPath").DefaultValue); + if (!Directory.Exists(server.GetProp("ServerPath").ToString())) + { + Directory.CreateDirectory(server.GetProp("ServerPath").ToString()); + } + File.WriteAllLines($@"{server.GetProp("ServerPath")}\server.properties", output); + } + } + + public void RemoveServerConfigs(IServerConfiguration serverInfo, NetworkMessageFlags flag) + { + try + { + File.Delete($@"{_configDir}\{serverInfo.GetFileName()}"); + switch (flag) + { + case NetworkMessageFlags.RemoveBckPly: + if (DeleteBackups(serverInfo)) + _logger.AppendLine($"Deleted Backups for server {serverInfo.GetServerName()}"); + if (DeletePlayerFiles(serverInfo)) + _logger.AppendLine($"Deleted Player files for server {serverInfo.GetServerName()}"); + break; + case NetworkMessageFlags.RemoveBckSrv: + if (DeleteBackups(serverInfo)) + _logger.AppendLine($"Deleted Backups for server {serverInfo.GetServerName()}"); + if (DeleteServerFiles(serverInfo)) + _logger.AppendLine($"Deleted server directory for server {serverInfo.GetServerName()}"); + break; + case NetworkMessageFlags.RemovePlySrv: + if (DeletePlayerFiles(serverInfo)) + _logger.AppendLine($"Deleted Player files for server {serverInfo.GetServerName()}"); + if (DeleteServerFiles(serverInfo)) + _logger.AppendLine($"Deleted server directory for server {serverInfo.GetServerName()}"); + break; + case NetworkMessageFlags.RemoveSrv: + if (DeleteServerFiles(serverInfo)) + _logger.AppendLine($"Deleted server directory for server {serverInfo.GetServerName()}"); + break; + case NetworkMessageFlags.RemovePlayers: + if (DeletePlayerFiles(serverInfo)) + _logger.AppendLine($"Deleted Player files for server {serverInfo.GetServerName()}"); + break; + case NetworkMessageFlags.RemoveBackups: + if (DeleteBackups(serverInfo)) + _logger.AppendLine($"Deleted Backups for server {serverInfo.GetServerName()}"); + break; + case NetworkMessageFlags.RemoveAll: + if (DeleteBackups(serverInfo)) + _logger.AppendLine($"Deleted Backups for server {serverInfo.GetServerName()}"); + if (DeletePlayerFiles(serverInfo)) + _logger.AppendLine($"Deleted Player files for server {serverInfo.GetServerName()}"); + if (DeleteServerFiles(serverInfo)) + _logger.AppendLine($"Deleted server directory for server {serverInfo.GetServerName()}"); + break; + case NetworkMessageFlags.None: + break; + } + _serviceConfiguration.RemoveServerInfo(serverInfo); + + } + catch { } + } + + public List EnumerateBackupsForServer(byte serverIndex) + { + string serverName = _serviceConfiguration.GetServerInfoByIndex(serverIndex).GetServerName(); + List newList = new List(); + try + { + foreach (DirectoryInfo dir in new DirectoryInfo($@"{_serviceConfiguration.GetProp("BackupPath")}\{serverName}").GetDirectories()) + { + string[] splitName = dir.Name.Split('_'); + newList.Add(new Property(dir.Name, new DateTime(long.Parse(splitName[1])).ToString("G"))); + } + } + catch (IOException) + { + return newList; + } + return newList; + } + + public void DeleteBackupsForServer(byte serverIndex, List list) + { + string serverName = _serviceConfiguration.GetServerInfoByIndex(serverIndex).GetServerName(); + try + { + foreach (string deleteDir in list) + foreach (DirectoryInfo dir in new DirectoryInfo($@"{_serviceConfiguration.GetProp("BackupPath")}\{serverName}").GetDirectories()) + if (dir.Name == deleteDir) + { + new FileUtils(_processInfo.GetDirectory()).DeleteFilesRecursively(new DirectoryInfo($@"{_serviceConfiguration.GetProp("BackupPath")}\{serverName}\{deleteDir}"), true); + _logger.AppendLine($"Deleted backup {deleteDir}."); + } + } + catch (IOException e) + { + _logger.AppendLine($"Error deleting selected backups! {e.Message}"); + } + } + + private bool DeleteBackups(IServerConfiguration serverInfo) + { + try + { + string configBackupPath = ""; + DirectoryInfo backupDirInfo = new DirectoryInfo($@"{configBackupPath}\{serverInfo.GetServerName()}"); + DirectoryInfo configBackupDirInfo = new DirectoryInfo($@"{_configDir}\Backups"); + foreach (DirectoryInfo dir in backupDirInfo.GetDirectories()) + { + if (dir.Name.Contains($"{serverInfo.GetServerName()}")) + { + dir.Delete(true); + } + } + foreach (FileInfo file in configBackupDirInfo.GetFiles()) + { + if (file.Name.Contains($"{serverInfo.GetServerName()}_")) + { + file.Delete(); + } + } + return true; + } + catch { return false; } + } + + private bool DeleteServerFiles(IServerConfiguration serverInfo) + { + try + { + new FileUtils(_processInfo.GetDirectory()).DeleteFilesRecursively(new DirectoryInfo(serverInfo.GetProp("ServerPath").ToString()), false); + return true; + } + catch { return false; } + } + + private bool DeletePlayerFiles(IServerConfiguration serverInfo) + { + try + { + DirectoryInfo configDirInfo = new DirectoryInfo(_configDir); + foreach (DirectoryInfo dir in configDirInfo.GetDirectories()) + { + if (dir.Name == "KnownPlayers" || dir.Name == "RegisteredPlayers") + { + foreach (FileInfo file in dir.GetFiles()) + { + if (file.Name.Contains($"{serverInfo.GetServerName()}")) + { + file.Delete(); + } + } + } + } + return true; + } + catch { return false; } + } + + public CommsKeyContainer GetKeyContainer() => _keyContainer; + + public Task LoadConfiguration(IConfiguration configuration) + { + throw new NotImplementedException(); + } + + public Task SaveConfiguration(IConfiguration configuration) + { + throw new NotImplementedException(); + } + } +} + diff --git a/BedrockService.backup/Service/Management/IConfigurator.cs b/BedrockService.backup/Service/Management/IConfigurator.cs new file mode 100644 index 00000000..f783eb53 --- /dev/null +++ b/BedrockService.backup/Service/Management/IConfigurator.cs @@ -0,0 +1,26 @@ +using BedrockService.Service.Server; +using BedrockService.Shared.Classes; +using BedrockService.Shared.Interfaces; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace BedrockService.Service.Management +{ + public interface IConfigurator + { + void DeleteBackupsForServer(byte serverIndex, List list); + List EnumerateBackupsForServer(byte serverIndex); + Task LoadAllConfigurations(); + Task LoadConfiguration(IConfiguration configuration); + void LoadPlayerDatabase(IServerConfiguration server); + void LoadRegisteredPlayers(IServerConfiguration server); + void RemoveServerConfigs(IServerConfiguration serverInfo, NetworkMessageFlags flag); + Task ReplaceServerBuild(IServerConfiguration server); + Task SaveConfiguration(IConfiguration configuration); + void SaveGlobalFile(); + void SaveKnownPlayerDatabase(IServerConfiguration server); + void SaveServerProps(IServerConfiguration server, bool SaveServerInfo); + void WriteJSONFiles(IServerConfiguration server); + CommsKeyContainer GetKeyContainer(); + } +} \ No newline at end of file diff --git a/BedrockService.backup/Service/Networking/ITCPListener.cs b/BedrockService.backup/Service/Networking/ITCPListener.cs new file mode 100644 index 00000000..f726dc8f --- /dev/null +++ b/BedrockService.backup/Service/Networking/ITCPListener.cs @@ -0,0 +1,17 @@ +using BedrockService.Service.Networking.NetworkMessageClasses; +using BedrockService.Shared.Classes; +using System.Collections.Generic; + +namespace BedrockService.Service.Networking +{ + public interface ITCPListener : IMessageSender + { + void StartListening(); + + void ResetListener(); + + void SetStrategyDictionaries(Dictionary standard, Dictionary flagged); + + void SetKeyContainer(CommsKeyContainer keyContainer); + } +} diff --git a/BedrockService.backup/Service/Networking/IUpdater.cs b/BedrockService.backup/Service/Networking/IUpdater.cs new file mode 100644 index 00000000..e436d0d4 --- /dev/null +++ b/BedrockService.backup/Service/Networking/IUpdater.cs @@ -0,0 +1,14 @@ +using BedrockService.Shared.Interfaces; +using System.Threading.Tasks; + +namespace BedrockService.Service.Networking +{ + public interface IUpdater + { + Task CheckUpdates(); + Task FetchBuild(string path, string version); + bool CheckVersionChanged(); + void MarkUpToDate(); + Task ReplaceBuild(IServerConfiguration serverConfiguration); + } +} \ No newline at end of file diff --git a/BedrockService.backup/Service/Networking/MessageInterfaces/IFlaggedMessageParser.cs b/BedrockService.backup/Service/Networking/MessageInterfaces/IFlaggedMessageParser.cs new file mode 100644 index 00000000..83833ec2 --- /dev/null +++ b/BedrockService.backup/Service/Networking/MessageInterfaces/IFlaggedMessageParser.cs @@ -0,0 +1,9 @@ +using BedrockService.Shared.Classes; + +namespace BedrockService.Service.Networking.NetworkMessageClasses +{ + public interface IFlaggedMessageParser + { + void ParseMessage(byte[] data, byte serverIndex, NetworkMessageFlags flag); + } +} diff --git a/BedrockService.backup/Service/Networking/MessageInterfaces/IMessageParser.cs b/BedrockService.backup/Service/Networking/MessageInterfaces/IMessageParser.cs new file mode 100644 index 00000000..22b39d28 --- /dev/null +++ b/BedrockService.backup/Service/Networking/MessageInterfaces/IMessageParser.cs @@ -0,0 +1,7 @@ +namespace BedrockService.Service.Networking.NetworkMessageClasses +{ + public interface IMessageParser + { + void ParseMessage(byte[] data, byte serverIndex); + } +} diff --git a/BedrockService.backup/Service/Networking/MessageInterfaces/IMessageSender.cs b/BedrockService.backup/Service/Networking/MessageInterfaces/IMessageSender.cs new file mode 100644 index 00000000..1d7aaf13 --- /dev/null +++ b/BedrockService.backup/Service/Networking/MessageInterfaces/IMessageSender.cs @@ -0,0 +1,19 @@ +using BedrockService.Shared.Classes; + +namespace BedrockService.Service.Networking.NetworkMessageClasses +{ + public interface IMessageSender + { + void SendData(byte[] bytes, NetworkMessageSource source, NetworkMessageDestination destination, byte serverIndex, NetworkMessageTypes type, NetworkMessageFlags status); + + void SendData(NetworkMessageSource source, NetworkMessageDestination destination, NetworkMessageTypes type); + + void SendData(NetworkMessageSource source, NetworkMessageDestination destination, byte serverIndex, NetworkMessageTypes type); + + void SendData(byte[] bytes, NetworkMessageSource source, NetworkMessageDestination destination, byte serverIndex, NetworkMessageTypes type); + + void SendData(byte[] bytes, NetworkMessageSource source, NetworkMessageDestination destination, NetworkMessageTypes type); + + void SendData(NetworkMessageSource source, NetworkMessageDestination destination, NetworkMessageTypes type, NetworkMessageFlags status); + } +} \ No newline at end of file diff --git a/BedrockService.backup/Service/Networking/NetworkStrategyLookup.cs b/BedrockService.backup/Service/Networking/NetworkStrategyLookup.cs new file mode 100644 index 00000000..4f5ce7a6 --- /dev/null +++ b/BedrockService.backup/Service/Networking/NetworkStrategyLookup.cs @@ -0,0 +1,654 @@ +using BedrockService.Service.Core; +using BedrockService.Service.Management; +using BedrockService.Service.Networking.NetworkMessageClasses; +using BedrockService.Service.Server; +using BedrockService.Shared.Classes; +using BedrockService.Shared.Interfaces; +using BedrockService.Shared.PackParser; +using BedrockService.Shared.Utilities; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; + +namespace BedrockService.Service.Networking +{ + public class NetworkStrategyLookup + { + private readonly Dictionary _standardMessageLookup; + private readonly Dictionary _flaggedMessageLookup; + + public NetworkStrategyLookup(ITCPListener messageSender, IBedrockService service, ILogger logger, IConfigurator configurator, IServiceConfiguration serviceConfiguration, IProcessInfo processInfo, IUpdater updater) + { + _standardMessageLookup = new Dictionary() + { + {NetworkMessageTypes.DelBackups, new DeleteBackups(configurator) }, + {NetworkMessageTypes.BackupAll, new ServerBackupAll(messageSender, service) }, + {NetworkMessageTypes.EnumBackups, new EnumBackups(configurator, messageSender) }, + {NetworkMessageTypes.Backup, new ServerBackup(messageSender, service) }, + {NetworkMessageTypes.PropUpdate, new ServerPropUpdate(configurator, serviceConfiguration, messageSender, service) }, + {NetworkMessageTypes.Restart, new ServerRestart(messageSender, service) }, + {NetworkMessageTypes.Command, new ServerCommand(messageSender, service, logger) }, + {NetworkMessageTypes.PackList, new PackList(messageSender, processInfo, serviceConfiguration, logger) }, + {NetworkMessageTypes.RemovePack, new RemovePack(messageSender, processInfo, serviceConfiguration) }, + {NetworkMessageTypes.PackFile, new PackFile(serviceConfiguration, processInfo, logger) }, + {NetworkMessageTypes.Connect, new Connect(messageSender, serviceConfiguration) }, + {NetworkMessageTypes.StartCmdUpdate, new StartCmdUpdate(configurator, serviceConfiguration) }, + {NetworkMessageTypes.CheckUpdates, new CheckUpdates(messageSender, updater) }, + {NetworkMessageTypes.BackupRollback, new BackupRollback(messageSender, service) }, + {NetworkMessageTypes.AddNewServer, new AddNewServer(configurator, messageSender, serviceConfiguration, service) }, + {NetworkMessageTypes.ConsoleLogUpdate, new ConsoleLogUpdate(messageSender, serviceConfiguration, service) }, + {NetworkMessageTypes.PlayersRequest, new PlayerRequest(messageSender, serviceConfiguration) }, + {NetworkMessageTypes.PlayersUpdate, new PlayersUpdate(configurator, messageSender, serviceConfiguration, service) }, + {NetworkMessageTypes.LevelEditRequest, new LevelEditRequest(messageSender, serviceConfiguration) }, + {NetworkMessageTypes.LevelEditFile, new LevelEditFile(serviceConfiguration, service) } + }; + _flaggedMessageLookup = new Dictionary() + { + {NetworkMessageTypes.RemoveServer, new RemoveServer(configurator, messageSender, serviceConfiguration, service) }, + }; + messageSender.SetStrategyDictionaries(_standardMessageLookup, _flaggedMessageLookup); + } + + class DeleteBackups : IMessageParser + { + private readonly IConfigurator _configurator; + + public DeleteBackups(IConfigurator configurator) + { + _configurator = configurator; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + string stringData = Encoding.UTF8.GetString(data, 5, data.Length - 5); + List backupFileNames = JsonConvert.DeserializeObject>(stringData, settings); + _configurator.DeleteBackupsForServer(serverIndex, backupFileNames); + } + } + + class ServerBackupAll : IMessageParser + { + private readonly IMessageSender _messageSender; + private readonly IBedrockService _service; + + public ServerBackupAll(IMessageSender messageSender, IBedrockService service) + { + _messageSender = messageSender; + _service = service; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + foreach (IBedrockServer server in _service.GetAllServers()) + server.RestartServer(true); + _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.UICallback); + } + } + + class ServerBackup : IMessageParser + { + private readonly IMessageSender _messageSender; + private readonly IBedrockService _service; + public ServerBackup(IMessageSender messageSender, IBedrockService service) + { + _messageSender = messageSender; + _service = service; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + _service.GetBedrockServerByIndex(serverIndex).RestartServer(true); + _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.UICallback); + } + } + + class EnumBackups : IMessageParser + { + private readonly IConfigurator _configurator; + private readonly IMessageSender _messageSender; + public EnumBackups(IConfigurator configurator, IMessageSender messageSender) + { + _configurator = configurator; + _messageSender = messageSender; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + Formatting indented = Formatting.Indented; + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(_configurator.EnumerateBackupsForServer(serverIndex), indented, settings)); + _messageSender.SendData(serializeToBytes, NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.EnumBackups); + + } + } + + class ServerPropUpdate : IMessageParser + { + private readonly IServiceConfiguration _serviceConfiguration; + private readonly IMessageSender _messageSender; + private readonly IBedrockService _bedrockService; + private readonly IConfigurator _configurator; + + public ServerPropUpdate(IConfigurator configurator, IServiceConfiguration serviceConfiguration, IMessageSender messageSender, IBedrockService bedrockService) + { + _configurator = configurator; + _serviceConfiguration = serviceConfiguration; + _messageSender = messageSender; + _bedrockService = bedrockService; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + string stringData = Encoding.UTF8.GetString(data, 5, data.Length - 5); + List propList = JsonConvert.DeserializeObject>(stringData, settings); + Property prop = propList.FirstOrDefault(p => p.KeyName == "server-name"); + if(prop == null) + { + _serviceConfiguration.SetAllProps(propList); + _configurator.SaveGlobalFile(); + _bedrockService.RestartService(); + _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.UICallback); + return; + } + _serviceConfiguration.GetServerInfoByIndex(serverIndex).SetAllProps(propList); + _bedrockService.GetBedrockServerByIndex(serverIndex).SetServerStatus(BedrockServer.ServerStatus.Stopping); + while (_bedrockService.GetBedrockServerByIndex(serverIndex).GetServerStatus() == BedrockServer.ServerStatus.Stopping) + { + Thread.Sleep(100); + } + _bedrockService.GetBedrockServerByIndex(serverIndex).SetServerStatus(BedrockServer.ServerStatus.Starting); + _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.UICallback); + } + } + + class ServerRestart : IMessageParser + { + private readonly IMessageSender _messageSender; + private readonly IBedrockService _service; + public ServerRestart(IMessageSender messageSender, IBedrockService service) + { + _messageSender = messageSender; + _service = service; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + _service.GetBedrockServerByIndex(serverIndex).RestartServer(false); + _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.UICallback); + } + } + + class ServerCommand : IMessageParser + { + private readonly IBedrockService _service; + private readonly ILogger _logger; + private readonly IMessageSender _messageSender; + + public ServerCommand(IMessageSender messageSender, IBedrockService service, ILogger logger) + { + _messageSender = messageSender; + _service = service; + _logger = logger; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + string stringData = Encoding.UTF8.GetString(data, 5, data.Length - 5); + _service.GetBedrockServerByIndex(serverIndex).WriteToStandardIn(stringData); + _logger.AppendLine($"Sent command {stringData} to stdInput stream"); + _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.UICallback); + } + } + + class PackList : IMessageParser + { + private readonly IMessageSender _messageSender; + private readonly IServiceConfiguration _serviceConfiguration; + private readonly IProcessInfo _processInfo; + private readonly ILogger _logger; + + public PackList(IMessageSender messageSender, IProcessInfo processInfo, IServiceConfiguration serviceConfiguration, ILogger logger) + { + _logger = logger; + _messageSender = messageSender; + _serviceConfiguration = serviceConfiguration; + _processInfo = processInfo; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + if (!File.Exists($@"{_processInfo.GetDirectory()}\Server\stock_packs.json")) + File.Copy($@"{_serviceConfiguration.GetServerInfoByIndex(serverIndex).GetProp("ServerPath")}\valid_known_packs.json", $@"{_processInfo.GetDirectory()}\Server\stock_packs.json"); + MinecraftKnownPacksClass knownPacks = new MinecraftKnownPacksClass($@"{_serviceConfiguration.GetServerInfoByIndex(serverIndex).GetProp("ServerPath")}\valid_known_packs.json", $@"{_processInfo.GetDirectory()}\Server\stock_packs.json"); + List list = new List(); + foreach (MinecraftKnownPacksClass.KnownPack pack in knownPacks.KnownPacks) + { + MinecraftPackParser currentParser = new MinecraftPackParser(_logger, _processInfo); + currentParser.ParseDirectory(new DirectoryInfo($@"{_serviceConfiguration.GetServerInfoByIndex(serverIndex).GetProp("ServerPath")}\{pack.path.Replace(@"/", @"\")}")); + list.Add(currentParser); + } + string arrayString = JArray.FromObject(list).ToString(); + _messageSender.SendData(Encoding.UTF8.GetBytes(arrayString), NetworkMessageSource.Server, NetworkMessageDestination.Client, NetworkMessageTypes.PackList); + } + } + + class RemovePack : IMessageParser + { + private readonly IMessageSender _messageSender; + private readonly IServiceConfiguration _serviceConfiguration; + private readonly IProcessInfo _processInfo; + + public RemovePack(IMessageSender messageSender, IProcessInfo processInfo, IServiceConfiguration serviceConfiguration) + { + _messageSender = messageSender; + _serviceConfiguration = serviceConfiguration; + _processInfo = processInfo; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + string stringData = Encoding.UTF8.GetString(data, 5, data.Length - 5); + MinecraftKnownPacksClass knownPacks = new MinecraftKnownPacksClass($@"{_serviceConfiguration.GetServerInfoByIndex(serverIndex).GetProp("ServerPath")}\valid_known_packs.json", $@"{_processInfo.GetDirectory()}\Server\stock_packs.json"); + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + List MCContainer = JsonConvert.DeserializeObject>(stringData, settings); + foreach (MinecraftPackContainer cont in MCContainer) + knownPacks.RemovePackFromServer(_serviceConfiguration.GetServerInfoByIndex(serverIndex).GetProp("ServerPath").ToString(), cont); + _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.UICallback); + } + } + + class LevelEditRequest : IMessageParser + { + private readonly IMessageSender _messageSender; + private readonly IServiceConfiguration _serviceConfiguration; + + public LevelEditRequest(IMessageSender messageSender, IServiceConfiguration serviceConfiguration) + { + _messageSender = messageSender; + _serviceConfiguration = serviceConfiguration; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + IServerConfiguration server = _serviceConfiguration.GetServerInfoByIndex(serverIndex); + string pathToLevelDat = $@"{_serviceConfiguration.GetServerInfoByIndex(serverIndex).GetProp("ServerPath")}\worlds\{server.GetProp("level-name")}\level.dat"; + byte[] levelDatToBytes = File.ReadAllBytes(pathToLevelDat); + _messageSender.SendData(levelDatToBytes, NetworkMessageSource.Server, NetworkMessageDestination.Client, NetworkMessageTypes.LevelEditFile); + } + } + + class PlayersUpdate : IMessageParser + { + private readonly IMessageSender _messageSender; + private readonly IServiceConfiguration _serviceConfiguration; + private readonly IConfigurator _configurator; + private readonly IBedrockService _service; + + public PlayersUpdate(IConfigurator configurator, IMessageSender messageSender, IServiceConfiguration serviceConfiguration, IBedrockService service) + { + _service = service; + _configurator = configurator; + _messageSender = messageSender; + _serviceConfiguration = serviceConfiguration; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + string stringData = Encoding.UTF8.GetString(data, 5, data.Length - 5); + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + List fetchedPlayers = JsonConvert.DeserializeObject>(stringData, settings); + foreach (IPlayer player in fetchedPlayers) + { + try + { + _serviceConfiguration.GetServerInfoByIndex(serverIndex).AddUpdatePlayer(player); + } + catch (Exception) + { + } + } + _configurator.SaveKnownPlayerDatabase(_serviceConfiguration.GetServerInfoByIndex(serverIndex)); + _configurator.WriteJSONFiles(_serviceConfiguration.GetServerInfoByIndex(serverIndex)); + Task.Delay(500).Wait(); + _service.GetBedrockServerByIndex(serverIndex).WriteToStandardIn("ops reload"); + _service.GetBedrockServerByIndex(serverIndex).WriteToStandardIn("whitelist reload"); + _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.UICallback); + + } + } + + class PackFile : IMessageParser + { + private readonly IServiceConfiguration _serviceConfiguration; + private readonly IProcessInfo _serviceProcessInfo; + private readonly ILogger _logger; + + public PackFile(IServiceConfiguration serviceConfiguration, IProcessInfo serviceProcessInfo, ILogger logger) + { + _logger = logger; + _serviceProcessInfo = serviceProcessInfo; + _serviceConfiguration = serviceConfiguration; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + MinecraftPackParser archiveParser = new MinecraftPackParser(data, _logger, _serviceProcessInfo); + foreach (MinecraftPackContainer container in archiveParser.FoundPacks) + { + string serverPath = _serviceConfiguration.GetServerInfoByIndex(serverIndex).GetProp("ServerPath").ToString(); + if (container.ManifestType == "WorldPack") + new FileUtils(_serviceProcessInfo.GetDirectory()).CopyFilesRecursively(container.PackContentLocation, new DirectoryInfo($@"{serverPath}\worlds\{container.FolderName}")); + if (container.ManifestType == "data") + new FileUtils(_serviceProcessInfo.GetDirectory()).CopyFilesRecursively(container.PackContentLocation, new DirectoryInfo($@"{serverPath}\behavior_packs\{container.FolderName}")); + if (container.ManifestType == "resources") + new FileUtils(_serviceProcessInfo.GetDirectory()).CopyFilesRecursively(container.PackContentLocation, new DirectoryInfo($@"{serverPath}\resource_packs\{container.FolderName}")); + } + } + } + + class LevelEditFile : IMessageParser + { + private readonly IServiceConfiguration _serviceConfiguration; + private readonly IBedrockService _bedrockService; + + public LevelEditFile(IServiceConfiguration serviceConfiguration, IBedrockService bedrockService) + { + _bedrockService = bedrockService; + _serviceConfiguration = serviceConfiguration; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + byte[] stripHeaderFromBuffer = new byte[data.Length - 5]; + Buffer.BlockCopy(data, 5, stripHeaderFromBuffer, 0, stripHeaderFromBuffer.Length); + IServerConfiguration server = _serviceConfiguration.GetServerInfoByIndex(serverIndex); + string pathToLevelDat = $@"{_serviceConfiguration.GetProp("ServersPath")}\{server.GetProp("server-name")}\worlds\{server.GetProp("level-name")}\level.dat"; + _bedrockService.GetBedrockServerByIndex(serverIndex).StopServer().Wait(); + File.WriteAllBytes(pathToLevelDat, stripHeaderFromBuffer); + _bedrockService.GetBedrockServerByIndex(serverIndex).SetServerStatus(BedrockServer.ServerStatus.Starting); + } + } + + class Connect : IMessageParser + { + private readonly IMessageSender _iTCPListener; + private readonly IServiceConfiguration _serviceConfiguration; + + public Connect(ITCPListener iTCPListener, IServiceConfiguration serviceConfiguration) + { + _iTCPListener = iTCPListener; + _serviceConfiguration = serviceConfiguration; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + Formatting indented = Formatting.Indented; + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + string jsonString = JsonConvert.SerializeObject(_serviceConfiguration, indented, settings); + byte[] serializeToBytes = Encoding.UTF8.GetBytes(jsonString); + _iTCPListener.SendData(serializeToBytes, NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.Connect); + } + } + + class StartCmdUpdate : IMessageParser + { + private readonly IServiceConfiguration _serviceConfiguration; + private readonly IConfigurator _configurator; + + public StartCmdUpdate(IConfigurator configurator, IServiceConfiguration serviceConfiguration) + { + _configurator = configurator; + _serviceConfiguration = serviceConfiguration; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + _serviceConfiguration.GetServerInfoByIndex(serverIndex).SetStartCommands(JsonConvert.DeserializeObject>(Encoding.UTF8.GetString(data, 5, data.Length - 5), settings)); + _configurator.SaveServerProps(_serviceConfiguration.GetServerInfoByIndex(serverIndex), true); + } + } + + class CheckUpdates : IMessageParser + { + private readonly IMessageSender _messageSender; + private readonly IUpdater _updater; + + public CheckUpdates(IMessageSender messageSender, IUpdater updater) + { + _updater = updater; + _messageSender = messageSender; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + _updater.CheckUpdates().Wait(); + if (_updater.CheckVersionChanged()) + { + _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.CheckUpdates); + } + + _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.UICallback); + } + } + + class BackupRollback : IMessageParser + { + private readonly IMessageSender _messageSender; + private readonly IBedrockService _service; + + public BackupRollback(IMessageSender messageSender, IBedrockService service) + { + _service = service; + _messageSender = messageSender; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + string stringData = Encoding.UTF8.GetString(data, 5, data.Length - 5); + _service.GetBedrockServerByIndex(serverIndex).RollbackToBackup(serverIndex, stringData); + _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.UICallback); + } + } + + class AddNewServer : IMessageParser + { + private readonly IMessageSender _messageSender; + private readonly IServiceConfiguration _serviceConfiguration; + private readonly IConfigurator _configurator; + private readonly IBedrockService _bedrockService; + + public AddNewServer(IConfigurator configurator, IMessageSender messageSender, IServiceConfiguration serviceConfiguration, IBedrockService bedrockService) + { + _bedrockService = bedrockService; + _configurator = configurator; + _messageSender = messageSender; + _serviceConfiguration = serviceConfiguration; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + string stringData = Encoding.UTF8.GetString(data, 5, data.Length - 5); + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + List propList = JsonConvert.DeserializeObject>(stringData, settings); + Property serverNameProp = propList.First(p => p.KeyName == "server-name"); + ServerInfo newServer = new ServerInfo(null, _serviceConfiguration.GetProp("ServersPath").ToString()) + { + ServerName = serverNameProp.ToString(), + ServerPropList = propList, + ServerPath = new Property("ServerPath", "") + { + Value = $@"{_serviceConfiguration.GetProp("ServersPath")}\{serverNameProp}" + }, + ServerExeName = new Property("ServerExeName", "") + { + Value = $"BedrockService.{serverNameProp}.exe" + }, + FileName = $@"{serverNameProp}.conf" + }; + _configurator.SaveServerProps(newServer, true); + _bedrockService.InitializeNewServer(newServer); + + byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(_serviceConfiguration, Formatting.Indented, settings)); + _messageSender.SendData(serializeToBytes, NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.Connect); + _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.UICallback); + + } + } + + class RemoveServer : IFlaggedMessageParser + { + private readonly IMessageSender _messageSender; + private readonly IServiceConfiguration _serviceConfiguration; + private readonly IConfigurator _configurator; + private readonly IBedrockService _bedrockService; + + public RemoveServer(IConfigurator configurator, IMessageSender messageSender, IServiceConfiguration serviceConfiguration, IBedrockService bedrockService) + { + this._bedrockService = bedrockService; + _configurator = configurator; + _messageSender = messageSender; + _serviceConfiguration = serviceConfiguration; + } + + public void ParseMessage(byte[] data, byte serverIndex, NetworkMessageFlags flag) + { + _bedrockService.GetBedrockServerByIndex(serverIndex).StopServer().Wait(); + _configurator.RemoveServerConfigs(_serviceConfiguration.GetServerInfoByIndex(serverIndex), flag); + _bedrockService.RemoveBedrockServerByIndex(serverIndex); + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(_serviceConfiguration, Formatting.Indented, settings)); + _messageSender.SendData(serializeToBytes, NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.Connect); + _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.UICallback); + + } + } + + class ConsoleLogUpdate : IMessageParser + { + private readonly IMessageSender _messageSender; + private readonly IBedrockService _service; + private readonly IServiceConfiguration _serviceConfiguration; + + public ConsoleLogUpdate(IMessageSender messageSender, IServiceConfiguration serviceConfiguration, IBedrockService service) + { + _service = service; + _messageSender = messageSender; + _serviceConfiguration = serviceConfiguration; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + string stringData = Encoding.UTF8.GetString(data, 5, data.Length - 5); + StringBuilder srvString = new StringBuilder(); + string[] split = stringData.Split('|'); + for (int i = 0; i < split.Length; i++) + { + string[] dataSplit = split[i].Split(';'); + string srvName = dataSplit[0]; + int srvTextLen; + int clientCurLen; + int loop; + ILogger srvText; + if (srvName != "Service") + { + try + { + srvText = _service.GetBedrockServerByName(srvName).GetLogger(); + } + catch(NullReferenceException) + { + break; + } + srvTextLen = srvText.Count(); + clientCurLen = int.Parse(dataSplit[1]); + loop = clientCurLen; + while (loop < srvTextLen) + { + srvString.Append($"{srvName};{srvText.FromIndex(loop)};{loop}|"); + loop++; + } + + } + else + { + srvTextLen = _serviceConfiguration.GetLog().Count; + clientCurLen = int.Parse(dataSplit[1]); + loop = clientCurLen; + while (loop < srvTextLen) + { + srvString.Append($"{srvName};{_serviceConfiguration.GetLog()[loop]};{loop}|"); + loop++; + } + } + } + if (srvString.Length > 1) + { + srvString.Remove(srvString.Length - 1, 1); + _messageSender.SendData(Encoding.UTF8.GetBytes(srvString.ToString()), NetworkMessageSource.Server, NetworkMessageDestination.Client, NetworkMessageTypes.ConsoleLogUpdate); + } + } + } + + class PlayerRequest : IMessageParser + { + private readonly IMessageSender _messageSender; + private readonly IServiceConfiguration _serviceConfiguration; + + public PlayerRequest(IMessageSender messageSender, IServiceConfiguration serviceConfiguration) + { + _messageSender = messageSender; + _serviceConfiguration = serviceConfiguration; + } + + public void ParseMessage(byte[] data, byte serverIndex) + { + IServerConfiguration server = _serviceConfiguration.GetServerInfoByIndex(serverIndex); + JsonSerializerSettings settings = new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.All + }; + byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(server.GetPlayerList(), Formatting.Indented, settings)); + _messageSender.SendData(serializeToBytes, NetworkMessageSource.Server, NetworkMessageDestination.Client, serverIndex, NetworkMessageTypes.PlayersRequest); + } + } + + } +} diff --git a/BedrockService.backup/Service/Networking/TCPListener.cs b/BedrockService.backup/Service/Networking/TCPListener.cs new file mode 100644 index 00000000..ded3ced8 --- /dev/null +++ b/BedrockService.backup/Service/Networking/TCPListener.cs @@ -0,0 +1,296 @@ +using BedrockService.Service.Core.Interfaces; +using BedrockService.Service.Core.Threads; +using BedrockService.Service.Networking.NetworkMessageClasses; +using BedrockService.Shared.Classes; +using BedrockService.Shared.Interfaces; +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Sockets; +using System.Threading; +using System.IO; +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; + +namespace BedrockService.Service.Networking +{ + public class TCPListener : ITCPListener, IMessageSender + { + private TcpClient _client; + private TcpListener _inListener; + private NetworkStream _stream; + private readonly IServiceConfiguration _serviceConfiguration; + private readonly ILogger _logger; + private IServiceThread _tcpThread; + private IServiceThread _clientThread; + private IServiceThread _heartbeatThread; + private bool _heartbeatRecieved = false; + private bool _firstHeartbeatRecieved = false; + private bool _keepAlive = false; + private int _heartbeatFailTimeout; + private readonly int _heartbeatFailTimeoutLimit = 200; + private Dictionary _standardMessageLookup; + private Dictionary _flaggedMessageLookup; + private readonly IPAddress _ipAddress = IPAddress.Parse("0.0.0.0"); + private readonly System.Timers.Timer _reconnectTimer = new System.Timers.Timer(500.0); + private CommsKeyContainer _keyContainer; + + public TCPListener(IServiceConfiguration serviceConfiguration, ILogger logger) + { + _logger = logger; + _serviceConfiguration = serviceConfiguration; + _reconnectTimer.Elapsed += ReconnectTimer_Elapsed; + _tcpThread = new TCPThread(new ThreadStart(StartListening)); + } + + private void ReconnectTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + { + _reconnectTimer.Stop(); + _tcpThread = new TCPThread(new ThreadStart(StartListening)); + } + + public void SetStrategyDictionaries(Dictionary standard, Dictionary flagged) + { + _standardMessageLookup = standard; + _flaggedMessageLookup = flagged; + } + + public void StartListening() + { + _inListener = new TcpListener(_ipAddress, int.Parse(_serviceConfiguration.GetProp("ClientPort").ToString())); + try + { + _inListener.Start(); + _keepAlive = true; + } + catch(SocketException e) + { + _logger.AppendLine($"Error! {e.Message}"); + Thread.Sleep(2000); + //Environment.Exit(1); + } + + while (true) + { + try + { + _client = _inListener.AcceptTcpClient(); + _stream = _client.GetStream(); + _clientThread = new ClientServiceThread(new ThreadStart(IncomingListener)); + _heartbeatThread = new HeartbeatThread(new ThreadStart(SendBackHeatbeatSignal)); + } + catch (ThreadStateException) { } + catch (NullReferenceException) { } + catch (InvalidOperationException) { } + catch (SocketException) { } + catch (Exception e) + { + _logger.AppendLine(e.ToString()); + } + } + } + + public void ResetListener() + { + _keepAlive = false; + while (_heartbeatThread.IsAlive()) + { + Thread.Sleep(300); + } + _stream.Close(); + _stream.Dispose(); + _client.Client.Blocking = false; + _inListener.Stop(); + _tcpThread.CloseThread(); + _tcpThread = null; + StartListening(); + } + + public void SendData(byte[] bytesToSend, NetworkMessageSource source, NetworkMessageDestination destination, byte serverIndex, NetworkMessageTypes type, NetworkMessageFlags status) + { + byte[] byteHeader = new byte[9 + bytesToSend.Length]; + byte[] len = BitConverter.GetBytes(5 + bytesToSend.Length); + Buffer.BlockCopy(len, 0, byteHeader, 0, 4); + byteHeader[4] = (byte)source; + byteHeader[5] = (byte)destination; + byteHeader[6] = serverIndex; + byteHeader[7] = (byte)type; + byteHeader[8] = (byte)status; + Buffer.BlockCopy(bytesToSend, 0, byteHeader, 9, bytesToSend.Length); + + if (_clientThread.IsAlive()) + { + try + { + _stream.Write(byteHeader, 0, byteHeader.Length); + _stream.Flush(); + } + catch + { + _logger.AppendLine("Error writing to network stream!"); + } + } + } + + public void SendData(byte[] bytes, NetworkMessageSource source, NetworkMessageDestination destination, byte serverIndex, NetworkMessageTypes type) => SendData(bytes, source, destination, serverIndex, type, NetworkMessageFlags.None); + + public void SendData(byte[] bytes, NetworkMessageSource source, NetworkMessageDestination destination, NetworkMessageTypes type) => SendData(bytes, source, destination, 0xFF, type, NetworkMessageFlags.None); + + public void SendData(NetworkMessageSource source, NetworkMessageDestination destination, NetworkMessageTypes type) => SendData(new byte[0], source, destination, 0xFF, type, NetworkMessageFlags.None); + + public void SendData(NetworkMessageSource source, NetworkMessageDestination destination, byte serverIndex, NetworkMessageTypes type) => SendData(new byte[0], source, destination, serverIndex, type, NetworkMessageFlags.None); + + public void SendData(NetworkMessageSource source, NetworkMessageDestination destination, NetworkMessageTypes type, NetworkMessageFlags status) => SendData(new byte[0], source, destination, 0xFF, type, status); + + private void IncomingListener() + { + _keepAlive = true; + _logger.AppendLine("Packet listener thread started."); + int AvailBytes = 0; + int byteCount = 0; + NetworkMessageSource msgSource = 0; + NetworkMessageDestination msgDest = 0; + byte serverIndex = 0xFF; + NetworkMessageTypes msgType = 0; + NetworkMessageFlags msgFlag = 0; + while (_keepAlive) + { + try + { + byte[] buffer = new byte[4]; + while (_client.Client.Available != 0) // Recieve data from client. + { + byteCount = _stream.Read(buffer, 0, 4); + int expectedLen = BitConverter.ToInt32(buffer, 0); + buffer = new byte[expectedLen]; + byteCount = _stream.Read(buffer, 0, expectedLen); + msgSource = (NetworkMessageSource)buffer[0]; + msgDest = (NetworkMessageDestination)buffer[1]; + serverIndex = buffer[2]; + msgType = (NetworkMessageTypes)buffer[3]; + msgFlag = (NetworkMessageFlags)buffer[4]; + if (msgType == NetworkMessageTypes.Heartbeat) + { + if (!_firstHeartbeatRecieved) + _firstHeartbeatRecieved = true; + _heartbeatRecieved = true; + } + if (msgType == NetworkMessageTypes.Disconnect) + { + ResetListener(); + } + if (msgType < NetworkMessageTypes.Heartbeat) + { + if (_standardMessageLookup.ContainsKey(msgType)) + _standardMessageLookup[msgType].ParseMessage(buffer, serverIndex); + else + _flaggedMessageLookup[msgType].ParseMessage(buffer, serverIndex, msgFlag); + } + } + Thread.Sleep(200); + } + catch (OutOfMemoryException) + { + _logger.AppendLine("Out of memory exception thrown."); + } + catch (ObjectDisposedException) + { + _logger.AppendLine("Client was disposed! Killing thread..."); + break; + } + catch (InvalidOperationException e) + { + if (msgType != NetworkMessageTypes.ConsoleLogUpdate) + { + _logger.AppendLine(e.Message); + _logger.AppendLine(e.StackTrace); + } + } + catch (ThreadAbortException) + { + _logger.AppendLine("ListenerThread aborted!"); + } + catch (Exception e) + { + _logger.AppendLine($"Error: {e.Message} {e.StackTrace}"); + } + try + { + AvailBytes = _client.Client.Available; + } + catch { } + if (!_clientThread.IsAlive()) + _clientThread.CloseThread(); + } + } + + private void SendBackHeatbeatSignal() + { + _logger.AppendLine("HeartBeatSender started."); + while (_keepAlive) + { + _heartbeatRecieved = false; + while (!_heartbeatRecieved && _keepAlive) + { + Thread.Sleep(100); + _heartbeatFailTimeout++; + if (_heartbeatFailTimeout > _heartbeatFailTimeoutLimit) + { + if (!_firstHeartbeatRecieved) + { + try + { + SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.Heartbeat); + _heartbeatFailTimeout = 0; + } + catch (Exception e) + { + _logger.AppendLine($"HeartBeatSender exited with error: {e.Message}"); + return; + } + } + } + } + _heartbeatRecieved = false; + _heartbeatFailTimeout = 0; + SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.Heartbeat); + int timeWaited = 0; + while (timeWaited < 3000) + { + Thread.Sleep(100); + timeWaited += 100; + if (!_keepAlive) + { + _logger.AppendLine("HeartBeatSender exited."); + return; + } + } + } + _logger.AppendLine("HeartBeatSender exited."); + } + + public void SetKeyContainer(CommsKeyContainer keyContainer) + { + _keyContainer = keyContainer; + } + + public bool VerifyClientData(byte[] certificate) + { + if(certificate != null) + { + byte[] decrypted; + using(RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) + { + rsa.ImportParameters(_keyContainer.LocalPrivateKey.GetPrivateKey()); + + } + using(RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) + { + rsa.ImportParameters(_keyContainer.RemotePublicKey.GetPrivateKey()); + + } + } + return true; + } + } +} \ No newline at end of file diff --git a/BedrockService.backup/Service/Networking/Updater.cs b/BedrockService.backup/Service/Networking/Updater.cs new file mode 100644 index 00000000..8be6efb1 --- /dev/null +++ b/BedrockService.backup/Service/Networking/Updater.cs @@ -0,0 +1,195 @@ +using BedrockService.Shared.Interfaces; +using BedrockService.Shared.Utilities; +using System; +using System.IO; +using System.IO.Compression; +using System.Net.Http; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; + +namespace BedrockService.Service.Networking +{ + public class Updater : IUpdater + { + private bool _versionChanged = false; + private readonly ILogger _logger; + private readonly IServiceConfiguration _serviceConfiguration; + private readonly IProcessInfo _processInfo; + private readonly string _version; + + public Updater(IProcessInfo processInfo, ILogger logger, IServiceConfiguration serviceConfiguration) + { + _serviceConfiguration = serviceConfiguration; + _processInfo = processInfo; + _logger = logger; + _version = "None"; + if (!File.Exists($@"{processInfo.GetDirectory()}\Server\bedrock_ver.ini")) + { + logger.AppendLine("Version ini file missing, creating and fetching build..."); + File.Create($@"{processInfo.GetDirectory()}\Server\bedrock_ver.ini").Close(); + } + _version = File.ReadAllText($@"{processInfo.GetDirectory()}\Server\bedrock_ver.ini"); + } + + public async Task CheckUpdates() + { + await Task.Run(async () => + { + _logger.AppendLine("Checking MCS Version and fetching update if needed..."); + HttpClient client = new HttpClient(); + client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/apng,*/*;q=0.8"); + client.DefaultRequestHeaders.Add("Accept-Language", "en-GB,en;q=0.9,en-US;q=0.8"); + client.DefaultRequestHeaders.Add("Connection", "keep-alive"); + client.DefaultRequestHeaders.Add("Cache-Control", "no-cache"); + client.DefaultRequestHeaders.Add("Pragma", "no-cache"); + client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko; Google Page Speed Insights) Chrome/27.0.1453 Safari/537.36"); + client.Timeout = new TimeSpan(0, 0, 3); + + string content = FetchHTTPContent(client).Result; + if (content == null) // This really doesn't fail often. Give it one more try or fail. + { + Thread.Sleep(500); + content = await FetchHTTPContent(client); + } + if (content == null) + return false; + Regex regex = new Regex(@"(https://minecraft.azureedge.net/bin-win/bedrock-server-)(.*)(\.zip)", RegexOptions.IgnoreCase); + Match m = regex.Match(content); + if (!m.Success) + { + _logger.AppendLine("Checking for updates failed. Check website functionality!"); + return false; + } + string downloadPath = m.Groups[0].Value; + string fetchedVersion = m.Groups[2].Value; + client.Dispose(); + + if (_version == fetchedVersion) + { + _logger.AppendLine($"Current version \"{fetchedVersion}\" is up to date!"); + return true; + } + _logger.AppendLine($"New version detected! Now fetching from {downloadPath}..."); + if (!FetchBuild(downloadPath, fetchedVersion).Wait(60000)) + { + _logger.AppendLine("Fetching build timed out. If this is a new service instance, please restart service!"); + return false; + } + _versionChanged = true; + File.WriteAllText($@"{_processInfo.GetDirectory()}\Server\bedrock_ver.ini", fetchedVersion); + _serviceConfiguration.SetServerVersion(fetchedVersion); + GenerateFileList(fetchedVersion); + return true; + + + }); + } + + public async Task FetchBuild(string path, string version) + { + string ZipDir = $@"{_processInfo.GetDirectory()}\Server\MCSFiles\Update_{version}.zip"; + if (!Directory.Exists($@"{_processInfo.GetDirectory()}\Server\MCSFiles")) + { + Directory.CreateDirectory($@"{_processInfo.GetDirectory()}\Server\MCSFiles"); + } + if (File.Exists(ZipDir)) + { + return; + } + //if (InstanceProvider.HostInfo.GetGlobalValue("AcceptedMojangLic") == "false") + //{ + // logger.AppendLine("You have not accepted the license. Please visit the readme for more info!"); + // return; + //} + _logger.AppendLine("Now downloading latest build of Minecraft Bedrock Server. Please wait..."); + using (var httpClient = new HttpClient()) + { + using (var request = new HttpRequestMessage(HttpMethod.Get, path)) + { + using (Stream contentStream = await (await httpClient.SendAsync(request)).Content.ReadAsStreamAsync(), stream = new FileStream(ZipDir, FileMode.Create, FileAccess.Write, FileShare.None, 256000, true)) + { + try + { + await contentStream.CopyToAsync(stream); + } + catch (Exception e) + { + _logger.AppendLine($"Download zip resulted in error: {e.StackTrace}"); + } + httpClient.Dispose(); + request.Dispose(); + contentStream.Dispose(); + return; + } + } + } + + } + + public bool CheckVersionChanged() => _versionChanged; + + public void MarkUpToDate() => _versionChanged = false; + + public async Task ReplaceBuild(IServerConfiguration server) + { + await Task.Run(() => + { + try + { + if (!Directory.Exists(server.GetProp("ServerPath").ToString())) + Directory.CreateDirectory(server.GetProp("ServerPath").ToString()); + else if (File.Exists($@"{_processInfo.GetDirectory()}\Server\MCSFiles\stock_filelist.ini")) + new FileUtils(_processInfo.GetDirectory()).DeleteFilelist(File.ReadAllLines($@"{_processInfo.GetDirectory()}\Server\MCSFiles\stock_filelist.ini"), server.GetProp("ServerPath").ToString()); + else + new FileUtils(_processInfo.GetDirectory()).DeleteFilesRecursively(new DirectoryInfo(server.GetProp("ServerPath").ToString()), false); + + ZipFile.ExtractToDirectory($@"{_processInfo.GetDirectory()}\Server\MCSFiles\Update_{_version}.zip", server.GetProp("ServerPath").ToString()); + File.Copy(server.GetProp("ServerPath") + "\\bedrock_server.exe", server.GetProp("ServerPath") + "\\" + server.GetProp("ServerExeName"), true); + } + catch (Exception e) + { + _logger.AppendLine($"ERROR: Got an exception deleting entire directory! {e.Message}"); + } + + + }); + } + + + private async Task FetchHTTPContent(HttpClient client) + { + try + { + return await client.GetStringAsync("https://www.minecraft.net/en-us/download/server/bedrock"); + } + catch (HttpRequestException) + { + _logger.AppendLine($"Error! Updater timed out, could not fetch current build!"); + } + catch (TaskCanceledException) + { + Thread.Sleep(200); + return await FetchHTTPContent(client); + } + catch (Exception e) + { + _logger.AppendLine($"Updater resulted in error: {e.Message}\n{e.InnerException}\n{e.StackTrace}"); + } + return null; + } + + private void GenerateFileList(string version) + { + using (ZipArchive zip = ZipFile.OpenRead($@"{_processInfo.GetDirectory()}\Server\MCSFiles\Update_{version}.zip")) + { + string[] fileList = new string[zip.Entries.Count]; + for (int i = 0; i < zip.Entries.Count; i++) + { + fileList[i] = zip.Entries[i].FullName.Replace('/', '\\'); + } + File.WriteAllLines($@"{_processInfo.GetDirectory()}\Server\MCSFiles\stock_filelist.ini", fileList); + } + } + } +} diff --git a/BedrockService.backup/Service/Program.cs b/BedrockService.backup/Service/Program.cs new file mode 100644 index 00000000..d3a6fc02 --- /dev/null +++ b/BedrockService.backup/Service/Program.cs @@ -0,0 +1,80 @@ +using BedrockService.Service.Core; +using BedrockService.Service.Logging; +using BedrockService.Service.Management; +using BedrockService.Service.Networking; +using BedrockService.Shared.Classes; +using BedrockService.Shared.Interfaces; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using Topshelf; + +namespace BedrockService.Service +{ + class Program + { + public static bool IsExiting = false; + private static bool _isDebugEnabled = false; + private static bool _isConsoleMode = false; + private static readonly IServiceCollection _services = new ServiceCollection(); + + static void Main(string[] args) + { + if (args.Length > 0) + { + _isDebugEnabled = args[0].ToLower() == "-debug"; + } + ConfigureServices(_services); + IServiceProvider serviceProvider = _services.BuildServiceProvider(); + serviceProvider.GetRequiredService().LoadAllConfigurations().Wait(); + serviceProvider.GetRequiredService().CheckUpdates().Wait(); + IService service = serviceProvider.GetRequiredService(); + ILogger Logger = serviceProvider.GetRequiredService(); + IProcessInfo ProcessInfo = serviceProvider.GetRequiredService(); + serviceProvider.GetRequiredService(); + if (args.Length == 0 || Environment.UserInteractive) + { + _isConsoleMode = true; + Logger.AppendLine("BedrockService startup detected in Console mode."); + } + else + { + Logger.AppendLine("BedrockService startup detected in Service mode."); + foreach (Process process in Process.GetProcesses()) + { + if (process.Id != ProcessInfo.GetProcessPID() && process.ProcessName.StartsWith("BedrockService.") && process.ProcessName != "BedrockService.Client") + { + Logger.AppendLine($"Found additional running instance of {process.ProcessName} with ID {process.Id}"); + Logger.AppendLine($"Killing process with id {process.Id}"); + process.Kill(); + } + } + } + service.InitializeHost().Wait(); + TopshelfExitCode rc = service.Run(); + var exitCode = (int)Convert.ChangeType(rc, rc.GetTypeCode()); + if (_isDebugEnabled) + { + Console.Write("Program is force-quitting. Press any key to exit."); + Console.Out.Flush(); + Console.ReadLine(); + } + Environment.ExitCode = exitCode; + } + private static void ConfigureServices(IServiceCollection services) + { + IProcessInfo processInfo = new ServiceProcessInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Path.GetFileName(Assembly.GetExecutingAssembly().Location), Process.GetCurrentProcess().Id, _isDebugEnabled, _isConsoleMode); + services.AddSingleton(processInfo); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + } + } +} diff --git a/BedrockService.backup/Service/Properties/AssemblyInfo.cs b/BedrockService.backup/Service/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..a875f734 --- /dev/null +++ b/BedrockService.backup/Service/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("BedrockService")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("BedrockService")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("f4b1f910-30b0-4f94-a49f-94142e790c9d")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("2.5.0.0")] +[assembly: AssemblyFileVersion("2.5.0.0")] diff --git a/BedrockService.backup/Service/Server/BedrockServer.cs b/BedrockService.backup/Service/Server/BedrockServer.cs new file mode 100644 index 00000000..87e5bf22 --- /dev/null +++ b/BedrockService.backup/Service/Server/BedrockServer.cs @@ -0,0 +1,465 @@ +using BedrockService.Service.Core.Interfaces; +using BedrockService.Service.Core.Threads; +using BedrockService.Service.Management; +using BedrockService.Service.Server.Management; +using BedrockService.Shared.Classes; +using BedrockService.Shared.Interfaces; +using BedrockService.Shared.Utilities; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using Topshelf; + +namespace BedrockService.Service.Server +{ + public class BedrockServer : IBedrockServer + { + private IServiceThread _serverThread; + private IServiceThread _watchdogThread; + private StreamWriter _stdInStream; + private Process _serverProcess; + private HostControl _hostController; + private ServerStatus _currentServerStatus; + private readonly IServerConfiguration _serverConfiguration; + private readonly IServiceConfiguration _serviceConfiguration; + private readonly IPlayerManager _playerManager; + private readonly IConfigurator _configurator; + private readonly ILogger _logger; + private readonly ILogger _serverLogger; + private readonly string _servicePath; + private const string _startupMessage = "[INFO] Server started."; + public enum ServerStatus + { + Stopped, + Starting, + Stopping, + Started + } + + public BedrockServer(IServerConfiguration serverConfiguration, IConfigurator configurator, ILogger logger, IServiceConfiguration serviceConfiguration, IProcessInfo processInfo) + { + _serverConfiguration = serverConfiguration; + _serviceConfiguration = serviceConfiguration; + _configurator = configurator; + _logger = logger; + _servicePath = processInfo.GetDirectory(); + _serverLogger = new ServerLogger(processInfo, serviceConfiguration, serverConfiguration, serverConfiguration.GetServerName()); + _playerManager = new PlayerManager(serverConfiguration, logger); + } + + public void WriteToStandardIn(string command) + { + _stdInStream.WriteLine(command); + } + + public void StartControl() + { + _serverThread = new ServerProcessThread(new ThreadStart(RunServer)); + } + + public void StopControl() + { + if (_serverProcess != null) + { + _logger.AppendLine("Sending Stop to Bedrock. Process.HasExited = " + _serverProcess.HasExited.ToString()); + + _serverProcess.CancelOutputRead(); + + _stdInStream.WriteLine("stop"); + while (!_serverProcess.HasExited) { } + } + _serverThread.CloseThread(); + _serverProcess = null; + _currentServerStatus = ServerStatus.Stopped; + } + + public void StartWatchdog(HostControl hostControl) + { + _hostController = hostControl; + if (_watchdogThread == null) + { + _watchdogThread = new WatchdogThread(new ThreadStart(ApplicationWatchdogMonitor)); + } + } + + private bool Backup() + { + try + { + FileInfo exe = new FileInfo($@"{_serverConfiguration.GetProp("ServerPath")}\{_serverConfiguration.GetProp("ServerExeName")}"); + string configBackupPath = _serviceConfiguration.GetProp("BackupPath").ToString(); + DirectoryInfo backupDir = new DirectoryInfo($@"{configBackupPath}\{_serverConfiguration.GetServerName()}"); + DirectoryInfo serverDir = new DirectoryInfo(_serverConfiguration.GetProp("ServerPath").ToString()); + DirectoryInfo worldsDir = new DirectoryInfo($@"{_serverConfiguration.GetProp("ServerPath")}\worlds"); + if (!backupDir.Exists) + { + backupDir.Create(); + } + int dirCount = backupDir.GetDirectories().Length; + try + { + if (dirCount >= int.Parse(_serviceConfiguration.GetProp("MaxBackupCount").ToString())) + { + Regex reg = new Regex(@"Backup_(.*)$"); + + List Dates = new List(); + foreach (DirectoryInfo dir in backupDir.GetDirectories()) + { + if (reg.IsMatch(dir.Name)) + { + Match match = reg.Match(dir.Name); + Dates.Add(Convert.ToInt64(match.Groups[1].Value)); + } + } + long OldestDate = 0; + foreach (long date in Dates) + { + if (OldestDate == 0) + { + OldestDate = date; + } + else if (date < OldestDate) + { + OldestDate = date; + } + } + Directory.Delete($@"{backupDir}\Backup_{OldestDate}", true); + } + } + catch (Exception e) + { + if (e.GetType() == typeof(FormatException)) + { + _logger.AppendLine("Error in Config! MaxBackupCount must be nothing but a number!"); + } + } + + DirectoryInfo targetDirectory = backupDir.CreateSubdirectory($"Backup_{DateTime.Now.Ticks}"); + _logger.AppendLine($"Backing up files for server {_serverConfiguration.GetServerName()}. Please wait!"); + if (_serviceConfiguration.GetProp("EntireBackups").ToString() == "false") + { + new FileUtils(_servicePath).CopyFilesRecursively(worldsDir, targetDirectory); + return true; + } + new FileUtils(_servicePath).CopyFilesRecursively(serverDir, targetDirectory); + return true; + } + catch (Exception e) + { + _logger.AppendLine($"Error with Backup: {e.StackTrace}"); + return false; + } + } + + public void StopWatchdog() + { + if(_watchdogThread != null) + _watchdogThread.CloseThread(); + _watchdogThread = null; + } + + public ServerStatus GetServerStatus() => _currentServerStatus; + + public void SetServerStatus(ServerStatus newStatus) => _currentServerStatus = newStatus; + + private void ApplicationWatchdogMonitor() + { + while (_watchdogThread.IsAlive()) + { + string exeName = _serverConfiguration.GetProp("ServerExeName").ToString(); + string appName = exeName.Substring(0, exeName.Length - 4); + if (!MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Starting) + { + StartControl(); + _logger.AppendLine($"Recieved start signal for server {_serverConfiguration.GetServerName()}."); + Thread.Sleep(15000); + } + while (MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Started) + { + Thread.Sleep(5000); + } + if (MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Stopping) + { + _logger.AppendLine($"BedrockService signaled stop to application {appName}."); + _logger.AppendLine("Stopping..."); + StopControl(); + while (_currentServerStatus == ServerStatus.Stopping) + { + Thread.Sleep(250); + } + } + if (!MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Started) + { + StopControl(); + _logger.AppendLine($"Started application {appName} was not found in running processes... Resarting {appName}."); + StartControl(); + Thread.Sleep(1500); + } + if (!MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Stopped) + { + _logger.AppendLine("Server stopped successfully."); + } + if (!MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Stopping) + { + _logger.AppendLine("Server stopped unexpectedly. Setting server status to stopped."); + _currentServerStatus = ServerStatus.Stopped; + } + while (!MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Stopped && !Program.IsExiting) + { + Thread.Sleep(1000); + } + if (!MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Stopped && Program.IsExiting) + { + return; + } + + } + } + + public bool RestartServer(bool ShouldPerformBackup) + { + if (_currentServerStatus == ServerStatus.Started) + { + _currentServerStatus = ServerStatus.Stopping; + while (_currentServerStatus == ServerStatus.Stopping) + { + Thread.Sleep(100); + } + if (ShouldPerformBackup) + { + if (!Backup()) + return false; + } + _currentServerStatus = ServerStatus.Starting; + } + return false; + } + + public string GetServerName() => _serverConfiguration.GetServerName(); + + private void RunServer() + { + string exeName = _serverConfiguration.GetProp("ServerExeName").ToString(); + string appName = exeName.Substring(0, exeName.Length - 4); + _configurator.WriteJSONFiles(_serverConfiguration); + _configurator.SaveServerProps(_serverConfiguration, false); + + try + { + if (File.Exists($@"{_serverConfiguration.GetProp("ServerPath")}\{_serverConfiguration.GetProp("ServerExeName")}")) + { + if (MonitoredAppExists(appName)) + { + Process[] processList = Process.GetProcessesByName(appName); + if (processList.Length != 0) + { + _logger.AppendLine($@"Application {appName} was found running! Killing to proceed."); + KillProcess(processList); + } + } + // Fires up a new process to run inside this one + CreateProcess(); + } + else + { + _logger.AppendLine($"The Bedrock Server is not accessible at {$@"{_serverConfiguration.GetProp("ServerPath")}\{_serverConfiguration.GetProp("ServerExeName")}"}\r\nCheck if the file is at that location and that permissions are correct."); + _hostController.Stop(); + } + } + catch (Exception e) + { + _logger.AppendLine($"Error Running Bedrock Server: {e.Message}\n{e.StackTrace}"); + _hostController.Stop(); + + } + + } + + private void CreateProcess() + { + string fileName = $@"{_serverConfiguration.GetProp("ServerPath")}\{_serverConfiguration.GetProp("ServerExeName")}"; + _serverProcess = Process.Start(new ProcessStartInfo + { + UseShellExecute = false, + RedirectStandardError = true, + RedirectStandardInput = true, + RedirectStandardOutput = true, + WindowStyle = ProcessWindowStyle.Hidden, + FileName = fileName + }); + _serverProcess.PriorityClass = ProcessPriorityClass.High; + _serverProcess.OutputDataReceived += StdOutToLog; + + _serverProcess.BeginOutputReadLine(); + _stdInStream = _serverProcess.StandardInput; + } + + private void KillProcess(Process[] processList) + { + foreach (Process process in processList) + { + try + { + process.Kill(); + Thread.Sleep(1000); + _logger.AppendLine($@"App {_serverConfiguration.GetProp("ServerExeName")} killed!"); + } + catch (Exception e) + { + _logger.AppendLine($"Killing proccess resulted in error: {e.StackTrace}"); + } + } + } + + private bool MonitoredAppExists(string monitoredAppName) + { + try + { + Process[] processList = Process.GetProcessesByName(monitoredAppName); + if (processList.Length == 0) + { + return false; + } + else + { + return true; + } + } + catch (Exception ex) + { + _logger.AppendLine("ApplicationWatcher MonitoredAppExists Exception: " + ex.StackTrace); + return true; + } + } + + private void StdOutToLog(object sender, DataReceivedEventArgs e) + { + if (e.Data != null && !e.Data.Contains("[INFO] Running AutoCompaction...")) + { + string dataMsg = e.Data; + string logFileText = "NO LOG FILE! - "; + if (dataMsg.StartsWith(logFileText)) + dataMsg = dataMsg.Substring(logFileText.Length, dataMsg.Length - logFileText.Length); + _serverLogger.AppendText($"{_serverConfiguration.GetServerName()}: {dataMsg}\r\n"); + if (e.Data != null) + { + + if (dataMsg.Contains(_startupMessage)) + { + _currentServerStatus = ServerStatus.Started; + Thread.Sleep(1000); + + if (_serverConfiguration.GetStartCommands().Count > 0) + { + RunStartupCommands(); + } + } + if (dataMsg.StartsWith("[INFO] Player connected")) + { + int usernameStart = dataMsg.IndexOf(':') + 2; + int usernameEnd = dataMsg.IndexOf(','); + int usernameLength = usernameEnd - usernameStart; + int xuidStart = dataMsg.IndexOf(':', usernameEnd) + 2; + string username = dataMsg.Substring(usernameStart, usernameLength); + string xuid = dataMsg.Substring(xuidStart, dataMsg.Length - xuidStart); + Console.WriteLine($"Player {username} connected with XUID: {xuid}"); + _playerManager.PlayerConnected(username, xuid); + _configurator.SaveKnownPlayerDatabase(_serverConfiguration); + } + if (dataMsg.StartsWith("[INFO] Player disconnected")) + { + int usernameStart = dataMsg.IndexOf(':') + 2; + int usernameEnd = dataMsg.IndexOf(','); + int usernameLength = usernameEnd - usernameStart; + int xuidStart = dataMsg.IndexOf(':', usernameEnd) + 2; + string username = dataMsg.Substring(usernameStart, usernameLength); + string xuid = dataMsg.Substring(xuidStart, dataMsg.Length - xuidStart); + Console.WriteLine($"Player {username} disconnected with XUID: {xuid}"); + _playerManager.PlayerDisconnected(xuid); + _configurator.SaveKnownPlayerDatabase(_serverConfiguration); + } + if (dataMsg.Contains("Failed to load Vanilla")) + { + _currentServerStatus = ServerStatus.Stopping; + while (_currentServerStatus != ServerStatus.Stopped) + Thread.Sleep(200); + if (_configurator.ReplaceServerBuild(_serverConfiguration).Wait(30000)) + _currentServerStatus = ServerStatus.Starting; + } + if(dataMsg.Contains("Version ")) + { + int msgStartIndex = dataMsg.IndexOf(']') + 2; + string focusedMsg = dataMsg.Substring(msgStartIndex, dataMsg.Length - msgStartIndex); + int versionIndex = focusedMsg.IndexOf(' ') + 1; + string versionString = focusedMsg.Substring(versionIndex, focusedMsg.Length - versionIndex); + string currentVersion = _serviceConfiguration.GetServerVersion(); + if (currentVersion != versionString) + { + _logger.AppendLine($"Server {GetServerName()} version found out-of-date! Now updating!"); + StopServer().Wait(); + _configurator.ReplaceServerBuild(_serverConfiguration).Wait(); + StartControl(); + } + } + } + } + } + + private void RunStartupCommands() + { + foreach (StartCmdEntry cmd in _serverConfiguration.GetStartCommands()) + { + _stdInStream.WriteLine(cmd.Command.Trim()); + Thread.Sleep(1000); + } + } + + public bool RollbackToBackup(byte serverIndex, string folderName) + { + IServerConfiguration server = _serviceConfiguration.GetServerInfoByIndex(serverIndex); + StopServer().Wait(); + try + { + foreach (DirectoryInfo dir in new DirectoryInfo($@"{_serviceConfiguration.GetProp("BackupPath")}\{server.GetServerName()}").GetDirectories()) + if (dir.Name == folderName) + { + new FileUtils(_servicePath).DeleteFilesRecursively(new DirectoryInfo($@"{server.GetProp("ServerPath")}\worlds"), false); + _logger.AppendLine($"Deleted world folder contents."); + foreach (DirectoryInfo worldDir in new DirectoryInfo($@"{_serviceConfiguration.GetProp("BackupPath")}\{server.GetServerName()}\{folderName}").GetDirectories()) + { + new FileUtils(_servicePath).CopyFilesRecursively(worldDir, new DirectoryInfo($@"{server.GetProp("ServerPath")}\worlds\{worldDir.Name}")); + _logger.AppendLine($@"Copied {worldDir.Name} to path {server.GetProp("ServerPath")}\worlds"); + } + SetServerStatus(ServerStatus.Starting); + return true; + } + } + catch (IOException e) + { + _logger.AppendLine($"Error deleting selected backups! {e.Message}"); + } + return false; + } + + public ILogger GetLogger() => _serverLogger; + + public IPlayerManager GetPlayerManager() => _playerManager; + + public Task StopServer() + { + return Task.Run(() => + { + _currentServerStatus = ServerStatus.Stopping; + while (_currentServerStatus != ServerStatus.Stopped) + { + Thread.Sleep(100); + } + + }); + } + } +} diff --git a/BedrockService.backup/Service/Server/IBedrockServer.cs b/BedrockService.backup/Service/Server/IBedrockServer.cs new file mode 100644 index 00000000..f9967d3b --- /dev/null +++ b/BedrockService.backup/Service/Server/IBedrockServer.cs @@ -0,0 +1,22 @@ +using BedrockService.Service.Server.Management; +using BedrockService.Shared.Interfaces; +using System.Threading.Tasks; +using Topshelf; + +namespace BedrockService.Service.Server +{ + public interface IBedrockServer + { + void StartWatchdog(HostControl hostControl); + void StopWatchdog(); + string GetServerName(); + void WriteToStandardIn(string command); + bool RestartServer(bool shouldPerformBackup); + bool RollbackToBackup(byte serverIndex, string folderName); + Task StopServer(); + BedrockServer.ServerStatus GetServerStatus(); + void SetServerStatus(BedrockServer.ServerStatus newStatus); + IPlayerManager GetPlayerManager(); + ILogger GetLogger(); + } +} diff --git a/BedrockService.backup/Service/Server/Management/IPlayerManager.cs b/BedrockService.backup/Service/Server/Management/IPlayerManager.cs new file mode 100644 index 00000000..c3c0017b --- /dev/null +++ b/BedrockService.backup/Service/Server/Management/IPlayerManager.cs @@ -0,0 +1,15 @@ +using BedrockService.Shared.Interfaces; +using System.Collections.Generic; + +namespace BedrockService.Service.Server.Management +{ + public interface IPlayerManager + { + IPlayer GetPlayerByXUID(string xuid); + void SetPlayer(IPlayer player); + List GetPlayers(); + void PlayerConnected(string username, string xuid); + void PlayerDisconnected(string xuid); + void UpdatePlayerFromCfg(string xuid, string username, string permission, string whitelisted, string ignoreMaxPlayerLimit); + } +} \ No newline at end of file diff --git a/BedrockService.backup/Service/Server/Management/PlayerManager.cs b/BedrockService.backup/Service/Server/Management/PlayerManager.cs new file mode 100644 index 00000000..c2238c39 --- /dev/null +++ b/BedrockService.backup/Service/Server/Management/PlayerManager.cs @@ -0,0 +1,71 @@ +using BedrockService.Shared.Classes; +using BedrockService.Shared.Interfaces; +using System; +using System.Collections.Generic; + +namespace BedrockService.Service.Server.Management +{ + public class PlayerManager : IPlayerManager + { + readonly IServerConfiguration _serverConfiguration; + readonly ILogger _logger; + + public PlayerManager(IServerConfiguration serverConfiguration, ILogger logger) + { + this._serverConfiguration = serverConfiguration; + this._logger = logger; + } + + public void PlayerConnected(string username, string xuid) + { + IPlayer playerFound = _serverConfiguration.GetPlayerByXuid(xuid); + if (playerFound == null) + { + _serverConfiguration.AddUpdatePlayer(new Player(xuid, username, DateTime.Now.Ticks.ToString(), "0", "0", false, _serverConfiguration.GetProp("default-player-permission-level").ToString(), false)); + return; + } + playerFound.UpdateTimes(DateTime.Now.Ticks.ToString(), playerFound.GetTimes()[2]); + _serverConfiguration.AddUpdatePlayer(playerFound); + } + + public void PlayerDisconnected(string xuid) + { + IPlayer playerFound = _serverConfiguration.GetPlayerByXuid(xuid); + string[] oldTimes = playerFound.GetTimes(); + playerFound.UpdateTimes(oldTimes[1], DateTime.Now.Ticks.ToString()); + _serverConfiguration.AddUpdatePlayer(playerFound); + } + + public void UpdatePlayerFromCfg(string xuid, string username, string permission, string whitelisted, string ignoreMaxPlayerLimit) + { + IPlayer playerFound = _serverConfiguration.GetPlayerByXuid(xuid); + if (playerFound == null) + { + playerFound = new Player(_serverConfiguration.GetProp("default-player-permission-level").ToString()); + playerFound.Initialize(xuid, username); + } + playerFound.UpdateRegistration(permission, whitelisted, ignoreMaxPlayerLimit); + } + + public IPlayer GetPlayerByXUID(string xuid) + { + if (GetPlayers().Count > 0) + return _serverConfiguration.GetPlayerByXuid(xuid); + return null; + } + + public void SetPlayer(IPlayer player) + { + try + { + _serverConfiguration.GetPlayerList()[_serverConfiguration.GetPlayerList().IndexOf(player)] = player; + } + catch + { + _serverConfiguration.GetPlayerList().Add(player); + } + } + + public List GetPlayers() => _serverConfiguration.GetPlayerList(); + } +} diff --git a/BedrockService/Service/packages.config b/BedrockService.backup/Service/packages.config similarity index 100% rename from BedrockService/Service/packages.config rename to BedrockService.backup/Service/packages.config diff --git a/BedrockService.backup/Service/upgrade.backup b/BedrockService.backup/Service/upgrade.backup new file mode 100644 index 00000000..4d52c68e --- /dev/null +++ b/BedrockService.backup/Service/upgrade.backup @@ -0,0 +1 @@ +Backup created at 1636641950 (11/11/2021 2:45:50 PM +00:00) \ No newline at end of file diff --git a/BedrockService/BedrockManagementServiceASP/BedrockManagementServiceASP.csproj b/BedrockService/BedrockManagementServiceASP/BedrockManagementServiceASP.csproj new file mode 100644 index 00000000..dd4c66d4 --- /dev/null +++ b/BedrockService/BedrockManagementServiceASP/BedrockManagementServiceASP.csproj @@ -0,0 +1,15 @@ + + + + net6.0 + enable + enable + dotnet-BedrockManagementServiceASP-4ABD78ED-14F3-43D6-821D-3F1C9B453A6F + Debug;Release;Publish + AnyCPU;x64 + + + + + + diff --git a/BedrockService/BedrockManagementServiceASP/Program.cs b/BedrockService/BedrockManagementServiceASP/Program.cs new file mode 100644 index 00000000..aa303a14 --- /dev/null +++ b/BedrockService/BedrockManagementServiceASP/Program.cs @@ -0,0 +1,9 @@ +using BedrockManagementServiceASP; + +IHost host = Host.CreateDefaultBuilder(args) + .ConfigureServices(services => { + services.AddHostedService(); + }) + .Build(); + +await host.RunAsync(); diff --git a/BedrockService/BedrockManagementServiceASP/Properties/launchSettings.json b/BedrockService/BedrockManagementServiceASP/Properties/launchSettings.json new file mode 100644 index 00000000..28900b50 --- /dev/null +++ b/BedrockService/BedrockManagementServiceASP/Properties/launchSettings.json @@ -0,0 +1,11 @@ +{ + "profiles": { + "BedrockManagementServiceASP": { + "commandName": "Project", + "dotnetRunMessages": true, + "environmentVariables": { + "DOTNET_ENVIRONMENT": "Development" + } + } + } +} diff --git a/BedrockService/BedrockManagementServiceASP/Worker.cs b/BedrockService/BedrockManagementServiceASP/Worker.cs new file mode 100644 index 00000000..c8f104ba --- /dev/null +++ b/BedrockService/BedrockManagementServiceASP/Worker.cs @@ -0,0 +1,16 @@ +namespace BedrockManagementServiceASP { + public class Worker : BackgroundService { + private readonly ILogger _logger; + + public Worker(ILogger logger) { + _logger = logger; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) { + while (!stoppingToken.IsCancellationRequested) { + _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); + await Task.Delay(1000, stoppingToken); + } + } + } +} \ No newline at end of file diff --git a/BedrockService/BedrockManagementServiceASP/appsettings.Development.json b/BedrockService/BedrockManagementServiceASP/appsettings.Development.json new file mode 100644 index 00000000..b2dcdb67 --- /dev/null +++ b/BedrockService/BedrockManagementServiceASP/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/BedrockService/BedrockManagementServiceASP/appsettings.json b/BedrockService/BedrockManagementServiceASP/appsettings.json new file mode 100644 index 00000000..b2dcdb67 --- /dev/null +++ b/BedrockService/BedrockManagementServiceASP/appsettings.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/BedrockService/BedrockService.Shared/BedrockService.Shared.csproj b/BedrockService/BedrockService.Shared/BedrockService.Shared.csproj index 2eded606..48275aa3 100644 --- a/BedrockService/BedrockService.Shared/BedrockService.Shared.csproj +++ b/BedrockService/BedrockService.Shared/BedrockService.Shared.csproj @@ -1,79 +1,32 @@ - - - + - Debug - AnyCPU - {F146D5E8-EF1F-4785-9150-182631F059B7} + netstandard2.0 Library - Properties - BedrockService.Shared - BedrockService.Shared - v4.7.2 - 512 - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 + false + Debug;Release;Publish + AnyCPU;x64 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 + 2 + + + 2 + + + 2 + + + 2 - - ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll - - - - - - - ..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll - True - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + all + - + + - \ No newline at end of file diff --git a/BedrockService/BedrockService.Shared/Classes/ClientSideServiceConfiguration.cs b/BedrockService/BedrockService.Shared/Classes/ClientSideServiceConfiguration.cs index f1936fa2..ae96a8e1 100644 --- a/BedrockService/BedrockService.Shared/Classes/ClientSideServiceConfiguration.cs +++ b/BedrockService/BedrockService.Shared/Classes/ClientSideServiceConfiguration.cs @@ -1,16 +1,13 @@ using BedrockService.Shared.Interfaces; -namespace BedrockService.Shared.Classes -{ - public class ClientSideServiceConfiguration : IClientSideServiceConfiguration - { +namespace BedrockService.Shared.Classes { + public class ClientSideServiceConfiguration : IClientSideServiceConfiguration { private readonly string _hostName; private readonly string _address; private readonly string _port; private readonly string _displayName; - public ClientSideServiceConfiguration(string hostName, string address, string port) - { + public ClientSideServiceConfiguration(string hostName, string address, string port) { this._hostName = hostName; this._address = address; this._port = port; diff --git a/BedrockService/BedrockService.Shared/Classes/CommsKeyContainer.cs b/BedrockService/BedrockService.Shared/Classes/CommsKeyContainer.cs new file mode 100644 index 00000000..41ca6c24 --- /dev/null +++ b/BedrockService/BedrockService.Shared/Classes/CommsKeyContainer.cs @@ -0,0 +1,80 @@ +using System; +using System.Security.Cryptography; + +namespace BedrockService.Shared.Classes { + [Serializable] + public class RSAContainer { + public byte[] D; + public byte[] DP; + public byte[] DQ; + public byte[] Exponent; + public byte[] InverseQ; + public byte[] Modulus; + public byte[] P; + public byte[] Q; + + public RSAContainer(RSAParameters input) { + D = input.D; + P = input.DP; + DP = input.DP; + Q = input.DQ; + DQ = input.DQ; + InverseQ = input.InverseQ; + Modulus = input.Modulus; + Exponent = input.Exponent; + } + + public RSAParameters GetPrivateKey() { + return new RSAParameters() { + D = this.D, + P = this.P, + DP = this.DP, + Q = this.Q, + DQ = this.DQ, + InverseQ = this.InverseQ, + Exponent = this.Exponent, + Modulus = this.Modulus + }; + } + + public RSAParameters GetPublicKey() { + return new RSAParameters() { + Modulus = this.Modulus, + Exponent = this.Exponent + }; + } + + public void SetPrivateKey(RSAParameters privateKey) { + this.D = privateKey.D; + this.DP = privateKey.DP; + this.P = privateKey.P; + this.DQ = privateKey.DQ; + this.Q = privateKey.Q; + this.InverseQ = privateKey.InverseQ; + this.Modulus = privateKey.Modulus; + this.Exponent = privateKey.Exponent; + } + + public void SetPublicKey(RSAParameters publicKey) { + this.Exponent = publicKey.Exponent; + this.Modulus = publicKey.Modulus; + } + } + + [Serializable] + public class CommsKeyContainer { + public RSAContainer LocalPrivateKey = new RSAContainer(new RSAParameters()); + public RSAContainer RemotePublicKey = new RSAContainer(new RSAParameters()); + public byte[] AesKey; + public byte[] AesIV; + + public CommsKeyContainer() { } + + public CommsKeyContainer(RSAParameters priv, RSAParameters pub, byte[] key, byte[] IV) { + LocalPrivateKey = new RSAContainer(priv); + RemotePublicKey = new RSAContainer(pub); + AesKey = key; + AesIV = IV; + } + } +} diff --git a/BedrockService/BedrockService.Shared/Classes/NetworkEnums.cs b/BedrockService/BedrockService.Shared/Classes/NetworkEnums.cs index 3cc62590..11ea024e 100644 --- a/BedrockService/BedrockService.Shared/Classes/NetworkEnums.cs +++ b/BedrockService/BedrockService.Shared/Classes/NetworkEnums.cs @@ -1,22 +1,18 @@ -namespace BedrockService.Shared.Classes -{ - public enum NetworkMessageSource - { +namespace BedrockService.Shared.Classes { + public enum NetworkMessageSource { Client, Server, Service } - public enum NetworkMessageDestination - { + public enum NetworkMessageDestination { Client, Server, Service } - public enum NetworkMessageTypes - { + public enum NetworkMessageTypes { Connect, AddNewServer, RemoveServer, @@ -43,8 +39,7 @@ public enum NetworkMessageTypes UICallback } - public enum NetworkMessageFlags - { + public enum NetworkMessageFlags { Failed, Passed, RemoveBackups, diff --git a/BedrockService/BedrockService.Shared/Classes/Player.cs b/BedrockService/BedrockService.Shared/Classes/Player.cs index 93b318b3..7d2b9197 100644 --- a/BedrockService/BedrockService.Shared/Classes/Player.cs +++ b/BedrockService/BedrockService.Shared/Classes/Player.cs @@ -2,10 +2,8 @@ using Newtonsoft.Json; using System; -namespace BedrockService.Shared.Classes -{ - public class Player : IPlayer - { +namespace BedrockService.Shared.Classes { + public class Player : IPlayer { [JsonProperty] private string Username { get; set; } [JsonProperty] @@ -28,8 +26,7 @@ public class Player : IPlayer private bool FromConfig { get; set; } [JsonConstructor] - public Player(string xuid, string username, string firstConn, string lastConn, string lastDiscon, bool whtlist, string perm, bool ignoreLimit) - { + public Player(string xuid, string username, string firstConn, string lastConn, string lastDiscon, bool whtlist, string perm, bool ignoreLimit) { Username = username; XUID = xuid; FirstConnectedTime = firstConn; @@ -40,22 +37,19 @@ public Player(string xuid, string username, string firstConn, string lastConn, s IgnorePlayerLimits = ignoreLimit; } - public Player(string serverDefaultPermission) - { + public Player(string serverDefaultPermission) { ServerDefaultPerm = serverDefaultPermission; PermissionLevel = serverDefaultPermission; } - public void Initialize(string xuid, string username) - { + public void Initialize(string xuid, string username) { XUID = xuid; Username = username; } public string GetUsername() => Username; - public string SearchForProperty(string input) - { + public string SearchForProperty(string input) { if (input == "name" || input == "username" || input == "un") return Username; if (input == "xuid" || input == "id") @@ -71,44 +65,32 @@ public string SearchForProperty(string input) public string GetXUID() => XUID; - public void UpdateTimes(string lastConn, string lastDiscon) - { + public void UpdateTimes(string lastConn, string lastDiscon) { if (FirstConnectedTime == "") FirstConnectedTime = DateTime.Now.Ticks.ToString(); LastConnectedTime = lastConn; LastDisconnectTime = lastDiscon; } - public void UpdateRegistration(string whtlist, string perm, string ignoreLimit) - { + public void UpdateRegistration(string whtlist, string perm, string ignoreLimit) { Whitelisted = bool.Parse(whtlist); PermissionLevel = perm; IgnorePlayerLimits = bool.Parse(ignoreLimit); } - public string[] GetTimes() - { - return new string[] { FirstConnectedTime, LastConnectedTime, LastDisconnectTime }; + public (string First, string Conn, string Disconn) GetTimes() { + return (FirstConnectedTime, LastConnectedTime, LastDisconnectTime); } - public string[] GetRegistration() - { - return new string[] { Whitelisted.ToString(), PermissionLevel, IgnorePlayerLimits.ToString() }; - } - - public bool IsDefaultRegistration() - { + public bool IsDefaultRegistration() { return Whitelisted == false && IgnorePlayerLimits == false && PermissionLevel == ServerDefaultPerm; } - public string ToString(string format) - { - if (format == "Known") - { + public string ToString(string format) { + if (format == "Known") { return $"{XUID},{Username},{FirstConnectedTime},{LastConnectedTime},{LastDisconnectTime}"; } - if (format == "Registered") - { + if (format == "Registered") { return $"{XUID},{Username},{PermissionLevel},{Whitelisted},{IgnorePlayerLimits}"; } return null; diff --git a/BedrockService/BedrockService.Shared/Classes/Property.cs b/BedrockService/BedrockService.Shared/Classes/Property.cs index ffc64a7a..6c9cd1aa 100644 --- a/BedrockService/BedrockService.Shared/Classes/Property.cs +++ b/BedrockService/BedrockService.Shared/Classes/Property.cs @@ -1,28 +1,23 @@ using Newtonsoft.Json; -namespace BedrockService.Shared.Classes -{ - public class Property - { +namespace BedrockService.Shared.Classes { + public class Property { public string KeyName { get; set; } public string Value { get; set; } public string DefaultValue { get; set; } [JsonConstructor] - public Property(string key, string defaultValue) - { + public Property(string key, string defaultValue) { KeyName = key; Value = defaultValue; DefaultValue = defaultValue; } - public override string ToString() - { + public override string ToString() { return Value; } - public void SetValue(string newValue) - { + public void SetValue(string newValue) { Value = newValue; } } diff --git a/BedrockService/BedrockService.Shared/Classes/ServerInfo.cs b/BedrockService/BedrockService.Shared/Classes/ServerInfo.cs index 969d0a0a..1908914f 100644 --- a/BedrockService/BedrockService.Shared/Classes/ServerInfo.cs +++ b/BedrockService/BedrockService.Shared/Classes/ServerInfo.cs @@ -2,10 +2,8 @@ using System.Collections.Generic; using System.Linq; -namespace BedrockService.Shared.Classes -{ - public class ServerInfo : IServerConfiguration - { +namespace BedrockService.Shared.Classes { + public class ServerInfo : IServerConfiguration { public string serversPath; public string ServerName { get; set; } public string FileName { get; set; } @@ -16,15 +14,13 @@ public class ServerInfo : IServerConfiguration public List ServerPropList = new List(); public List StartCmds = new List(); - public ServerInfo(string[] configEntries, string coreServersPath) - { + public ServerInfo(string[] configEntries, string coreServersPath) { serversPath = coreServersPath; InitializeDefaults(); ProcessConfiguration(configEntries); } - public void InitializeDefaults() - { + public void InitializeDefaults() { ServerName = "Default"; FileName = "Default.conf"; ServerPath = new Property("ServerPath", $@"{serversPath}\{ServerName}"); @@ -52,34 +48,30 @@ public void InitializeDefaults() ServerPropList.Add(new Property("compression-threshold", "1")); ServerPropList.Add(new Property("server-authoritative-movement", "server-auth")); ServerPropList.Add(new Property("player-movement-score-threshold", "20")); + ServerPropList.Add(new Property("player-movement-action-direction-threshold", "0.85")); ServerPropList.Add(new Property("player-movement-distance-threshold", "0.3")); ServerPropList.Add(new Property("player-movement-duration-threshold-in-ms", "500")); ServerPropList.Add(new Property("correct-player-movement", "false")); + ServerPropList.Add(new Property("server-authoritative-block-breaking", "false")); } public void SetStartCommands(List newEntries) => StartCmds = newEntries; - public void ProcessConfiguration(string[] fileEntries) - { + public void ProcessConfiguration(string[] fileEntries) { if (fileEntries == null) return; - foreach (string line in fileEntries) - { - if (!line.StartsWith("#") && !string.IsNullOrEmpty(line)) - { + foreach (string line in fileEntries) { + if (!line.StartsWith("#") && !string.IsNullOrEmpty(line)) { string[] split = line.Split('='); - if (split.Length == 1) - { + if (split.Length == 1) { split = new string[] { split[0], "" }; } Property SrvProp = ServerPropList.FirstOrDefault(prop => prop.KeyName == split[0]); - if (SrvProp != null) - { + if (SrvProp != null) { SetProp(split[0], split[1]); } - switch (split[0]) - { + switch (split[0]) { case "server-name": ServerName = split[1]; ServerPath.SetValue($@"{serversPath}\{ServerName}"); @@ -95,43 +87,34 @@ public void ProcessConfiguration(string[] fileEntries) } } - public bool SetProp(string name, string newValue) - { - try - { + public bool SetProp(string name, string newValue) { + try { Property serverProp = ServerPropList.First(prop => prop.KeyName == name); ServerPropList[ServerPropList.IndexOf(serverProp)].SetValue(newValue); return true; } - catch - { + catch { } return false; } - public bool SetProp(Property propToSet) - { - try - { + public bool SetProp(Property propToSet) { + try { Property serverProp = ServerPropList.First(prop => prop.KeyName == propToSet.KeyName); ServerPropList[ServerPropList.IndexOf(serverProp)] = propToSet; return true; } - catch - { + catch { } return false; } - public Property GetProp(string name) - { + public Property GetProp(string name) { Property foundProp = ServerPropList.FirstOrDefault(prop => prop.KeyName == name); - if (foundProp == null) - { - switch (name) - { + if (foundProp == null) { + switch (name) { case "ServerPath": return ServerPath; case "ServerExeName": @@ -143,26 +126,22 @@ public Property GetProp(string name) public void SetAllInfos() => throw new System.NotImplementedException(); - public void AddStartCommand(string command) - { + public void AddStartCommand(string command) { StartCmds.Add(new StartCmdEntry(command)); } - public bool DeleteStartCommand(string command) - { + public bool DeleteStartCommand(string command) { StartCmdEntry entry = StartCmds.FirstOrDefault(prop => prop.Command == command); return StartCmds.Remove(entry); } public List GetStartCommands() => StartCmds; - public override string ToString() - { + public override string ToString() { return ServerName; } - public override int GetHashCode() - { + public override int GetHashCode() { int hashCode = -298215838; hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(ServerName); hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(FileName); @@ -170,8 +149,7 @@ public override int GetHashCode() return hashCode; } - public override bool Equals(object obj) - { + public override bool Equals(object obj) { return obj is ServerInfo info && ServerName == info.ServerName && EqualityComparer.Default.Equals(ServerPath, info.ServerPath); @@ -183,29 +161,24 @@ public override bool Equals(object obj) public void SetAllProps(List newPropList) => ServerPropList = newPropList; - public void AddUpdatePlayer(IPlayer player) - { + public void AddUpdatePlayer(IPlayer player) { IPlayer foundPlayer = PlayersList.FirstOrDefault(p => p.GetXUID() == player.GetXUID()); - if (foundPlayer == null) - { + if (foundPlayer == null) { PlayersList.Add(player); return; } PlayersList[PlayersList.IndexOf(foundPlayer)] = player; } - public IPlayer GetPlayerByXuid(string xuid) - { + public IPlayer GetPlayerByXuid(string xuid) { IPlayer foundPlayer = PlayersList.FirstOrDefault(p => p.GetXUID() == xuid); - if (foundPlayer == null) - { + if (foundPlayer == null) { return null; } return foundPlayer; } - public string GetFileName() - { + public string GetFileName() { return FileName; } diff --git a/BedrockService/BedrockService.Shared/Classes/ServerLogger.cs b/BedrockService/BedrockService.Shared/Classes/ServerLogger.cs index 83fa2495..c3757ad8 100644 --- a/BedrockService/BedrockService.Shared/Classes/ServerLogger.cs +++ b/BedrockService/BedrockService.Shared/Classes/ServerLogger.cs @@ -4,10 +4,8 @@ using System.IO; using System.Text; -namespace BedrockService.Shared.Classes -{ - public class ServerLogger : ILogger - { +namespace BedrockService.Shared.Classes { + public class ServerLogger : IBedrockLogger { private StringBuilder OutString = new StringBuilder(); [NonSerialized] private readonly StreamWriter _logWriter; @@ -17,15 +15,13 @@ public class ServerLogger : ILogger private readonly string _logDir; private readonly IServerConfiguration _serverConfiguration; - public ServerLogger(IProcessInfo processInfo, IServiceConfiguration serviceConfiguration, IServerConfiguration serverConfiguration, string parent) - { + public ServerLogger(IProcessInfo processInfo, IServiceConfiguration serviceConfiguration, IServerConfiguration serverConfiguration, string parent) { _serverConfiguration = serverConfiguration; _logDir = $@"{processInfo.GetDirectory()}\Server\Logs"; _logToFile = bool.Parse(serviceConfiguration.GetProp("LogServersToFile").ToString()); _parent = parent; _logToConsole = true; - if (_logToFile) - { + if (_logToFile) { if (!Directory.Exists(_logDir)) Directory.CreateDirectory(_logDir); _logWriter = new StreamWriter($@"{_logDir}\ServerLog_{parent}_{DateTime.Now:yyyymmddhhmmss}.log", true); @@ -33,67 +29,53 @@ public ServerLogger(IProcessInfo processInfo, IServiceConfiguration serviceConfi } [JsonConstructor] - public ServerLogger(string serverName) - { + public ServerLogger(string serverName) { _parent = serverName; _logToFile = false; _logToConsole = false; } - public void AppendLine(string text) - { - try - { + public void AppendLine(string text) { + try { _serverConfiguration.GetLog().Add(text); - if (_logToFile && _logWriter != null) - { + if (_logToFile && _logWriter != null) { _logWriter.WriteLine(text); _logWriter.Flush(); } if (_logToConsole) Console.WriteLine(text); } - catch - { + catch { } } - public void AppendText(string text) - { - try - { + public void AppendText(string text) { + try { _serverConfiguration.GetLog().Add(text); - if (_logToFile && _logWriter != null) - { + if (_logToFile && _logWriter != null) { _logWriter.Write(text); _logWriter.Flush(); } - if (_logToConsole) - { + if (_logToConsole) { Console.Write(text); Console.Out.Flush(); } } - catch - { + catch { } } - public int Count() - { + public int Count() { return _serverConfiguration.GetLog().Count; } - public string FromIndex(int index) - { + public string FromIndex(int index) { return _serverConfiguration.GetLog()[index]; } - public override string ToString() - { + public override string ToString() { OutString = new StringBuilder(); - foreach (string s in _serverConfiguration.GetLog()) - { + foreach (string s in _serverConfiguration.GetLog()) { OutString.Append(s); } return OutString.ToString(); diff --git a/BedrockService/BedrockService.Shared/Classes/ServiceInfo.cs b/BedrockService/BedrockService.Shared/Classes/ServiceInfo.cs index b7fea589..a9a83ad4 100644 --- a/BedrockService/BedrockService.Shared/Classes/ServiceInfo.cs +++ b/BedrockService/BedrockService.Shared/Classes/ServiceInfo.cs @@ -3,10 +3,8 @@ using System.Collections.Generic; using System.Linq; -namespace BedrockService.Shared.Classes -{ - public class ServiceInfo : IServiceConfiguration - { +namespace BedrockService.Shared.Classes { + public class ServiceInfo : IServiceConfiguration { private string hostName { get; set; } private string address { get; set; } private string hostDisplayName { get; set; } @@ -20,14 +18,14 @@ public class ServiceInfo : IServiceConfiguration private List globals = new List(); private readonly IProcessInfo _processInfo; - public ServiceInfo(IProcessInfo processInfo) - { + public ServiceInfo(IProcessInfo processInfo) { _processInfo = processInfo; - InitializeDefaults(); + if (processInfo == null || processInfo.ShouldStartService()) { + InitializeDefaults(); + } } - public void InitializeDefaults() - { + public void InitializeDefaults() { globals.Clear(); globals.Add(new Property("ServersPath", @"C:\MCBedrockService")); globals.Add(new Property("AcceptedMojangLic", "false")); @@ -43,62 +41,49 @@ public void InitializeDefaults() globals.Add(new Property("LogServiceToFile", "true")); } - public void ProcessConfiguration(string[] fileEntries) - { - foreach (string line in fileEntries) - { - if (!line.StartsWith("#") && !string.IsNullOrEmpty(line)) - { + public void ProcessConfiguration(string[] fileEntries) { + foreach (string line in fileEntries) { + if (!line.StartsWith("#") && !string.IsNullOrEmpty(line)) { string[] split = line.Split('='); - if (split.Length == 1) - { + if (split.Length == 1) { split[1] = ""; } - if (split[0] == "BackupPath") - { + if (split[0] == "BackupPath") { if (split[1] == "Default") split[1] = $@"{_processInfo.GetDirectory()}\Server\Backups"; } - if (!SetProp(split[0], split[1])) - { + if (!SetProp(split[0], split[1])) { //Logger.AppendLine($"Error! Key \"{split[0]}\" was not found! Check configs!"); } } } } - public bool SetProp(string name, string newValue) - { - try - { + public bool SetProp(string name, string newValue) { + try { Property GlobalToEdit = globals.First(glob => glob.KeyName == name); globals[globals.IndexOf(GlobalToEdit)].SetValue(newValue); return true; } - catch - { + catch { // handle soon. return false; } } - public bool SetProp(Property propToSet) - { - try - { + public bool SetProp(Property propToSet) { + try { Property GlobalToEdit = globals.First(glob => glob.KeyName == propToSet.KeyName); globals[globals.IndexOf(GlobalToEdit)] = propToSet; } - catch - { + catch { // handle soon. return false; } return true; } - public Property GetProp(string name) - { + public Property GetProp(string name) { return globals.FirstOrDefault(prop => prop.KeyName == name); } @@ -106,40 +91,33 @@ public Property GetProp(string name) public void SetAllProps(List props) => globals = props; - public IServerConfiguration GetServerInfoByName(string serverName) - { + public IServerConfiguration GetServerInfoByName(string serverName) { return ServerList.FirstOrDefault(info => info.GetServerName() == serverName); } - public IServerConfiguration GetServerInfoByIndex(int index) - { + public IServerConfiguration GetServerInfoByIndex(int index) { return ServerList[index]; } - public void RemoveServerInfo(IServerConfiguration serverConfiguration) - { + public void RemoveServerInfo(IServerConfiguration serverConfiguration) { ServerList.Remove(serverConfiguration.GetServerInfo()); } - public void SetServerInfo(IServerConfiguration newInfo) - { + public void SetServerInfo(IServerConfiguration newInfo) { ServerList[ServerList.IndexOf(newInfo.GetServerInfo())] = newInfo.GetServerInfo(); } public List GetServerList() => ServerList; - public void SetAllServerInfos(List newInfos) - { + public void SetAllServerInfos(List newInfos) { ServerList = newInfos; } - public void AddNewServerInfo(IServerConfiguration serverConfiguration) - { + public void AddNewServerInfo(IServerConfiguration serverConfiguration) { ServerList.Add(serverConfiguration); } - public void RemoveServerInfoByIndex(int serverIndex) - { + public void RemoveServerInfoByIndex(int serverIndex) { ServerList.RemoveAt(serverIndex); } diff --git a/BedrockService/BedrockService.Shared/Classes/ServiceProcessInfo.cs b/BedrockService/BedrockService.Shared/Classes/ServiceProcessInfo.cs index 9f9e0645..7681bd5f 100644 --- a/BedrockService/BedrockService.Shared/Classes/ServiceProcessInfo.cs +++ b/BedrockService/BedrockService.Shared/Classes/ServiceProcessInfo.cs @@ -1,36 +1,32 @@ using BedrockService.Shared.Interfaces; -namespace BedrockService.Shared.Classes -{ - public class ServiceProcessInfo : IProcessInfo - { +namespace BedrockService.Shared.Classes { + public class ServiceProcessInfo : IProcessInfo { private readonly string _serviceDirectory; - private readonly string _serviceExeName; private readonly int _processPid; private bool _debugEnabled; private bool _isConsoleMode; + private bool _shouldStartService; - public ServiceProcessInfo(string serviceDirectory, string serviceExeName, int processPid, bool debugEnabled, bool isConsoleMode) - { + public ServiceProcessInfo(string serviceDirectory, int processPid, bool debugEnabled, bool isConsoleMode, bool shouldStartService) { _serviceDirectory = serviceDirectory; - _serviceExeName = serviceExeName; _processPid = processPid; _debugEnabled = debugEnabled; _isConsoleMode = isConsoleMode; + _shouldStartService = shouldStartService; } public string GetDirectory() => _serviceDirectory; - public string GetExecutableName() => _serviceExeName; - public int GetProcessPID() => _processPid; public bool IsDebugEnabled() => _debugEnabled; public bool IsConsoleMode() => _isConsoleMode; - public void SetArguments(bool isDebug, bool isConsole) - { + public bool ShouldStartService() => _shouldStartService; + + public void SetArguments(bool isDebug, bool isConsole) { _debugEnabled = isDebug; _isConsoleMode = isConsole; } diff --git a/BedrockService/BedrockService.Shared/Classes/StartCmdEntry.cs b/BedrockService/BedrockService.Shared/Classes/StartCmdEntry.cs index 5200e2d8..554c2c2a 100644 --- a/BedrockService/BedrockService.Shared/Classes/StartCmdEntry.cs +++ b/BedrockService/BedrockService.Shared/Classes/StartCmdEntry.cs @@ -1,11 +1,8 @@ -namespace BedrockService.Shared.Classes -{ - public class StartCmdEntry - { +namespace BedrockService.Shared.Classes { + public class StartCmdEntry { public string Command = "help 1"; - public StartCmdEntry(string entry) - { + public StartCmdEntry(string entry) { Command = entry; } } diff --git a/BedrockService/BedrockService.Shared/Interfaces/IBedrockConfiguration.cs b/BedrockService/BedrockService.Shared/Interfaces/IBedrockConfiguration.cs new file mode 100644 index 00000000..346a0efa --- /dev/null +++ b/BedrockService/BedrockService.Shared/Interfaces/IBedrockConfiguration.cs @@ -0,0 +1,23 @@ +using BedrockService.Shared.Classes; +using System.Collections.Generic; + +namespace BedrockService.Shared.Interfaces { + public interface IBedrockConfiguration { + + void InitializeDefaults(); + + void ProcessConfiguration(string[] configEntries); + + bool SetProp(Property propToSet); + + Property GetProp(string keyName); + + List GetAllProps(); + + void SetAllProps(List newPropList); + + List GetLog(); + + void SetLog(List newLog); + } +} diff --git a/BedrockService/BedrockService.Shared/Interfaces/IBedrockLogger.cs b/BedrockService/BedrockService.Shared/Interfaces/IBedrockLogger.cs new file mode 100644 index 00000000..40c443d8 --- /dev/null +++ b/BedrockService/BedrockService.Shared/Interfaces/IBedrockLogger.cs @@ -0,0 +1,9 @@ +namespace BedrockService.Shared.Interfaces { + public interface IBedrockLogger { + void AppendLine(string incomingText); + void AppendText(string incomingText); + int Count(); + string FromIndex(int index); + string ToString(); + } +} diff --git a/BedrockService/BedrockService.Shared/Interfaces/IClientSideServiceConfiguration.cs b/BedrockService/BedrockService.Shared/Interfaces/IClientSideServiceConfiguration.cs index 4d4c8f7a..9f1907d4 100644 --- a/BedrockService/BedrockService.Shared/Interfaces/IClientSideServiceConfiguration.cs +++ b/BedrockService/BedrockService.Shared/Interfaces/IClientSideServiceConfiguration.cs @@ -1,7 +1,5 @@ -namespace BedrockService.Shared.Interfaces -{ - public interface IClientSideServiceConfiguration - { +namespace BedrockService.Shared.Interfaces { + public interface IClientSideServiceConfiguration { string GetAddress(); string GetDisplayName(); string GetHostName(); diff --git a/BedrockService/BedrockService.Shared/Interfaces/IPlayer.cs b/BedrockService/BedrockService.Shared/Interfaces/IPlayer.cs index f4a4876e..28315449 100644 --- a/BedrockService/BedrockService.Shared/Interfaces/IPlayer.cs +++ b/BedrockService/BedrockService.Shared/Interfaces/IPlayer.cs @@ -1,15 +1,12 @@ -namespace BedrockService.Shared.Interfaces -{ - public interface IPlayer - { +namespace BedrockService.Shared.Interfaces { + public interface IPlayer { void Initialize(string xuid, string username); void UpdateTimes(string lastConn, string lastDiscon); void UpdateRegistration(string permission, string whitelisted, string ignoreMaxPlayerLimit); string SearchForProperty(string input); string GetUsername(); string GetXUID(); - string[] GetTimes(); - string[] GetRegistration(); + (string First, string Conn, string Disconn) GetTimes(); bool IsPlayerWhitelisted(); bool PlayerIgnoresLimit(); string GetPermissionLevel(); diff --git a/BedrockService/BedrockService.Shared/Interfaces/IProcessInfo.cs b/BedrockService/BedrockService.Shared/Interfaces/IProcessInfo.cs index b6af2a12..a0e22cf3 100644 --- a/BedrockService/BedrockService.Shared/Interfaces/IProcessInfo.cs +++ b/BedrockService/BedrockService.Shared/Interfaces/IProcessInfo.cs @@ -1,17 +1,15 @@ -namespace BedrockService.Shared.Interfaces -{ - public interface IProcessInfo - { +namespace BedrockService.Shared.Interfaces { + public interface IProcessInfo { string GetDirectory(); - string GetExecutableName(); - int GetProcessPID(); bool IsDebugEnabled(); bool IsConsoleMode(); + bool ShouldStartService(); + void SetArguments(bool isDebug, bool isConsole); } } diff --git a/BedrockService/BedrockService.Shared/Interfaces/IServerConfiguration.cs b/BedrockService/BedrockService.Shared/Interfaces/IServerConfiguration.cs index ed5c41bb..6b6c43e0 100644 --- a/BedrockService/BedrockService.Shared/Interfaces/IServerConfiguration.cs +++ b/BedrockService/BedrockService.Shared/Interfaces/IServerConfiguration.cs @@ -1,10 +1,8 @@ using BedrockService.Shared.Classes; using System.Collections.Generic; -namespace BedrockService.Shared.Interfaces -{ - public interface IServerConfiguration : IConfiguration - { +namespace BedrockService.Shared.Interfaces { + public interface IServerConfiguration : IBedrockConfiguration { string GetServerName(); string GetFileName(); diff --git a/BedrockService/BedrockService.Shared/Interfaces/IServiceConfiguration.cs b/BedrockService/BedrockService.Shared/Interfaces/IServiceConfiguration.cs index 836d530b..a86ee787 100644 --- a/BedrockService/BedrockService.Shared/Interfaces/IServiceConfiguration.cs +++ b/BedrockService/BedrockService.Shared/Interfaces/IServiceConfiguration.cs @@ -1,9 +1,7 @@ using System.Collections.Generic; -namespace BedrockService.Shared.Interfaces -{ - public interface IServiceConfiguration : IConfiguration - { +namespace BedrockService.Shared.Interfaces { + public interface IServiceConfiguration : IBedrockConfiguration { IServerConfiguration GetServerInfoByName(string serverName); IServerConfiguration GetServerInfoByIndex(int index); diff --git a/BedrockService/BedrockService.Shared/MincraftJson/KnownPacksJsonModel.cs b/BedrockService/BedrockService.Shared/MincraftJson/KnownPacksJsonModel.cs new file mode 100644 index 00000000..5d076e90 --- /dev/null +++ b/BedrockService/BedrockService.Shared/MincraftJson/KnownPacksJsonModel.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; + +namespace BedrockService.Shared.MincraftJson { + internal class KnownPacksJsonModel { + public int file_version { get; set; } + public string file_system { get; set; } + public bool? from_disk { get; set; } + public List hashes { get; set; } + public string path { get; set; } + public string uuid { get; set; } + public string version { get; set; } + + public override string ToString() { + return path; + } + } +} diff --git a/BedrockService/BedrockService.Shared/MincraftJson/PermissionsJsonModel.cs b/BedrockService/BedrockService.Shared/MincraftJson/PermissionsJsonModel.cs new file mode 100644 index 00000000..ddfff9a9 --- /dev/null +++ b/BedrockService/BedrockService.Shared/MincraftJson/PermissionsJsonModel.cs @@ -0,0 +1,11 @@ +namespace BedrockService.Shared.MincraftJson { + internal class PermissionsJsonModel { + public string permission { get; set; } + public string xuid { get; set; } + + public PermissionsJsonModel(string permission, string xuid) { + this.permission = permission; + this.xuid = xuid; + } + } +} diff --git a/BedrockService/BedrockService.Shared/MincraftJson/WhitelistJsonModel.cs b/BedrockService/BedrockService.Shared/MincraftJson/WhitelistJsonModel.cs new file mode 100644 index 00000000..70bc67eb --- /dev/null +++ b/BedrockService/BedrockService.Shared/MincraftJson/WhitelistJsonModel.cs @@ -0,0 +1,13 @@ +namespace BedrockService.Shared.MincraftJson { + internal class WhitelistJsonModel { + public bool ignoresPlayerLimit { get; set; } + public string permission { get; set; } + public string xuid { get; set; } + + public WhitelistJsonModel(bool IgnoreLimits, string XUID, string Permission) { + ignoresPlayerLimit = IgnoreLimits; + xuid = XUID; + permission = Permission; + } + } +} diff --git a/BedrockService/BedrockService.Shared/MincraftJson/WorldPacksJsonModel.cs b/BedrockService/BedrockService.Shared/MincraftJson/WorldPacksJsonModel.cs new file mode 100644 index 00000000..1b371b05 --- /dev/null +++ b/BedrockService/BedrockService.Shared/MincraftJson/WorldPacksJsonModel.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; + +namespace BedrockService.Shared.MincraftJson { + public class WorldPacksJsonModel { + public string pack_id { get; set; } + public List version { get; set; } + + public WorldPacksJsonModel(string id, List ver) { + pack_id = id; + version = ver; + } + } +} diff --git a/BedrockService/BedrockService.Shared/PackParser/MinecraftKnownPacksClass.cs b/BedrockService/BedrockService.Shared/PackParser/MinecraftKnownPacksClass.cs index 68f1dfc8..0c197cb3 100644 --- a/BedrockService/BedrockService.Shared/PackParser/MinecraftKnownPacksClass.cs +++ b/BedrockService/BedrockService.Shared/PackParser/MinecraftKnownPacksClass.cs @@ -3,14 +3,11 @@ using System.IO; using System.Linq; -namespace BedrockService.Shared.PackParser -{ - public class MinecraftKnownPacksClass - { +namespace BedrockService.Shared.PackParser { + public class MinecraftKnownPacksClass { public List KnownPacks = new List(); private readonly List _stockPacks = new List(); - public class KnownPack - { + public class KnownPack { public int file_version { get; set; } public string file_system { get; set; } public bool? from_disk { get; set; } @@ -19,19 +16,16 @@ public class KnownPack public string uuid { get; set; } public string version { get; set; } - public override string ToString() - { + public override string ToString() { return path; } } - public MinecraftKnownPacksClass(string serverFile, string stockFile) - { + public MinecraftKnownPacksClass(string serverFile, string stockFile) { KnownPacks = ParseJsonArray(serverFile); _stockPacks = ParseJsonArray(stockFile); KnownPacks.RemoveAt(0); // Strip file version entry. - foreach (KnownPack pack in _stockPacks) - { + foreach (KnownPack pack in _stockPacks) { KnownPack packToRemove = new KnownPack(); if (pack.uuid == null) continue; @@ -40,8 +34,7 @@ public MinecraftKnownPacksClass(string serverFile, string stockFile) } } - public void RemovePackFromServer(string serverPath, MinecraftPackContainer pack) - { + public void RemovePackFromServer(string serverPath, MinecraftPackContainer pack) { if (pack.ManifestType == "WorldPack") Directory.Delete($@"{serverPath}\worlds\{pack.FolderName}", true); if (pack.ManifestType == "data") @@ -55,8 +48,7 @@ public void RemovePackFromServer(string serverPath, MinecraftPackContainer pack) File.WriteAllText($@"{serverPath}\valid_known_packs.json", JArray.FromObject(packsToWrite).ToString()); } - private List ParseJsonArray(string jsonFile) - { + private List ParseJsonArray(string jsonFile) { JArray packList = JArray.Parse(File.ReadAllText(jsonFile)); List parsedPackInfos = new List(); foreach (JToken token in packList) diff --git a/BedrockService/BedrockService.Shared/PackParser/MinecraftPackParser.cs b/BedrockService/BedrockService.Shared/PackParser/MinecraftPackParser.cs index c6c4127e..c799f8ac 100644 --- a/BedrockService/BedrockService.Shared/PackParser/MinecraftPackParser.cs +++ b/BedrockService/BedrockService.Shared/PackParser/MinecraftPackParser.cs @@ -5,136 +5,113 @@ using System.IO; using System.IO.Compression; -namespace BedrockService.Shared.PackParser -{ - public class Header - { +namespace BedrockService.Shared.PackParser { + public class Header { public string description { get; set; } public string name { get; set; } public string uuid { get; set; } public List version { get; set; } } - public class Module - { + public class Module { public string description { get; set; } public string type { get; set; } public string uuid { get; set; } public List version { get; set; } } - public class Dependency - { + public class Dependency { public string uuid { get; set; } public List version { get; set; } } - public class Manifest - { + public class Manifest { public int format_version { get; set; } public Header header { get; set; } public List modules { get; set; } public List dependencies { get; set; } } - public class MinecraftPackContainer - { + public class MinecraftPackContainer { public Manifest JsonManifest; - public DirectoryInfo PackContentLocation; + public string PackContentLocation; public string ManifestType; public string FolderName; public byte[] IconBytes; - public override string ToString() - { + public override string ToString() { return JsonManifest != null ? JsonManifest.header.name : "WorldPack"; } } - public class MinecraftPackParser - { + public class MinecraftPackParser { private readonly IProcessInfo _processInfo; - private readonly ILogger _logger; - public DirectoryInfo PackExtractDirectory; + private readonly IBedrockLogger _logger; + public string PackExtractDirectory; public List FoundPacks = new List(); [JsonConstructor] - public MinecraftPackParser(ILogger logger, IProcessInfo processInfo) - { + public MinecraftPackParser(IBedrockLogger logger, IProcessInfo processInfo) { _processInfo = processInfo; _logger = logger; } - public MinecraftPackParser(byte[] fileContents, ILogger logger, IProcessInfo processInfo) - { + public MinecraftPackParser(byte[] fileContents, IBedrockLogger logger, IProcessInfo processInfo) { _logger = logger; - PackExtractDirectory = new DirectoryInfo($@"{processInfo.GetDirectory()}\Temp"); + PackExtractDirectory = $@"{processInfo.GetDirectory()}\Temp"; _processInfo = processInfo; new FileUtils(processInfo.GetDirectory()).ClearTempDir(); - using (MemoryStream fileStream = new MemoryStream(fileContents, 5, fileContents.Length - 5)) - { - using (ZipArchive zipArchive = new ZipArchive(fileStream, ZipArchiveMode.Read)) - { - zipArchive.ExtractToDirectory(PackExtractDirectory.FullName); + using (MemoryStream fileStream = new MemoryStream(fileContents, 5, fileContents.Length - 5)) { + using (ZipArchive zipArchive = new ZipArchive(fileStream, ZipArchiveMode.Read)) { + zipArchive.ExtractToDirectory(PackExtractDirectory); } } ParseDirectory(PackExtractDirectory); } - public MinecraftPackParser(string[] files, DirectoryInfo extractDir, ILogger logger, IProcessInfo processInfo) - { + public MinecraftPackParser(string[] files, string extractDir, IBedrockLogger logger, IProcessInfo processInfo) { PackExtractDirectory = extractDir; _logger = logger; _processInfo = processInfo; new FileUtils(_processInfo.GetDirectory()).ClearTempDir(); - if (Directory.Exists($@"{PackExtractDirectory.FullName}\ZipTemp")) - { - Directory.CreateDirectory($@"{PackExtractDirectory.FullName}\ZipTemp"); + if (Directory.Exists($@"{PackExtractDirectory}\ZipTemp")) { + Directory.CreateDirectory($@"{PackExtractDirectory}\ZipTemp"); } - foreach (string file in files) - { + foreach (string file in files) { FileInfo fInfo = new FileInfo(file); - string zipFilePath = $@"{PackExtractDirectory.FullName}\{fInfo.Name.Replace(fInfo.Extension, "")}"; + string zipFilePath = $@"{PackExtractDirectory}\{fInfo.Name.Replace(fInfo.Extension, "")}"; ZipFile.ExtractToDirectory(file, zipFilePath); - foreach (FileInfo extractedFile in new DirectoryInfo(zipFilePath).GetFiles()) - { - if (extractedFile.Extension == ".mcpack") - { + foreach (FileInfo extractedFile in new DirectoryInfo(zipFilePath).GetFiles()) { + if (extractedFile.Extension == ".mcpack") { Directory.CreateDirectory($@"{zipFilePath}\{extractedFile.Name.Replace(extractedFile.Extension, "")}"); ZipFile.ExtractToDirectory(extractedFile.FullName, $@"{zipFilePath}\{fInfo.Name.Replace(fInfo.Extension, "")}_{extractedFile.Name.Replace(extractedFile.Extension, "")}"); } } } - foreach (DirectoryInfo directory in PackExtractDirectory.GetDirectories()) - ParseDirectory(directory); + DirectoryInfo directoryInfo = new DirectoryInfo(PackExtractDirectory); + ParseDirectory(PackExtractDirectory); } - public void ParseDirectory(DirectoryInfo directoryToParse) - { - _logger.AppendLine($"Parsing directory {directoryToParse.Name}"); - if (directoryToParse.Exists) - { - foreach (FileInfo file in directoryToParse.GetFiles("*", SearchOption.AllDirectories)) - { - if (file.Name == "levelname.txt") - { + public void ParseDirectory(string directoryToParse) { + DirectoryInfo directoryInfo = new DirectoryInfo(directoryToParse); + if (directoryInfo.Exists) { + _logger.AppendLine($"Parsing directory {directoryInfo.Name}"); + foreach (FileInfo file in directoryInfo.GetFiles("*", SearchOption.AllDirectories)) { + if (file.Name == "levelname.txt") { byte[] iconBytes; - try - { + try { if (File.Exists($@"{file.Directory.FullName}\world_icon.jpeg")) iconBytes = File.ReadAllBytes($@"{file.Directory.FullName}\world_icon.jpeg"); else iconBytes = File.ReadAllBytes($@"{file.Directory.FullName}\world_icon.png"); } - catch - { + catch { iconBytes = null; } - FoundPacks.Add(new MinecraftPackContainer - { + FoundPacks.Add(new MinecraftPackContainer { JsonManifest = null, - PackContentLocation = file.Directory, + PackContentLocation = file.Directory.FullName, ManifestType = "WorldPack", FolderName = file.Directory.Name, IconBytes = iconBytes @@ -142,29 +119,26 @@ public void ParseDirectory(DirectoryInfo directoryToParse) _logger.AppendLine("Pack was detected as MCWorld"); return; } - if (file.Name == "manifest.json") - { + if (file.Name == "manifest.json") { byte[] iconBytes; if (File.Exists($@"{file.Directory.FullName}\pack_icon.jpeg")) iconBytes = File.ReadAllBytes($@"{file.Directory.FullName}\pack_icon.jpeg"); else iconBytes = File.ReadAllBytes($@"{file.Directory.FullName}\pack_icon.png"); - MinecraftPackContainer container = new MinecraftPackContainer - { + MinecraftPackContainer container = new MinecraftPackContainer { JsonManifest = new Manifest(), - PackContentLocation = file.Directory, + PackContentLocation = file.Directory.FullName, ManifestType = "", FolderName = file.Directory.Name, IconBytes = iconBytes }; - JsonSerializerSettings settings = new JsonSerializerSettings() - { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; container.JsonManifest = JsonConvert.DeserializeObject(File.ReadAllText(file.FullName), settings); container.ManifestType = container.JsonManifest.modules[0].type; - _logger.AppendLine($"{container.ManifestType} pack found, name: {container.JsonManifest.header.name}, path: {container.PackContentLocation.Name}"); + _logger.AppendLine($"{container.ManifestType} pack found, name: {container.JsonManifest.header.name}, path: {container.PackContentLocation}"); FoundPacks.Add(container); } } diff --git a/BedrockService/BedrockService.Shared/Properties/AssemblyInfo.cs b/BedrockService/BedrockService.Shared/Properties/AssemblyInfo.cs index 0b64fbcf..33322d86 100644 --- a/BedrockService/BedrockService.Shared/Properties/AssemblyInfo.cs +++ b/BedrockService/BedrockService.Shared/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("2.5.6.0")] +[assembly: AssemblyFileVersion("2.5.6.0")] diff --git a/BedrockService/BedrockService.Shared/Utilities/FileUtils.cs b/BedrockService/BedrockService.Shared/Utilities/FileUtils.cs index 6ef8cebb..bf0044b7 100644 --- a/BedrockService/BedrockService.Shared/Utilities/FileUtils.cs +++ b/BedrockService/BedrockService.Shared/Utilities/FileUtils.cs @@ -1,26 +1,25 @@ -using System.Collections.Generic; +using BedrockService.Shared.MincraftJson; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading.Tasks; -namespace BedrockService.Shared.Utilities -{ - public class FileUtils - { +namespace BedrockService.Shared.Utilities { + public class FileUtils { readonly string _servicePath; - public FileUtils(string servicePath) - { - this._servicePath = servicePath; + public FileUtils(string servicePath) { + _servicePath = servicePath; } - public void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target) - { + public void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target) { foreach (DirectoryInfo dir in source.GetDirectories()) CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name)); foreach (FileInfo file in source.GetFiles()) file.CopyTo(Path.Combine(target.FullName, file.Name), true); } - public void DeleteFilesRecursively(DirectoryInfo source, bool removeSourceFolder) - { + public void DeleteFilesRecursively(DirectoryInfo source, bool removeSourceFolder) { foreach (DirectoryInfo dir in source.GetDirectories()) DeleteFilesRecursively(dir, removeSourceFolder); foreach (FileInfo file in source.GetFiles()) @@ -31,8 +30,7 @@ public void DeleteFilesRecursively(DirectoryInfo source, bool removeSourceFolder source.Delete(true); } - public void ClearTempDir() - { + public void ClearTempDir() { DirectoryInfo tempDirectory = new DirectoryInfo($@"{_servicePath}\Temp"); if (!tempDirectory.Exists) tempDirectory.Create(); @@ -42,11 +40,9 @@ public void ClearTempDir() directory.Delete(true); } - public void DeleteFilelist(string[] fileList, string serverPath) - { + public void DeleteFilelist(string[] fileList, string serverPath) { foreach (string file in fileList) - try - { + try { File.Delete($@"{serverPath}\{file}"); } catch { } @@ -58,5 +54,65 @@ public void DeleteFilelist(string[] fileList, string serverPath) Directory.Delete(dir, true); } + public void WriteStringToFile(string path, string content) => File.WriteAllText(path, content); + + public void WriteStringArrayToFile(string path, string[] content) => File.WriteAllLines(path, content); + + public void UpdateJArrayFile(string path, JArray content, System.Type type) { + try { + string currentFileContents = null; + JArray jArray = new JArray(); + if (File.Exists(path)) { + currentFileContents = File.ReadAllText(path); + jArray = JArray.Parse(currentFileContents); + } + if (type == typeof(WorldPacksJsonModel)) { + foreach (JToken jToken in content) { + bool doesContainToken = false; + foreach (JToken currentToken in jArray) { + if (currentToken.ToObject().pack_id == jToken.ToObject().pack_id) { + doesContainToken = true; + } + } + if (!doesContainToken) { + jArray.Add(jToken); + } + } + } + File.WriteAllText(path, jArray.ToString()); + } + catch (System.Exception) { + return; + } + } + + public Task BackupWorldFilesFromQuery(Dictionary fileNameSizePairs, string worldPath, string destinationPath) { + return Task.Run(() => { + try { + foreach (KeyValuePair file in fileNameSizePairs) { + string fileName = file.Key.Replace('/', '\\'); + int fileSize = file.Value; + string filePath = $@"{worldPath}\{fileName}"; + string destFilePath = $@"{destinationPath}\{fileName}"; + byte[] fileData = null; + using (FileStream fs = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + using (MemoryStream ms = new MemoryStream()) { + fs.CopyTo(ms); + ms.Position = 0; + fileData = ms.ToArray(); + } + byte[] destData = new byte[fileSize]; + Buffer.BlockCopy(fileData, 0, destData, 0, fileSize); + Directory.CreateDirectory(new FileInfo(destFilePath).DirectoryName); + File.WriteAllBytes(destFilePath, fileData); + } + return true; + } + catch (System.Exception ex) { + Console.WriteLine($"Error! {ex.Message}"); + } + return false; + }); + } } } diff --git a/BedrockService/BedrockService.sln b/BedrockService/BedrockService.sln index 29c749fe..528b8100 100644 --- a/BedrockService/BedrockService.sln +++ b/BedrockService/BedrockService.sln @@ -1,46 +1,90 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29709.97 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BedrockService.Service", "Service\BedrockService.Service.csproj", "{13B2B5A8-71E9-49F4-9BFB-3C3B3C0A054C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BedrockService.Service", "Service\BedrockService.Service.csproj", "{13B2B5A8-71E9-49F4-9BFB-3C3B3C0A054C}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{83D2040C-760E-4475-ACBE-587536C90911}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BedrockService.Client", "Client\BedrockService.Client.csproj", "{A2DAF70A-925A-4F4B-B7EE-CAACE75D6740}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BedrockService.Client", "Client\BedrockService.Client.csproj", "{A2DAF70A-925A-4F4B-B7EE-CAACE75D6740}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BedrockServiceUnitTests", "BedrockServiceUnitTests\BedrockServiceUnitTests.csproj", "{216E8E7A-77A9-4077-A5B5-2C63424E7B83}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BedrockService.Shared", "BedrockService.Shared\BedrockService.Shared.csproj", "{F146D5E8-EF1F-4785-9150-182631F059B7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BedrockService.Shared", "BedrockService.Shared\BedrockService.Shared.csproj", "{F146D5E8-EF1F-4785-9150-182631F059B7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BedrockManagementServiceASP", "BedrockManagementServiceASP\BedrockManagementServiceASP.csproj", "{4AA65E9F-E3BE-4173-BE3B-BD4DFCD21C40}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClientUnitTests", "ClientUnitTests\ClientUnitTests.csproj", "{550B6A98-60C3-4765-BFED-2CAA0AFFAEBB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceTests", "ServiceTests\ServiceTests.csproj", "{B20CAE22-52BD-4A49-ADA8-04F7C7007155}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Publish|Any CPU = Publish|Any CPU + Publish|x64 = Publish|x64 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {13B2B5A8-71E9-49F4-9BFB-3C3B3C0A054C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {13B2B5A8-71E9-49F4-9BFB-3C3B3C0A054C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {13B2B5A8-71E9-49F4-9BFB-3C3B3C0A054C}.Debug|x64.ActiveCfg = Debug|x64 + {13B2B5A8-71E9-49F4-9BFB-3C3B3C0A054C}.Debug|x64.Build.0 = Debug|x64 + {13B2B5A8-71E9-49F4-9BFB-3C3B3C0A054C}.Publish|Any CPU.ActiveCfg = Publish|Any CPU + {13B2B5A8-71E9-49F4-9BFB-3C3B3C0A054C}.Publish|Any CPU.Build.0 = Publish|Any CPU + {13B2B5A8-71E9-49F4-9BFB-3C3B3C0A054C}.Publish|x64.ActiveCfg = Publish|x64 + {13B2B5A8-71E9-49F4-9BFB-3C3B3C0A054C}.Publish|x64.Build.0 = Publish|x64 {13B2B5A8-71E9-49F4-9BFB-3C3B3C0A054C}.Release|Any CPU.ActiveCfg = Release|Any CPU {13B2B5A8-71E9-49F4-9BFB-3C3B3C0A054C}.Release|Any CPU.Build.0 = Release|Any CPU + {13B2B5A8-71E9-49F4-9BFB-3C3B3C0A054C}.Release|x64.ActiveCfg = Release|x64 + {13B2B5A8-71E9-49F4-9BFB-3C3B3C0A054C}.Release|x64.Build.0 = Release|x64 {A2DAF70A-925A-4F4B-B7EE-CAACE75D6740}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A2DAF70A-925A-4F4B-B7EE-CAACE75D6740}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A2DAF70A-925A-4F4B-B7EE-CAACE75D6740}.Debug|x64.ActiveCfg = Debug|x64 + {A2DAF70A-925A-4F4B-B7EE-CAACE75D6740}.Debug|x64.Build.0 = Debug|x64 + {A2DAF70A-925A-4F4B-B7EE-CAACE75D6740}.Publish|Any CPU.ActiveCfg = Publish|Any CPU + {A2DAF70A-925A-4F4B-B7EE-CAACE75D6740}.Publish|Any CPU.Build.0 = Publish|Any CPU + {A2DAF70A-925A-4F4B-B7EE-CAACE75D6740}.Publish|x64.ActiveCfg = Publish|x64 + {A2DAF70A-925A-4F4B-B7EE-CAACE75D6740}.Publish|x64.Build.0 = Publish|x64 {A2DAF70A-925A-4F4B-B7EE-CAACE75D6740}.Release|Any CPU.ActiveCfg = Release|Any CPU {A2DAF70A-925A-4F4B-B7EE-CAACE75D6740}.Release|Any CPU.Build.0 = Release|Any CPU - {216E8E7A-77A9-4077-A5B5-2C63424E7B83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {216E8E7A-77A9-4077-A5B5-2C63424E7B83}.Debug|Any CPU.Build.0 = Debug|Any CPU - {216E8E7A-77A9-4077-A5B5-2C63424E7B83}.Release|Any CPU.ActiveCfg = Release|Any CPU - {216E8E7A-77A9-4077-A5B5-2C63424E7B83}.Release|Any CPU.Build.0 = Release|Any CPU + {A2DAF70A-925A-4F4B-B7EE-CAACE75D6740}.Release|x64.ActiveCfg = Release|x64 + {A2DAF70A-925A-4F4B-B7EE-CAACE75D6740}.Release|x64.Build.0 = Release|x64 {F146D5E8-EF1F-4785-9150-182631F059B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F146D5E8-EF1F-4785-9150-182631F059B7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F146D5E8-EF1F-4785-9150-182631F059B7}.Debug|x64.ActiveCfg = Debug|x64 + {F146D5E8-EF1F-4785-9150-182631F059B7}.Debug|x64.Build.0 = Debug|x64 + {F146D5E8-EF1F-4785-9150-182631F059B7}.Publish|Any CPU.ActiveCfg = Publish|Any CPU + {F146D5E8-EF1F-4785-9150-182631F059B7}.Publish|Any CPU.Build.0 = Publish|Any CPU + {F146D5E8-EF1F-4785-9150-182631F059B7}.Publish|x64.ActiveCfg = Publish|x64 + {F146D5E8-EF1F-4785-9150-182631F059B7}.Publish|x64.Build.0 = Publish|x64 {F146D5E8-EF1F-4785-9150-182631F059B7}.Release|Any CPU.ActiveCfg = Release|Any CPU {F146D5E8-EF1F-4785-9150-182631F059B7}.Release|Any CPU.Build.0 = Release|Any CPU - {550B6A98-60C3-4765-BFED-2CAA0AFFAEBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {550B6A98-60C3-4765-BFED-2CAA0AFFAEBB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {550B6A98-60C3-4765-BFED-2CAA0AFFAEBB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {550B6A98-60C3-4765-BFED-2CAA0AFFAEBB}.Release|Any CPU.Build.0 = Release|Any CPU + {F146D5E8-EF1F-4785-9150-182631F059B7}.Release|x64.ActiveCfg = Release|x64 + {F146D5E8-EF1F-4785-9150-182631F059B7}.Release|x64.Build.0 = Release|x64 + {4AA65E9F-E3BE-4173-BE3B-BD4DFCD21C40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4AA65E9F-E3BE-4173-BE3B-BD4DFCD21C40}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4AA65E9F-E3BE-4173-BE3B-BD4DFCD21C40}.Debug|x64.ActiveCfg = Debug|x64 + {4AA65E9F-E3BE-4173-BE3B-BD4DFCD21C40}.Debug|x64.Build.0 = Debug|x64 + {4AA65E9F-E3BE-4173-BE3B-BD4DFCD21C40}.Publish|Any CPU.ActiveCfg = Publish|Any CPU + {4AA65E9F-E3BE-4173-BE3B-BD4DFCD21C40}.Publish|Any CPU.Build.0 = Publish|Any CPU + {4AA65E9F-E3BE-4173-BE3B-BD4DFCD21C40}.Publish|x64.ActiveCfg = Publish|x64 + {4AA65E9F-E3BE-4173-BE3B-BD4DFCD21C40}.Publish|x64.Build.0 = Publish|x64 + {4AA65E9F-E3BE-4173-BE3B-BD4DFCD21C40}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4AA65E9F-E3BE-4173-BE3B-BD4DFCD21C40}.Release|Any CPU.Build.0 = Release|Any CPU + {4AA65E9F-E3BE-4173-BE3B-BD4DFCD21C40}.Release|x64.ActiveCfg = Release|x64 + {4AA65E9F-E3BE-4173-BE3B-BD4DFCD21C40}.Release|x64.Build.0 = Release|x64 + {B20CAE22-52BD-4A49-ADA8-04F7C7007155}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B20CAE22-52BD-4A49-ADA8-04F7C7007155}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B20CAE22-52BD-4A49-ADA8-04F7C7007155}.Debug|x64.ActiveCfg = Debug|x64 + {B20CAE22-52BD-4A49-ADA8-04F7C7007155}.Debug|x64.Build.0 = Debug|x64 + {B20CAE22-52BD-4A49-ADA8-04F7C7007155}.Publish|Any CPU.ActiveCfg = Publish|Any CPU + {B20CAE22-52BD-4A49-ADA8-04F7C7007155}.Publish|Any CPU.Build.0 = Publish|Any CPU + {B20CAE22-52BD-4A49-ADA8-04F7C7007155}.Publish|x64.ActiveCfg = Publish|x64 + {B20CAE22-52BD-4A49-ADA8-04F7C7007155}.Publish|x64.Build.0 = Publish|x64 + {B20CAE22-52BD-4A49-ADA8-04F7C7007155}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B20CAE22-52BD-4A49-ADA8-04F7C7007155}.Release|Any CPU.Build.0 = Release|Any CPU + {B20CAE22-52BD-4A49-ADA8-04F7C7007155}.Release|x64.ActiveCfg = Release|x64 + {B20CAE22-52BD-4A49-ADA8-04F7C7007155}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -49,6 +93,7 @@ Global {13B2B5A8-71E9-49F4-9BFB-3C3B3C0A054C} = {83D2040C-760E-4475-ACBE-587536C90911} {A2DAF70A-925A-4F4B-B7EE-CAACE75D6740} = {83D2040C-760E-4475-ACBE-587536C90911} {F146D5E8-EF1F-4785-9150-182631F059B7} = {83D2040C-760E-4475-ACBE-587536C90911} + {4AA65E9F-E3BE-4173-BE3B-BD4DFCD21C40} = {83D2040C-760E-4475-ACBE-587536C90911} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7A40EC18-E15E-44CE-87EE-61F71CBC3FB6} diff --git a/BedrockService/BedrockServiceUnitTests/BedrockServiceUnitTests.csproj b/BedrockService/BedrockServiceUnitTests/BedrockServiceUnitTests.csproj index bb449d2b..4cabbb43 100644 --- a/BedrockService/BedrockServiceUnitTests/BedrockServiceUnitTests.csproj +++ b/BedrockService/BedrockServiceUnitTests/BedrockServiceUnitTests.csproj @@ -86,14 +86,6 @@ {F146D5E8-EF1F-4785-9150-182631F059B7} BedrockService.Shared - - {a2daf70a-925a-4f4b-b7ee-caace75d6740} - BedrockService.Client - - - {13b2b5a8-71e9-49f4-9bfb-3c3b3c0a054c} - BedrockService.Service - diff --git a/BedrockService/BedrockServiceUnitTests/Properties/AssemblyInfo.cs b/BedrockService/BedrockServiceUnitTests/Properties/AssemblyInfo.cs index dbcdf908..b3183c09 100644 --- a/BedrockService/BedrockServiceUnitTests/Properties/AssemblyInfo.cs +++ b/BedrockService/BedrockServiceUnitTests/Properties/AssemblyInfo.cs @@ -1,5 +1,3 @@ -using System.Reflection; -using System.Runtime.InteropServices; [assembly: AssemblyTitle("BedrockServiceUnitTests")] [assembly: AssemblyDescription("")] diff --git a/BedrockService/BedrockServiceUnitTests/app.config b/BedrockService/BedrockServiceUnitTests/app.config new file mode 100644 index 00000000..28b67d9c --- /dev/null +++ b/BedrockService/BedrockServiceUnitTests/app.config @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BedrockService/Client/BedrockService.Client.csproj b/BedrockService/Client/BedrockService.Client.csproj index 70028f03..03761923 100644 --- a/BedrockService/Client/BedrockService.Client.csproj +++ b/BedrockService/Client/BedrockService.Client.csproj @@ -1,17 +1,8 @@ - - - + - Debug - AnyCPU - {A2DAF70A-925A-4F4B-B7EE-CAACE75D6740} + net6.0-windows WinExe - BedrockService.Client - BedrockService.Client - v4.7.2 - 512 - true - true + false publish\ true Disk @@ -24,144 +15,38 @@ true 0 1.0.0.%2a - false false true + false + true + true + Debug;Release;Publish + AnyCPU;x64 - x86 - true - full - false ..\bin\Debug\ - DEBUG;TRACE - prompt - 4 + + + ..\bin\Debug\ - AnyCPU - pdbonly - true ..\bin\Release\ - TRACE - prompt - 4 + + + ..\bin\Release\ + + + ..\bin\Release\ + + + ..\bin\Release\ BedrockService.Client.Forms.MainWindow + mc_icon.ico - - ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll - - - - - - - - - - - - - - - - - - Form - - - AddNewServerForm.cs - - - Form - - - ClientConfigForm.cs - - - Form - - - ManagePacksForms.cs - - - Form - - - NewPlayerRegistrationForm.cs - - - Form - - - PlayerManagerForm.cs - - - - - - Form - - - PropEditorForm.cs - - - Form - - - MainWindow.cs - - - - - - AddNewServerForm.cs - - - ClientConfigForm.cs - - - ManagePacksForms.cs - - - NewPlayerRegistrationForm.cs - - - PlayerManagerForm.cs - - - PropEditorForm.cs - - - MainWindow.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - True - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - @@ -175,12 +60,29 @@ false - - - {f146d5e8-ef1f-4785-9150-182631f059b7} - BedrockService.Shared - + + + + + + + + all + + + + + + True + True + Settings.settings + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + - \ No newline at end of file diff --git a/BedrockService/Client/Forms/AddNewServerForm.Designer.cs b/BedrockService/Client/Forms/AddNewServerForm.Designer.cs index 1291703f..da5d8b41 100644 --- a/BedrockService/Client/Forms/AddNewServerForm.Designer.cs +++ b/BedrockService/Client/Forms/AddNewServerForm.Designer.cs @@ -42,57 +42,64 @@ private void InitializeComponent() // // srvNameBox // - this.srvNameBox.Location = new System.Drawing.Point(106, 56); + this.srvNameBox.Location = new System.Drawing.Point(124, 65); + this.srvNameBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.srvNameBox.Name = "srvNameBox"; - this.srvNameBox.Size = new System.Drawing.Size(100, 20); + this.srvNameBox.Size = new System.Drawing.Size(116, 23); this.srvNameBox.TabIndex = 0; // // label1 // this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(30, 59); + this.label1.Location = new System.Drawing.Point(35, 68); + this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(70, 13); + this.label1.Size = new System.Drawing.Size(75, 15); this.label1.TabIndex = 1; this.label1.Text = "Server name:"; // // label2 // this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(30, 85); + this.label2.Location = new System.Drawing.Point(35, 98); + this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(56, 13); + this.label2.Size = new System.Drawing.Size(60, 15); this.label2.TabIndex = 3; this.label2.Text = "IP v4 port:"; // // ipV4Box // - this.ipV4Box.Location = new System.Drawing.Point(106, 82); + this.ipV4Box.Location = new System.Drawing.Point(124, 95); + this.ipV4Box.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.ipV4Box.Name = "ipV4Box"; - this.ipV4Box.Size = new System.Drawing.Size(100, 20); + this.ipV4Box.Size = new System.Drawing.Size(116, 23); this.ipV4Box.TabIndex = 2; // // label3 // this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(30, 111); + this.label3.Location = new System.Drawing.Point(35, 128); + this.label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(56, 13); + this.label3.Size = new System.Drawing.Size(60, 15); this.label3.TabIndex = 5; this.label3.Text = "IP v6 port:"; // // ipV6Box // - this.ipV6Box.Location = new System.Drawing.Point(106, 108); + this.ipV6Box.Location = new System.Drawing.Point(124, 125); + this.ipV6Box.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.ipV6Box.Name = "ipV6Box"; - this.ipV6Box.Size = new System.Drawing.Size(100, 20); + this.ipV6Box.Size = new System.Drawing.Size(116, 23); this.ipV6Box.TabIndex = 4; // // editPropsBtn // - this.editPropsBtn.Location = new System.Drawing.Point(33, 149); + this.editPropsBtn.Location = new System.Drawing.Point(38, 172); + this.editPropsBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.editPropsBtn.Name = "editPropsBtn"; - this.editPropsBtn.Size = new System.Drawing.Size(173, 23); + this.editPropsBtn.Size = new System.Drawing.Size(202, 27); this.editPropsBtn.TabIndex = 6; this.editPropsBtn.Text = "Edit server settings..."; this.editPropsBtn.UseVisualStyleBackColor = true; @@ -100,9 +107,10 @@ private void InitializeComponent() // // saveBtn // - this.saveBtn.Location = new System.Drawing.Point(106, 191); + this.saveBtn.Location = new System.Drawing.Point(124, 220); + this.saveBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.saveBtn.Name = "saveBtn"; - this.saveBtn.Size = new System.Drawing.Size(100, 23); + this.saveBtn.Size = new System.Drawing.Size(117, 27); this.saveBtn.TabIndex = 7; this.saveBtn.Text = "Save Server"; this.saveBtn.UseVisualStyleBackColor = true; @@ -112,18 +120,19 @@ private void InitializeComponent() // this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.label4.Location = new System.Drawing.Point(30, 9); + this.label4.Location = new System.Drawing.Point(35, 10); + this.label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(176, 44); + this.label4.Size = new System.Drawing.Size(201, 51); this.label4.TabIndex = 8; this.label4.Text = "Add a new server to the service. Note: Requires a Global restart to run new serve" + "r!"; // // AddNewServerForm // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(238, 226); + this.ClientSize = new System.Drawing.Size(274, 261); this.Controls.Add(this.label4); this.Controls.Add(this.saveBtn); this.Controls.Add(this.editPropsBtn); @@ -133,10 +142,14 @@ private void InitializeComponent() this.Controls.Add(this.ipV4Box); this.Controls.Add(this.label1); this.Controls.Add(this.srvNameBox); + this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.MaximizeBox = false; + this.MaximumSize = new System.Drawing.Size(290, 300); this.MinimizeBox = false; + this.MinimumSize = new System.Drawing.Size(290, 300); this.Name = "AddNewServerForm"; this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "AddNewServerForm"; this.ResumeLayout(false); this.PerformLayout(); diff --git a/BedrockService/Client/Forms/AddNewServerForm.cs b/BedrockService/Client/Forms/AddNewServerForm.cs index 9b328bac..9cd89859 100644 --- a/BedrockService/Client/Forms/AddNewServerForm.cs +++ b/BedrockService/Client/Forms/AddNewServerForm.cs @@ -5,15 +5,12 @@ using System.Linq; using System.Windows.Forms; -namespace BedrockService.Client.Forms -{ - public partial class AddNewServerForm : Form - { +namespace BedrockService.Client.Forms { + public partial class AddNewServerForm : Form { public List DefaultProps = new List(); private readonly List serverConfigurations; private readonly IClientSideServiceConfiguration serviceConfiguration; - public AddNewServerForm(IClientSideServiceConfiguration serviceConfiguration, List serverConfigurations) - { + public AddNewServerForm(IClientSideServiceConfiguration serviceConfiguration, List serverConfigurations) { this.serviceConfiguration = serviceConfiguration; this.serverConfigurations = serverConfigurations; InitializeComponent(); @@ -22,8 +19,7 @@ public AddNewServerForm(IClientSideServiceConfiguration serviceConfiguration, Li DefaultProps = server.GetAllProps(); } - private void editPropsBtn_Click(object sender, System.EventArgs e) - { + private void editPropsBtn_Click(object sender, System.EventArgs e) { PropEditorForm editSrvDialog = new PropEditorForm(); if (srvNameBox.TextLength > 0) DefaultProps.First(prop => prop.KeyName == "server-name").Value = srvNameBox.Text; @@ -32,27 +28,22 @@ private void editPropsBtn_Click(object sender, System.EventArgs e) if (ipV6Box.TextLength > 0) DefaultProps.First(prop => prop.KeyName == "server-portv6").Value = ipV6Box.Text; editSrvDialog.PopulateBoxes(DefaultProps); - if (editSrvDialog.ShowDialog() == DialogResult.OK) - { + if (editSrvDialog.ShowDialog() == DialogResult.OK) { DefaultProps = editSrvDialog.workingProps; editSrvDialog.Close(); editSrvDialog.Dispose(); } } - private void saveBtn_Click(object sender, System.EventArgs e) - { + private void saveBtn_Click(object sender, System.EventArgs e) { List usedPorts = new List(); usedPorts.Add(serviceConfiguration.GetPort()); - foreach (IServerConfiguration serverConfiguration in serverConfigurations) - { + foreach (IServerConfiguration serverConfiguration in serverConfigurations) { usedPorts.Add(serverConfiguration.GetProp("server-port").ToString()); usedPorts.Add(serverConfiguration.GetProp("server-portv6").ToString()); } - foreach(string port in usedPorts) - { - if(ipV4Box.Text == port || ipV6Box.Text == port) - { + foreach (string port in usedPorts) { + if (ipV4Box.Text == port || ipV6Box.Text == port) { MessageBox.Show($"You have selected port {port} to use, but this port is already used. Please select another port!"); return; } diff --git a/BedrockService/Client/Forms/AddNewServerForm.resx b/BedrockService/Client/Forms/AddNewServerForm.resx index 1af7de15..f298a7be 100644 --- a/BedrockService/Client/Forms/AddNewServerForm.resx +++ b/BedrockService/Client/Forms/AddNewServerForm.resx @@ -1,64 +1,4 @@ - - - + diff --git a/BedrockService/Client/Forms/ClientConfigForm.Designer.cs b/BedrockService/Client/Forms/ClientConfigForm.Designer.cs index bf9ac45d..28860705 100644 --- a/BedrockService/Client/Forms/ClientConfigForm.Designer.cs +++ b/BedrockService/Client/Forms/ClientConfigForm.Designer.cs @@ -41,16 +41,20 @@ private void InitializeComponent() // // serverGridView // + this.serverGridView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.serverGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; this.serverGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { this.HostName, this.HostAddress, this.Port}); - this.serverGridView.Location = new System.Drawing.Point(12, 30); + this.serverGridView.Location = new System.Drawing.Point(9, 22); + this.serverGridView.Margin = new System.Windows.Forms.Padding(2); this.serverGridView.Name = "serverGridView"; this.serverGridView.RowHeadersWidth = 62; this.serverGridView.RowTemplate.Height = 28; - this.serverGridView.Size = new System.Drawing.Size(1154, 381); + this.serverGridView.Size = new System.Drawing.Size(786, 184); this.serverGridView.TabIndex = 0; // // HostName @@ -76,18 +80,22 @@ private void InitializeComponent() // // nbtPathLabel // + this.nbtPathLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.nbtPathLabel.AutoSize = true; - this.nbtPathLabel.Location = new System.Drawing.Point(12, 437); + this.nbtPathLabel.Location = new System.Drawing.Point(9, 226); + this.nbtPathLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); this.nbtPathLabel.Name = "nbtPathLabel"; - this.nbtPathLabel.Size = new System.Drawing.Size(130, 20); + this.nbtPathLabel.Size = new System.Drawing.Size(95, 15); this.nbtPathLabel.TabIndex = 1; this.nbtPathLabel.Text = "NBT Studio path:"; // // nbtButton // - this.nbtButton.Location = new System.Drawing.Point(16, 473); + this.nbtButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.nbtButton.Location = new System.Drawing.Point(12, 253); + this.nbtButton.Margin = new System.Windows.Forms.Padding(2); this.nbtButton.Name = "nbtButton"; - this.nbtButton.Size = new System.Drawing.Size(209, 37); + this.nbtButton.Size = new System.Drawing.Size(163, 28); this.nbtButton.TabIndex = 2; this.nbtButton.Text = "Set NBT Studio path"; this.nbtButton.UseVisualStyleBackColor = true; @@ -95,9 +103,11 @@ private void InitializeComponent() // // saveBtn // - this.saveBtn.Location = new System.Drawing.Point(957, 473); + this.saveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.saveBtn.Location = new System.Drawing.Point(632, 253); + this.saveBtn.Margin = new System.Windows.Forms.Padding(2); this.saveBtn.Name = "saveBtn"; - this.saveBtn.Size = new System.Drawing.Size(209, 37); + this.saveBtn.Size = new System.Drawing.Size(163, 28); this.saveBtn.TabIndex = 3; this.saveBtn.Text = "Save settings"; this.saveBtn.UseVisualStyleBackColor = true; @@ -105,15 +115,18 @@ private void InitializeComponent() // // ClientConfigForm // - this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1178, 544); + this.ClientSize = new System.Drawing.Size(804, 306); this.Controls.Add(this.saveBtn); this.Controls.Add(this.nbtButton); this.Controls.Add(this.nbtPathLabel); this.Controls.Add(this.serverGridView); + this.Margin = new System.Windows.Forms.Padding(2); + this.MinimumSize = new System.Drawing.Size(820, 345); this.Name = "ClientConfigForm"; - this.Text = "ClientConfigForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Client Configuration"; ((System.ComponentModel.ISupportInitialize)(this.serverGridView)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); diff --git a/BedrockService/Client/Forms/ClientConfigForm.cs b/BedrockService/Client/Forms/ClientConfigForm.cs index 4d4c88b2..716e450f 100644 --- a/BedrockService/Client/Forms/ClientConfigForm.cs +++ b/BedrockService/Client/Forms/ClientConfigForm.cs @@ -3,63 +3,44 @@ using BedrockService.Shared.Interfaces; using System; using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows.Forms; -namespace BedrockService.Client.Forms -{ - public partial class ClientConfigForm : Form - { +namespace BedrockService.Client.Forms { + public partial class ClientConfigForm : Form { private readonly List _clientConfigs; private readonly ConfigManager _configManager; - public ClientConfigForm(ConfigManager configManager) - { + public ClientConfigForm(ConfigManager configManager) { InitializeComponent(); _configManager = configManager; _clientConfigs = _configManager.HostConnectList; - if (!string.IsNullOrEmpty(_configManager.NBTStudioPath)) - { + if (!string.IsNullOrEmpty(_configManager.NBTStudioPath)) { nbtPathLabel.Text = $"NBT Studio path: {_configManager.NBTStudioPath}"; } - foreach (IClientSideServiceConfiguration config in _clientConfigs) - { + foreach (IClientSideServiceConfiguration config in _clientConfigs) { serverGridView.Rows.Add(new string[3] { config.GetHostName(), config.GetAddress(), config.GetPort() }); } } - public void SimulateTests() - { + public void SimulateTests() { nbtButton.PerformClick(); } - private void nbtButton_Click(object sender, EventArgs e) - { - using(OpenFileDialog fileDialog = new OpenFileDialog()) - { + private void nbtButton_Click(object sender, EventArgs e) { + using (OpenFileDialog fileDialog = new OpenFileDialog()) { fileDialog.Filter = "EXE Files|*.exe"; fileDialog.FileName = "NbtStudio.exe"; fileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); - if(fileDialog.ShowDialog() == DialogResult.OK) - { + if (fileDialog.ShowDialog() == DialogResult.OK) { _configManager.NBTStudioPath = fileDialog.FileName; nbtPathLabel.Text = $"NBT Studio path: {_configManager.NBTStudioPath}"; } } } - private void saveBtn_Click(object sender, EventArgs e) - { + private void saveBtn_Click(object sender, EventArgs e) { List newConfigs = new List(); - foreach(DataGridViewRow row in serverGridView.Rows) - { - if (!string.IsNullOrEmpty((string)row.Cells[0].Value)) - { + foreach (DataGridViewRow row in serverGridView.Rows) { + if (!string.IsNullOrEmpty((string)row.Cells[0].Value)) { newConfigs.Add(new ClientSideServiceConfiguration((string)row.Cells[0].Value, (string)row.Cells[1].Value, (string)row.Cells[2].Value)); } } diff --git a/BedrockService/Client/Forms/ClientConfigForm.resx b/BedrockService/Client/Forms/ClientConfigForm.resx index 2d8f1f02..51332f02 100644 --- a/BedrockService/Client/Forms/ClientConfigForm.resx +++ b/BedrockService/Client/Forms/ClientConfigForm.resx @@ -1,64 +1,4 @@ - - - + @@ -126,13 +66,4 @@ True - - True - - - True - - - True - \ No newline at end of file diff --git a/BedrockService/Client/Forms/MainWindow.Designer.cs b/BedrockService/Client/Forms/MainWindow.Designer.cs index 7b72ed20..f63ebee1 100644 --- a/BedrockService/Client/Forms/MainWindow.Designer.cs +++ b/BedrockService/Client/Forms/MainWindow.Designer.cs @@ -58,9 +58,10 @@ private void InitializeComponent() // Connect // this.Connect.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.Connect.Location = new System.Drawing.Point(622, 57); + this.Connect.Location = new System.Drawing.Point(580, 66); + this.Connect.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.Connect.Name = "Connect"; - this.Connect.Size = new System.Drawing.Size(170, 25); + this.Connect.Size = new System.Drawing.Size(198, 29); this.Connect.TabIndex = 0; this.Connect.Text = "Connect"; this.Connect.UseVisualStyleBackColor = true; @@ -70,9 +71,10 @@ private void InitializeComponent() // this.HostInfoLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.HostInfoLabel.AutoSize = true; - this.HostInfoLabel.Location = new System.Drawing.Point(620, 12); + this.HostInfoLabel.Location = new System.Drawing.Point(577, 14); + this.HostInfoLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.HostInfoLabel.Name = "HostInfoLabel"; - this.HostInfoLabel.Size = new System.Drawing.Size(87, 13); + this.HostInfoLabel.Size = new System.Drawing.Size(98, 15); this.HostInfoLabel.TabIndex = 1; this.HostInfoLabel.Text = "HostConnectInfo"; // @@ -81,9 +83,10 @@ private void InitializeComponent() this.HostListBox.AllowDrop = true; this.HostListBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.HostListBox.FormattingEnabled = true; - this.HostListBox.Location = new System.Drawing.Point(622, 28); + this.HostListBox.Location = new System.Drawing.Point(580, 32); + this.HostListBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.HostListBox.Name = "HostListBox"; - this.HostListBox.Size = new System.Drawing.Size(355, 21); + this.HostListBox.Size = new System.Drawing.Size(414, 23); this.HostListBox.TabIndex = 2; this.HostListBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.HostListBox_KeyPress); // @@ -92,12 +95,13 @@ private void InitializeComponent() this.LogBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.LogBox.Location = new System.Drawing.Point(12, 28); + this.LogBox.Location = new System.Drawing.Point(14, 32); + this.LogBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.LogBox.Multiline = true; this.LogBox.Name = "LogBox"; this.LogBox.ReadOnly = true; this.LogBox.ScrollBars = System.Windows.Forms.ScrollBars.Both; - this.LogBox.Size = new System.Drawing.Size(580, 361); + this.LogBox.Size = new System.Drawing.Size(530, 402); this.LogBox.TabIndex = 3; this.LogBox.WordWrap = false; // @@ -106,9 +110,11 @@ private void InitializeComponent() this.ServerSelectBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Right))); this.ServerSelectBox.FormattingEnabled = true; - this.ServerSelectBox.Location = new System.Drawing.Point(808, 96); + this.ServerSelectBox.ItemHeight = 15; + this.ServerSelectBox.Location = new System.Drawing.Point(797, 111); + this.ServerSelectBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.ServerSelectBox.Name = "ServerSelectBox"; - this.ServerSelectBox.Size = new System.Drawing.Size(170, 95); + this.ServerSelectBox.Size = new System.Drawing.Size(198, 94); this.ServerSelectBox.TabIndex = 4; this.ServerSelectBox.SelectedIndexChanged += new System.EventHandler(this.ServerSelectBox_SelectedIndexChanged); // @@ -116,9 +122,10 @@ private void InitializeComponent() // this.Disconn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.Disconn.Enabled = false; - this.Disconn.Location = new System.Drawing.Point(808, 57); + this.Disconn.Location = new System.Drawing.Point(797, 66); + this.Disconn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.Disconn.Name = "Disconn"; - this.Disconn.Size = new System.Drawing.Size(170, 25); + this.Disconn.Size = new System.Drawing.Size(198, 29); this.Disconn.TabIndex = 5; this.Disconn.Text = "Disconnect"; this.Disconn.UseVisualStyleBackColor = true; @@ -128,9 +135,10 @@ private void InitializeComponent() // this.EditGlobals.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.EditGlobals.Enabled = false; - this.EditGlobals.Location = new System.Drawing.Point(808, 266); + this.EditGlobals.Location = new System.Drawing.Point(797, 293); + this.EditGlobals.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.EditGlobals.Name = "EditGlobals"; - this.EditGlobals.Size = new System.Drawing.Size(170, 23); + this.EditGlobals.Size = new System.Drawing.Size(198, 27); this.EditGlobals.TabIndex = 8; this.EditGlobals.Text = "Edit global service settings"; this.EditGlobals.UseVisualStyleBackColor = true; @@ -140,9 +148,10 @@ private void InitializeComponent() // this.removeSrvBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.removeSrvBtn.Enabled = false; - this.removeSrvBtn.Location = new System.Drawing.Point(808, 353); + this.removeSrvBtn.Location = new System.Drawing.Point(797, 393); + this.removeSrvBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.removeSrvBtn.Name = "removeSrvBtn"; - this.removeSrvBtn.Size = new System.Drawing.Size(170, 23); + this.removeSrvBtn.Size = new System.Drawing.Size(198, 27); this.removeSrvBtn.TabIndex = 9; this.removeSrvBtn.Text = "Remove selected server"; this.removeSrvBtn.UseVisualStyleBackColor = true; @@ -152,9 +161,10 @@ private void InitializeComponent() // this.ChkUpdates.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.ChkUpdates.Enabled = false; - this.ChkUpdates.Location = new System.Drawing.Point(808, 294); + this.ChkUpdates.Location = new System.Drawing.Point(797, 325); + this.ChkUpdates.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.ChkUpdates.Name = "ChkUpdates"; - this.ChkUpdates.Size = new System.Drawing.Size(170, 23); + this.ChkUpdates.Size = new System.Drawing.Size(198, 27); this.ChkUpdates.TabIndex = 10; this.ChkUpdates.Text = "Check for updates"; this.ChkUpdates.UseVisualStyleBackColor = true; @@ -164,9 +174,10 @@ private void InitializeComponent() // this.GlobBackup.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.GlobBackup.Enabled = false; - this.GlobBackup.Location = new System.Drawing.Point(808, 237); + this.GlobBackup.Location = new System.Drawing.Point(797, 259); + this.GlobBackup.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.GlobBackup.Name = "GlobBackup"; - this.GlobBackup.Size = new System.Drawing.Size(170, 23); + this.GlobBackup.Size = new System.Drawing.Size(198, 27); this.GlobBackup.TabIndex = 11; this.GlobBackup.Text = "Backup all servers"; this.GlobBackup.UseVisualStyleBackColor = true; @@ -176,9 +187,10 @@ private void InitializeComponent() // this.cmdTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.cmdTextBox.Enabled = false; - this.cmdTextBox.Location = new System.Drawing.Point(446, 429); + this.cmdTextBox.Location = new System.Drawing.Point(374, 481); + this.cmdTextBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.cmdTextBox.Name = "cmdTextBox"; - this.cmdTextBox.Size = new System.Drawing.Size(355, 20); + this.cmdTextBox.Size = new System.Drawing.Size(414, 23); this.cmdTextBox.TabIndex = 12; this.cmdTextBox.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.cmdTextBox_KeyPress); // @@ -186,9 +198,10 @@ private void InitializeComponent() // this.SendCmd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.SendCmd.Enabled = false; - this.SendCmd.Location = new System.Drawing.Point(808, 426); + this.SendCmd.Location = new System.Drawing.Point(797, 478); + this.SendCmd.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.SendCmd.Name = "SendCmd"; - this.SendCmd.Size = new System.Drawing.Size(170, 23); + this.SendCmd.Size = new System.Drawing.Size(198, 27); this.SendCmd.TabIndex = 13; this.SendCmd.Text = "Send command to server"; this.SendCmd.UseVisualStyleBackColor = true; @@ -198,9 +211,10 @@ private void InitializeComponent() // this.EditCfg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.EditCfg.Enabled = false; - this.EditCfg.Location = new System.Drawing.Point(622, 208); + this.EditCfg.Location = new System.Drawing.Point(580, 226); + this.EditCfg.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.EditCfg.Name = "EditCfg"; - this.EditCfg.Size = new System.Drawing.Size(170, 23); + this.EditCfg.Size = new System.Drawing.Size(198, 27); this.EditCfg.TabIndex = 15; this.EditCfg.Text = "Edit server config"; this.EditCfg.UseVisualStyleBackColor = true; @@ -210,9 +224,10 @@ private void InitializeComponent() // this.PlayerManagerBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.PlayerManagerBtn.Enabled = false; - this.PlayerManagerBtn.Location = new System.Drawing.Point(622, 382); + this.PlayerManagerBtn.Location = new System.Drawing.Point(580, 427); + this.PlayerManagerBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.PlayerManagerBtn.Name = "PlayerManagerBtn"; - this.PlayerManagerBtn.Size = new System.Drawing.Size(170, 23); + this.PlayerManagerBtn.Size = new System.Drawing.Size(198, 27); this.PlayerManagerBtn.TabIndex = 16; this.PlayerManagerBtn.Text = "Player Manager"; this.PlayerManagerBtn.UseVisualStyleBackColor = true; @@ -222,9 +237,10 @@ private void InitializeComponent() // this.EditStCmd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.EditStCmd.Enabled = false; - this.EditStCmd.Location = new System.Drawing.Point(622, 237); + this.EditStCmd.Location = new System.Drawing.Point(580, 259); + this.EditStCmd.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.EditStCmd.Name = "EditStCmd"; - this.EditStCmd.Size = new System.Drawing.Size(170, 23); + this.EditStCmd.Size = new System.Drawing.Size(198, 27); this.EditStCmd.TabIndex = 18; this.EditStCmd.Text = "Edit start commands"; this.EditStCmd.UseVisualStyleBackColor = true; @@ -234,9 +250,10 @@ private void InitializeComponent() // this.ManPacks.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.ManPacks.Enabled = false; - this.ManPacks.Location = new System.Drawing.Point(622, 353); + this.ManPacks.Location = new System.Drawing.Point(580, 393); + this.ManPacks.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.ManPacks.Name = "ManPacks"; - this.ManPacks.Size = new System.Drawing.Size(170, 23); + this.ManPacks.Size = new System.Drawing.Size(198, 27); this.ManPacks.TabIndex = 19; this.ManPacks.Text = "R/B Pack Manager"; this.ManPacks.UseVisualStyleBackColor = true; @@ -246,9 +263,10 @@ private void InitializeComponent() // this.SingBackup.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.SingBackup.Enabled = false; - this.SingBackup.Location = new System.Drawing.Point(622, 266); + this.SingBackup.Location = new System.Drawing.Point(580, 293); + this.SingBackup.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.SingBackup.Name = "SingBackup"; - this.SingBackup.Size = new System.Drawing.Size(170, 23); + this.SingBackup.Size = new System.Drawing.Size(198, 27); this.SingBackup.TabIndex = 20; this.SingBackup.Text = "Backup selected server"; this.SingBackup.UseVisualStyleBackColor = true; @@ -258,9 +276,10 @@ private void InitializeComponent() // this.RestartSrv.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.RestartSrv.Enabled = false; - this.RestartSrv.Location = new System.Drawing.Point(622, 294); + this.RestartSrv.Location = new System.Drawing.Point(580, 325); + this.RestartSrv.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.RestartSrv.Name = "RestartSrv"; - this.RestartSrv.Size = new System.Drawing.Size(170, 23); + this.RestartSrv.Size = new System.Drawing.Size(198, 27); this.RestartSrv.TabIndex = 21; this.RestartSrv.Text = "Restart selected server"; this.RestartSrv.UseVisualStyleBackColor = true; @@ -270,9 +289,10 @@ private void InitializeComponent() // this.BackupManagerBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.BackupManagerBtn.Enabled = false; - this.BackupManagerBtn.Location = new System.Drawing.Point(622, 324); + this.BackupManagerBtn.Location = new System.Drawing.Point(580, 360); + this.BackupManagerBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.BackupManagerBtn.Name = "BackupManagerBtn"; - this.BackupManagerBtn.Size = new System.Drawing.Size(170, 23); + this.BackupManagerBtn.Size = new System.Drawing.Size(198, 27); this.BackupManagerBtn.TabIndex = 22; this.BackupManagerBtn.Text = "Backup Manager"; this.BackupManagerBtn.UseVisualStyleBackColor = true; @@ -282,10 +302,11 @@ private void InitializeComponent() // this.SvcLog.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.SvcLog.Enabled = false; - this.SvcLog.Location = new System.Drawing.Point(17, 395); + this.SvcLog.Location = new System.Drawing.Point(20, 442); + this.SvcLog.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.SvcLog.Name = "SvcLog"; this.SvcLog.RightToLeft = System.Windows.Forms.RightToLeft.No; - this.SvcLog.Size = new System.Drawing.Size(131, 26); + this.SvcLog.Size = new System.Drawing.Size(153, 30); this.SvcLog.TabIndex = 24; this.SvcLog.Text = "Switch to service logs"; this.SvcLog.TextAlign = System.Drawing.ContentAlignment.MiddleRight; @@ -295,20 +316,22 @@ private void InitializeComponent() // this.ServerInfoBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Right))); - this.ServerInfoBox.Location = new System.Drawing.Point(622, 96); + this.ServerInfoBox.Location = new System.Drawing.Point(580, 111); + this.ServerInfoBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.ServerInfoBox.Multiline = true; this.ServerInfoBox.Name = "ServerInfoBox"; this.ServerInfoBox.ReadOnly = true; - this.ServerInfoBox.Size = new System.Drawing.Size(170, 95); + this.ServerInfoBox.Size = new System.Drawing.Size(198, 95); this.ServerInfoBox.TabIndex = 25; // // newSrvBtn // this.newSrvBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.newSrvBtn.Enabled = false; - this.newSrvBtn.Location = new System.Drawing.Point(808, 208); + this.newSrvBtn.Location = new System.Drawing.Point(797, 226); + this.newSrvBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.newSrvBtn.Name = "newSrvBtn"; - this.newSrvBtn.Size = new System.Drawing.Size(170, 23); + this.newSrvBtn.Size = new System.Drawing.Size(198, 27); this.newSrvBtn.TabIndex = 26; this.newSrvBtn.Text = "Deploy new server"; this.newSrvBtn.UseVisualStyleBackColor = true; @@ -318,10 +341,11 @@ private void InitializeComponent() // this.scrollLockChkBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.scrollLockChkBox.Enabled = false; - this.scrollLockChkBox.Location = new System.Drawing.Point(464, 395); + this.scrollLockChkBox.Location = new System.Drawing.Point(395, 442); + this.scrollLockChkBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.scrollLockChkBox.Name = "scrollLockChkBox"; this.scrollLockChkBox.RightToLeft = System.Windows.Forms.RightToLeft.No; - this.scrollLockChkBox.Size = new System.Drawing.Size(131, 26); + this.scrollLockChkBox.Size = new System.Drawing.Size(153, 30); this.scrollLockChkBox.TabIndex = 27; this.scrollLockChkBox.Text = "Lock scrollbar to end"; this.scrollLockChkBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight; @@ -332,9 +356,10 @@ private void InitializeComponent() // this.nbtStudioBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.nbtStudioBtn.Enabled = false; - this.nbtStudioBtn.Location = new System.Drawing.Point(808, 324); + this.nbtStudioBtn.Location = new System.Drawing.Point(797, 360); + this.nbtStudioBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.nbtStudioBtn.Name = "nbtStudioBtn"; - this.nbtStudioBtn.Size = new System.Drawing.Size(170, 23); + this.nbtStudioBtn.Size = new System.Drawing.Size(198, 27); this.nbtStudioBtn.TabIndex = 28; this.nbtStudioBtn.Text = "Edit world via NBTStudio"; this.nbtStudioBtn.UseVisualStyleBackColor = true; @@ -343,10 +368,10 @@ private void InitializeComponent() // clientConfigBtn // this.clientConfigBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.clientConfigBtn.Location = new System.Drawing.Point(808, 382); - this.clientConfigBtn.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.clientConfigBtn.Location = new System.Drawing.Point(797, 427); + this.clientConfigBtn.Margin = new System.Windows.Forms.Padding(5, 6, 5, 6); this.clientConfigBtn.Name = "clientConfigBtn"; - this.clientConfigBtn.Size = new System.Drawing.Size(170, 23); + this.clientConfigBtn.Size = new System.Drawing.Size(198, 27); this.clientConfigBtn.TabIndex = 29; this.clientConfigBtn.Text = "Edit client config"; this.clientConfigBtn.UseVisualStyleBackColor = true; @@ -354,9 +379,9 @@ private void InitializeComponent() // // MainWindow // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(989, 467); + this.ClientSize = new System.Drawing.Size(1008, 525); this.Controls.Add(this.clientConfigBtn); this.Controls.Add(this.nbtStudioBtn); this.Controls.Add(this.scrollLockChkBox); @@ -382,7 +407,8 @@ private void InitializeComponent() this.Controls.Add(this.HostListBox); this.Controls.Add(this.HostInfoLabel); this.Controls.Add(this.Connect); - this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.Margin = new System.Windows.Forms.Padding(5, 6, 5, 6); + this.MinimumSize = new System.Drawing.Size(1024, 564); this.Name = "MainWindow"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "Bedrock Service Management"; diff --git a/BedrockService/Client/Forms/MainWindow.cs b/BedrockService/Client/Forms/MainWindow.cs index 2420abe2..ab831456 100644 --- a/BedrockService/Client/Forms/MainWindow.cs +++ b/BedrockService/Client/Forms/MainWindow.cs @@ -6,18 +6,15 @@ using System.Diagnostics; using System.IO; using System.Linq; -using System.Reflection; using System.Runtime.InteropServices; using System.Text; -using System.Timers; using System.Threading; using System.Threading.Tasks; +using System.Timers; using System.Windows.Forms; -namespace BedrockService.Client.Forms -{ - public partial class MainWindow : Form - { +namespace BedrockService.Client.Forms { + public partial class MainWindow : Form { public IServiceConfiguration connectedHost; public IServerConfiguration selectedServer; public IClientSideServiceConfiguration clientSideServiceConfiguration; @@ -27,13 +24,12 @@ public partial class MainWindow : Form private int _connectTimeout; private bool _followTail = false; private const int _connectTimeoutLimit = 3; - private readonly ILogger _logger; + private readonly IBedrockLogger _logger; private readonly IProcessInfo _processInfo; private readonly System.Timers.Timer _connectTimer = new System.Timers.Timer(100.0); private readonly LogManager _logManager; private readonly ConfigManager _configManager; - public MainWindow(IProcessInfo processInfo, ILogger logger) - { + public MainWindow(IProcessInfo processInfo, IBedrockLogger logger) { _processInfo = processInfo; _logger = logger; _logManager = new LogManager(_logger); @@ -44,15 +40,12 @@ public MainWindow(IProcessInfo processInfo, ILogger logger) _connectTimer.Elapsed += ConnectTimer_Elapsed; } - private void ConnectTimer_Elapsed(object sender, ElapsedEventArgs e) - { - if (_connectTimer.Enabled && !FormManager.TCPClient.Connected) - { - if (_connectTimer.Interval == 100.0) - _connectTimer.Interval = 5000.0; + private void ConnectTimer_Elapsed(object sender, ElapsedEventArgs e) { + if (_connectTimer.Enabled && !FormManager.TCPClient.EstablishedLink) { + _connectTimer.Interval = 2000.0; Invoke((MethodInvoker)delegate { FormManager.TCPClient.ConnectHost(_configManager.HostConnectList.FirstOrDefault(host => host.GetHostName() == (string)HostListBox.SelectedItem)); }); - if (connectedHost != null && FormManager.TCPClient.Connected) - { + Thread.Sleep(500); + if (connectedHost != null && FormManager.TCPClient.EstablishedLink) { ServerBusy = false; Invoke((MethodInvoker)delegate { ComponentEnableManager(); }); _connectTimer.Enabled = false; @@ -61,19 +54,17 @@ private void ConnectTimer_Elapsed(object sender, ElapsedEventArgs e) return; } _connectTimeout++; - if (_connectTimeout >= _connectTimeoutLimit) - { - Invoke((MethodInvoker)delegate - { + if (_connectTimeout >= _connectTimeoutLimit) { + _connectTimer.Enabled = false; + _connectTimer.Stop(); + _connectTimer.Close(); + Invoke((MethodInvoker)delegate { RefreshServerContents(); HostInfoLabel.Text = $"Failed to connect to host!"; Connect.Enabled = true; ComponentEnableManager(); - _connectTimer.Enabled = false; - _connectTimer.Stop(); - _connectTimer.Close(); - return; }); + return; } } } @@ -92,8 +83,7 @@ private void ConnectTimer_Elapsed(object sender, ElapsedEventArgs e) [DllImport("user32.dll")] static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); - struct ScrollInfo - { + struct ScrollInfo { public uint Size; public uint Mask; public int Min; @@ -103,8 +93,7 @@ struct ScrollInfo public int TrackPos; } - enum ScrollInfoMask - { + enum ScrollInfoMask { Range = 0x1, Page = 0x2, Pos = 0x4, @@ -113,8 +102,7 @@ enum ScrollInfoMask All = Range + Page + Pos + TrackPos } - enum ScrollBarDirection - { + enum ScrollBarDirection { Horizontal = 0, Vertical = 1, Ctl = 2, @@ -141,34 +129,28 @@ enum ScrollBarDirection [STAThread] - public static void Main() - { + public static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.ApplicationExit += OnExit; Application.Run(FormManager.MainWindow); } - public void RefreshServerContents() - { - Invoke((MethodInvoker)delegate - { + public void RefreshServerContents() { + Invoke((MethodInvoker)delegate { Refresh(); return; }); } - public override void Refresh() - { + public override void Refresh() { HostInfoLabel.Text = $"Connected to host:"; ServerSelectBox.Items.Clear(); - if(connectedHost != null) - { + if (connectedHost != null) { _logManager.InitLogThread(connectedHost); foreach (ServerInfo server in connectedHost.GetServerList()) ServerSelectBox.Items.Add(server.ServerName); - if(ServerSelectBox.Items.Count > 0) - { + if (ServerSelectBox.Items.Count > 0) { ServerSelectBox.SelectedIndex = 0; selectedServer = connectedHost.GetServerInfoByName((string)ServerSelectBox.SelectedItem); } @@ -177,27 +159,22 @@ public override void Refresh() base.Refresh(); } - public void InitForm() - { + public void InitForm() { _configManager.LoadConfigs(); HostListBox.Items.Clear(); - foreach (IClientSideServiceConfiguration host in _configManager.HostConnectList) - { + foreach (IClientSideServiceConfiguration host in _configManager.HostConnectList) { HostListBox.Items.Add(host.GetHostName()); } - if(HostListBox.Items.Count > 0) - { + if (HostListBox.Items.Count > 0) { HostListBox.SelectedIndex = 0; } HostListBox.Refresh(); FormClosing += MainWindow_FormClosing; } - public void HeartbeatFailDisconnect() - { + public void HeartbeatFailDisconnect() { Disconn_Click(null, null); - try - { + try { HostInfoLabel.Invoke((MethodInvoker)delegate { HostInfoLabel.Text = "Lost connection to host!"; }); ServerInfoBox.Invoke((MethodInvoker)delegate { ServerInfoBox.Text = "Lost connection to host!"; }); ServerBusy = false; @@ -209,8 +186,7 @@ public void HeartbeatFailDisconnect() connectedHost = null; } - public void UpdateLogBox(string contents) - { + public void UpdateLogBox(string contents) { int curPos = HorizontalScrollPosition; LogBox.Text = contents; HorizontalScrollPosition = curPos; @@ -218,21 +194,17 @@ public void UpdateLogBox(string contents) ScrollToEnd(); } - private static void OnExit(object sender, EventArgs e) - { + private static void OnExit(object sender, EventArgs e) { FormManager.TCPClient.Dispose(); } - private void SvcLog_CheckedChanged(object sender, EventArgs e) - { + private void SvcLog_CheckedChanged(object sender, EventArgs e) { ShowsSvcLog = SvcLog.Checked; } - private void MainWindow_FormClosing(object sender, FormClosingEventArgs e) - { + private void MainWindow_FormClosing(object sender, FormClosingEventArgs e) { _logger.AppendLine("Stopping log thread..."); - if (_logManager.StopLogThread()) - { + if (_logManager.StopLogThread()) { _logger.AppendLine("Sending disconnect msg..."); FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Service, NetworkMessageTypes.Disconnect); _logger.AppendLine("Closing connection..."); @@ -242,8 +214,7 @@ private void MainWindow_FormClosing(object sender, FormClosingEventArgs e) } } - private void Connect_Click(object sender, EventArgs e) - { + private void Connect_Click(object sender, EventArgs e) { HostInfoLabel.Text = $"Connecting to host {(string)HostListBox.SelectedItem}..."; Connect.Enabled = false; _connectTimeout = 0; @@ -251,14 +222,10 @@ private void Connect_Click(object sender, EventArgs e) _connectTimer.Start(); } - private void ServerSelectBox_SelectedIndexChanged(object sender, EventArgs e) - { - if (connectedHost != null) - { - foreach (ServerInfo server in connectedHost.GetServerList()) - { - if (ServerSelectBox.SelectedItem != null && ServerSelectBox.SelectedItem.ToString() == server.GetServerName()) - { + private void ServerSelectBox_SelectedIndexChanged(object sender, EventArgs e) { + if (connectedHost != null) { + foreach (ServerInfo server in connectedHost.GetServerList()) { + if (ServerSelectBox.SelectedItem != null && ServerSelectBox.SelectedItem.ToString() == server.GetServerName()) { selectedServer = server; ServerInfoBox.Text = server.GetServerName(); ComponentEnableManager(); @@ -267,20 +234,16 @@ private void ServerSelectBox_SelectedIndexChanged(object sender, EventArgs e) } } - private void SingBackup_Click(object sender, EventArgs e) - { + private void SingBackup_Click(object sender, EventArgs e) { FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Server, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.Backup); DisableUI(); } - private void EditCfg_Click(object sender, EventArgs e) - { + private void EditCfg_Click(object sender, EventArgs e) { _editDialog = new PropEditorForm(); _editDialog.PopulateBoxes(selectedServer.GetAllProps()); - if (_editDialog.ShowDialog() == DialogResult.OK) - { - JsonSerializerSettings settings = new JsonSerializerSettings() - { + if (_editDialog.ShowDialog() == DialogResult.OK) { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(_editDialog.workingProps, Formatting.Indented, settings)); @@ -292,20 +255,16 @@ private void EditCfg_Click(object sender, EventArgs e) } } - private void RestartSrv_Click(object sender, EventArgs e) - { + private void RestartSrv_Click(object sender, EventArgs e) { FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Server, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.Restart); DisableUI(); } - private void EditGlobals_Click(object sender, EventArgs e) - { + private void EditGlobals_Click(object sender, EventArgs e) { _editDialog = new PropEditorForm(); _editDialog.PopulateBoxes(connectedHost.GetAllProps()); - if (_editDialog.ShowDialog() == DialogResult.OK) - { - JsonSerializerSettings settings = new JsonSerializerSettings() - { + if (_editDialog.ShowDialog() == DialogResult.OK) { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(_editDialog.workingProps, Formatting.Indented, settings)); @@ -313,27 +272,33 @@ private void EditGlobals_Click(object sender, EventArgs e) connectedHost.SetAllProps(_editDialog.workingProps); _editDialog.Close(); _editDialog.Dispose(); - RestartSrv_Click(null, null); + ServiceRestartFromClient(); } } - private void GlobBackup_Click(object sender, EventArgs e) - { + private void GlobBackup_Click(object sender, EventArgs e) { FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Service, NetworkMessageTypes.BackupAll); DisableUI(); } - private void newSrvBtn_Click(object sender, EventArgs e) - { - if(clientSideServiceConfiguration == null) - { + private Task ServiceRestartFromClient() { + return Task.Run(() => { + Invoke(() => { + Disconn_Click(null, null); + Connect.Enabled = false; + Task.Delay(6000).Wait(); + Connect_Click(null, null); + }); + }); + } + + private void newSrvBtn_Click(object sender, EventArgs e) { + if (clientSideServiceConfiguration == null) { clientSideServiceConfiguration = _configManager.HostConnectList.First(host => host.GetHostName() == HostListBox.Text); } AddNewServerForm newServerForm = new AddNewServerForm(clientSideServiceConfiguration, connectedHost.GetServerList()); - if (newServerForm.ShowDialog() == DialogResult.OK) - { - JsonSerializerSettings settings = new JsonSerializerSettings() - { + if (newServerForm.ShowDialog() == DialogResult.OK) { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(newServerForm.DefaultProps, Formatting.Indented, settings)); @@ -343,29 +308,27 @@ private void newSrvBtn_Click(object sender, EventArgs e) } } - private void RemoveSrvBtn_Click(object sender, EventArgs e) - { + private void RemoveSrvBtn_Click(object sender, EventArgs e) { FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Service, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.RemoveServer, NetworkMessageFlags.RemoveAll); DisableUI(); } - private void PlayerManager_Click(object sender, EventArgs e) - { + private void PlayerManager_Click(object sender, EventArgs e) { FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Server, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.PlayersRequest); + DisableUI(); WaitForServerData().Wait(); FormManager.TCPClient.PlayerInfoArrived = false; PlayerManagerForm form = new PlayerManagerForm(selectedServer); - form.Show(); + if (form.ShowDialog() != DialogResult.OK) { + ServerBusy = false; + } } - private void Disconn_Click(object sender, EventArgs e) - { - if (_logManager.StopLogThread()) - { - try - { - if (FormManager.TCPClient.Connected) - { + private void Disconn_Click(object sender, EventArgs e) { + _connectTimer.Stop(); + if (_logManager.StopLogThread()) { + try { + if (FormManager.TCPClient.Connected) { FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Service, NetworkMessageTypes.Disconnect); Thread.Sleep(500); FormManager.TCPClient.CloseConnection(); @@ -373,8 +336,7 @@ private void Disconn_Click(object sender, EventArgs e) selectedServer = null; connectedHost = null; LogBox.Invoke((MethodInvoker)delegate { LogBox.Text = ""; }); - FormManager.MainWindow.Invoke((MethodInvoker)delegate - { + FormManager.MainWindow.Invoke((MethodInvoker)delegate { ComponentEnableManager(); ServerSelectBox.Items.Clear(); ServerSelectBox.SelectedIndex = -1; @@ -387,27 +349,22 @@ private void Disconn_Click(object sender, EventArgs e) } } - private void SendCmd_Click(object sender, EventArgs e) - { - if (cmdTextBox.Text.Length > 0) - { + private void SendCmd_Click(object sender, EventArgs e) { + if (cmdTextBox.Text.Length > 0) { byte[] msg = Encoding.UTF8.GetBytes(cmdTextBox.Text); FormManager.TCPClient.SendData(msg, NetworkMessageSource.Client, NetworkMessageDestination.Server, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.Command); } cmdTextBox.Text = ""; } - private void EditStCmd_Click(object sender, EventArgs e) - { + private void EditStCmd_Click(object sender, EventArgs e) { PropEditorForm editSrvDialog = new PropEditorForm(); editSrvDialog.PopulateStartCmds(selectedServer.GetStartCommands()); - JsonSerializerSettings settings = new JsonSerializerSettings() - { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; - byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(editSrvDialog.startCmds, Formatting.Indented, settings)); - if (editSrvDialog.ShowDialog() == DialogResult.OK) - { + if (editSrvDialog.ShowDialog() == DialogResult.OK) { + byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(editSrvDialog.startCmds, Formatting.Indented, settings)); DisableUI(); FormManager.TCPClient.SendData(serializeToBytes, NetworkMessageSource.Client, NetworkMessageDestination.Service, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.StartCmdUpdate); selectedServer.SetStartCommands(editSrvDialog.startCmds); @@ -417,24 +374,20 @@ private void EditStCmd_Click(object sender, EventArgs e) } } - private void ChkUpdates_Click(object sender, EventArgs e) - { + private void ChkUpdates_Click(object sender, EventArgs e) { FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Service, NetworkMessageTypes.CheckUpdates); DisableUI(); } - private int HorizontalScrollPosition - { - get - { + private int HorizontalScrollPosition { + get { ScrollInfo si = new ScrollInfo(); si.Size = (uint)Marshal.SizeOf(si); si.Mask = (uint)ScrollInfoMask.All; GetScrollInfo(LogBox.Handle, (int)ScrollBarDirection.Vertical, ref si); return si.Pos; } - set - { + set { ScrollInfo si = new ScrollInfo(); si.Size = (uint)Marshal.SizeOf(si); si.Mask = (uint)ScrollInfoMask.All; @@ -445,8 +398,7 @@ private int HorizontalScrollPosition } } - public void ScrollToEnd() - { + public void ScrollToEnd() { // Get the current scroll info. ScrollInfo si = new ScrollInfo(); @@ -462,26 +414,22 @@ public void ScrollToEnd() _followTail = true; } - public void PerformBackupTests() - { + public void PerformBackupTests() { HostListBox.SelectedIndex = 0; Connect_Click(null, null); GlobBackup_Click(null, null); DisableUI(); ServerSelectBox.SelectedIndex = 0; FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Service, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.EnumBackups); - DisableUI().Wait(); FormManager.TCPClient.EnumBackupsArrived = false; - JsonSerializerSettings settings = new JsonSerializerSettings() - { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new string[] { FormManager.TCPClient.BackupList[0].ToString() }, Formatting.Indented, settings)); FormManager.TCPClient.SendData(serializeToBytes, NetworkMessageSource.Client, NetworkMessageDestination.Service, FormManager.MainWindow.connectedHost.GetServerIndex(FormManager.MainWindow.selectedServer), NetworkMessageTypes.DelBackups); } - private void ComponentEnableManager() - { + private void ComponentEnableManager() { Connect.Enabled = connectedHost == null; Disconn.Enabled = connectedHost != null; newSrvBtn.Enabled = connectedHost != null && !ServerBusy; @@ -504,119 +452,101 @@ private void ComponentEnableManager() SvcLog.Enabled = (connectedHost != null && selectedServer != null && !ServerBusy); } - public Task DisableUI() - { + public Task DisableUI() { ServerBusy = true; - return Task.Run(() => - { - + return Task.Run(() => { Invoke((MethodInvoker)delegate { ComponentEnableManager(); }); - while (ServerBusy) - { - Task.Delay(250); + while (ServerBusy) { + Task.Delay(250).Wait(); } Invoke((MethodInvoker)delegate { ComponentEnableManager(); }); }); } - public Task WaitForServerData() - { - return Task.Run(() => - { - while (!FormManager.TCPClient.EnumBackupsArrived && !FormManager.TCPClient.PlayerInfoArrived && FormManager.TCPClient.RecievedPacks == null) - { - Task.Delay(250); + public Task WaitForServerData() { + return Task.Run(() => { + while (!FormManager.TCPClient.EnumBackupsArrived && !FormManager.TCPClient.PlayerInfoArrived && FormManager.TCPClient.RecievedPacks == null) { + Task.Delay(250).Wait(); } }); } - public class ServerConnectException : Exception - { + public class ServerConnectException : Exception { public ServerConnectException() { } public ServerConnectException(string message) - : base(message) - { + : base(message) { } public ServerConnectException(string message, Exception inner) - : base(message, inner) - { + : base(message, inner) { } } private void scrollLockChkBox_CheckedChanged(object sender, EventArgs e) => _followTail = scrollLockChkBox.Checked; - private void cmdTextBox_KeyPress(object sender, KeyPressEventArgs e) - { - if (e.KeyChar == (char)Keys.Enter) - { + private void cmdTextBox_KeyPress(object sender, KeyPressEventArgs e) { + if (e.KeyChar == (char)Keys.Enter) { SendCmd_Click(null, null); } } - private void HostListBox_KeyPress(object sender, KeyPressEventArgs e) - { - if (e.KeyChar == (char)Keys.Enter) - { + private void HostListBox_KeyPress(object sender, KeyPressEventArgs e) { + if (e.KeyChar == (char)Keys.Enter) { Connect_Click(null, null); } } - private void BackupManager_Click(object sender, EventArgs e) - { - using (PropEditorForm editDialog = new PropEditorForm()) - { - editDialog.EnableBackupManager(); + private void BackupManager_Click(object sender, EventArgs e) { + using (PropEditorForm editDialog = new PropEditorForm()) { FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Service, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.EnumBackups); DisableUI(); WaitForServerData().Wait(); FormManager.TCPClient.EnumBackupsArrived = false; editDialog.PopulateBoxes(FormManager.TCPClient.BackupList); - if (editDialog.ShowDialog() == DialogResult.OK) - { + editDialog.EnableBackupManager(); + if (editDialog.ShowDialog() == DialogResult.OK) { FormManager.TCPClient.SendData(Encoding.UTF8.GetBytes(editDialog.RollbackFolderName), NetworkMessageSource.Client, NetworkMessageDestination.Service, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.BackupRollback); ServerBusy = true; } + else { + ServerBusy = false; + } editDialog.Close(); } } - private void ManPacks_Click(object sender, EventArgs e) - { + private void ManPacks_Click(object sender, EventArgs e) { FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Server, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.PackList); DisableUI(); WaitForServerData().Wait(); - using (ManagePacksForms form = new ManagePacksForms(connectedHost.GetServerIndex(selectedServer), _logger, _processInfo)) - { + using (ManagePacksForms form = new ManagePacksForms(connectedHost.GetServerIndex(selectedServer), _logger, _processInfo)) { form.PopulateServerPacks(FormManager.TCPClient.RecievedPacks); - if (form.ShowDialog() == DialogResult.OK) - form.Close(); + if (form.ShowDialog() != DialogResult.OK) { + ServerBusy = false; + } + form.Close(); } - FormManager.TCPClient.RecievedPacks = null; } - private void nbtStudioBtn_Click(object sender, EventArgs e) - { + private void nbtStudioBtn_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(_configManager.NBTStudioPath)) - using (OpenFileDialog openFile = new OpenFileDialog()) - { + using (OpenFileDialog openFile = new OpenFileDialog()) { openFile.FileName = "NBTStudio.exe"; openFile.Title = "Please locate NBT Studio executable..."; openFile.Filter = "NBTStudio.exe|NBTStudio.exe"; - if (openFile.ShowDialog() == DialogResult.OK) - { + if (openFile.ShowDialog() == DialogResult.OK) { _configManager.NBTStudioPath = openFile.FileName; _configManager.SaveConfigFile(); } + else return; } ServerBusy = true; FormManager.TCPClient.SendData(NetworkMessageSource.Client, NetworkMessageDestination.Server, connectedHost.GetServerIndex(selectedServer), NetworkMessageTypes.LevelEditRequest); DisableUI(); - using (Process nbtStudioProcess = new Process()) - { + using (Process nbtStudioProcess = new Process()) { string tempPath = $@"{Path.GetTempPath()}level.dat"; nbtStudioProcess.StartInfo = new ProcessStartInfo(_configManager.NBTStudioPath, tempPath); nbtStudioProcess.Start(); @@ -626,25 +556,19 @@ private void nbtStudioBtn_Click(object sender, EventArgs e) ServerBusy = false; } - private void HostListBox_SelectedIndexChanged(object sender, EventArgs e) - { - if(HostListBox.SelectedIndex != -1) - { + private void HostListBox_SelectedIndexChanged(object sender, EventArgs e) { + if (HostListBox.SelectedIndex != -1) { clientSideServiceConfiguration = _configManager.HostConnectList.FirstOrDefault(host => host.GetHostName() == (string)HostListBox.SelectedItem); } } - private void MainWindow_Load(object sender, EventArgs e) - { + private void MainWindow_Load(object sender, EventArgs e) { } - private void clientConfigBtn_Click(object sender, EventArgs e) - { - using (ClientConfigForm form = new ClientConfigForm(_configManager)) - { - if(form.ShowDialog() == DialogResult.OK) - { + private void clientConfigBtn_Click(object sender, EventArgs e) { + using (ClientConfigForm form = new ClientConfigForm(_configManager)) { + if (form.ShowDialog() == DialogResult.OK) { form.Close(); InitForm(); } diff --git a/BedrockService/Client/Forms/MainWindow.resx b/BedrockService/Client/Forms/MainWindow.resx index 26b2a12a..ff8110ee 100644 --- a/BedrockService/Client/Forms/MainWindow.resx +++ b/BedrockService/Client/Forms/MainWindow.resx @@ -1,64 +1,4 @@ - - - + diff --git a/BedrockService/Client/Forms/ManagePacksForms.Designer.cs b/BedrockService/Client/Forms/ManagePacksForms.Designer.cs index 3e09ec3a..db310b6f 100644 --- a/BedrockService/Client/Forms/ManagePacksForms.Designer.cs +++ b/BedrockService/Client/Forms/ManagePacksForms.Designer.cs @@ -46,12 +46,13 @@ private void InitializeComponent() // // serverListBox // - this.serverListBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left))); this.serverListBox.FormattingEnabled = true; - this.serverListBox.Location = new System.Drawing.Point(12, 82); + this.serverListBox.ItemHeight = 15; + this.serverListBox.Location = new System.Drawing.Point(14, 95); + this.serverListBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.serverListBox.Name = "serverListBox"; - this.serverListBox.Size = new System.Drawing.Size(189, 251); + this.serverListBox.SelectionMode = System.Windows.Forms.SelectionMode.MultiSimple; + this.serverListBox.Size = new System.Drawing.Size(220, 289); this.serverListBox.TabIndex = 0; this.serverListBox.Click += new System.EventHandler(this.ListBox_SelectedIndexChanged); // @@ -60,19 +61,22 @@ private void InitializeComponent() this.parsedPacksListBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Right))); this.parsedPacksListBox.FormattingEnabled = true; - this.parsedPacksListBox.Location = new System.Drawing.Point(599, 82); + this.parsedPacksListBox.ItemHeight = 15; + this.parsedPacksListBox.Location = new System.Drawing.Point(690, 95); + this.parsedPacksListBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.parsedPacksListBox.Name = "parsedPacksListBox"; this.parsedPacksListBox.SelectionMode = System.Windows.Forms.SelectionMode.MultiSimple; - this.parsedPacksListBox.Size = new System.Drawing.Size(189, 251); + this.parsedPacksListBox.Size = new System.Drawing.Size(220, 289); this.parsedPacksListBox.TabIndex = 1; this.parsedPacksListBox.Click += new System.EventHandler(this.ListBox_SelectedIndexChanged); // // sendPacksBtn // this.sendPacksBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.sendPacksBtn.Location = new System.Drawing.Point(468, 82); + this.sendPacksBtn.Location = new System.Drawing.Point(537, 95); + this.sendPacksBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.sendPacksBtn.Name = "sendPacksBtn"; - this.sendPacksBtn.Size = new System.Drawing.Size(125, 23); + this.sendPacksBtn.Size = new System.Drawing.Size(146, 27); this.sendPacksBtn.TabIndex = 2; this.sendPacksBtn.Text = "Send selected packs"; this.sendPacksBtn.UseVisualStyleBackColor = true; @@ -81,9 +85,10 @@ private void InitializeComponent() // sendAllBtn // this.sendAllBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.sendAllBtn.Location = new System.Drawing.Point(468, 111); + this.sendAllBtn.Location = new System.Drawing.Point(537, 128); + this.sendAllBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.sendAllBtn.Name = "sendAllBtn"; - this.sendAllBtn.Size = new System.Drawing.Size(125, 23); + this.sendAllBtn.Size = new System.Drawing.Size(146, 27); this.sendAllBtn.TabIndex = 3; this.sendAllBtn.Text = "Send all packs"; this.sendAllBtn.UseVisualStyleBackColor = true; @@ -91,9 +96,10 @@ private void InitializeComponent() // // removePackBtn // - this.removePackBtn.Location = new System.Drawing.Point(207, 82); + this.removePackBtn.Location = new System.Drawing.Point(241, 95); + this.removePackBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.removePackBtn.Name = "removePackBtn"; - this.removePackBtn.Size = new System.Drawing.Size(119, 23); + this.removePackBtn.Size = new System.Drawing.Size(139, 27); this.removePackBtn.TabIndex = 4; this.removePackBtn.Text = "Remove pack"; this.removePackBtn.UseVisualStyleBackColor = true; @@ -101,9 +107,10 @@ private void InitializeComponent() // // removeAllPacksBtn // - this.removeAllPacksBtn.Location = new System.Drawing.Point(207, 111); + this.removeAllPacksBtn.Location = new System.Drawing.Point(241, 128); + this.removeAllPacksBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.removeAllPacksBtn.Name = "removeAllPacksBtn"; - this.removeAllPacksBtn.Size = new System.Drawing.Size(119, 23); + this.removeAllPacksBtn.Size = new System.Drawing.Size(139, 27); this.removeAllPacksBtn.TabIndex = 5; this.removeAllPacksBtn.Text = "Remove all packs"; this.removeAllPacksBtn.UseVisualStyleBackColor = true; @@ -111,21 +118,22 @@ private void InitializeComponent() // // textBox1 // - this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.textBox1.Location = new System.Drawing.Point(288, 211); + this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom))); + this.textBox1.Location = new System.Drawing.Point(332, 243); + this.textBox1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.textBox1.Multiline = true; this.textBox1.Name = "textBox1"; this.textBox1.ReadOnly = true; - this.textBox1.Size = new System.Drawing.Size(219, 122); + this.textBox1.Size = new System.Drawing.Size(255, 140); this.textBox1.TabIndex = 6; // // selectedPackIcon // - this.selectedPackIcon.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.selectedPackIcon.Location = new System.Drawing.Point(332, 75); + this.selectedPackIcon.Anchor = System.Windows.Forms.AnchorStyles.Top; + this.selectedPackIcon.Location = new System.Drawing.Point(383, 87); + this.selectedPackIcon.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.selectedPackIcon.Name = "selectedPackIcon"; - this.selectedPackIcon.Size = new System.Drawing.Size(130, 130); + this.selectedPackIcon.Size = new System.Drawing.Size(152, 150); this.selectedPackIcon.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; this.selectedPackIcon.TabIndex = 7; this.selectedPackIcon.TabStop = false; @@ -133,9 +141,10 @@ private void InitializeComponent() // openFileBtn // this.openFileBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.openFileBtn.Location = new System.Drawing.Point(599, 29); + this.openFileBtn.Location = new System.Drawing.Point(690, 33); + this.openFileBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.openFileBtn.Name = "openFileBtn"; - this.openFileBtn.Size = new System.Drawing.Size(189, 23); + this.openFileBtn.Size = new System.Drawing.Size(220, 27); this.openFileBtn.TabIndex = 8; this.openFileBtn.Text = "Open pack file(s)"; this.openFileBtn.UseVisualStyleBackColor = true; @@ -144,9 +153,10 @@ private void InitializeComponent() // label1 // this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(12, 66); + this.label1.Location = new System.Drawing.Point(14, 76); + this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(153, 13); + this.label1.Size = new System.Drawing.Size(169, 15); this.label1.TabIndex = 9; this.label1.Text = "Current packs found on server:"; // @@ -154,9 +164,10 @@ private void InitializeComponent() // this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(596, 66); + this.label2.Location = new System.Drawing.Point(686, 76); + this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(146, 13); + this.label2.Size = new System.Drawing.Size(161, 15); this.label2.TabIndex = 10; this.label2.Text = "Packs found in archive file(s):"; // @@ -165,18 +176,19 @@ private void InitializeComponent() this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(204, 9); + this.label3.Location = new System.Drawing.Point(238, 10); + this.label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(418, 13); + this.label3.Size = new System.Drawing.Size(454, 15); this.label3.TabIndex = 11; this.label3.Text = "!! NOTICE !! Send map pack alone, do not send all! Not all packs will parse serve" + "r-side!"; // // ManagePacksForms // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(800, 450); + this.ClientSize = new System.Drawing.Size(924, 405); this.Controls.Add(this.label3); this.Controls.Add(this.label2); this.Controls.Add(this.label1); @@ -189,8 +201,11 @@ private void InitializeComponent() this.Controls.Add(this.sendPacksBtn); this.Controls.Add(this.parsedPacksListBox); this.Controls.Add(this.serverListBox); + this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.MinimumSize = new System.Drawing.Size(940, 444); this.Name = "ManagePacksForms"; - this.Text = "Form1"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Pack Manager"; ((System.ComponentModel.ISupportInitialize)(this.selectedPackIcon)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); diff --git a/BedrockService/Client/Forms/ManagePacksForms.cs b/BedrockService/Client/Forms/ManagePacksForms.cs index 29fbfe9f..001829c6 100644 --- a/BedrockService/Client/Forms/ManagePacksForms.cs +++ b/BedrockService/Client/Forms/ManagePacksForms.cs @@ -11,16 +11,13 @@ using System.Text; using System.Windows.Forms; -namespace BedrockService.Client.Forms -{ - public partial class ManagePacksForms : Form - { +namespace BedrockService.Client.Forms { + public partial class ManagePacksForms : Form { private readonly byte ServerIndex = 0x00; - private readonly ILogger Logger; + private readonly IBedrockLogger Logger; private readonly IProcessInfo ProcessInfo; private readonly DirectoryInfo PackExtractDir; - public ManagePacksForms(byte serverIndex, ILogger logger, IProcessInfo processInfo) - { + public ManagePacksForms(byte serverIndex, IBedrockLogger logger, IProcessInfo processInfo) { Logger = logger; PackExtractDir = new DirectoryInfo($@"{processInfo.GetDirectory()}\Temp"); ProcessInfo = processInfo; @@ -28,108 +25,97 @@ public ManagePacksForms(byte serverIndex, ILogger logger, IProcessInfo processIn InitializeComponent(); } - public void PopulateServerPacks(List packList) - { - foreach (MinecraftPackParser pack in packList) - foreach (MinecraftPackContainer container in pack.FoundPacks) - serverListBox.Items.Add(container); + public void PopulateServerPacks(List packList) { + foreach (MinecraftPackContainer container in packList) + serverListBox.Items.Add(container); + FormManager.TCPClient.RecievedPacks = null; } - private void ListBox_SelectedIndexChanged(object sender, EventArgs e) - { + private void ListBox_SelectedIndexChanged(object sender, EventArgs e) { ListBox thisBox = (ListBox)sender; if (thisBox == serverListBox) parsedPacksListBox.SelectedIndex = -1; if (thisBox == parsedPacksListBox) serverListBox.SelectedIndex = -1; - if (thisBox.SelectedIndex != -1) - { + if (thisBox.SelectedIndex != -1) { MinecraftPackContainer selectedPack = (MinecraftPackContainer)thisBox.SelectedItem; if (selectedPack.IconBytes != null) - using (MemoryStream ms = new MemoryStream(selectedPack.IconBytes)) - { + using (MemoryStream ms = new MemoryStream(selectedPack.IconBytes)) { selectedPackIcon.Image = Image.FromStream(ms); } if (selectedPack.JsonManifest != null) textBox1.Text = $"{selectedPack.JsonManifest.header.name}\r\n{selectedPack.JsonManifest.header.description}\r\n{selectedPack.JsonManifest.header.uuid}\r\n{selectedPack.JsonManifest.header.version[0]}"; else - textBox1.Text = selectedPack.PackContentLocation.Name; + textBox1.Text = new DirectoryInfo(selectedPack.PackContentLocation).Name; } } - private void removePackBtn_Click(object sender, EventArgs e) - { - if (serverListBox.SelectedIndex != -1) - { + private void removePackBtn_Click(object sender, EventArgs e) { + if (serverListBox.SelectedIndex != -1) { List temp = new List(); - temp.Add((MinecraftPackContainer)serverListBox.SelectedItem); - JsonSerializerSettings settings = new JsonSerializerSettings() - { + object[] items = new object[serverListBox.SelectedItems.Count]; + serverListBox.SelectedItems.CopyTo(items, 0); + foreach (object item in items) { + temp.Add((MinecraftPackContainer)item); + serverListBox.Items.Remove(item); + } + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; FormManager.TCPClient.SendData(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(temp, Formatting.Indented, settings)), NetworkMessageSource.Client, NetworkMessageDestination.Server, ServerIndex, NetworkMessageTypes.RemovePack); - serverListBox.Items.Remove(temp[0]); } - + DialogResult = DialogResult.OK; } - private void removeAllPacksBtn_Click(object sender, EventArgs e) - { + private void removeAllPacksBtn_Click(object sender, EventArgs e) { List temp = new List(); foreach (object item in serverListBox.Items) temp.Add((MinecraftPackContainer)item); - JsonSerializerSettings settings = new JsonSerializerSettings() - { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; FormManager.TCPClient.SendData(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(temp, Formatting.Indented, settings)), NetworkMessageSource.Client, NetworkMessageDestination.Server, ServerIndex, NetworkMessageTypes.RemovePack); - serverListBox.Items.Clear(); + DialogResult = DialogResult.OK; } - private void sendPacksBtn_Click(object sender, EventArgs e) - { - if (parsedPacksListBox.SelectedIndex != -1) - { + private void sendPacksBtn_Click(object sender, EventArgs e) { + if (parsedPacksListBox.SelectedIndex != -1) { object[] items = new object[parsedPacksListBox.SelectedItems.Count]; parsedPacksListBox.SelectedItems.CopyTo(items, 0); SendPacks(items); } } - private void sendAllBtn_Click(object sender, EventArgs e) - { + private void sendAllBtn_Click(object sender, EventArgs e) { object[] items = new object[parsedPacksListBox.Items.Count]; parsedPacksListBox.Items.CopyTo(items, 0); SendPacks(items); } - private void openFileBtn_Click(object sender, EventArgs e) - { + private void openFileBtn_Click(object sender, EventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); openFileDialog.Filter = "MC pack file (.MCWORLD, .MCPACK, .MCADDON, .Zip)|*.mcworld;*.mcpack;*.mcaddon;*.zip"; openFileDialog.Title = "Select pack file(s)"; openFileDialog.Multiselect = true; - if (openFileDialog.ShowDialog() == DialogResult.OK) - { - MinecraftPackParser parser = new MinecraftPackParser(openFileDialog.FileNames, PackExtractDir, Logger, ProcessInfo); + if (openFileDialog.ShowDialog() == DialogResult.OK) { + MinecraftPackParser parser = new MinecraftPackParser(openFileDialog.FileNames, PackExtractDir.FullName, Logger, ProcessInfo); parsedPacksListBox.Items.Clear(); foreach (MinecraftPackContainer container in parser.FoundPacks) parsedPacksListBox.Items.Add(container); } } - private void SendPacks(object[] packList) - { - foreach (MinecraftPackContainer container in packList) - { + private void SendPacks(object[] packList) { + foreach (MinecraftPackContainer container in packList) { Directory.CreateDirectory($@"{PackExtractDir.FullName}\ZipTemp"); - container.PackContentLocation.MoveTo($@"{PackExtractDir.FullName}\ZipTemp\{container.PackContentLocation.Name}"); - container.PackContentLocation = new DirectoryInfo($@"{PackExtractDir.FullName}\ZipTemp\{container.PackContentLocation.Name}"); + DirectoryInfo directoryInfo = new DirectoryInfo(container.PackContentLocation); + directoryInfo.MoveTo($@"{PackExtractDir.FullName}\ZipTemp\{directoryInfo.Name}"); + container.PackContentLocation = $@"{PackExtractDir.FullName}\ZipTemp\{directoryInfo.Name}"; } ZipFile.CreateFromDirectory($@"{PackExtractDir.FullName}\ZipTemp", $@"{PackExtractDir.FullName}\SendZip.zip"); FormManager.TCPClient.SendData(File.ReadAllBytes($@"{PackExtractDir.FullName}\SendZip.zip"), NetworkMessageSource.Client, NetworkMessageDestination.Server, ServerIndex, NetworkMessageTypes.PackFile); - parsedPacksListBox.Items.Clear(); + DialogResult = DialogResult.OK; } } } diff --git a/BedrockService/Client/Forms/ManagePacksForms.resx b/BedrockService/Client/Forms/ManagePacksForms.resx index 1af7de15..f298a7be 100644 --- a/BedrockService/Client/Forms/ManagePacksForms.resx +++ b/BedrockService/Client/Forms/ManagePacksForms.resx @@ -1,64 +1,4 @@ - - - + diff --git a/BedrockService/Client/Forms/NewPlayerRegistrationForm.Designer.cs b/BedrockService/Client/Forms/NewPlayerRegistrationForm.Designer.cs index 66d091df..1f27ef77 100644 --- a/BedrockService/Client/Forms/NewPlayerRegistrationForm.Designer.cs +++ b/BedrockService/Client/Forms/NewPlayerRegistrationForm.Designer.cs @@ -45,50 +45,56 @@ private void InitializeComponent() // label2 // this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(70, 33); + this.label2.Location = new System.Drawing.Point(82, 38); + this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(36, 13); + this.label2.Size = new System.Drawing.Size(36, 15); this.label2.TabIndex = 1; this.label2.Text = "XUID:"; // // xuidTextBox // - this.xuidTextBox.Location = new System.Drawing.Point(111, 30); + this.xuidTextBox.Location = new System.Drawing.Point(130, 35); + this.xuidTextBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.xuidTextBox.Name = "xuidTextBox"; - this.xuidTextBox.Size = new System.Drawing.Size(185, 20); + this.xuidTextBox.Size = new System.Drawing.Size(215, 23); this.xuidTextBox.TabIndex = 2; // // usernameTextBox // - this.usernameTextBox.Location = new System.Drawing.Point(111, 56); + this.usernameTextBox.Location = new System.Drawing.Point(130, 65); + this.usernameTextBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.usernameTextBox.Name = "usernameTextBox"; - this.usernameTextBox.Size = new System.Drawing.Size(185, 20); + this.usernameTextBox.Size = new System.Drawing.Size(215, 23); this.usernameTextBox.TabIndex = 4; // // label3 // this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(48, 59); + this.label3.Location = new System.Drawing.Point(56, 68); + this.label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(58, 13); + this.label3.Size = new System.Drawing.Size(63, 15); this.label3.TabIndex = 3; this.label3.Text = "Username:"; // // label4 // this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(46, 85); + this.label4.Location = new System.Drawing.Point(54, 98); + this.label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(60, 13); + this.label4.Size = new System.Drawing.Size(68, 15); this.label4.TabIndex = 5; this.label4.Text = "Permission:"; // // label5 // this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(40, 109); + this.label5.Location = new System.Drawing.Point(47, 126); + this.label5.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(65, 13); + this.label5.Size = new System.Drawing.Size(71, 15); this.label5.TabIndex = 6; this.label5.Text = "Whitelisted?"; // @@ -99,15 +105,17 @@ private void InitializeComponent() "visitor", "member", "operator"}); - this.permissionComboBox.Location = new System.Drawing.Point(111, 82); + this.permissionComboBox.Location = new System.Drawing.Point(130, 95); + this.permissionComboBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.permissionComboBox.Name = "permissionComboBox"; - this.permissionComboBox.Size = new System.Drawing.Size(185, 21); + this.permissionComboBox.Size = new System.Drawing.Size(215, 23); this.permissionComboBox.TabIndex = 7; // // whitelistedChkBox // this.whitelistedChkBox.AutoSize = true; - this.whitelistedChkBox.Location = new System.Drawing.Point(111, 109); + this.whitelistedChkBox.Location = new System.Drawing.Point(130, 126); + this.whitelistedChkBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.whitelistedChkBox.Name = "whitelistedChkBox"; this.whitelistedChkBox.Size = new System.Drawing.Size(15, 14); this.whitelistedChkBox.TabIndex = 8; @@ -116,7 +124,8 @@ private void InitializeComponent() // ignoreLimitChkBox // this.ignoreLimitChkBox.AutoSize = true; - this.ignoreLimitChkBox.Location = new System.Drawing.Point(111, 132); + this.ignoreLimitChkBox.Location = new System.Drawing.Point(130, 152); + this.ignoreLimitChkBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.ignoreLimitChkBox.Name = "ignoreLimitChkBox"; this.ignoreLimitChkBox.Size = new System.Drawing.Size(15, 14); this.ignoreLimitChkBox.TabIndex = 9; @@ -125,17 +134,19 @@ private void InitializeComponent() // label6 // this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(5, 132); + this.label6.Location = new System.Drawing.Point(6, 152); + this.label6.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(101, 13); + this.label6.Size = new System.Drawing.Size(112, 15); this.label6.TabIndex = 10; this.label6.Text = "Ignore max players?"; // // button1 // - this.button1.Location = new System.Drawing.Point(221, 123); + this.button1.Location = new System.Drawing.Point(258, 142); + this.button1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(75, 25); + this.button1.Size = new System.Drawing.Size(88, 29); this.button1.TabIndex = 11; this.button1.Text = "Save"; this.button1.UseVisualStyleBackColor = true; @@ -143,9 +154,9 @@ private void InitializeComponent() // // NewPlayerRegistrationForm // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(323, 171); + this.ClientSize = new System.Drawing.Size(359, 191); this.Controls.Add(this.button1); this.Controls.Add(this.label6); this.Controls.Add(this.ignoreLimitChkBox); @@ -157,9 +168,13 @@ private void InitializeComponent() this.Controls.Add(this.label3); this.Controls.Add(this.xuidTextBox); this.Controls.Add(this.label2); + this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.MaximizeBox = false; + this.MaximumSize = new System.Drawing.Size(375, 230); this.MinimizeBox = false; + this.MinimumSize = new System.Drawing.Size(375, 230); this.Name = "NewPlayerRegistrationForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "New Player Registration Form"; this.ResumeLayout(false); this.PerformLayout(); diff --git a/BedrockService/Client/Forms/NewPlayerRegistrationForm.cs b/BedrockService/Client/Forms/NewPlayerRegistrationForm.cs index 2de19efc..b63c8607 100644 --- a/BedrockService/Client/Forms/NewPlayerRegistrationForm.cs +++ b/BedrockService/Client/Forms/NewPlayerRegistrationForm.cs @@ -3,23 +3,17 @@ using System; using System.Windows.Forms; -namespace BedrockService.Client.Forms -{ - public partial class NewPlayerRegistrationForm : Form - { +namespace BedrockService.Client.Forms { + public partial class NewPlayerRegistrationForm : Form { public IPlayer PlayerToAdd; - public NewPlayerRegistrationForm() - { + public NewPlayerRegistrationForm() { InitializeComponent(); } - private void saveClick(object sender, EventArgs e) - { - if (usernameTextBox.TextLength > 0 && xuidTextBox.TextLength == 16) - { + private void saveClick(object sender, EventArgs e) { + if (usernameTextBox.TextLength > 0 && xuidTextBox.TextLength == 16) { PlayerToAdd = new Player(xuidTextBox.Text, usernameTextBox.Text, DateTime.Now.Ticks.ToString(), "0", "0", whitelistedChkBox.Checked, permissionComboBox.SelectedItem.ToString(), ignoreLimitChkBox.Checked); DialogResult = DialogResult.OK; - Close(); } } } diff --git a/BedrockService/Client/Forms/NewPlayerRegistrationForm.resx b/BedrockService/Client/Forms/NewPlayerRegistrationForm.resx index 1af7de15..f298a7be 100644 --- a/BedrockService/Client/Forms/NewPlayerRegistrationForm.resx +++ b/BedrockService/Client/Forms/NewPlayerRegistrationForm.resx @@ -1,64 +1,4 @@ - - - + diff --git a/BedrockService/Client/Forms/PlayerManagerForm.Designer.cs b/BedrockService/Client/Forms/PlayerManagerForm.Designer.cs index d548d659..2d2b0d5f 100644 --- a/BedrockService/Client/Forms/PlayerManagerForm.Designer.cs +++ b/BedrockService/Client/Forms/PlayerManagerForm.Designer.cs @@ -29,9 +29,9 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle7 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle8 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle9 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle(); this.searchEntryBox = new System.Windows.Forms.TextBox(); this.saveBtn = new System.Windows.Forms.Button(); this.label2 = new System.Windows.Forms.Label(); @@ -44,20 +44,22 @@ private void InitializeComponent() // this.searchEntryBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.searchEntryBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.searchEntryBox.Location = new System.Drawing.Point(177, 390); + this.searchEntryBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.searchEntryBox.Location = new System.Drawing.Point(206, 349); + this.searchEntryBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.searchEntryBox.Name = "searchEntryBox"; - this.searchEntryBox.Size = new System.Drawing.Size(729, 26); + this.searchEntryBox.Size = new System.Drawing.Size(629, 26); this.searchEntryBox.TabIndex = 4; this.searchEntryBox.TextChanged += new System.EventHandler(this.searchEntryBox_TextChanged); // // saveBtn // this.saveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.saveBtn.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.saveBtn.Location = new System.Drawing.Point(912, 390); + this.saveBtn.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.saveBtn.Location = new System.Drawing.Point(843, 349); + this.saveBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.saveBtn.Name = "saveBtn"; - this.saveBtn.Size = new System.Drawing.Size(87, 26); + this.saveBtn.Size = new System.Drawing.Size(102, 30); this.saveBtn.TabIndex = 5; this.saveBtn.Text = "Save"; this.saveBtn.UseVisualStyleBackColor = true; @@ -67,8 +69,9 @@ private void InitializeComponent() // this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.label2.AutoSize = true; - this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label2.Location = new System.Drawing.Point(127, 393); + this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.label2.Location = new System.Drawing.Point(148, 352); + this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(44, 20); this.label2.TabIndex = 6; @@ -81,44 +84,47 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Right))); this.gridView.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.AllCells; this.gridView.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.AllCells; - dataGridViewCellStyle7.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; - dataGridViewCellStyle7.BackColor = System.Drawing.SystemColors.Control; - dataGridViewCellStyle7.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - dataGridViewCellStyle7.ForeColor = System.Drawing.SystemColors.WindowText; - dataGridViewCellStyle7.SelectionBackColor = System.Drawing.SystemColors.Highlight; - dataGridViewCellStyle7.SelectionForeColor = System.Drawing.SystemColors.HighlightText; - dataGridViewCellStyle7.WrapMode = System.Windows.Forms.DataGridViewTriState.True; - this.gridView.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle7; + dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.gridView.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1; this.gridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - dataGridViewCellStyle8.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; - dataGridViewCellStyle8.BackColor = System.Drawing.SystemColors.Window; - dataGridViewCellStyle8.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - dataGridViewCellStyle8.ForeColor = System.Drawing.SystemColors.ControlText; - dataGridViewCellStyle8.SelectionBackColor = System.Drawing.SystemColors.Highlight; - dataGridViewCellStyle8.SelectionForeColor = System.Drawing.SystemColors.HighlightText; - dataGridViewCellStyle8.WrapMode = System.Windows.Forms.DataGridViewTriState.False; - this.gridView.DefaultCellStyle = dataGridViewCellStyle8; - this.gridView.Location = new System.Drawing.Point(16, 27); + dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.gridView.DefaultCellStyle = dataGridViewCellStyle2; + this.gridView.Location = new System.Drawing.Point(19, 31); + this.gridView.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.gridView.Name = "gridView"; - dataGridViewCellStyle9.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; - dataGridViewCellStyle9.BackColor = System.Drawing.SystemColors.Control; - dataGridViewCellStyle9.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - dataGridViewCellStyle9.ForeColor = System.Drawing.SystemColors.WindowText; - dataGridViewCellStyle9.SelectionBackColor = System.Drawing.SystemColors.Highlight; - dataGridViewCellStyle9.SelectionForeColor = System.Drawing.SystemColors.HighlightText; - dataGridViewCellStyle9.WrapMode = System.Windows.Forms.DataGridViewTriState.True; - this.gridView.RowHeadersDefaultCellStyle = dataGridViewCellStyle9; - this.gridView.Size = new System.Drawing.Size(983, 338); + dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Control; + dataGridViewCellStyle3.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + dataGridViewCellStyle3.ForeColor = System.Drawing.SystemColors.WindowText; + dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.gridView.RowHeadersDefaultCellStyle = dataGridViewCellStyle3; + this.gridView.Size = new System.Drawing.Size(926, 289); this.gridView.TabIndex = 3; this.gridView.CellBeginEdit += new System.Windows.Forms.DataGridViewCellCancelEventHandler(this.gridView_CellBeginEdit); this.gridView.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.gridView_CellEndEdit); // // registerPlayerBtn // - this.registerPlayerBtn.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.registerPlayerBtn.Location = new System.Drawing.Point(16, 390); + this.registerPlayerBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.registerPlayerBtn.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.registerPlayerBtn.Location = new System.Drawing.Point(19, 348); + this.registerPlayerBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.registerPlayerBtn.Name = "registerPlayerBtn"; - this.registerPlayerBtn.Size = new System.Drawing.Size(105, 26); + this.registerPlayerBtn.Size = new System.Drawing.Size(122, 30); this.registerPlayerBtn.TabIndex = 7; this.registerPlayerBtn.Text = "Register new..."; this.registerPlayerBtn.UseVisualStyleBackColor = true; @@ -126,16 +132,18 @@ private void InitializeComponent() // // PlayerManagerForm // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1016, 435); + this.ClientSize = new System.Drawing.Size(964, 401); this.Controls.Add(this.registerPlayerBtn); this.Controls.Add(this.gridView); this.Controls.Add(this.label2); this.Controls.Add(this.saveBtn); this.Controls.Add(this.searchEntryBox); this.Margin = new System.Windows.Forms.Padding(2); + this.MinimumSize = new System.Drawing.Size(980, 440); this.Name = "PlayerManagerForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Player Manager"; ((System.ComponentModel.ISupportInitialize)(this.gridView)).EndInit(); this.ResumeLayout(false); diff --git a/BedrockService/Client/Forms/PlayerManagerForm.cs b/BedrockService/Client/Forms/PlayerManagerForm.cs index ea819e69..02c10459 100644 --- a/BedrockService/Client/Forms/PlayerManagerForm.cs +++ b/BedrockService/Client/Forms/PlayerManagerForm.cs @@ -7,26 +7,22 @@ using System.Text; using System.Windows.Forms; -namespace BedrockService.Client.Forms -{ - public partial class PlayerManagerForm : Form - { +namespace BedrockService.Client.Forms { + public partial class PlayerManagerForm : Form { private readonly IServerConfiguration _server; private readonly string[] RegisteredPlayerColumnArray = new string[8] { "XUID:", "Username:", "Permission:", "Whitelisted:", "Ignores max players:", "First connected on:", "Last connected on:", "Time spent in game:" }; private List playersFound = new List(); private readonly List modifiedPlayers = new List(); private IPlayer playerToEdit; - public PlayerManagerForm(IServerConfiguration server) - { + public PlayerManagerForm(IServerConfiguration server) { InitializeComponent(); _server = server; playersFound = _server.GetPlayerList(); gridView.Columns.Clear(); gridView.Rows.Clear(); - foreach (string s in RegisteredPlayerColumnArray) - { + foreach (string s in RegisteredPlayerColumnArray) { gridView.Columns.Add(s.Replace(" ", "").Replace(":", ""), s); } gridView.Columns[5].ReadOnly = true; @@ -39,48 +35,36 @@ public PlayerManagerForm(IServerConfiguration server) RefreshGridContents(); } - private void RefreshGridContents() - { + private void RefreshGridContents() { gridView.Rows.Clear(); - foreach (IPlayer player in playersFound) - { - string[] playerReg = player.GetRegistration(); - string[] playerTimes = player.GetTimes(); - string playerFirstConnect = playerTimes[0]; - string playerConnectTime = playerTimes[1]; - string playerDisconnectTime = playerTimes[2]; - string playerWhitelist = playerReg[0]; + foreach (IPlayer player in playersFound) { + var playerTimes = player.GetTimes(); string playerPermission = player.GetPermissionLevel(); - string playerIgnoreLimit = playerReg[2]; - TimeSpan timeSpent = TimeSpan.FromTicks(long.Parse(playerConnectTime) - long.Parse(playerDisconnectTime)); - string[] list = new string[] { player.GetXUID(), player.GetUsername(), playerPermission, playerWhitelist, playerIgnoreLimit, playerFirstConnect, playerConnectTime, timeSpent.ToString("hhmmss") }; + TimeSpan timeSpent = TimeSpan.FromTicks(long.Parse(playerTimes.Conn) - long.Parse(playerTimes.Disconn)); + string[] list = new string[] { player.GetXUID(), player.GetUsername(), playerPermission, player.IsPlayerWhitelisted().ToString(), player.PlayerIgnoresLimit().ToString(), playerTimes.First, playerTimes.Conn, timeSpent.ToString("hhmmss") }; gridView.Rows.Add(list); } gridView.Refresh(); } - private void saveBtn_Click(object sender, EventArgs e) - { - if (modifiedPlayers.Count > 0) - { - foreach (IPlayer player in modifiedPlayers) - { + private void saveBtn_Click(object sender, EventArgs e) { + if (modifiedPlayers.Count > 0) { + foreach (IPlayer player in modifiedPlayers) { _server.AddUpdatePlayer(player); } } - JsonSerializerSettings settings = new JsonSerializerSettings() - { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; byte[] sendBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(modifiedPlayers, Formatting.Indented, settings)); FormManager.TCPClient.SendData(sendBytes, NetworkMessageSource.Client, NetworkMessageDestination.Server, FormManager.MainWindow.connectedHost.GetServerIndex(_server), NetworkMessageTypes.PlayersUpdate); FormManager.MainWindow.DisableUI(); + DialogResult = DialogResult.OK; Close(); Dispose(); } - private void searchEntryBox_TextChanged(object sender, EventArgs e) - { + private void searchEntryBox_TextChanged(object sender, EventArgs e) { playersFound = _server.GetPlayerList(); string curText = searchEntryBox.Text; List tempList = new List(); @@ -88,23 +72,17 @@ private void searchEntryBox_TextChanged(object sender, EventArgs e) string cmd; string value; - if (curText.Contains(":")) - { + if (curText.Contains(":")) { splitCommands = curText.Split(','); - if (splitCommands.Length > 1) - { - foreach (string s in splitCommands) - { - if (s.Contains(":")) - { + if (splitCommands.Length > 1) { + foreach (string s in splitCommands) { + if (s.Contains(":")) { string[] finalSplit = s.Split(':'); cmd = finalSplit[0]; value = finalSplit[1]; tempList = new List(); - foreach (IPlayer player in playersFound) - { - if (player.SearchForProperty(cmd).Contains(value)) - { + foreach (IPlayer player in playersFound) { + if (player.SearchForProperty(cmd).Contains(value)) { tempList.Add(player); } } @@ -116,10 +94,8 @@ private void searchEntryBox_TextChanged(object sender, EventArgs e) splitCommands = curText.Split(':'); cmd = splitCommands[0]; value = splitCommands[1]; - foreach (IPlayer player in playersFound) - { - if (player.SearchForProperty(cmd).Contains(value)) - { + foreach (IPlayer player in playersFound) { + if (player.SearchForProperty(cmd).Contains(value)) { tempList.Add(player); } } @@ -129,39 +105,33 @@ private void searchEntryBox_TextChanged(object sender, EventArgs e) } } - private void gridView_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) - { + private void gridView_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) { DataGridViewRow focusedRow = gridView.Rows[e.RowIndex]; playerToEdit = _server.GetPlayerByXuid((string)focusedRow.Cells[0].Value); } - private void gridView_CellEndEdit(object sender, DataGridViewCellEventArgs e) - { + private void gridView_CellEndEdit(object sender, DataGridViewCellEventArgs e) { DataGridViewRow focusedRow = gridView.Rows[e.RowIndex]; - string[] playerReg = playerToEdit.GetRegistration(); - string[] playerTimes = playerToEdit.GetTimes(); - string playerFirstConnect = playerTimes[0]; - string playerConnectTime = playerTimes[1]; - string playerDisconnectTime = playerTimes[2]; - string playerWhitelist = playerReg[0]; - string playerPermission = playerReg[1]; - string playerIgnoreLimit = playerReg[2]; - if ((string)focusedRow.Cells[0].Value != playerToEdit.GetXUID() || (string)focusedRow.Cells[1].Value != playerToEdit.GetUsername() || (string)focusedRow.Cells[2].Value != playerPermission || (string)focusedRow.Cells[3].Value != playerWhitelist || (string)focusedRow.Cells[4].Value != playerIgnoreLimit) - { + var playerTimes = playerToEdit.GetTimes(); + string playerFirstConnect = playerTimes.First; + string playerConnectTime = playerTimes.Conn; + string playerDisconnectTime = playerTimes.Disconn; + string playerWhitelist = playerToEdit.IsPlayerWhitelisted().ToString(); + string playerPermission = playerToEdit.GetPermissionLevel(); + string playerIgnoreLimit = playerToEdit.PlayerIgnoresLimit().ToString(); + if ((string)focusedRow.Cells[0].Value != playerToEdit.GetXUID() || (string)focusedRow.Cells[1].Value != playerToEdit.GetUsername() || (string)focusedRow.Cells[2].Value != playerPermission || (string)focusedRow.Cells[3].Value != playerWhitelist || (string)focusedRow.Cells[4].Value != playerIgnoreLimit) { playerToEdit = new Player((string)focusedRow.Cells[0].Value, (string)focusedRow.Cells[1].Value, playerFirstConnect, playerConnectTime, playerDisconnectTime, bool.Parse((string)focusedRow.Cells[3].Value), (string)focusedRow.Cells[2].Value, bool.Parse((string)focusedRow.Cells[4].Value)); modifiedPlayers.Add(playerToEdit); } } - private void registerPlayerBtn_Click(object sender, EventArgs e) - { - using (NewPlayerRegistrationForm form = new NewPlayerRegistrationForm()) - { - if (form.ShowDialog() == DialogResult.OK) - { + private void registerPlayerBtn_Click(object sender, EventArgs e) { + using (NewPlayerRegistrationForm form = new NewPlayerRegistrationForm()) { + if (form.ShowDialog() == DialogResult.OK) { _server.GetPlayerList().Add(form.PlayerToAdd); modifiedPlayers.Add(form.PlayerToAdd); RefreshGridContents(); + form.Close(); } } } diff --git a/BedrockService/Client/Forms/PlayerManagerForm.resx b/BedrockService/Client/Forms/PlayerManagerForm.resx index 1af7de15..f298a7be 100644 --- a/BedrockService/Client/Forms/PlayerManagerForm.resx +++ b/BedrockService/Client/Forms/PlayerManagerForm.resx @@ -1,64 +1,4 @@ - - - + diff --git a/BedrockService/Client/Forms/PropEditorForm.Designer.cs b/BedrockService/Client/Forms/PropEditorForm.Designer.cs index c27c8bd2..45aac6b8 100644 --- a/BedrockService/Client/Forms/PropEditorForm.Designer.cs +++ b/BedrockService/Client/Forms/PropEditorForm.Designer.cs @@ -40,10 +40,11 @@ private void InitializeComponent() // // CancelBtn // - this.CancelBtn.Anchor = System.Windows.Forms.AnchorStyles.Bottom; - this.CancelBtn.Location = new System.Drawing.Point(13, 362); + this.CancelBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.CancelBtn.Location = new System.Drawing.Point(13, 322); + this.CancelBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.CancelBtn.Name = "CancelBtn"; - this.CancelBtn.Size = new System.Drawing.Size(200, 23); + this.CancelBtn.Size = new System.Drawing.Size(170, 30); this.CancelBtn.TabIndex = 48; this.CancelBtn.Text = "Cancel"; this.CancelBtn.UseVisualStyleBackColor = true; @@ -51,10 +52,11 @@ private void InitializeComponent() // // SaveBtn // - this.SaveBtn.Anchor = System.Windows.Forms.AnchorStyles.Bottom; - this.SaveBtn.Location = new System.Drawing.Point(588, 362); + this.SaveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.SaveBtn.Location = new System.Drawing.Point(531, 322); + this.SaveBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.SaveBtn.Name = "SaveBtn"; - this.SaveBtn.Size = new System.Drawing.Size(200, 23); + this.SaveBtn.Size = new System.Drawing.Size(170, 30); this.SaveBtn.TabIndex = 49; this.SaveBtn.Text = "Save"; this.SaveBtn.UseVisualStyleBackColor = true; @@ -70,10 +72,12 @@ private void InitializeComponent() this.gridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { this.EntryKey, this.EntryData}); - this.gridView.Location = new System.Drawing.Point(13, 13); + this.gridView.Location = new System.Drawing.Point(13, 15); + this.gridView.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.gridView.MultiSelect = false; this.gridView.Name = "gridView"; - this.gridView.Size = new System.Drawing.Size(775, 343); + this.gridView.RowHeadersWidth = 62; + this.gridView.Size = new System.Drawing.Size(686, 301); this.gridView.TabIndex = 1; this.gridView.NewRowNeeded += new System.Windows.Forms.DataGridViewRowEventHandler(this.gridView_NewRowNeeded); // @@ -88,32 +92,38 @@ private void InitializeComponent() // EntryData // this.EntryData.HeaderText = "Value:"; + this.EntryData.MinimumWidth = 8; this.EntryData.Name = "EntryData"; - this.EntryData.Width = 600; + this.EntryData.Width = 300; // // DelBackupBtn // - this.DelBackupBtn.Anchor = System.Windows.Forms.AnchorStyles.Bottom; + this.DelBackupBtn.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.DelBackupBtn.Enabled = false; - this.DelBackupBtn.Location = new System.Drawing.Point(301, 362); + this.DelBackupBtn.Location = new System.Drawing.Point(271, 322); + this.DelBackupBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.DelBackupBtn.Name = "DelBackupBtn"; - this.DelBackupBtn.Size = new System.Drawing.Size(200, 23); + this.DelBackupBtn.Size = new System.Drawing.Size(170, 30); this.DelBackupBtn.TabIndex = 50; this.DelBackupBtn.Text = "Delete Backup"; this.DelBackupBtn.UseVisualStyleBackColor = true; this.DelBackupBtn.Visible = false; this.DelBackupBtn.Click += new System.EventHandler(this.DelBackupBtn_Click); // - // EditSrv + // PropEditorForm // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(800, 397); + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.ClientSize = new System.Drawing.Size(714, 361); this.Controls.Add(this.DelBackupBtn); this.Controls.Add(this.gridView); this.Controls.Add(this.SaveBtn); this.Controls.Add(this.CancelBtn); - this.Name = "EditSrv"; + this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.MinimumSize = new System.Drawing.Size(730, 400); + this.Name = "PropEditorForm"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Form1"; ((System.ComponentModel.ISupportInitialize)(this.gridView)).EndInit(); @@ -125,8 +135,8 @@ private void InitializeComponent() private System.Windows.Forms.Button CancelBtn; private System.Windows.Forms.Button SaveBtn; private System.Windows.Forms.DataGridView gridView; + private System.Windows.Forms.Button DelBackupBtn; private System.Windows.Forms.DataGridViewTextBoxColumn EntryKey; private System.Windows.Forms.DataGridViewTextBoxColumn EntryData; - private System.Windows.Forms.Button DelBackupBtn; } } \ No newline at end of file diff --git a/BedrockService/Client/Forms/PropEditorForm.cs b/BedrockService/Client/Forms/PropEditorForm.cs index 2fc849e8..c0c09b45 100644 --- a/BedrockService/Client/Forms/PropEditorForm.cs +++ b/BedrockService/Client/Forms/PropEditorForm.cs @@ -6,30 +6,25 @@ using System.Text; using System.Windows.Forms; -namespace BedrockService.Client.Forms -{ - public partial class PropEditorForm : Form - { +namespace BedrockService.Client.Forms { + public partial class PropEditorForm : Form { readonly DataGridView dataGrid; public List workingProps; public List startCmds; public string RollbackFolderName = ""; - public PropEditorForm() - { + public PropEditorForm() { InitializeComponent(); dataGrid = gridView; } - public void PopulateBoxes(List propList) - { + public void PopulateBoxes(List propList) { int index = 0; workingProps = propList; - foreach (Property prop in workingProps) - { + this.Text = "Properties Editor"; + foreach (Property prop in workingProps) { dataGrid.Rows.Add(new string[2] { prop.KeyName, prop.Value }); - if (prop.KeyName == "server-name" || prop.KeyName == "server-port" || prop.KeyName == "server-portv6") - { + if (prop.KeyName == "server-name" || prop.KeyName == "server-port" || prop.KeyName == "server-portv6") { dataGrid.Rows[index].ReadOnly = true; dataGrid.Rows[index].DefaultCellStyle.BackColor = System.Drawing.Color.FromArgb(225, 225, 225); } @@ -38,38 +33,33 @@ public void PopulateBoxes(List propList) gridView.AllowUserToAddRows = false; } - public void PopulateStartCmds(List list) - { + public void PopulateStartCmds(List list) { + this.Text = "Start Command Editor"; startCmds = list; gridView.Columns.RemoveAt(0); - foreach (StartCmdEntry entry in startCmds) - { + gridView.AllowUserToDeleteRows = true; + foreach (StartCmdEntry entry in startCmds) { dataGrid.Rows.Add(new string[1] { entry.Command }); } } - public void EnableBackupManager() - { + public void EnableBackupManager() { + this.Text = "Backup Manager"; gridView.MultiSelect = true; DelBackupBtn.Enabled = true; DelBackupBtn.Visible = true; SaveBtn.Text = "Rollback this date"; } - private void CancelBtn_Click(object sender, EventArgs e) - { + private void CancelBtn_Click(object sender, EventArgs e) { Close(); Dispose(); } - private void SaveBtn_Click(object sender, EventArgs e) - { - if (DelBackupBtn.Enabled) - { - if (dataGrid.SelectedRows.Count == 0) - { - if (dataGrid.SelectedCells.Count == 1) - { + private void SaveBtn_Click(object sender, EventArgs e) { + if (DelBackupBtn.Enabled) { + if (dataGrid.SelectedRows.Count == 0) { + if (dataGrid.SelectedCells.Count == 1) { dataGrid.SelectedCells[0].OwningRow.Selected = true; } } @@ -79,20 +69,15 @@ private void SaveBtn_Click(object sender, EventArgs e) Close(); } startCmds = new List(); - foreach (DataGridViewRow row in dataGrid.Rows) - { - if (workingProps != null) - { - foreach (Property prop in workingProps) - { - if ((string)row.Cells[0].Value == prop.KeyName) - { + foreach (DataGridViewRow row in dataGrid.Rows) { + if (workingProps != null) { + foreach (Property prop in workingProps) { + if ((string)row.Cells[0].Value == prop.KeyName) { prop.Value = (string)row.Cells[1].Value; } } } - else - { + else { if ((string)row.Cells[0].Value != null) startCmds.Add(new StartCmdEntry((string)row.Cells[0].Value)); } @@ -102,19 +87,15 @@ private void SaveBtn_Click(object sender, EventArgs e) Close(); } - private void gridView_NewRowNeeded(object sender, DataGridViewRowEventArgs e) - { + private void gridView_NewRowNeeded(object sender, DataGridViewRowEventArgs e) { DataGridViewRow focusedRow = gridView.CurrentRow; focusedRow.Cells[0].Value = "Cmd:"; gridView.Refresh(); } - private void DelBackupBtn_Click(object sender, EventArgs e) - { - if (dataGrid.SelectedRows.Count == 0) - { - if (dataGrid.SelectedCells.Count == 1) - { + private void DelBackupBtn_Click(object sender, EventArgs e) { + if (dataGrid.SelectedRows.Count == 0) { + if (dataGrid.SelectedCells.Count == 1) { dataGrid.SelectedCells[0].OwningRow.Selected = true; } } @@ -122,8 +103,7 @@ private void DelBackupBtn_Click(object sender, EventArgs e) if (dataGrid.SelectedRows.Count > 0) foreach (DataGridViewRow viewRow in dataGrid.SelectedRows) removeBackups.Add((string)viewRow.Cells[0].Value); - JsonSerializerSettings settings = new JsonSerializerSettings() - { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(removeBackups, Formatting.Indented, settings)); diff --git a/BedrockService/Client/Forms/PropEditorForm.resx b/BedrockService/Client/Forms/PropEditorForm.resx index 6f35f1cd..b1ad47f2 100644 --- a/BedrockService/Client/Forms/PropEditorForm.resx +++ b/BedrockService/Client/Forms/PropEditorForm.resx @@ -1,64 +1,4 @@ - - - + @@ -123,10 +63,4 @@ True - - True - - - True - \ No newline at end of file diff --git a/BedrockService/Client/Management/ClientLogger.cs b/BedrockService/Client/Management/ClientLogger.cs index 8e9a737e..8587a41a 100644 --- a/BedrockService/Client/Management/ClientLogger.cs +++ b/BedrockService/Client/Management/ClientLogger.cs @@ -4,51 +4,42 @@ using System.IO; using System.Text; -namespace BedrockService.Client.Management -{ - public class ClientLogger : ILogger - { +namespace BedrockService.Client.Management { + public class ClientLogger : IBedrockLogger { public List Log = new List(); public StringBuilder OutString = new StringBuilder(); public StreamWriter LogWriter; private readonly string LogDir; - public ClientLogger(IProcessInfo processInfo) - { + public ClientLogger(IProcessInfo processInfo) { LogDir = $@"{processInfo.GetDirectory()}\Client\ClientLogs"; - if (!Directory.Exists(LogDir)) - { + if (!Directory.Exists(LogDir)) { Directory.CreateDirectory(LogDir); } LogWriter = new StreamWriter($@"{LogDir}\ClientLog_{DateTime.Now:yyyymmddhhmmss}.log", true); } - public void AppendLine(string text) - { + public void AppendLine(string text) { string addText = $"Client: {text}\r\n"; Log.Add(addText); LogWriter.WriteLine(addText); LogWriter.Flush(); - Console.WriteLine(text); + System.Diagnostics.Debug.WriteLine(text); } public void AppendText(string text) => AppendLine(text); - public int Count() - { + public int Count() { return Log.Count; } - public string FromIndex(int index) - { + public string FromIndex(int index) { return Log[index]; } - public override string ToString() - { + public override string ToString() { OutString = new StringBuilder(); - foreach (string s in Log) - { + foreach (string s in Log) { OutString.Append(s); } return OutString.ToString(); diff --git a/BedrockService/Client/Management/ConfigManager.cs b/BedrockService/Client/Management/ConfigManager.cs index 837c0fa8..d23b07d1 100644 --- a/BedrockService/Client/Management/ConfigManager.cs +++ b/BedrockService/Client/Management/ConfigManager.cs @@ -1,71 +1,58 @@ using BedrockService.Shared.Classes; using BedrockService.Shared.Interfaces; -using System; using System.Collections.Generic; using System.IO; using System.Text; -namespace BedrockService.Client.Management -{ - public class ConfigManager - { +namespace BedrockService.Client.Management { + public class ConfigManager { public string ConfigDir = $@"{Directory.GetCurrentDirectory()}\Client\Configs"; public string ConfigFile; public List HostConnectList = new List(); public string NBTStudioPath; - private readonly ILogger Logger; + private readonly IBedrockLogger Logger; - public ConfigManager(ILogger logger) - { + public ConfigManager(IBedrockLogger logger) { Logger = logger; ConfigFile = $@"{ConfigDir}\Config.conf"; } - public void LoadConfigs() - { + public void LoadConfigs() { HostConnectList.Clear(); - if (!Directory.Exists(ConfigDir)) - { + if (!Directory.Exists(ConfigDir)) { Directory.CreateDirectory(ConfigDir); } - if (!File.Exists(ConfigFile)) - { + if (!File.Exists(ConfigFile)) { Logger.AppendLine("Config file missing! Regenerating default file..."); CreateDefaultConfig(); LoadConfigs(); return; } string[] lines = File.ReadAllLines(ConfigFile); - foreach (string line in lines) - { + foreach (string line in lines) { string[] entrySplit = line.Split('='); - if (!string.IsNullOrEmpty(line) && !line.StartsWith("#")) - { - if (entrySplit[0] == "HostEntry") - { + if (!string.IsNullOrEmpty(line) && !line.StartsWith("#")) { + if (entrySplit[0] == "HostEntry") { string[] hostSplit = entrySplit[1].Split(';'); string[] addressSplit = hostSplit[1].Split(':'); IClientSideServiceConfiguration hostToList = new ClientSideServiceConfiguration(hostSplit[0], addressSplit[0], addressSplit[1]); HostConnectList.Add(hostToList); } - if (entrySplit[0] == "NBTStudioPath") - { + if (entrySplit[0] == "NBTStudioPath") { NBTStudioPath = entrySplit[1]; } } } } - public void CreateDefaultConfig() - { + public void CreateDefaultConfig() { string[] Config = new string[] { "HostEntry=host1;127.0.0.1:19134" }; StringBuilder builder = new StringBuilder(); builder.Append("# Hosts\n"); - foreach (string entry in Config) - { + foreach (string entry in Config) { builder.Append($"{entry}\n"); } builder.Append("\n# Settings\n"); @@ -73,12 +60,10 @@ public void CreateDefaultConfig() File.WriteAllText(ConfigFile, builder.ToString()); } - public void SaveConfigFile() - { + public void SaveConfigFile() { StringBuilder fileContent = new StringBuilder(); fileContent.Append("# hosts\n\n"); - foreach (ClientSideServiceConfiguration host in HostConnectList) - { + foreach (ClientSideServiceConfiguration host in HostConnectList) { fileContent.Append($"HostEntry={host.GetHostName()};{host.GetAddress()}:{host.GetPort()}\n"); } fileContent.Append("\n# Settings\n"); diff --git a/BedrockService/Client/Management/FormManager.cs b/BedrockService/Client/Management/FormManager.cs index 37a2ca80..e4eca0f6 100644 --- a/BedrockService/Client/Management/FormManager.cs +++ b/BedrockService/Client/Management/FormManager.cs @@ -6,32 +6,24 @@ using System.IO; using System.Reflection; -namespace BedrockService.Client.Management -{ - public sealed class FormManager - { - private static readonly IProcessInfo processInfo = new ServiceProcessInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Path.GetFileName(Assembly.GetExecutingAssembly().Location), Process.GetCurrentProcess().Id, false, true); - private static readonly ILogger Logger = new ClientLogger(processInfo); +namespace BedrockService.Client.Management { + public sealed class FormManager { + private static readonly IProcessInfo processInfo = new ServiceProcessInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Process.GetCurrentProcess().Id, false, true, true); + private static readonly IBedrockLogger Logger = new ClientLogger(processInfo); private static MainWindow main; private static TCPClient client; - public static MainWindow MainWindow - { - get - { - if (main == null || main.IsDisposed) - { + public static MainWindow MainWindow { + get { + if (main == null || main.IsDisposed) { main = new MainWindow(processInfo, Logger); } return main; } } - public static TCPClient TCPClient - { - get - { - if (client == null) - { + public static TCPClient TCPClient { + get { + if (client == null) { client = new TCPClient(Logger); } return client; diff --git a/BedrockService/Client/Management/LogManager.cs b/BedrockService/Client/Management/LogManager.cs index 7e8a1d05..45383779 100644 --- a/BedrockService/Client/Management/LogManager.cs +++ b/BedrockService/Client/Management/LogManager.cs @@ -4,118 +4,97 @@ using System.Collections.Generic; using System.Text; using System.Threading; +using System.Threading.Tasks; using System.Windows.Forms; -namespace BedrockService.Client.Management -{ - class LogManager - { - public Thread LogThread; +namespace BedrockService.Client.Management { + class LogManager { + public Task LogTask; public bool EnableFlag; public bool Working = false; public List ServiceLogs = new List(); - private IServiceConfiguration connectedHost; - private readonly ILogger Logger; + private CancellationTokenSource _logTaskCancelSource; + private IServiceConfiguration _connectedHost; + private readonly IBedrockLogger _logger; - public LogManager(ILogger logger) - { - Logger = logger; + public LogManager(IBedrockLogger logger) { + _logger = logger; } - private void LogManagerTask() - { - while (FormManager.TCPClient.Connected) - { - try - { + private void LogManagerTask() { + while (!_logTaskCancelSource.Token.IsCancellationRequested) { + try { Working = true; StringBuilder sendString = new StringBuilder(); - foreach (ServerInfo server in connectedHost.GetServerList()) - { + foreach (ServerInfo server in _connectedHost.GetServerList()) { server.ConsoleBuffer = server.ConsoleBuffer ?? new List(); sendString.Append($"{server.ServerName};{server.ConsoleBuffer.Count}|"); } - sendString.Append($"Service;{connectedHost.GetLog().Count}"); + sendString.Append($"Service;{_connectedHost.GetLog().Count}"); byte[] stringsToBytes = Encoding.UTF8.GetBytes(sendString.ToString()); FormManager.TCPClient.SendData(stringsToBytes, NetworkMessageSource.Client, NetworkMessageDestination.Service, NetworkMessageTypes.ConsoleLogUpdate); Thread.Sleep(200); int currentLogBoxLength = 0; - if (FormManager.MainWindow.selectedServer == null) - { + if (FormManager.MainWindow.selectedServer == null) { UpdateLogBoxInvoked(""); } - FormManager.MainWindow.LogBox.Invoke((MethodInvoker)delegate - { + FormManager.MainWindow.LogBox.Invoke((MethodInvoker)delegate { currentLogBoxLength = FormManager.MainWindow.LogBox.TextLength; }); - if (FormManager.MainWindow.ShowsSvcLog && connectedHost.GetLog().Count != currentLogBoxLength) - { - UpdateLogBoxInvoked(string.Join("\r\n", connectedHost.GetLog())); + if (FormManager.MainWindow.ShowsSvcLog && _connectedHost.GetLog().Count != currentLogBoxLength) { + UpdateLogBoxInvoked(string.Join("\r\n", _connectedHost.GetLog())); } - else if (!FormManager.MainWindow.ShowsSvcLog && FormManager.MainWindow.selectedServer.GetLog() != null && FormManager.MainWindow.selectedServer.GetLog().Count != currentLogBoxLength) - { + else if (!FormManager.MainWindow.ShowsSvcLog && FormManager.MainWindow.selectedServer != null && FormManager.MainWindow.selectedServer.GetLog() != null && FormManager.MainWindow.selectedServer.GetLog().Count != currentLogBoxLength) { UpdateLogBoxInvoked(string.Join("", FormManager.MainWindow.selectedServer.GetLog())); } } - catch (Exception e) - { - Logger.AppendLine($"LogManager Error! Stacetrace: {e.StackTrace}"); + catch (Exception e) { + _logger.AppendLine($"LogManager Error! Stacetrace: {e.StackTrace}"); } } } - public bool InitLogThread(IServiceConfiguration host) - { - connectedHost = host; + public bool InitLogThread(IServiceConfiguration host) { + _connectedHost = host; + _logTaskCancelSource = new CancellationTokenSource(); return StartLogThread(); } - public bool StartLogThread() - { - try - { - if (LogThread != null && LogThread.IsAlive) - LogThread.Abort(); - LogThread = new Thread(new ThreadStart(LogManagerTask)); - LogThread.Name = "LogThread"; - LogThread.IsBackground = true; - EnableFlag = true; - LogThread.Start(); - Logger.AppendLine("LogThread started"); + public bool StartLogThread() { + try { + if (LogTask != null && !_logTaskCancelSource.IsCancellationRequested) + _logTaskCancelSource.Cancel(); + Thread.Sleep(500); + _logTaskCancelSource = new CancellationTokenSource(); + LogTask = Task.Factory.StartNew(new Action(LogManagerTask), _logTaskCancelSource.Token); + _logger.AppendLine("LogThread started"); return true; } - catch (Exception e) - { - Logger.AppendLine($"Error starting LogThread: {e.StackTrace}"); + catch (Exception e) { + _logger.AppendLine($"Error starting LogThread: {e.StackTrace}"); } return false; } - public bool StopLogThread() - { - if (LogThread == null) - { + public bool StopLogThread() { + if (LogTask == null) { return true; } - try - { - LogThread.Abort(); + try { + _logTaskCancelSource.Cancel(); } - catch (ThreadAbortException e) - { - Logger.AppendLine(e.StackTrace); + catch (ThreadAbortException e) { + _logger.AppendLine(e.StackTrace); } - Logger.AppendLine("LogThread stopped"); - LogThread = null; + _logger.AppendLine("LogThread stopped"); + LogTask = null; return true; } - private static void UpdateLogBoxInvoked(string contents) - { - FormManager.MainWindow.LogBox.Invoke((MethodInvoker)delegate - { + private static void UpdateLogBoxInvoked(string contents) { + FormManager.MainWindow.LogBox.Invoke((MethodInvoker)delegate { FormManager.MainWindow.UpdateLogBox(contents); }); } diff --git a/BedrockService/Client/Networking/TCPClient.cs b/BedrockService/Client/Networking/TCPClient.cs index 15eb7cab..c4ec0b9f 100644 --- a/BedrockService/Client/Networking/TCPClient.cs +++ b/BedrockService/Client/Networking/TCPClient.cs @@ -10,98 +10,81 @@ using System.Net.Sockets; using System.Text; using System.Threading; +using System.Threading.Tasks; -namespace BedrockService.Client.Networking -{ - public class TCPClient - { +namespace BedrockService.Client.Networking { + public class TCPClient { public TcpClient OpenedTcpClient; public string ClientName; public NetworkStream stream; + public bool EstablishedLink; public bool Connected; public bool EnableRead; public bool PlayerInfoArrived; public bool EnumBackupsArrived; public List BackupList; - public List RecievedPacks; - public Thread ClientReciever; - public Thread HeartbeatThread; + public List RecievedPacks; + public Task ClientReciever; + private CancellationTokenSource? _netCancelSource; private int _heartbeatFailTimeout; - private const int _heartbeatFailTimeoutLimit = 250; - private bool _heartbeatRecieved; - private bool _keepAlive; - private readonly ILogger _logger; + private const int _heartbeatFailTimeoutLimit = 2; + private readonly IBedrockLogger _logger; - public TCPClient (ILogger logger) - { + public TCPClient(IBedrockLogger logger) { _logger = logger; } - public void ConnectHost(IClientSideServiceConfiguration host) - { - if (EstablishConnection(host.GetAddress(), int.Parse(host.GetPort()))) - { + public void ConnectHost(IClientSideServiceConfiguration host) { + if (EstablishConnection(host.GetAddress(), int.Parse(host.GetPort()))) { SendData(NetworkMessageSource.Client, NetworkMessageDestination.Service, NetworkMessageTypes.Connect); return; } } - public bool EstablishConnection(string addr, int port) - { + public bool EstablishConnection(string addr, int port) { _logger.AppendLine("Connecting to Server"); - try - { + _netCancelSource = new CancellationTokenSource(); + try { EnableRead = false; OpenedTcpClient = new TcpClient(addr, port); stream = OpenedTcpClient.GetStream(); - _keepAlive = true; - ClientReciever = new Thread(new ThreadStart(ReceiveListener)); - ClientReciever.Name = "ClientPacketReviever"; - ClientReciever.IsBackground = true; - ClientReciever.Start(); + EstablishedLink = true; + ClientReciever = Task.Factory.StartNew(new Action(ReceiveListener), _netCancelSource.Token); } - catch - { + catch { _logger.AppendLine("Could not connect to Server"); - if(ClientReciever != null) - ClientReciever.Abort(); + if (ClientReciever != null) + _netCancelSource.Cancel(); ClientReciever = null; return false; } - return _keepAlive; + return EstablishedLink; } - public void CloseConnection() - { - try - { + public void CloseConnection() { + try { if (stream != null) stream.Dispose(); stream = null; Connected = false; - _keepAlive = false; + EstablishedLink = false; + _netCancelSource.Cancel(); } - catch (NullReferenceException) - { + catch (NullReferenceException) { Connected = false; - _keepAlive = false; + EstablishedLink = false; } - catch (Exception e) - { + catch (Exception e) { _logger.AppendLine($"Error closing connection: {e.StackTrace}"); } } - public void ReceiveListener() - { - List byteBlocks = new List(); - while (_keepAlive) - { - try - { + public void ReceiveListener() { + while (!_netCancelSource.IsCancellationRequested) { + SendData(NetworkMessageSource.Client, NetworkMessageDestination.Service, NetworkMessageTypes.Heartbeat); + try { byte[] buffer = new byte[4]; - while (OpenedTcpClient.Client.Available > 0) - { + while (OpenedTcpClient.Client.Available > 0) { int byteCount = stream.Read(buffer, 0, 4); int expectedLen = BitConverter.ToInt32(buffer, 0); buffer = new byte[expectedLen]; @@ -117,48 +100,24 @@ public void ReceiveListener() if (destination != NetworkMessageDestination.Client) continue; int srvCurLen = 0; - JsonSerializerSettings settings = new JsonSerializerSettings() - { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; - switch (source) - { + switch (source) { case NetworkMessageSource.Service: - switch (msgType) - { + switch (msgType) { case NetworkMessageTypes.Connect: - try - { + try { _logger.AppendLine("Connection to Host successful!"); FormManager.MainWindow.connectedHost = null; FormManager.MainWindow.connectedHost = JsonConvert.DeserializeObject(data, settings); Connected = true; FormManager.MainWindow.RefreshServerContents(); - _heartbeatFailTimeout = 0; - if (HeartbeatThread == null || !HeartbeatThread.IsAlive) - HeartbeatThread = new Thread(new ThreadStart(SendHeatbeatSignal)) - { - IsBackground = true, - Name = "HeartBeatThread" - }; - HeartbeatThread.Start(); - } - catch (Exception e) - { + catch (Exception e) { _logger.AppendLine($"Error: ConnectMan reported error: {e.Message}\n{e.StackTrace}"); } break; - case NetworkMessageTypes.Heartbeat: - _heartbeatRecieved = true; - if (!HeartbeatThread.IsAlive) - { - HeartbeatThread = new Thread(new ThreadStart(SendHeatbeatSignal)); - HeartbeatThread.IsBackground = true; - HeartbeatThread.Name = "HeartBeatThread"; - HeartbeatThread.Start(); - } - break; case NetworkMessageTypes.EnumBackups: @@ -180,30 +139,24 @@ public void ReceiveListener() } break; case NetworkMessageSource.Server: - switch (msgType) - { + switch (msgType) { case NetworkMessageTypes.ConsoleLogUpdate: string[] strings = data.Split('|'); - for (int i = 0; i < strings.Length; i++) - { + for (int i = 0; i < strings.Length; i++) { string[] srvSplit = strings[i].Split(';'); string srvName = srvSplit[0]; string srvText = srvSplit[1]; srvCurLen = int.Parse(srvSplit[2]); - if (srvName != "Service") - { + if (srvName != "Service") { IServerConfiguration bedrockServer = FormManager.MainWindow.connectedHost.GetServerInfoByName(srvName); int curCount = bedrockServer.GetLog().Count; - if (curCount == srvCurLen) - { + if (curCount == srvCurLen) { bedrockServer.GetLog().Add(srvText); } } - else - { + else { int curCount = FormManager.MainWindow.connectedHost.GetLog().Count; - if (curCount == srvCurLen) - { + if (curCount == srvCurLen) { FormManager.MainWindow.connectedHost.GetLog().Add(srvText); } } @@ -221,10 +174,10 @@ public void ReceiveListener() break; case NetworkMessageTypes.PackList: - List temp = new List(); + List temp = new List(); JArray jArray = JArray.Parse(data); foreach (JToken token in jArray) - temp.Add(token.ToObject()); + temp.Add(token.ToObject()); RecievedPacks = temp; break; @@ -249,41 +202,14 @@ public void ReceiveListener() } } } - catch (Exception e) - { + catch (Exception e) { _logger.AppendLine($"TCPClient error! Stacktrace: {e.Message}\n{e.StackTrace}"); } Thread.Sleep(200); } } - public void SendHeatbeatSignal() - { - _logger.AppendLine("HeartbeatThread started."); - while (_keepAlive) - { - _heartbeatRecieved = false; - SendData(NetworkMessageSource.Client, NetworkMessageDestination.Service, NetworkMessageTypes.Heartbeat); - while (!_heartbeatRecieved && _keepAlive) - { - Thread.Sleep(100); - _heartbeatFailTimeout++; - if (_heartbeatFailTimeout > _heartbeatFailTimeoutLimit) - { - FormManager.MainWindow.HeartbeatFailDisconnect(); - HeartbeatThread.Abort(); - _heartbeatFailTimeout = 0; - } - } - // Logger.AppendLine("ThumpThump"); - _heartbeatRecieved = false; - _heartbeatFailTimeout = 0; - Thread.Sleep(3000); - } - } - - public bool SendData(byte[] bytes, NetworkMessageSource source, NetworkMessageDestination destination, byte serverIndex, NetworkMessageTypes type, NetworkMessageFlags status) - { + public bool SendData(byte[] bytes, NetworkMessageSource source, NetworkMessageDestination destination, byte serverIndex, NetworkMessageTypes type, NetworkMessageFlags status) { byte[] compiled = new byte[9 + bytes.Length]; byte[] len = BitConverter.GetBytes(5 + bytes.Length); Buffer.BlockCopy(len, 0, compiled, 0, 4); @@ -293,18 +219,23 @@ public bool SendData(byte[] bytes, NetworkMessageSource source, NetworkMessageDe compiled[7] = (byte)type; compiled[8] = (byte)status; Buffer.BlockCopy(bytes, 0, compiled, 9, bytes.Length); - if (_keepAlive) - { - try - { + if (EstablishedLink) { + try { stream.Write(compiled, 0, compiled.Length); stream.Flush(); + _heartbeatFailTimeout = 0; return true; - } - catch - { + catch { _logger.AppendLine("Error writing to network stream!"); + Thread.Sleep(100); + _heartbeatFailTimeout++; + if (_heartbeatFailTimeout > _heartbeatFailTimeoutLimit) { + Task.Run(() => { FormManager.MainWindow.HeartbeatFailDisconnect(); }); + _netCancelSource.Cancel(); + EstablishedLink = false; + _heartbeatFailTimeout = 0; + } return false; } } @@ -323,16 +254,14 @@ public bool SendData(byte[] bytes, NetworkMessageSource source, NetworkMessageDe public void SendData(NetworkMessageSource source, NetworkMessageDestination destination, NetworkMessageTypes type, NetworkMessageFlags status) => SendData(new byte[0], source, destination, 0xFF, type, status); - public void Dispose() - { - if (HeartbeatThread != null && HeartbeatThread.IsAlive) - HeartbeatThread.Abort(); - if (ClientReciever != null && ClientReciever.IsAlive) - ClientReciever.Abort(); - HeartbeatThread = null; + public void Dispose() { + if (_netCancelSource != null) { + _netCancelSource.Cancel(); + _netCancelSource.Dispose(); + _netCancelSource = null; + } ClientReciever = null; - if (OpenedTcpClient != null) - { + if (OpenedTcpClient != null) { OpenedTcpClient.Close(); OpenedTcpClient.Dispose(); } diff --git a/BedrockService/Client/Properties/Settings.Designer.cs b/BedrockService/Client/Properties/Settings.Designer.cs index 609bb426..20a0d7cd 100644 --- a/BedrockService/Client/Properties/Settings.Designer.cs +++ b/BedrockService/Client/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace BedrockService.Client.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.0.3.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); diff --git a/BedrockService/Client/mc_icon.ico b/BedrockService/Client/mc_icon.ico new file mode 100644 index 00000000..0c675e0b Binary files /dev/null and b/BedrockService/Client/mc_icon.ico differ diff --git a/BedrockService/ClientUnitTests/ClientUnitTests.csproj b/BedrockService/ClientUnitTests/ClientUnitTests.csproj index 1bbbb29c..e977ee03 100644 --- a/BedrockService/ClientUnitTests/ClientUnitTests.csproj +++ b/BedrockService/ClientUnitTests/ClientUnitTests.csproj @@ -61,10 +61,6 @@ {f146d5e8-ef1f-4785-9150-182631f059b7} BedrockService.Shared - - {a2daf70a-925a-4f4b-b7ee-caace75d6740} - BedrockService.Client - diff --git a/BedrockService/ClientUnitTests/FormTests.cs b/BedrockService/ClientUnitTests/FormTests.cs index 128eac3b..85bcb5cc 100644 --- a/BedrockService/ClientUnitTests/FormTests.cs +++ b/BedrockService/ClientUnitTests/FormTests.cs @@ -1,16 +1,13 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using BedrockService.Client.Forms; +using BedrockService.Client.Forms; +using BedrockService.Client.Management; using BedrockService.Shared.Classes; using BedrockService.Shared.Interfaces; -using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using BedrockService.Client.Management; using System.Diagnostics; -using System.Reflection; using System.IO; -using System.Windows.Forms; +using System.Reflection; +using System.Threading.Tasks; namespace ClientUnitTests { diff --git a/BedrockService/ClientUnitTests/Properties/AssemblyInfo.cs b/BedrockService/ClientUnitTests/Properties/AssemblyInfo.cs index 66261c92..c7de3b86 100644 --- a/BedrockService/ClientUnitTests/Properties/AssemblyInfo.cs +++ b/BedrockService/ClientUnitTests/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; [assembly: AssemblyTitle("ClientUnitTests")] diff --git a/BedrockService/Service/BedrockService.Service.csproj b/BedrockService/Service/BedrockService.Service.csproj index f0053119..cb523b9f 100644 --- a/BedrockService/Service/BedrockService.Service.csproj +++ b/BedrockService/Service/BedrockService.Service.csproj @@ -1,17 +1,6 @@ - - - + - Debug - AnyCPU - {13B2B5A8-71E9-49F4-9BFB-3C3B3C0A054C} Exe - BedrockService.Service - BedrockService.Service - v4.7.2 - 512 - true - true true C:\Users\crowbar\source\repos\BedrockManagementService\Releases\ true @@ -31,25 +20,28 @@ false true true + Debug;Release;Publish + AnyCPU;x64 - x86 - true - full - false ..\bin\Debug\ - DEBUG;TRACE - prompt + 2 + + + ..\bin\Debug\ 2 - AnyCPU - pdbonly - true ..\bin\Release\ - TRACE - prompt - 4 + + + ..\bin\Release\ + + + ..\bin\Release\ + + + ..\bin\Release\ EE2403F7477A35F08B98B0A8FB2404C95BE04FEB @@ -63,113 +55,15 @@ false - - false - - - - ..\packages\Microsoft.Bcl.AsyncInterfaces.5.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll - False - True - - - ..\packages\Microsoft.Extensions.DependencyInjection.5.0.2\lib\net461\Microsoft.Extensions.DependencyInjection.dll - False - True - - - ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.5.0.0\lib\net461\Microsoft.Extensions.DependencyInjection.Abstractions.dll - False - True - - - ..\packages\NCrontab.Signed.3.3.2\lib\net35\NCrontab.Signed.dll - False - True - - - ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll - False - True - - - - False - - - - - False - - - - ..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll - True - True - - - ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll - True - False - - - - - ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll - True - - - - - - False - - - - - - ..\packages\Topshelf.4.3.0\lib\net452\Topshelf.dll - False - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + net6.0-windows + false + mc_icon.ico + False @@ -183,15 +77,29 @@ - - + + + + + + + + + + + + + + all + + + + + - - - {f146d5e8-ef1f-4785-9150-182631f059b7} - BedrockService.Shared - + + + - \ No newline at end of file diff --git a/BedrockService/Service/Core/BedrockService.cs b/BedrockService/Service/Core/BedrockService.cs index 103be71c..01280d89 100644 --- a/BedrockService/Service/Core/BedrockService.cs +++ b/BedrockService/Service/Core/BedrockService.cs @@ -1,36 +1,22 @@ using BedrockService.Service.Core.Interfaces; -using BedrockService.Service.Management; -using BedrockService.Service.Networking; using BedrockService.Service.Server; -using BedrockService.Shared.Interfaces; -using BedrockService.Service.Core.Threads; using NCrontab; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; using System.Timers; -using Topshelf; -namespace BedrockService.Service.Core -{ - public class BedrockService : ServiceControl, IBedrockService - { - private enum ServiceStatus - { +namespace BedrockService.Service.Core { + public class BedrockService : ServiceControl, IBedrockService { + private enum ServiceStatus { Stopped, Starting, Started, Stopping } private readonly IServiceConfiguration _serviceConfiguration; - private readonly ILogger _logger; + private readonly IBedrockLogger _logger; private readonly IProcessInfo _processInfo; private readonly IConfigurator _configurator; private readonly IUpdater _updater; private readonly ITCPListener _tCPListener; - private readonly IServiceThread _tcpThread; private readonly CrontabSchedule _shed; private readonly CrontabSchedule _updaterCron; private HostControl _hostControl; @@ -38,192 +24,155 @@ private enum ServiceStatus private System.Timers.Timer _updaterTimer; private System.Timers.Timer _cronTimer; - public BedrockService(IConfigurator configurator, IUpdater updater, ILogger logger, IServiceConfiguration serviceConfiguration, IProcessInfo serviceProcessInfo, ITCPListener tCPListener) - { - _tCPListener = tCPListener; - _configurator = configurator; - _serviceConfiguration = serviceConfiguration; - _processInfo = serviceProcessInfo; - _updater = updater; - _logger = logger; - _shed = CrontabSchedule.TryParse(serviceConfiguration.GetProp("BackupCron").ToString()); - _updaterCron = CrontabSchedule.TryParse(serviceConfiguration.GetProp("UpdateCron").ToString()); - Initialize(); + public BedrockService(IConfigurator configurator, IUpdater updater, IBedrockLogger logger, IServiceConfiguration serviceConfiguration, IProcessInfo serviceProcessInfo, ITCPListener tCPListener) { + if (serviceProcessInfo.ShouldStartService()) { + _tCPListener = tCPListener; + _configurator = configurator; + _configurator.LoadAllConfigurations().Wait(); + _serviceConfiguration = serviceConfiguration; + _processInfo = serviceProcessInfo; + _updater = updater; + _updater.CheckUpdates().Wait(); + _logger = logger; + _shed = CrontabSchedule.TryParse(serviceConfiguration.GetProp("BackupCron").ToString()); + _updaterCron = CrontabSchedule.TryParse(serviceConfiguration.GetProp("UpdateCron").ToString()); + Initialize(); + _tCPListener.SetKeyContainer(_configurator.GetKeyContainer()); + } } - public bool Start(HostControl hostControl) - { + public bool Start(HostControl hostControl) { _hostControl = hostControl; - try - { + try { ValidSettingsCheck(); - foreach (var brs in _bedrockServers) - { - if(hostControl != null) + foreach (var brs in _bedrockServers) { + if (hostControl != null) _hostControl.RequestAdditionalTime(TimeSpan.FromSeconds(30)); brs.SetServerStatus(BedrockServer.ServerStatus.Starting); brs.StartWatchdog(_hostControl); } return true; } - catch (Exception e) - { + catch (Exception e) { _logger.AppendLine($"Error Starting BedrockServiceWrapper {e.StackTrace}"); return false; } } - public bool Stop(HostControl hostControl) - { + public bool Stop(HostControl hostControl) { _hostControl = hostControl; - try - { - foreach (var brs in _bedrockServers) - { + try { + foreach (var brs in _bedrockServers) { brs.SetServerStatus(BedrockServer.ServerStatus.Stopping); while (brs.GetServerStatus() == BedrockServer.ServerStatus.Stopping && !Program.IsExiting) Thread.Sleep(100); } - _tcpThread.CloseThread(); return true; } - catch (Exception e) - { + catch (Exception e) { _logger.AppendLine($"Error Stopping BedrockServiceWrapper {e.StackTrace}"); return false; } } - public void RestartService() - { - try - { - foreach (IBedrockServer brs in _bedrockServers) - { + public void RestartService() { + try { + foreach (IBedrockServer brs in _bedrockServers) { brs.SetServerStatus(BedrockServer.ServerStatus.Stopping); while (brs.GetServerStatus() == BedrockServer.ServerStatus.Stopping && !Program.IsExiting) Thread.Sleep(100); } - foreach (IBedrockServer brs in _bedrockServers) - { - brs.StopWatchdog(); - } - try - { + try { _tCPListener.ResetListener(); } catch (ThreadAbortException) { } _configurator.LoadAllConfigurations().Wait(); Initialize(); - foreach (var brs in _bedrockServers) - { + foreach (var brs in _bedrockServers) { brs.SetServerStatus(BedrockServer.ServerStatus.Starting); } Start(_hostControl); } - catch (Exception e) - { + catch (Exception e) { _logger.AppendLine($"Error Stopping BedrockServiceWrapper {e.StackTrace}"); } } - public IBedrockServer GetBedrockServerByIndex(int serverIndex) - { + public IBedrockServer GetBedrockServerByIndex(int serverIndex) { return _bedrockServers[serverIndex]; } - public IBedrockServer GetBedrockServerByName(string name) - { + public IBedrockServer GetBedrockServerByName(string name) { return _bedrockServers.FirstOrDefault(brs => brs.GetServerName() == name); } public List GetAllServers() => _bedrockServers; - public void InitializeNewServer(IServerConfiguration server) - { + public void InitializeNewServer(IServerConfiguration server) { IBedrockServer bedrockServer = new BedrockServer(server, _configurator, _logger, _serviceConfiguration, _processInfo); _bedrockServers.Add(bedrockServer); _serviceConfiguration.AddNewServerInfo(server); - if (ValidSettingsCheck()) - { + if (ValidSettingsCheck()) { bedrockServer.SetServerStatus(BedrockServer.ServerStatus.Starting); bedrockServer.StartWatchdog(_hostControl); } } - private void Initialize() - { + private void Initialize() { _bedrockServers.Clear(); - if (_serviceConfiguration.GetProp("BackupEnabled").ToString() == "true" && _shed != null) - { + if (_serviceConfiguration.GetProp("BackupEnabled").ToString() == "true" && _shed != null) { _cronTimer = new System.Timers.Timer((_shed.GetNextOccurrence(DateTime.Now) - DateTime.Now).TotalMilliseconds); _cronTimer.Elapsed += CronTimer_Elapsed; _cronTimer.Start(); } - if (_serviceConfiguration.GetProp("CheckUpdates").ToString() == "true" && _updaterCron != null) - { + if (_serviceConfiguration.GetProp("CheckUpdates").ToString() == "true" && _updaterCron != null) { _updaterTimer = new System.Timers.Timer((_updaterCron.GetNextOccurrence(DateTime.Now) - DateTime.Now).TotalMilliseconds); _updaterTimer.Elapsed += UpdateTimer_Elapsed; _logger.AppendLine($"Updates Enabled, will be checked in: {((float)_updaterTimer.Interval / 1000)} seconds."); _updaterTimer.Start(); } - try - { + try { List temp = _serviceConfiguration.GetServerList(); - foreach (IServerConfiguration server in temp) - { + foreach (IServerConfiguration server in temp) { IBedrockServer bedrockServer = new BedrockServer(server, _configurator, _logger, _serviceConfiguration, _processInfo); _bedrockServers.Add(bedrockServer); } } - catch (Exception e) - { + catch (Exception e) { _logger.AppendLine($"Error Instantiating BedrockServiceWrapper: {e.StackTrace}"); } } - private void CronTimer_Elapsed(object sender, ElapsedEventArgs e) - { - try - { - if (_cronTimer != null) - { + private void CronTimer_Elapsed(object sender, ElapsedEventArgs e) { + try { + if (_cronTimer != null) { _cronTimer.Stop(); _cronTimer = null; } - if (_serviceConfiguration.GetProp("BackupEnabled").ToString() == "true" && _shed != null) - { - Backup(); - + if (_serviceConfiguration.GetProp("BackupEnabled").ToString() == "true" && _shed != null) { + BackupAllServers(); _cronTimer = new System.Timers.Timer((_shed.GetNextOccurrence(DateTime.Now) - DateTime.Now).TotalMilliseconds); _cronTimer.Elapsed += CronTimer_Elapsed; _cronTimer.Start(); } } - catch (Exception ex) - { + catch (Exception ex) { _logger.AppendLine($"Error in BackupTimer_Elapsed {ex}"); } } - private void UpdateTimer_Elapsed(object sender, ElapsedEventArgs e) - { - try - { - if (_updaterTimer != null) - { + private void UpdateTimer_Elapsed(object sender, ElapsedEventArgs e) { + try { + if (_updaterTimer != null) { _updaterTimer.Stop(); _updaterTimer = null; } _updater.CheckUpdates().Wait(); - if (_serviceConfiguration.GetProp("CheckUpdates").ToString() == "true" && _updater != null) - { - if (_updater.CheckVersionChanged()) - { + if (_serviceConfiguration.GetProp("CheckUpdates").ToString() == "true" && _updater != null) { + if (_updater.CheckVersionChanged()) { _logger.AppendLine("Version change detected! Restarting server(s) to apply update..."); - foreach(IBedrockServer server in _bedrockServers) - { + foreach (IBedrockServer server in _bedrockServers) { server.RestartServer(false); } } @@ -233,69 +182,53 @@ private void UpdateTimer_Elapsed(object sender, ElapsedEventArgs e) _updaterTimer.Start(); } } - catch (Exception ex) - { + catch (Exception ex) { _logger.AppendLine($"Error in UpdateTimer_Elapsed {ex}"); } } - private void Backup() - { + private void BackupAllServers() { _logger.AppendLine("Service started backup manager."); - foreach (var brs in _bedrockServers) - { - brs.RestartServer(true); + foreach (var brs in _bedrockServers) { + brs.InitializeBackup(); } _logger.AppendLine("Backups have been completed."); } - private bool ValidSettingsCheck() - { + private bool ValidSettingsCheck() { bool validating = true; bool dupedSettingsFound = false; - while (validating) - { - if (_serviceConfiguration.GetServerList().Count() < 1) - { + while (validating) { + if (_serviceConfiguration.GetServerList().Count() < 1) { throw new Exception("No Servers Configured"); } - else - { - foreach (IServerConfiguration server in _serviceConfiguration.GetServerList()) - { - foreach (IServerConfiguration compareServer in _serviceConfiguration.GetServerList()) - { - if (server != compareServer) - { + else { + foreach (IServerConfiguration server in _serviceConfiguration.GetServerList()) { + foreach (IServerConfiguration compareServer in _serviceConfiguration.GetServerList()) { + if (server != compareServer) { if (server.GetProp("server-port").Equals(compareServer.GetProp("server-port")) || server.GetProp("server-portv6").Equals(compareServer.GetProp("server-portv6")) || - server.GetProp("server-name").Equals(compareServer.GetProp("server-name"))) - { + server.GetProp("server-name").Equals(compareServer.GetProp("server-name"))) { _logger.AppendLine($"Duplicate server settings between servers {server.GetFileName()} and {compareServer.GetFileName()}."); dupedSettingsFound = true; } } } } - if (dupedSettingsFound) - { + if (dupedSettingsFound) { throw new Exception("Duplicate settings found! Check logs."); } - foreach (var server in _serviceConfiguration.GetServerList()) - { - if (_updater.CheckVersionChanged() || !File.Exists(server.GetProp("ServerPath") + "\\bedrock_server.exe")) - { + foreach (var server in _serviceConfiguration.GetServerList()) { + if (_updater.CheckVersionChanged() || !File.Exists(server.GetProp("ServerPath") + "\\bedrock_server.exe")) { _configurator.ReplaceServerBuild(server).Wait(); } - if (server.GetProp("ServerExeName").ToString() != "bedrock_server.exe" && File.Exists(server.GetProp("ServerPath") + "\\bedrock_server.exe") && !File.Exists(server.GetProp("ServerPath") + "\\" + server.GetProp("ServerExeName"))) - { + if (server.GetProp("ServerExeName").ToString() != "bedrock_server.exe" && File.Exists(server.GetProp("ServerPath") + "\\bedrock_server.exe") && !File.Exists(server.GetProp("ServerPath") + "\\" + server.GetProp("ServerExeName"))) { File.Copy(server.GetProp("ServerPath") + "\\bedrock_server.exe", server.GetProp("ServerPath") + "\\" + server.GetProp("ServerExeName")); } } if (_updater.CheckVersionChanged()) _updater.MarkUpToDate(); - else - { + else { validating = false; } } @@ -303,8 +236,7 @@ private bool ValidSettingsCheck() return true; } - public void RemoveBedrockServerByIndex(int serverIndex) - { + public void RemoveBedrockServerByIndex(int serverIndex) { _bedrockServers.RemoveAt(serverIndex); } } diff --git a/BedrockService/Service/Core/Interfaces/IBedrockService.cs b/BedrockService/Service/Core/Interfaces/IBedrockService.cs index 4fadcf8e..ea197552 100644 --- a/BedrockService/Service/Core/Interfaces/IBedrockService.cs +++ b/BedrockService/Service/Core/Interfaces/IBedrockService.cs @@ -1,12 +1,7 @@ using BedrockService.Service.Server; -using BedrockService.Shared.Interfaces; -using System.Collections.Generic; -using Topshelf; -namespace BedrockService.Service.Core -{ - public interface IBedrockService : ServiceControl - { +namespace BedrockService.Service.Core.Interfaces { + public interface IBedrockService : ServiceControl { IBedrockServer GetBedrockServerByIndex(int index); void RemoveBedrockServerByIndex(int serverIndex); diff --git a/BedrockService/Service/Core/Interfaces/IService.cs b/BedrockService/Service/Core/Interfaces/IService.cs index b4ef9e09..b7bd2294 100644 --- a/BedrockService/Service/Core/Interfaces/IService.cs +++ b/BedrockService/Service/Core/Interfaces/IService.cs @@ -1,10 +1,5 @@ -using System.Threading.Tasks; - -namespace BedrockService.Service.Core -{ - public interface IService - { +namespace BedrockService.Service.Core.Interfaces { + public interface IService : IHostedService { Task InitializeHost(); - Topshelf.TopshelfExitCode Run(); } } diff --git a/BedrockService/Service/Core/Service.cs b/BedrockService/Service/Core/Service.cs index 87decbd5..14e9b86f 100644 --- a/BedrockService/Service/Core/Service.cs +++ b/BedrockService/Service/Core/Service.cs @@ -1,67 +1,62 @@ using BedrockService.Service.Core.Interfaces; -using BedrockService.Service.Core.Threads; -using BedrockService.Service.Networking; using BedrockService.Service.Server; -using BedrockService.Shared.Interfaces; -using System; -using System.Threading; -using System.Threading.Tasks; -using Topshelf; using Topshelf.Runtime; -namespace BedrockService.Service.Core -{ - public class Service : IService - { +namespace BedrockService.Service.Core { + public class Service : IService { private readonly IBedrockService _bedrockService; - private Host _host; - private readonly ILogger _logger; + private Topshelf.Host _host; + private readonly IBedrockLogger _logger; + IHostApplicationLifetime _applicationLifetime; - public Service(ILogger logger, IBedrockService bedrockService) - { + public Service(IBedrockLogger logger, IBedrockService bedrockService, NetworkStrategyLookup lookup, IHostApplicationLifetime appLifetime) { _logger = logger; _bedrockService = bedrockService; + _applicationLifetime = appLifetime; + appLifetime.ApplicationStarted.Register(OnStarted); } - public async Task InitializeHost() - { - await Task.Run(() => - { - _host = HostFactory.New(hostConfig => - { + public async Task InitializeHost() { + await Task.Run(() => { + _host = HostFactory.New(hostConfig => { hostConfig.SetStartTimeout(TimeSpan.FromSeconds(10)); hostConfig.SetStopTimeout(TimeSpan.FromSeconds(10)); hostConfig.UseAssemblyInfoForServiceInfo(); - hostConfig.Service(settings => _bedrockService, s => - { + hostConfig.Service(settings => _bedrockService, s => { s.BeforeStartingService(_ => _logger.AppendLine("Starting service...")); - s.BeforeStoppingService(_ => - { + s.BeforeStoppingService(_ => { _logger.AppendLine("Stopping service..."); - foreach (IBedrockServer server in _bedrockService.GetAllServers()) - { + foreach (IBedrockServer server in _bedrockService.GetAllServers()) { server.SetServerStatus(BedrockServer.ServerStatus.Stopping); while (server.GetServerStatus() != BedrockServer.ServerStatus.Stopped) Thread.Sleep(100); } + Environment.Exit(0); }); }); - + hostConfig.EnableShutdown(); + hostConfig.EnableHandleCtrlBreak(); hostConfig.RunAsLocalSystem(); hostConfig.SetDescription("Windows Service Wrapper for Windows Bedrock Server"); hostConfig.SetDisplayName("BedrockService"); hostConfig.SetServiceName("BedrockService"); hostConfig.UnhandledExceptionPolicy = UnhandledExceptionPolicyCode.LogErrorOnly; - - hostConfig.EnableServiceRecovery(src => - { + hostConfig.AfterInstall(() => { + _logger.AppendLine("Service install completed... Exiting!"); + Task.Delay(1000).Wait(); + _applicationLifetime.StopApplication(); + }); + hostConfig.AfterUninstall(() => { + _logger.AppendLine("Service uninstall completed... Exiting!"); + Task.Delay(1000).Wait(); + _applicationLifetime.StopApplication(); + }); + hostConfig.EnableServiceRecovery(src => { src.RestartService(delayInMinutes: 0); src.RestartService(delayInMinutes: 1); src.SetResetPeriod(days: 1); }); - - hostConfig.OnException((ex) => - { + hostConfig.OnException((ex) => { _logger.AppendLine("Exception occured Main : " + ex.Message); }); }); @@ -69,6 +64,16 @@ await Task.Run(() => }); } - public TopshelfExitCode Run() => _host.Run(); + public Task StartAsync(CancellationToken cancellationToken) { + return InitializeHost(); + } + + public Task StopAsync(CancellationToken cancellationToken) { + return Task.Delay(100); + } + + private void OnStarted() { + Task.Run(() => { _host.Run(); }); + } } } diff --git a/BedrockService/Service/Logging/ServiceLogger.cs b/BedrockService/Service/Logging/ServiceLogger.cs index 7d3237fe..28615fac 100644 --- a/BedrockService/Service/Logging/ServiceLogger.cs +++ b/BedrockService/Service/Logging/ServiceLogger.cs @@ -1,13 +1,8 @@ -using BedrockService.Shared.Interfaces; -using Newtonsoft.Json; -using System; -using System.IO; +using Newtonsoft.Json; using System.Text; -namespace BedrockService.Service.Logging -{ - public class ServiceLogger : ILogger - { +namespace BedrockService.Service.Logging { + public class ServiceLogger : IBedrockLogger { private readonly IServiceConfiguration _serviceConfiguration; private StringBuilder _outputString = new StringBuilder(); [NonSerialized] @@ -17,83 +12,70 @@ public class ServiceLogger : ILogger private readonly string _parent = "Service"; private readonly string _logPath; - public ServiceLogger(IProcessInfo processInfo, IServiceConfiguration serviceConfiguration) - { + public ServiceLogger(IProcessInfo processInfo, IServiceConfiguration serviceConfiguration) { _serviceConfiguration = serviceConfiguration; _logPath = $@"{processInfo.GetDirectory()}\Service\Logs"; - _logToFile = bool.Parse(serviceConfiguration.GetProp("LogServiceToFile").ToString()); - _logToConsole = true; - if (_logToFile) - { - if (!Directory.Exists(_logPath)) - Directory.CreateDirectory(_logPath); - _logWriter = new StreamWriter($@"{_logPath}\ServiceLog_{_parent}_{DateTime.Now:yyyymmddhhmmss}.log", true); + if (processInfo.ShouldStartService()) { + _logToFile = bool.Parse(serviceConfiguration.GetProp("LogServiceToFile").ToString()); + _logToConsole = true; + if (_logToFile) { + if (!Directory.Exists(_logPath)) + Directory.CreateDirectory(_logPath); + _logWriter = new StreamWriter($@"{_logPath}\ServiceLog_{_parent}_{DateTime.Now:yyyymmddhhmmss}.log", true); + } + AppendLine($"Service logging started. Service working directory: {processInfo.GetDirectory()}"); } } [JsonConstructor] - public ServiceLogger(IServiceConfiguration serviceConfiguration, string serverName) - { + public ServiceLogger(IServiceConfiguration serviceConfiguration, string serverName) { _serviceConfiguration = serviceConfiguration; _parent = serverName; _logToFile = false; _logToConsole = false; } - public void AppendLine(string text) - { - try - { + public void AppendLine(string text) { + try { _serviceConfiguration.GetLog().Add(text); - if (_logToFile && _logWriter != null) - { + if (_logToFile && _logWriter != null) { _logWriter.WriteLine(text); _logWriter.Flush(); } if (_logToConsole) Console.WriteLine(text); } - catch - { + catch { } } - public void AppendText(string text) - { - try - { + public void AppendText(string text) { + try { _serviceConfiguration.GetLog().Add(text); - if (_logToFile && _logWriter != null) - { + if (_logToFile && _logWriter != null) { _logWriter.Write(text); _logWriter.Flush(); } - if (_logToConsole) - { + if (_logToConsole) { Console.Write(text); Console.Out.Flush(); } } - catch - { + catch { } } - public int Count() - { + public int Count() { return _serviceConfiguration.GetLog().Count; } - public string FromIndex(int index) - { + public string FromIndex(int index) { return _serviceConfiguration.GetLog()[index]; } - public override string ToString() - { + public override string ToString() { _outputString = new StringBuilder(); - foreach (string s in _serviceConfiguration.GetLog()) - { + foreach (string s in _serviceConfiguration.GetLog()) { _outputString.Append(s); } return _outputString.ToString(); diff --git a/BedrockService/Service/Management/ConfigManager.cs b/BedrockService/Service/Management/ConfigManager.cs index 4a9b49ac..b0a1d1d4 100644 --- a/BedrockService/Service/Management/ConfigManager.cs +++ b/BedrockService/Service/Management/ConfigManager.cs @@ -1,42 +1,41 @@ -using BedrockService.Service.Server; -using BedrockService.Shared.Classes; -using BedrockService.Shared.Interfaces; -using BedrockService.Shared.Utilities; -using System; -using System.Collections.Generic; -using System.IO; +using BedrockService.Shared.Utilities; using System.IO.Compression; +using System.Runtime.Serialization.Formatters.Binary; +using System.Security.Cryptography; using System.Text; -using System.Threading; -using System.Threading.Tasks; -namespace BedrockService.Service.Management -{ - public class ConfigManager : IConfigurator - { +namespace BedrockService.Service.Management { + public class ConfigManager : IConfigurator { private readonly string _configDir; private readonly string _globalFile; + private readonly string _clientKeyPath; + private readonly string _commsKeyPath; private string _loadedVersion; private static readonly object _fileLock = new object(); private readonly IServiceConfiguration _serviceConfiguration; private readonly IProcessInfo _processInfo; - private readonly ILogger _logger; + private readonly IBedrockLogger _logger; + private CommsKeyContainer _keyContainer; + private RSAParameters _serviceKey; + private RSAParameters _clientKey; - public ConfigManager(IProcessInfo processInfo, IServiceConfiguration serviceConfiguration, ILogger logger) - { + public ConfigManager(IProcessInfo processInfo, IServiceConfiguration serviceConfiguration, IBedrockLogger logger) { _processInfo = processInfo; _serviceConfiguration = serviceConfiguration; _logger = logger; _configDir = $@"{_processInfo.GetDirectory()}\Server\Configs"; _globalFile = $@"{_processInfo.GetDirectory()}\Service\Globals.conf"; + _clientKeyPath = $@"{_processInfo.GetDirectory()}\Client\ClientKey.dat"; + _commsKeyPath = $@"{_processInfo.GetDirectory()}\Service\CommsKey.dat"; } - public async Task LoadAllConfigurations() - { - await Task.Run(() => - { + public async Task LoadAllConfigurations() { + await Task.Run(() => { + BinaryFormatter formatter = new BinaryFormatter(); if (!Directory.Exists(_configDir)) Directory.CreateDirectory(_configDir); + if (!Directory.Exists($@"{_processInfo.GetDirectory()}\Client")) + Directory.CreateDirectory($@"{_processInfo.GetDirectory()}\Client"); if (!Directory.Exists($@"{_configDir}\KnownPlayers\Backups")) Directory.CreateDirectory($@"{_configDir}\KnownPlayers\Backups"); if (!Directory.Exists($@"{_configDir}\RegisteredPlayers\Backups")) @@ -45,12 +44,44 @@ await Task.Run(() => Directory.CreateDirectory($@"{_configDir}\Backups"); if (File.Exists($@"{_configDir}\..\bedrock_ver.ini")) _loadedVersion = File.ReadAllText($@"{_configDir}\..\bedrock_ver.ini"); + if (!File.Exists(_commsKeyPath)) { + RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048); + using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider()) { + CommsKeyContainer serviceKeys = new CommsKeyContainer(); + CommsKeyContainer clientKeys = new CommsKeyContainer(); + serviceKeys.LocalPrivateKey.SetPrivateKey(rsa.ExportParameters(true)); + clientKeys.RemotePublicKey.SetPublicKey(rsa.ExportParameters(false)); + rsa = new RSACryptoServiceProvider(2048); + clientKeys.LocalPrivateKey.SetPrivateKey(rsa.ExportParameters(true)); + serviceKeys.RemotePublicKey.SetPublicKey(rsa.ExportParameters(false)); + aes.GenerateKey(); + aes.GenerateIV(); + serviceKeys.AesKey = aes.Key; + clientKeys.AesKey = aes.Key; + serviceKeys.AesIV = aes.IV; + clientKeys.AesIV = aes.IV; + formatter.Serialize(File.Create(_clientKeyPath), clientKeys); + formatter.Serialize(File.Create(_commsKeyPath), serviceKeys); + } + rsa.Clear(); + rsa.Dispose(); + } + else { + try { + _keyContainer = (CommsKeyContainer)formatter.Deserialize(File.Open(_commsKeyPath, FileMode.Open)); + _serviceKey = _keyContainer.LocalPrivateKey.GetPrivateKey(); + _clientKey = _keyContainer.RemotePublicKey.GetPrivateKey(); + } + catch { + _logger.AppendLine("Error loading Encryption keys!"); + } + } + ServerInfo serverInfo; LoadGlobals(); _serviceConfiguration.GetServerList().Clear(); string[] files = Directory.GetFiles(_configDir, "*.conf"); - foreach (string file in files) - { + foreach (string file in files) { FileInfo FInfo = new FileInfo(file); string[] fileEntries = File.ReadAllLines(file); serverInfo = new ServerInfo(fileEntries, _serviceConfiguration.GetProp("ServersPath").ToString()); @@ -58,8 +89,7 @@ await Task.Run(() => LoadRegisteredPlayers(serverInfo); _serviceConfiguration.AddNewServerInfo(serverInfo); } - if (_serviceConfiguration.GetServerList().Count == 0) - { + if (_serviceConfiguration.GetServerList().Count == 0) { serverInfo = new ServerInfo(null, _serviceConfiguration.GetProp("ServersPath").ToString()); serverInfo.InitializeDefaults(); SaveServerProps(serverInfo, true); @@ -68,14 +98,12 @@ await Task.Run(() => }); } - public void SaveGlobalFile() - { + public void SaveGlobalFile() { string[] output = new string[_serviceConfiguration.GetAllProps().Count + 3]; int index = 0; output[index++] = "#Globals"; output[index++] = string.Empty; - foreach (Property prop in _serviceConfiguration.GetAllProps()) - { + foreach (Property prop in _serviceConfiguration.GetAllProps()) { output[index++] = $"{prop.KeyName}={prop}"; } output[index++] = string.Empty; @@ -83,36 +111,30 @@ public void SaveGlobalFile() File.WriteAllLines(_globalFile, output); } - public void LoadRegisteredPlayers(IServerConfiguration server) - { + public void LoadRegisteredPlayers(IServerConfiguration server) { string serverName = server.GetServerName(); string filePath = $@"{_configDir}\RegisteredPlayers\{serverName}.preg"; - if (!File.Exists(filePath)) - { + if (!File.Exists(filePath)) { File.Create(filePath).Close(); return; } - foreach (string entry in File.ReadLines(filePath)) - { + foreach (string entry in File.ReadLines(filePath)) { if (entry.StartsWith("#") || string.IsNullOrWhiteSpace(entry)) continue; string[] split = entry.Split(','); _logger.AppendLine($"Server \"{server.GetServerName()}\" Loaded registered player: {split[1]}"); IPlayer playerFound = server.GetPlayerByXuid(split[0]); - if (playerFound == null) - { + if (playerFound == null) { server.AddUpdatePlayer(new Player(split[0], split[1], DateTime.Now.Ticks.ToString(), "0", "0", split[3].ToLower() == "true", split[2], split[4].ToLower() == "true")); continue; } - string[] playerTimes = playerFound.GetTimes(); - server.AddUpdatePlayer(new Player(split[0], split[1], playerTimes[0], playerTimes[1], playerTimes[2], split[3].ToLower() == "true", split[2], split[4].ToLower() == "true")); + var playerTimes = playerFound.GetTimes(); + server.AddUpdatePlayer(new Player(split[0], split[1], playerTimes.First, playerTimes.Conn, playerTimes.Disconn, split[3].ToLower() == "true", split[2], split[4].ToLower() == "true")); } } - private void LoadGlobals() - { - if (File.Exists(_globalFile)) - { + private void LoadGlobals() { + if (File.Exists(_globalFile)) { _logger.AppendLine("Loading Globals..."); _serviceConfiguration.ProcessConfiguration(File.ReadAllLines(_globalFile)); _serviceConfiguration.SetServerVersion(_loadedVersion); @@ -123,44 +145,32 @@ private void LoadGlobals() SaveGlobalFile(); } - private int RoundOff(int i) - { + private int RoundOff(int i) { return ((int)Math.Round(i / 10.0)) * 10; } - public async Task ReplaceServerBuild(IServerConfiguration server) - { - await Task.Run(() => - { - try - { + public async Task ReplaceServerBuild(IServerConfiguration server) { + await Task.Run(() => { + try { if (!Directory.Exists(server.GetProp("ServerPath").ToString())) Directory.CreateDirectory(server.GetProp("ServerPath").ToString()); - while (_serviceConfiguration.GetServerVersion() == null || _serviceConfiguration.GetServerVersion() == "None") - { + while (_serviceConfiguration.GetServerVersion() == null || _serviceConfiguration.GetServerVersion() == "None") { Thread.Sleep(150); } - using (ZipArchive archive = ZipFile.OpenRead($@"{_processInfo.GetDirectory()}\Server\MCSFiles\Update_{ _serviceConfiguration.GetServerVersion()}.zip")) - { + using (ZipArchive archive = ZipFile.OpenRead($@"{_processInfo.GetDirectory()}\Server\MCSFiles\Update_{ _serviceConfiguration.GetServerVersion()}.zip")) { int fileCount = archive.Entries.Count; - for(int i=0; i } File.Copy(server.GetProp("ServerPath").ToString() + "\\bedrock_server.exe", server.GetProp("ServerPath").ToString() + "\\" + server.GetProp("ServerExeName").ToString(), true); } - catch (Exception e) - { + catch (Exception e) { _logger.AppendLine($"ERROR: Got an exception deleting entire directory! {e.Message}"); } }); } - public void LoadPlayerDatabase(IServerConfiguration server) - { + public void LoadPlayerDatabase(IServerConfiguration server) { string filePath = $@"{_configDir}\KnownPlayers\{server.GetServerName()}.playerdb"; - if (!File.Exists(filePath)) - { + if (!File.Exists(filePath)) { File.Create(filePath).Close(); return; } - foreach (string entry in File.ReadLines(filePath)) - { + foreach (string entry in File.ReadLines(filePath)) { if (entry.StartsWith("#") || string.IsNullOrWhiteSpace(entry)) continue; string[] split = entry.Split(','); _logger.AppendLine($"Server \"{server.GetServerName()}\" loaded known player: {split[1]}"); IPlayer playerFound = server.GetPlayerByXuid(split[0]); - if (playerFound == null) - { + if (playerFound == null) { server.AddUpdatePlayer(new Player(split[0], split[1], split[2], split[3], split[4], false, server.GetProp("default-player-permission-level").ToString(), false)); continue; } - string[] playerTimes = playerFound.GetTimes(); - server.AddUpdatePlayer(new Player(split[0], split[1], playerTimes[0], playerTimes[1], playerTimes[2], playerFound.IsPlayerWhitelisted(), playerFound.GetPermissionLevel(), playerFound.PlayerIgnoresLimit())); + var playerTimes = playerFound.GetTimes(); + server.AddUpdatePlayer(new Player(split[0], split[1], playerTimes.First, playerTimes.Conn, playerTimes.Disconn, playerFound.IsPlayerWhitelisted(), playerFound.GetPermissionLevel(), playerFound.PlayerIgnoresLimit())); } } - public void SaveKnownPlayerDatabase(IServerConfiguration server) - { - lock (_fileLock) - { + public void SaveKnownPlayerDatabase(IServerConfiguration server) { + lock (_fileLock) { string filePath = $@"{_configDir}\KnownPlayers\{server.GetServerName()}.playerdb"; - if (File.Exists(filePath)) - { + if (File.Exists(filePath)) { File.Copy(filePath, $@"{_configDir}\KnownPlayers\Backups\{server.GetServerName()}_{DateTime.Now:mmddyyhhmmssff}.dbbak", true); } TextWriter writer = new StreamWriter(filePath); - foreach (Player entry in server.GetPlayerList()) - { + foreach (Player entry in server.GetPlayerList()) { writer.WriteLine(entry.ToString("Known")); } writer.Flush(); writer.Close(); } - lock (_fileLock) - { + lock (_fileLock) { string filePath = $@"{_configDir}\RegisteredPlayers\{server.GetServerName()}.preg"; - if (File.Exists(filePath)) - { + if (File.Exists(filePath)) { File.Copy(filePath, $@"{_configDir}\RegisteredPlayers\Backups\{server.GetServerName()}_{DateTime.Now:mmddyyhhmmssff}.bak", true); } TextWriter writer = new StreamWriter(filePath); @@ -230,8 +229,7 @@ public void SaveKnownPlayerDatabase(IServerConfiguration server) writer.WriteLine("# Register player entries: PlayerEntry=xuid,username,permission,isWhitelisted,ignoreMaxPlayers"); writer.WriteLine("# Example: 1234111222333444,TestUser,visitor,false,false"); writer.WriteLine(""); - foreach (IPlayer player in server.GetPlayerList()) - { + foreach (IPlayer player in server.GetPlayerList()) { if (!player.IsDefaultRegistration()) writer.WriteLine(player.ToString("Registered")); } @@ -240,25 +238,20 @@ public void SaveKnownPlayerDatabase(IServerConfiguration server) } } - public void WriteJSONFiles(IServerConfiguration server) - { + public void WriteJSONFiles(IServerConfiguration server) { StringBuilder sb = new StringBuilder(); sb.Append("[\n"); - foreach (IPlayer player in server.GetPlayerList()) - { - string[] playerReg = player.GetRegistration(); - if (!player.IsDefaultRegistration() && playerReg[0] == "True") - { + foreach (IPlayer player in server.GetPlayerList()) { + if (!player.IsDefaultRegistration() && player.IsPlayerWhitelisted()) { sb.Append("\t{\n"); - sb.Append($"\t\t\"ignoresPlayerLimit\": {playerReg[0].ToLower()},\n"); + sb.Append($"\t\t\"ignoresPlayerLimit\": {player.PlayerIgnoresLimit().ToString().ToLower()},\n"); sb.Append($"\t\t\"name\": \"{player.GetUsername()}\",\n"); sb.Append($"\t\t\"xuid\": \"{player.GetXUID()}\"\n"); sb.Append("\t},\n"); } } - if (sb.Length > 2) - { + if (sb.Length > 2) { sb.Remove(sb.Length - 2, 2); } sb.Append("\n]"); @@ -266,49 +259,39 @@ public void WriteJSONFiles(IServerConfiguration server) sb = new StringBuilder(); sb.Append("[\n"); - foreach (Player player in server.GetPlayerList()) - { - string[] playerReg = player.GetRegistration(); - if (!player.IsDefaultRegistration() && playerReg[0] == "False") - { + foreach (Player player in server.GetPlayerList()) { + if (!player.IsDefaultRegistration()) { sb.Append("\t{\n"); - sb.Append($"\t\t\"permission\": \"{playerReg[1]}\",\n"); + sb.Append($"\t\t\"permission\": \"{player.GetPermissionLevel()}\",\n"); sb.Append($"\t\t\"xuid\": \"{player.GetXUID()}\"\n"); sb.Append("\t},\n"); } } - if (sb.Length > 2) - { + if (sb.Length > 2) { sb.Remove(sb.Length - 2, 2); } sb.Append("\n]"); File.WriteAllText($@"{server.GetProp("ServerPath")}\permissions.json", sb.ToString()); } - public void SaveServerProps(IServerConfiguration server, bool SaveServerInfo) - { + public void SaveServerProps(IServerConfiguration server, bool SaveServerInfo) { int index = 0; string[] output = new string[5 + server.GetAllProps().Count + server.GetStartCommands().Count]; output[index++] = "#Server"; - foreach (Property prop in server.GetAllProps()) - { + foreach (Property prop in server.GetAllProps()) { output[index++] = $"{prop.KeyName}={prop}"; } - if (!SaveServerInfo) - { - if (!Directory.Exists(server.GetProp("ServerPath").ToString())) - { + if (!SaveServerInfo) { + if (!Directory.Exists(server.GetProp("ServerPath").ToString())) { Directory.CreateDirectory(server.GetProp("ServerPath").ToString()); } File.WriteAllLines($@"{server.GetProp("ServerPath")}\server.properties", output); } - else - { + else { output[index++] = string.Empty; output[index++] = "#StartCmds"; - foreach (StartCmdEntry startCmd in server.GetStartCommands()) - { + foreach (StartCmdEntry startCmd in server.GetStartCommands()) { output[index++] = $"AddStartCmd={startCmd.Command}"; } output[index++] = string.Empty; @@ -316,21 +299,17 @@ public void SaveServerProps(IServerConfiguration server, bool SaveServerInfo) File.WriteAllLines($@"{_configDir}\{server.GetFileName()}", output); if (server.GetProp("ServerPath").ToString() == null) server.GetProp("ServerPath").SetValue(server.GetProp("ServerPath").DefaultValue); - if (!Directory.Exists(server.GetProp("ServerPath").ToString())) - { + if (!Directory.Exists(server.GetProp("ServerPath").ToString())) { Directory.CreateDirectory(server.GetProp("ServerPath").ToString()); } File.WriteAllLines($@"{server.GetProp("ServerPath")}\server.properties", output); } } - public void RemoveServerConfigs(IServerConfiguration serverInfo, NetworkMessageFlags flag) - { - try - { + public void RemoveServerConfigs(IServerConfiguration serverInfo, NetworkMessageFlags flag) { + try { File.Delete($@"{_configDir}\{serverInfo.GetFileName()}"); - switch (flag) - { + switch (flag) { case NetworkMessageFlags.RemoveBckPly: if (DeleteBackups(serverInfo)) _logger.AppendLine($"Deleted Backups for server {serverInfo.GetServerName()}"); @@ -378,62 +357,48 @@ public void RemoveServerConfigs(IServerConfiguration serverInfo, NetworkMessageF catch { } } - public List EnumerateBackupsForServer(byte serverIndex) - { + public List EnumerateBackupsForServer(byte serverIndex) { string serverName = _serviceConfiguration.GetServerInfoByIndex(serverIndex).GetServerName(); List newList = new List(); - try - { - foreach (DirectoryInfo dir in new DirectoryInfo($@"{_serviceConfiguration.GetProp("BackupPath")}\{serverName}").GetDirectories()) - { + try { + foreach (DirectoryInfo dir in new DirectoryInfo($@"{_serviceConfiguration.GetProp("BackupPath")}\{serverName}").GetDirectories()) { string[] splitName = dir.Name.Split('_'); newList.Add(new Property(dir.Name, new DateTime(long.Parse(splitName[1])).ToString("G"))); } } - catch (IOException) - { + catch (IOException) { return newList; } return newList; } - public void DeleteBackupsForServer(byte serverIndex, List list) - { + public void DeleteBackupsForServer(byte serverIndex, List list) { string serverName = _serviceConfiguration.GetServerInfoByIndex(serverIndex).GetServerName(); - try - { + try { foreach (string deleteDir in list) foreach (DirectoryInfo dir in new DirectoryInfo($@"{_serviceConfiguration.GetProp("BackupPath")}\{serverName}").GetDirectories()) - if (dir.Name == deleteDir) - { + if (dir.Name == deleteDir) { new FileUtils(_processInfo.GetDirectory()).DeleteFilesRecursively(new DirectoryInfo($@"{_serviceConfiguration.GetProp("BackupPath")}\{serverName}\{deleteDir}"), true); _logger.AppendLine($"Deleted backup {deleteDir}."); } } - catch (IOException e) - { + catch (IOException e) { _logger.AppendLine($"Error deleting selected backups! {e.Message}"); } } - private bool DeleteBackups(IServerConfiguration serverInfo) - { - try - { + private bool DeleteBackups(IServerConfiguration serverInfo) { + try { string configBackupPath = ""; DirectoryInfo backupDirInfo = new DirectoryInfo($@"{configBackupPath}\{serverInfo.GetServerName()}"); DirectoryInfo configBackupDirInfo = new DirectoryInfo($@"{_configDir}\Backups"); - foreach (DirectoryInfo dir in backupDirInfo.GetDirectories()) - { - if (dir.Name.Contains($"{serverInfo.GetServerName()}")) - { + foreach (DirectoryInfo dir in backupDirInfo.GetDirectories()) { + if (dir.Name.Contains($"{serverInfo.GetServerName()}")) { dir.Delete(true); } } - foreach (FileInfo file in configBackupDirInfo.GetFiles()) - { - if (file.Name.Contains($"{serverInfo.GetServerName()}_")) - { + foreach (FileInfo file in configBackupDirInfo.GetFiles()) { + if (file.Name.Contains($"{serverInfo.GetServerName()}_")) { file.Delete(); } } @@ -442,29 +407,21 @@ private bool DeleteBackups(IServerConfiguration serverInfo) catch { return false; } } - private bool DeleteServerFiles(IServerConfiguration serverInfo) - { - try - { + private bool DeleteServerFiles(IServerConfiguration serverInfo) { + try { new FileUtils(_processInfo.GetDirectory()).DeleteFilesRecursively(new DirectoryInfo(serverInfo.GetProp("ServerPath").ToString()), false); return true; } catch { return false; } } - private bool DeletePlayerFiles(IServerConfiguration serverInfo) - { - try - { + private bool DeletePlayerFiles(IServerConfiguration serverInfo) { + try { DirectoryInfo configDirInfo = new DirectoryInfo(_configDir); - foreach (DirectoryInfo dir in configDirInfo.GetDirectories()) - { - if (dir.Name == "KnownPlayers" || dir.Name == "RegisteredPlayers") - { - foreach (FileInfo file in dir.GetFiles()) - { - if (file.Name.Contains($"{serverInfo.GetServerName()}")) - { + foreach (DirectoryInfo dir in configDirInfo.GetDirectories()) { + if (dir.Name == "KnownPlayers" || dir.Name == "RegisteredPlayers") { + foreach (FileInfo file in dir.GetFiles()) { + if (file.Name.Contains($"{serverInfo.GetServerName()}")) { file.Delete(); } } @@ -475,13 +432,13 @@ private bool DeletePlayerFiles(IServerConfiguration serverInfo) catch { return false; } } - public Task LoadConfiguration(IConfiguration configuration) - { + public CommsKeyContainer GetKeyContainer() => _keyContainer; + + public Task LoadConfiguration(IBedrockConfiguration configuration) { throw new NotImplementedException(); } - public Task SaveConfiguration(IConfiguration configuration) - { + public Task SaveConfiguration(IBedrockConfiguration configuration) { throw new NotImplementedException(); } } diff --git a/BedrockService/Service/Management/IConfigurator.cs b/BedrockService/Service/Management/IConfigurator.cs index a547140f..28d5c7cd 100644 --- a/BedrockService/Service/Management/IConfigurator.cs +++ b/BedrockService/Service/Management/IConfigurator.cs @@ -1,25 +1,18 @@ -using BedrockService.Service.Server; -using BedrockService.Shared.Classes; -using BedrockService.Shared.Interfaces; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace BedrockService.Service.Management -{ - public interface IConfigurator - { +namespace BedrockService.Service.Management { + public interface IConfigurator { void DeleteBackupsForServer(byte serverIndex, List list); List EnumerateBackupsForServer(byte serverIndex); Task LoadAllConfigurations(); - Task LoadConfiguration(IConfiguration configuration); + Task LoadConfiguration(IBedrockConfiguration configuration); void LoadPlayerDatabase(IServerConfiguration server); void LoadRegisteredPlayers(IServerConfiguration server); void RemoveServerConfigs(IServerConfiguration serverInfo, NetworkMessageFlags flag); Task ReplaceServerBuild(IServerConfiguration server); - Task SaveConfiguration(IConfiguration configuration); + Task SaveConfiguration(IBedrockConfiguration configuration); void SaveGlobalFile(); void SaveKnownPlayerDatabase(IServerConfiguration server); void SaveServerProps(IServerConfiguration server, bool SaveServerInfo); void WriteJSONFiles(IServerConfiguration server); + CommsKeyContainer GetKeyContainer(); } } \ No newline at end of file diff --git a/BedrockService/Service/Networking/ITCPListener.cs b/BedrockService/Service/Networking/ITCPListener.cs index b2af7c6c..173edf42 100644 --- a/BedrockService/Service/Networking/ITCPListener.cs +++ b/BedrockService/Service/Networking/ITCPListener.cs @@ -1,15 +1,13 @@ -using BedrockService.Service.Networking.NetworkMessageClasses; -using BedrockService.Shared.Classes; -using System.Collections.Generic; +using BedrockService.Service.Networking.MessageInterfaces; -namespace BedrockService.Service.Networking -{ - public interface ITCPListener : IMessageSender - { - void StartListening(); +namespace BedrockService.Service.Networking { + public interface ITCPListener : IMessageSender { + Task StartListening(); void ResetListener(); void SetStrategyDictionaries(Dictionary standard, Dictionary flagged); + + void SetKeyContainer(CommsKeyContainer keyContainer); } } diff --git a/BedrockService/Service/Networking/IUpdater.cs b/BedrockService/Service/Networking/IUpdater.cs index e436d0d4..8653d1a2 100644 --- a/BedrockService/Service/Networking/IUpdater.cs +++ b/BedrockService/Service/Networking/IUpdater.cs @@ -1,10 +1,5 @@ -using BedrockService.Shared.Interfaces; -using System.Threading.Tasks; - -namespace BedrockService.Service.Networking -{ - public interface IUpdater - { +namespace BedrockService.Service.Networking { + public interface IUpdater { Task CheckUpdates(); Task FetchBuild(string path, string version); bool CheckVersionChanged(); diff --git a/BedrockService/Service/Networking/MessageInterfaces/IFlaggedMessageParser.cs b/BedrockService/Service/Networking/MessageInterfaces/IFlaggedMessageParser.cs index 83833ec2..715b1347 100644 --- a/BedrockService/Service/Networking/MessageInterfaces/IFlaggedMessageParser.cs +++ b/BedrockService/Service/Networking/MessageInterfaces/IFlaggedMessageParser.cs @@ -1,9 +1,5 @@ -using BedrockService.Shared.Classes; - -namespace BedrockService.Service.Networking.NetworkMessageClasses -{ - public interface IFlaggedMessageParser - { +namespace BedrockService.Service.Networking.MessageInterfaces { + public interface IFlaggedMessageParser { void ParseMessage(byte[] data, byte serverIndex, NetworkMessageFlags flag); } } diff --git a/BedrockService/Service/Networking/MessageInterfaces/IMessageParser.cs b/BedrockService/Service/Networking/MessageInterfaces/IMessageParser.cs index 22b39d28..23218552 100644 --- a/BedrockService/Service/Networking/MessageInterfaces/IMessageParser.cs +++ b/BedrockService/Service/Networking/MessageInterfaces/IMessageParser.cs @@ -1,7 +1,5 @@ -namespace BedrockService.Service.Networking.NetworkMessageClasses -{ - public interface IMessageParser - { +namespace BedrockService.Service.Networking.MessageInterfaces { + public interface IMessageParser { void ParseMessage(byte[] data, byte serverIndex); } } diff --git a/BedrockService/Service/Networking/MessageInterfaces/IMessageSender.cs b/BedrockService/Service/Networking/MessageInterfaces/IMessageSender.cs index 1d7aaf13..10653abb 100644 --- a/BedrockService/Service/Networking/MessageInterfaces/IMessageSender.cs +++ b/BedrockService/Service/Networking/MessageInterfaces/IMessageSender.cs @@ -1,9 +1,5 @@ -using BedrockService.Shared.Classes; - -namespace BedrockService.Service.Networking.NetworkMessageClasses -{ - public interface IMessageSender - { +namespace BedrockService.Service.Networking.MessageInterfaces { + public interface IMessageSender { void SendData(byte[] bytes, NetworkMessageSource source, NetworkMessageDestination destination, byte serverIndex, NetworkMessageTypes type, NetworkMessageFlags status); void SendData(NetworkMessageSource source, NetworkMessageDestination destination, NetworkMessageTypes type); diff --git a/BedrockService/Service/Networking/NetworkStrategyLookup.cs b/BedrockService/Service/Networking/NetworkStrategyLookup.cs index 75bb3577..6ddbdbd1 100644 --- a/BedrockService/Service/Networking/NetworkStrategyLookup.cs +++ b/BedrockService/Service/Networking/NetworkStrategyLookup.cs @@ -1,30 +1,19 @@ -using BedrockService.Service.Core; -using BedrockService.Service.Management; -using BedrockService.Service.Networking.NetworkMessageClasses; +using BedrockService.Service.Core.Interfaces; +using BedrockService.Service.Networking.MessageInterfaces; using BedrockService.Service.Server; -using BedrockService.Shared.Classes; -using BedrockService.Shared.Interfaces; +using BedrockService.Shared.MincraftJson; using BedrockService.Shared.PackParser; using BedrockService.Shared.Utilities; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; using System.Text; -using System.Threading; -using System.Threading.Tasks; -namespace BedrockService.Service.Networking -{ - public class NetworkStrategyLookup - { +namespace BedrockService.Service.Networking { + public class NetworkStrategyLookup { private readonly Dictionary _standardMessageLookup; private readonly Dictionary _flaggedMessageLookup; - public NetworkStrategyLookup(ITCPListener messageSender, IBedrockService service, ILogger logger, IConfigurator configurator, IServiceConfiguration serviceConfiguration, IProcessInfo processInfo, IUpdater updater) - { + public NetworkStrategyLookup(ITCPListener messageSender, IBedrockService service, IBedrockLogger logger, IConfigurator configurator, IServiceConfiguration serviceConfiguration, IProcessInfo processInfo, IUpdater updater) { _standardMessageLookup = new Dictionary() { {NetworkMessageTypes.DelBackups, new DeleteBackups(configurator) }, @@ -35,8 +24,8 @@ public NetworkStrategyLookup(ITCPListener messageSender, IBedrockService service {NetworkMessageTypes.Restart, new ServerRestart(messageSender, service) }, {NetworkMessageTypes.Command, new ServerCommand(messageSender, service, logger) }, {NetworkMessageTypes.PackList, new PackList(messageSender, processInfo, serviceConfiguration, logger) }, - {NetworkMessageTypes.RemovePack, new RemovePack(messageSender, processInfo, serviceConfiguration) }, - {NetworkMessageTypes.PackFile, new PackFile(serviceConfiguration, processInfo, logger) }, + {NetworkMessageTypes.RemovePack, new RemovePack(messageSender, processInfo, serviceConfiguration, logger) }, + {NetworkMessageTypes.PackFile, new PackFile(messageSender, serviceConfiguration, processInfo, logger) }, {NetworkMessageTypes.Connect, new Connect(messageSender, serviceConfiguration) }, {NetworkMessageTypes.StartCmdUpdate, new StartCmdUpdate(configurator, serviceConfiguration) }, {NetworkMessageTypes.CheckUpdates, new CheckUpdates(messageSender, updater) }, @@ -52,22 +41,20 @@ public NetworkStrategyLookup(ITCPListener messageSender, IBedrockService service { {NetworkMessageTypes.RemoveServer, new RemoveServer(configurator, messageSender, serviceConfiguration, service) }, }; - messageSender.SetStrategyDictionaries(_standardMessageLookup, _flaggedMessageLookup); + if (processInfo.ShouldStartService()) { + messageSender.SetStrategyDictionaries(_standardMessageLookup, _flaggedMessageLookup); + } } - class DeleteBackups : IMessageParser - { + class DeleteBackups : IMessageParser { private readonly IConfigurator _configurator; - public DeleteBackups(IConfigurator configurator) - { + public DeleteBackups(IConfigurator configurator) { _configurator = configurator; } - public void ParseMessage(byte[] data, byte serverIndex) - { - JsonSerializerSettings settings = new JsonSerializerSettings() - { + public void ParseMessage(byte[] data, byte serverIndex) { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; string stringData = Encoding.UTF8.GetString(data, 5, data.Length - 5); @@ -76,57 +63,47 @@ public void ParseMessage(byte[] data, byte serverIndex) } } - class ServerBackupAll : IMessageParser - { + class ServerBackupAll : IMessageParser { private readonly IMessageSender _messageSender; private readonly IBedrockService _service; - public ServerBackupAll(IMessageSender messageSender, IBedrockService service) - { + public ServerBackupAll(IMessageSender messageSender, IBedrockService service) { _messageSender = messageSender; _service = service; } - public void ParseMessage(byte[] data, byte serverIndex) - { + public void ParseMessage(byte[] data, byte serverIndex) { foreach (IBedrockServer server in _service.GetAllServers()) server.RestartServer(true); _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.UICallback); } } - class ServerBackup : IMessageParser - { + class ServerBackup : IMessageParser { private readonly IMessageSender _messageSender; private readonly IBedrockService _service; - public ServerBackup(IMessageSender messageSender, IBedrockService service) - { + public ServerBackup(IMessageSender messageSender, IBedrockService service) { _messageSender = messageSender; _service = service; } - public void ParseMessage(byte[] data, byte serverIndex) - { - _service.GetBedrockServerByIndex(serverIndex).RestartServer(true); + public void ParseMessage(byte[] data, byte serverIndex) { + _service.GetBedrockServerByIndex(serverIndex).InitializeBackup(); _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.UICallback); } } - class EnumBackups : IMessageParser - { + class EnumBackups : IMessageParser { private readonly IConfigurator _configurator; private readonly IMessageSender _messageSender; - public EnumBackups(IConfigurator configurator, IMessageSender messageSender) - { + public EnumBackups(IConfigurator configurator, IMessageSender messageSender) { _configurator = configurator; _messageSender = messageSender; } - public void ParseMessage(byte[] data, byte serverIndex) - { + public void ParseMessage(byte[] data, byte serverIndex) { Formatting indented = Formatting.Indented; - JsonSerializerSettings settings = new JsonSerializerSettings() - { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(_configurator.EnumerateBackupsForServer(serverIndex), indented, settings)); @@ -135,32 +112,27 @@ public void ParseMessage(byte[] data, byte serverIndex) } } - class ServerPropUpdate : IMessageParser - { + class ServerPropUpdate : IMessageParser { private readonly IServiceConfiguration _serviceConfiguration; private readonly IMessageSender _messageSender; private readonly IBedrockService _bedrockService; private readonly IConfigurator _configurator; - public ServerPropUpdate(IConfigurator configurator, IServiceConfiguration serviceConfiguration, IMessageSender messageSender, IBedrockService bedrockService) - { + public ServerPropUpdate(IConfigurator configurator, IServiceConfiguration serviceConfiguration, IMessageSender messageSender, IBedrockService bedrockService) { _configurator = configurator; _serviceConfiguration = serviceConfiguration; _messageSender = messageSender; _bedrockService = bedrockService; } - public void ParseMessage(byte[] data, byte serverIndex) - { - JsonSerializerSettings settings = new JsonSerializerSettings() - { + public void ParseMessage(byte[] data, byte serverIndex) { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; string stringData = Encoding.UTF8.GetString(data, 5, data.Length - 5); List propList = JsonConvert.DeserializeObject>(stringData, settings); Property prop = propList.FirstOrDefault(p => p.KeyName == "server-name"); - if(prop == null) - { + if (prop == null) { _serviceConfiguration.SetAllProps(propList); _configurator.SaveGlobalFile(); _bedrockService.RestartService(); @@ -168,9 +140,9 @@ public void ParseMessage(byte[] data, byte serverIndex) return; } _serviceConfiguration.GetServerInfoByIndex(serverIndex).SetAllProps(propList); + _configurator.SaveServerProps(_serviceConfiguration.GetServerInfoByIndex(serverIndex), true); _bedrockService.GetBedrockServerByIndex(serverIndex).SetServerStatus(BedrockServer.ServerStatus.Stopping); - while (_bedrockService.GetBedrockServerByIndex(serverIndex).GetServerStatus() == BedrockServer.ServerStatus.Stopping) - { + while (_bedrockService.GetBedrockServerByIndex(serverIndex).GetServerStatus() == BedrockServer.ServerStatus.Stopping) { Thread.Sleep(100); } _bedrockService.GetBedrockServerByIndex(serverIndex).SetServerStatus(BedrockServer.ServerStatus.Starting); @@ -178,38 +150,32 @@ public void ParseMessage(byte[] data, byte serverIndex) } } - class ServerRestart : IMessageParser - { + class ServerRestart : IMessageParser { private readonly IMessageSender _messageSender; private readonly IBedrockService _service; - public ServerRestart(IMessageSender messageSender, IBedrockService service) - { + public ServerRestart(IMessageSender messageSender, IBedrockService service) { _messageSender = messageSender; _service = service; } - public void ParseMessage(byte[] data, byte serverIndex) - { + public void ParseMessage(byte[] data, byte serverIndex) { _service.GetBedrockServerByIndex(serverIndex).RestartServer(false); _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.UICallback); } } - class ServerCommand : IMessageParser - { + class ServerCommand : IMessageParser { private readonly IBedrockService _service; - private readonly ILogger _logger; + private readonly IBedrockLogger _logger; private readonly IMessageSender _messageSender; - public ServerCommand(IMessageSender messageSender, IBedrockService service, ILogger logger) - { + public ServerCommand(IMessageSender messageSender, IBedrockService service, IBedrockLogger logger) { _messageSender = messageSender; _service = service; _logger = logger; } - public void ParseMessage(byte[] data, byte serverIndex) - { + public void ParseMessage(byte[] data, byte serverIndex) { string stringData = Encoding.UTF8.GetString(data, 5, data.Length - 5); _service.GetBedrockServerByIndex(serverIndex).WriteToStandardIn(stringData); _logger.AppendLine($"Sent command {stringData} to stdInput stream"); @@ -217,79 +183,70 @@ public void ParseMessage(byte[] data, byte serverIndex) } } - class PackList : IMessageParser - { + class PackList : IMessageParser { private readonly IMessageSender _messageSender; private readonly IServiceConfiguration _serviceConfiguration; private readonly IProcessInfo _processInfo; - private readonly ILogger _logger; + private readonly IBedrockLogger _logger; - public PackList(IMessageSender messageSender, IProcessInfo processInfo, IServiceConfiguration serviceConfiguration, ILogger logger) - { + public PackList(IMessageSender messageSender, IProcessInfo processInfo, IServiceConfiguration serviceConfiguration, IBedrockLogger logger) { _logger = logger; _messageSender = messageSender; _serviceConfiguration = serviceConfiguration; _processInfo = processInfo; } - public void ParseMessage(byte[] data, byte serverIndex) - { + public void ParseMessage(byte[] data, byte serverIndex) { if (!File.Exists($@"{_processInfo.GetDirectory()}\Server\stock_packs.json")) File.Copy($@"{_serviceConfiguration.GetServerInfoByIndex(serverIndex).GetProp("ServerPath")}\valid_known_packs.json", $@"{_processInfo.GetDirectory()}\Server\stock_packs.json"); MinecraftKnownPacksClass knownPacks = new MinecraftKnownPacksClass($@"{_serviceConfiguration.GetServerInfoByIndex(serverIndex).GetProp("ServerPath")}\valid_known_packs.json", $@"{_processInfo.GetDirectory()}\Server\stock_packs.json"); - List list = new List(); - foreach (MinecraftKnownPacksClass.KnownPack pack in knownPacks.KnownPacks) - { + List list = new List(); + foreach (MinecraftKnownPacksClass.KnownPack pack in knownPacks.KnownPacks) { MinecraftPackParser currentParser = new MinecraftPackParser(_logger, _processInfo); - currentParser.ParseDirectory(new DirectoryInfo($@"{_serviceConfiguration.GetServerInfoByIndex(serverIndex).GetProp("ServerPath")}\{pack.path.Replace(@"/", @"\")}")); - list.Add(currentParser); + currentParser.ParseDirectory($@"{_serviceConfiguration.GetServerInfoByIndex(serverIndex).GetProp("ServerPath")}\{pack.path.Replace(@"/", @"\")}"); + list.AddRange(currentParser.FoundPacks); } string arrayString = JArray.FromObject(list).ToString(); _messageSender.SendData(Encoding.UTF8.GetBytes(arrayString), NetworkMessageSource.Server, NetworkMessageDestination.Client, NetworkMessageTypes.PackList); } } - class RemovePack : IMessageParser - { + class RemovePack : IMessageParser { private readonly IMessageSender _messageSender; private readonly IServiceConfiguration _serviceConfiguration; private readonly IProcessInfo _processInfo; + private readonly IBedrockLogger _logger; - public RemovePack(IMessageSender messageSender, IProcessInfo processInfo, IServiceConfiguration serviceConfiguration) - { + public RemovePack(IMessageSender messageSender, IProcessInfo processInfo, IServiceConfiguration serviceConfiguration, IBedrockLogger logger) { _messageSender = messageSender; _serviceConfiguration = serviceConfiguration; _processInfo = processInfo; + _logger = logger; } - public void ParseMessage(byte[] data, byte serverIndex) - { + public void ParseMessage(byte[] data, byte serverIndex) { string stringData = Encoding.UTF8.GetString(data, 5, data.Length - 5); MinecraftKnownPacksClass knownPacks = new MinecraftKnownPacksClass($@"{_serviceConfiguration.GetServerInfoByIndex(serverIndex).GetProp("ServerPath")}\valid_known_packs.json", $@"{_processInfo.GetDirectory()}\Server\stock_packs.json"); - JsonSerializerSettings settings = new JsonSerializerSettings() - { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; - List MCContainer = JsonConvert.DeserializeObject>(stringData, settings); - foreach (MinecraftPackContainer cont in MCContainer) - knownPacks.RemovePackFromServer(_serviceConfiguration.GetServerInfoByIndex(serverIndex).GetProp("ServerPath").ToString(), cont); + List container = JsonConvert.DeserializeObject>(stringData, settings); + foreach (MinecraftPackContainer content in container) + knownPacks.RemovePackFromServer(_serviceConfiguration.GetServerInfoByIndex(serverIndex).GetProp("ServerPath").ToString(), content); _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.UICallback); } } - class LevelEditRequest : IMessageParser - { + class LevelEditRequest : IMessageParser { private readonly IMessageSender _messageSender; private readonly IServiceConfiguration _serviceConfiguration; - public LevelEditRequest(IMessageSender messageSender, IServiceConfiguration serviceConfiguration) - { + public LevelEditRequest(IMessageSender messageSender, IServiceConfiguration serviceConfiguration) { _messageSender = messageSender; _serviceConfiguration = serviceConfiguration; } - public void ParseMessage(byte[] data, byte serverIndex) - { + public void ParseMessage(byte[] data, byte serverIndex) { IServerConfiguration server = _serviceConfiguration.GetServerInfoByIndex(serverIndex); string pathToLevelDat = $@"{_serviceConfiguration.GetServerInfoByIndex(serverIndex).GetProp("ServerPath")}\worlds\{server.GetProp("level-name")}\level.dat"; byte[] levelDatToBytes = File.ReadAllBytes(pathToLevelDat); @@ -297,37 +254,30 @@ public void ParseMessage(byte[] data, byte serverIndex) } } - class PlayersUpdate : IMessageParser - { + class PlayersUpdate : IMessageParser { private readonly IMessageSender _messageSender; private readonly IServiceConfiguration _serviceConfiguration; private readonly IConfigurator _configurator; private readonly IBedrockService _service; - public PlayersUpdate(IConfigurator configurator, IMessageSender messageSender, IServiceConfiguration serviceConfiguration, IBedrockService service) - { + public PlayersUpdate(IConfigurator configurator, IMessageSender messageSender, IServiceConfiguration serviceConfiguration, IBedrockService service) { _service = service; _configurator = configurator; _messageSender = messageSender; _serviceConfiguration = serviceConfiguration; } - public void ParseMessage(byte[] data, byte serverIndex) - { + public void ParseMessage(byte[] data, byte serverIndex) { string stringData = Encoding.UTF8.GetString(data, 5, data.Length - 5); - JsonSerializerSettings settings = new JsonSerializerSettings() - { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; List fetchedPlayers = JsonConvert.DeserializeObject>(stringData, settings); - foreach (IPlayer player in fetchedPlayers) - { - try - { + foreach (IPlayer player in fetchedPlayers) { + try { _serviceConfiguration.GetServerInfoByIndex(serverIndex).AddUpdatePlayer(player); } - catch (Exception) - { + catch (Exception) { } } _configurator.SaveKnownPlayerDatabase(_serviceConfiguration.GetServerInfoByIndex(serverIndex)); @@ -336,124 +286,122 @@ public void ParseMessage(byte[] data, byte serverIndex) _service.GetBedrockServerByIndex(serverIndex).WriteToStandardIn("ops reload"); _service.GetBedrockServerByIndex(serverIndex).WriteToStandardIn("whitelist reload"); _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.UICallback); - } } - class PackFile : IMessageParser - { + class PackFile : IMessageParser { + private readonly IMessageSender _messageSender; private readonly IServiceConfiguration _serviceConfiguration; private readonly IProcessInfo _serviceProcessInfo; - private readonly ILogger _logger; + private readonly IBedrockLogger _logger; - public PackFile(IServiceConfiguration serviceConfiguration, IProcessInfo serviceProcessInfo, ILogger logger) - { + public PackFile(IMessageSender messageSender, IServiceConfiguration serviceConfiguration, IProcessInfo serviceProcessInfo, IBedrockLogger logger) { + _messageSender = messageSender; _logger = logger; _serviceProcessInfo = serviceProcessInfo; _serviceConfiguration = serviceConfiguration; } - public void ParseMessage(byte[] data, byte serverIndex) - { + public void ParseMessage(byte[] data, byte serverIndex) { MinecraftPackParser archiveParser = new MinecraftPackParser(data, _logger, _serviceProcessInfo); - foreach (MinecraftPackContainer container in archiveParser.FoundPacks) - { + foreach (MinecraftPackContainer container in archiveParser.FoundPacks) { string serverPath = _serviceConfiguration.GetServerInfoByIndex(serverIndex).GetProp("ServerPath").ToString(); - if (container.ManifestType == "WorldPack") - new FileUtils(_serviceProcessInfo.GetDirectory()).CopyFilesRecursively(container.PackContentLocation, new DirectoryInfo($@"{serverPath}\worlds\{container.FolderName}")); - if (container.ManifestType == "data") - new FileUtils(_serviceProcessInfo.GetDirectory()).CopyFilesRecursively(container.PackContentLocation, new DirectoryInfo($@"{serverPath}\behavior_packs\{container.FolderName}")); - if (container.ManifestType == "resources") - new FileUtils(_serviceProcessInfo.GetDirectory()).CopyFilesRecursively(container.PackContentLocation, new DirectoryInfo($@"{serverPath}\resource_packs\{container.FolderName}")); + string levelName = _serviceConfiguration.GetServerInfoByIndex(serverIndex).GetProp("level-name").ToString(); + string filePath = null; + FileUtils fileUtils = new FileUtils(_serviceProcessInfo.GetDirectory()); + if (container.ManifestType == "WorldPack") { + fileUtils.CopyFilesRecursively(new DirectoryInfo(container.PackContentLocation), new DirectoryInfo($@"{serverPath}\worlds\{container.FolderName}")); + } + if (container.ManifestType == "data") { + fileUtils.CopyFilesRecursively(new DirectoryInfo(container.PackContentLocation), new DirectoryInfo($@"{serverPath}\behavior_packs\{container.FolderName}")); + filePath = $@"{serverPath}\worlds\{levelName}\world_behavior_packs.json"; + } + if (container.ManifestType == "resources") { + fileUtils.CopyFilesRecursively(new DirectoryInfo(container.PackContentLocation), new DirectoryInfo($@"{serverPath}\resource_packs\{container.FolderName}")); + filePath = $@"{serverPath}\worlds\{levelName}\world_resource_packs.json"; + } + if (filePath != null) { + WorldPacksJsonModel worldPackManifentClass = new WorldPacksJsonModel(container.JsonManifest.header.uuid, container.JsonManifest.header.version); + List list = new List(); + list.Add(worldPackManifentClass); + fileUtils.UpdateJArrayFile(filePath, JArray.FromObject(list), typeof(WorldPacksJsonModel)); + _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.UICallback); + } } } } - class LevelEditFile : IMessageParser - { + class LevelEditFile : IMessageParser { private readonly IServiceConfiguration _serviceConfiguration; private readonly IBedrockService _bedrockService; - public LevelEditFile(IServiceConfiguration serviceConfiguration, IBedrockService bedrockService) - { + public LevelEditFile(IServiceConfiguration serviceConfiguration, IBedrockService bedrockService) { _bedrockService = bedrockService; _serviceConfiguration = serviceConfiguration; } - public void ParseMessage(byte[] data, byte serverIndex) - { + public void ParseMessage(byte[] data, byte serverIndex) { byte[] stripHeaderFromBuffer = new byte[data.Length - 5]; Buffer.BlockCopy(data, 5, stripHeaderFromBuffer, 0, stripHeaderFromBuffer.Length); IServerConfiguration server = _serviceConfiguration.GetServerInfoByIndex(serverIndex); string pathToLevelDat = $@"{_serviceConfiguration.GetProp("ServersPath")}\{server.GetProp("server-name")}\worlds\{server.GetProp("level-name")}\level.dat"; - _bedrockService.GetBedrockServerByIndex(serverIndex).StopServer().Wait(); + _bedrockService.GetBedrockServerByIndex(serverIndex).StopServer(false).Wait(); File.WriteAllBytes(pathToLevelDat, stripHeaderFromBuffer); _bedrockService.GetBedrockServerByIndex(serverIndex).SetServerStatus(BedrockServer.ServerStatus.Starting); } } - class Connect : IMessageParser - { - private readonly IMessageSender _messageSender; + class Connect : IMessageParser { + private readonly IMessageSender _iTCPListener; private readonly IServiceConfiguration _serviceConfiguration; - public Connect(IMessageSender messageSender, IServiceConfiguration serviceConfiguration) - { - _messageSender = messageSender; + public Connect(ITCPListener iTCPListener, IServiceConfiguration serviceConfiguration) { + _iTCPListener = iTCPListener; _serviceConfiguration = serviceConfiguration; } - public void ParseMessage(byte[] data, byte serverIndex) - { + public void ParseMessage(byte[] data, byte serverIndex) { Formatting indented = Formatting.Indented; - JsonSerializerSettings settings = new JsonSerializerSettings() - { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; string jsonString = JsonConvert.SerializeObject(_serviceConfiguration, indented, settings); byte[] serializeToBytes = Encoding.UTF8.GetBytes(jsonString); - _messageSender.SendData(serializeToBytes, NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.Connect); + _iTCPListener.SendData(serializeToBytes, NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.Connect); } } - class StartCmdUpdate : IMessageParser - { + class StartCmdUpdate : IMessageParser { private readonly IServiceConfiguration _serviceConfiguration; private readonly IConfigurator _configurator; - public StartCmdUpdate(IConfigurator configurator, IServiceConfiguration serviceConfiguration) - { + public StartCmdUpdate(IConfigurator configurator, IServiceConfiguration serviceConfiguration) { _configurator = configurator; _serviceConfiguration = serviceConfiguration; } - public void ParseMessage(byte[] data, byte serverIndex) - { - JsonSerializerSettings settings = new JsonSerializerSettings() - { + public void ParseMessage(byte[] data, byte serverIndex) { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; - _serviceConfiguration.GetServerInfoByIndex(serverIndex).SetStartCommands(JsonConvert.DeserializeObject>(Encoding.UTF8.GetString(data, 5, data.Length - 5), settings)); + List entries = JsonConvert.DeserializeObject>(Encoding.UTF8.GetString(data, 5, data.Length - 5), settings); + _serviceConfiguration.GetServerInfoByIndex(serverIndex).SetStartCommands(entries); _configurator.SaveServerProps(_serviceConfiguration.GetServerInfoByIndex(serverIndex), true); } } - class CheckUpdates : IMessageParser - { + class CheckUpdates : IMessageParser { private readonly IMessageSender _messageSender; private readonly IUpdater _updater; - public CheckUpdates(IMessageSender messageSender, IUpdater updater) - { + public CheckUpdates(IMessageSender messageSender, IUpdater updater) { _updater = updater; _messageSender = messageSender; } - public void ParseMessage(byte[] data, byte serverIndex) - { + public void ParseMessage(byte[] data, byte serverIndex) { _updater.CheckUpdates().Wait(); - if (_updater.CheckVersionChanged()) - { + if (_updater.CheckVersionChanged()) { _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.CheckUpdates); } @@ -461,59 +409,49 @@ public void ParseMessage(byte[] data, byte serverIndex) } } - class BackupRollback : IMessageParser - { + class BackupRollback : IMessageParser { private readonly IMessageSender _messageSender; private readonly IBedrockService _service; - public BackupRollback(IMessageSender messageSender, IBedrockService service) - { + public BackupRollback(IMessageSender messageSender, IBedrockService service) { _service = service; _messageSender = messageSender; } - public void ParseMessage(byte[] data, byte serverIndex) - { + public void ParseMessage(byte[] data, byte serverIndex) { string stringData = Encoding.UTF8.GetString(data, 5, data.Length - 5); _service.GetBedrockServerByIndex(serverIndex).RollbackToBackup(serverIndex, stringData); _messageSender.SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.UICallback); } } - class AddNewServer : IMessageParser - { + class AddNewServer : IMessageParser { private readonly IMessageSender _messageSender; private readonly IServiceConfiguration _serviceConfiguration; private readonly IConfigurator _configurator; private readonly IBedrockService _bedrockService; - - public AddNewServer(IConfigurator configurator, IMessageSender messageSender, IServiceConfiguration serviceConfiguration, IBedrockService bedrockService) - { + + public AddNewServer(IConfigurator configurator, IMessageSender messageSender, IServiceConfiguration serviceConfiguration, IBedrockService bedrockService) { _bedrockService = bedrockService; _configurator = configurator; _messageSender = messageSender; _serviceConfiguration = serviceConfiguration; } - public void ParseMessage(byte[] data, byte serverIndex) - { + public void ParseMessage(byte[] data, byte serverIndex) { string stringData = Encoding.UTF8.GetString(data, 5, data.Length - 5); - JsonSerializerSettings settings = new JsonSerializerSettings() - { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; List propList = JsonConvert.DeserializeObject>(stringData, settings); Property serverNameProp = propList.First(p => p.KeyName == "server-name"); - ServerInfo newServer = new ServerInfo(null, _serviceConfiguration.GetProp("ServersPath").ToString()) - { + ServerInfo newServer = new ServerInfo(null, _serviceConfiguration.GetProp("ServersPath").ToString()) { ServerName = serverNameProp.ToString(), ServerPropList = propList, - ServerPath = new Property("ServerPath", "") - { + ServerPath = new Property("ServerPath", "") { Value = $@"{_serviceConfiguration.GetProp("ServersPath")}\{serverNameProp}" }, - ServerExeName = new Property("ServerExeName", "") - { + ServerExeName = new Property("ServerExeName", "") { Value = $"BedrockService.{serverNameProp}.exe" }, FileName = $@"{serverNameProp}.conf" @@ -528,28 +466,24 @@ public void ParseMessage(byte[] data, byte serverIndex) } } - class RemoveServer : IFlaggedMessageParser - { + class RemoveServer : IFlaggedMessageParser { private readonly IMessageSender _messageSender; private readonly IServiceConfiguration _serviceConfiguration; private readonly IConfigurator _configurator; private readonly IBedrockService _bedrockService; - public RemoveServer(IConfigurator configurator, IMessageSender messageSender, IServiceConfiguration serviceConfiguration, IBedrockService bedrockService) - { + public RemoveServer(IConfigurator configurator, IMessageSender messageSender, IServiceConfiguration serviceConfiguration, IBedrockService bedrockService) { this._bedrockService = bedrockService; _configurator = configurator; _messageSender = messageSender; _serviceConfiguration = serviceConfiguration; } - public void ParseMessage(byte[] data, byte serverIndex, NetworkMessageFlags flag) - { - _bedrockService.GetBedrockServerByIndex(serverIndex).StopServer().Wait(); + public void ParseMessage(byte[] data, byte serverIndex, NetworkMessageFlags flag) { + _bedrockService.GetBedrockServerByIndex(serverIndex).StopServer(true).Wait(); _configurator.RemoveServerConfigs(_serviceConfiguration.GetServerInfoByIndex(serverIndex), flag); _bedrockService.RemoveBedrockServerByIndex(serverIndex); - JsonSerializerSettings settings = new JsonSerializerSettings() - { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(_serviceConfiguration, Formatting.Indented, settings)); @@ -559,88 +493,73 @@ public void ParseMessage(byte[] data, byte serverIndex, NetworkMessageFlags flag } } - class ConsoleLogUpdate : IMessageParser - { + class ConsoleLogUpdate : IMessageParser { private readonly IMessageSender _messageSender; private readonly IBedrockService _service; private readonly IServiceConfiguration _serviceConfiguration; - public ConsoleLogUpdate(IMessageSender messageSender, IServiceConfiguration serviceConfiguration, IBedrockService service) - { + public ConsoleLogUpdate(IMessageSender messageSender, IServiceConfiguration serviceConfiguration, IBedrockService service) { _service = service; _messageSender = messageSender; _serviceConfiguration = serviceConfiguration; } - public void ParseMessage(byte[] data, byte serverIndex) - { + public void ParseMessage(byte[] data, byte serverIndex) { string stringData = Encoding.UTF8.GetString(data, 5, data.Length - 5); StringBuilder srvString = new StringBuilder(); string[] split = stringData.Split('|'); - for (int i = 0; i < split.Length; i++) - { + for (int i = 0; i < split.Length; i++) { string[] dataSplit = split[i].Split(';'); string srvName = dataSplit[0]; int srvTextLen; int clientCurLen; int loop; - ILogger srvText; - if (srvName != "Service") - { - try - { - srvText = _service.GetBedrockServerByName(srvName).GetLogger(); + IBedrockLogger srvText; + if (srvName != "Service") { + try { + srvText = _service.GetBedrockServerByName(srvName).GetLogger(); } - catch(NullReferenceException) - { + catch (NullReferenceException) { break; } srvTextLen = srvText.Count(); clientCurLen = int.Parse(dataSplit[1]); loop = clientCurLen; - while (loop < srvTextLen) - { + while (loop < srvTextLen) { srvString.Append($"{srvName};{srvText.FromIndex(loop)};{loop}|"); loop++; } } - else - { + else { srvTextLen = _serviceConfiguration.GetLog().Count; clientCurLen = int.Parse(dataSplit[1]); loop = clientCurLen; - while (loop < srvTextLen) - { + while (loop < srvTextLen) { srvString.Append($"{srvName};{_serviceConfiguration.GetLog()[loop]};{loop}|"); loop++; } } } - if (srvString.Length > 1) - { + if (srvString.Length > 1) { srvString.Remove(srvString.Length - 1, 1); _messageSender.SendData(Encoding.UTF8.GetBytes(srvString.ToString()), NetworkMessageSource.Server, NetworkMessageDestination.Client, NetworkMessageTypes.ConsoleLogUpdate); } } } - class PlayerRequest : IMessageParser - { + class PlayerRequest : IMessageParser { private readonly IMessageSender _messageSender; private readonly IServiceConfiguration _serviceConfiguration; - public PlayerRequest(IMessageSender messageSender, IServiceConfiguration serviceConfiguration) - { + public PlayerRequest(IMessageSender messageSender, IServiceConfiguration serviceConfiguration) { _messageSender = messageSender; _serviceConfiguration = serviceConfiguration; } - public void ParseMessage(byte[] data, byte serverIndex) - { + public void ParseMessage(byte[] data, byte serverIndex) { IServerConfiguration server = _serviceConfiguration.GetServerInfoByIndex(serverIndex); - JsonSerializerSettings settings = new JsonSerializerSettings() - { + JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; byte[] serializeToBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(server.GetPlayerList(), Formatting.Indented, settings)); diff --git a/BedrockService/Service/Networking/TCPListener.cs b/BedrockService/Service/Networking/TCPListener.cs index 29cdd0b1..94b7e279 100644 --- a/BedrockService/Service/Networking/TCPListener.cs +++ b/BedrockService/Service/Networking/TCPListener.cs @@ -1,109 +1,106 @@ -using BedrockService.Service.Core.Interfaces; -using BedrockService.Service.Core.Threads; -using BedrockService.Service.Networking.NetworkMessageClasses; -using BedrockService.Shared.Classes; -using BedrockService.Shared.Interfaces; -using System; -using System.Collections.Generic; +using BedrockService.Service.Networking.MessageInterfaces; using System.Net; using System.Net.Sockets; -using System.Threading; +using System.Security.Cryptography; -namespace BedrockService.Service.Networking -{ - public class TCPListener : ITCPListener, IMessageSender - { +namespace BedrockService.Service.Networking { + public class TCPListener : ITCPListener, IMessageSender { private TcpClient _client; private TcpListener _inListener; private NetworkStream _stream; private readonly IServiceConfiguration _serviceConfiguration; - private readonly ILogger _logger; - private IServiceThread _tcpThread; - private IServiceThread _clientThread; - private IServiceThread _heartbeatThread; - private bool _heartbeatRecieved = false; - private bool _firstHeartbeatRecieved = false; - private bool _keepAlive = false; + private readonly IBedrockLogger _logger; private int _heartbeatFailTimeout; - private readonly int _heartbeatFailTimeoutLimit = 200; + private readonly int _heartbeatFailTimeoutLimit = 2; private Dictionary _standardMessageLookup; private Dictionary _flaggedMessageLookup; private readonly IPAddress _ipAddress = IPAddress.Parse("0.0.0.0"); - private readonly System.Timers.Timer _reconnectTimer = new System.Timers.Timer(500.0); + private CommsKeyContainer _keyContainer; + private CancellationTokenSource _cancelTokenSource = new CancellationTokenSource(); + private Task _tcpTask; + private Task _recieverTask; - public TCPListener(IServiceConfiguration serviceConfiguration, ILogger logger) - { + public TCPListener(IServiceConfiguration serviceConfiguration, IBedrockLogger logger, IProcessInfo processInfo) { _logger = logger; _serviceConfiguration = serviceConfiguration; - _reconnectTimer.Elapsed += ReconnectTimer_Elapsed; - _tcpThread = new TCPThread(new ThreadStart(StartListening)); + _cancelTokenSource = new CancellationTokenSource(); + if (processInfo.ShouldStartService()) { + InitializeTasks(); + } } - private void ReconnectTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) - { - _reconnectTimer.Stop(); - _tcpThread = new TCPThread(new ThreadStart(StartListening)); + private void InitializeTasks() { + _tcpTask = StartListening(); + _recieverTask = IncomingListener(); + _tcpTask.Start(); } - public void SetStrategyDictionaries(Dictionary standard, Dictionary flagged) - { + public void SetStrategyDictionaries(Dictionary standard, Dictionary flagged) { _standardMessageLookup = standard; _flaggedMessageLookup = flagged; } - public void StartListening() - { - _inListener = new TcpListener(_ipAddress, int.Parse(_serviceConfiguration.GetProp("ClientPort").ToString())); - try - { - _inListener.Start(); - _keepAlive = true; - } - catch(SocketException e) - { - _logger.AppendLine($"Error! {e.Message}"); - Thread.Sleep(2000); - //Environment.Exit(1); - } + public Task StartListening() { + return new Task(() => { + _logger.AppendLine("TCP listener task started."); + _inListener = new TcpListener(_ipAddress, int.Parse(_serviceConfiguration.GetProp("ClientPort").ToString())); + try { - while (true) - { - try - { - _client = _inListener.AcceptTcpClient(); - _stream = _client.GetStream(); - _clientThread = new ClientServiceThread(new ThreadStart(IncomingListener)); - _heartbeatThread = new HeartbeatThread(new ThreadStart(SendBackHeatbeatSignal)); + while (_standardMessageLookup == null) { Task.Delay(100).Wait(); } + _inListener.Start(); } - catch (ThreadStateException) { } - catch (NullReferenceException) { } - catch (InvalidOperationException) { } - catch (SocketException) { } - catch (Exception e) - { - _logger.AppendLine(e.ToString()); + catch (SocketException e) { + _logger.AppendLine($"Error! {e.Message}"); + Thread.Sleep(2000); + Environment.Exit(1); } - } + while (true) { + try { + if (_inListener.Pending()) { + _cancelTokenSource = new CancellationTokenSource(); + _client = _inListener.AcceptTcpClient(); + _stream = _client.GetStream(); + _recieverTask.Start(); + } + if (_cancelTokenSource.IsCancellationRequested) { + _logger.AppendLine("TCP Listener task canceled!"); + _inListener.Stop(); + _inListener = null; + return; + } + Task.Delay(500).Wait(); + } + catch (NullReferenceException) { } + catch (InvalidOperationException) { + _inListener = null; + return; + } + catch (SocketException) { } + catch (Exception e) { + _logger.AppendLine(e.ToString()); + } + } + }, _cancelTokenSource.Token); } - public void ResetListener() - { - _keepAlive = false; - while (_heartbeatThread.IsAlive()) - { - Thread.Sleep(300); - } - _stream.Close(); - _stream.Dispose(); - _client.Client.Blocking = false; - _inListener.Stop(); - _tcpThread.CloseThread(); - _tcpThread = null; - StartListening(); + public void ResetListener() { + Task.Run(() => { + _logger.AppendLine("Resetting listener!"); + _client.Client.Blocking = false; + _stream.Close(); + _stream.Dispose(); + _client.Close(); + _inListener?.Stop(); + _cancelTokenSource?.Cancel(); + while (_tcpTask.Status == TaskStatus.Running || _recieverTask.Status == TaskStatus.Running) { + Task.Delay(100).Wait(); + } + _cancelTokenSource = new CancellationTokenSource(); + InitializeTasks(); + }); } - public void SendData(byte[] bytesToSend, NetworkMessageSource source, NetworkMessageDestination destination, byte serverIndex, NetworkMessageTypes type, NetworkMessageFlags status) - { + public void SendData(byte[] bytesToSend, NetworkMessageSource source, NetworkMessageDestination destination, byte serverIndex, NetworkMessageTypes type, NetworkMessageFlags status) { byte[] byteHeader = new byte[9 + bytesToSend.Length]; byte[] len = BitConverter.GetBytes(5 + bytesToSend.Length); Buffer.BlockCopy(len, 0, byteHeader, 0, 4); @@ -113,16 +110,20 @@ public void SendData(byte[] bytesToSend, NetworkMessageSource source, NetworkMes byteHeader[7] = (byte)type; byteHeader[8] = (byte)status; Buffer.BlockCopy(bytesToSend, 0, byteHeader, 9, bytesToSend.Length); - if (_clientThread.IsAlive()) - { - try - { + + if (_tcpTask?.Status == TaskStatus.Running && _recieverTask?.Status == TaskStatus.Running) { + try { _stream.Write(byteHeader, 0, byteHeader.Length); _stream.Flush(); + _heartbeatFailTimeout = 0; } - catch - { + catch { _logger.AppendLine("Error writing to network stream!"); + _heartbeatFailTimeout++; + if (_heartbeatFailTimeout >= _heartbeatFailTimeoutLimit) { + ResetListener(); + _heartbeatFailTimeout = 0; + } } } } @@ -137,131 +138,94 @@ public void SendData(byte[] bytesToSend, NetworkMessageSource source, NetworkMes public void SendData(NetworkMessageSource source, NetworkMessageDestination destination, NetworkMessageTypes type, NetworkMessageFlags status) => SendData(new byte[0], source, destination, 0xFF, type, status); - private void IncomingListener() - { - _keepAlive = true; - _logger.AppendLine("Packet listener thread started."); - int AvailBytes = 0; - int byteCount = 0; - NetworkMessageSource msgSource = 0; - NetworkMessageDestination msgDest = 0; - byte serverIndex = 0xFF; - NetworkMessageTypes msgType = 0; - NetworkMessageFlags msgFlag = 0; - while (_keepAlive) - { - try - { - byte[] buffer = new byte[4]; - while (_client.Client.Available != 0) // Recieve data from client. - { - byteCount = _stream.Read(buffer, 0, 4); - int expectedLen = BitConverter.ToInt32(buffer, 0); - buffer = new byte[expectedLen]; - byteCount = _stream.Read(buffer, 0, expectedLen); - msgSource = (NetworkMessageSource)buffer[0]; - msgDest = (NetworkMessageDestination)buffer[1]; - serverIndex = buffer[2]; - msgType = (NetworkMessageTypes)buffer[3]; - msgFlag = (NetworkMessageFlags)buffer[4]; - if (msgType == NetworkMessageTypes.Heartbeat) - { - if (!_firstHeartbeatRecieved) - _firstHeartbeatRecieved = true; - _heartbeatRecieved = true; - } - if (msgType == NetworkMessageTypes.Disconnect) + private Task IncomingListener() { + return new Task(() => { + _logger.AppendLine("TCP Client packet listener started."); + int AvailBytes = 0; + int byteCount = 0; + NetworkMessageSource msgSource = 0; + NetworkMessageDestination msgDest = 0; + byte serverIndex = 0xFF; + NetworkMessageTypes msgType = 0; + NetworkMessageFlags msgFlag = 0; + while (true) { + SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.Heartbeat); + if (_cancelTokenSource.IsCancellationRequested) { + _logger.AppendLine("TCP Client packet listener canceled!"); + return; + } + try { + byte[] buffer = new byte[4]; + while (_client.Client != null && _client.Client.Available != 0) // Recieve data from client. { - ResetListener(); + byteCount = _stream.Read(buffer, 0, 4); + int expectedLen = BitConverter.ToInt32(buffer, 0); + buffer = new byte[expectedLen]; + byteCount = _stream.Read(buffer, 0, expectedLen); + msgSource = (NetworkMessageSource)buffer[0]; + msgDest = (NetworkMessageDestination)buffer[1]; + serverIndex = buffer[2]; + msgType = (NetworkMessageTypes)buffer[3]; + msgFlag = (NetworkMessageFlags)buffer[4]; + if (msgType == NetworkMessageTypes.Disconnect) { + ResetListener(); + } + if (msgType < NetworkMessageTypes.Heartbeat) { + try { + if (_standardMessageLookup.ContainsKey(msgType)) + _standardMessageLookup[msgType].ParseMessage(buffer, serverIndex); + else + _flaggedMessageLookup[msgType].ParseMessage(buffer, serverIndex, msgFlag); + } + catch { + if (msgType == NetworkMessageTypes.Connect) + Task.Delay(1000).Wait(); + ResetListener(); + } + } } - if (msgType < NetworkMessageTypes.Heartbeat) - { - if (_standardMessageLookup.ContainsKey(msgType)) - _standardMessageLookup[msgType].ParseMessage(buffer, serverIndex); - else - _flaggedMessageLookup[msgType].ParseMessage(buffer, serverIndex, msgFlag); + Task.Delay(500).Wait(); + } + catch (OutOfMemoryException) { + _logger.AppendLine("Out of memory exception thrown."); + } + catch (ObjectDisposedException) { + _logger.AppendLine("Client was disposed!"); + } + catch (InvalidOperationException e) { + if (msgType != NetworkMessageTypes.ConsoleLogUpdate) { + _logger.AppendLine(e.Message); + _logger.AppendLine(e.StackTrace); } } - Thread.Sleep(200); - } - catch (OutOfMemoryException) - { - _logger.AppendLine("Out of memory exception thrown."); - } - catch (ObjectDisposedException) - { - _logger.AppendLine("Client was disposed! Killing thread..."); - break; - } - catch (InvalidOperationException e) - { - if (msgType != NetworkMessageTypes.ConsoleLogUpdate) - { - _logger.AppendLine(e.Message); - _logger.AppendLine(e.StackTrace); + catch (Exception e) { + _logger.AppendLine($"Error: {e.Message} {e.StackTrace}"); } + try { + AvailBytes = _client.Client != null ? _client.Client.Available : 0; + } + catch { } } - catch (ThreadAbortException) - { - _logger.AppendLine("ListenerThread aborted!"); - } - catch (Exception e) - { - _logger.AppendLine($"Error: {e.Message} {e.StackTrace}"); - } - try - { - AvailBytes = _client.Client.Available; - } - catch { } - if (!_clientThread.IsAlive()) - _clientThread.CloseThread(); - } + }, _cancelTokenSource.Token); } - private void SendBackHeatbeatSignal() - { - _logger.AppendLine("HeartBeatSender started."); - while (_keepAlive) - { - _heartbeatRecieved = false; - while (!_heartbeatRecieved && _keepAlive) - { - Thread.Sleep(100); - _heartbeatFailTimeout++; - if (_heartbeatFailTimeout > _heartbeatFailTimeoutLimit) - { - if (!_firstHeartbeatRecieved) - { - try - { - SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.Heartbeat); - _heartbeatFailTimeout = 0; - } - catch (Exception e) - { - _logger.AppendLine($"HeartBeatSender exited with error: {e.Message}"); - return; - } - } - } + public void SetKeyContainer(CommsKeyContainer keyContainer) { + _keyContainer = keyContainer; + } + + public bool VerifyClientData(byte[] certificate) { + if (certificate != null) { + byte[] decrypted; + using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { + rsa.ImportParameters(_keyContainer.LocalPrivateKey.GetPrivateKey()); + } - _heartbeatRecieved = false; - _heartbeatFailTimeout = 0; - SendData(NetworkMessageSource.Service, NetworkMessageDestination.Client, NetworkMessageTypes.Heartbeat); - int timeWaited = 0; - while (timeWaited < 3000) - { - Thread.Sleep(100); - timeWaited += 100; - if (!_keepAlive) - { - _logger.AppendLine("HeartBeatSender exited."); - return; - } + using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { + rsa.ImportParameters(_keyContainer.RemotePublicKey.GetPrivateKey()); + } } - _logger.AppendLine("HeartBeatSender exited."); + return true; } } } \ No newline at end of file diff --git a/BedrockService/Service/Networking/Updater.cs b/BedrockService/Service/Networking/Updater.cs index 8be6efb1..2f2bf4ba 100644 --- a/BedrockService/Service/Networking/Updater.cs +++ b/BedrockService/Service/Networking/Updater.cs @@ -1,41 +1,37 @@ -using BedrockService.Shared.Interfaces; -using BedrockService.Shared.Utilities; -using System; -using System.IO; +using BedrockService.Shared.Utilities; using System.IO.Compression; using System.Net.Http; using System.Text.RegularExpressions; -using System.Threading; -using System.Threading.Tasks; -namespace BedrockService.Service.Networking -{ - public class Updater : IUpdater - { +namespace BedrockService.Service.Networking { + public class Updater : IUpdater { private bool _versionChanged = false; - private readonly ILogger _logger; + private readonly IBedrockLogger _logger; private readonly IServiceConfiguration _serviceConfiguration; private readonly IProcessInfo _processInfo; private readonly string _version; - public Updater(IProcessInfo processInfo, ILogger logger, IServiceConfiguration serviceConfiguration) - { + public Updater(IProcessInfo processInfo, IBedrockLogger logger, IServiceConfiguration serviceConfiguration) { _serviceConfiguration = serviceConfiguration; _processInfo = processInfo; _logger = logger; _version = "None"; - if (!File.Exists($@"{processInfo.GetDirectory()}\Server\bedrock_ver.ini")) - { - logger.AppendLine("Version ini file missing, creating and fetching build..."); - File.Create($@"{processInfo.GetDirectory()}\Server\bedrock_ver.ini").Close(); + if (processInfo.ShouldStartService()) { + if (!Directory.Exists($@"{processInfo.GetDirectory()}\Server")) { Directory.CreateDirectory($@"{processInfo.GetDirectory()}\Server"); } + if (!File.Exists($@"{processInfo.GetDirectory()}\Server\bedrock_ver.ini")) { + logger.AppendLine("Version ini file missing, creating and fetching build..."); + File.Create($@"{processInfo.GetDirectory()}\Server\bedrock_ver.ini").Close(); + } + _version = File.ReadAllText($@"{processInfo.GetDirectory()}\Server\bedrock_ver.ini"); } - _version = File.ReadAllText($@"{processInfo.GetDirectory()}\Server\bedrock_ver.ini"); } - public async Task CheckUpdates() - { - await Task.Run(async () => - { + public async Task CheckUpdates() { + await Task.Run(async () => { + if (bool.Parse(_serviceConfiguration.GetProp("AcceptedMojangLic").ToString())) { + _logger.AppendLine("You have not accepted the license. Please visit the readme for more info!"); + return false; + } _logger.AppendLine("Checking MCS Version and fetching update if needed..."); HttpClient client = new HttpClient(); client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/apng,*/*;q=0.8"); @@ -45,7 +41,6 @@ await Task.Run(async () => client.DefaultRequestHeaders.Add("Pragma", "no-cache"); client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko; Google Page Speed Insights) Chrome/27.0.1453 Safari/537.36"); client.Timeout = new TimeSpan(0, 0, 3); - string content = FetchHTTPContent(client).Result; if (content == null) // This really doesn't fail often. Give it one more try or fail. { @@ -56,8 +51,7 @@ await Task.Run(async () => return false; Regex regex = new Regex(@"(https://minecraft.azureedge.net/bin-win/bedrock-server-)(.*)(\.zip)", RegexOptions.IgnoreCase); Match m = regex.Match(content); - if (!m.Success) - { + if (!m.Success) { _logger.AppendLine("Checking for updates failed. Check website functionality!"); return false; } @@ -65,14 +59,12 @@ await Task.Run(async () => string fetchedVersion = m.Groups[2].Value; client.Dispose(); - if (_version == fetchedVersion) - { + if (_version == fetchedVersion) { _logger.AppendLine($"Current version \"{fetchedVersion}\" is up to date!"); return true; } _logger.AppendLine($"New version detected! Now fetching from {downloadPath}..."); - if (!FetchBuild(downloadPath, fetchedVersion).Wait(60000)) - { + if (!FetchBuild(downloadPath, fetchedVersion).Wait(60000)) { _logger.AppendLine("Fetching build timed out. If this is a new service instance, please restart service!"); return false; } @@ -81,40 +73,25 @@ await Task.Run(async () => _serviceConfiguration.SetServerVersion(fetchedVersion); GenerateFileList(fetchedVersion); return true; - - }); } - public async Task FetchBuild(string path, string version) - { + public async Task FetchBuild(string path, string version) { string ZipDir = $@"{_processInfo.GetDirectory()}\Server\MCSFiles\Update_{version}.zip"; - if (!Directory.Exists($@"{_processInfo.GetDirectory()}\Server\MCSFiles")) - { + if (!Directory.Exists($@"{_processInfo.GetDirectory()}\Server\MCSFiles")) { Directory.CreateDirectory($@"{_processInfo.GetDirectory()}\Server\MCSFiles"); } - if (File.Exists(ZipDir)) - { + if (File.Exists(ZipDir)) { return; } - //if (InstanceProvider.HostInfo.GetGlobalValue("AcceptedMojangLic") == "false") - //{ - // logger.AppendLine("You have not accepted the license. Please visit the readme for more info!"); - // return; - //} _logger.AppendLine("Now downloading latest build of Minecraft Bedrock Server. Please wait..."); - using (var httpClient = new HttpClient()) - { - using (var request = new HttpRequestMessage(HttpMethod.Get, path)) - { - using (Stream contentStream = await (await httpClient.SendAsync(request)).Content.ReadAsStreamAsync(), stream = new FileStream(ZipDir, FileMode.Create, FileAccess.Write, FileShare.None, 256000, true)) - { - try - { + using (var httpClient = new HttpClient()) { + using (var request = new HttpRequestMessage(HttpMethod.Get, path)) { + using (Stream contentStream = await (await httpClient.SendAsync(request)).Content.ReadAsStreamAsync(), stream = new FileStream(ZipDir, FileMode.Create, FileAccess.Write, FileShare.None, 256000, true)) { + try { await contentStream.CopyToAsync(stream); } - catch (Exception e) - { + catch (Exception e) { _logger.AppendLine($"Download zip resulted in error: {e.StackTrace}"); } httpClient.Dispose(); @@ -124,68 +101,54 @@ public async Task FetchBuild(string path, string version) } } } - } public bool CheckVersionChanged() => _versionChanged; public void MarkUpToDate() => _versionChanged = false; - public async Task ReplaceBuild(IServerConfiguration server) - { - await Task.Run(() => - { - try - { - if (!Directory.Exists(server.GetProp("ServerPath").ToString())) + public async Task ReplaceBuild(IServerConfiguration server) { + await Task.Run(() => { + try { + if (!Directory.Exists(server.GetProp("ServerPath").ToString())) { Directory.CreateDirectory(server.GetProp("ServerPath").ToString()); - else if (File.Exists($@"{_processInfo.GetDirectory()}\Server\MCSFiles\stock_filelist.ini")) + } + else if (File.Exists($@"{_processInfo.GetDirectory()}\Server\MCSFiles\stock_filelist.ini")) { new FileUtils(_processInfo.GetDirectory()).DeleteFilelist(File.ReadAllLines($@"{_processInfo.GetDirectory()}\Server\MCSFiles\stock_filelist.ini"), server.GetProp("ServerPath").ToString()); - else + } + else { new FileUtils(_processInfo.GetDirectory()).DeleteFilesRecursively(new DirectoryInfo(server.GetProp("ServerPath").ToString()), false); - - ZipFile.ExtractToDirectory($@"{_processInfo.GetDirectory()}\Server\MCSFiles\Update_{_version}.zip", server.GetProp("ServerPath").ToString()); - File.Copy(server.GetProp("ServerPath") + "\\bedrock_server.exe", server.GetProp("ServerPath") + "\\" + server.GetProp("ServerExeName"), true); + ZipFile.ExtractToDirectory($@"{_processInfo.GetDirectory()}\Server\MCSFiles\Update_{_version}.zip", server.GetProp("ServerPath").ToString()); + File.Copy(server.GetProp("ServerPath") + "\\bedrock_server.exe", server.GetProp("ServerPath") + "\\" + server.GetProp("ServerExeName"), true); + } } - catch (Exception e) - { + catch (Exception e) { _logger.AppendLine($"ERROR: Got an exception deleting entire directory! {e.Message}"); } - - }); } - - private async Task FetchHTTPContent(HttpClient client) - { - try - { + private async Task FetchHTTPContent(HttpClient client) { + try { return await client.GetStringAsync("https://www.minecraft.net/en-us/download/server/bedrock"); } - catch (HttpRequestException) - { + catch (HttpRequestException) { _logger.AppendLine($"Error! Updater timed out, could not fetch current build!"); } - catch (TaskCanceledException) - { + catch (TaskCanceledException) { Thread.Sleep(200); return await FetchHTTPContent(client); } - catch (Exception e) - { + catch (Exception e) { _logger.AppendLine($"Updater resulted in error: {e.Message}\n{e.InnerException}\n{e.StackTrace}"); } return null; } - private void GenerateFileList(string version) - { - using (ZipArchive zip = ZipFile.OpenRead($@"{_processInfo.GetDirectory()}\Server\MCSFiles\Update_{version}.zip")) - { + private void GenerateFileList(string version) { + using (ZipArchive zip = ZipFile.OpenRead($@"{_processInfo.GetDirectory()}\Server\MCSFiles\Update_{version}.zip")) { string[] fileList = new string[zip.Entries.Count]; - for (int i = 0; i < zip.Entries.Count; i++) - { + for (int i = 0; i < zip.Entries.Count; i++) { fileList[i] = zip.Entries[i].FullName.Replace('/', '\\'); } File.WriteAllLines($@"{_processInfo.GetDirectory()}\Server\MCSFiles\stock_filelist.ini", fileList); diff --git a/BedrockService/Service/Program.cs b/BedrockService/Service/Program.cs index d3a6fc02..66028d83 100644 --- a/BedrockService/Service/Program.cs +++ b/BedrockService/Service/Program.cs @@ -1,80 +1,64 @@ -using BedrockService.Service.Core; -using BedrockService.Service.Logging; -using BedrockService.Service.Management; -using BedrockService.Service.Networking; -using BedrockService.Shared.Classes; -using BedrockService.Shared.Interfaces; -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Diagnostics; -using System.IO; -using System.Reflection; -using Topshelf; +// This application entry point is based on ASP.NET Core new project templates and is included +// as a starting point for app host configuration. +// This file may need updated according to the specific scenario of the application being upgraded. +// For more information on ASP.NET Core hosting, see https://docs.microsoft.com/aspnet/core/fundamentals/host/web-host -namespace BedrockService.Service -{ - class Program - { +global using BedrockService.Service.Logging; +global using BedrockService.Service.Management; +global using BedrockService.Service.Networking; +global using BedrockService.Shared.Classes; +global using BedrockService.Shared.Interfaces; +global using Microsoft.AspNetCore.Hosting; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Hosting; +global using System; +global using System.Collections.Generic; +global using System.Diagnostics; +global using System.IO; +global using System.Linq; +global using System.Reflection; +global using System.Threading; +global using System.Threading.Tasks; +global using Topshelf; +using BedrockService.Service.Core.Interfaces; + +namespace BedrockService.Service { + public class Program { public static bool IsExiting = false; private static bool _isDebugEnabled = false; private static bool _isConsoleMode = false; - private static readonly IServiceCollection _services = new ServiceCollection(); - - static void Main(string[] args) - { - if (args.Length > 0) - { + private static bool _shouldStartService = true; + private static CancellationTokenSource CancellationTokenSource = new CancellationTokenSource(); + private static CancellationToken token = CancellationTokenSource.Token; + public static void Main(string[] args) { + if (args.Length > 0) { + Console.WriteLine(string.Join(" ", args)); _isDebugEnabled = args[0].ToLower() == "-debug"; + _shouldStartService = + args[0].ToLower() != "install" && + args[0].ToLower() != "uninstall" && + args[0].ToLower() != "start" && + args[0].ToLower() != "stop"; } - ConfigureServices(_services); - IServiceProvider serviceProvider = _services.BuildServiceProvider(); - serviceProvider.GetRequiredService().LoadAllConfigurations().Wait(); - serviceProvider.GetRequiredService().CheckUpdates().Wait(); - IService service = serviceProvider.GetRequiredService(); - ILogger Logger = serviceProvider.GetRequiredService(); - IProcessInfo ProcessInfo = serviceProvider.GetRequiredService(); - serviceProvider.GetRequiredService(); - if (args.Length == 0 || Environment.UserInteractive) - { + if (args.Length == 0 || Environment.UserInteractive) { _isConsoleMode = true; - Logger.AppendLine("BedrockService startup detected in Console mode."); - } - else - { - Logger.AppendLine("BedrockService startup detected in Service mode."); - foreach (Process process in Process.GetProcesses()) - { - if (process.Id != ProcessInfo.GetProcessPID() && process.ProcessName.StartsWith("BedrockService.") && process.ProcessName != "BedrockService.Client") - { - Logger.AppendLine($"Found additional running instance of {process.ProcessName} with ID {process.Id}"); - Logger.AppendLine($"Killing process with id {process.Id}"); - process.Kill(); - } - } } - service.InitializeHost().Wait(); - TopshelfExitCode rc = service.Run(); - var exitCode = (int)Convert.ChangeType(rc, rc.GetTypeCode()); - if (_isDebugEnabled) - { - Console.Write("Program is force-quitting. Press any key to exit."); - Console.Out.Flush(); - Console.ReadLine(); - } - Environment.ExitCode = exitCode; - } - private static void ConfigureServices(IServiceCollection services) - { - IProcessInfo processInfo = new ServiceProcessInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), Path.GetFileName(Assembly.GetExecutingAssembly().Location), Process.GetCurrentProcess().Id, _isDebugEnabled, _isConsoleMode); - services.AddSingleton(processInfo); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); + CreateHostBuilder(args).Build().Run(); } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args) + .ConfigureServices((hostContext, services) => { + IProcessInfo processInfo = new ServiceProcessInfo(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName), Process.GetCurrentProcess().Id, _isDebugEnabled, _isConsoleMode, _shouldStartService); + services.AddHostedService() + .AddSingleton(processInfo) + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton(); + }); } } diff --git a/BedrockService/Service/Properties/AssemblyInfo.cs b/BedrockService/Service/Properties/AssemblyInfo.cs index 37ca46b4..298c0a0c 100644 --- a/BedrockService/Service/Properties/AssemblyInfo.cs +++ b/BedrockService/Service/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -31,5 +30,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("2.5.6.0")] +[assembly: AssemblyFileVersion("2.5.6.0")] diff --git a/BedrockService/Service/Server/BedrockServer.cs b/BedrockService/Service/Server/BedrockServer.cs index 87e5bf22..1ed343bf 100644 --- a/BedrockService/Service/Server/BedrockServer.cs +++ b/BedrockService/Service/Server/BedrockServer.cs @@ -1,25 +1,13 @@ -using BedrockService.Service.Core.Interfaces; -using BedrockService.Service.Core.Threads; -using BedrockService.Service.Management; -using BedrockService.Service.Server.Management; -using BedrockService.Shared.Classes; -using BedrockService.Shared.Interfaces; +using BedrockService.Service.Server.Management; using BedrockService.Shared.Utilities; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; using System.Text.RegularExpressions; -using System.Threading; -using System.Threading.Tasks; -using Topshelf; -namespace BedrockService.Service.Server -{ - public class BedrockServer : IBedrockServer - { - private IServiceThread _serverThread; - private IServiceThread _watchdogThread; +namespace BedrockService.Service.Server { + public class BedrockServer : IBedrockServer { + private Task _serverTask; + private Task _watchdogTask; + private CancellationTokenSource _serverCanceler = new CancellationTokenSource(); + private CancellationTokenSource _watchdogCanceler = new CancellationTokenSource(); private StreamWriter _stdInStream; private Process _serverProcess; private HostControl _hostController; @@ -28,20 +16,18 @@ public class BedrockServer : IBedrockServer private readonly IServiceConfiguration _serviceConfiguration; private readonly IPlayerManager _playerManager; private readonly IConfigurator _configurator; - private readonly ILogger _logger; - private readonly ILogger _serverLogger; + private readonly IBedrockLogger _logger; + private readonly IBedrockLogger _serverLogger; private readonly string _servicePath; - private const string _startupMessage = "[INFO] Server started."; - public enum ServerStatus - { + private const string _startupMessage = "INFO] Server started."; + public enum ServerStatus { Stopped, Starting, Stopping, Started } - public BedrockServer(IServerConfiguration serverConfiguration, IConfigurator configurator, ILogger logger, IServiceConfiguration serviceConfiguration, IProcessInfo processInfo) - { + public BedrockServer(IServerConfiguration serverConfiguration, IConfigurator configurator, IBedrockLogger logger, IServiceConfiguration serviceConfiguration, IProcessInfo processInfo) { _serverConfiguration = serverConfiguration; _serviceConfiguration = serviceConfiguration; _configurator = configurator; @@ -51,20 +37,19 @@ public BedrockServer(IServerConfiguration serverConfiguration, IConfigurator con _playerManager = new PlayerManager(serverConfiguration, logger); } - public void WriteToStandardIn(string command) - { + public void WriteToStandardIn(string command) { _stdInStream.WriteLine(command); } - public void StartControl() - { - _serverThread = new ServerProcessThread(new ThreadStart(RunServer)); + public void StartControl() { + _serverCanceler = new CancellationTokenSource(); + _serverTask = RunServer(); + _serverTask.Start(); } - public void StopControl() - { - if (_serverProcess != null) - { + public void StopControl() { + _serverCanceler.Cancel(); + if (_serverProcess != null) { _logger.AppendLine("Sending Stop to Bedrock. Process.HasExited = " + _serverProcess.HasExited.ToString()); _serverProcess.CancelOutputRead(); @@ -72,168 +57,148 @@ public void StopControl() _stdInStream.WriteLine("stop"); while (!_serverProcess.HasExited) { } } - _serverThread.CloseThread(); _serverProcess = null; _currentServerStatus = ServerStatus.Stopped; } - public void StartWatchdog(HostControl hostControl) - { + public void StartWatchdog(HostControl hostControl) { + _watchdogCanceler = new CancellationTokenSource(); _hostController = hostControl; - if (_watchdogThread == null) - { - _watchdogThread = new WatchdogThread(new ThreadStart(ApplicationWatchdogMonitor)); - } + _watchdogTask = ApplicationWatchdogMonitor(); + _watchdogTask.Start(); + } + + public void InitializeBackup() { + WriteToStandardIn("save hold"); + Task.Delay(1000).Wait(); + WriteToStandardIn("save query"); } - private bool Backup() - { - try - { + private bool PerformBackup(string queryString) { + try { + FileUtils fileUtils = new FileUtils(_servicePath); FileInfo exe = new FileInfo($@"{_serverConfiguration.GetProp("ServerPath")}\{_serverConfiguration.GetProp("ServerExeName")}"); string configBackupPath = _serviceConfiguration.GetProp("BackupPath").ToString(); DirectoryInfo backupDir = new DirectoryInfo($@"{configBackupPath}\{_serverConfiguration.GetServerName()}"); DirectoryInfo serverDir = new DirectoryInfo(_serverConfiguration.GetProp("ServerPath").ToString()); DirectoryInfo worldsDir = new DirectoryInfo($@"{_serverConfiguration.GetProp("ServerPath")}\worlds"); - if (!backupDir.Exists) - { + if (!backupDir.Exists) { backupDir.Create(); } + Dictionary backupFileInfoPairs = new Dictionary(); + string[] files = queryString.Split(", "); + foreach (string file in files) { + string[] fileInfoSplit = file.Split(':'); + string fileName = fileInfoSplit[0]; + int fileSize = int.Parse(fileInfoSplit[1]); + backupFileInfoPairs.Add(fileName, fileSize); + } int dirCount = backupDir.GetDirectories().Length; - try - { - if (dirCount >= int.Parse(_serviceConfiguration.GetProp("MaxBackupCount").ToString())) - { + try { + if (dirCount >= int.Parse(_serviceConfiguration.GetProp("MaxBackupCount").ToString())) { Regex reg = new Regex(@"Backup_(.*)$"); List Dates = new List(); - foreach (DirectoryInfo dir in backupDir.GetDirectories()) - { - if (reg.IsMatch(dir.Name)) - { + foreach (DirectoryInfo dir in backupDir.GetDirectories()) { + if (reg.IsMatch(dir.Name)) { Match match = reg.Match(dir.Name); Dates.Add(Convert.ToInt64(match.Groups[1].Value)); } } long OldestDate = 0; - foreach (long date in Dates) - { - if (OldestDate == 0) - { + foreach (long date in Dates) { + if (OldestDate == 0) { OldestDate = date; } - else if (date < OldestDate) - { + else if (date < OldestDate) { OldestDate = date; } } Directory.Delete($@"{backupDir}\Backup_{OldestDate}", true); } } - catch (Exception e) - { - if (e.GetType() == typeof(FormatException)) - { + catch (Exception e) { + if (e.GetType() == typeof(FormatException)) { _logger.AppendLine("Error in Config! MaxBackupCount must be nothing but a number!"); } } DirectoryInfo targetDirectory = backupDir.CreateSubdirectory($"Backup_{DateTime.Now.Ticks}"); _logger.AppendLine($"Backing up files for server {_serverConfiguration.GetServerName()}. Please wait!"); - if (_serviceConfiguration.GetProp("EntireBackups").ToString() == "false") - { - new FileUtils(_servicePath).CopyFilesRecursively(worldsDir, targetDirectory); - return true; + if (_serviceConfiguration.GetProp("EntireBackups").ToString() == "false") { + bool resuilt = fileUtils.BackupWorldFilesFromQuery(backupFileInfoPairs, worldsDir.FullName, $@"{targetDirectory.FullName}").Result; + WriteToStandardIn("save resume"); + return resuilt; } - new FileUtils(_servicePath).CopyFilesRecursively(serverDir, targetDirectory); - return true; + fileUtils.CopyFilesRecursively(serverDir, targetDirectory); + bool result = fileUtils.BackupWorldFilesFromQuery(backupFileInfoPairs, worldsDir.FullName, $@"{targetDirectory.FullName}\{_serverConfiguration.GetProp("level-name")}").Result; + WriteToStandardIn("save resume"); + return result; } - catch (Exception e) - { + catch (Exception e) { _logger.AppendLine($"Error with Backup: {e.StackTrace}"); return false; } } - public void StopWatchdog() - { - if(_watchdogThread != null) - _watchdogThread.CloseThread(); - _watchdogThread = null; - } - public ServerStatus GetServerStatus() => _currentServerStatus; public void SetServerStatus(ServerStatus newStatus) => _currentServerStatus = newStatus; - private void ApplicationWatchdogMonitor() - { - while (_watchdogThread.IsAlive()) - { - string exeName = _serverConfiguration.GetProp("ServerExeName").ToString(); - string appName = exeName.Substring(0, exeName.Length - 4); - if (!MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Starting) - { - StartControl(); - _logger.AppendLine($"Recieved start signal for server {_serverConfiguration.GetServerName()}."); - Thread.Sleep(15000); - } - while (MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Started) - { - Thread.Sleep(5000); - } - if (MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Stopping) - { - _logger.AppendLine($"BedrockService signaled stop to application {appName}."); - _logger.AppendLine("Stopping..."); - StopControl(); - while (_currentServerStatus == ServerStatus.Stopping) - { - Thread.Sleep(250); + private Task ApplicationWatchdogMonitor() { + return new Task(() => { + while (true) { + if (_watchdogCanceler.IsCancellationRequested) { + _logger.AppendLine("WatchDog Task was canceled. Stopping server!"); + StopControl(); + return; } + string exeName = _serverConfiguration.GetProp("ServerExeName").ToString(); + string appName = exeName.Substring(0, exeName.Length - 4); + if (MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Starting) { + _logger.AppendLine($"BedrockService found {appName} already running! Killing to proceed..."); + KillProcesses(Process.GetProcessesByName(appName)); + } + if (MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Stopping) { + _logger.AppendLine($"BedrockService signaled stop to application {appName}."); + _logger.AppendLine("Stopping..."); + StopControl(); + while (_currentServerStatus == ServerStatus.Stopping) { + Task.Delay(500).Wait(); + } + } + if (!MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Starting) { + StartControl(); + _logger.AppendLine($"Recieved start signal for server {_serverConfiguration.GetServerName()}."); + Task.Delay(25000).Wait(); + } + if (!MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Started) { + StopControl(); + _logger.AppendLine($"Started application {appName} was not found in running processes... Resarting {appName}."); + StartControl(); + Task.Delay(1500).Wait(); + } + if (!MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Stopped) { + _logger.AppendLine("Server stopped successfully."); + } + if (!MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Stopping) { + _logger.AppendLine("Server stopped unexpectedly. Setting server status to stopped."); + _currentServerStatus = ServerStatus.Stopped; + } + if (!MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Stopped && Program.IsExiting) { + return; + } + Task.Delay(3000).Wait(); } - if (!MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Started) - { - StopControl(); - _logger.AppendLine($"Started application {appName} was not found in running processes... Resarting {appName}."); - StartControl(); - Thread.Sleep(1500); - } - if (!MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Stopped) - { - _logger.AppendLine("Server stopped successfully."); - } - if (!MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Stopping) - { - _logger.AppendLine("Server stopped unexpectedly. Setting server status to stopped."); - _currentServerStatus = ServerStatus.Stopped; - } - while (!MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Stopped && !Program.IsExiting) - { - Thread.Sleep(1000); - } - if (!MonitoredAppExists(appName) && _currentServerStatus == ServerStatus.Stopped && Program.IsExiting) - { - return; - } - - } + }, _watchdogCanceler.Token); } - public bool RestartServer(bool ShouldPerformBackup) - { - if (_currentServerStatus == ServerStatus.Started) - { + public bool RestartServer(bool ShouldPerformBackup) { + if (_currentServerStatus == ServerStatus.Started) { _currentServerStatus = ServerStatus.Stopping; - while (_currentServerStatus == ServerStatus.Stopping) - { + while (_currentServerStatus == ServerStatus.Stopping) { Thread.Sleep(100); } - if (ShouldPerformBackup) - { - if (!Backup()) - return false; - } _currentServerStatus = ServerStatus.Starting; } return false; @@ -241,49 +206,40 @@ public bool RestartServer(bool ShouldPerformBackup) public string GetServerName() => _serverConfiguration.GetServerName(); - private void RunServer() - { - string exeName = _serverConfiguration.GetProp("ServerExeName").ToString(); - string appName = exeName.Substring(0, exeName.Length - 4); - _configurator.WriteJSONFiles(_serverConfiguration); - _configurator.SaveServerProps(_serverConfiguration, false); - - try - { - if (File.Exists($@"{_serverConfiguration.GetProp("ServerPath")}\{_serverConfiguration.GetProp("ServerExeName")}")) - { - if (MonitoredAppExists(appName)) - { - Process[] processList = Process.GetProcessesByName(appName); - if (processList.Length != 0) - { - _logger.AppendLine($@"Application {appName} was found running! Killing to proceed."); - KillProcess(processList); + private Task RunServer() { + return new Task(() => { + string exeName = _serverConfiguration.GetProp("ServerExeName").ToString(); + string appName = exeName.Substring(0, exeName.Length - 4); + _configurator.WriteJSONFiles(_serverConfiguration); + _configurator.SaveServerProps(_serverConfiguration, false); + + try { + if (File.Exists($@"{_serverConfiguration.GetProp("ServerPath")}\{_serverConfiguration.GetProp("ServerExeName")}")) { + if (MonitoredAppExists(appName)) { + Process[] processList = Process.GetProcessesByName(appName); + if (processList.Length != 0) { + _logger.AppendLine($@"Application {appName} was found running! Killing to proceed."); + KillProcesses(processList); + } } + // Fires up a new process to run inside this one + CreateProcess(); + } + else { + _logger.AppendLine($"The Bedrock Server is not accessible at {$@"{_serverConfiguration.GetProp("ServerPath")}\{_serverConfiguration.GetProp("ServerExeName")}"}\r\nCheck if the file is at that location and that permissions are correct."); + _hostController.Stop(); } - // Fires up a new process to run inside this one - CreateProcess(); } - else - { - _logger.AppendLine($"The Bedrock Server is not accessible at {$@"{_serverConfiguration.GetProp("ServerPath")}\{_serverConfiguration.GetProp("ServerExeName")}"}\r\nCheck if the file is at that location and that permissions are correct."); + catch (Exception e) { + _logger.AppendLine($"Error Running Bedrock Server: {e.Message}\n{e.StackTrace}"); _hostController.Stop(); } - } - catch (Exception e) - { - _logger.AppendLine($"Error Running Bedrock Server: {e.Message}\n{e.StackTrace}"); - _hostController.Stop(); - - } - + }, _serverCanceler.Token); } - private void CreateProcess() - { + private void CreateProcess() { string fileName = $@"{_serverConfiguration.GetProp("ServerPath")}\{_serverConfiguration.GetProp("ServerExeName")}"; - _serverProcess = Process.Start(new ProcessStartInfo - { + _serverProcess = Process.Start(new ProcessStartInfo { UseShellExecute = false, RedirectStandardError = true, RedirectStandardInput = true, @@ -298,68 +254,53 @@ private void CreateProcess() _stdInStream = _serverProcess.StandardInput; } - private void KillProcess(Process[] processList) - { - foreach (Process process in processList) - { - try - { + private void KillProcesses(Process[] processList) { + foreach (Process process in processList) { + try { process.Kill(); Thread.Sleep(1000); _logger.AppendLine($@"App {_serverConfiguration.GetProp("ServerExeName")} killed!"); } - catch (Exception e) - { + catch (Exception e) { _logger.AppendLine($"Killing proccess resulted in error: {e.StackTrace}"); } } } - private bool MonitoredAppExists(string monitoredAppName) - { - try - { + private bool MonitoredAppExists(string monitoredAppName) { + try { Process[] processList = Process.GetProcessesByName(monitoredAppName); - if (processList.Length == 0) - { + if (processList.Length == 0) { return false; } - else - { + else { return true; } } - catch (Exception ex) - { + catch (Exception ex) { _logger.AppendLine("ApplicationWatcher MonitoredAppExists Exception: " + ex.StackTrace); return true; } } - private void StdOutToLog(object sender, DataReceivedEventArgs e) - { - if (e.Data != null && !e.Data.Contains("[INFO] Running AutoCompaction...")) - { + private void StdOutToLog(object sender, DataReceivedEventArgs e) { + if (e.Data != null && !e.Data.Contains("INFO] Running AutoCompaction...")) { string dataMsg = e.Data; string logFileText = "NO LOG FILE! - "; if (dataMsg.StartsWith(logFileText)) dataMsg = dataMsg.Substring(logFileText.Length, dataMsg.Length - logFileText.Length); _serverLogger.AppendText($"{_serverConfiguration.GetServerName()}: {dataMsg}\r\n"); - if (e.Data != null) - { + if (e.Data != null) { - if (dataMsg.Contains(_startupMessage)) - { + if (dataMsg.Contains(_startupMessage)) { _currentServerStatus = ServerStatus.Started; - Thread.Sleep(1000); + Task.Delay(3000).Wait(); - if (_serverConfiguration.GetStartCommands().Count > 0) - { + if (_serverConfiguration.GetStartCommands().Count > 0) { RunStartupCommands(); } } - if (dataMsg.StartsWith("[INFO] Player connected")) - { + if (dataMsg.StartsWith("[INFO] Player connected")) { int usernameStart = dataMsg.IndexOf(':') + 2; int usernameEnd = dataMsg.IndexOf(','); int usernameLength = usernameEnd - usernameStart; @@ -370,8 +311,7 @@ private void StdOutToLog(object sender, DataReceivedEventArgs e) _playerManager.PlayerConnected(username, xuid); _configurator.SaveKnownPlayerDatabase(_serverConfiguration); } - if (dataMsg.StartsWith("[INFO] Player disconnected")) - { + if (dataMsg.StartsWith("[INFO] Player disconnected")) { int usernameStart = dataMsg.IndexOf(':') + 2; int usernameEnd = dataMsg.IndexOf(','); int usernameLength = usernameEnd - usernameStart; @@ -382,55 +322,58 @@ private void StdOutToLog(object sender, DataReceivedEventArgs e) _playerManager.PlayerDisconnected(xuid); _configurator.SaveKnownPlayerDatabase(_serverConfiguration); } - if (dataMsg.Contains("Failed to load Vanilla")) - { + if (dataMsg.Contains("Failed to load Vanilla")) { _currentServerStatus = ServerStatus.Stopping; while (_currentServerStatus != ServerStatus.Stopped) Thread.Sleep(200); if (_configurator.ReplaceServerBuild(_serverConfiguration).Wait(30000)) _currentServerStatus = ServerStatus.Starting; } - if(dataMsg.Contains("Version ")) - { + if (dataMsg.Contains("Version ")) { int msgStartIndex = dataMsg.IndexOf(']') + 2; string focusedMsg = dataMsg.Substring(msgStartIndex, dataMsg.Length - msgStartIndex); int versionIndex = focusedMsg.IndexOf(' ') + 1; string versionString = focusedMsg.Substring(versionIndex, focusedMsg.Length - versionIndex); string currentVersion = _serviceConfiguration.GetServerVersion(); - if (currentVersion != versionString) - { + if (currentVersion != versionString) { _logger.AppendLine($"Server {GetServerName()} version found out-of-date! Now updating!"); - StopServer().Wait(); + StopServer(false).Wait(); _configurator.ReplaceServerBuild(_serverConfiguration).Wait(); StartControl(); } } + if (dataMsg.Contains("A previous save has not been completed.")) { + Task.Delay(1000).Wait(); + WriteToStandardIn("save query"); + } + if (dataMsg.Contains($@"{_serverConfiguration.GetProp("level-name")}/db/")) { + _logger.AppendLine("Save data string detected! Performing backup now!"); + if (PerformBackup(dataMsg)) { + _logger.AppendLine($"Backup for server {_serverConfiguration.GetServerName()} Completed."); + return; + } + _logger.AppendLine($"Backup for server {_serverConfiguration.GetServerName()} Failed. Check logs!"); + } } } } - private void RunStartupCommands() - { - foreach (StartCmdEntry cmd in _serverConfiguration.GetStartCommands()) - { + private void RunStartupCommands() { + foreach (StartCmdEntry cmd in _serverConfiguration.GetStartCommands()) { _stdInStream.WriteLine(cmd.Command.Trim()); Thread.Sleep(1000); } } - public bool RollbackToBackup(byte serverIndex, string folderName) - { + public bool RollbackToBackup(byte serverIndex, string folderName) { IServerConfiguration server = _serviceConfiguration.GetServerInfoByIndex(serverIndex); - StopServer().Wait(); - try - { + StopServer(false).Wait(); + try { foreach (DirectoryInfo dir in new DirectoryInfo($@"{_serviceConfiguration.GetProp("BackupPath")}\{server.GetServerName()}").GetDirectories()) - if (dir.Name == folderName) - { + if (dir.Name == folderName) { new FileUtils(_servicePath).DeleteFilesRecursively(new DirectoryInfo($@"{server.GetProp("ServerPath")}\worlds"), false); _logger.AppendLine($"Deleted world folder contents."); - foreach (DirectoryInfo worldDir in new DirectoryInfo($@"{_serviceConfiguration.GetProp("BackupPath")}\{server.GetServerName()}\{folderName}").GetDirectories()) - { + foreach (DirectoryInfo worldDir in new DirectoryInfo($@"{_serviceConfiguration.GetProp("BackupPath")}\{server.GetServerName()}\{folderName}").GetDirectories()) { new FileUtils(_servicePath).CopyFilesRecursively(worldDir, new DirectoryInfo($@"{server.GetProp("ServerPath")}\worlds\{worldDir.Name}")); _logger.AppendLine($@"Copied {worldDir.Name} to path {server.GetProp("ServerPath")}\worlds"); } @@ -438,27 +381,25 @@ public bool RollbackToBackup(byte serverIndex, string folderName) return true; } } - catch (IOException e) - { + catch (IOException e) { _logger.AppendLine($"Error deleting selected backups! {e.Message}"); } return false; } - public ILogger GetLogger() => _serverLogger; + public IBedrockLogger GetLogger() => _serverLogger; public IPlayerManager GetPlayerManager() => _playerManager; - public Task StopServer() - { - return Task.Run(() => - { + public Task StopServer(bool stopWatchdog) { + return Task.Run(() => { _currentServerStatus = ServerStatus.Stopping; - while (_currentServerStatus != ServerStatus.Stopped) - { + while (_currentServerStatus != ServerStatus.Stopped) { Thread.Sleep(100); } - + if (stopWatchdog) { + _watchdogCanceler.Cancel(); + } }); } } diff --git a/BedrockService/Service/Server/IBedrockServer.cs b/BedrockService/Service/Server/IBedrockServer.cs index f9967d3b..4b064d0e 100644 --- a/BedrockService/Service/Server/IBedrockServer.cs +++ b/BedrockService/Service/Server/IBedrockServer.cs @@ -1,22 +1,17 @@ using BedrockService.Service.Server.Management; -using BedrockService.Shared.Interfaces; -using System.Threading.Tasks; -using Topshelf; -namespace BedrockService.Service.Server -{ - public interface IBedrockServer - { +namespace BedrockService.Service.Server { + public interface IBedrockServer { void StartWatchdog(HostControl hostControl); - void StopWatchdog(); string GetServerName(); void WriteToStandardIn(string command); bool RestartServer(bool shouldPerformBackup); bool RollbackToBackup(byte serverIndex, string folderName); - Task StopServer(); + Task StopServer(bool stopWatchdog); + void InitializeBackup(); BedrockServer.ServerStatus GetServerStatus(); void SetServerStatus(BedrockServer.ServerStatus newStatus); IPlayerManager GetPlayerManager(); - ILogger GetLogger(); + IBedrockLogger GetLogger(); } } diff --git a/BedrockService/Service/Server/Management/IPlayerManager.cs b/BedrockService/Service/Server/Management/IPlayerManager.cs index c3c0017b..41d9609d 100644 --- a/BedrockService/Service/Server/Management/IPlayerManager.cs +++ b/BedrockService/Service/Server/Management/IPlayerManager.cs @@ -1,10 +1,5 @@ -using BedrockService.Shared.Interfaces; -using System.Collections.Generic; - -namespace BedrockService.Service.Server.Management -{ - public interface IPlayerManager - { +namespace BedrockService.Service.Server.Management { + public interface IPlayerManager { IPlayer GetPlayerByXUID(string xuid); void SetPlayer(IPlayer player); List GetPlayers(); diff --git a/BedrockService/Service/Server/Management/PlayerManager.cs b/BedrockService/Service/Server/Management/PlayerManager.cs index c2238c39..3fa132b1 100644 --- a/BedrockService/Service/Server/Management/PlayerManager.cs +++ b/BedrockService/Service/Server/Management/PlayerManager.cs @@ -1,67 +1,50 @@ -using BedrockService.Shared.Classes; -using BedrockService.Shared.Interfaces; -using System; -using System.Collections.Generic; - -namespace BedrockService.Service.Server.Management -{ - public class PlayerManager : IPlayerManager - { +namespace BedrockService.Service.Server.Management { + public class PlayerManager : IPlayerManager { readonly IServerConfiguration _serverConfiguration; - readonly ILogger _logger; + readonly IBedrockLogger _logger; - public PlayerManager(IServerConfiguration serverConfiguration, ILogger logger) - { + public PlayerManager(IServerConfiguration serverConfiguration, IBedrockLogger logger) { this._serverConfiguration = serverConfiguration; this._logger = logger; } - public void PlayerConnected(string username, string xuid) - { + public void PlayerConnected(string username, string xuid) { IPlayer playerFound = _serverConfiguration.GetPlayerByXuid(xuid); - if (playerFound == null) - { + if (playerFound == null) { _serverConfiguration.AddUpdatePlayer(new Player(xuid, username, DateTime.Now.Ticks.ToString(), "0", "0", false, _serverConfiguration.GetProp("default-player-permission-level").ToString(), false)); return; } - playerFound.UpdateTimes(DateTime.Now.Ticks.ToString(), playerFound.GetTimes()[2]); + playerFound.UpdateTimes(DateTime.Now.Ticks.ToString(), playerFound.GetTimes().Disconn); _serverConfiguration.AddUpdatePlayer(playerFound); } - public void PlayerDisconnected(string xuid) - { + public void PlayerDisconnected(string xuid) { IPlayer playerFound = _serverConfiguration.GetPlayerByXuid(xuid); - string[] oldTimes = playerFound.GetTimes(); - playerFound.UpdateTimes(oldTimes[1], DateTime.Now.Ticks.ToString()); + var oldTimes = playerFound.GetTimes(); + playerFound.UpdateTimes(oldTimes.Conn, DateTime.Now.Ticks.ToString()); _serverConfiguration.AddUpdatePlayer(playerFound); } - public void UpdatePlayerFromCfg(string xuid, string username, string permission, string whitelisted, string ignoreMaxPlayerLimit) - { + public void UpdatePlayerFromCfg(string xuid, string username, string permission, string whitelisted, string ignoreMaxPlayerLimit) { IPlayer playerFound = _serverConfiguration.GetPlayerByXuid(xuid); - if (playerFound == null) - { + if (playerFound == null) { playerFound = new Player(_serverConfiguration.GetProp("default-player-permission-level").ToString()); playerFound.Initialize(xuid, username); } playerFound.UpdateRegistration(permission, whitelisted, ignoreMaxPlayerLimit); } - public IPlayer GetPlayerByXUID(string xuid) - { + public IPlayer GetPlayerByXUID(string xuid) { if (GetPlayers().Count > 0) return _serverConfiguration.GetPlayerByXuid(xuid); return null; } - public void SetPlayer(IPlayer player) - { - try - { + public void SetPlayer(IPlayer player) { + try { _serverConfiguration.GetPlayerList()[_serverConfiguration.GetPlayerList().IndexOf(player)] = player; } - catch - { + catch { _serverConfiguration.GetPlayerList().Add(player); } } diff --git a/BedrockService/Service/app.config b/BedrockService/Service/app.config new file mode 100644 index 00000000..312bb3f2 --- /dev/null +++ b/BedrockService/Service/app.config @@ -0,0 +1,3 @@ + + + diff --git a/BedrockService/Service/appsettings.Development.json b/BedrockService/Service/appsettings.Development.json new file mode 100644 index 00000000..c9294ca4 --- /dev/null +++ b/BedrockService/Service/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/BedrockService/Service/appsettings.json b/BedrockService/Service/appsettings.json new file mode 100644 index 00000000..93b64d37 --- /dev/null +++ b/BedrockService/Service/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} diff --git a/BedrockService/Service/mc_icon.ico b/BedrockService/Service/mc_icon.ico new file mode 100644 index 00000000..0c675e0b Binary files /dev/null and b/BedrockService/Service/mc_icon.ico differ diff --git a/BedrockService/ServiceTests/ConfiguratorTests.cs b/BedrockService/ServiceTests/ConfiguratorTests.cs new file mode 100644 index 00000000..6288a919 --- /dev/null +++ b/BedrockService/ServiceTests/ConfiguratorTests.cs @@ -0,0 +1,19 @@ +using BedrockService.Service; +using BedrockService.Service.Management; +using Microsoft.Extensions.DependencyInjection; +using System; +using Xunit; + +namespace ServiceTests { + public class ConfiguratorTests { + readonly IServiceProvider _services = + Program.CreateHostBuilder(new string[] { }).Build().Services; // one liner + IConfigurator myService; + + [Fact] + public void VerifyServiceInContainer() { + myService = _services.GetRequiredService(); + Assert.NotNull(myService); + } + } +} \ No newline at end of file diff --git a/BedrockService/ServiceTests/ServiceTests.cs b/BedrockService/ServiceTests/ServiceTests.cs new file mode 100644 index 00000000..29a39b36 --- /dev/null +++ b/BedrockService/ServiceTests/ServiceTests.cs @@ -0,0 +1,18 @@ +using BedrockService.Service; +using BedrockService.Service.Core.Interfaces; +using Microsoft.Extensions.DependencyInjection; +using System; +using Xunit; + +namespace ServiceTests { + public class ServiceTests { + readonly IServiceProvider _services = + Program.CreateHostBuilder(new string[] { }).Build().Services; // one liner + + [Fact] + public void VerifyServiceInContainer() { + IBedrockService myService = _services.GetRequiredService(); + Assert.NotNull(myService); + } + } +} \ No newline at end of file diff --git a/BedrockService/ServiceTests/ServiceTests.csproj b/BedrockService/ServiceTests/ServiceTests.csproj new file mode 100644 index 00000000..9bbe4d51 --- /dev/null +++ b/BedrockService/ServiceTests/ServiceTests.csproj @@ -0,0 +1,31 @@ + + + + net6.0-windows + enable + + false + + Debug;Release;Publish + + AnyCPU;x64 + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + +