diff options
Diffstat (limited to 'ShiftOS_TheReturn')
| -rw-r--r-- | ShiftOS_TheReturn/Command.cs | 6 | ||||
| -rw-r--r-- | ShiftOS_TheReturn/Commands.cs | 28 | ||||
| -rw-r--r-- | ShiftOS_TheReturn/KernelWatchdog.cs | 70 | ||||
| -rw-r--r-- | ShiftOS_TheReturn/SaveSystem.cs | 110 | ||||
| -rw-r--r-- | ShiftOS_TheReturn/ServerManager.cs | 7 | ||||
| -rw-r--r-- | ShiftOS_TheReturn/ShiftOS.Engine.csproj | 1 | ||||
| -rw-r--r-- | ShiftOS_TheReturn/Shiftorium.cs | 14 | ||||
| -rw-r--r-- | ShiftOS_TheReturn/Story.cs | 63 | ||||
| -rw-r--r-- | ShiftOS_TheReturn/TerminalBackend.cs | 156 |
9 files changed, 333 insertions, 122 deletions
diff --git a/ShiftOS_TheReturn/Command.cs b/ShiftOS_TheReturn/Command.cs index 85da6ca..a5924ed 100644 --- a/ShiftOS_TheReturn/Command.cs +++ b/ShiftOS_TheReturn/Command.cs @@ -30,6 +30,12 @@ using System.Threading.Tasks; namespace ShiftOS.Engine { + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] + public class KernelModeAttribute : Attribute + { + + } + public class Command : Attribute { public string name; diff --git a/ShiftOS_TheReturn/Commands.cs b/ShiftOS_TheReturn/Commands.cs index 76aa42f..0ea00e5 100644 --- a/ShiftOS_TheReturn/Commands.cs +++ b/ShiftOS_TheReturn/Commands.cs @@ -164,7 +164,35 @@ namespace ShiftOS.Engine } } + [Command("reconnect")] + [RequiresUpgrade("hacker101_deadaccts")] + public static bool Reconnect() + { + Console.WriteLine("--reconnecting to multi-user domain..."); + KernelWatchdog.MudConnected = true; + Console.WriteLine("--done."); + return true; + } + + [Command("disconnect")] + [RequiresUpgrade("hacker101_deadaccts")] + public static bool Disconnect() + { + Console.WriteLine("--connection to multi-user domain severed..."); + KernelWatchdog.MudConnected = false; + return true; + } + [Command("sendmsg")] + [KernelMode] + [RequiresUpgrade("hacker101_deadaccts")] + [RequiresArgument("header")] + [RequiresArgument("body")] + public static bool SendMessage(Dictionary<string, object> args) + { + ServerManager.SendMessage(args["header"].ToString(), args["body"].ToString()); + return true; + } } [RequiresUpgrade("mud_fundamentals")] diff --git a/ShiftOS_TheReturn/KernelWatchdog.cs b/ShiftOS_TheReturn/KernelWatchdog.cs new file mode 100644 index 0000000..1b59b25 --- /dev/null +++ b/ShiftOS_TheReturn/KernelWatchdog.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using static ShiftOS.Objects.ShiftFS.Utils; + +namespace ShiftOS.Engine +{ + public static class KernelWatchdog + { + public static void Log(string e, string desc) + { + string line = $"[{DateTime.Now}] <{e}> {desc}"; + if (FileExists("0:/system/data/kernel.log")) + { + string contents = ReadAllText("0:/system/data/kernel.log"); + contents += Environment.NewLine + line; + WriteAllText("0:/system/data/kernel.log", contents); + } + else + { + WriteAllText("0:/system/data/kernel.log", line); + } + } + + public static bool InKernelMode { get; private set; } + public static bool MudConnected { get; set; } + + public static bool IsSafe(Type type) + { + if (InKernelMode == true) + return true; + + foreach (var attrib in type.GetCustomAttributes(false)) + { + if (attrib is KernelModeAttribute) + return false; + } + return true; + } + + public static bool IsSafe(MethodInfo type) + { + if (InKernelMode == true) + return true; + + foreach (var attrib in type.GetCustomAttributes(false)) + { + if (attrib is KernelModeAttribute) + return false; + } + return true; + } + + + public static void EnterKernelMode() + { + InKernelMode = true; + Console.WriteLine("<kernel> Watchdog deactivated, system-level access granted."); + } + + public static void LeaveKernelMode() + { + InKernelMode = false; + Console.WriteLine("<kernel> Kernel mode disabled."); + } + } +} diff --git a/ShiftOS_TheReturn/SaveSystem.cs b/ShiftOS_TheReturn/SaveSystem.cs index 9ae18a9..df4c6d6 100644 --- a/ShiftOS_TheReturn/SaveSystem.cs +++ b/ShiftOS_TheReturn/SaveSystem.cs @@ -109,28 +109,35 @@ namespace ShiftOS.Engine bool guidReceived = false; ServerManager.GUIDReceived += (str) => { + //Connection successful! Stop waiting! guidReceived = true; - Console.WriteLine("{CONNECTION_SUCCESSFUL}"); + Console.WriteLine("Connection successful."); }; try { ServerManager.Initiate("secondary4162.cloudapp.net", 13370); - while(guidReceived == false) + //This haults the client until the connection is successful. + while (ServerManager.thisGuid == new Guid()) { } + Console.WriteLine("GUID received - bootstrapping complete."); + FinishBootstrap(); } catch (Exception ex) { + //No errors, this never gets called. Console.WriteLine("{ERROR}: " + ex.Message); Thread.Sleep(3000); ServerManager.StartLANServer(); - while (guidReceived == false) + while (ServerManager.thisGuid == new Guid()) { } + Console.WriteLine("GUID received - bootstrapping complete."); + FinishBootstrap(); } } else @@ -138,62 +145,71 @@ namespace ShiftOS.Engine ServerManager.StartLANServer(); } - ServerManager.MessageReceived += (msg) => - { - if(msg.Name == "mud_savefile") - { - CurrentSave = JsonConvert.DeserializeObject<Save>(msg.Contents); - } - else if(msg.Name == "mud_login_denied") - { - oobe.PromptForLogin(); - } - }; + //Nothing happens past this point - but the client IS connected! It shouldn't be stuck in that while loop above. - ReadSave(); + + })); + thread.IsBackground = true; + thread.Start(); + } - while(CurrentSave == null) - { + public static void FinishBootstrap() + { + KernelWatchdog.Log("mud_handshake", "handshake successful: kernel watchdog access code is \"" + ServerManager.thisGuid.ToString() + "\""); + ServerManager.MessageReceived += (msg) => + { + if (msg.Name == "mud_savefile") + { + CurrentSave = JsonConvert.DeserializeObject<Save>(msg.Contents); + } + else if (msg.Name == "mud_login_denied") + { + oobe.PromptForLogin(); } + }; - Shiftorium.Init(); + ReadSave(); - while (CurrentSave.StoryPosition < 1) - { + while (CurrentSave == null) + { - } + } - Thread.Sleep(75); + Shiftorium.Init(); - Thread.Sleep(50); - Console.WriteLine("{SYSTEM_INITIATED}"); + while (CurrentSave.StoryPosition < 1) + { - TerminalBackend.InStory = false; - TerminalBackend.PrefixEnabled = true; - Shiftorium.LogOrphanedUpgrades = true; + } + + Thread.Sleep(75); + + Thread.Sleep(50); + Console.WriteLine("{SYSTEM_INITIATED}"); + + TerminalBackend.InStory = false; + TerminalBackend.PrefixEnabled = true; + Shiftorium.LogOrphanedUpgrades = true; + Desktop.InvokeOnWorkerThread(new Action(() => + { + ShiftOS.Engine.Scripting.LuaInterpreter.RunSft(Paths.GetPath("kernel.sft")); + })); + Desktop.InvokeOnWorkerThread(new Action(() => Desktop.PopulateAppLauncher())); + if (CurrentSave.StoryPosition == 1) + { Desktop.InvokeOnWorkerThread(new Action(() => { - ShiftOS.Engine.Scripting.LuaInterpreter.RunSft(Paths.GetPath("kernel.sft")); + TutorialManager.StartTutorial(); + })); - Desktop.InvokeOnWorkerThread(new Action(() => Desktop.PopulateAppLauncher())); - if (CurrentSave.StoryPosition == 1) - { - Desktop.InvokeOnWorkerThread(new Action(() => - { - TutorialManager.StartTutorial(); - - })); - while(TutorialManager.IsInTutorial == true) { } - GameReady?.Invoke(); - } - else - { - GameReady?.Invoke(); - } - })); - thread.IsBackground = true; - thread.Start(); + while (TutorialManager.IsInTutorial == true) { } + GameReady?.Invoke(); + } + else + { + GameReady?.Invoke(); + } } public delegate void EmptyEventHandler(); @@ -299,7 +315,7 @@ namespace ShiftOS.Engine System.IO.File.WriteAllText(Paths.SaveFile, Utils.ExportMount(0)); } - public static void TransferCodepointsFrom(string who, int amount) + public static void TransferCodepointsFrom(string who, long amount) { NotificationDaemon.AddNotification(NotificationType.CodepointsReceived, amount); CurrentSave.Codepoints += amount; diff --git a/ShiftOS_TheReturn/ServerManager.cs b/ShiftOS_TheReturn/ServerManager.cs index 3059391..a121ab6 100644 --- a/ShiftOS_TheReturn/ServerManager.cs +++ b/ShiftOS_TheReturn/ServerManager.cs @@ -126,6 +126,13 @@ namespace ShiftOS.Engine thisGuid = new Guid(msg.Contents); GUIDReceived?.Invoke(msg.Contents); } + else if(msg.Name == "allusers") + { + foreach(var acc in JsonConvert.DeserializeObject<string[]>(msg.Contents)) + { + Console.WriteLine(acc); + } + } else if(msg.Name == "update_your_cp") { var args = JsonConvert.DeserializeObject<Dictionary<string, object>>(msg.Contents); diff --git a/ShiftOS_TheReturn/ShiftOS.Engine.csproj b/ShiftOS_TheReturn/ShiftOS.Engine.csproj index 3702b18..20ca879 100644 --- a/ShiftOS_TheReturn/ShiftOS.Engine.csproj +++ b/ShiftOS_TheReturn/ShiftOS.Engine.csproj @@ -107,6 +107,7 @@ <Compile Include="FileSkimmerBackend.cs" /> <Compile Include="Infobox.cs" /> <Compile Include="IShiftOSWindow.cs" /> + <Compile Include="KernelWatchdog.cs" /> <Compile Include="Localization.cs" /> <Compile Include="NotificationDaemon.cs" /> <Compile Include="OutOfBoxExperience.cs" /> diff --git a/ShiftOS_TheReturn/Shiftorium.cs b/ShiftOS_TheReturn/Shiftorium.cs index ab95f43..0bdd9f4 100644 --- a/ShiftOS_TheReturn/Shiftorium.cs +++ b/ShiftOS_TheReturn/Shiftorium.cs @@ -204,7 +204,19 @@ namespace ShiftOS.Engine } try { - return SaveSystem.CurrentSave.Upgrades[id]; + if (SaveSystem.CurrentSave == null) + return false; + + if (SaveSystem.CurrentSave.StoriesExperienced == null) + SaveSystem.CurrentSave.StoriesExperienced = new List<string>(); + + bool upgInstalled = false; + if(SaveSystem.CurrentSave.Upgrades.ContainsKey(id)) + upgInstalled = SaveSystem.CurrentSave.Upgrades[id]; + + if(upgInstalled == false) + return SaveSystem.CurrentSave.StoriesExperienced.Contains(id); + return true; } catch { diff --git a/ShiftOS_TheReturn/Story.cs b/ShiftOS_TheReturn/Story.cs index 9d8078e..ecd04f4 100644 --- a/ShiftOS_TheReturn/Story.cs +++ b/ShiftOS_TheReturn/Story.cs @@ -37,6 +37,48 @@ namespace ShiftOS.Engine { public class Story { + public static void Start(string stid) + { + foreach (var exec in System.IO.Directory.GetFiles(Environment.CurrentDirectory)) + { + if(exec.EndsWith(".exe") || exec.EndsWith(".dll")) + { + try + { + if (SaveSystem.CurrentSave.StoriesExperienced == null) + SaveSystem.CurrentSave.StoriesExperienced = new List<string>(); + var asm = Assembly.LoadFile(exec); + foreach(var type in asm.GetTypes()) + { + foreach(var mth in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) + { + foreach(var attrib in mth.GetCustomAttributes(false)) + { + if(attrib is StoryAttribute) + { + var story = attrib as StoryAttribute; + if(story.StoryID == stid) + { + mth.Invoke(null, null); + SaveSystem.CurrentSave.StoriesExperienced.Add(stid); + return; + } + } + } + } + } + } + catch { } + } + } +#if DEBUG + throw new ArgumentException("Story ID not found: " + stid + " - Talk to Michael. NOW."); +#else + Debug.Print("No such story: " + stid); +#endif + } + + public static void RunFromInternalResource(string resource_id) { var t = typeof(Properties.Resources); @@ -262,4 +304,25 @@ namespace ShiftOS.Engine thread.Start(); } } + + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] + public class StoryAttribute : Attribute + { + /// <summary> + /// Creates a new instance of the <see cref="StoryAttribute"/> attribute. + /// </summary> + /// <param name="id">The ID of this story plot.</param> + /// <remarks> + /// <para> + /// The <see cref="StoryAttribute"/> is used to turn a static, public method into a story element. Using the specified <paramref name="id"/> argument, the ShiftOS Engine can determine whether this plot has already been experienced, and using the <see cref="Shiftorium"/> classes, the ID is treated as a special Shiftorium upgrade, and you can use the <see cref="RequiresUpgradeAttribute"/> attribute as well as the various other ways of determining whether a Shiftorium upgrade is installed to determine if this plot has been experienced. + /// </para> + /// </remarks> + public StoryAttribute(string id) + { + StoryID = id; + } + + public string StoryID { get; private set; } + + } } diff --git a/ShiftOS_TheReturn/TerminalBackend.cs b/ShiftOS_TheReturn/TerminalBackend.cs index 3c8e62a..8be54d0 100644 --- a/ShiftOS_TheReturn/TerminalBackend.cs +++ b/ShiftOS_TheReturn/TerminalBackend.cs @@ -139,121 +139,129 @@ namespace ShiftOS.Engine { if (Shiftorium.UpgradeAttributesUnlocked(type)) { - foreach (var a in type.GetCustomAttributes(false)) + if (KernelWatchdog.IsSafe(type)) { - if (a is Namespace) + foreach (var a in type.GetCustomAttributes(false)) { - var ns = a as Namespace; - if (text.Split('.')[0] == ns.name) + if (a is Namespace) { - foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) + var ns = a as Namespace; + if (text.Split('.')[0] == ns.name) { - if (Shiftorium.UpgradeAttributesUnlocked(method)) + foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) { - if (CanRunRemotely(method, isRemote)) + if (Shiftorium.UpgradeAttributesUnlocked(method)) { - foreach (var ma in method.GetCustomAttributes(false)) + if (KernelWatchdog.IsSafe(method)) { - if (ma is Command) + if (CanRunRemotely(method, isRemote)) { - var cmd = ma as Command; - if (text.Split('.')[1] == cmd.name) + foreach (var ma in method.GetCustomAttributes(false)) { - - var attr = method.GetCustomAttribute<CommandObsolete>(); - - if (attr != null) + if (ma is Command) { - string newcommand = attr.newcommand; - if (attr.warn) + var cmd = ma as Command; + if (text.Split('.')[1] == cmd.name) { - Console.WriteLine(Localization.Parse((newcommand == "" ? "{ERROR}" : "{WARN}") + attr.reason, new Dictionary<string, string>() { + + var attr = method.GetCustomAttribute<CommandObsolete>(); + + if (attr != null) + { + string newcommand = attr.newcommand; + if (attr.warn) + { + Console.WriteLine(Localization.Parse((newcommand == "" ? "{ERROR}" : "{WARN}") + attr.reason, new Dictionary<string, string>() { {"%newcommand", newcommand} })); - } - if (newcommand != "") - { - // redo the entire process running newcommand - - return RunClient(newcommand, args); - } - } + } + if (newcommand != "") + { + // redo the entire process running newcommand - var requiresArgs = method.GetCustomAttributes<RequiresArgument>(); + return RunClient(newcommand, args); + } + } - bool error = false; - bool providedusage = false; + var requiresArgs = method.GetCustomAttributes<RequiresArgument>(); - foreach (RequiresArgument argument in requiresArgs) - { - if (!args.ContainsKey(argument.argument)) - { + bool error = false; + bool providedusage = false; - if (!providedusage) + foreach (RequiresArgument argument in requiresArgs) { - string usageparse = "{COMMAND_" + ns.name.ToUpper() + "_" + cmd.name.ToUpper() + "_USAGE}"; - if (usageparse == Localization.Parse(usageparse)) - usageparse = ""; - else - usageparse = Shiftorium.UpgradeInstalled("help_usage") ? Localization.Parse("{ERROR}{USAGE}" + usageparse, new Dictionary<string, string>() { + if (!args.ContainsKey(argument.argument)) + { + + if (!providedusage) + { + string usageparse = "{COMMAND_" + ns.name.ToUpper() + "_" + cmd.name.ToUpper() + "_USAGE}"; + if (usageparse == Localization.Parse(usageparse)) + usageparse = ""; + else + usageparse = Shiftorium.UpgradeInstalled("help_usage") ? Localization.Parse("{ERROR}{USAGE}" + usageparse, new Dictionary<string, string>() { {"%ns", ns.name}, {"%cmd", cmd.name} }) : ""; - Console.WriteLine(usageparse); + Console.WriteLine(usageparse); - providedusage = true; - } + providedusage = true; + } - if (Shiftorium.UpgradeInstalled("help_usage")) - { - Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED}", new Dictionary<string, string>() { + if (Shiftorium.UpgradeInstalled("help_usage")) + { + Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED}", new Dictionary<string, string>() { {"%argument", argument.argument} })); + } + else + { + Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED_NO_USAGE}")); + } + + error = true; + } } - else + + if (error) { - Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED_NO_USAGE}")); + throw new Exception("{ERROR_COMMAND_WRONG}"); } - error = true; + try + { + return (bool)method.Invoke(null, new[] { args }); + } + catch (TargetInvocationException e) + { + Console.WriteLine(Localization.Parse("{ERROR_EXCEPTION_THROWN_IN_METHOD}")); + Console.WriteLine(e.InnerException.Message); + Console.WriteLine(e.InnerException.StackTrace); + return true; + } + catch + { + return (bool)method.Invoke(null, new object[] { }); + } } } - - if (error) - { - throw new Exception("{ERROR_COMMAND_WRONG}"); - } - - try - { - return (bool)method.Invoke(null, new[] { args }); - } - catch (TargetInvocationException e) - { - Console.WriteLine(Localization.Parse("{ERROR_EXCEPTION_THROWN_IN_METHOD}")); - Console.WriteLine(e.InnerException.Message); - Console.WriteLine(e.InnerException.StackTrace); - return true; - } - catch - { - return (bool)method.Invoke(null, new object[] { }); - } } } + else + { + Console.WriteLine(text + " cannot be ran in a remote session"); + return true; + } } - } - else - { - Console.WriteLine(text + " cannot be ran in a remote session"); - return true; + } } } } } } + } } } |
