From 91f97a65b2c6d1fad3a211a6739a49d9908f69a2 Mon Sep 17 00:00:00 2001 From: Michael VanOverbeek Date: Wed, 15 Feb 2017 21:30:58 +0000 Subject: [PATCH] whoa mud refactoring --- ShiftOS.Objects/MudAttributes.cs | 4 +- ShiftOS.Server/ChatBackend.cs | 7 +-- ShiftOS.Server/Core.cs | 15 +++-- ShiftOS.Server/LegionManager.cs | 14 ++--- ShiftOS.Server/MemoManager.cs | 6 +- ShiftOS.Server/PongHighscores.cs | 6 +- ShiftOS.Server/Program.cs | 99 +++++++++++++++++++++++++------ ShiftOS.Server/RemoteTerminal.cs | 10 ++-- ShiftOS.Server/SaveManager.cs | 14 ++--- ShiftOS.Server/ShiftnetBackend.cs | 4 +- ShiftOS.Server/ShopBackend.cs | 14 ++--- 11 files changed, 130 insertions(+), 63 deletions(-) diff --git a/ShiftOS.Objects/MudAttributes.cs b/ShiftOS.Objects/MudAttributes.cs index b3b7380..f944337 100644 --- a/ShiftOS.Objects/MudAttributes.cs +++ b/ShiftOS.Objects/MudAttributes.cs @@ -15,12 +15,14 @@ namespace ShiftOS.Objects /// This attribute can be used on a static method to make the multi-user domain server software see this method as a MUD request handler. /// /// The header ID of the request this method should handle. - public MudRequestAttribute(string rName) + public MudRequestAttribute(string rName, Type expected) { RequestName = rName; + ExpectedType = expected; } public string RequestName { get; private set; } + public Type ExpectedType { get; private set; } } [AttributeUsage(AttributeTargets.Method)] diff --git a/ShiftOS.Server/ChatBackend.cs b/ShiftOS.Server/ChatBackend.cs index a7b8462..b7ee1e3 100644 --- a/ShiftOS.Server/ChatBackend.cs +++ b/ShiftOS.Server/ChatBackend.cs @@ -115,7 +115,7 @@ namespace ShiftOS.Server public delegate void empty(); - [MudRequest("chat_getallchannels")] + [MudRequest("chat_getallchannels", null)] public static void GetAllChannels(string guid, object contents) { server.DispatchTo(new Guid(guid), new NetObject("chat_all", new ServerMessage @@ -126,11 +126,10 @@ namespace ShiftOS.Server })); } - [MudRequest("chat_send")] + [MudRequest("chat_send", typeof(ChatMessage))] public static void ReceiveMessage(string guid, object contents) { - var args = contents as Dictionary; - var msg = new ChatMessage(args["Username"] as string, args["SystemName"] as string, args["Message"] as string, args["Channel"] as string); + var msg = contents as ChatMessage; MessageReceived?.Invoke(guid, msg); } diff --git a/ShiftOS.Server/Core.cs b/ShiftOS.Server/Core.cs index 3a29151..88f0cc6 100644 --- a/ShiftOS.Server/Core.cs +++ b/ShiftOS.Server/Core.cs @@ -14,7 +14,7 @@ namespace ShiftOS.Server { public static class Core { - [MudRequest("getguid_reply")] + [MudRequest("getguid_reply", typeof(string))] public static void GuidBounce(string guid, object contents) { //The message's GUID was manipulated by the client to send to another client. @@ -28,7 +28,7 @@ namespace ShiftOS.Server } - [MudRequest("getguid_send")] + [MudRequest("getguid_send", typeof(string))] public static void GuidReceiver(string guid, object contents) { string usrname = contents as string; @@ -41,12 +41,12 @@ namespace ShiftOS.Server } - [MudRequest("script")] + [MudRequest("script", typeof(Dictionary))] public static void RunScript(string guid, object contents) { try { - var args = JsonConvert.DeserializeObject>(JsonConvert.SerializeObject(contents)); + var args = contents as Dictionary; string user = ""; string script = ""; @@ -85,7 +85,12 @@ namespace ShiftOS.Server } catch { - throw new MudException($"Command parse error."); + Program.server.DispatchTo(new Guid(guid), new NetObject("error", new ServerMessage + { + Name = "Error", + GUID = "Server", + Contents = JsonConvert.SerializeObject(new MudException("Command parse error")) + })); } } diff --git a/ShiftOS.Server/LegionManager.cs b/ShiftOS.Server/LegionManager.cs index 452b216..27170f9 100644 --- a/ShiftOS.Server/LegionManager.cs +++ b/ShiftOS.Server/LegionManager.cs @@ -13,14 +13,14 @@ namespace ShiftOS.Server { public static class LegionManager { - [MudRequest("legion_createnew")] + [MudRequest("legion_createnew", typeof(Legion))] public static void CreateLegion(string guid, object contents) { List legions = new List(); if (File.Exists("legions.json")) legions = JsonConvert.DeserializeObject>(File.ReadAllText("legions.json")); - var l = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(contents)); + var l = contents as Legion; bool legionExists = false; foreach (var legion in legions) @@ -52,7 +52,7 @@ namespace ShiftOS.Server } - [MudRequest("legion_get_all")] + [MudRequest("legion_get_all", null)] public static void GetAllLegions(string guid, object contents) { List allLegions = new List(); @@ -69,10 +69,10 @@ namespace ShiftOS.Server } - [MudRequest("legion_get_users")] + [MudRequest("legion_get_users", typeof(Legion))] public static void GetLegionUsers(string guid, object contents) { - var lgn = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(contents)); + var lgn = contents as Legion; List userIDs = new List(); @@ -98,10 +98,10 @@ namespace ShiftOS.Server } - [MudRequest("user_get_legion")] + [MudRequest("user_get_legion", typeof(Save))] public static void GetUserLegion(string guid, object contents) { - var userSave = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(contents)); + var userSave = contents as Save; if (File.Exists("legions.json")) { diff --git a/ShiftOS.Server/MemoManager.cs b/ShiftOS.Server/MemoManager.cs index ed0a2e9..7251dc8 100644 --- a/ShiftOS.Server/MemoManager.cs +++ b/ShiftOS.Server/MemoManager.cs @@ -13,7 +13,7 @@ namespace ShiftOS.Server { public static class MemoManager { - [MudRequest("get_memos_for_user")] + [MudRequest("get_memos_for_user", typeof(Dictionary))] public static void GetMemosForUser(string guid, object contents) { var args = contents as Dictionary; @@ -44,10 +44,10 @@ namespace ShiftOS.Server } - [MudRequest("mud_postmemo")] + [MudRequest("mud_postmemo", typeof(MUDMemo))] public static void PostMemo(string guid, object contents) { - MUDMemo memo = JsonConvert.DeserializeObject(contents as string); + MUDMemo memo = contents as MUDMemo; List memos = new List(); if (File.Exists("memos.json")) diff --git a/ShiftOS.Server/PongHighscores.cs b/ShiftOS.Server/PongHighscores.cs index a06c4c2..fe5ddf2 100644 --- a/ShiftOS.Server/PongHighscores.cs +++ b/ShiftOS.Server/PongHighscores.cs @@ -13,7 +13,7 @@ namespace ShiftOS.Server { public static class PongHighscores { - [MudRequest("pong_gethighscores")] + [MudRequest("pong_gethighscores", null)] public static void GetHighScores(string guid, object contents) { if (File.Exists("pong_highscores.json")) @@ -28,14 +28,14 @@ namespace ShiftOS.Server } - [MudRequest("pong_sethighscores")] + [MudRequest("pong_sethighscores", typeof(PongHighscore))] public static void PostHighscores(string guid, object contents) { var hs = new List(); if (File.Exists("pong_highscores.json")) hs = JsonConvert.DeserializeObject>(File.ReadAllText("pong_highscores.json")); - var newHS = JsonConvert.DeserializeObject(contents as string); + var newHS = contents as PongHighscore; for (int i = 0; i <= hs.Count; i++) { try diff --git a/ShiftOS.Server/Program.cs b/ShiftOS.Server/Program.cs index 69571d0..376f95f 100644 --- a/ShiftOS.Server/Program.cs +++ b/ShiftOS.Server/Program.cs @@ -36,6 +36,7 @@ using System.Net.Sockets; using System.Security.Cryptography; using System.IO.Compression; using System.Reflection; +using System.Threading; namespace ShiftOS.Server { @@ -230,36 +231,96 @@ namespace ShiftOS.Server { foreach (var attrib in method.GetCustomAttributes(false)) { - if (attrib is MudRequestAttribute) + new Thread(() => { - if ((attrib as MudRequestAttribute).RequestName == msg.Name) + if (attrib is MudRequestAttribute) { - try + var mAttrib = attrib as MudRequestAttribute; + if (mAttrib.RequestName == msg.Name) { - object contents = msg.Contents; try { - contents = JsonConvert.DeserializeObject>(msg.Contents); + object contents = null; + bool throwOnNull = false; + + + if(mAttrib.ExpectedType == typeof(int)) + { + int result = 0; + if (int.TryParse(msg.Contents, out result) == true) + { + contents = result; + } + else + { + throw new MudException($"Protocol error: {msg.Name} expects a 32-bit signed integer for the message contents."); + } + } + else if(mAttrib.ExpectedType == typeof(long)) + { + long result = 0; + if (long.TryParse(msg.Contents, out result) == true) + { + contents = result; + } + else + { + throw new MudException($"Protocol error: {msg.Name} expects a 64-bit signed integer for the message contents."); + } + } + else if(mAttrib.ExpectedType == typeof(bool)) + { + throwOnNull = true; + if(msg.Contents.ToLower() == "true") + { + contents = true; + } + else if (msg.Contents.ToLower() == "false") + { + contents = false; + } + else + { + contents = null; + throw new MudException("Protocol error: " + msg.Name + " expects a content type of 'boolean'. Please send either 'true' or 'false'."); + } + } + else if(mAttrib.ExpectedType == null) + { + throwOnNull = false; + } + else + { + //object type + object result = null; + try + { + result = Convert.ChangeType(JsonConvert.DeserializeObject(msg.Contents), mAttrib.ExpectedType); + } + catch + { + result = null; + } + if (result == null) + throw new MudException($"Protocol error: {msg.Name} expects an object of type {mAttrib.ExpectedType.FullName}. Please send a JSON string representing an object of this type."); + contents = result; + } + + method?.Invoke(null, new[] { msg.GUID, contents }); + } + catch (Exception mEx) + { + Console.WriteLine(mEx); + ClientDispatcher.DispatchTo("Error", msg.GUID, mEx); } catch { - + Console.WriteLine($@"[{DateTime.Now}] {method.Name}: Missing guid and content parameters, request handler NOT RAN."); } - - method?.Invoke(null, new[] { msg.GUID, contents }); + return; } - catch (Exception mEx) - { - Console.WriteLine(mEx); - ClientDispatcher.DispatchTo("Error", msg.GUID, mEx); - } - catch - { - Console.WriteLine($@"[{DateTime.Now}] {method.Name}: Missing guid and content parameters, request handler NOT RAN."); - } - return; } - } + }).Start(); } } } diff --git a/ShiftOS.Server/RemoteTerminal.cs b/ShiftOS.Server/RemoteTerminal.cs index 6742e44..c78aca1 100644 --- a/ShiftOS.Server/RemoteTerminal.cs +++ b/ShiftOS.Server/RemoteTerminal.cs @@ -11,7 +11,7 @@ namespace ShiftOS.Server { public static class RemoteTerminal { - [MudRequest("trm_handshake_accept")] + [MudRequest("trm_handshake_accept", typeof(Dictionary))] public static void AcceptHandshake(string guid, object contents) { var args = contents as Dictionary; @@ -26,7 +26,7 @@ namespace ShiftOS.Server } } - [MudRequest("trm_invcmd")] + [MudRequest("trm_invcmd", typeof(Dictionary))] public static void InvokeCommand(string guid, object contents) { Console.WriteLine("Before arg check"); @@ -48,7 +48,7 @@ namespace ShiftOS.Server } - [MudRequest("trm_handshake_request")] + [MudRequest("trm_handshake_request", typeof(Dictionary))] public static void RequestHandshake(string guid, object contents) { var args = contents as Dictionary; @@ -63,7 +63,7 @@ namespace ShiftOS.Server } } - [MudRequest("trm_handshake_stop")] + [MudRequest("trm_handshake_stop", typeof(Dictionary))] public static void StopSession(string guid, object contents) { var args = contents as Dictionary; @@ -78,7 +78,7 @@ namespace ShiftOS.Server } - [MudRequest("write")] + [MudRequest("write", typeof(Dictionary))] public static void WriteText(string guid, object contents) { var args = contents as Dictionary; diff --git a/ShiftOS.Server/SaveManager.cs b/ShiftOS.Server/SaveManager.cs index 785bdec..fcca2bb 100644 --- a/ShiftOS.Server/SaveManager.cs +++ b/ShiftOS.Server/SaveManager.cs @@ -13,7 +13,7 @@ namespace ShiftOS.Server { public static class SaveManager { - [MudRequest("usr_getcp")] + [MudRequest("usr_getcp", typeof(Dictionary))] public static void GetCodepoints(string guid, object contents) { var args = contents as Dictionary; @@ -34,7 +34,7 @@ namespace ShiftOS.Server } - [MudRequest("mud_login")] + [MudRequest("mud_login", typeof(Dictionary))] public static void UserLogin(string guid, object contents) { var args = contents as Dictionary; @@ -78,7 +78,7 @@ namespace ShiftOS.Server } - [MudRequest("mud_checkuserexists")] + [MudRequest("mud_checkuserexists", typeof(Dictionary))] public static void CheckUserExists(string guid, object contents) { var args = contents as Dictionary; @@ -120,10 +120,10 @@ namespace ShiftOS.Server } - [MudRequest("mud_save")] + [MudRequest("mud_save", typeof(Save))] public static void SaveGame(string guid, object contents) { - var sav = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(contents)); + var sav = contents as Save; WriteEncFile("saves/" + sav.Username + ".save", JsonConvert.SerializeObject(sav, Formatting.Indented)); @@ -139,7 +139,7 @@ namespace ShiftOS.Server catch { } } - [MudRequest("usr_givecp")] + [MudRequest("usr_givecp", typeof(Dictionary))] public static void GiveCodepoints(string guid, object contents) { var args = contents as Dictionary; @@ -171,7 +171,7 @@ namespace ShiftOS.Server } - [MudRequest("usr_takecp")] + [MudRequest("usr_takecp", typeof(Dictionary))] public static void TakeCodepoints(string guid, object contents) { var args = contents as Dictionary; diff --git a/ShiftOS.Server/ShiftnetBackend.cs b/ShiftOS.Server/ShiftnetBackend.cs index 701021d..3241298 100644 --- a/ShiftOS.Server/ShiftnetBackend.cs +++ b/ShiftOS.Server/ShiftnetBackend.cs @@ -13,7 +13,7 @@ namespace ShiftOS.Server { public static class ShiftnetBackend { - [MudRequest("download_start")] + [MudRequest("download_start", typeof(string))] public static void StartDownload(string guid, object contents) { string url = contents as string; @@ -54,7 +54,7 @@ The page you requested at was not found on this multi-user domain." } - [MudRequest("shiftnet_get")] + [MudRequest("shiftnet_get", typeof(Dictionary))] public static void GetPage(string guid, object contents) { var args = contents as Dictionary; diff --git a/ShiftOS.Server/ShopBackend.cs b/ShiftOS.Server/ShopBackend.cs index 071417a..d8267b9 100644 --- a/ShiftOS.Server/ShopBackend.cs +++ b/ShiftOS.Server/ShopBackend.cs @@ -13,7 +13,7 @@ namespace ShiftOS.Server { public static class ShopBackend { - [MudRequest("update_shop_by_user")] + [MudRequest("update_shop_by_user", typeof(Dictionary))] public static void UpdateShopByUser(string guid, object contents) { var args = contents as Dictionary; @@ -37,7 +37,7 @@ namespace ShiftOS.Server Program.ClientDispatcher.DispatchTo("shop_added", guid, ""); } - [MudRequest("create_shop")] + [MudRequest("create_shop", typeof(Dictionary))] public static void CreateShop(string guid, object contents) { var args = contents as Dictionary; @@ -45,7 +45,7 @@ namespace ShiftOS.Server if (File.Exists("shops.json")) shopFile = JsonConvert.DeserializeObject>(File.ReadAllText("shops.json")); - var newShop = JsonConvert.DeserializeObject(contents as string); + var newShop = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(contents)); foreach (var shop in shopFile) { @@ -64,7 +64,7 @@ namespace ShiftOS.Server } - [MudRequest("user_shop_check")] + [MudRequest("user_shop_check", typeof(Dictionary))] public static void UserShopCheck(string guid, object contents) { var args = contents as Dictionary; @@ -85,7 +85,7 @@ namespace ShiftOS.Server Program.ClientDispatcher.DispatchTo("user_shop_check_result", guid, res.ToString()); } - [MudRequest("shop_getitems")] + [MudRequest("shop_getitems", typeof(Dictionary))] public static void GetShopItems(string guid, object contents) { var args = contents as Dictionary; @@ -111,7 +111,7 @@ namespace ShiftOS.Server } - [MudRequest("shop_getall")] + [MudRequest("shop_getall", null)] public static void GetAllShops(string guid, object contents) { var args = contents as Dictionary; @@ -129,7 +129,7 @@ namespace ShiftOS.Server Program.ClientDispatcher.DispatchTo("shop_all", guid, shops); } - [MudRequest("user_get_shop")] + [MudRequest("user_get_shop", typeof(string))] public static void GetShop(string guid, object contents) { string shopOwner = contents as string;