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;