From f30dcf5ef41d54c588d7b42c48be8d941abba72e Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 8 Jan 2017 09:57:10 -0500 Subject: Initial upload --- ShiftOS_TheReturn/AltTabWindow.Designer.cs | 42 + ShiftOS_TheReturn/AltTabWindow.cs | 29 + ShiftOS_TheReturn/AltTabWindow.resx | 120 +++ ShiftOS_TheReturn/App.config | 6 + ShiftOS_TheReturn/AppLauncherDaemon.cs | 67 ++ ShiftOS_TheReturn/AppearanceManager.cs | 184 ++++ ShiftOS_TheReturn/AudioManager.cs | 42 + ShiftOS_TheReturn/Command.cs | 93 ++ ShiftOS_TheReturn/Commands.cs | 524 +++++++++++ ShiftOS_TheReturn/CrashHandler.Designer.cs | 151 ++++ ShiftOS_TheReturn/CrashHandler.cs | 181 ++++ ShiftOS_TheReturn/CtrlTabMenu.cs | 26 + ShiftOS_TheReturn/Desktop.cs | 96 ++ ShiftOS_TheReturn/FileSkimmerBackend.cs | 152 ++++ ShiftOS_TheReturn/IShiftOSWindow.cs | 17 + ShiftOS_TheReturn/Infobox.cs | 38 + ShiftOS_TheReturn/Infobox.resx | 120 +++ ShiftOS_TheReturn/Localization.cs | 177 ++++ ShiftOS_TheReturn/OutOfBoxExperience.cs | 63 ++ ShiftOS_TheReturn/OutOfBoxExperience.cs.rej | 105 +++ ShiftOS_TheReturn/Paths.cs | 139 +++ ShiftOS_TheReturn/Program.cs | 46 + ShiftOS_TheReturn/Properties/AssemblyInfo.cs | 40 + ShiftOS_TheReturn/Properties/Resources.Designer.cs | 190 ++++ ShiftOS_TheReturn/Properties/Resources.resx | 142 +++ ShiftOS_TheReturn/Properties/Settings.Designer.cs | 26 + ShiftOS_TheReturn/Properties/Settings.settings | 7 + ShiftOS_TheReturn/Resources/Shiftorium.txt | 594 +++++++++++++ ShiftOS_TheReturn/Resources/Songs.txt | 4 + ShiftOS_TheReturn/Resources/hello.txt | 1 + ShiftOS_TheReturn/Resources/languages.txt | 4 + ShiftOS_TheReturn/Resources/secretlang.txt | 3 + ShiftOS_TheReturn/Resources/strings_de.txt | 225 +++++ ShiftOS_TheReturn/Resources/strings_en.txt | 222 +++++ ShiftOS_TheReturn/Resources/strings_ver.txt | 216 +++++ .../Resources/sys_shiftoriumstory.txt | 45 + ShiftOS_TheReturn/SaveSystem.cs | 268 ++++++ ShiftOS_TheReturn/Scripting.cs | 484 +++++++++++ ShiftOS_TheReturn/ServerManager.cs | 177 ++++ ShiftOS_TheReturn/ShiftOS.Engine.csproj | 261 ++++++ ShiftOS_TheReturn/Shiftorium.cs | 226 +++++ ShiftOS_TheReturn/Skinning.cs | 967 +++++++++++++++++++++ ShiftOS_TheReturn/Story.cs | 241 +++++ ShiftOS_TheReturn/TerminalBackend.cs | 211 +++++ ShiftOS_TheReturn/TerminalTextWriter.cs | 75 ++ ShiftOS_TheReturn/VirusEngine.cs | 158 ++++ ShiftOS_TheReturn/WinOpenAttribute.cs | 18 + ShiftOS_TheReturn/packages.config | 7 + 48 files changed, 7230 insertions(+) create mode 100644 ShiftOS_TheReturn/AltTabWindow.Designer.cs create mode 100644 ShiftOS_TheReturn/AltTabWindow.cs create mode 100644 ShiftOS_TheReturn/AltTabWindow.resx create mode 100644 ShiftOS_TheReturn/App.config create mode 100644 ShiftOS_TheReturn/AppLauncherDaemon.cs create mode 100644 ShiftOS_TheReturn/AppearanceManager.cs create mode 100644 ShiftOS_TheReturn/AudioManager.cs create mode 100644 ShiftOS_TheReturn/Command.cs create mode 100644 ShiftOS_TheReturn/Commands.cs create mode 100644 ShiftOS_TheReturn/CrashHandler.Designer.cs create mode 100644 ShiftOS_TheReturn/CrashHandler.cs create mode 100644 ShiftOS_TheReturn/CtrlTabMenu.cs create mode 100644 ShiftOS_TheReturn/Desktop.cs create mode 100644 ShiftOS_TheReturn/FileSkimmerBackend.cs create mode 100644 ShiftOS_TheReturn/IShiftOSWindow.cs create mode 100644 ShiftOS_TheReturn/Infobox.cs create mode 100644 ShiftOS_TheReturn/Infobox.resx create mode 100644 ShiftOS_TheReturn/Localization.cs create mode 100644 ShiftOS_TheReturn/OutOfBoxExperience.cs create mode 100644 ShiftOS_TheReturn/OutOfBoxExperience.cs.rej create mode 100644 ShiftOS_TheReturn/Paths.cs create mode 100644 ShiftOS_TheReturn/Program.cs create mode 100644 ShiftOS_TheReturn/Properties/AssemblyInfo.cs create mode 100644 ShiftOS_TheReturn/Properties/Resources.Designer.cs create mode 100644 ShiftOS_TheReturn/Properties/Resources.resx create mode 100644 ShiftOS_TheReturn/Properties/Settings.Designer.cs create mode 100644 ShiftOS_TheReturn/Properties/Settings.settings create mode 100644 ShiftOS_TheReturn/Resources/Shiftorium.txt create mode 100644 ShiftOS_TheReturn/Resources/Songs.txt create mode 100644 ShiftOS_TheReturn/Resources/hello.txt create mode 100644 ShiftOS_TheReturn/Resources/languages.txt create mode 100644 ShiftOS_TheReturn/Resources/secretlang.txt create mode 100644 ShiftOS_TheReturn/Resources/strings_de.txt create mode 100644 ShiftOS_TheReturn/Resources/strings_en.txt create mode 100644 ShiftOS_TheReturn/Resources/strings_ver.txt create mode 100644 ShiftOS_TheReturn/Resources/sys_shiftoriumstory.txt create mode 100644 ShiftOS_TheReturn/SaveSystem.cs create mode 100644 ShiftOS_TheReturn/Scripting.cs create mode 100644 ShiftOS_TheReturn/ServerManager.cs create mode 100644 ShiftOS_TheReturn/ShiftOS.Engine.csproj create mode 100644 ShiftOS_TheReturn/Shiftorium.cs create mode 100644 ShiftOS_TheReturn/Skinning.cs create mode 100644 ShiftOS_TheReturn/Story.cs create mode 100644 ShiftOS_TheReturn/TerminalBackend.cs create mode 100644 ShiftOS_TheReturn/TerminalTextWriter.cs create mode 100644 ShiftOS_TheReturn/VirusEngine.cs create mode 100644 ShiftOS_TheReturn/WinOpenAttribute.cs create mode 100644 ShiftOS_TheReturn/packages.config (limited to 'ShiftOS_TheReturn') diff --git a/ShiftOS_TheReturn/AltTabWindow.Designer.cs b/ShiftOS_TheReturn/AltTabWindow.Designer.cs new file mode 100644 index 0000000..8be3b32 --- /dev/null +++ b/ShiftOS_TheReturn/AltTabWindow.Designer.cs @@ -0,0 +1,42 @@ +namespace ShiftOS.Engine { + partial class AltTabWindow { + /// + /// 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.SuspendLayout(); + // + // AltTabWindow + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(284, 261); + this.Name = "AltTabWindow"; + this.Text = "AltTabWindow"; + this.Load += new System.EventHandler(this.AltTabWindow_Load); + this.ResumeLayout(false); + + } + + #endregion + } +} \ No newline at end of file diff --git a/ShiftOS_TheReturn/AltTabWindow.cs b/ShiftOS_TheReturn/AltTabWindow.cs new file mode 100644 index 0000000..b0c535e --- /dev/null +++ b/ShiftOS_TheReturn/AltTabWindow.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace ShiftOS.Engine { + public partial class AltTabWindow : Form { + public AltTabWindow() { + InitializeComponent(); + } + + internal void CycleBack() { + Console.WriteLine("Cycle Backwards"); + } + + internal void CycleForwards() { + Console.WriteLine("Cycle Forwards"); + } + + private void AltTabWindow_Load(object sender, EventArgs e) { + + } + } +} diff --git a/ShiftOS_TheReturn/AltTabWindow.resx b/ShiftOS_TheReturn/AltTabWindow.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/ShiftOS_TheReturn/AltTabWindow.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/ShiftOS_TheReturn/App.config b/ShiftOS_TheReturn/App.config new file mode 100644 index 0000000..88fa402 --- /dev/null +++ b/ShiftOS_TheReturn/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/ShiftOS_TheReturn/AppLauncherDaemon.cs b/ShiftOS_TheReturn/AppLauncherDaemon.cs new file mode 100644 index 0000000..8dc203a --- /dev/null +++ b/ShiftOS_TheReturn/AppLauncherDaemon.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using Newtonsoft.Json; + +namespace ShiftOS.Engine +{ + public static class AppLauncherDaemon + { + public static bool Contains(this AssemblyName[] asms, string name) + { + foreach(var asm in asms) + { + if (asm.FullName.Contains(name)) + return true; + } + return false; + } + + public static List Available() + { + List win = new List(); + + foreach (var asmExec in System.IO.Directory.GetFiles(Environment.CurrentDirectory)) + { + if (asmExec.EndsWith(".dll") | asmExec.EndsWith(".exe")) + { + var asm = Assembly.LoadFrom(asmExec); + + if (asm.GetReferencedAssemblies().Contains("ShiftOS.Engine") || asm.FullName.Contains("ShiftOS.Engine")) + { + foreach (var type in asm.GetTypes()) + { + if (type.GetInterfaces().Contains(typeof(IShiftOSWindow))) + { + foreach (var attr in type.GetCustomAttributes(false)) + { + if (attr is LauncherAttribute) + { + var launch = attr as LauncherAttribute; + if (launch.UpgradeInstalled) + { + win.Add(new LauncherItem { DisplayData = launch, LaunchType = type }); + } + } + } + } + } + } + } + } + return win; + } + + } + + public class LauncherItem + { + public LauncherAttribute DisplayData { get; internal set; } + public Type LaunchType { get; internal set; } + + } +} diff --git a/ShiftOS_TheReturn/AppearanceManager.cs b/ShiftOS_TheReturn/AppearanceManager.cs new file mode 100644 index 0000000..b600ad9 --- /dev/null +++ b/ShiftOS_TheReturn/AppearanceManager.cs @@ -0,0 +1,184 @@ +#define MUD_RAPIDDEV + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using Newtonsoft.Json; +using static ShiftOS.Engine.SaveSystem; + +namespace ShiftOS.Engine +{ + public static class AppearanceManager + { + [Obsolete("Please use Localization.GetAllLanguages().")] + public static string[] GetLanguages() + { + return Localization.GetAllLanguages(); + } + + public static void AddFocusEvents(Control ctrl, Control child) + { + child.Enter += (o, a) => + { + ctrl.BringToFront(); + }; + child.MouseDown += (o, a) => + { + ctrl.BringToFront(); + }; + + foreach (Control c in child.Controls) + { + c.Enter += (o, a) => + { + ctrl.BringToFront(); + }; + c.MouseDown += (o, a) => + { + ctrl.BringToFront(); + }; + + try + { + AddFocusEvents(ctrl, c); + } + catch { } + } + } + + + public static string LastTerminalText { get; set; } + public static int CurrentPosition { get; set; } + public static int LastLength { get; set; } + + + public static void Minimize(IWindowBorder form) + { + winmgr.Minimize(form); + } + + public static void Maximize(IWindowBorder form) + { + winmgr.Maximize(form); + } + + + + public static List OpenForms = new List(); + + public static bool CanOpenWindow(IShiftOSWindow form) + { +#if !MUD_RAPIDDEV + if (ServerManager.IsSingleplayer) + { + foreach (var attr in form.GetType().GetCustomAttributes(false)) + { + if (attr is MultiplayerOnlyAttribute) + return false; + } + } +#endif + return true; + } + + public static void SetupWindow(IShiftOSWindow form) + { + winmgr.SetupWindow(form); + Desktop.ResetPanelButtons(); + } + + public static void Close(IShiftOSWindow win) + { + winmgr.Close(win); + Desktop.ResetPanelButtons(); + } + + public static void SetupDialog(IShiftOSWindow form) + { + winmgr.SetupDialog(form); + Desktop.ResetPanelButtons(); + } + + private static WindowManager winmgr = null; + + public static double Measure(this string text, Font font) + { + return Graphics.FromImage(new Bitmap(1, 1)).MeasureString(text, font).Width; + } + + public static void Initiate(WindowManager mgr) + { + winmgr = mgr; + } + + [Obsolete("This is a stub.")] + public static void DoWinformsSkinningMagicOnWpf(this UserControl ctrl) + { + //SetupControls(ctrl); + } + + public static event EmptyEventHandler OnExit; + + internal static void Exit() + { + OnExit?.Invoke(); + //disconnect from MUD + ServerManager.Disconnect(); + } + + + internal static bool BordersHidden(Form frm) + { + string t = frm.Tag as string; + if (t == null) + return false; + + return t.Contains("hidden"); + } + + public static ITerminalWidget ConsoleOut { get; set; } + + public static void StartConsoleOut() + { + Console.SetOut(new TerminalTextWriter()); + } + + public static void Invoke(Action act) + { + winmgr.InvokeAction(act); + } + } + + public interface ITerminalWidget + { + void Write(string text); + void WriteLine(string text); + void Clear(); + void SelectBottom(); + } + + public abstract class WindowManager + { + public abstract void Minimize(IWindowBorder border); + public abstract void Maximize(IWindowBorder border); + + public abstract void Close(IShiftOSWindow win); + + public abstract void SetupWindow(IShiftOSWindow win); + public abstract void SetupDialog(IShiftOSWindow win); + + public abstract void InvokeAction(Action act); + } + + public interface IWindowBorder + { + void Close(); + string Text { get; set; } + IShiftOSWindow ParentWindow { get; set; } + } +} diff --git a/ShiftOS_TheReturn/AudioManager.cs b/ShiftOS_TheReturn/AudioManager.cs new file mode 100644 index 0000000..1bf63dc --- /dev/null +++ b/ShiftOS_TheReturn/AudioManager.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; +using WMPLib; + +namespace ShiftOS.Engine +{ + public static class AudioManager + { + public static WindowsMediaPlayer player = null; + + public static void Init() + { + player = new WindowsMediaPlayer(); + player.PlayStateChange += (o) => + { + switch ((WMPPlayState)o) + { + case WMPPlayState.wmppsPlaying: + case WMPPlayState.wmppsBuffering: + case WMPPlayState.wmppsReconnecting: + + break; + case WMPPlayState.wmppsReady: + PickRandomSong(); + break; + } + }; + PickRandomSong(); + } + + public static void PickRandomSong() + { + var lst = JsonConvert.DeserializeObject>(Properties.Resources.Songs); + + player.URL = lst[new Random().Next(0, lst.Count)]; + } + } +} diff --git a/ShiftOS_TheReturn/Command.cs b/ShiftOS_TheReturn/Command.cs new file mode 100644 index 0000000..e645a3e --- /dev/null +++ b/ShiftOS_TheReturn/Command.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShiftOS.Engine { + public class Command : Attribute { + public string name; + public string description = ""; + public string usage = ""; + public bool hide = false; + + public Command(string name) { + this.name = name; + } + public Command(string name, bool hide) { + this.name = name; + this.hide = hide; + } + public Command(string name, string usage, string description) { + this.name = name; + this.description = description; + this.usage = usage; + } + } + + public class RequiresUpgradeAttribute : Attribute { + public string Upgrade { get; set; } + public bool Installed { + get { + if (Upgrade.Contains(";")) { + string[] split = Upgrade.Split(';'); + foreach (var upg in split) { + if (!Shiftorium.UpgradeInstalled(upg)) + return false; + } + return true; + } else { + return Shiftorium.UpgradeInstalled(Upgrade); + } + } + } + + /// + /// Marks this Form or Command as dependant on this upgrade. + /// + /// Upgrade ID - See 'shiftorium.json' in resources for all IDs and their metadata. + public RequiresUpgradeAttribute(string upg) { + Upgrade = upg; + } + } + + public class Namespace : Attribute { + public string name; + public bool hide; + public Namespace(string n) { + name = n; + } + public Namespace(string n, bool hide) { + name = n; + this.hide = hide; + } + } + + [AttributeUsage(AttributeTargets.Method)] + public class CommandObsolete : Attribute { + public string reason; + public string newcommand; + public bool warn; + + public CommandObsolete(string reason, string newcommand, bool warn) { + this.reason = reason; // %n for newcommand + this.newcommand = newcommand; + this.warn = warn; + } + } + + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + public class RequiresArgument : Attribute { + public string argument; + + public RequiresArgument(string argument) { + this.argument = argument; + } + + public override object TypeId { + get { + return this; + } + } + } +} diff --git a/ShiftOS_TheReturn/Commands.cs b/ShiftOS_TheReturn/Commands.cs new file mode 100644 index 0000000..65281ba --- /dev/null +++ b/ShiftOS_TheReturn/Commands.cs @@ -0,0 +1,524 @@ +#define DEVEL + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using ShiftOS.Engine.Properties; +using System.IO; +using Newtonsoft.Json; +using System.IO.Compression; + +using ShiftOS.Objects; +using Discoursistency.Base.Models.Authentication; +using ShiftOS.Engine.Scripting; +using ShiftOS.Objects.ShiftFS; + +namespace ShiftOS.Engine { + [Namespace("virus")] + public class VirusTestCommands { + [Command("infect")] + public static void InfectFileWithMUDVirus(Dictionary args) { + string signature = ""; + + if (args.ContainsKey("signature")) + signature = args["signature"] as string; + else + throw new Exception("Virus signature not provided."); + + string script = ""; + + Action scriptFound = new Action((s) => { + script = s; + Virus v = new LuaVirus(s, 1); + VirusEngine.Add(v); + VirusEngine.Infect($"lua.{v.Signature}.1"); + }); + + ServerManager.MessageReceived += (srv) => { + if (srv.Name == "mud_virus") { + scriptFound?.Invoke(srv.Contents); + scriptFound = null; + } + }; + + ServerManager.SendMessage("getvirus", signature); + } + } + + + [RequiresUpgrade("mud_fundamentals")] + [Namespace("mud")] + public static class MUDCommands { + [Command("addvirus")] + public static void Virus_AddToDatabase(Dictionary args) { + string file = ""; + int threatLevel = 0; + + + if (args.ContainsKey("file")) + file = args["file"] as string; + else + throw new Exception("No 'file' argument provided."); + + if (args.ContainsKey("threatlevel")) + threatLevel = Convert.ToInt32(args["threatlevel"].ToString()); + + Virus lua = new LuaVirus(Utils.ReadAllText(file), threatLevel); + + Console.WriteLine("Virus uploaded to current multi-user domain successfully."); + + } + + + [Command("status")] + public static bool Status() { + ServerManager.PrintDiagnostics(); + return true; + } + + [Command("connect")] + public static bool Connect(Dictionary args) { + try { + string ip = (args.ContainsKey("addr") == true) ? args["addr"] as string : "michaeltheshifter.me"; + int port = (args.ContainsKey("port") == true) ? Convert.ToInt32(args["port"] as string) : 13370; + try { + ServerManager.Initiate(ip, port); + } catch (Exception ex) { + Console.WriteLine("{ERROR}: " + ex.Message); + } + return true; + } catch (Exception ex) { + Console.WriteLine("Error running script:" + ex); + return false; + } + } + + + } + + [RequiresUpgrade("mud_fundamentals")] + [Namespace("chat")] + public static class ChatCommands { + [RequiresArgument("id")] + [RequiresArgument("name")] + [RequiresArgument("topic")] + [Command("create")] + public static bool CreateChat(Dictionary args) { + string id = ""; + string topic = ""; + string name = ""; + int max_users = 0; + + id = args["id"] as string; + name = args["topic"] as string; + topic = args["name"] as string; + + bool valid = true; + + if (string.IsNullOrEmpty(id) || string.IsNullOrEmpty(name) || string.IsNullOrEmpty(topic)) + valid = false; + + if (valid) { + ServerManager.SendMessage("chat_create", $@"{{ + id: ""{id}"", + name: ""{name}"", + topic: ""{topic}"", + max_users: {max_users} +}}"); + } else { + Console.WriteLine("{CHAT_PLEASE_PROVIDE_VALID_CHANNEL_DATA}"); + } + return true; + } + + } + + [Namespace("trm")] + public static class TerminalCommands { + [Command("clear")] + public static bool Clear() { + AppearanceManager.ConsoleOut.Clear(); + return true; + } + } + +#if DEVEL + [Namespace("cheats", true)] + public static class CheatCommands { + [Command("freecp", true)] + [CommandObsolete("{OBSOLETE_CHEATS_FREECP}", "dev.freecp", true)] + public static bool FreeCodepoints(Dictionary args) { + // never called + return true; + } + } + [Namespace("dev")] + public static class ShiftOSDevCommands { + [Command("multarg")] + [RequiresArgument("id")] + [RequiresArgument("name")] + [RequiresArgument("type")] + public static bool MultArg(Dictionary args) { + return true; + } + + + [Command("freecp")] + public static bool FreeCodepoints(Dictionary args) { + if (args.ContainsKey("amount")) + try { + int codepointsToAdd = Convert.ToInt32(args["amount"].ToString()); + SaveSystem.TransferCodepointsFrom("dev", codepointsToAdd); + return true; + } catch (Exception ex) { + Console.WriteLine("{ERROR}: " + ex.Message); + return true; + } + + SaveSystem.TransferCodepointsFrom("dev", 1000); + return true; + } + + [Command("unlockeverything")] + public static bool GetAllUpgrades() { + foreach (var upg in Shiftorium.GetDefaults()) { + Shiftorium.Buy(upg.ID, 0); + } + return true; + } + + [Command("info")] + public static bool DevInformation() { + Console.WriteLine("{SHIFTOS_PLUS_MOTTO}"); + Console.WriteLine("{SHIFTOS_VERSION_INFO}" + Assembly.GetExecutingAssembly().GetName().Version); + return true; + } + [Command("pullfile")] + public static bool PullFile(Dictionary args) { + if (args.ContainsKey("physical") && args.ContainsKey("virtual")) { + string file = (string)args["physical"]; + string dest = (string)args["virtual"]; + if (System.IO.File.Exists(file)) { + Console.WriteLine("Pulling physical file to virtual drive..."); + byte[] filebytes = System.IO.File.ReadAllBytes(file); + ShiftOS.Objects.ShiftFS.Utils.WriteAllBytes(dest, filebytes); + } else { + Console.WriteLine("The specified file does not exist on the physical drive."); + } + } else { + Console.WriteLine("You must supply a physical path."); + } + return true; + } + [Command("crash")] + public static bool CrashInstantly() { + try { + throw new Exception("ShiftOS was sent a command to forcefully crash."); + } catch (Exception e) { + CrashHandler.Start(e); + return true; + } + } + } +#endif + + [Namespace("sos")] + public static class ShiftOSCommands { + + [Command("shutdown")] + public static bool Shutdown() { + SaveSystem.ShuttingDown = true; + TerminalBackend.InvokeCommand("sos.save"); + AppearanceManager.Exit(); + return true; + } + [Command("verify")] + public static bool Verify(Dictionary args) { + if (SaveSystem.CurrentSave.StoryPosition == 4) { + if (args.ContainsKey(Localization.Parse("{ARGS_PASSWORD}"))) { + if (args[Localization.Parse("{ARGS_PASSWORD}")] as string == "theepicwin") { + SaveSystem.CurrentSave.StoryPosition++; + } else { + Console.WriteLine("{SENTIENCE_INVALIDPASSWORD}"); + } + } else { + Console.WriteLine("{SENTIENCE_INVALIDPASSWORD}"); + } + return true; + } else { + return false; + } + } + + + [Command("help", "{COMMAND_HELP_USAGE}", "{COMMAND_HELP_DESCRIPTION}")] + public static bool Help() { + var asm = Assembly.GetExecutingAssembly(); + + var types = asm.GetTypes(); + + foreach (var type in types) { + if (Shiftorium.UpgradeAttributesUnlocked(type)) { + foreach (var a in type.GetCustomAttributes(false)) { + if (a is Namespace) { + var ns = a as Namespace; + + if (!ns.hide) { + string descp = "{NAMESPACE_" + ns.name.ToUpper() + "_DESCRIPTION}"; + if (descp == Localization.Parse(descp)) + descp = ""; + else + descp = Shiftorium.UpgradeInstalled("help_description") ? Localization.Parse("{SEPERATOR}" + descp) : ""; + + Console.WriteLine($"{{NAMESPACE}}{ns.name}" + descp); + + foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) { + if (Shiftorium.UpgradeAttributesUnlocked(method)) { + foreach (var ma in method.GetCustomAttributes(false)) { + if (ma is Command) { + var cmd = ma as Command; + + if (!cmd.hide) { + string descriptionparse = "{COMMAND_" + ns.name.ToUpper() + "_" + cmd.name.ToUpper() + "_DESCRIPTION}"; + string usageparse = "{COMMAND_" + ns.name.ToUpper() + "_" + cmd.name.ToUpper() + "_USAGE}"; + if (descriptionparse == Localization.Parse(descriptionparse)) + descriptionparse = ""; + else + descriptionparse = Shiftorium.UpgradeInstalled("help_description") ? Localization.Parse("{SEPERATOR}" + descriptionparse) : ""; + + if (usageparse == Localization.Parse(usageparse)) + usageparse = ""; + else + usageparse = Shiftorium.UpgradeInstalled("help_usage") ? Localization.Parse("{SEPERATOR}" + usageparse, new Dictionary() { + {"%ns", ns.name}, + {"%cmd", cmd.name} + }) : ""; + + Console.WriteLine($"{{COMMAND}}{ns.name}.{cmd.name}" + usageparse + descriptionparse); + } + } + } + } + + } + } + + } + } + } + } + + return true; + } + + [Command("save")] + public static bool Save() { + SaveSystem.SaveGame(); + return true; + } + + [Command("status")] + public static bool Status() { + Console.WriteLine($@"ShiftOS version {Assembly.GetExecutingAssembly().GetName().Version.ToString()} + +Codepoints: {SaveSystem.CurrentSave.Codepoints} +Upgrades: {SaveSystem.CurrentSave.CountUpgrades()} installed, + {Shiftorium.GetAvailable().Length} available"); + return true; + } + } + + + [Namespace("shiftorium")] + public static class ShiftoriumCommands { + [Command("buy")] + [RequiresArgument("upgrade")] + public static bool BuyUpgrade(Dictionary userArgs) { + try { + string upgrade = ""; + + if (userArgs.ContainsKey("upgrade")) + upgrade = (string)userArgs["upgrade"]; + else + throw new Exception("You must specify a valid 'upgrade' value."); + + foreach (var upg in Shiftorium.GetAvailable()) { + if (upg.ID == upgrade) { + Shiftorium.Buy(upgrade, upg.Cost); + return true; + } + } + + throw new Exception($"Couldn't find upgrade with ID: {upgrade}"); + } catch { + return false; + } + } + + [RequiresUpgrade("shiftorium_bulk_buy")] + [Command("bulkbuy")] + [RequiresArgument("upgrades")] + public static bool BuyBulk(Dictionary args) { + if (args.ContainsKey("upgrades")) { + string[] upgrade_list = (args["upgrades"] as string).Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries); + foreach (var upg in upgrade_list) { + var dict = new Dictionary(); + dict.Add("upgrade", upg); + BuyUpgrade(dict); + } + } else { + throw new Exception("Please specify a list of upgrades in the 'upgrades' argument. Each upgrade is separated by a comma."); + } + return true; + } + + + [Command("info")] + public static bool ViewInfo(Dictionary userArgs) { + try { + string upgrade = ""; + + if (userArgs.ContainsKey("upgrade")) + upgrade = (string)userArgs["upgrade"]; + else + throw new Exception("You must specify a valid 'upgrade' value."); + + foreach (var upg in Shiftorium.GetDefaults()) { + if (upg.ID == upgrade) { + Console.WriteLine($@"Information for {upgrade}: + +{upg.Name} - {upg.Cost} Codepoints +------------------------------------------------------ + +{upg.Description} + +To buy this upgrade, run: +shiftorium.buy{{upgrade:""{upg.ID}""}}"); + return true; + } + } + + throw new Exception($"Couldn't find upgrade with ID: {upgrade}"); + } catch { + return false; + } + } + [Command("list")] + public static bool ListAll() { + try { + Dictionary upgrades = new Dictionary(); + int maxLength = 5; + + foreach (var upg in Shiftorium.GetAvailable()) { + if (upg.ID.Length > maxLength) { + maxLength = upg.ID.Length; + } + + upgrades.Add(upg.ID, upg.Cost); + } + + Console.WriteLine("ID".PadRight((maxLength + 5) - 2) + "Cost (Codepoints)"); + + foreach (var upg in upgrades) { + Console.WriteLine(upg.Key.PadRight((maxLength + 5) - upg.Key.Length) + " " + upg.Value.ToString()); + } + return true; + } catch (Exception e) { + CrashHandler.Start(e); + return false; + } + } + } + + [Namespace("win")] + public static class WindowCommands { + + + + + [Command("list")] + public static bool List() { + Console.WriteLine("{ID}\t{WINDOW}"); + foreach (var app in AppearanceManager.OpenForms) { + //All .NET object instances have a unique hash code. Good for fake process management. + Console.WriteLine($"{app.GetHashCode()}\t{app.Text}"); + } + return true; + } + + [Command("open")] + public static bool Open(Dictionary args) + { + try + { + if (args.ContainsKey("app")) + { + var app = args["app"] as string; + //ANNND now we start reflecting... + foreach (var asmExec in System.IO.Directory.GetFiles(Environment.CurrentDirectory)) + { + if (asmExec.EndsWith(".exe") || asmExec.EndsWith(".dll")) + { + var asm = Assembly.LoadFile(asmExec); + + foreach (var type in asm.GetTypes()) + { + if (type.BaseType == typeof(UserControl)) + { + foreach (var attr in type.GetCustomAttributes(false)) + { + if (attr is WinOpenAttribute) + { + if (app == (attr as WinOpenAttribute).ID) + { + if (SaveSystem.CurrentSave.Upgrades.ContainsKey(app)) + { + if (Shiftorium.UpgradeInstalled(app)) + { + IShiftOSWindow frm = Activator.CreateInstance(type) as IShiftOSWindow; + AppearanceManager.SetupWindow(frm); + return true; + } + else + { + throw new Exception($"{app} was not found on your system! Try looking in the shiftorium..."); + } + } + else + { + IShiftOSWindow frm = Activator.CreateInstance(type) as IShiftOSWindow; + AppearanceManager.SetupWindow(frm); + return true; + } + } + } + } + } + } + } + } + + } + else + { + Console.WriteLine("Please specify a valid 'app' param."); + return true; + } + Console.WriteLine("Couldn't find the specified app on your system."); + return true; + } + catch (Exception ex) + { + Console.WriteLine("Error running script:" + ex); + return false; + } + } + + + } +} diff --git a/ShiftOS_TheReturn/CrashHandler.Designer.cs b/ShiftOS_TheReturn/CrashHandler.Designer.cs new file mode 100644 index 0000000..0bd0b5c --- /dev/null +++ b/ShiftOS_TheReturn/CrashHandler.Designer.cs @@ -0,0 +1,151 @@ +namespace ShiftOS.Engine +{ + partial class CrashHandler + { + /// + /// 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.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CrashHandler)); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.rtbcrash = new System.Windows.Forms.RichTextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.btnjump = new System.Windows.Forms.Button(); + this.button1 = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 25F); + this.label1.Location = new System.Drawing.Point(13, 22); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(726, 39); + this.label1.TabIndex = 0; + this.label1.Text = "The ShiftOS client has experienced a fatal bug."; + // + // label2 + // + this.label2.Location = new System.Drawing.Point(20, 74); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(800, 136); + this.label2.TabIndex = 1; + this.label2.Text = @"We are terribly sorry for interrupting your gameplay, but unfortunately ShiftOS encountered a major problem that it couldn't recover from. This can be caused by any of the following reasons: + + - Broken MUD scripts (check with the script author if you see this error after running a script) + - A bug in the ShiftOS code + - Incorrect or malformed server message (also could be a bug in ShiftOS.) + +We were safely able to save your game and disconnect you from the multi-user domain. We have also sent the crash info to the developers of ShiftOS for you. Below is a copy of what we sent for your reference:"; + // + // pictureBox1 + // + this.pictureBox1.ImageLocation = "https://archive.raytron.org/shiftos/styles/black_pearl/imageset/shiftos.png"; + this.pictureBox1.Location = new System.Drawing.Point(12, 560); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(414, 105); + this.pictureBox1.TabIndex = 2; + this.pictureBox1.TabStop = false; + // + // rtbcrash + // + this.rtbcrash.BackColor = System.Drawing.Color.Black; + this.rtbcrash.EnableAutoDragDrop = true; + this.rtbcrash.Font = new System.Drawing.Font("Consolas", 8.25F); + this.rtbcrash.ForeColor = System.Drawing.Color.Gray; + this.rtbcrash.Location = new System.Drawing.Point(20, 214); + this.rtbcrash.Name = "rtbcrash"; + this.rtbcrash.Size = new System.Drawing.Size(800, 340); + this.rtbcrash.TabIndex = 3; + this.rtbcrash.Text = ""; + // + // label3 + // + this.label3.Location = new System.Drawing.Point(444, 560); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(382, 47); + this.label3.TabIndex = 4; + this.label3.Text = "You may click \"Jump back in\" to attempt to recover the session. If you experience" + + " this screen again, try quitting the game and relaunching. If that doesn\'t help," + + " there may be something terribly wrong."; + // + // btnjump + // + this.btnjump.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnjump.Location = new System.Drawing.Point(736, 642); + this.btnjump.Name = "btnjump"; + this.btnjump.Size = new System.Drawing.Size(84, 23); + this.btnjump.TabIndex = 5; + this.btnjump.Text = "Jump back in"; + this.btnjump.UseVisualStyleBackColor = true; + this.btnjump.Click += new System.EventHandler(this.btnjump_Click); + // + // button1 + // + this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.button1.Location = new System.Drawing.Point(646, 642); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(84, 23); + this.button1.TabIndex = 6; + this.button1.Text = "Close ShiftOS"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // CrashHandler + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.ClientSize = new System.Drawing.Size(838, 677); + this.Controls.Add(this.button1); + this.Controls.Add(this.btnjump); + this.Controls.Add(this.label3); + this.Controls.Add(this.rtbcrash); + this.Controls.Add(this.pictureBox1); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.ForeColor = System.Drawing.Color.White; + this.Name = "CrashHandler"; + this.Text = "CrashHandler"; + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.RichTextBox rtbcrash; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Button btnjump; + private System.Windows.Forms.Button button1; + } +} \ No newline at end of file diff --git a/ShiftOS_TheReturn/CrashHandler.cs b/ShiftOS_TheReturn/CrashHandler.cs new file mode 100644 index 0000000..f49a8f3 --- /dev/null +++ b/ShiftOS_TheReturn/CrashHandler.cs @@ -0,0 +1,181 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Reflection; +using System.Management; +using System.Windows.Forms; +using Newtonsoft.Json; +using System.Threading; +using System.IO; + +namespace ShiftOS.Engine +{ + public class GetHardwareInfo + { + public static string GetProcessorName() + { + string ProcessorName = ""; + ManagementObjectSearcher mos + = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Processor"); + + foreach (ManagementObject mo in mos.Get()) + ProcessorName = mo["Name"].ToString(); + + return ProcessorName; + } + public static string GetGPUName() + { + string GPUName = ""; + ManagementObjectSearcher mos + = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_VideoController"); + + foreach (ManagementObject mo in mos.Get()) + GPUName = mo["Name"].ToString(); + + return GPUName; + } + public static string GetRAMAmount() + { + var RAMAmount = ""; + ManagementObjectSearcher mos + = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_PhysicalMemory"); + + foreach (ManagementObject mo in mos.Get()) + RAMAmount = mo["Capacity"].ToString(); + + RAMAmount = (RAMAmount + " B"); + + return RAMAmount; + } + } + + + public partial class CrashHandler : Form + { + public CrashHandler() + { + InitializeComponent(); + + + //Send the bug to Debugle + // or alternatively, send to reportbug@shiftos.ml OR narodgaming@shiftos.ml + + } + + public static Exception HandledException = null; + + public static void Start(Exception e) + { + if (SaveSystem.CurrentSave != null) + { + TerminalBackend.InvokeCommand("sos.save"); //save ShiftOS to disk before killing the session + } + + //Close ALL FORMS in the current session. + while (Application.OpenForms.Count != 0) + { + Application.OpenForms[0].Dispose(); + } + + //Disconnect us from the ShiftOS multi-user domain. + ServerManager.Disconnect(); + + //Set our global exception variable, and show the exception dialog. + HandledException = e; + System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly(); + System.IO.FileInfo fileInfo = new System.IO.FileInfo(assembly.Location); + DateTime lastModified = fileInfo.LastWriteTime; + + string rtbcrash_Text = $@" === ShiftOS has crashed === + +Basic Information For User: +--------------------------------- + +When: {DateTime.Now.ToString()} +Why: {HandledException.Message} +What: {HandledException.GetType().Name} + +We, at the ShiftOS Development Team, apologise for your game crash, +we will take this bug report seriously - and it has been emailed +to the development team of ShiftOS, thank you for enjoying our game! + +Advanced Information (for experts and developers): +---------------------------------------------------- + +Host system information: +--------------------------------- + +Operating system: {Environment.OSVersion.Platform.ToString()} +Version: {Environment.OSVersion.VersionString} +Is 64-bit: {Environment.Is64BitOperatingSystem} +ShiftOS exec path: {Application.ExecutablePath} + +Advanced Host Information: +--------------------------------- + +CPU Name: {GetHardwareInfo.GetProcessorName()} +Physical RAM Installed: {GetHardwareInfo.GetRAMAmount()} +GPU Name: {GetHardwareInfo.GetGPUName()} + +ShiftOS basic information: +--------------------------------- + +ShiftOS Version: {Assembly.GetExecutingAssembly().GetName().Version} +ShiftOS Date: {lastModified.ToString()} + +ShiftOS environment information: +--------------------------------- + +Is Save loaded: {(SaveSystem.CurrentSave != null)} +Paths loaded in system: {JsonConvert.SerializeObject(Paths.GetAll())} + + +Crash: {HandledException.GetType().Name} +-------------------------------------------- + +Exception message: {HandledException.Message} +HResult (this is technical): {HandledException.HResult} +Has inner exception: {(HandledException.InnerException != null)} +Stack trace: +{HandledException.StackTrace}"; + + if (HandledException.InnerException != null) + { + var i = HandledException.InnerException; + rtbcrash_Text += $@" + +Inner: {i.GetType().Name} +-------------------------------------------- + +Exception message: {i.Message} +HResult (this is technical): {i.HResult} +Stack trace: +{i.StackTrace}"; + + } + + File.WriteAllText("crash.txt", rtbcrash_Text); + var result = MessageBox.Show(caption: "ShiftOS - Fatal error", text: "ShiftOS has encountered a fatal error and has been shut down. Info about the error has been saved to a file called crash.txt in the same folder as the active executable. Would you like to try and recover the game session?", buttons: MessageBoxButtons.YesNo); + if(result == DialogResult.Yes) + { + Application.Restart(); + } + } + + private void button1_Click(object sender, EventArgs e) + { + this.Close(); + } + + private void btnjump_Click(object sender, EventArgs e) + { + this.Close(); + Application.Restart(); + } + } +} diff --git a/ShiftOS_TheReturn/CtrlTabMenu.cs b/ShiftOS_TheReturn/CtrlTabMenu.cs new file mode 100644 index 0000000..306bf65 --- /dev/null +++ b/ShiftOS_TheReturn/CtrlTabMenu.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShiftOS.Engine { + static class CtrlTabMenu { + public static AltTabWindow altTabWindow; + + internal static void Show() { + if(altTabWindow != null) { + altTabWindow = new AltTabWindow(); + altTabWindow.Show(); + } + } + + internal static void CycleBack() { + altTabWindow.CycleBack(); + } + + internal static void CycleForwards() { + altTabWindow.CycleForwards(); + } + } +} diff --git a/ShiftOS_TheReturn/Desktop.cs b/ShiftOS_TheReturn/Desktop.cs new file mode 100644 index 0000000..28a3d33 --- /dev/null +++ b/ShiftOS_TheReturn/Desktop.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using static ShiftOS.Engine.SkinEngine; + +namespace ShiftOS.Engine +{ + public class LauncherAttribute : Attribute + { + /// + /// Marks this form as a launcher item that, when clicked, will open the form. + /// + /// The text displayed on the launcher item + /// Whether or not an upgrade must be installed to see the launcher + /// The ID of the upgrade - leave blank if requiresUpgrade is false. + public LauncherAttribute(string name, bool requiresUpgrade, string upgradeID = "") + { + Name = name; + RequiresUpgrade = requiresUpgrade; + ID = upgradeID; + } + + public string Name { get; set; } + public bool RequiresUpgrade { get; set; } + public string ID { get; set; } + public bool UpgradeInstalled + { + get + { + if (!RequiresUpgrade) + return true; + + return Shiftorium.UpgradeInstalled(ID); + } + } + } + + + public interface IDesktop + { + void SetupDesktop(); + void PopulateAppLauncher(LauncherItem[] items); + void ShowWindow(IWindowBorder border); + void KillWindow(IWindowBorder border); + void PopulatePanelButtons(); + void MinimizeWindow(IWindowBorder brdr); + void MaximizeWindow(IWindowBorder brdr); + void RestoreWindow(IWindowBorder brdr); + void InvokeOnWorkerThread(Action act); + Size GetSize(); + } + + public static class Desktop + { + private static IDesktop _desktop = null; + + public static Size Size { get + { + return _desktop.GetSize(); + } + } + + public static void Init(IDesktop desk) + { + _desktop = desk; + } + + public static void InvokeOnWorkerThread(Action act) + { + _desktop.InvokeOnWorkerThread(act); + } + + public static void ResetPanelButtons() + { + _desktop.PopulatePanelButtons(); + } + + public static void ShowWindow(IWindowBorder brdr) + { + _desktop.ShowWindow(brdr); + } + + public static void PopulateAppLauncher() + { + _desktop.PopulateAppLauncher(AppLauncherDaemon.Available().ToArray()); + } + } + +} diff --git a/ShiftOS_TheReturn/FileSkimmerBackend.cs b/ShiftOS_TheReturn/FileSkimmerBackend.cs new file mode 100644 index 0000000..00ad45b --- /dev/null +++ b/ShiftOS_TheReturn/FileSkimmerBackend.cs @@ -0,0 +1,152 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; +using static ShiftOS.Objects.ShiftFS.Utils; + +namespace ShiftOS.Engine +{ + /// + /// Provides basic high-level access to the ShiftOS filesystem engine (ShiftFS) and File Skimmer. + /// + public static class FileSkimmerBackend + { + private static IFileSkimmer _fs = null; + + /// + /// Opens a file from the specified ShiftFS path. + /// + /// The path to open. + public static void OpenFile(string path) + { + _fs.OpenFile(path); + } + + /// + /// Gets the file type of a given path. + /// + /// The path to check + /// The FileType of the path + public static FileType GetFileType(string path) + { + + if (path == "__upone") + return FileType.UpOne; + + if (DirectoryExists(path)) + { + if (Mounts.Contains(GetDirectoryInfo(path))) + return FileType.Mount; + else + return FileType.Directory; + } + + + string ext = path.Split('.')[path.Split('.').Length - 1]; + switch (ext) + { + case "txt": + return FileType.TextFile; + case "pic": + case "png": + case "jpg": + case "bmp": + case "gif": + return FileType.Image; + case "py": + return FileType.Python; + case "mfs": + return FileType.Filesystem; + case "lua": + return FileType.Lua; + case "skn": + return FileType.Skin; + case "json": + return FileType.JSON; + case "sft": + //No, not "sex" - ShiftOS EXecutable. xD + case "sex": + return FileType.Executable; + default: + return FileType.Unknown; + } + } + + /// + /// Opens the specified directory path inside a new File Skimmer frontend. + /// + /// The path to open + public static void OpenDirectory(string path) + { + _fs.OpenDirectory(path); + } + + /// + /// Allows you to prompt the user to select a file, either to open or save, and filter the types of files they can select. + /// + /// An array of file extensions that the user may select. + /// The UI style of the new file select frontend. + /// The Action that is called when the user selects a file. The string argument provided by this call is the path of the file they selected. + public static void GetFile(string[] types, FileOpenerStyle style, Action callback) + { + _fs.GetPath(types, style, callback); + } + + /// + /// Initiates the file skimmer backend with a new middle-end layer. + /// + /// The middle-end IFileSkimmer that'll do all the work. + /// Without a middle-end, the File Skimmer will not function properly. + public static void Init(IFileSkimmer fs) + { + _fs = fs; + } + + public static System.Drawing.Image GetImage(string filepath) + { + return new Bitmap(42, 42); + } + } + + /// + /// Provides primary middle-end functions allowing the File Skimmer API to talk with your frontend. + /// + public interface IFileSkimmer + { + void OpenFile(string filepath); + void GetPath(string[] filetypes, FileOpenerStyle style, Action callback); + void OpenDirectory(string path); + } + + + /// + /// Different types of UI styles for File Openers. + /// + public enum FileOpenerStyle + { + Open, + Save + } + + /// + /// Recognized file types within the ShiftFS engine. + /// + public enum FileType + { + TextFile, + Directory, + Mount, + UpOne, + Image, + Skin, + JSON, + Executable, + Lua, + Python, + Filesystem, + Unknown + } +} diff --git a/ShiftOS_TheReturn/IShiftOSWindow.cs b/ShiftOS_TheReturn/IShiftOSWindow.cs new file mode 100644 index 0000000..1da789d --- /dev/null +++ b/ShiftOS_TheReturn/IShiftOSWindow.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShiftOS.Engine +{ + public interface IShiftOSWindow + { + void OnLoad(); + + void OnSkinLoad(); + bool OnUnload(); + void OnUpgrade(); + } +} diff --git a/ShiftOS_TheReturn/Infobox.cs b/ShiftOS_TheReturn/Infobox.cs new file mode 100644 index 0000000..8969491 --- /dev/null +++ b/ShiftOS_TheReturn/Infobox.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace ShiftOS.Engine +{ + public class Infobox + { + private static IInfobox _infobox = null; + + [Obsolete("Please use Infobox.Show instead.")] + public Infobox(string title, string message) + { + Infobox.Show(title, message); + } + + public static void Show(string title, string message) + { + _infobox.Open(title, message); + } + + public static void Init(IInfobox info) + { + _infobox = info; + } + } + + public interface IInfobox + { + void Open(string title, string msg); + } +} diff --git a/ShiftOS_TheReturn/Infobox.resx b/ShiftOS_TheReturn/Infobox.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/ShiftOS_TheReturn/Infobox.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/ShiftOS_TheReturn/Localization.cs b/ShiftOS_TheReturn/Localization.cs new file mode 100644 index 0000000..fd491b9 --- /dev/null +++ b/ShiftOS_TheReturn/Localization.cs @@ -0,0 +1,177 @@ +using Newtonsoft.Json; +using ShiftOS.Objects.ShiftFS; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShiftOS.Engine +{ + public interface ILanguageProvider + { + List GetJSONTranscripts(); + void WriteDefaultTranscript(); + string GetCurrentTranscript(); + string[] GetAllLanguages(); + } + + public static class Localization + { + private static ILanguageProvider _provider = null; + + public static string[] GetAllLanguages() + { + if(_provider == null) + { + return JsonConvert.DeserializeObject(Properties.Resources.languages); + } + else + { + return _provider.GetAllLanguages(); + } + } + + public static void SetupTHETRUEDefaultLocals() + { + if (_provider == null) + { + var lines = Properties.Resources.strings_en; + var path = "english.local"; + Utils.WriteAllText(Paths.GetPath(path), lines); + } + else + { + _provider.WriteDefaultTranscript(); + } + } + + public static void SetupDefaultLocals(string lines, string path) + { + Utils.WriteAllText(Paths.GetPath(path), lines); + + } + + + /// + /// Takes in a string and parses localization blocks into text blocks in the current language. + /// + /// "{CODEPOINTS}: 0" will come out as "Codepoints: 0" if the current language is english. + /// The string to parse + /// The parsed string. + /// + public static string Parse(string original) + { + return Parse(original, new Dictionary()); + } + + + public static string Parse(string original, Dictionary replace) + { + Dictionary localizationStrings = new Dictionary(); + + + + try + { + localizationStrings = JsonConvert.DeserializeObject>(_provider.GetCurrentTranscript()); + } + catch + { + localizationStrings = JsonConvert.DeserializeObject>(Utils.ReadAllText(Paths.GetPath("english.local"))); + } + + foreach (var kv in localizationStrings) + { + original = original.Replace(kv.Key, kv.Value); + } + + List orphaned = new List(); + if (Utils.FileExists("0:/dev_orphaned_lang.txt")) + { + orphaned = JsonConvert.DeserializeObject>(Utils.ReadAllText("0:/dev_orphaned_lang.txt")); + } + + + int start_index = 0; + int length = 0; + bool indexing = false; + + foreach (var c in original) + { + if (c == '{') + { + start_index = original.IndexOf(c); + indexing = true; + } + + if (indexing == true) + { + length++; + if (c == '}') + { + indexing = false; + string o = original.Substring(start_index, length); + if (!orphaned.Contains(o)) + { + orphaned.Add(o); + } + start_index = 0; + length = 0; + } + } + } + + if (orphaned.Count > 0) + { + Utils.WriteAllText("0:/dev_orphaned_lang.txt", JsonConvert.SerializeObject(orphaned, Formatting.Indented)); + } + + //string original2 = Parse(original); + + string usernameReplace = ""; + string domainReplace = ""; + + if (SaveSystem.CurrentSave != null) + { + usernameReplace = SaveSystem.CurrentSave.Username; + domainReplace = SaveSystem.CurrentSave.SystemName; + } + + string namespaceReplace = ""; + string commandReplace = ""; + + if (TerminalBackend.latestCommmand != "" && TerminalBackend.latestCommmand.IndexOf('.') > -1) + { + namespaceReplace = TerminalBackend.latestCommmand.Split('.')[0]; + commandReplace = TerminalBackend.latestCommmand.Split('.')[1]; + } + + Dictionary defaultReplace = new Dictionary() { + {"%username", usernameReplace}, + {"%domain", domainReplace}, + {"%ns", namespaceReplace}, + {"%cmd", commandReplace}, + {"%cp", SaveSystem.CurrentSave?.Codepoints.ToString() }, + }; + + foreach (KeyValuePair replacement in replace) + { + original = original.Replace(replacement.Key, Parse(replacement.Value)); + } + + foreach (KeyValuePair replacement in defaultReplace) + { + original = original.Replace(replacement.Key, replacement.Value); + } + + return original; + } + + public static void RegisterProvider(ILanguageProvider p) + { + _provider = p; + } + } +} diff --git a/ShiftOS_TheReturn/OutOfBoxExperience.cs b/ShiftOS_TheReturn/OutOfBoxExperience.cs new file mode 100644 index 0000000..04df726 --- /dev/null +++ b/ShiftOS_TheReturn/OutOfBoxExperience.cs @@ -0,0 +1,63 @@ +using Newtonsoft.Json; +using ShiftOS.Objects; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Windows.Input; +using ShiftOS.Objects.ShiftFS; + +namespace ShiftOS.Engine +{ + public class OutOfBoxExperience + { + private static IOobe _oobe = null; + + public static void Init(IOobe oobe) + { + _oobe = oobe; + } + + public static void Start(Save save) + { + + if (_oobe == null) + throw new InvalidOperationException("OOBE frontend not activated! This function can't be used! Please use OutOfBoxExperience.Init() passing an IOobe-implementing object to start the OOBE frontend."); + + + _oobe.StartShowing(save); + + + } + + public static void PromptForLogin() + { + Desktop.InvokeOnWorkerThread(new Action(() => + { + _oobe.PromptForLogin(); + })); + } + + public static void ShowSaveTransfer(Save save) + { + Desktop.InvokeOnWorkerThread(new Action(() => + { + _oobe.ShowSaveTransfer(save); + + })); + } + } + + public interface IOobe + { + void StartShowing(Save save); + void ShowSaveTransfer(Save save); + void PromptForLogin(); + } +} diff --git a/ShiftOS_TheReturn/OutOfBoxExperience.cs.rej b/ShiftOS_TheReturn/OutOfBoxExperience.cs.rej new file mode 100644 index 0000000..49be1b2 --- /dev/null +++ b/ShiftOS_TheReturn/OutOfBoxExperience.cs.rej @@ -0,0 +1,105 @@ +diff a/ShiftOS_TheReturn/OutOfBoxExperience.cs b/ShiftOS_TheReturn/OutOfBoxExperience.cs (rejected hunks) +@@ -98,36 +98,84 @@ + + var t = new Thread(new ThreadStart(() => + { +- int current = 0; ++ int current = 0; ++ Console.WriteLine("{INSTALLING_SHIFTOS}"); ++ while (current != 100) ++ { ++ string parse = Localization.Parse("{TERMINAL_FORMATTING_DRIVE}", new Dictionary() ++ { ++ { "%percent", $"{current}" } ++ }); + Console.WriteLine("{INSTALLING_SHIFTOS}"); +- while (current != 100) ++ Console.WriteLine(parse); ++ Thread.Sleep(250); ++ this.Invoke(new Action(() => + { +- string parse = Localization.Parse("{TERMINAL_FORMATTING_DRIVE}", new Dictionary() ++ txtterm.Text = ""; ++ })); ++ current += 1; ++ } ++ ++ string p = Localization.Parse("{TERMINAL_FORMATTING_DRIVE}", new Dictionary() + { + { "%percent", $"{current}" } + }); +- Console.WriteLine("{INSTALLING_SHIFTOS}"); +- Console.WriteLine(parse); +- Thread.Sleep(250); +- this.Invoke(new Action(() => +- { +- txtterm.Text = ""; +- })); +- current += 1; ++ Console.WriteLine("{INSTALLING_SHIFTOS}"); ++ Console.WriteLine(p); ++ ++ Thread.Sleep(1000); ++ ++ Console.WriteLine("{GENERATING_PATHS}"); ++ ++ ScanAllFiles("0:"); ++ ++ Thread.Sleep(1250); ++ ++ Console.WriteLine("{CREATING_USER}"); ++ ++ Thread.Sleep(300); ++ ++ Console.WriteLine("{SHIFTOS_HAS_BEEN_INSTALLED}"); ++ ++ for (int i = 5; i >= 0; i--) ++ { ++ Console.WriteLine(Localization.Parse("{REBOOTING_SYSTEM}", new Dictionary() ++ { ++ { "%i", i.ToString()} ++ })); ++ Thread.Sleep(1000); + } + +- string p = Localization.Parse("{TERMINAL_FORMATTING_DRIVE}", new Dictionary() ++ this.Invoke(new Action(() => + { +- { "%percent", $"{current}" } +- }); +- Console.WriteLine("{INSTALLING_SHIFTOS}"); +- Console.WriteLine(p); ++ txtterm.Text = ""; ++ })); + +- Thread.Sleep(1000); ++ Console.WriteLine("{TERMINAL_TUTORIAL_1}"); + +- Console.WriteLine("{GENERATING_PATHS}"); ++ SaveSystem.TransferCodepointsFrom("sos", 50); + +- ScanAllFiles("0:"); ++ Applications.Terminal.InStory = false; ++ ++ while (!Shiftorium.UpgradeInstalled("mud_fundamentals")) ++ { ++ ++ } ++ ++ var t2 = new Thread(new ThreadStart(() => ++ { ++ int storyPos = SaveSystem.CurrentSave.StoryPosition + 1; ++ while(storyPos > SaveSystem.CurrentSave.StoryPosition) ++ { ++ this.Invoke(new Action(() => ++ { ++ this.Close(); ++ })); ++ } ++ })); ++ t2.IsBackground = true; ++ t2.Start(); ++ Story.StartDevXLies(); + + })); + t.IsBackground = true; diff --git a/ShiftOS_TheReturn/Paths.cs b/ShiftOS_TheReturn/Paths.cs new file mode 100644 index 0000000..00a4edf --- /dev/null +++ b/ShiftOS_TheReturn/Paths.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using static ShiftOS.Objects.ShiftFS.Utils; +using ShiftOS.Objects.ShiftFS; +using Newtonsoft.Json; +using System.Threading; + +namespace ShiftOS.Engine +{ + public static class Paths + { + public static void Init() + { + Locations = new Dictionary(); + Locations.Add("classic", "C:\\ShiftOS"); + Locations.Add("root", "0:"); + + AddPath("root", "system"); + + AddPath("root", "home"); + AddPath("home", "documents"); + AddPath("home", "desktop"); + AddPath("home", "pictures"); + + + AddPath("system", "local"); + AddPath("local", "english.local"); + AddPath("local", "deutsch.local"); + AddPath("local", "verbose.local"); + AddPath("system", "data"); + AddPath("data", "save.json"); + AddPath("data", "user.dat"); + AddPath("data", "skin"); + AddPath("skin", "current"); + AddPath("current", "skin.json"); + AddPath("current", "images"); + + CheckPathExistence(); + + CreateAndMountSharedFolder(); + } + + /// + /// Returns all paths in an array of strings. + /// + /// The array + public static string[] GetAll() + { + List strings = new List(); + foreach(var str in Locations) + { + strings.Add(str.Key + " = " + str.Value); + } + return strings.ToArray(); + + } + + public static string[] GetAllWithoutKey() + { + List strings = new List(); + foreach (var str in Locations) + { + strings.Add(str.Value); + } + return strings.ToArray(); + + } + + public static string GetPath(string id) + { + return Locations[id]; + } + + private static void CheckPathExistence() + { + foreach(var path in Locations) + { + if (!path.Value.Contains(".") && path.Key != "classic") + { + if (!DirectoryExists(path.Value)) + { + Console.WriteLine($"Writing directory: {path.Value.Replace(Locations["root"], "\\")}"); + CreateDirectory(path.Value); + } + } + } + } + + private static Dictionary Locations { get; set; } + + public static void CreateAndMountSharedFolder() + { + if (!System.IO.Directory.Exists(SharedFolder)) + { + System.IO.Directory.CreateDirectory(SharedFolder); + } + + var mount = new Directory(); + mount.Name = "Shared"; + Utils.Mount(JsonConvert.SerializeObject(mount)); + ScanForDirectories(SharedFolder, 1); + } + + + + public static void ScanForDirectories(string folder, int mount) + { + foreach (var file in System.IO.Directory.GetFiles(folder)) + { + string mfsDir = file.Replace(SharedFolder, $"{mount}:").Replace("\\", "/"); + WriteAllBytes(mfsDir, System.IO.File.ReadAllBytes(file)); + } + foreach (var directory in System.IO.Directory.GetDirectories(folder)) + { + string mfsDir = directory.Replace(SharedFolder, $"{mount}:").Replace("\\", "/"); + CreateDirectory(mfsDir); + ScanForDirectories(directory, mount); + } + } + + public static string SharedFolder { get { return Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\ShiftOS_Shared"; } } + public static string SaveFile { get { return Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\ShiftOS.mfs"; } } + public static string SaveFileInner { get { return Locations["save.json"]; } } + + public static void AddPath(string parent, string path) + { + Locations.Add(path, Locations[parent] + "/" + path); + } + + public static string Translate(string path) + { + return Locations["root"] + path.Replace("\\", "/"); + } + } +} diff --git a/ShiftOS_TheReturn/Program.cs b/ShiftOS_TheReturn/Program.cs new file mode 100644 index 0000000..d6c8979 --- /dev/null +++ b/ShiftOS_TheReturn/Program.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Diagnostics; + +namespace ShiftOS.Engine +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + public static void Main() + { + try + { + Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); + //Taxes: Remote Desktop Connection and painting + //http://blogs.msdn.com/oldnewthing/archive/2006/01/03/508694.aspx + Application.ThreadException += (o, a) => + { + CrashHandler.Start(a.Exception); + }; + + Application.ApplicationExit += (o, a) => + { + ServerManager.Disconnect(); + + //I really want a glass of juice. + //Process.GetCurrentProcess().Kill(); + }; + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + //Application.Run(new Desktop()); + } + catch(Exception ex) + { + CrashHandler.Start(ex); + + } + } + } +} diff --git a/ShiftOS_TheReturn/Properties/AssemblyInfo.cs b/ShiftOS_TheReturn/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..6c54aba --- /dev/null +++ b/ShiftOS_TheReturn/Properties/AssemblyInfo.cs @@ -0,0 +1,40 @@ +using System; +using System.Reflection; +using System.Runtime.CompilerServices; +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("ShiftOS")] +[assembly: AssemblyDescription("Shift it your way.")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("ShiftOS Development Team")] +[assembly: AssemblyProduct("ShiftOS")] +[assembly: AssemblyCopyright("Copyright © Michael VanOverbeek & ShiftOS Developers 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +//[assembly: Obsolete("Why the fuck is this thing SO DEPENDENT ON WINFORMS")] + +// 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("7c979b07-0585-4033-a110-e5555b9d6651")] + +// Version information for an assembly consists of the following four values: +// +// Major Versino +// 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.*")] + + //Devs: Increase the assembly version by one minor every release. If the minor hits over 9, set it to 0 and increment the major. Starting version is 1.0. +[assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/ShiftOS_TheReturn/Properties/Resources.Designer.cs b/ShiftOS_TheReturn/Properties/Resources.Designer.cs new file mode 100644 index 0000000..48c910f --- /dev/null +++ b/ShiftOS_TheReturn/Properties/Resources.Designer.cs @@ -0,0 +1,190 @@ +//------------------------------------------------------------------------------ +// +// 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 ShiftOS.Engine.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", "4.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("ShiftOS.Engine.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; + } + } + + /// + /// Looks up a localized string similar to . + /// + internal static string hello { + get { + return ResourceManager.GetString("hello", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to [ + /// "english" + /// "deutsch - in beta" + ///]. + /// + internal static string languages { + get { + return ResourceManager.GetString("languages", resourceCulture); + } + } + internal static string secretlang + { + get + { + return ResourceManager.GetString("secretlang", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to [ + /// { + /// Name: "MUD Fundamentals", + /// Cost: 50, + /// Description: "Some basic commands for the terminal that'll help you out in the multi-user domain.", + /// Dependencies: null + /// }, + /// { + /// Name: "WM 4 Windows", + /// Cost: 150, + /// Description: "Display up to 4 simultaneous windows on-screen in a 2x2 grid.", + /// Dependencies: "window_manager" + /// }, + /// { + /// Name: "Virus Scanner", + /// Cost: 2000, + /// Description: "Being inside the multi-user domain comes with many risks, one of which being viruses. The Virus Scanner can m [rest of string was truncated]";. + /// + internal static string Shiftorium { + get { + return ResourceManager.GetString("Shiftorium", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to [ + /// "http://downloads.michaeltheshifter.me/music/blockride.mp3", + /// "http://downloads.michaeltheshifter.me/music/nightcoding.mp3" + ///]. + /// + internal static string Songs { + get { + return ResourceManager.GetString("Songs", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to { + /// "{SUBMIT}":"Bestätigen", + /// + ///"{TERMINAL_TUTORIAL_1}":"Wilkommen zum ShiftOS Terminal. Hier wirst du die meiste Zeit in ShiftOS verbringen. + /// + ///Eine kurze Erklärung wie du das Terminal benutzt lautet wiefolgt. Du kannst das command 'sos.help' benutzen um eine Liste aller commands aufzurufen. Schreib es + ///einfach in das Terminal und drücke <enter> um alle commands anzuzeigen. + /// + ///Commands können mit argumenten versehen werden, indem du ein key-value Paar in einem {} Block hinter dem command angibst. Zum Be [rest of string was truncated]";. + /// + internal static string strings_de { + get { + return ResourceManager.GetString("strings_de", resourceCulture); + } + } + + internal static string strings_ver + { + get + { + return ResourceManager.GetString("strings_ver", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to { + /// "{SUBMIT}":"Submit", + /// + ///"{TERMINAL_TUTORIAL_1}":"Welcome to the ShiftOS terminal. This is where you will spend the bulk of your time within ShiftOS. + /// + ///A brief rundown of how to use the terminal is as follows. You can use the 'sos.help' command to show a list of all commands. Simply type it in and strike <enter> to view all commands. + /// + ///Commands can be sent arguments by specifying a key-value pair inside a {} block at the end of the command. For example: + /// + ///some.command{print:\"hello\"} + ///math.add{op1 [rest of string was truncated]";. + /// + internal static string strings_en { + get { + return ResourceManager.GetString("strings_en", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to { + /// Character: "sys", + /// Lines:[ + /// "Hello there, %user.", + /// "Welcome to ShiftOS.", + /// "This is an automated message to all new sentiences within the ShiftOS multi-user domain.", + /// "Before you can begin with ShiftOS, you'll need to know a few things about it.", + /// "One: Terminal command syntax.", + /// "Inside ShiftOS, the bulk of your time is going to be spent within the Terminal.", + /// "The Terminal is an application that starts up when you turn on your computer. It allows you to execute system commands, ope [rest of string was truncated]";. + /// + internal static string sys_shiftoriumstory { + get { + return ResourceManager.GetString("sys_shiftoriumstory", resourceCulture); + } + } + } +} diff --git a/ShiftOS_TheReturn/Properties/Resources.resx b/ShiftOS_TheReturn/Properties/Resources.resx new file mode 100644 index 0000000..85e3d22 --- /dev/null +++ b/ShiftOS_TheReturn/Properties/Resources.resx @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + ..\Resources\hello.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + ..\Resources\languages.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + + ..\Resources\Shiftorium.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + + ..\Resources\Songs.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + + ..\Resources\strings_de.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + + ..\Resources\strings_en.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + + ..\Resources\sys_shiftoriumstory.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + \ No newline at end of file diff --git a/ShiftOS_TheReturn/Properties/Settings.Designer.cs b/ShiftOS_TheReturn/Properties/Settings.Designer.cs new file mode 100644 index 0000000..a1e2e32 --- /dev/null +++ b/ShiftOS_TheReturn/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 ShiftOS.Engine.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.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/ShiftOS_TheReturn/Properties/Settings.settings b/ShiftOS_TheReturn/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/ShiftOS_TheReturn/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/ShiftOS_TheReturn/Resources/Shiftorium.txt b/ShiftOS_TheReturn/Resources/Shiftorium.txt new file mode 100644 index 0000000..e36480e --- /dev/null +++ b/ShiftOS_TheReturn/Resources/Shiftorium.txt @@ -0,0 +1,594 @@ +[ + { + Name: "MUD Fundamentals", + Cost: 50, + Description: "Some basic commands for the terminal that'll help you out in the multi-user domain.", + Dependencies: null + }, + { + Name: "WM 4 Windows", + Cost: 150, + Description: "Display up to 4 simultaneous windows on-screen in a 2x2 grid.", + Dependencies: "window_manager" + }, + { + Name: "Virus Scanner", + Cost: 2000, + Description: "Being inside the multi-user domain comes with many risks, one of which being viruses. The Virus Scanner can mitigate this threat by allowing you to scan the files on your system for any viruses and delete them for you.", + Dependencies: "mud_fundamentals;file_skimmer" + }, + { + Name: "AL Virus Scanner", + Cost: 150, + Description: "Add an App Launcher entry for the Virus Scanner.", + Dependencies: "virus_scanner;app_launcher" + }, + { + Name: "WM Panel Buttons", + Cost: 200, + Description: "Sometimes it's useful to have a list of windows that are open on your system so you can easily switch between them.", + Dependencies: "desktop;wm_unlimited_windows" + }, + { + Name: "AL Skin Loader", + Cost: 125, + Description: "Buy this upgrade to add an entry for the Skin Loader to the App Launcher.", + Dependencies: "app_launcher;skinning" + }, + { + Name: "Shift Panel Buttons", + Cost: 150, + Description: "Want to customize your panel buttons? This Shifter category is for you!", + Dependencies: "wm_panel_buttons" + }, + { + Name: "TextPad Lua Support", + Cost: 450, + Description: "Use TextPad to write Lua scripts!", + Dependencies: "textpad;file_skimmer", + }, + { + Name: "TextPad Python Support", + Cost: 450, + Description: "Use TextPad to write Python scripts!", + Dependencies: "textpad;file_skimmer", + }, + { + Name: "App Launcher", + Cost: 10000, + Description: "It may be expensive, but having an easy-access menu to all your apps is very valuable.", + Dependencies:"desktop;wm_unlimited_windows" + }, + { + Name: "MUD Cracker", + Cost: 500, + Description: "An application for cracking the current multi-user domain's admin password.", + Dependencies: "mud_fundamentals" + }, + { + Name: "AL MUD Cracker", + Cost: 100, + Description: "Add a launcher item for the MUD cracker.", + Dependencies: "mud_cracker;app_launcher" + }, + { + Name: "Textpad", + Cost: 2500, + Description: "\"Write, save and open a text document.\"", + Dependencies: "file_skimmer" + }, + { + Name: "Shifter", + Cost: 20000, + Description: "Tired of the green and black look that is ShiftOS's default skin? Use the Shifter to shift it your way.", + Dependencies: "desktop;wm_unlimited_windows", + }, + { + Name: "Name Changer", + Cost: 10000, + Description: "Are you not a linux person and want the terminal to be called Command Prompt? Well this app is for you!", + Dependencies: "shifter", + }, + { + Name: "AL Name Changer", + Cost: 200, + Description: "Launch the Name Changer from the app launcher.", + Dependencies: "name_changer", + }, + { + Name: "{UPGRADE_DEVELOPMENT}", + Cost: 20000, + Description: "Dont buy this upgrade yet, it does nothing", + Dependencies: "", + }, + { + Name: "AL Shifter", + Cost: 500, + Description: "Launch the Shifter from the app launcher.", + Dependencies: "app_launcher;shifter" + }, + { + Name: "AL Pong", + Cost: 100, + Description: "Launch Pong from the app launcher.", + Dependencies: "app_launcher" + }, + { + Name: "AL Textpad", + Cost: 250, + Description: "Write, save and open text documents from the App Launcher.", + Dependencies:"app_launcher;textpad" + }, + { + Name: "AL File Skimmer", + Cost: 200, + Description: "Open the File Skimmer from your App Launcher.", + Dependencies:"app_launcher;file_skimmer" + }, + { + Name: "WM Free Placement", + Cost: 2000, + Description: "Disable the grid system and allow windows to be freely positioned, moved, and overlapped.", + Dependencies: "wm_4_windows" + }, + { + Name: "Desktop", + Cost: 10000, + Description: "Use a fully customizable desktop in place of the terminal to control ShiftOS.", + Dependencies: "window_manager" + }, + { + Name: "Close command", + Cost: 150, + Description: "Add a win.close script to allow you to close windows.", + Dependencies: "mud_fundamentals", + }, + { + Name: "WM Unlimited Windows", + Cost: 5000, + Description: "Break the limit of windows that can be run. Perfect for high-maintenance tasks.", + Dependencies: "wm_free_placement;close_command" + }, + { + Name: "Minimize Command", + Cost: 1250, + Description: "Use the win.mini{id} command to minimize/restore windows.", + Dependencies: "desktop" + }, + { + Name: "Maximize Command", + Cost: 1250, + Description: "Use the win.max{id} command to maximize windows.", + Dependencies: "wm_titlebar;desktop;wm_free_placement" + }, + { + Name: "Close Button", + Cost: 1000, + Description: "Add a close button to the titlebar to easily close applications.", + Dependencies: "wm_titlebar;close_command" + }, + { + Name: "Minimize Button", + Cost: 1000, + Description: "Minimize windows using a button on the titlebar", + Dependencies: "wm_titlebar;minimize_command" + }, + { + Name: "Shiftorium Bulk Buy", + Cost: 2000, + Description:"Tired of typing shiftorium.buy{} all the time? This upgrade will add a bulk buy command which allows you to specify a comma-separated list of upgrades to buy." + }, + { + Name: "File Skimmer", + Cost: 500, + Description: "View the files on your computer using File Skimmer.", + Dependencies: null + }, + { + Name: "Maximize Button", + Cost: 500, + Description: "Maximize windows using a button on the titlebar", + Dependencies: "wm_titlebar;maximize_command" + }, + { + Name: "Clock", + Cost: 100, + Description: "Adds a script that shows the amount of seconds that have passed since Midnight. Use 'sys.clock' to activate it.", + Dependencies: "mud_fundamentals" + }, + { + Name: "WM Titlebar", + Cost: 250, + Description: "Display a title on each window.", + Dependencies: "window_manager" + }, + { + Name: "Clock Minutes", + Cost: 250, + Description: "Upgrade the sys.clock command to show minutes since midnight with a {type:\"m\"} argument.", + Dependencies: "clock" + }, + { + Name: "Clock Hours", + Cost: 225, + Description: "Upgrade the sys.clock command to show hours since midnight with a {type:\"h\"} argument.", + Dependencies: "clock_minutes" + }, + { + Name: "Clock AM and PM", + Cost: 75, + Description: "Change the clock to be 12-hour based, showing whether the current time is ante-meridiem or post-meridiem.", + Dependencies: "clock_hours", + }, + { + Name: "Full Precision Time", + Cost: 500, + Description: "Show full-precision time by default when using sys.clock.", + Dependencies: "clock_am_and_pm" + }, + { + Name: "Desktop Clock Widget", + Cost: 1000, + Description: "Add a widget to the desktop which shows the results of sys.clock as text on the desktop.", + Dependencies: "clock;desktop" + }, + { + Name: "AL MUD Chat", + Cost: 125, + Description: "Adds an app launcher entry for the MUD chat application.", + Dependencies: "mud_fundamentals;app_launcher" + }, + { + Name: "Draggable windows", + Cost: 400, + Description: "Allows you to drag windows around with the mouse using the title bar.", + Dependencies: "wm_titlebar;wm_free_placement" + }, + { + Name: "Window Manager", + Cost: 100, + Description: "Allows you to run two windows simultaneously within ShiftOS.", + Dependencies: "mud_fundamentals" + }, + { + Name: "Pong Upgrade", + Cost: 4000, + Description: "This upgrade makes pong double the codepoints you get from it so you can spend less time grinding!", + Dependencies: "mud_fundamentals;window_manager" + }, + { + Name: "Pong Upgrade 2", + Cost: 10000, + Description: "So you lost in pong, it must be sad to lose all the codepoints you've gained. With this upgrade you can save 1 percent of the loss, so at least you get something for losing!", + Dependencies: "mud_fundamentals;window_manager;pong_upgrade" + }, + { + Name: "WAV Player", + Cost: 10000, + Description: "Want to listen to the greatest tunes? Well get this app asap!", + Dependencies: "desktop;wm_free_placement" + }, + { + Name: "WAV Player AL", + Cost: 300, + Description: "Just another app launcher, making it easier to listen to your favorite songs!", + Dependencies: "desktop;wm_free_placement;wav_player" + }, + + //SHIFTER SUBCATEGORIES + + { + Name: "Shift Titlebar", + Cost: 100, + Description: "Customize the Titlebar within the Shifter.", + Dependencies: "shifter;wm_titlebar" + }, + { + Name: "Shift Title Text", + Cost: 100, + Description: "Title text looking boring? This upgrade lets you customize the font, color, and position of the Title Text.", + Dependencies: "shift_titlebar" + }, + { + Name: "Shift Window Borders", + Cost: 100, + Description: "Want to customize the look of the ShiftOS window borders? Buy this upgrade and you can customize the color and thickness of the borders.", + Dependencies: "shifter" + }, + { + Name: "Shift Desktop Panel", + Cost: 100, + Description: "Not liking your desktop panel the way it is? Buy this upgrade to allow you to change the color, height, and position of the desktop panel.", + Dependencies: "shifter;desktop" + }, + { + Name: "Shift App Launcher", + Cost: 100, + Description: "You've made your desktop panel look very nice, but your app launcher looks kinda out of place. This upgrade will fix that, allowing you to change the position, size, and appearance of the app launcher button.", + Dependencies: "shift_desktop_panel;app_launcher" + }, + { + Name: "Shift Panel Clock", + Cost: 100, + Dependencies: "shift_desktop_panel;desktop_clock_widget", + Description: "That clock is very simple - let's shift it! This upgrade allows you to customize the font and color of the panel clock." + }, + { + Name: "Shift Title Buttons", + Cost: 100, + Dependencies: "close_button;minimize_button;maximize_button;shift_titlebar", + Description: "Those title buttons look very similar and primitive - with this upgrade you can change the size, position, and color of each button." + }, + + //SKINNING STUFF + + { + Name: "Skinning", + Cost: 50000, + Description: "It may be expensive, but with this upgrade, you can break the limitations of using just solid colors and gradients for your skin and start using images!", + Dependencies: "shifter" + }, + + + //ARTPAD + { + Name: "Artpad", + Cost: 25000, + Description: "ArtPad is a very extensible tool that allows you to draw images within ShiftOS. Buy this upgrade to gain access to it through win.open{}!" + }, + { + Name: "AL Artpad", + Cost: 250, + Description: "Add an App Launcher Entry for Artpad!", + Dependencies: "artpad;app_launcher" + }, + + + + + //ARTPAD PIXEL LIMITS + + { + Name: "Artpad Pixel Limit 4", + Cost: 100, + Dependencies: "artpad", + Description: "Having ArtPad is great, but there's not much you can draw with only 2 pixels. Buy this upgrade to increase the breathing room your imagination can have." + }, + { + Name: "Artpad Pixel Limit 8", + Cost: 150, + Dependencies: "artpad_pixel_limit_4", + Description: "With a 4 pixel limit, you can do some simple patterns and such, but it's still not great. Buy this upgrade to double the pixel limit and add even more possibilities!" + }, + { + Name: "Artpad Pixel Limit 16", + Cost: 200, + Dependencies:"artpad_pixel_limit_8", + Description: "Now we can have 8-pixel images, but we still can't do much more than simple patterns and icons. Use this upgrade to double the max image size yet again and allow even more images!" + }, + { + Name: "Artpad Pixel Limit 64", + Cost: 600, + Dependencies: "artpad_pixel_limit_16", + Description: "Alright. Now it's time to kick it into high-gear. Patterns and icons are fun, but let's increase the image size even more to allow higher-detail icons/patterns and small sprites!" + }, + { + Name: "Artpad Pixel Limit 256", + Cost: 1000, + Dependencies: "artpad_pixel_limit_64", + Description: "We can create high resolution icons and patterns, but we still can't really do too much more than that. Buy this upgrade and you'll be able to have up to 256 pixels in an image!" + }, + { + Name: "Artpad Pixel Limit 1024", + Cost: 1250, + Dependencies: "artpad_pixel_limit_256", + Description: "Let's make things even higher quality! With this upgrade, we'll be able to increase the image size by 4 times! ArtPad is really starting to advance." + }, + { + Name: "Artpad Pixel Limit 4096", + Cost: 4800, + Dependencies: "artpad_pixel_limit_1024", + Description: "Now we can do 1024-pixel images, but how about increasing the limit by 4 times yet again? That'll leave even more room for imagination and drawings!" + }, + { + Name: "Artpad Pixel Limit 16384", + Cost: 19200, + Dependencies: "artpad_pixel_limit_4096", + Description: "We're ever-so-slightly approaching limitless possibilities. With this upgrade, images in ArtPad will be able to have up to 16384 pixels. We can make desktop backgrounds for small monitors!" + }, + { + Name: "Artpad Pixel Limit 65536", + Cost: 76800, + Dependencies: "artpad_pixel_limit_16384", + Description: "Wow! This might be the last time we'll have to deal with pixel limits. It's amazing how far we've came since 2-pixel gradients. Now let's go even further." + }, + { + Name: "Artpad Limitless Pixels", + Cost: 100000, + Dependencies: "artpad_pixel_limit_65536", + Description: "We have a pretty high pixel limit, but with this upgrade, pixel limits are no more! With limitless pixels comes limitless creativity. Have fun!" + }, + + { + Name: "AL Shutdown", + Cost: 300, + Dependencies: "app_launcher", + Description: "Want to shut down ShiftOS from your app launcher? This is the perfect upgrade for you." + }, + + { + Name: "Help Description", + Id: "help_description", + Cost: 150, + Dependencies: "", + Description: "Dont understand what some commands do in the terminal? With this upgrade, it adds a handy little description to almost every command when you run the command sos.help!" + }, + { + Name: "Help Usage", + Cost: 150, + Dependencies: "help_description", + Description: "You got descriptions on what some commands do in the terminal, but wouldn't it be handy to also see what the proper usage is for? Now you can with this upgrade!" + }, + + //ARTPAD TOOLS + { + Name: "Artpad Pixel Placer", + Dependencies: "artpad", + Cost: 750, + Description: "This tool extends the Pixel Setter to allow you to use your mouse to place pixels by clicking on the canvas." + }, + { + Name: "Artpad PP Movement Mode", + Dependencies: "artpad_pixel_placer", + Cost: 500, + Description: "This tool extends the Pixel Placer and allows you to drag your mouse while the button is held down to draw pixels on the canvas." + }, + { + Name: "Artpad Pencil", + Dependencies: "artpad_pp_movement_mode", + Cost: 1000, + Description: "Using the power of the Pixel Placer's movement mode, the Pencil can draw strokes of different thicknesses. Most tools will extend this tool." + }, + { + Name: "Artpad Paintbrush", + Cost: 1000, + Dependencies: "artpad_pencil", + Description: "The Paintbrush allows you to draw more thick strokes on the canvas than the Pencil does." + }, + { + Name: "Artpad Eraser", + Cost: 500, + Dependencies: "artpad_paintbrush;artpad_undo", + Description: "Undo not effective? Want to only erase a select bit of the canvas? Use this tool to get an eraser!" + }, + { + Name: "Artpad Load", + Cost: 350, + Dependencies: "artpad;file_skimmer", + Description: "Want to start off from an existing masterpiece? This tool is for you. Select any .pic file and it'll be loaded onto the canvas!" + }, + { + Name: "Artpad Line Tool", + Cost: 800, + Dependencies: "artpad_pp_movement_mode", + Description: "Using the power of linear interpolation and the Pixel Placer Movement Mode, the Line tool can help you draw straight lines from one point to another." + }, + { + Name: "Artpad Rectangle Tool", + Cost: 400, + Dependencies: "artpad_line_tool", + Description: "With the line tool we are able to figure out the distance from point A to point B. Let's use that basic framework to draw rectangles!" + }, + { + Name: "Artpad Oval Tool", + Cost: 401, + Dependencies: "artpad_line_tool", + Description: "Want to draw some ovals? With this tool, you can! It uses the data from the line tool to construct a circle as you drag the mouse." + }, + { + Name: "Artpad Fill Tool", + Cost: 1000, + Dependencies: "artpad_pixel_placer", + Description: "The Pixel Placer is useful because we can grab pixel coordinates from the mouse, and determine how we can fill the area with a certain color - let's do that!" + }, + { + Name: "Artpad Text Tool", + Cost: 1500, + Dependencies: "artpad_pixel_placer", + Description: "Want to place text on your canvas? Use the Text Tool to do so!" + }, + { + Name: "Artpad New", + Dependencies: "artpad", + Cost: 500, + Description: "Made a mistake? Want a blank canvas? This tool gives you just that." + }, + { + Name: "Artpad Open", + Dependencies: "artpad;file_skimmer", + Cost: 600, + Description: "Want to edit an artpad picture? If you have the File Skimmer, then this tool is for you!" + }, + { + Name: "Artpad Save", + Dependencies: "artpad;file_skimmer", + Cost: 1000, + Description: "Have you been working extra-hard on a masterpiece in ArtPad and want to save? This upgrade is a must-have!" + }, + { + Name: "Artpad Undo", + Dependencies: "artpad_new", + Cost: 59, + Description: "Mistakes happen - but if you have to clear the canvas every time you mess up one single pixel it can get annoying. This tool will help mitigate that - you'll be able to make your last change magically disappear!" + }, + { + Name: "Artpad Redo", + Dependencies: "artpad_undo", + Cost: 50, + Description: "Did you change your mind about that mistake you've undone? Want it back? This tool is for you. Note that the second you add something new after an undo, the undone change is wiped forever!" + }, + + + + //ARTPAD COLOR PALETTES + + { + Name: "Artpad 4 Color Palettes", + Dependencies: "artpad", + Cost: 150, + Description: "Want to add an extra 2 colors to your palette? Buy this upgrade to do so!" + }, + { + Name: "Artpad 8 Color Palettes", + Dependencies: "artpad_4_color_palettes", + Cost: 400, + Description: "Want to add an extra 4 color palette entries to your Artpad to have even more colors used at once? Buy this upgrade, and that will happen!" + }, + { + Name: "Artpad 16 Color Palettes", + Dependencies: "artpad_8_color_palettes", + Cost: 600, + Description: "With this upgrade, you can have up to 16 different colors in your ArtPad palette. Good for drawing intense scenes without constantly selecting different colors." + }, + { + Name: "Artpad 32 Color Palettes", + Dependencies: "artpad_16_color_palettes", + Cost: 850, + Description: "Having 16 different color palettes is nice, but you know what's nicer? Having 32!" + }, + { + Name: "Artpad 64 Color Palettes", + Dependencies: "artpad_32_color_palettes", + Cost: 1700, + Description: "Well then. We have 32 color palettes - let's double that." + }, + { + Name: "Artpad 128 Color Palettes", + Dependencies: "artpad_128_color_palettes", + Cost: 3400, + Description: "With this upgrade we'll be able to have 128 simultaneous colors in our palette. It may get a bit glitchy though... maybe a window manager upgrade could help?" + }, + + + + //SHIFTORIUM UPGRADES FOR THE SHIFTORIUM ITSELF + + { + Name: "Shiftorium GUI", + Cost: 100, + Description: "You may spend lots of time in your terminal - executing scripts, chatting, etc, but why make it so difficult and repetitive to upgrade your system? With this upgrade, a GUI will be added to the Shiftorium, and will be accessible using win.open{app:\"shiftorium\"}." + }, + { + Name: "AL Shiftorium", + Cost: 250, + Dependencies: "shiftorium_gui;app_launcher", + Description: "Add an App Launcher Entry for the Shiftorium!" + }, + { + Name: "Shiftorium GUI Codepoints Display", + Cost: 2500, + Dependencies: "shiftorium_gui", + Description: "In the shiftorium GUI but dont know what you can spend because you can't see how many code points are on hand? Well shop easy, because with this upgrade that is now possible! You have to restart the shiftorium for it to work." + } + +] \ No newline at end of file diff --git a/ShiftOS_TheReturn/Resources/Songs.txt b/ShiftOS_TheReturn/Resources/Songs.txt new file mode 100644 index 0000000..1b7daff --- /dev/null +++ b/ShiftOS_TheReturn/Resources/Songs.txt @@ -0,0 +1,4 @@ +[ + "http://downloads.michaeltheshifter.me/music/blockride.mp3", + "http://downloads.michaeltheshifter.me/music/nightcoding.mp3" +] \ No newline at end of file diff --git a/ShiftOS_TheReturn/Resources/hello.txt b/ShiftOS_TheReturn/Resources/hello.txt new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/ShiftOS_TheReturn/Resources/hello.txt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ShiftOS_TheReturn/Resources/languages.txt b/ShiftOS_TheReturn/Resources/languages.txt new file mode 100644 index 0000000..ca34308 --- /dev/null +++ b/ShiftOS_TheReturn/Resources/languages.txt @@ -0,0 +1,4 @@ +[ + "english" + "deutsch - in beta" +] \ No newline at end of file diff --git a/ShiftOS_TheReturn/Resources/secretlang.txt b/ShiftOS_TheReturn/Resources/secretlang.txt new file mode 100644 index 0000000..b089af5 --- /dev/null +++ b/ShiftOS_TheReturn/Resources/secretlang.txt @@ -0,0 +1,3 @@ +[ + "verbose - joke lang - in beta" +] \ No newline at end of file diff --git a/ShiftOS_TheReturn/Resources/strings_de.txt b/ShiftOS_TheReturn/Resources/strings_de.txt new file mode 100644 index 0000000..10535c8 --- /dev/null +++ b/ShiftOS_TheReturn/Resources/strings_de.txt @@ -0,0 +1,225 @@ +{ + "{SUBMIT}":"Bestätigen", + +"{TERMINAL_TUTORIAL_1}":"Wilkommen zum ShiftOS Terminal. Hier wirst du die meiste Zeit in ShiftOS verbringen. + +Eine kurze Erklärung wie du das Terminal benutzt lautet wiefolgt. Du kannst das command 'sos.help' benutzen um eine Liste aller commands aufzurufen. Schreib es +einfach in das Terminal und drücke um alle commands anzuzeigen. + +Commands können mit argumenten versehen werden, indem du ein key-value Paar in einem {} Block hinter dem command angibst. Zum Beispiel: + +some.command{print:\"Guten Tag!\"} +math.add{op1:1, op2:2} +set.value{key:\"somekey\", value:true} + +Dir wurden 50 Codepoints als Startgeld gegeben - benutz dein Wissen um mit ihnen das MUD Fundamentals Shiftorium Upgrade zu kaufen. Das ganze mit dem Terminal. +Um das MUD Fundamentals Upgrade zu kaufen, tippe shiftorium.buy{upgrade:\"mud_fundamentals\"} in das Terminal. Das ganze funktioniert auch mit anderen Upgrades die +du kaufen willst, ersetze mud_fundamentals einfach mit einem anderen Upgradenamen. +", + + + "{TERMINAL_TUTORIAL_2}":"Du hast den Test erfolgreich bestanden. ShiftOS wird seine Grundfunktionen installieren.", + "{ABOUT}":"Über", + "{START_SYSTEM_SCAN}":"Starte systemweiten Scan", + "{SCAN_HOME}":"Scanne 0:/home", + "{SCAN_SYSTEM}":"Scanne 0:/system", + "{RESULTS}":"Ergebnisse", + "{VIRUSSCANNER_ABOUT}":"Wilkommen zum ShiftOS Virenscanner. + +Der ShiftOS Virenscanner ist ein Werkzeug welches dir erlaubt jede/s Datei oder System zu scannen und herauszufinden +ob es ein Virus ist. Wenn ein Virus erkannt wird, hast do die Option ihn danach zu löschen indem du 'Entfernen' +klickst. + +Wenn eine Systemdatei von dem Virenscanner erkannt wird, wird sie ersetzt.", + "{PLAY}":"Spielen", + "{APPLICATIONS}":"Anwendungen", + "{TERMINAL}":"Terminal", + "{PONG}":"Pong", + "{CODEPOINTS}":"Codepoints", + "{CODEPOINTS_VALUE}":"%cp " + "{SHIFTORIUM}":"Shiftorium", + "{HACK}":"Hack", + "{SHIFTER}":"Shifter", + "{MUD_SHORT}":"MUD", + "{MUD}":"Multi-user domain", + "{DESKTOP}":"Desktop", + "{WINDOW}":"Fenster", + "{WINDOW_MANAGER}":"Fenstermanager", + "{UPGRADE}":"Upgrade", + "{UPGRADES}":"Upgrades", + "{APPLICATION}":"Anwendung", + "{SCRIPT}":"Skript", + "{ERROR}":"Error", + "{SCRIPTS}":"Skripts", + "{NULL}":"null", + "{ID}":"ID Num", + "{SYSTEM_INITIATED}":"System initialisiert", + "{PASSWORD}":"Passwort", + "{CRACK}":"Crack", + "{ARTPAD_UNDO_ERROR}":"Artpad - Fehler rückgängig machen", + "{ARTPAD_NEXT_STEP_WILL_KILL_CANVAS_JUST_FLIPPING_CLICK_NEW}":"You cannot undo the previous action as it would delete the canvas. If you'd like to clear the canvas, click New.", + "{ARTPAD_REDO_ERROR}":"Artpad - Wiederherstellungserror", + "{ARTPAD_NOTHING_TO_REDO}":"Artpad kann nichts wiederherstellen! Behalte im Kopf, dass wenn du etwas rückgängig machst und dann zeichnest, das der Verlauf gelöscht wird.", + "{ARTPAD_MAGNIFIER_ERROR}": "Artpad - Magnifier Error", + "{ARTPAD_MAGNIFICATION_ERROR_EXP_2}": "Artpad kann nicht weiter ranzoomen!", + "{ARTPAD_MAGNIFICATION_ERROR_EXP}": "Artpad kann nicht weiter ranzoomen. Naja, es kann, aber es will nicht.", + "{SHUTDOWN}":"Herunterfahren", + "{CONNECTING_TO_MUD}":"Verbinde mit dem Multi-User Domain...", + "{READING_FS}":"Lese Dateisystem...", + "{INIT_KERNEL}":"Initialisiere Kernel...", + "{START_DESKTOP}":"Starte Desktop-Session...", + "{DONE}": "Fertig", + "{READING_CONFIG}":"Lese Konfiguration...", + "{ID_TAKEN}":"ID Existiert bereits! Benutze chat.join um diesen Chat zu betreten.", + "{CHAT_NOT_FOUND_OR_TOO_MANY_MEMBERS}":"Dieser Chat existiert entweder nicht oder er ist voll.", + "{CHAT_NOT_FOUND_OR_NOT_IN_CHAT}":"Du bist zurzeit nicht in diesem Chat.", + "{CHAT_PLEASE_PROVIDE_VALID_CHANNEL_DATA}":"Du hast keine gültige Chat-Metadata angegeben! Bitte benutze chat.create{id:\"deine_id\", name:\"Dein Chatname\", topic:\"Thema deines Channels\"}.", + "{UPGRADE_PROGRESS}":"Upgrade progress""Upgrade Fortschritt", + "{WIN_PROVIDEID}":"Bitte gib eine gültige Fenster ID von win.list an.", + "{WIN_CANTCLOSETERMINAL}":"Du kannst dieses Terminal nicht schließen.", + "{WELCOME_TO_SHIFTORIUM}":"Willkommen zum Shiftorium!", + "{SUCCESSFULLY_CREATED_CHAT}":"Chat erfolgreich erstellt. Benutze chat.join{id:\"chat_id_hier\"} um ihm beizutreten.", + "{CHAT_HAS_JOINED}":"hat den Chat betreten.", + "{HAS_LEFT_CHAT}":"hat den Chat verlassen.", + "{SHIFTORIUM_EXP}":"The Shiftorium is your one-stop-shop for ShiftOS system enhancements, upgrades and applications. + + You can buy upgrades in the Shiftorium using a currency called Codepoints, which you can earn by doing various tasks within ShiftOS, such as playing Pong, stealing them from other users, and finding ways to make your own. It's up to you how you get your Codepoints. + + You can then use them to buy new applications, features, enhancements and upgrades for ShiftOS that make the user experience a lot better. Be careful though, buying too many system enhancements without buying new ways of earning Codepoints first can leave you in the dust and unable to upgrade the system. + + Anyways, feel free to browse from our wonderful selection! You can see a list of available upgrades on the left, as well as a progress bar showing how much you've upgraded the system compared to how much you still can.", + "{PONG_WELCOME}":"Welcome to Pong.", + "{PONG_DESC}":"Pong is an arcade game where your goal is to get the ball past the opponent paddle while keeping it from getting past yours. + + In ShiftOS, Pong is modified - you only have one chance, the game is divided into 60 second levels, and you can earn Codepoints by surviving a level, and beating the opponent.", + "{NO_APP_TO_OPEN}":"No app found for this file!", + "{NO_APP_TO_OPEN_EXP}":"File Skimmer could not find an application that can open this file.", + "{CLIENT_DIAGNOSTICS}":"Client diagnostics", + "{GUID}":"GUID", + "{CLIENT_DATA}":"Client data", + "{CLOSE}":"Close", + "{LOAD_DEFAULT}":"Load default", + "{IMPORT}":"Import", + "{EXPORT}":"Export", + "{APPLY}":"Apply", + "{TEMPLATE}":"Template", + "{H_VEL}":"Horizontal velocity", + "{V_VEL}":"Vertical velocity", + "{LEVEL}":"Level", + "{UPGRADE_DEVELOPMENT}":"Development Upgrade", + "{UPGRADE_DEVELOPMENT_DESCRIPTION}":"Development Upgrade Don't Buy", + "{SECONDS_LEFT}":"seconds left", + "{CASH_OUT_WITH_CODEPOINTS}":"Cash out with your codepoints", + "{PONG_PLAY_ON_FOR_MORE}":"Play on for more!", + "{YOU_REACHED_LEVEL}":"You've reached level", + "{PONG_BEAT_AI_REWARD}":"Reward for beating AI (CP)", + "{PONG_BEAT_AI_REWARD_SECONDARY}":"Codepoints for beating AI:", + "{CODEPOINTS_FOR_BEATING_LEVEL}":"Codepoints for beating level", + "{YOU_WON}":"You won", + "{YOU_LOSE}":"You lose", + "{TRY_AGAIN}":"Try again", + "{CODEPOINTS_SHORT}":"CP", + "{TERMINAL_FORMATTING_DRIVE}":"Formatting drive... %percent %", + "{INSTALLING_SHIFTOS}":"Installing ShiftOS on %domain.", + "{YOU_MISSED_OUT_ON}":"You missed out on", + "{BUT_YOU_GAINED}":"But you gained", + "{PONG_PLAYON_DESC}":"Or do you want to try your luck on the next level to increase your reward?", + "{PONG_CASHOUT_DESC}":"Would you like the end the game now and cash out with your reward?", + "{INITIAL_H_VEL}":"Initial H Vel", + "{INITIAL_V_VEL}":"Initial V Vel", + "{INC_H_VEL}":"Increment H Vel", + "{INC_V_VEL}":"Increment V Vel", + "{MULTIPLAYER_ONLY}":"Program not compatible with single-user domain.", + "{MULTIPLAYER_ONLY_EXP}":"This program cannot run within a single-user domain. You must be within a multi-user domain to use this program.", + "{SHIFTER_SKIN_APPLIED}":"Shifter - Settings applied!", + "{YOU_HAVE_EARNED}":"You have earned", + "{CREATING_PATH}":"Creating directory: %path", + "{CREATING_FILE}":"Creating file: %path", + "{SHIFTORIUM_HELP_DESCRIPTION}": "Help Descriptions", + "{CREATING_USER}":"Creating user %username", + "{SEPERATOR}":" - ", + "{NAMESPACE}":"Namespace ", + "{COMMAND}": "| Command ", + "{SHIFTOS_HAS_BEEN_INSTALLED}":"ShiftOS has been installed on %domain.", + "{WARN}": "WARN: ", + "{ERROR}": "!ERROR! ", + "{OBSOLETE_CHEATS_FREECP}": "The %ns.%cmd command is obsolete and has been replaced with %newcommand", + "{REBOOTING_SYSTEM}":"Rebooting system in %i seconds...", + "{ERROR_ARGUMENT_REQUIRED}": "You must supply an %argument value", + "{ERROR_ARGUMENT_REQUIRED_NO_USAGE}": "You are missing some arguments.", + "{GENERATING_PATHS}":"Generating paths...", + "{ERROR_COMMAND_WRONG}": "Check your syntax and try again", + "{LOGIN_EXP}": "Login as the admin of the multi user domain.", + + "{USAGE}": "Usage: ", + + "{NAMESPACE_SOS_DESCRIPTION}":"The ShiftOS Namespace", + "{COMMAND_HELP_USAGE}":"%ns.%cmd{[topic:]}", + "{COMMAND_HELP_DESCRIPTION}":"Lists all commands", + "{COMMAND_SOS_SHUTDOWN_USAGE}":"%ns.%cmd", + "{COMMAND_SOS_SHUTDOWN_DESCRIPTION}":"Saves and shuts down ShiftOS", + "{COMMAND_SOS_STATUS_USAGE}":"%ns.%cmd", + "{COMMAND_SOS_STATUS_DESCRIPTION}":"Displays how many codepoints you have", + "{COMMAND_DEV_CRASH_USAGE}":"%ns.%cmd", + "{COMMAND_DEV_CRASH_DESCRIPTION}":"Shuts down ShiftOS forcefully", + "{COMMAND_DEV_UNLOCKEVERYTHING_USAGE}":"%ns.%cmd", + "{COMMAND_DEV_UNLOCKEVERYTHING_DESCRIPTION}":"Unlocks all shiftorium upgrades", + "{COMMAND_DEV_FREECP_USAGE}":"%ns.%cmd{[amount:1000]}", + "{COMMAND_DEV_FREECP_DESCRIPTION}":"Gives [ammount] codepoints", + "{COMMAND_TRM_CLEAR_USAGE}":"%ns.%cmd", + "{COMMAND_TRM_CLEAR_DESCRIPTION}":"Clears the terminal", + "{COMMAND_SHIFTORIUM_BUY_USAGE}":"%ns.%cmd{upgrade:}", + "{COMMAND_SHIFTORIUM_BUY_DESCRIPTION}":"Buys [upgrade]", + "{COMMAND_SHIFTORIUM_LIST_USAGE}":"%ns.%cmd", + "{COMMAND_SHIFTORIUM_LIST_DESCRIPTION}":"Lists the upgrades that you can get", + "{COMMAND_SHIFTORIUM_INFO_USAGE}":"%ns.%cmd{upgrade:}", + "{COMMAND_SHIFTORIUM_INFO_DESCRIPTION}":"Gives a description about an upgrade", + "{COMMAND_DEV_MULTARG_USAGE}":"%ns.%cmd{id:,name:,type:}", + "{COMMAND_DEV_MULTARG_DESCRIPTION}":"A command which requiers multiple arguments", + + "{ERR_COMMAND_NOT_FOUND}":"Command not found.", + "{MUD_ERROR}":"MUD error", + + "{PROLOGUE_NO_USER_DETECTED}":"No user detected. Please enter a username.", + "{PROLOGUE_BADUSER}":"Invalid username detected.", + "{PROLOGUE_NOSPACES}":"Usernames must not contain spaces.", + "{PROLOGUE_PLEASE_ENTER_USERNAME}":"Please enter a valid username. Blank usernames are not permitted.", + + "{SHIFTORIUM_NOTENOUGHCP}":"Not enough codepoints: ", + "{SHIFTORIUM_TRANSFERRED_FROM}":"Received Codepoints from", + "{SHIFTORIUM_TRANSFERRED_TO}":"Transferred Codepoints to", + + "{SE_SAVING}":"Saving game to disk", + "{SE_TIPOFADVICE}":"Tip of advice: ShiftOS will always save your game after big events or when you shut down the operating system. You can also invoke a save yourself using 'sos.save'.", + + "{STORY_WELCOME}":"Welcome to ShiftOS", + "{STORY_SENTIENCEUNKNOWN}":"Your sentience is currently unknown. Please strike the Enter key to prove you are alive.", + + "{SENTIENCE_BASIC}":"Sentience: Basic - User can respond to basic instructions.", + "{SENTIENCE_BASICPLUS}":"Sentience: Basic+ - User can invoke commands within the ecosystem.", + "{SENTIENCE_POSSIBLEHUMAN}":"Sentience: Possible human - user can perform actions based on a choice.", + "{SENTIENCE_POSSIBLEHUMANPLUS}":"Sentience: Possible human+ - user can infer, and can pass arguments.", + "{SENTIENCE_HUMAN}":"Sentience: Human. Thanks for your patience.", + "{SENTIENCE_INVALIDPASSWORD}":"The password you entered is invalid.", + + "{ARGS_PASSWORD}":"password", + + "{SHIFTOS_PLUS_MOTTO}":"ShiftOS, Shift it YOUR way.", + "{SHIFTOS_VERSION_INFO}":"ShiftOS Version: ", + "{USER_NAME}":"Username", + "{DISCOURSE_INTEGRATION}":"Discourse Integration", + "{SYSTEM_NAME}":"System Name", + "{USER_INFO}":"User Information", + "{SELECT_LANG}":"Select language", + "{WELCOME_TO_SHIFTOS}":"Welcome to ShiftOS Alpha!", + "{CREATE}":"Create", + "{INSTALL}":"Install", + "{ALIAS}":"Alias:", + "{OBSOLETE_SYS_SHUTDOWN}":"sys.shutdown is obsolete", + "{PY_EXCEPTION}":"There was an error running python code.", + "{LUA_ERROR}":"There was an error running lua code." + + "{TERMINAL_NAME}":"Terminal", + "{ARTPAD_NAME}":"Artpad", + "{PONG_NAME}":"Pong", +} \ No newline at end of file diff --git a/ShiftOS_TheReturn/Resources/strings_en.txt b/ShiftOS_TheReturn/Resources/strings_en.txt new file mode 100644 index 0000000..6cd1be0 --- /dev/null +++ b/ShiftOS_TheReturn/Resources/strings_en.txt @@ -0,0 +1,222 @@ +{ + "{SUBMIT}":"Submit", + +"{TERMINAL_TUTORIAL_1}":"Welcome to the ShiftOS terminal. This is where you will spend the bulk of your time within ShiftOS. + +A brief rundown of how to use the terminal is as follows. You can use the 'sos.help' command to show a list of all commands. Simply type it in and strike to view all commands. + +Commands can be sent arguments by specifying a key-value pair inside a {} block at the end of the command. For example: + +some.command{print:\"hello\"} +math.add{op1:1,op2:2} +set.value{key:\"somekey\", value:true} + +You have been given 50 Codepoints - use your knowledge to use them to buy the MUD Fundamentals Shiftorium Upgrade using the terminal. +To buy MUD Fundamentals, type shiftorium.buy{upgrade:\"mud_fundamentals\"} This is also true for any other thing you want to buy from the shiftorium, just replace mud_fundementals with any other upgrade id. +", + + + "{TERMINAL_TUTORIAL_2}":"You successfully passed the test. ShiftOS will now start installing it's base functionality.", + "{ABOUT}":"About", + "{START_SYSTEM_SCAN}":"Start system-wide scan", + "{SCAN_HOME}":"Scan 0:/home", + "{SCAN_SYSTEM}":"Scan 0:/system", + "{RESULTS}":"Results", + "{VIRUSSCANNER_ABOUT}":"Welcome to the ShiftOS virus scanner. + +The ShiftOS virus scanner is a utility that allows you to scan any file on your system and see if it is a virus. If a virus is detected, you have the option to delete it after the scan by clicking 'Remove'. + +If a system file is deleted by the virus scanner, it will be replaced.", + "{PLAY}":"Play", + "{APPLICATIONS}":"Applications", + "{TERMINAL}":"Terminal", + "{PONG}":"Pong", + "{CODEPOINTS}":"Codepoints", + "{CODEPOINTS_VALUE}":"%cp " + "{SHIFTORIUM}":"Shiftorium", + "{HACK}":"Hack", + "{SHIFTER}":"Shifter", + "{MUD_SHORT}":"MUD", + "{MUD}":"Multi-user domain", + "{DESKTOP}":"Desktop", + "{WINDOW}":"Window", + "{WINDOW_MANAGER}":"Window manager", + "{UPGRADE}":"Upgrade", + "{UPGRADES}":"Upgrades", + "{APPLICATION}":"Application", + "{SCRIPT}":"Script", + "{ERROR}":"Error", + "{SCRIPTS}":"Scripts", + "{NULL}":"null", + "{ID}":"ID Num", + "{SYSTEM_INITIATED}":"System initiated", + "{PASSWORD}":"Password", + "{CRACK}":"Crack", + "{ARTPAD_UNDO_ERROR}":"Artpad - Undo error", + "{ARTPAD_NEXT_STEP_WILL_KILL_CANVAS_JUST_FLIPPING_CLICK_NEW}":"You cannot undo the previous action as it would delete the canvas. If you'd like to clear the canvas, click New.", + "{ARTPAD_REDO_ERROR}":"Artpad - Redo error", + "{ARTPAD_NOTHING_TO_REDO}": "Artpad has nothing to redo! Remember that when you undo and then draw on the canvas, all redo history is wiped.", + "{ARTPAD_MAGNIFIER_ERROR}": "Artpad - Magnifier error", + "{ARTPAD_MAGNIFICATION_ERROR_EXP_2}": "Artpad cannot zoom out any further as the canvas would disappear!", + "{ARTPAD_MAGNIFICATION_ERROR_EXP}": "Artpad cannot zoom any further into the canvas. Well, it can, it just doesn't want to.", + "{SHUTDOWN}":"Shutdown", + "{CONNECTING_TO_MUD}":"Connecting to the multi-user domain...", + "{READING_FS}":"Reading filesystem...", + "{INIT_KERNEL}":"Initiating kernel...", + "{START_DESKTOP}":"Starting desktop session...", + "{DONE}": "done", + "{READING_CONFIG}":"Reading configuration...", + "{ID_TAKEN}":"ID has been taken! Use chat.join to join this chat.", + "{CHAT_NOT_FOUND_OR_TOO_MANY_MEMBERS}":"This chat either doesn't exist or has too many users in it.", + "{CHAT_NOT_FOUND_OR_NOT_IN_CHAT}":"You are not currently in this chat.", + "{CHAT_PLEASE_PROVIDE_VALID_CHANNEL_DATA}":"You did not specify valid chat metadata! Please do chat.create{id:\"your_id\", name:\"Your chat\", topic:\"Your chat's topic\"}.", + "{UPGRADE_PROGRESS}":"Upgrade progress", + "{WIN_PROVIDEID}":"Please provide a valid Window ID from win.list.", + "{WIN_CANTCLOSETERMINAL}":"You cannot close this terminal.", + "{WELCOME_TO_SHIFTORIUM}":"Welcome to the Shiftorium", + "{SUCCESSFULLY_CREATED_CHAT}":"Successfully created chat. Use chat.join{id:\"chat_id_here\"} to join it.", + "{CHAT_HAS_JOINED}":"has joined the chat.", + "{HAS_LEFT_CHAT}":"has left the chat.", + "{SHIFTORIUM_EXP}":"The Shiftorium is your one-stop-shop for ShiftOS system enhancements, upgrades and applications. + + You can buy upgrades in the Shiftorium using a currency called Codepoints, which you can earn by doing various tasks within ShiftOS, such as playing Pong, stealing them from other users, and finding ways to make your own. It's up to you how you get your Codepoints. + + You can then use them to buy new applications, features, enhancements and upgrades for ShiftOS that make the user experience a lot better. Be careful though, buying too many system enhancements without buying new ways of earning Codepoints first can leave you in the dust and unable to upgrade the system. + + Anyways, feel free to browse from our wonderful selection! You can see a list of available upgrades on the left, as well as a progress bar showing how much you've upgraded the system compared to how much you still can.", + "{PONG_WELCOME}":"Welcome to Pong.", + "{PONG_DESC}":"Pong is an arcade game where your goal is to get the ball past the opponent paddle while keeping it from getting past yours. + + In ShiftOS, Pong is modified - you only have one chance, the game is divided into 60 second levels, and you can earn Codepoints by surviving a level, and beating the opponent.", + "{NO_APP_TO_OPEN}":"No app found for this file!", + "{NO_APP_TO_OPEN_EXP}":"File Skimmer could not find an application that can open this file.", + "{CLIENT_DIAGNOSTICS}":"Client diagnostics", + "{GUID}":"GUID", + "{CLIENT_DATA}":"Client data", + "{CLOSE}":"Close", + "{LOAD_DEFAULT}":"Load default", + "{IMPORT}":"Import", + "{EXPORT}":"Export", + "{APPLY}":"Apply", + "{TEMPLATE}":"Template", + "{H_VEL}":"Horizontal velocity", + "{V_VEL}":"Vertical velocity", + "{LEVEL}":"Level", + "{UPGRADE_DEVELOPMENT}":"Development Upgrade", + "{UPGRADE_DEVELOPMENT_DESCRIPTION}":"Development Upgrade Don't Buy", + "{SECONDS_LEFT}":"seconds left", + "{CASH_OUT_WITH_CODEPOINTS}":"Cash out with your codepoints", + "{PONG_PLAY_ON_FOR_MORE}":"Play on for more!", + "{YOU_REACHED_LEVEL}":"You've reached level", + "{PONG_BEAT_AI_REWARD}":"Reward for beating AI (CP)", + "{PONG_BEAT_AI_REWARD_SECONDARY}":"Codepoints for beating AI:", + "{CODEPOINTS_FOR_BEATING_LEVEL}":"Codepoints for beating level", + "{YOU_WON}":"You won", + "{YOU_LOSE}":"You lose", + "{TRY_AGAIN}":"Try again", + "{CODEPOINTS_SHORT}":"CP", + "{TERMINAL_FORMATTING_DRIVE}":"Formatting drive... %percent %", + "{INSTALLING_SHIFTOS}":"Installing ShiftOS on %domain.", + "{YOU_MISSED_OUT_ON}":"You missed out on", + "{BUT_YOU_GAINED}":"But you gained", + "{PONG_PLAYON_DESC}":"Or do you want to try your luck on the next level to increase your reward?", + "{PONG_CASHOUT_DESC}":"Would you like the end the game now and cash out with your reward?", + "{INITIAL_H_VEL}":"Initial H Vel", + "{INITIAL_V_VEL}":"Initial V Vel", + "{INC_H_VEL}":"Increment H Vel", + "{INC_V_VEL}":"Increment V Vel", + "{MULTIPLAYER_ONLY}":"Program not compatible with single-user domain.", + "{MULTIPLAYER_ONLY_EXP}":"This program cannot run within a single-user domain. You must be within a multi-user domain to use this program.", + "{SHIFTER_SKIN_APPLIED}":"Shifter - Settings applied!", + "{YOU_HAVE_EARNED}":"You have earned", + "{YOU_HAVE}":"You have: ", + "{CREATING_PATH}":"Creating directory: %path", + "{CREATING_FILE}":"Creating file: %path", + "{SHIFTORIUM_HELP_DESCRIPTION}": "Help Descriptions", + "{CREATING_USER}":"Creating user %username", + "{SEPERATOR}":" - ", + "{NAMESPACE}":"Namespace ", + "{COMMAND}": "| Command ", + "{SHIFTOS_HAS_BEEN_INSTALLED}":"ShiftOS has been installed on %domain.", + "{WARN}": "WARN: ", + "{ERROR}": "!ERROR! ", + "{OBSOLETE_CHEATS_FREECP}": "The %ns.%cmd command is obsolete and has been replaced with %newcommand", + "{REBOOTING_SYSTEM}":"Rebooting system in %i seconds...", + "{ERROR_ARGUMENT_REQUIRED}": "You must supply an %argument value", + "{ERROR_ARGUMENT_REQUIRED_NO_USAGE}": "You are missing some arguments.", + "{GENERATING_PATHS}":"Generating paths...", + "{ERROR_COMMAND_WRONG}": "Check your syntax and try again", + "{LOGIN_EXP}": "Login as the admin of the multi user domain.", + + "{USAGE}": "Usage: ", + + "{NAMESPACE_SOS_DESCRIPTION}":"The ShiftOS Namespace", + "{COMMAND_HELP_USAGE}":"%ns.%cmd{[topic:]}", + "{COMMAND_HELP_DESCRIPTION}":"Lists all commands", + "{COMMAND_SOS_SHUTDOWN_USAGE}":"%ns.%cmd", + "{COMMAND_SOS_SHUTDOWN_DESCRIPTION}":"Saves and shuts down ShiftOS", + "{COMMAND_SOS_STATUS_USAGE}":"%ns.%cmd", + "{COMMAND_SOS_STATUS_DESCRIPTION}":"Displays how many codepoints you have", + "{COMMAND_DEV_CRASH_USAGE}":"%ns.%cmd", + "{COMMAND_DEV_CRASH_DESCRIPTION}":"Shuts down ShiftOS forcefully", + "{COMMAND_DEV_UNLOCKEVERYTHING_USAGE}":"%ns.%cmd", + "{COMMAND_DEV_UNLOCKEVERYTHING_DESCRIPTION}":"Unlocks all shiftorium upgrades", + "{COMMAND_DEV_FREECP_USAGE}":"%ns.%cmd{[amount:1000]}", + "{COMMAND_DEV_FREECP_DESCRIPTION}":"Gives [ammount] codepoints", + "{COMMAND_TRM_CLEAR_USAGE}":"%ns.%cmd", + "{COMMAND_TRM_CLEAR_DESCRIPTION}":"Clears the terminal", + "{COMMAND_SHIFTORIUM_BUY_USAGE}":"%ns.%cmd{upgrade:}", + "{COMMAND_SHIFTORIUM_BUY_DESCRIPTION}":"Buys [upgrade]", + "{COMMAND_SHIFTORIUM_LIST_USAGE}":"%ns.%cmd", + "{COMMAND_SHIFTORIUM_LIST_DESCRIPTION}":"Lists the upgrades that you can get", + "{COMMAND_SHIFTORIUM_INFO_USAGE}":"%ns.%cmd{upgrade:}", + "{COMMAND_SHIFTORIUM_INFO_DESCRIPTION}":"Gives a description about an upgrade", + "{COMMAND_DEV_MULTARG_USAGE}":"%ns.%cmd{id:,name:,type:}", + "{COMMAND_DEV_MULTARG_DESCRIPTION}":"A command which requiers multiple arguments", + + "{ERR_COMMAND_NOT_FOUND}":"Command not found.", + "{MUD_ERROR}":"MUD error", + + "{PROLOGUE_NO_USER_DETECTED}":"No user detected. Please enter a username.", + "{PROLOGUE_BADUSER}":"Invalid username detected.", + "{PROLOGUE_NOSPACES}":"Usernames must not contain spaces.", + "{PROLOGUE_PLEASE_ENTER_USERNAME}":"Please enter a valid username. Blank usernames are not permitted.", + + "{SHIFTORIUM_NOTENOUGHCP}":"Not enough codepoints: ", + "{SHIFTORIUM_TRANSFERRED_FROM}":"Received Codepoints from", + "{SHIFTORIUM_TRANSFERRED_TO}":"Transferred Codepoints to", + + "{SE_SAVING}":"Saving game to disk", + "{SE_TIPOFADVICE}":"Tip of advice: ShiftOS will always save your game after big events or when you shut down the operating system. You can also invoke a save yourself using 'sos.save'.", + + "{STORY_WELCOME}":"Welcome to ShiftOS", + "{STORY_SENTIENCEUNKNOWN}":"Your sentience is currently unknown. Please strike the Enter key to prove you are alive.", + + "{SENTIENCE_BASIC}":"Sentience: Basic - User can respond to basic instructions.", + "{SENTIENCE_BASICPLUS}":"Sentience: Basic+ - User can invoke commands within the ecosystem.", + "{SENTIENCE_POSSIBLEHUMAN}":"Sentience: Possible human - user can perform actions based on a choice.", + "{SENTIENCE_POSSIBLEHUMANPLUS}":"Sentience: Possible human+ - user can infer, and can pass arguments.", + "{SENTIENCE_HUMAN}":"Sentience: Human. Thanks for your patience.", + "{SENTIENCE_INVALIDPASSWORD}":"The password you entered is invalid.", + + "{ARGS_PASSWORD}":"password", + + "{SHIFTOS_PLUS_MOTTO}":"ShiftOS, Shift it YOUR way.", + "{SHIFTOS_VERSION_INFO}":"ShiftOS Version: ", + "{USER_NAME}":"Username", + "{DISCOURSE_INTEGRATION}":"Discourse Integration", + "{SYSTEM_NAME}":"System Name", + "{USER_INFO}":"User Information", + "{SELECT_LANG}":"Select language", + "{WELCOME_TO_SHIFTOS}":"Welcome to ShiftOS Alpha!", + "{CREATE}":"Create", + "{INSTALL}":"Install", + "{ALIAS}":"Alias:", + "{OBSOLETE_SYS_SHUTDOWN}":"sys.shutdown is obsolete", + "{PY_EXCEPTION}":"There was an error running python code.", + "{LUA_ERROR}":"There was an error running lua code." + + "{TERMINAL_NAME}":"Terminal", + "{ARTPAD_NAME}":"Artpad", + "{PONG_NAME}":"Pong", +} \ No newline at end of file diff --git a/ShiftOS_TheReturn/Resources/strings_ver.txt b/ShiftOS_TheReturn/Resources/strings_ver.txt new file mode 100644 index 0000000..9c67bda --- /dev/null +++ b/ShiftOS_TheReturn/Resources/strings_ver.txt @@ -0,0 +1,216 @@ +{ + "{SUBMIT}":"You as a homo sapien are going to perform an action where you confirm what you have said", + +"{TERMINAL_TUTORIAL_1}":"Welcome to the ShiftOS terminal. This is where you will spend the bulk of your time within ShiftOS. + +A brief rundown of how to use the terminal is as follows. You can use the 'sos.help' command to show a list of all commands. Simply type it in and strike to view all commands. + +Commands can be sent arguments by specifying a key-value pair inside a {} block at the end of the command. For example: + +some.command{print:\"hello\"} +math.add{op1:1,op2:2} +set.value{key:\"somekey\", value:true} + +You have been given 50 Codepoints - use your knowledge to use them to buy the MUD Fundamentals Shiftorium Upgrade using the terminal. +To buy MUD Fundamentals, type shiftorium.buy{upgrade:\"mud_fundamentals\"} This is also true for any other thing you want to buy from the shiftorium, just replace mud_fundementals with any other upgrade id. +", + + + "{TERMINAL_TUTORIAL_2}":"You successfully passed the test. ShiftOS will now start installing it's base functionality.", + "{ABOUT}":"About", + "{START_SYSTEM_SCAN}":"Start system-wide scan", + "{SCAN_HOME}":"Scan 0:/home", + "{SCAN_SYSTEM}":"Scan 0:/system", + "{RESULTS}":"Results", + "{VIRUSSCANNER_ABOUT}":"Welcome to the ShiftOS virus scanner. + +The ShiftOS virus scanner is a utility that allows you to scan any file on your system and see if it is a virus. If a virus is detected, you have the option to delete it after the scan by clicking 'Remove'. + +If a system file is deleted by the virus scanner, it will be replaced.", + "{PLAY}":"Play", + "{APPLICATIONS}":"Applications", + "{TERMINAL}":"Terminal", + "{PONG}":"Pong", + "{CODEPOINTS}":"Codepoints", + "{SHIFTORIUM}":"Shiftorium", + "{HACK}":"Hack", + "{SHIFTER}":"Shifter", + "{MUD_SHORT}":"MUD", + "{MUD}":"Multi-user domain", + "{DESKTOP}":"Desktop", + "{WINDOW}":"Window", + "{WINDOW_MANAGER}":"Window manager", + "{UPGRADE}":"Upgrade", + "{UPGRADES}":"Upgrades", + "{APPLICATION}":"Application", + "{SCRIPT}":"Script", + "{ERROR}":"Error", + "{SCRIPTS}":"Scripts", + "{NULL}":"null", + "{ID}":"ID Num", + "{SYSTEM_INITIATED}":"System initiated", + "{PASSWORD}":"Password", + "{CRACK}":"Crack", + "{ARTPAD_UNDO_ERROR}":"Artpad - Undo error", + "{ARTPAD_NEXT_STEP_WILL_KILL_CANVAS_JUST_FLIPPING_CLICK_NEW}":"You cannot undo the previous action as it would delete the canvas. If you'd like to clear the canvas, click New.", + "{ARTPAD_REDO_ERROR}":"Artpad - Redo error", + "{ARTPAD_NOTHING_TO_REDO}": "Artpad has nothing to redo! Remember that when you undo and then draw on the canvas, all redo history is wiped.", + "{ARTPAD_MAGNIFIER_ERROR}": "Artpad - Magnifier error", + "{ARTPAD_MAGNIFICATION_ERROR_EXP_2}": "Artpad cannot zoom out any further as the canvas would disappear!", + "{ARTPAD_MAGNIFICATION_ERROR_EXP}": "Artpad cannot zoom any further into the canvas. Well, it can, it just doesn't want to.", + "{SHUTDOWN}":"Shutdown", + "{CONNECTING_TO_MUD}":"Connecting to the multi-user domain...", + "{READING_FS}":"Reading filesystem...", + "{INIT_KERNEL}":"Initiating kernel...", + "{START_DESKTOP}":"Starting desktop session...", + "{DONE}": "done", + "{READING_CONFIG}":"Reading configuration...", + "{ID_TAKEN}":"ID has been taken! Use chat.join to join this chat.", + "{CHAT_NOT_FOUND_OR_TOO_MANY_MEMBERS}":"This chat either doesn't exist or has too many users in it.", + "{CHAT_NOT_FOUND_OR_NOT_IN_CHAT}":"You are not currently in this chat.", + "{CHAT_PLEASE_PROVIDE_VALID_CHANNEL_DATA}":"You did not specify valid chat metadata! Please do chat.create{id:\"your_id\", name:\"Your chat\", topic:\"Your chat's topic\"}.", + "{UPGRADE_PROGRESS}":"Upgrade progress", + "{WIN_PROVIDEID}":"Please provide a valid Window ID from win.list.", + "{WIN_CANTCLOSETERMINAL}":"You cannot close this terminal.", + "{WELCOME_TO_SHIFTORIUM}":"Welcome to the Shiftorium", + "{SUCCESSFULLY_CREATED_CHAT}":"Successfully created chat. Use chat.join{id:\"chat_id_here\"} to join it.", + "{CHAT_HAS_JOINED}":"has joined the chat.", + "{HAS_LEFT_CHAT}":"has left the chat.", + "{SHIFTORIUM_EXP}":"The Shiftorium is your one-stop-shop for ShiftOS system enhancements, upgrades and applications. + + You can buy upgrades in the Shiftorium using a currency called Codepoints, which you can earn by doing various tasks within ShiftOS, such as playing Pong, stealing them from other users, and finding ways to make your own. It's up to you how you get your Codepoints. + + You can then use them to buy new applications, features, enhancements and upgrades for ShiftOS that make the user experience a lot better. Be careful though, buying too many system enhancements without buying new ways of earning Codepoints first can leave you in the dust and unable to upgrade the system. + + Anyways, feel free to browse from our wonderful selection! You can see a list of available upgrades on the left, as well as a progress bar showing how much you've upgraded the system compared to how much you still can.", + "{PONG_WELCOME}":"You as a homo sapien are brought to this application known as Pong, and you are certainly welcome to this application.", + "{PONG_DESC}":"Pong is an arcade game where your goal is to get the ball past the opponent paddle while keeping it from getting past yours. + + In ShiftOS, Pong is modified - you only have one chance, the game is divided into 60 second levels, and you can earn Codepoints by surviving a level, and beating the opponent.", + "{NO_APP_TO_OPEN}":"No app found for this file!", + "{NO_APP_TO_OPEN_EXP}":"File Skimmer could not find an application that can open this file.", + "{CLIENT_DIAGNOSTICS}":"Client diagnostics", + "{GUID}":"GUID", + "{CLIENT_DATA}":"Client data", + "{CLOSE}":"Close", + "{LOAD_DEFAULT}":"Load default", + "{IMPORT}":"Import", + "{EXPORT}":"Export", + "{APPLY}":"Apply", + "{TEMPLATE}":"Template", + "{H_VEL}":"Horizontal velocity", + "{V_VEL}":"Vertical velocity", + "{LEVEL}":"Level", + "{UPGRADE_DEVELOPMENT}":"Development Upgrade", + "{UPGRADE_DEVELOPMENT_DESCRIPTION}":"Development Upgrade Don't Buy", + "{SECONDS_LEFT}":"seconds left", + "{CASH_OUT_WITH_CODEPOINTS}":"Cash out with your codepoints", + "{PONG_PLAY_ON_FOR_MORE}":"Play on for more!", + "{YOU_REACHED_LEVEL}":"You've reached level", + "{PONG_BEAT_AI_REWARD}":"Reward for beating AI (CP)", + "{PONG_BEAT_AI_REWARD_SECONDARY}":"Codepoints for beating AI:", + "{CODEPOINTS_FOR_BEATING_LEVEL}":"Codepoints for beating level", + "{YOU_WON}":"You won", + "{YOU_LOSE}":"You lose", + "{TRY_AGAIN}":"Try again", + "{CODEPOINTS_SHORT}":"CP", + "{TERMINAL_FORMATTING_DRIVE}":"Formatting drive... %percent %", + "{INSTALLING_SHIFTOS}":"Installing ShiftOS on %domain.", + "{YOU_MISSED_OUT_ON}":"You missed out on", + "{BUT_YOU_GAINED}":"But you gained", + "{PONG_PLAYON_DESC}":"Or do you want to try your luck on the next level to increase your reward?", + "{PONG_CASHOUT_DESC}":"Would you like the end the game now and cash out with your reward?", + "{INITIAL_H_VEL}":"Initial H Vel", + "{INITIAL_V_VEL}":"Initial V Vel", + "{INC_H_VEL}":"Increment H Vel", + "{INC_V_VEL}":"Increment V Vel", + "{MULTIPLAYER_ONLY}":"Program not compatible with single-user domain.", + "{MULTIPLAYER_ONLY_EXP}":"This program cannot run within a single-user domain. You must be within a multi-user domain to use this program.", + "{SHIFTER_SKIN_APPLIED}":"Shifter - Settings applied!", + "{YOU_HAVE_EARNED}":"You have earned", + "{CREATING_PATH}":"Creating directory: %path", + "{CREATING_FILE}":"Creating file: %path", + "{SHIFTORIUM_HELP_DESCRIPTION}": "Help Descriptions", + "{CREATING_USER}":"Creating user %username", + "{SEPERATOR}":" - ", + "{NAMESPACE}":"Namespace ", + "{COMMAND}": "| Command ", + "{SHIFTOS_HAS_BEEN_INSTALLED}":"ShiftOS has been installed on %domain.", + "{WARN}": "WARN: ", + "{ERROR}": "!ERROR! ", + "{OBSOLETE_CHEATS_FREECP}": "The %ns.%cmd command is obsolete and has been replaced with %newcommand", + "{REBOOTING_SYSTEM}":"Rebooting system in %i seconds...", + "{ERROR_ARGUMENT_REQUIRED}": "You must supply an %argument value", + "{ERROR_ARGUMENT_REQUIRED_NO_USAGE}": "You are missing some arguments.", + "{GENERATING_PATHS}":"Generating paths...", + "{ERROR_COMMAND_WRONG}": "Check your syntax and try again", + "{LOGIN_EXP}": "Login as the admin of the multi user domain.", + + "{USAGE}": "Usage: ", + + "{NAMESPACE_SOS_DESCRIPTION}":"The ShiftOS Namespace", + "{COMMAND_HELP_USAGE}":"%ns.%cmd{[topic:]}", + "{COMMAND_HELP_DESCRIPTION}":"Lists all commands", + "{COMMAND_SOS_SHUTDOWN_USAGE}":"%ns.%cmd", + "{COMMAND_SOS_SHUTDOWN_DESCRIPTION}":"Saves and shuts down ShiftOS", + "{COMMAND_SOS_STATUS_USAGE}":"%ns.%cmd", + "{COMMAND_SOS_STATUS_DESCRIPTION}":"Displays how many codepoints you have", + "{COMMAND_DEV_CRASH_USAGE}":"%ns.%cmd", + "{COMMAND_DEV_CRASH_DESCRIPTION}":"Shuts down ShiftOS forcefully", + "{COMMAND_DEV_UNLOCKEVERYTHING_USAGE}":"%ns.%cmd", + "{COMMAND_DEV_UNLOCKEVERYTHING_DESCRIPTION}":"Unlocks all shiftorium upgrades", + "{COMMAND_DEV_FREECP_USAGE}":"%ns.%cmd{[amount:1000]}", + "{COMMAND_DEV_FREECP_DESCRIPTION}":"Gives [ammount] codepoints", + "{COMMAND_TRM_CLEAR_USAGE}":"%ns.%cmd", + "{COMMAND_TRM_CLEAR_DESCRIPTION}":"Clears the terminal", + "{COMMAND_SHIFTORIUM_BUY_USAGE}":"%ns.%cmd{upgrade:}", + "{COMMAND_SHIFTORIUM_BUY_DESCRIPTION}":"Buys [upgrade]", + "{COMMAND_SHIFTORIUM_LIST_USAGE}":"%ns.%cmd", + "{COMMAND_SHIFTORIUM_LIST_DESCRIPTION}":"Lists the upgrades that you can get", + "{COMMAND_SHIFTORIUM_INFO_USAGE}":"%ns.%cmd{upgrade:}", + "{COMMAND_SHIFTORIUM_INFO_DESCRIPTION}":"Gives a description about an upgrade", + "{COMMAND_DEV_MULTARG_USAGE}":"%ns.%cmd{id:,name:,type:}", + "{COMMAND_DEV_MULTARG_DESCRIPTION}":"A command which requiers multiple arguments", + + "{ERR_COMMAND_NOT_FOUND}":"Command not found.", + "{MUD_ERROR}":"MUD error", + + "{PROLOGUE_NO_USER_DETECTED}":"No user detected. Please enter a username.", + "{PROLOGUE_BADUSER}":"Invalid username detected.", + "{PROLOGUE_NOSPACES}":"Usernames must not contain spaces.", + "{PROLOGUE_PLEASE_ENTER_USERNAME}":"Please enter a valid username. Blank usernames are not permitted.", + + "{SHIFTORIUM_NOTENOUGHCP}":"Not enough codepoints: ", + "{SHIFTORIUM_TRANSFERRED_FROM}":"Received Codepoints from", + "{SHIFTORIUM_TRANSFERRED_TO}":"Transferred Codepoints to", + + "{SE_SAVING}":"Saving game to disk", + "{SE_TIPOFADVICE}":"Tip of advice: ShiftOS will always save your game after big events or when you shut down the operating system. You can also invoke a save yourself using 'sos.save'.", + + "{STORY_WELCOME}":"Welcome to ShiftOS", + "{STORY_SENTIENCEUNKNOWN}":"Your sentience is currently unknown. Please strike the Enter key to prove you are alive.", + + "{SENTIENCE_BASIC}":"Sentience: Basic - User can respond to basic instructions.", + "{SENTIENCE_BASICPLUS}":"Sentience: Basic+ - User can invoke commands within the ecosystem.", + "{SENTIENCE_POSSIBLEHUMAN}":"Sentience: Possible human - user can perform actions based on a choice.", + "{SENTIENCE_POSSIBLEHUMANPLUS}":"Sentience: Possible human+ - user can infer, and can pass arguments.", + "{SENTIENCE_HUMAN}":"Sentience: Human. Thanks for your patience.", + "{SENTIENCE_INVALIDPASSWORD}":"The password you entered is invalid.", + + "{ARGS_PASSWORD}":"password", + + "{SHIFTOS_PLUS_MOTTO}":"ShiftOS, Shift it YOUR way.", + "{SHIFTOS_VERSION_INFO}":"ShiftOS Version: ", + "{USER_NAME}":"Username", + "{DISCOURSE_INTEGRATION}":"Discourse Integration", + "{SYSTEM_NAME}":"System Name", + "{USER_INFO}":"User Information", + "{SELECT_LANG}":"Select language", + "{WELCOME_TO_SHIFTOS}":"Welcome to ShiftOS Alpha!", + "{CREATE}":"Create", + "{INSTALL}":"Install", + "{ALIAS}":"Alias:", + "{OBSOLETE_SYS_SHUTDOWN}":"sys.shutdown is obsolete", + "{PY_EXCEPTION}":"There was an error running python code.", + "{LUA_ERROR}":"There was an error running lua code." +} \ No newline at end of file diff --git a/ShiftOS_TheReturn/Resources/sys_shiftoriumstory.txt b/ShiftOS_TheReturn/Resources/sys_shiftoriumstory.txt new file mode 100644 index 0000000..93a06ba --- /dev/null +++ b/ShiftOS_TheReturn/Resources/sys_shiftoriumstory.txt @@ -0,0 +1,45 @@ +{ + Character: "sys", + Lines:[ + "Hello there, %user.", + "Welcome to ShiftOS.", + "This is an automated message to all new sentiences within the ShiftOS multi-user domain.", + "Before you can begin with ShiftOS, you'll need to know a few things about it.", + "One: Terminal command syntax.", + "Inside ShiftOS, the bulk of your time is going to be spent within the Terminal.", + "The Terminal is an application that starts up when you turn on your computer. It allows you to execute system commands, open programs and control your system.", + "To enter commands into your terminal, simply type in the user who created the command's name, a.k.a it's \"namespace\", followed by a period (.) followed by the command's name.", + "For example, sos.help.", + "If you would like to specify command parameters, you can do so by entering a set of curly braces {} after the command name.", + "An empty set of curly braces, or none at all, means no parameters. However, if you'd like to send a parameter, inside the curly braces, type the parameter name", + "followed by a colon (:) and then the value.", + "There are various value types you can use: + + - Booleans ({key:true, key2:false}) + - Integers ({number:123}) - Note that integers have a maximum value of 2.4 billion. + - Strings ({key:\"value\"}) + - Objects ({key:{key2:\"value\"}}) + - Arrays ({key:[\"element 1\", \"element 2\"]})", + "For example, I can do win.open{app:\"pong\"} to open the Pong application from the Terminal.", + "Next on the list - Codepoints and the Shiftorium.", + "Right now you only have two applications - the Terminal, and Pong.", + "This is not a usable operating system.", + "You can only have one application open.", + "You can't customize it.", + "You can't access your files.", + "Only the Terminal and Pong.", + "But fear not. You can upgrade ShiftOS just like you would a car or a home.", + "You can buy new applications, tweaks, features, and other upgrades.", + "But how?", + "First, you need Codepoints.", + "cmd:givecp 50", + "You have been given 50 Codepoints.", + "You can use Codepoints to buy upgrades inside the Shiftorium.", + "The first upgrade you want to buy is called MUD Fundamentals.", + "It unlocks certain capabilities within the multi-user domain such as the ability to run scripts and commands within the multi-user domain, as well as the ability to chat with other sentiences and upload your own programs.", + "It costs 50 Codepoints. You may buy it using the codepoints you have been given, or you can try and earn your own Codepoints using pong.", + "But be careful, it's best to buy things that can give you even more Codepoints...", + "because when you run out and can't make any more.... you're stuck with what you've got.", + "Disconnecting from sentience '%user' on system %domain.", + ] +} \ No newline at end of file diff --git a/ShiftOS_TheReturn/SaveSystem.cs b/ShiftOS_TheReturn/SaveSystem.cs new file mode 100644 index 0000000..b746003 --- /dev/null +++ b/ShiftOS_TheReturn/SaveSystem.cs @@ -0,0 +1,268 @@ +//#define ONLINEMODE + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.IO; +using Newtonsoft.Json; +using ShiftOS.Objects; +using ShiftOS.Objects.ShiftFS; +using oobe = ShiftOS.Engine.OutOfBoxExperience; +using static System.Net.Mime.MediaTypeNames; + +namespace ShiftOS.Engine +{ + public class EngineConfig + { + public bool ConnectToMud = true; + public string MudDefaultIP = "dome.rol.im"; + public int MudDefaultPort = 13370; + } + + public static class SaveSystem + { + public static bool ShuttingDown = false; + + public static Save CurrentSave { get; set; } + + /// + /// Start the entire ShiftOS engine. + /// + /// Whether ShiftOS should initiate it's Windows Forms front-end. + public static void Begin(bool useDefaultUI = true) + { + if (!System.IO.File.Exists(Paths.SaveFile)) + { + var root = new ShiftOS.Objects.ShiftFS.Directory(); + root.Name = "System"; + root.permissions = Permissions.All; + System.IO.File.WriteAllText(Paths.SaveFile, JsonConvert.SerializeObject(root)); + } + + + if (Utils.Mounts.Count == 0) + Utils.Mount(System.IO.File.ReadAllText(Paths.SaveFile)); + Paths.Init(); + + Localization.SetupTHETRUEDefaultLocals(); + SkinEngine.Init(); + + TerminalBackend.OpenTerminal(); + + TerminalBackend.InStory = true; + var thread = new Thread(new ThreadStart(() => + { + //Do not uncomment until I sort out the copyright stuff... - Michael + //AudioManager.Init(); + + var defaultConf = new EngineConfig(); + if (System.IO.File.Exists("engineconfig.json")) + defaultConf = JsonConvert.DeserializeObject(System.IO.File.ReadAllText("engineconfig.json")); + else + { + System.IO.File.WriteAllText("engineconfig.json", JsonConvert.SerializeObject(defaultConf, Formatting.Indented)); + } + + Thread.Sleep(350); + Console.WriteLine("Initiating kernel..."); + Thread.Sleep(250); + Console.WriteLine("Reading filesystem..."); + Thread.Sleep(100); + Console.WriteLine("Reading configuration..."); + + Console.WriteLine("{CONNECTING_TO_MUD}"); + + if (defaultConf.ConnectToMud == true) + { + try + { + bool guidReceived = false; + ServerManager.GUIDReceived += (str) => + { + guidReceived = true; + Console.WriteLine("{CONNECTION_SUCCESSFUL}"); + }; + + ServerManager.Initiate("secondary4162.cloudapp.net", 13370); + while(guidReceived == false) + { + + } + } + catch (Exception ex) + { + Console.WriteLine("{ERROR}: " + ex.Message); + Thread.Sleep(3000); + ServerManager.StartLANServer(); + } + } + else + { + ServerManager.StartLANServer(); + } + + ServerManager.MessageReceived += (msg) => + { + if(msg.Name == "mud_savefile") + { + CurrentSave = JsonConvert.DeserializeObject(msg.Contents); + } + else if(msg.Name == "mud_login_denied") + { + oobe.PromptForLogin(); + } + }; + + ReadSave(); + + while(CurrentSave == null) + { + + } + + Shiftorium.Init(); + + while (CurrentSave.StoryPosition < 5) + { + + } + + Thread.Sleep(75); + + + + if (Shiftorium.UpgradeInstalled("desktop")) + { + Console.Write("{START_DESKTOP}"); + + Thread.Sleep(50); + Console.WriteLine(" ...{DONE}."); + } + + Story.Start(); + + + Thread.Sleep(50); + Console.WriteLine("{SYSTEM_INITIATED}"); + + TerminalBackend.InStory = false; + Shiftorium.LogOrphanedUpgrades = true; + Desktop.InvokeOnWorkerThread(new Action(() => Desktop.PopulateAppLauncher())); + GameReady?.Invoke(); + })); + thread.IsBackground = true; + thread.Start(); + } + + public delegate void EmptyEventHandler(); + + public static List Users + { + get; + private set; + } + + public static event EmptyEventHandler GameReady; + + public static void TransferCodepointsToVoid(int amount) + { + CurrentSave.Codepoints -= amount; + if(!Shiftorium.Silent) + Console.WriteLine($"{{SHIFTORIUM_TRANSFERRED_TO}}: {amount} -> sys"); + } + + public static void ReadSave() + { + //Migrate old saves. + if(System.IO.Directory.Exists("C:\\ShiftOS2")) + { + Console.WriteLine("Old save detected. Migrating filesystem to MFS..."); + foreach (string file in System.IO.Directory.EnumerateDirectories("C:\\ShiftOS2") +.Select(d => new DirectoryInfo(d).FullName)) + { + if(!Utils.DirectoryExists(file.Replace("C:\\ShiftOS2\\", "0:/").Replace("\\", "/"))) + Utils.CreateDirectory(file.Replace("C:\\ShiftOS2\\", "0:/").Replace("\\", "/")); + } + foreach (string file in System.IO.Directory.EnumerateFiles("C:\\ShiftOS2")) + { + + string rfile = Path.GetFileName(file); + Utils.WriteAllBytes(file.Replace("C:\\ShiftOS2\\", "0:/").Replace("\\", "/"), System.IO.File.ReadAllBytes(file)); + Console.WriteLine("Exported file " + file); + } + + } + + + if (Utils.FileExists(Paths.SaveFileInner)) + { + oobe.ShowSaveTransfer(JsonConvert.DeserializeObject(Utils.ReadAllText(Paths.SaveFileInner))); + } + else + { + if (Utils.FileExists(Paths.GetPath("user.dat"))) + { + var userdat = JsonConvert.DeserializeObject(Utils.ReadAllText(Paths.GetPath("user.dat"))); + + ServerManager.SendMessage("mud_login", $@"{{ + username: ""{userdat.Username}"", + password: ""{userdat.Password}"" +}}"); + } + else + { + NewSave(); + } + } + + } + + public static void NewSave() + { + AppearanceManager.Invoke(new Action(() => + { + CurrentSave = new Save(); + CurrentSave.Codepoints = 0; + CurrentSave.Upgrades = new Dictionary(); + Shiftorium.Init(); + oobe.Start(CurrentSave); + })); + } + + public static void SaveGame() + { + if(!Shiftorium.Silent) + Console.WriteLine(""); + if(!Shiftorium.Silent) + Console.Write("{SE_SAVING}... "); + + string username = CurrentSave.Username; + string password = CurrentSave.Password; + + if (!Utils.FileExists(Paths.GetPath("user.dat"))) + { + Utils.WriteAllText(Paths.GetPath("user.dat"), $@"{{ + username: ""{username}"", + password: ""{password}"" +}}"); + } + + ServerManager.SendMessage("mud_save", JsonConvert.SerializeObject(CurrentSave, Formatting.Indented)); + if(!Shiftorium.Silent) + Console.WriteLine(" ...{DONE}."); + System.IO.File.WriteAllText(Paths.SaveFile, Utils.ExportMount(0)); + } + + public static void TransferCodepointsFrom(string who, int amount) + { + Console.WriteLine($"{{SHIFTORIUM_TRANSFERRED_FROM}}: {amount} <- {who}"); + CurrentSave.Codepoints += amount; + Console.Write($"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}:~$ "); + } + } + + public delegate void TextSentEventHandler(string text); +} diff --git a/ShiftOS_TheReturn/Scripting.cs b/ShiftOS_TheReturn/Scripting.cs new file mode 100644 index 0000000..05675a5 --- /dev/null +++ b/ShiftOS_TheReturn/Scripting.cs @@ -0,0 +1,484 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using IronPython; +using IronPython.Hosting; +using Microsoft.Scripting.Hosting; +using System.Reflection; +using ShiftOS.Objects.ShiftFS; +using DynamicLua; +using System.Dynamic; +using Newtonsoft.Json; +using System.Windows.Forms; +using System.Threading; + +namespace ShiftOS.Engine.Scripting +{ + public class LuaInterpreter + { + dynamic Lua = new DynamicLua.DynamicLua(); + public bool Running = true; + + public LuaInterpreter() + { + SetupAPIs(); + Application.ApplicationExit += (o, a) => + { + Running = false; + }; + } + + public void SetupAPIs() + { + + //This temporary proxy() method will be used by the API prober. + Lua.proxy = new Func((objName) => + { + var asm = Assembly.GetExecutingAssembly(); + foreach (var type in asm.GetTypes()) + { + if (type.Name == objName) + { + dynamic dynObj = Activator.CreateInstance(type); + return dynObj; + } + + } + throw new Exception("{CLASS_NOT_FOUND}"); + }); + + var thisasm = Assembly.GetExecutingAssembly(); + foreach (var type in thisasm.GetTypes()) + { + foreach (var attr in type.GetCustomAttributes(false)) + { + if (attr is ExposedAttribute) + { + var eattr = attr as ExposedAttribute; + Lua($"{eattr.Name} = proxy(\"{type.Name}\")"); + } + } + } + //Now we can null out the proxy() method as it can cause security risks. + Lua.isRunning = new Func(() => { return this.Running; }); + Lua.proxy = null; + Lua.invokeOnWorkerThread = new Action((func) => + { + Desktop.InvokeOnWorkerThread(new Action(() => + { + Lua(func + "()"); + })); + }); + Lua.invokeOnNewThread = new Action((func) => + { + var t = new Thread(new ThreadStart(() => + { + Lua(func + "()"); + })); + t.IsBackground = true; + t.Start(); + }); + } + + + public void ExecuteFile(string file) + { + if (Utils.FileExists(file)) + { + Execute(Utils.ReadAllText(file)); + } + else + { + throw new Exception("The file \"" + file + "\" was not found on the system."); + } + } + + public void Execute(string lua) + { + Console.WriteLine(""); + Lua(lua); + Console.WriteLine($"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}:~$ "); + } + } + + public class LuaVirus : Virus + { + public override string Signature + { + get + { + return signature; + } + } + + public override int ThreatLevel + { + get + { + return _threatlevel; + } + } + + public override string Type + { + get + { + return "lua"; + } + } + + private LuaInterpreter interpreter = null; + private string signature = "unknown"; + + private int _threatlevel = 0; + + public LuaVirus(string script, int threatLevel) : base() + { + _threatlevel = threatLevel; + + interpreter = new LuaInterpreter(); + + Action mud_message = new Action((sig) => + { + signature = sig; + }); + + ServerManager.MessageReceived += (msg) => + { + if(msg.Name == "mud_virus_signature") + { + mud_message?.Invoke(msg.Contents); + mud_message = null; + } + }; + + ServerManager.SendMessage("mud_scanvirus", script); + + _script = script; + } + + + private string _script = ""; + + public override void Activate() + { + interpreter.Execute(_script); + } + + public override void Deactivate() + { + interpreter.Running = false; + interpreter = null; + } + } + + [Exposed("consts")] + public class Constants + { + public readonly DockStyle dock_none = DockStyle.None; + public readonly DockStyle dock_top = DockStyle.Top; + public readonly DockStyle dock_bottom = DockStyle.Bottom; + public readonly DockStyle dock_left = DockStyle.Left; + public readonly DockStyle dock_right = DockStyle.Right; + public readonly DockStyle dock_fill = DockStyle.Fill; + + public readonly AnchorStyles anchor_none = 0x00; + public readonly AnchorStyles anchor_top = AnchorStyles.Top; + public readonly AnchorStyles anchor_bottom = AnchorStyles.Bottom; + public readonly AnchorStyles anchor_left = AnchorStyles.Left; + public readonly AnchorStyles anchor_right = AnchorStyles.Right; + + } + + [Exposed("shiftos")] + public class CoreAPI + { + public void sleep(int ms) { Thread.Sleep(ms); } + + public bool isRunning() { return !SaveSystem.ShuttingDown; } + + public int random(int min, int max) + { + return new Random().Next(min, max); + } + + public void info(string title, string message) + { + Infobox.Show(title, message); + } + + public void executeCommand(string cmd) + { + TerminalBackend.InvokeCommand(cmd); + } + + public void shutdown() + { + TerminalBackend.InvokeCommand("sys.shutdown"); + } + } + [Exposed("shiftorium")] + public class ShiftoriumAPI + { + public dynamic[] getAvailable() + { + return Shiftorium.GetAvailable(); + } + + public dynamic[] getAll() + { + return Shiftorium.GetDefaults().ToArray(); + } + + public bool upgradeInstalled(string id) + { + return Shiftorium.UpgradeInstalled(id); + } + + public bool buy(ShiftoriumUpgrade upgrade) + { + foreach (var upg in getAvailable()) + { + if (upg.ID == upgrade && SaveSystem.CurrentSave.Codepoints >= upg.Cost) + { + return true; + } + } + return false; + } + } + + [Exposed("gui")] + public class GuiAPI + { + public void addControl(dynamic parent, dynamic child) + { + parent.Controls.Add(child); + } + + public dynamic size(int width, int height) + { + return new System.Drawing.Size(width, height); + } + + public dynamic point(int x, int y) + { + return new System.Drawing.Point(x, y); + } + + public dynamic rect(dynamic p, dynamic s) + { + return new System.Drawing.Rectangle(p, s); + } + + public dynamic rect(int x, int y, int w, int h) + { + return new System.Drawing.Rectangle(x, y, w, h); + } + + public dynamic panel() + { + return new Panel(); + } + + public dynamic label() + { + return new Label(); + } + + public dynamic button() + { + return new Button(); + } + + public dynamic listbox() + { + return new ListBox(); + } + + public dynamic combobox() + { + return new ComboBox(); + } + + public dynamic textbox() + { + return new TextBox(); + } + + public dynamic window() + { + return new Form(); + } + + } + + [Exposed("color")] + public class ColorAPI + { + public dynamic fromRgb(int r, int g, int b) + { + return System.Drawing.Color.FromArgb(r, g, b); + } + + public dynamic fromArgb(int a, int r, int g, int b) + { + return System.Drawing.Color.FromArgb(a, r, g, b); + } + + public dynamic fromName(string name) + { + return System.Drawing.Color.FromName(name); + } + } + + [Exposed("fonts")] + public class FontsAPI + { + public readonly int style_regular = 0x00; + public readonly int style_bold = 0x01; + public readonly int style_italic = 0x02; + public readonly int style_underline = 0x04; + public readonly int style_strike = 0x08; + + public dynamic create(string name, float size, int style) + { + return new System.Drawing.Font(name, size, (System.Drawing.FontStyle)style); + } + + } + + [Exposed("json")] + public class JsonAPI + { + public string serialize(dynamic dynObj) + { + return JsonConvert.SerializeObject(dynObj); + } + + public dynamic deserialize(string json) + { + return JsonConvert.DeserializeObject(json); + } + } + + [Exposed("fs")] + public class FilesystemAPI + { + public void writeAllText(string target, string contents) + { + Utils.WriteAllText(target, contents); + } + + public string readAllText(string file) + { + return Utils.ReadAllText(file); + } + + public bool fileExists(string file) + { + return Utils.FileExists(file); + } + + public bool directoryExists(string dir) + { + return Utils.DirectoryExists(dir); + } + + public void createDirectory(string dir) + { + Utils.CreateDirectory(dir); + } + + //experimental - no idea how arrays will be handled in Lua... + public string[] getFiles(string dir) + { + return Utils.GetFiles(dir); + } + + public string[] getDirectories(string dir) + { + return Utils.GetDirectories(dir); + } + + public string mount(string mfsFile) + { + Utils.MountPersistent(mfsFile); + return $"{Utils.Mounts.Count - 1}:"; + } + + public void unmount(int driveNum) + { + Utils.Mounts.RemoveAt(driveNum); + } + + } + + + public class PythonInterpreter + { + ScriptEngine python; + ScriptScope pyScope; + ScriptSource pySource; + + public PythonInterpreter() + { + python = Python.CreateEngine(); + pyScope = python.CreateScope(); + AddExposedObjects(); + } + + private void AddExposedObjects() + { + var asm = Assembly.GetExecutingAssembly(); + foreach(var type in asm.GetTypes()) + { + foreach(var attr in type.GetCustomAttributes(false)) + { + if(attr is ExposedAttribute) + { + var eattr = attr as ExposedAttribute; + dynamic dynObj = Activator.CreateInstance(type); + pyScope.SetVariable(eattr.Name, dynObj); + } + } + } + } + + public void ExecuteFile(string file) + { + if(Utils.FileExists(file)) + { + Execute(Utils.ReadAllText(file)); + } + else + { + throw new Exception("The file \"" + file + "\" was not found on the system."); + } + } + + public void Execute(string py) + { + Console.WriteLine(""); + pySource = python.CreateScriptSourceFromString(py, Microsoft.Scripting.SourceCodeKind.AutoDetect); + pySource.Execute(pyScope); + Console.Write($"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}:~$ "); + } + } + + public class ExposedAttribute : Attribute + { + /// + /// Marks the following class as exposed to the ShiftOS Scripting System. + /// + /// The object name that the Scripting System should use as the variable name for scripts. + public ExposedAttribute(string objName) + { + Name = objName; + } + + public string Name { get; set; } + } +} diff --git a/ShiftOS_TheReturn/ServerManager.cs b/ShiftOS_TheReturn/ServerManager.cs new file mode 100644 index 0000000..3d654e8 --- /dev/null +++ b/ShiftOS_TheReturn/ServerManager.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ShiftOS.Objects; +using NetSockets; +using System.Windows.Forms; +using System.Threading; +using ShiftOS; +using static ShiftOS.Engine.SaveSystem; +using Newtonsoft.Json; + +namespace ShiftOS.Engine +{ + public static class ServerManager + { + public static void PrintDiagnostics() + { + Console.WriteLine($@"{{CLIENT_DIAGNOSTICS}} + +{{GUID}}: {thisGuid} +{{CLIENT_DATA}}: + +{JsonConvert.SerializeObject(client, Formatting.Indented)}"); + } + + private static Guid thisGuid { get; set; } + private static NetObjectClient client { get; set; } + + public static void Disconnect() + { + if (client != null) + { + client.Disconnect(); + } + Disconnected?.Invoke(); + + } + + public static event EmptyEventHandler Disconnected; + + public static void InitiateMUDHack() + { + MessageReceived += ServerManager_MessageReceived; + SendMessage("mudhack_init", ""); + } + + public static event Action ServerPasswordGenerated; + public static event EmptyEventHandler ServerAccessGranted; + public static event EmptyEventHandler ServerAccessDenied; + public static event Action GUIDReceived; + public static event Action> UsersReceived; + + private static void ServerManager_MessageReceived(ServerMessage msg) + { + switch(msg.Name) + { + case "mudhack_users": + UsersReceived?.Invoke(JsonConvert.DeserializeObject>(msg.Contents)); + break; + case "mudhack_init": + ServerPasswordGenerated?.Invoke(msg.Contents); + break; + case "mudhack_denied": + ServerAccessDenied?.Invoke(); + break; + case "mudhack_granted": + ServerAccessGranted?.Invoke(); + break; + case "getguid_fromserver": + if(SaveSystem.CurrentSave.Username == msg.Contents) + { + client.Send(new NetObject("yes_i_am", new ServerMessage + { + Name = "getguid_reply", + GUID = msg.GUID, + Contents = thisGuid.ToString(), + })); + } + break; + case "getguid_reply": + GUIDReceived?.Invoke(msg.Contents); + break; + } + } + + public static void Detach_ServerManager_MessageReceived() + { + MessageReceived -= new ServerMessageReceived(ServerManager_MessageReceived); + } + + public static void Initiate(string mud_address, int port) + { + client = new NetObjectClient(); + + client.OnReceived += (o, a) => + { + var msg = a.Data.Object as ServerMessage; + if (msg.Name == "Welcome") + { + thisGuid = new Guid(msg.Contents); + GUIDReceived?.Invoke(msg.Contents); + } + else if(msg.Name =="broadcast") + { + Console.WriteLine(msg.Contents); + } + else if (msg.Name == "Error") + { + var ex = JsonConvert.DeserializeObject(msg.Contents); + TerminalBackend.PrefixEnabled = true; + Console.WriteLine($@"{{MUD_ERROR}}: {ex.Message}"); + TerminalBackend.PrefixEnabled = true; + Console.Write($"{SaveSystem.CurrentSave.Username}@{CurrentSave.SystemName}:~$ "); + } + else + { + MessageReceived?.Invoke(msg); + } + }; + + client.Connect(mud_address, port); + + } + + public static void SendMessage(string name, string contents) + { + var sMsg = new ServerMessage + { + Name = name, + Contents = contents, + GUID = thisGuid.ToString(), + }; + + client.Send(new NetObject("msg", sMsg)); + + } + + private static bool singleplayer = false; + public static bool IsSingleplayer { get { return singleplayer; } } + + public static void StartLANServer() + { + singleplayer = true; + ShiftOS.Server.Program.ServerStarted += (address) => + { + Console.WriteLine($"Connecting to {address}..."); + Initiate(address, 13370); + }; + Disconnected += () => + { + ShiftOS.Server.Program.Stop(); + }; + ShiftOS.Server.Program.Main(new[] { "" }); + + + } + + + public static event ServerMessageReceived MessageReceived; + + } + + public delegate void ServerMessageReceived(ServerMessage msg); + + public class MultiplayerOnlyAttribute : Attribute + { + /// + /// Marks this application as a multiplayer-only application. + /// + public MultiplayerOnlyAttribute() + { + + } + } +} diff --git a/ShiftOS_TheReturn/ShiftOS.Engine.csproj b/ShiftOS_TheReturn/ShiftOS.Engine.csproj new file mode 100644 index 0000000..a88b3d9 --- /dev/null +++ b/ShiftOS_TheReturn/ShiftOS.Engine.csproj @@ -0,0 +1,261 @@ + + + + + Debug + AnyCPU + {7C979B07-0585-4033-A110-E5555B9D6651} + Library + Properties + ShiftOS.Engine + ShiftOS.Engine + v4.5.2 + 512 + true + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + false + + + + + + + ..\Libraries\Discoursistency.Base.dll + + + ..\Libraries\Discoursistency.HTTP.dll + + + ..\Libraries\Discoursistency.Util.dll + + + ..\packages\DynamicLua.1.1.2.0\lib\net40-Client\DynamicLua.dll + True + + + ..\packages\IronPython.2.7.5\lib\Net45\IronPython.dll + True + + + ..\packages\IronPython.2.7.5\lib\Net45\IronPython.Modules.dll + True + + + ..\packages\IronPython.2.7.5\lib\Net45\IronPython.SQLite.dll + True + + + ..\packages\IronPython.2.7.5\lib\Net45\IronPython.Wpf.dll + True + + + ..\packages\IronPython.2.7.5\lib\Net45\Microsoft.Dynamic.dll + True + + + ..\packages\IronPython.2.7.5\lib\Net45\Microsoft.Scripting.dll + True + + + ..\packages\IronPython.2.7.5\lib\Net45\Microsoft.Scripting.AspNet.dll + True + + + ..\packages\IronPython.2.7.5\lib\Net45\Microsoft.Scripting.Metadata.dll + True + + + ..\Libraries\NetSockets.dll + + + ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + True + + + + + + + + + + + + + + + + + + + + + + Form + + + AltTabWindow.cs + + + + + + + + + CrashHandler.cs + + + + + + + + + + + + + True + True + Resources.resx + + + + + + + + + + + + + AltTabWindow.cs + + + Infobox.cs + + + ResXFileCodeGenerator + Designer + Resources.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + {a069089a-8962-4607-b2b2-4cf4a371066e} + ShiftOS.Objects + + + {226c63b4-e60d-4949-b4e7-7a2ddbb96776} + ShiftOS.Server + + + + + {22D6F304-B0F6-11D0-94AB-0080C74C7E95} + 1 + 0 + 0 + tlbimp + False + True + + + {00020430-0000-0000-C000-000000000046} + 2 + 0 + 0 + primary + False + True + + + {6BF52A50-394A-11D3-B153-00C04F79FAA6} + 1 + 0 + 0 + tlbimp + False + True + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ShiftOS_TheReturn/Shiftorium.cs b/ShiftOS_TheReturn/Shiftorium.cs new file mode 100644 index 0000000..44357f5 --- /dev/null +++ b/ShiftOS_TheReturn/Shiftorium.cs @@ -0,0 +1,226 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using static ShiftOS.Engine.SaveSystem; + +namespace ShiftOS.Engine +{ + public static class Shiftorium + { + /// + /// Whether or not shiftorium output should be written to the console. + /// + public static bool Silent = false; + + public static void InvokeUpgradeInstalled() + { + Installed?.Invoke(); + } + + + public static bool Buy(string id, int cost) + { + if(SaveSystem.CurrentSave.Codepoints >= cost) + { + SaveSystem.CurrentSave.Upgrades[id] = true; + TerminalBackend.InvokeCommand("sos.save"); + SaveSystem.TransferCodepointsToVoid(cost); + Installed?.Invoke(); + Desktop.ResetPanelButtons(); + Desktop.PopulateAppLauncher(); + return true; + } + else + { + if(!Silent) + Console.WriteLine($"{{SHIFTORIUM_NOTENOUGHCP}}: {cost} > {SaveSystem.CurrentSave.Codepoints}"); + return false; + } + } + + public static bool UpgradeAttributesUnlocked(Type type) + { + foreach(var attr in type.GetCustomAttributes(true)) + { + if(attr is RequiresUpgradeAttribute) + { + var rAttr = attr as RequiresUpgradeAttribute; + return rAttr.Installed; + } + } + + return true; + } + + public static bool UpgradeAttributesUnlocked(MethodInfo type) + { + foreach (var attr in type.GetCustomAttributes(true)) + { + if (attr is RequiresUpgradeAttribute) + { + var rAttr = attr as RequiresUpgradeAttribute; + return rAttr.Installed; + } + } + + return true; + } + + public static bool UpgradeAttributesUnlocked(PropertyInfo type) + { + foreach (var attr in type.GetCustomAttributes(true)) + { + if (attr is RequiresUpgradeAttribute) + { + var rAttr = attr as RequiresUpgradeAttribute; + return rAttr.Installed; + } + } + + return true; + } + + public static bool UpgradeAttributesUnlocked(FieldInfo type) + { + foreach (var attr in type.GetCustomAttributes(true)) + { + if (attr is RequiresUpgradeAttribute) + { + var rAttr = attr as RequiresUpgradeAttribute; + return rAttr.Installed; + } + } + + return true; + } + + + public static void Init() + { + try + { + var dict = GetDefaults(); + foreach (var itm in dict) + { + if (!SaveSystem.CurrentSave.Upgrades.ContainsKey(itm.ID)) + { + SaveSystem.CurrentSave.Upgrades.Add(itm.ID, false); + } + } + } + catch + { + } + } + + public static int GetCPValue(string id) + { + foreach(var upg in GetDefaults()) + { + if (upg.ID == id) + return upg.Cost; + } + return 0; + } + + public static ShiftoriumUpgrade[] GetAvailable() + { + List available = new List(); + foreach(var defaultupg in GetDefaults()) + { + if (!UpgradeInstalled(defaultupg.ID) && DependenciesInstalled(defaultupg)) + available.Add(defaultupg); + } + return available.ToArray(); + } + + public static bool DependenciesInstalled(ShiftoriumUpgrade upg) + { + if (string.IsNullOrEmpty(upg.Dependencies)) + { + return true;//root upgrade, no parents + } + else if (upg.Dependencies.Contains(";")) + { + string[] dependencies = upg.Dependencies.Split(';'); + foreach(var dependency in dependencies) + { + if (!UpgradeInstalled(dependency)) + return false; + } + return true; + } + else + { + return UpgradeInstalled(upg.Dependencies); + } + } + + public static event EmptyEventHandler Installed; + + public static bool UpgradeInstalled(string id) + { + if (SaveSystem.CurrentSave != null) + { + if (SaveSystem.CurrentSave.Upgrades == null) + Init(); + } + try + { + return SaveSystem.CurrentSave.Upgrades[id]; + } + catch (Exception ex) + { + if(LogOrphanedUpgrades == true) + Console.WriteLine($"WHOA, Developers! Upgrade ID '{id}' is unaccounted for in the Shiftorium.txt resource!"); + return false; + } + } + + //LEAVE THIS AS FALSE. The game will set it when the save is loaded. + public static bool LogOrphanedUpgrades = false; + + private static IShiftoriumProvider _provider = null; + + public static void RegisterProvider(IShiftoriumProvider p) + { + _provider = p; + } + + //Bless the newer NEWER engine. + public static List GetDefaults() + { + try + { + return _provider.GetDefaults(); + } + catch (Exception ex) + { + Console.WriteLine("Couldn't get the upgrade definition list from the provider."); + Console.WriteLine("This might be able to help:"); + Console.WriteLine(ex); + return JsonConvert.DeserializeObject>(Properties.Resources.Shiftorium); + } + } + } + + public interface IShiftoriumProvider + { + List GetDefaults(); + } + + public class ShiftoriumUpgrade + { + public string Name { get; set; } + public string Description { get; set; } + public int Cost { get; set; } + public string ID { get { return (this.Id != null ? this.Id : (Name.ToLower().Replace(" ", "_"))); } } + public string Id { get; } + + public string Dependencies { get; set; } + } +} diff --git a/ShiftOS_TheReturn/Skinning.cs b/ShiftOS_TheReturn/Skinning.cs new file mode 100644 index 0000000..170bb37 --- /dev/null +++ b/ShiftOS_TheReturn/Skinning.cs @@ -0,0 +1,967 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; +using System.Windows.Forms; +using static ShiftOS.Engine.SaveSystem; +using ShiftOS.Objects.ShiftFS; + +namespace ShiftOS.Engine { + public static class SkinEngine { + public static ImageLayout GetImageLayout(string img) { + if (LoadedSkin.SkinImageLayouts.ContainsKey(img)) { + return LoadedSkin.SkinImageLayouts[img]; + } else { + LoadedSkin.SkinImageLayouts.Add(img, ImageLayout.Tile); + return ImageLayout.Tile; + } + } + + public static System.Drawing.Image GetImage(string img) { + var type = typeof(Skin); + + foreach (var field in type.GetFields()) { + foreach (var attr in field.GetCustomAttributes(false)) { + if (attr is ImageAttribute) { + var iattr = attr as ImageAttribute; + if (iattr.Name == img) { + byte[] image = (byte[])field.GetValue(LoadedSkin); + return ImageFromBinary(image); + } + } + } + } + + return null; + } + + public static Image ImageFromBinary(byte[] image) { + if (image == null) + return null; + Image img = (Bitmap)((new ImageConverter()).ConvertFrom(image)); + return img; + } + + private static Skin loadedSkin = new Skin(); + + public static Skin LoadedSkin + { + get + { + return loadedSkin; + } + private set + { + loadedSkin = value; + } + } + + public static void Init() { + Application.ApplicationExit += (o, a) => { + SaveSkin(); + }; + + if (!Utils.FileExists(Paths.GetPath("skin.json"))) { + LoadedSkin = new ShiftOS.Engine.Skin(); + SaveSkin(); + } else { + LoadSkin(); + } + if (SaveSystem.CurrentSave != null) { + SkinLoaded?.Invoke(); + } + } + + public static event EmptyEventHandler SkinLoaded; + + public static void LoadSkin() { + LoadedSkin = JsonConvert.DeserializeObject(Utils.ReadAllText(Paths.GetPath("skin.json"))); + SkinLoaded?.Invoke(); + Desktop.ResetPanelButtons(); + Desktop.PopulateAppLauncher(); + } + + public static void SaveSkin() { + Utils.WriteAllText(Paths.GetPath("skin.json"), JsonConvert.SerializeObject(LoadedSkin, Formatting.Indented)); + } + } + + public class Skin { + //borrowing from the discourse theme for the default skin + private static readonly Color DefaultBackground = Color.FromArgb(0, 0x44, 0x00); + private static readonly Color DefaultForeground = Color.FromArgb(0xDD, 0xDD, 0xDD); + private static readonly Color Accent1 = Color.FromArgb(0x66, 0x66, 0x66); + private static readonly Color Accent2 = Color.FromArgb(0x80, 0, 0); + private static readonly Color DesktopBG = Color.FromArgb(0x22, 0x22, 0x22); + private static readonly Font SysFont = new Font("Tahoma", 9F); + private static readonly Font SysFont2 = new Font("Tahoma", 10F, FontStyle.Bold); + private static readonly Font Header1 = new Font("Helvetica", 20F, FontStyle.Bold); + private static readonly Font Header2 = new Font("Helvetica", 17.5F, FontStyle.Bold); + private static readonly Font Header3 = new Font("Tahoma", 15F, FontStyle.Bold); + + private static readonly Color TitleBG = Color.FromArgb(0x11, 0x11, 0x11); + private static readonly Color TitleFG = Color.FromArgb(0xaa, 0xaa, 0xaa); + + //Todo: When making Shifter GUI we need to label all these with proper Shifter attributes to get 'em displaying in the right places. + + [ShifterMeta("Windows")] + [ShifterCategory("Titlebar")] + [RequiresUpgrade("shift_title_text")] + [ShifterName("Title Font")] + [ShifterDescription("The font style for the title text.")] + public Font TitleFont = SysFont2; + + [ShifterMeta("System")] + [ShifterCategory("General")] + [ShifterName("System Font")] + [ShifterDescription("The font style used by the system.")] + public Font MainFont = SysFont; + + [ShifterEnumMask(new[] { "Right", "Left"})] + [ShifterMeta("Windows")] + [ShifterCategory("Title Buttons")] + [ShifterName("Title button position")] + [ShifterDescription("Where should the title buttons be located?")] + public int TitleButtonPosition = 0; + + [ShifterMeta("System")] + [ShifterCategory("Header Fonts")] + [ShifterName("1st level header")] + [ShifterDescription("The font used in level 1 (title) headers.")] + public Font HeaderFont = Header1; + + + [ShifterMeta("System")] + [ShifterCategory("Header Fonts")] + [ShifterName("2nd level header")] + [ShifterDescription("The font used in level 2 (subtitle) headers.")] + public Font Header2Font = Header2; + + + [ShifterMeta("System")] + [ShifterCategory("Header Fonts")] + [ShifterName("3rd level header")] + [ShifterDescription("The font used in level 3 (section) headers.")] + public Font Header3Font = Header3; + + + + [ShifterMeta("System")] + [ShifterCategory("General")] + [ShifterName("System Background")] + [ShifterDescription("The background color of all system controls in the UI.")] + public Color ControlColor = DefaultBackground; + + [ShifterMeta("System")] + [ShifterCategory("General")] + [ShifterName("System Foreground")] + [ShifterDescription("The foreground color of all system controls in the UI.")] + public Color ControlTextColor = DefaultForeground; + + [ShifterMeta("Windows")] + [ShifterCategory("Titlebar")] + [ShifterName("Title Text Color")] + [RequiresUpgrade("shift_title_text")] + [ShifterDescription("The color of the title text.")] + public Color TitleTextColor = TitleFG; + + [ShifterMeta("Windows")] + [ShifterCategory("Titlebar")] + [ShifterName("Title Background Color")] + [RequiresUpgrade("shift_titlebar")] + [ShifterDescription("The color of the titlebar's background.")] + public Color TitleBackgroundColor = TitleBG; + + [ShifterMeta("Windows")] + [ShifterCategory("Window border")] + [ShifterName("Left Border Background")] + [RequiresUpgrade("shift_window_borders")] + [ShifterDescription("The background color for the left border.")] + public Color BorderLeftBackground = TitleBG; + + [ShifterMeta("Windows")] + [ShifterCategory("Window border")] + [ShifterName("Right Border Background")] + [RequiresUpgrade("shift_window_borders")] + [ShifterDescription("The background color for the right border.")] + public Color BorderRightBackground = TitleBG; + + [ShifterMeta("Desktop")] + [ShifterCategory("Panel buttons")] + [RequiresUpgrade("shift_panel_buttons")] + [ShifterName("Panel buttons from top")] + [ShifterDescription("How far from the top should the panel buttons be?")] + public int PanelButtonFromTop = 2; + + [ShifterMeta("Windows")] + [ShifterCategory("Window border")] + [ShifterName("Bottom Border Background")] + [RequiresUpgrade("shift_window_borders")] + [ShifterDescription("The background color for the bottom border.")] + public Color BorderBottomBackground = TitleBG; + + [ShifterMeta("Desktop")] + [ShifterCategory("Panel buttons")] + [ShifterName("Panel button holder from left")] + [ShifterDescription("How far from the left should the panel button holder be?")] + [RequiresUpgrade("shift_panel_buttons")] + public int PanelButtonHolderFromLeft = 68; + + [ShifterMeta("Windows")] + [ShifterCategory("Window border")] + [ShifterName("Bottom Left Border Background")] + [RequiresUpgrade("shift_window_borders")] + [ShifterDescription("The background color for the bottom left border.")] + public Color BorderBottomLeftBackground = TitleBG; + + [ShifterMeta("Windows")] + [ShifterCategory("Window border")] + [ShifterName("Bottom Right Border Background")] + [RequiresUpgrade("shift_window_borders")] + [ShifterDescription("The background color for the bottom right border.")] + public Color BorderBottomRightBackground = TitleBG; + + [ShifterMeta("Windows")] + [ShifterCategory("Title Buttons")] + [ShifterName("Close Button Color")] + [RequiresUpgrade("shift_title_buttons")] + [ShifterDescription("The close button color")] + public Color CloseButtonColor = Accent2; + + [ShifterMeta("Windows")] + [ShifterCategory("Title Buttons")] + [ShifterName("Maximize Button Color")] + [RequiresUpgrade("shift_title_buttons")] + [ShifterDescription("The maximize button color")] + public Color MaximizeButtonColor = Accent1; + + [ShifterMeta("Windows")] + [ShifterCategory("Title Buttons")] + [ShifterName("Minimize Button Color")] + [RequiresUpgrade("shift_title_buttons")] + [ShifterDescription("The minimize button color")] + public Color MinimizeButtonColor = Accent1; + + [ShifterMeta("Desktop")] + [ShifterCategory("Desktop Panel")] + [ShifterName("Panel Background")] + [RequiresUpgrade("shift_desktop_panel")] + [ShifterDescription("The background color used by the desktop panel")] + public Color DesktopPanelColor = TitleBG; + + [ShifterMeta("Desktop")] + [ShifterCategory("Desktop Panel")] + [ShifterName("Panel Clock Text Color")] + [RequiresUpgrade("shift_panel_clock")] + [ShifterDescription("The text color used by the desktop panel's clock.")] + public Color DesktopPanelClockColor = TitleFG; + + [ShifterMeta("Desktop")] + [ShifterCategory("Desktop Panel")] + [ShifterName("Panel Clock Background Color")] + [RequiresUpgrade("shift_panel_clock")] + [ShifterDescription("The background color used by the desktop panel's clock.")] + public Color DesktopPanelClockBackgroundColor = TitleBG; + + [ShifterMeta("Desktop")] + [ShifterCategory("Desktop Panel")] + [ShifterName("Panel Clock Font")] + [RequiresUpgrade("shift_panel_clock")] + [ShifterDescription("The font used by the desktop panel's clock.")] + public Font DesktopPanelClockFont = Skin.SysFont2; + + [ShifterMeta("Desktop")] + [ShifterCategory("Desktop Panel")] + [ShifterName("Panel Clock From Right")] + [RequiresUpgrade("shift_panel_clock")] + [ShifterDescription("The position in pixels relative to the width of the desktop panel that the clock will sit at.")] + public Point DesktopPanelClockFromRight = new Point(2, 2); + + + [ShifterMeta("Desktop")] + [ShifterCategory("Desktop Panel")] + [ShifterName("Panel Height")] + [RequiresUpgrade("shift_desktop_panel")] + [ShifterDescription("The height in pixels of the desktop panel.")] + public int DesktopPanelHeight = 24; + + [ShifterMeta("Desktop")] + [ShifterCategory("Desktop Panel")] + [ShifterName("Panel Position")] + [ShifterEnumMask(new[] { "Top", "Bottom" })] + [RequiresUpgrade("shift_desktop_panel")] + [ShifterDescription("The position of the desktop panel.")] + public int DesktopPanelPosition = 0; + + [ShifterMeta("Windows")] + [ShifterCategory("Titlebar")] + [ShifterName("Titlebar Height")] + [RequiresUpgrade("shift_titlebar")] + [ShifterDescription("The height of the titlebar.")] + public int TitlebarHeight = 30; + + [ShifterMeta("Windows")] + [ShifterCategory("Title Buttons")] + [ShifterName("Close Button Size")] + [RequiresUpgrade("shift_title_buttons")] + [ShifterDescription("The close button size")] + public Size CloseButtonSize = new Size(24, 24); + + [ShifterMeta("Windows")] + [ShifterCategory("Title Buttons")] + [ShifterName("Maximize Button Size")] + [RequiresUpgrade("shift_title_buttons")] + [ShifterDescription("The maximize button size")] + public Size MaximizeButtonSize = new Size(24, 24); + + [ShifterMeta("Windows")] + [ShifterCategory("Title Buttons")] + [ShifterName("Minimize Button Size")] + [RequiresUpgrade("shift_title_buttons")] + [ShifterDescription("The minimize button size")] + public Size MinimizeButtonSize = new Size(24, 24); + + [ShifterMeta("Windows")] + [ShifterCategory("Title Buttons")] + [ShifterName("Close Button From Right")] + [RequiresUpgrade("shift_title_buttons")] + [ShifterDescription("The close button location from the right of the titlebar.")] + public Point CloseButtonFromSide = new Point(3, (30 - 24) / 2); + + [ShifterMeta("Windows")] + [ShifterCategory("Title Buttons")] + [ShifterName("Maximize Button From Right")] + [RequiresUpgrade("shift_title_buttons")] + [ShifterDescription("The maximize button location from the right of the titlebar.")] + public Point MaximizeButtonFromSide = new Point(24 + 6, (30 - 24) / 2); + + [ShifterMeta("Windows")] + [ShifterCategory("Title Buttons")] + [ShifterName("Minimize Button From Right")] + [RequiresUpgrade("shift_title_buttons")] + [ShifterDescription("The minimize button location from the right of the titlebar.")] + public Point MinimizeButtonFromSide = new Point(48 + 9, (30 - 24) / 2); + + [ShifterMeta("Windows")] + [ShifterCategory("Titlebar")] + [ShifterName("Title text centered?")] + [RequiresUpgrade("shift_title_text")] + [ShifterDescription("Is the title text centered?")] + public bool TitleTextCentered = false; + + [ShifterMeta("Windows")] + [ShifterCategory("Titlebar")] + [ShifterName("Title Text From Left")] + [ShifterFlag("TitleTextCentered", false)] + [RequiresUpgrade("shift_title_text")] + [ShifterDescription("The title text location from the left of the titlebar.")] + public Point TitleTextLeft = new Point(4, 4); + + [ShifterMeta("Desktop")] + [ShifterCategory("General")] + [ShifterName("Desktop Background Color")] + [ShifterDescription("The background color of the desktop.")] + public Color DesktopColor = DesktopBG; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Button select highlight")] + public Color Menu_ButtonSelectedHighlight = Accent2; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Button select border")] + public Color Menu_ButtonSelectedHighlightBorder = Accent2; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Button pressed highlight")] + public Color Menu_ButtonPressedHighlight = Accent1; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Button pressed border")] + public Color Menu_ButtonPressedHighlightBorder = Accent1; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Button checked highlight")] + public Color Menu_ButtonCheckedHighlight = Accent1; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Button checked border")] + public Color Menu_ButtonCheckedHighlightBorder = Accent1; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Button pressed gradient border")] + public Color Menu_ButtonPressedBorder = Accent1; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Button selected gradient border")] + public Color Menu_ButtonSelectedBorder = Accent2; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Button checked gradient start")] + public Color Menu_ButtonCheckedGradientBegin = Accent1; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Button checked gradient middle")] + public Color Menu_ButtonCheckedGradientMiddle = Accent1; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Button checked gradient end")] + public Color Menu_ButtonCheckedGradientEnd = Accent1; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Button selected gradient start")] + public Color Menu_ButtonSelectedGradientBegin = Accent2; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Button selected gradient middle")] + public Color Menu_ButtonSelectedGradientMiddle = Accent2; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Button selected gradient end")] + public Color Menu_ButtonSelectedGradientEnd = Accent2; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Button pressed gradient start")] + public Color Menu_ButtonPressedGradientBegin = Accent1; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Button pressed gradient middle")] + public Color Menu_ButtonPressedGradientMiddle = Accent1; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Button pressed gradient end")] + public Color Menu_ButtonPressedGradientEnd = Accent1; + + [ShifterMeta("Menus")] + [ShifterCategory("General")] + [ShifterName("Check BG")] + public Color Menu_CheckBackground = Skin.TitleBG; + + [ShifterMeta("Menus")] + [ShifterCategory("General")] + [ShifterName("Check BG (Selected)")] + public Color Menu_CheckSelectedBackground = Accent2; + + [ShifterMeta("Menus")] + [ShifterCategory("General")] + [ShifterName("Check BG (Pressed)")] + public Color Menu_CheckPressedBackground = Accent1; + + [ShifterMeta("Menus")] + [ShifterCategory("Menu bars")] + [ShifterName("Margin gradient start")] + public Color Menu_ImageMarginGradientBegin = TitleBG; + + [ShifterMeta("Menus")] + [ShifterCategory("Menu bars")] + [ShifterName("Margin gradient middle")] + public Color Menu_ImageMarginGradientMiddle = TitleBG; + + [ShifterMeta("Menus")] + [ShifterCategory("Menu bars")] + [ShifterName("Margin gradient end")] + public Color Menu_ImageMarginGradientEnd = TitleBG; + + [ShifterMeta("Menus")] + [ShifterCategory("Menu bars")] + [ShifterName("Menu gradient start")] + public Color Menu_MenuStripGradientBegin = TitleBG; + + [ShifterMeta("Menus")] + [ShifterCategory("Menu bars")] + [ShifterName("Menu gradient end")] + public Color Menu_MenuStripGradientEnd = TitleBG; + + [ShifterMeta("Menus")] + [ShifterCategory("Menu bars")] + [ShifterName("Menu item selected")] + public Color Menu_MenuItemSelected = Accent2; + + [ShifterMeta("Menus")] + [ShifterCategory("Menu bars")] + [ShifterName("Menu item border")] + public Color Menu_MenuItemBorder = DefaultBackground; + + [ShifterMeta("Menus")] + [ShifterCategory("Menu bars")] + [ShifterName("Menu border")] + public Color Menu_MenuBorder = DefaultBackground; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Menu item selected gradient start")] + public Color Menu_MenuItemSelectedGradientBegin = Accent2; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Menu item selected gradient end")] + public Color Menu_MenuItemSelectedGradientEnd = Accent2; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Menu item pressed gradient start")] + public Color Menu_MenuItemPressedGradientBegin = Accent1; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Menu item pressed gradient middle")] + public Color Menu_MenuItemPressedGradientMiddle = Accent1; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Menu item pressed gradient end")] + public Color Menu_MenuItemPressedGradientEnd = Accent1; + + [ShifterMeta("Menus")] + [ShifterCategory("General")] + [ShifterName("Rafter gradient start")] + public Color Menu_RaftingContainerGradientBegin = TitleBG; + + [ShifterMeta("Menus")] + [ShifterCategory("General")] + [ShifterName("Rafter gradient end")] + public Color Menu_RaftingContainerGradientEnd = TitleBG; + + [ShifterMeta("Menus")] + [ShifterCategory("General")] + [ShifterName("Separator Color 1")] + public Color Menu_SeparatorDark = DefaultForeground; + + [ShifterMeta("Menus")] + [ShifterCategory("General")] + [ShifterName("Separator Color 2")] + public Color Menu_SeparatorLight = TitleFG; + + [ShifterMeta("Menus")] + [ShifterCategory("Status bars")] + [ShifterName("Status bar gradient start")] + public Color Menu_StatusStripGradientBegin = TitleBG; + + [ShifterMeta("Menus")] + [ShifterCategory("Status bars")] + [ShifterName("Status bar gradient end")] + public Color Menu_StatusStripGradientEnd = TitleBG; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Toolbar Border")] + public Color Menu_ToolStripBorder = TitleBG; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Dropdown background")] + public Color Menu_ToolStripDropDownBackground = DefaultBackground; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Toolbar gradient start")] + public Color Menu_ToolStripGradientBegin = TitleBG; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Toolbar gradient middle")] + public Color Menu_ToolStripGradientMiddle = TitleBG; + + [ShifterMeta("Menus")] + [ShifterCategory("Toolbars")] + [ShifterName("Toolbar gradient end")] + public Color Menu_ToolStripGradientEnd = TitleBG; + + [ShifterMeta("Menus")] + [ShifterCategory("Menu holders")] + [ShifterName("Content panel gradient start")] + public Color Menu_ToolStripContentPanelGradientBegin = TitleBG; + + [ShifterMeta("Menus")] + [ShifterCategory("Menu holders")] + [ShifterName("Content panel gradient end")] + public Color Menu_ToolStripContentPanelGradientEnd = TitleBG; + + [ShifterMeta("Menus")] + [ShifterCategory("Menu holders")] + [ShifterName("Panel gradient start")] + public Color Menu_ToolStripPanelGradientBegin = TitleBG; + + [ShifterMeta("Menus")] + [ShifterCategory("Menu holders")] + [ShifterName("Panel gradient end")] + public Color Menu_ToolStripPanelGradientEnd = TitleBG; + + [ShifterMeta("Menus")] + [ShifterCategory("General")] + [ShifterName("Menu text color")] + public Color Menu_TextColor = DefaultForeground; + + [ShifterMeta("Menus")] + [ShifterCategory("General")] + [ShifterName("Menu selected text color")] + public Color Menu_SelectedTextColor = TitleFG; + + + + //Images + [Image("closebutton")] + [ShifterMeta("Windows")] + [ShifterCategory("Title Buttons")] + [ShifterName("Close Button Image")] + [RequiresUpgrade("shift_title_buttons;skinning")] + [ShifterDescription("Show an image on the Close Button using this setting.")] + public byte[] CloseButtonImage = null; + + [Image("minimizebutton")] + [ShifterMeta("Windows")] + [ShifterCategory("Title Buttons")] + [ShifterName("Minimize Button Image")] + [RequiresUpgrade("shift_title_buttons;skinning")] + [ShifterDescription("Show an image on the Minimize Button using this setting.")] + public byte[] MinimizeButtonImage = null; + + [Image("maximizebutton")] + [ShifterMeta("Windows")] + [ShifterCategory("Title Buttons")] + [ShifterName("Maximize Button Image")] + [RequiresUpgrade("shift_title_buttons;skinning")] + [ShifterDescription("Show an image on the Maximize Button using this setting.")] + public byte[] MaximizeButtonImage = null; + + [Image("desktopbackground")] + [ShifterMeta("Desktop")] + [ShifterCategory("General")] + [ShifterName("Desktop Background Image")] + [RequiresUpgrade("skinning")] + [ShifterDescription("Use an image as your desktop background.")] + public byte[] DesktopBackgroundImage = null; + + [ShifterMeta("Desktop")] + [ShifterCategory("App Launcher")] + [ShifterName("App launcher text")] + [ShifterDescription("The text displayed on the app launcher.")] + [RequiresUpgrade("shift_app_launcher")] + public string AppLauncherText = "ShiftOS"; + + [ShifterMeta("Desktop")] + [ShifterCategory("App Launcher")] + [ShifterName("App launcher from left")] + [ShifterDescription("The position of the app launcher from the left of the Desktop Panel.")] + [RequiresUpgrade("shift_app_launcher")] + public Point AppLauncherFromLeft = new Point(0, 0); + + [ShifterMeta("Desktop")] + [ShifterCategory("App Launcher")] + [ShifterName("App launcher size")] + [ShifterDescription("The size of the app launcher.")] + [RequiresUpgrade("shift_app_launcher")] + public Size AppLauncherHolderSize = new Size(68, 24); + + [ShifterMeta("Desktop")] + [ShifterCategory("App Launcher")] + [ShifterName("App launcher image")] + [ShifterDescription("The image that will appear on the app launcher.")] + [Image("applauncher")] + [RequiresUpgrade("skinning;shift_app_launcher")] + public byte[] AppLauncherImage = null; + + [ShifterMeta("System")] + [ShifterCategory("General")] + [ShifterName("Terminal font")] + public Font TerminalFont = new Font("Lucida Console", 9F, FontStyle.Regular); + + [ShifterMeta("System")] + [ShifterCategory("General")] + [ShifterName("Terminal text color")] + public Color TerminalForeColor = DefaultForeground; + + [ShifterMeta("System")] + [ShifterCategory("General")] + [ShifterName("Terminal background color")] + public Color TerminalBackColor = DesktopBG; + + [ShifterMeta("Desktop")] + [ShifterCategory("Desktop Panel")] + [ShifterName("Panel background image")] + [Image("desktoppanel")] + [RequiresUpgrade("skinning;shift_desktop_panel")] + public byte[] DesktopPanelBackground = null; + + [ShifterMeta("Windows")] + [ShifterCategory("Titlebar")] + [ShifterName("Titlebar background image")] + [Image("titlebar")] + [RequiresUpgrade("skinning;shift_titlebar")] + public byte[] TitleBarBackground = null; + + [ShifterMeta("Windows")] + [ShifterCategory("Titlebar")] + [RequiresUpgrade("shift_titlebar")] + [ShifterName("Show title corners?")] + [ShifterDescription("If checked, a left and a right section will appear on the titlebar which is useful for rounded corners, padding, or other useful properties.")] + public bool ShowTitleCorners = false; + + [ShifterMeta("Windows")] + [ShifterCategory("Titlebar")] + [RequiresUpgrade("shift_titlebar")] + [ShifterFlag("ShowTitleCorners", true)] + [ShifterName("Title left background color")] + [ShifterDescription("What color should be used for the left title corner?")] + public Color TitleLeftCornerBackground = TitleBG; + + [ShifterMeta("Windows")] + [ShifterCategory("Titlebar")] + [RequiresUpgrade("shift_titlebar")] + [ShifterFlag("ShowTitleCorners", true)] + [ShifterName("Title right background color")] + [ShifterDescription("What color should be used for the right title corner?")] + public Color TitleRightCornerBackground = TitleBG; + + [ShifterMeta("Windows")] + [ShifterCategory("Titlebar")] + [RequiresUpgrade("shift_titlebar")] + [ShifterFlag("ShowTitleCorners", true)] + [ShifterName("Title left corner width")] + [ShifterDescription("How wide should the left title corner be?")] + public int TitleLeftCornerWidth = 2; + + [ShifterMeta("Windows")] + [ShifterCategory("Titlebar")] + [RequiresUpgrade("shift_titlebar")] + [ShifterFlag("ShowTitleCorners", true)] + [ShifterName("Title right corner width")] + [ShifterDescription("How wide should the right title corner be?")] + public int TitleRightCornerWidth = 2; + + [ShifterMeta("Windows")] + [ShifterCategory("Titlebar")] + [RequiresUpgrade("skinning;shift_titlebar")] + [ShifterFlag("ShowTitleCorners", true)] + [ShifterName("Title left corner background image")] + [ShifterDescription("Select an image to appear as the background texture for the left titlebar corner.")] + [Image("titleleft")] + public byte[] TitleLeftBG = null; + + [ShifterMeta("Windows")] + [ShifterCategory("Titlebar")] + [RequiresUpgrade("skinning;shift_titlebar")] + [ShifterFlag("ShowTitleCorners", true)] + [ShifterName("Title right corner background image")] + [ShifterDescription("Select an image to appear as the background texture for the right titlebar corner.")] + [Image("titleright")] + public byte[] TitleRightBG = null; + + + [ShifterMeta("System")] + [ShifterCategory("General")] + [ShifterName("System color key-out")] + [ShifterDescription("This is a color that will be represented as \"transparent\" in windows. This does not affect the desktop.")] + public Color SystemKey = Color.FromArgb(1, 0, 1); + + [ShifterMeta("Windows")] + [ShifterCategory("Window border")] + [RequiresUpgrade("skinning;shift_window_borders")] + [Image("bottomborder")] + [ShifterName("Bottom Border Image")] + [ShifterDescription("Select an image to appear on the bottom border.")] + public byte[] BottomBorderBG = null; + + [ShifterMeta("Windows")] + [ShifterCategory("Window border")] + [RequiresUpgrade("skinning;shift_window_borders")] + [Image("bottomrborder")] + [ShifterName("Bottom Right Border Image")] + [ShifterDescription("Select an image to appear on the bottom right border.")] + public byte[] BottomRBorderBG = null; + + [ShifterMeta("Windows")] + [ShifterCategory("Window border")] + [RequiresUpgrade("skinning;shift_window_borders")] + [Image("bottomlborder")] + [ShifterName("Bottom Left Border Image")] + [ShifterDescription("Select an image to appear on the bottom left border.")] + public byte[] BottomLBorderBG = null; + + [ShifterMeta("Windows")] + [ShifterCategory("Window border")] + [RequiresUpgrade("skinning;shift_window_borders")] + [Image("leftborder")] + [ShifterName("Left Border Image")] + [ShifterDescription("Select an image to appear on the left border.")] + public byte[] LeftBorderBG = null; + + [ShifterMeta("Windows")] + [ShifterCategory("Window border")] + [RequiresUpgrade("skinning;shift_window_borders")] + [Image("rightborder")] + [ShifterName("Right Border Image")] + [ShifterDescription("Select an image to appear on the right border.")] + public byte[] RightBorderBG = null; + + [ShifterMeta("Windows")] + [ShifterCategory("Window border")] + [RequiresUpgrade("shift_window_borders")] + [ShifterName("Left border width")] + [ShifterDescription("How wide should the left border be?")] + public int LeftBorderWidth = 2; + + [ShifterMeta("Windows")] + [ShifterCategory("Window border")] + [RequiresUpgrade("shift_window_borders")] + [ShifterName("Right border width")] + [ShifterDescription("How wide should the right border be?")] + public int RightBorderWidth = 2; + + [ShifterMeta("Windows")] + [ShifterCategory("Window border")] + [RequiresUpgrade("shift_window_borders")] + [ShifterName("Bottom border height")] + [ShifterDescription("How tall should the bottom border be?")] + public int BottomBorderWidth = 2; + + [Image("panelbutton")] + [ShifterMeta("Desktop")] + [ShifterCategory("Panel buttons")] + [RequiresUpgrade("skinning;shift_panel_buttons")] + [ShifterName("Panel button background image")] + [ShifterDescription("Select a texture to display as the panel button background.")] + public byte[] PanelButtonBG = null; + + [ShifterMeta("Desktop")] + [ShifterCategory("Panel buttons")] + [RequiresUpgrade("shift_panel_buttons")] + [ShifterName("Panel button size")] + [ShifterDescription("How big should the panel button be?")] + public Size PanelButtonSize = new Size(185, 20); + + [ShifterMeta("Desktop")] + [ShifterCategory("Panel buttons")] + [RequiresUpgrade("shift_panel_buttons")] + [ShifterName("Panel button background color")] + [ShifterDescription("Select a background color for the panel button.")] + public Color PanelButtonColor = Skin.Accent2; + + [ShifterMeta("Desktop")] + [ShifterCategory("Panel buttons")] + [RequiresUpgrade("shift_panel_buttons")] + [ShifterName("Panel button text color")] + [ShifterDescription("Select a text color for the panel button.")] + public Color PanelButtonTextColor = Skin.TitleFG; + + [ShifterMeta("Desktop")] + [ShifterCategory("Panel buttons")] + [RequiresUpgrade("shift_panel_buttons")] + [ShifterName("Panel button text from left")] + [ShifterDescription("The position relative to the panel button left in pixels that the text is placed at.")] + public Point PanelButtonFromLeft = new Point(2, 2); + + [ShifterMeta("Desktop")] + [ShifterCategory("Panel buttons")] + [RequiresUpgrade("shift_panel_buttons")] + [ShifterName("Panel button font")] + [ShifterDescription("Select a font for the panel button.")] + public Font PanelButtonFont = Skin.SysFont2; + + + //we DO NOT want this showing in the shifter. + [ShifterHidden] + public Dictionary SkinImageLayouts = new Dictionary(); + } + + public class ShifterHiddenAttribute : Attribute { + + } + + public class ShifterFlagAttribute : Attribute { + public ShifterFlagAttribute(string flag, bool expected) { + Expected = expected; + Flag = flag; + } + + public bool Expected { get; set; } + public string Flag { get; set; } + public bool IsTrue(Skin skn) { + foreach (var f in skn.GetType().GetFields()) { + if (f.Name == Flag) { + if (f.FieldType == typeof(bool)) { + return (bool)f.GetValue(skn) == Expected; + } + } + } + throw new ArgumentException("The flag attribute was given an incorrect flag variable name."); + } + } + + public class ImageAttribute : Attribute { + /// + /// Attribute a byte array within the Skin object with this attribute and the engine and Shifter will see it as an image and you'll be able to grab the image by calling SkinEngine.GetImage() passing the name you input here. + /// + /// The name you want to reference this image as in the code. + public ImageAttribute(string name) { + Name = name; + } + + public string Name { get; set; } + } + + + public class ShifterEnumMaskAttribute : Attribute { + public ShifterEnumMaskAttribute(string[] items) { + Items = items; + } + + public string[] Items { get; set; } + } + + + + public class ShifterNameAttribute : Attribute { + public ShifterNameAttribute(string name) { + Name = name; + } + + public string Name { get; set; } + } + + public class ShifterDescriptionAttribute : Attribute { + public ShifterDescriptionAttribute(string description) { + Description = description; + } + + public string Description { get; set; } + } + + public class ShifterCategoryAttribute : Attribute { + + public ShifterCategoryAttribute(string category) { + Category = category; + } + + public string Category { get; set; } + } + + public class ShifterMetaAttribute : Attribute { + + public ShifterMetaAttribute(string meta) { + Meta = meta; + } + + public string Meta { get; set; } + } +} diff --git a/ShiftOS_TheReturn/Story.cs b/ShiftOS_TheReturn/Story.cs new file mode 100644 index 0000000..d7da473 --- /dev/null +++ b/ShiftOS_TheReturn/Story.cs @@ -0,0 +1,241 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace ShiftOS.Engine +{ + public class Story + { + public static void RunFromInternalResource(string resource_id) + { + var t = typeof(Properties.Resources); + + foreach(var prop in t.GetProperties(System.Reflection.BindingFlags.NonPublic | BindingFlags.Static)) + { + if(prop.Name == resource_id) + { + if(prop.PropertyType == typeof(string)) + { + WriteStory(prop.GetValue(null) as string); + + return; + } + } + } + throw new ArgumentException("Couldn't find resource ID inside the engine: " + resource_id); + } + + + public string Character { get; set; } + public List Lines { get; set; } + + public static void Start() + { + Console.WriteLine(); + if(SaveSystem.CurrentSave.StoryPosition == 5) + { + StartDevXLies(); + } + } + + public static void StartDevXLies() + { + int chatProgress = 0; + //bool LoopStuck = false; + string textToWrite = ""; + const int TYPE_SPEED_MS = 45; + bool done = false; + bool write = true; + + while (done == false) { + write = true; + switch (chatProgress) + { + case 0: + textToWrite = "User joined: @" + SaveSystem.CurrentSave.Username; + break; + case 1: + textToWrite = $"Hello, {SaveSystem.CurrentSave.Username}."; + break; + case 2: //If C:\ShiftOS doesn't exist the player won't notice this is here. + if (Directory.Exists(Paths.GetPath("classic"))) + { + textToWrite = "I see you've participated in my previous ShiftOS experiment. Welcome back, Shifter. I assume you know lots about ShiftOS, but there are some updates I have to tell you."; + } + else + { + write = false; + } + break; + case 3: //DevX hates ShiftOS-Next secretly. + if (Directory.Exists(Paths.GetPath("classic") + "-Next")) + { + textToWrite = "Hmmmm.... looking at my sentience records, I see you've participated in ShiftOS-Next. This is gonna be difficult."; + } + else + { + write = false; + } + break; + case 4: + textToWrite = "There's a lot that has changed within ShiftOS."; + break; + case 5: + textToWrite = "First off, I want to tell you a bit about myself in case you don't already know."; + break; + case 6: + textToWrite = "My name is DevX. I am the architect of ShiftOS. I have chosen you to take part in helping me out with it."; + break; + case 7: + textToWrite = "You see, in my past attempts it has all been about an evolving operating system and seeing how the users work with it..."; + break; + case 8: + textToWrite = "Almost one hundred percent of the time, people have found out it was an experiment and they could simply return to their regular system with a specific upgrade."; + break; + case 9: + textToWrite = "But now, I want to try something different - something unique."; + break; + case 10: + textToWrite = "ShiftOS is the same as it has been in my previous attempts, but now, your goal is to gain as much wealth and power as possible."; + break; + case 11: + textToWrite = "Right now you are inside my segregation LAN. Only you and me exist within this domain. You are free from other users unless I create them."; + break; + case 12: + textToWrite = "Since you have proved your sentience, I have a task for you outside the segregation LAN."; + break; + case 13: + textToWrite = "But first... you need to be taught a few things."; + break; + case 14: + textToWrite = "First off, when I bring you into my multi-user domain, you'll first want to establish as much wealth as possible."; + break; + case 15: + textToWrite = "Wealth comes in the form of Codepoints - a currency used among users of the multi-user domain."; + break; + case 16: + textToWrite = @"You can get Codepoints by doing the following: + + - Stealing them from other users + - Extracting them from inactive/unverified sentiences + - Using specific scripts/programs within ShiftOS + - Creating paid scripts/applications within ShiftOS"; + break; + case 17: + textToWrite = "You can use Codepoints to buy upgrades using the 'shiftorium.buy' command, or you can use them to pay other users, or scripts."; + break; + case 18: + textToWrite = "Within the multi-user domain you are free to do whatever you want. Larcany, theft, deceiving, lies, and distribution of malware is permitted under my watch."; + break; + case 19: + textToWrite = "Do whatever you have to to get Codepoints."; + break; + case 20: + textToWrite = "Then use them to make yourself stronger by buying upgrades at the shiftorium."; + break; + case 21: + textToWrite = "If you want to get a bit devious within the multi-user domain, look around for scripts that will expose user account information."; + break; + case 22: + textToWrite = "Or just spread a virus around the mud."; + break; + case 23: + textToWrite = "Or you can be the 'good' guy and stop these attacks and gain the trust of other users."; + break; + case 24: + textToWrite = "It's up to you. Just, don't mess with my system. You won't want me coming to you after that. I'm watching."; + break; + case 25: + textToWrite = "User left chat: @" + SaveSystem.CurrentSave.Username; + done = true; + SaveSystem.CurrentSave.StoryPosition++; + TerminalBackend.InvokeCommand("sos.save"); + break; + + } + + if (write == true) + { + Console.WriteLine(); + Console.Write("DevX: "); + foreach(char c in textToWrite) + { + Console.Beep(750, TYPE_SPEED_MS); + if (c == '\n') + { + + } + else if (c == '\r') + { + Console.WriteLine(); + } + else + { + Console.Write(c); + } + } + Thread.Sleep(1000); + } + chatProgress += 1; + } + } + + + public static void WriteStory(string json) + { + var thread = new Thread(new ThreadStart(() => + { + var story = JsonConvert.DeserializeObject(json); + + const int TYPESPEED = 45; + + foreach (var line in story.Lines) + { + var localized = Localization.Parse(line); + + + if (line.StartsWith("cmd:")) + { + string[] cmdsplit = line.Replace("cmd:", "").Split(' '); + switch (cmdsplit[0]) + { + case "givecp": + SaveSystem.TransferCodepointsFrom(story.Character, Convert.ToInt32(cmdsplit[1])); + break; + } + } + else + { + Console.Write(story.Character + ": "); + + foreach (var c in localized) + { + Console.Beep(1024, TYPESPEED); + if (c == '\r') + { + + } + else if (c == '\n') + Console.WriteLine(); + else + Console.Write(c); + } + + Console.WriteLine(); + Thread.Sleep(1000); + } + } + Console.Write($"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}:~$ "); + })); + thread.IsBackground = true; + thread.Start(); + } + } +} diff --git a/ShiftOS_TheReturn/TerminalBackend.cs b/ShiftOS_TheReturn/TerminalBackend.cs new file mode 100644 index 0000000..9e8eb96 --- /dev/null +++ b/ShiftOS_TheReturn/TerminalBackend.cs @@ -0,0 +1,211 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Newtonsoft.Json; +using static ShiftOS.Engine.SaveSystem; + +namespace ShiftOS.Engine +{ + public static class TerminalBackend + { + public static bool Elevated { get; set; } + + public static Dictionary GetArgs(ref string text) + { + bool shouldParse = false; + int argStart = 0; + if (text.Contains("{")) + { + shouldParse = true; + argStart = text.IndexOf('{'); + } + + if (shouldParse == false) + { + string replacement = Regex.Replace(text, @"\t|\n|\r", ""); + text = replacement + "{}"; + shouldParse = true; + argStart = text.IndexOf('{'); + } + + string args = text.Substring(argStart, text.Length - argStart); + + text = text.Remove(argStart, text.Length - argStart).Replace(" ", ""); + return JsonConvert.DeserializeObject>(args); + } + + public static string LastCommand = ""; + + public static void InvokeCommand(string text) + { + try + { + if (string.IsNullOrWhiteSpace(text)) + return; + + var args = GetArgs(ref text); + + bool commandWasClient = RunClient(text, args); + + if (!commandWasClient && !string.IsNullOrWhiteSpace(text)) + { + PrefixEnabled = false; + ServerManager.SendMessage("script", $@"{{ + user: ""{text.Split('.')[0]}"", + script: ""{text.Split('.')[1]}"", + args: ""{JsonConvert.SerializeObject(args)}"" +}}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Command parse error: {ex.Message}"); + PrefixEnabled = true; + + } + } + + public static bool PrefixEnabled { get; set; } + + public static bool InStory { get; set; } + + public static string latestCommmand = ""; + + public static event EmptyEventHandler TerminalRequested; + + internal static void OpenTerminal() + { + TerminalRequested?.Invoke(); + } + + public static bool RunClient(string text, Dictionary args) + { + latestCommmand = text; + + foreach (var asmExec in System.IO.Directory.GetFiles(Environment.CurrentDirectory)) + { + try + { + var asm = Assembly.LoadFile(asmExec); + + var types = asm.GetTypes(); + + foreach (var type in types) + { + if (Shiftorium.UpgradeAttributesUnlocked(type)) + { + foreach (var a in type.GetCustomAttributes(false)) + { + if (a is Namespace) + { + var ns = a as Namespace; + if (text.Split('.')[0] == ns.name) + { + foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) + { + if (Shiftorium.UpgradeAttributesUnlocked(method)) + { + foreach (var ma in method.GetCustomAttributes(false)) + { + if (ma is Command) + { + var cmd = ma as Command; + if (text.Split('.')[1] == cmd.name) + { + + var attr = method.GetCustomAttribute(); + + if (attr != null) + { + string newcommand = attr.newcommand; + if (attr.warn) + { + Console.WriteLine(Localization.Parse((newcommand == "" ? "{ERROR}" : "{WARN}") + attr.reason, new Dictionary() { + {"%newcommand", newcommand} + })); + } + if (newcommand != "") + { + // redo the entire process running newcommand + + return RunClient(newcommand, args); + } + } + + var requiresArgs = method.GetCustomAttributes(); + + bool error = false; + bool providedusage = false; + + foreach (RequiresArgument argument in requiresArgs) + { + 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() { + {"%ns", ns.name}, + {"%cmd", cmd.name} + }) : ""; + + Console.WriteLine(usageparse); + + providedusage = true; + } + + if (Shiftorium.UpgradeInstalled("help_usage")) + { + Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED}", new Dictionary() { + {"%argument", argument.argument} + })); + } + else + { + Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED_NO_USAGE}")); + } + + error = true; + } + } + + if (error) + { + throw new Exception("{ERROR_COMMAND_WRONG}"); + } + + try + { + return (bool)method.Invoke(null, new[] { args }); + } + catch + { + return (bool)method.Invoke(null, new object[] { }); + } + } + } + } + } + } + } + } + } + } + } + } + catch { } + } + return false; + } + + + } +} diff --git a/ShiftOS_TheReturn/TerminalTextWriter.cs b/ShiftOS_TheReturn/TerminalTextWriter.cs new file mode 100644 index 0000000..b36c13a --- /dev/null +++ b/ShiftOS_TheReturn/TerminalTextWriter.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using System.Windows.Forms; + +namespace ShiftOS.Engine +{ + public class TerminalTextWriter : TextWriter + { + [System.Runtime.InteropServices.DllImport("user32.dll")] + public static extern bool LockWindowUpdate(IntPtr hWndLock); + + + public override Encoding Encoding + { + get + { + return Encoding.Unicode; + } + } + + public ITerminalWidget UnderlyingControl + { + get + { + return AppearanceManager.ConsoleOut; + } + } + + public void select() + { + Desktop.InvokeOnWorkerThread(new Action(() => + { + UnderlyingControl.SelectBottom(); + + })); + } + + public override void Write(char value) + { + Desktop.InvokeOnWorkerThread(new Action(() => + { + UnderlyingControl.Write(value.ToString()); + select(); + })); + } + + public override void WriteLine(string value) + { + Desktop.InvokeOnWorkerThread(new Action(() => + { + UnderlyingControl.WriteLine(value); + select(); + })); + } + + public void SetLastText() + { + } + + public override void Write(string value) + { + Desktop.InvokeOnWorkerThread(new Action(() => + { + UnderlyingControl.Write(value.ToString()); + select(); + })); + } + + + } +} diff --git a/ShiftOS_TheReturn/VirusEngine.cs b/ShiftOS_TheReturn/VirusEngine.cs new file mode 100644 index 0000000..9823375 --- /dev/null +++ b/ShiftOS_TheReturn/VirusEngine.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using static ShiftOS.Objects.ShiftFS.Utils; + + +namespace ShiftOS.Engine +{ + public static class VirusEngine + { + private static List _infections = new List(); + + public static void Add(Virus virus) + { + _infections.Add(virus); + } + + public static void InfectFile(string file, string virusid) + { + string existing = ""; + + if(probeFile(file, out existing) == true) + { + existing = existing.Replace("<>", "").Replace("<>", ""); + + existing += ";" + virusid; + + existing = "<>" + existing + "<>"; + + string c = ReadAllText(file); + + string temp = ""; + + if(probeFile(file, out temp) == true) + { + c = c.Replace(temp, existing); + } + else + { + c = existing + c; + } + WriteAllText(file, c); + return; + } + else + { + existing = "<>" + virusid + "<>"; + string c = ReadAllText(file); + c = existing + c; + WriteAllText(file, c); + return; + } + + + } + + internal static string[] FindAllVirusesInFile(string file) + { + string existing = ""; + if(probeFile(file, out existing) == true) + { + existing = existing.Replace("<>", "").Replace("<>", ""); + return existing.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries); ; + } + else + { + return null; + } + } + + private static bool probeFile(string file, out string existing) + { + int startIndex = 0; + int endIndex = 0; + + bool found = false; + + string contents = ReadAllText(file); + + for(int i = 0; i < contents.Length; i++) + { + string end = "<>"; + try + { + if (contents.Substring(i, end.Length) == end) + { + endIndex = i + end.Length; + found = true; + break; + } + } + catch { } + } + + if (found == false) { + existing = "<><>"; + } + else + { + existing = contents.Substring(startIndex, endIndex); + } + return found; + } + + public static void Infect(string virusid) + { + string[] id_split = virusid.Split('.'); + + foreach(var v in _infections) + { + if(v.Type == id_split[0]) + { + if(v.Signature == id_split[1]) + { + if(v.ThreatLevel == Convert.ToInt32(id_split[2])) + { + var t = new Thread(new ThreadStart(() => + { + v.Activate(); + })); + t.IsBackground = true; + t.Start(); + return; + } + } + } + } + throw new Exception("Virus not found in the system."); + } + + internal static void ProbeFileRaw(string filePath, out string existing) + { + probeFile(filePath, out existing); + } + } + + public abstract class Virus + { + /// + /// Inject the virus into system memory by running it. + /// + public abstract void Activate(); + + /// + /// Terminate the virus. + /// + public abstract void Deactivate(); + + public abstract int ThreatLevel { get; } + + public abstract string Signature { get; } + + public abstract string Type { get; } + } +} diff --git a/ShiftOS_TheReturn/WinOpenAttribute.cs b/ShiftOS_TheReturn/WinOpenAttribute.cs new file mode 100644 index 0000000..152ce72 --- /dev/null +++ b/ShiftOS_TheReturn/WinOpenAttribute.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShiftOS.Engine +{ + public class WinOpenAttribute : Attribute + { + public string ID { get; private set; } + + public WinOpenAttribute (string id) + { + ID = id; + } + } +} diff --git a/ShiftOS_TheReturn/packages.config b/ShiftOS_TheReturn/packages.config new file mode 100644 index 0000000..ace2c07 --- /dev/null +++ b/ShiftOS_TheReturn/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file -- cgit v1.2.3