aboutsummaryrefslogtreecommitdiff
path: root/ShiftOS_TheReturn
diff options
context:
space:
mode:
Diffstat (limited to 'ShiftOS_TheReturn')
-rw-r--r--ShiftOS_TheReturn/Command.cs6
-rw-r--r--ShiftOS_TheReturn/Commands.cs28
-rw-r--r--ShiftOS_TheReturn/KernelWatchdog.cs70
-rw-r--r--ShiftOS_TheReturn/SaveSystem.cs110
-rw-r--r--ShiftOS_TheReturn/ServerManager.cs7
-rw-r--r--ShiftOS_TheReturn/ShiftOS.Engine.csproj1
-rw-r--r--ShiftOS_TheReturn/Shiftorium.cs14
-rw-r--r--ShiftOS_TheReturn/Story.cs63
-rw-r--r--ShiftOS_TheReturn/TerminalBackend.cs156
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;
+
}
}
}
}
}
}
+
}
}
}