From dd95bc225f332c3c8ad23db55b3600b75e9511f1 Mon Sep 17 00:00:00 2001 From: lempamo Date: Tue, 28 Feb 2017 12:27:16 -0500 Subject: found a NRE --- ShiftOS_TheReturn/Shiftorium.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ShiftOS_TheReturn/Shiftorium.cs') diff --git a/ShiftOS_TheReturn/Shiftorium.cs b/ShiftOS_TheReturn/Shiftorium.cs index e6fc299..ab95f43 100644 --- a/ShiftOS_TheReturn/Shiftorium.cs +++ b/ShiftOS_TheReturn/Shiftorium.cs @@ -208,9 +208,9 @@ namespace ShiftOS.Engine } catch { - return false; Console.WriteLine("Upgrade " + id + "DNE."); Console.WriteLine(); + return false; } } -- cgit v1.2.3 From a28a68bcf8ef5e1e9d7d049d8d25515f43d5407f Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 7 Mar 2017 08:22:52 -0500 Subject: story IDs are now treated as shiftorium upgrades --- ShiftOS_TheReturn/Shiftorium.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'ShiftOS_TheReturn/Shiftorium.cs') diff --git a/ShiftOS_TheReturn/Shiftorium.cs b/ShiftOS_TheReturn/Shiftorium.cs index ab95f43..24fa123 100644 --- a/ShiftOS_TheReturn/Shiftorium.cs +++ b/ShiftOS_TheReturn/Shiftorium.cs @@ -204,6 +204,9 @@ namespace ShiftOS.Engine } try { + if (SaveSystem.CurrentSave.StoriesExperienced.Contains(id)) + return true; + return SaveSystem.CurrentSave.Upgrades[id]; } catch -- cgit v1.2.3 From 0ea74f3088d2b302ab796ae02fffb5dfd4bc8a4f Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 7 Mar 2017 09:18:40 -0500 Subject: story stuff --- ShiftOS.WinForms/HackerCommands.cs | 137 +++++++++++++++++++++++++++++++ ShiftOS.WinForms/ShiftOS.WinForms.csproj | 1 + ShiftOS_TheReturn/SaveSystem.cs | 2 +- ShiftOS_TheReturn/Shiftorium.cs | 12 ++- 4 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 ShiftOS.WinForms/HackerCommands.cs (limited to 'ShiftOS_TheReturn/Shiftorium.cs') diff --git a/ShiftOS.WinForms/HackerCommands.cs b/ShiftOS.WinForms/HackerCommands.cs new file mode 100644 index 0000000..ebe25a2 --- /dev/null +++ b/ShiftOS.WinForms/HackerCommands.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using ShiftOS.Engine; +using ShiftOS.WinForms.Applications; + +namespace ShiftOS.WinForms +{ + [Namespace("l337")] + [RequiresUpgrade("hacker101_deadaccts")] + public static class HackerCommands + { + private static void writeSlow(string text) + { + Console.Write("[hacker101@undisclosed]: "); + foreach(var c in text.ToCharArray()) + { + Console.Write(c); + Thread.Sleep(125); + } + Console.WriteLine(); + Thread.Sleep(1000); + } + + [Story("hacker101_deadaccts")] + public static void DeadAccountsStory() + { + if (!terminalIsOpen()) + { + AppearanceManager.SetupWindow(new Terminal()); + } + + var t = new Thread(() => + { + Console.WriteLine("[sys@mud]: Warning: User connecting to system..."); + Thread.Sleep(75); + Console.WriteLine("[sys@mud]: UBROADCAST: Username: hacker101 - Sysname: undisclosed"); + Thread.Sleep(50); + Console.Write("--locking mud connection resources..."); + Thread.Sleep(50); + Console.WriteLine("...done."); + Console.Write("--locking user input... "); + Thread.Sleep(75); + TerminalBackend.PrefixEnabled = false; + TerminalBackend.InStory = true; + Console.WriteLine("...done."); + + Thread.Sleep(2000); + writeSlow($"Hello there, fellow multi-user domain user."); + writeSlow("My name, as you can tell, is hacker101."); + writeSlow("And yours must be... don't say it... it's " + SaveSystem.CurrentSave.Username + "@" + SaveSystem.CurrentSave.SystemName + ", right?"); + writeSlow("Of course it is."); + writeSlow("And I bet you 10,000 Codepoints that you have... " + SaveSystem.CurrentSave.Codepoints.ToString() + " Codepoints."); + writeSlow("Oh, and how much upgrades have you installed since you first started using ShiftOS?"); + writeSlow("That would be... uhh... " + SaveSystem.CurrentSave.CountUpgrades().ToString() + "."); + writeSlow("I'm probably freaking you out right now. You are probably thinking that you're unsafe and need to lock yourself down."); + writeSlow("But, don't worry, I mean no harm."); + writeSlow("In fact, I am a multi-user domain safety activist and security professional."); + writeSlow("I need your help with something."); + writeSlow("Inside the multi-user domain, every now and then these 'dead' user accounts pop up."); + writeSlow("They're infesting everything. They're in every legion, they infest chatrooms, and they take up precious hard drive space."); + writeSlow("Eventually there's going to be tons of them just sitting there taking over the MUD. We can't have that."); + writeSlow("It sounds like a conspiracy theory indeed, but it's true, in fact, these dead accounts hold some valuable treasures."); + writeSlow("I'm talking Codepoints, skins, documents, the possibilities are endless."); + writeSlow("I'm going to execute a quick sys-script that will show you how you can help get rid of these accounts, and also gain some valuable resources to help you on your digital frontier."); + writeSlow("This script will also show you the fundamentals of security exploitation and theft of resources - which if you want to survive in the multi-user domain is paramount."); + writeSlow("Good luck."); + Thread.Sleep(1000); + Console.WriteLine("--user disconnected"); + Thread.Sleep(75); + Console.WriteLine("--commands unlocked - check sos.help."); + Thread.Sleep(45); + SaveSystem.SaveGame(); + Console.Write("--unlocking user input..."); + Thread.Sleep(75); + Console.Write(" ..done"); + TerminalBackend.InStory = false; + TerminalBackend.PrefixEnabled = true; + Console.Write($"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}:~$ "); + StartHackerTutorial(); + }); + t.IsBackground = true; + t.Start(); + } + + internal static void StartHackerTutorial() + { + //nyi + } + + private static bool terminalIsOpen() + { + foreach(var win in AppearanceManager.OpenForms) + { + if (win.ParentWindow is Terminal) + return true; + } + return false; + } + } + + [Namespace("storydev")] + public static class StoryDevCommands + { + [Command("start", description = "Starts a story plot.", usage ="id:string")] + [RequiresArgument("id")] + [RemoteLock] + public static bool StartStory(Dictionary args) + { + Story.Start(args["id"].ToString()); + return true; + } + + [Command("unexperience", description = "Marks a story plot as not-experienced yet.", usage ="id:string")] + [RemoteLock] + [RequiresArgument("id")] + public static bool Unexperience(Dictionary args) + { + string id = args["id"].ToString(); + if (SaveSystem.CurrentSave.StoriesExperienced.Contains(id)) + { + Console.WriteLine("Unexperiencing " + id + "."); + SaveSystem.CurrentSave.StoriesExperienced.Remove(id); + SaveSystem.SaveGame(); + } + else + { + Console.WriteLine("Story ID not found."); + } + + return true; + } + } +} diff --git a/ShiftOS.WinForms/ShiftOS.WinForms.csproj b/ShiftOS.WinForms/ShiftOS.WinForms.csproj index 7d4f0d3..4bc79a0 100644 --- a/ShiftOS.WinForms/ShiftOS.WinForms.csproj +++ b/ShiftOS.WinForms/ShiftOS.WinForms.csproj @@ -238,6 +238,7 @@ FakeSetupScreen.cs + Form diff --git a/ShiftOS_TheReturn/SaveSystem.cs b/ShiftOS_TheReturn/SaveSystem.cs index 9ae18a9..9f0b9b7 100644 --- a/ShiftOS_TheReturn/SaveSystem.cs +++ b/ShiftOS_TheReturn/SaveSystem.cs @@ -110,7 +110,7 @@ namespace ShiftOS.Engine ServerManager.GUIDReceived += (str) => { guidReceived = true; - Console.WriteLine("{CONNECTION_SUCCESSFUL}"); + Console.WriteLine("Connection successful."); }; try diff --git a/ShiftOS_TheReturn/Shiftorium.cs b/ShiftOS_TheReturn/Shiftorium.cs index 24fa123..198dcc7 100644 --- a/ShiftOS_TheReturn/Shiftorium.cs +++ b/ShiftOS_TheReturn/Shiftorium.cs @@ -204,10 +204,16 @@ namespace ShiftOS.Engine } try { - if (SaveSystem.CurrentSave.StoriesExperienced.Contains(id)) - return true; + if (SaveSystem.CurrentSave == null) + return false; - return SaveSystem.CurrentSave.Upgrades[id]; + if (SaveSystem.CurrentSave.StoriesExperienced == null) + SaveSystem.CurrentSave.StoriesExperienced = new List(); + + if (!SaveSystem.CurrentSave.StoriesExperienced.Contains(id)) + return SaveSystem.CurrentSave.Upgrades[id]; + + return true; } catch { -- cgit v1.2.3 From 2a747334bd926d79537b9e8d4f38c79a815752e5 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 7 Mar 2017 14:56:48 -0500 Subject: WHOA HACKING --- .../Applications/TutorialBox.Designer.cs | 57 +++ ShiftOS.WinForms/Applications/TutorialBox.cs | 73 ++++ ShiftOS.WinForms/Applications/TutorialBox.resx | 120 +++++ ShiftOS.WinForms/Controls/TerminalBox.cs | 2 + ShiftOS.WinForms/HackerCommands.cs | 484 ++++++++++++++++++++- ShiftOS.WinForms/ShiftOS.WinForms.csproj | 9 + ShiftOS_TheReturn/Command.cs | 6 + ShiftOS_TheReturn/Commands.cs | 28 ++ ShiftOS_TheReturn/KernelWatchdog.cs | 70 +++ ShiftOS_TheReturn/SaveSystem.cs | 4 +- ShiftOS_TheReturn/ServerManager.cs | 7 + ShiftOS_TheReturn/ShiftOS.Engine.csproj | 1 + ShiftOS_TheReturn/Shiftorium.cs | 7 +- ShiftOS_TheReturn/TerminalBackend.cs | 156 +++---- 14 files changed, 939 insertions(+), 85 deletions(-) create mode 100644 ShiftOS.WinForms/Applications/TutorialBox.Designer.cs create mode 100644 ShiftOS.WinForms/Applications/TutorialBox.cs create mode 100644 ShiftOS.WinForms/Applications/TutorialBox.resx create mode 100644 ShiftOS_TheReturn/KernelWatchdog.cs (limited to 'ShiftOS_TheReturn/Shiftorium.cs') diff --git a/ShiftOS.WinForms/Applications/TutorialBox.Designer.cs b/ShiftOS.WinForms/Applications/TutorialBox.Designer.cs new file mode 100644 index 0000000..6e74023 --- /dev/null +++ b/ShiftOS.WinForms/Applications/TutorialBox.Designer.cs @@ -0,0 +1,57 @@ +namespace ShiftOS.WinForms.Applications +{ + partial class TutorialBox + { + /// + /// 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 Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.lbltuttext = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // lbltuttext + // + this.lbltuttext.Dock = System.Windows.Forms.DockStyle.Fill; + this.lbltuttext.Location = new System.Drawing.Point(0, 0); + this.lbltuttext.Name = "lbltuttext"; + this.lbltuttext.Size = new System.Drawing.Size(401, 134); + this.lbltuttext.TabIndex = 0; + // + // TutorialBox + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.lbltuttext); + this.Name = "TutorialBox"; + this.Size = new System.Drawing.Size(401, 134); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Label lbltuttext; + } +} diff --git a/ShiftOS.WinForms/Applications/TutorialBox.cs b/ShiftOS.WinForms/Applications/TutorialBox.cs new file mode 100644 index 0000000..25921e1 --- /dev/null +++ b/ShiftOS.WinForms/Applications/TutorialBox.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using ShiftOS.Engine; +using System.Threading; + +namespace ShiftOS.WinForms.Applications +{ + + [DefaultTitle("Tutorial objective")] + public partial class TutorialBox : UserControl, IShiftOSWindow + { + public TutorialBox() + { + InitializeComponent(); + IsComplete = false; + lbltuttext.Text = ""; + } + + bool stillTyping = false; + + public void SetObjective(string text) + { + while (stillTyping == true) + { + + } + + new Thread(() => + { + stillTyping = true; + this.Invoke(new Action(() => + { + lbltuttext.Text = ""; + })); + foreach(var c in text.ToCharArray()) + { + this.Invoke(new Action(() => + { + lbltuttext.Text += c; + })); + Thread.Sleep(75); + } + stillTyping = false; + }).Start(); + } + + public void OnLoad() + { + } + + public void OnSkinLoad() + { + } + + public bool IsComplete { get; set; } + + public bool OnUnload() + { + return IsComplete; + } + + public void OnUpgrade() + { + } + } +} diff --git a/ShiftOS.WinForms/Applications/TutorialBox.resx b/ShiftOS.WinForms/Applications/TutorialBox.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/ShiftOS.WinForms/Applications/TutorialBox.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.WinForms/Controls/TerminalBox.cs b/ShiftOS.WinForms/Controls/TerminalBox.cs index 200c1d7..4fcb429 100644 --- a/ShiftOS.WinForms/Controls/TerminalBox.cs +++ b/ShiftOS.WinForms/Controls/TerminalBox.cs @@ -52,7 +52,9 @@ namespace ShiftOS.WinForms.Controls public void Write(string text) { + this.HideSelection = true; this.AppendText(Localization.Parse(text)); + this.HideSelection = false; } public void WriteLine(string text) diff --git a/ShiftOS.WinForms/HackerCommands.cs b/ShiftOS.WinForms/HackerCommands.cs index ebe25a2..7938fd0 100644 --- a/ShiftOS.WinForms/HackerCommands.cs +++ b/ShiftOS.WinForms/HackerCommands.cs @@ -1,27 +1,67 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using Newtonsoft.Json; using ShiftOS.Engine; +using ShiftOS.Objects; using ShiftOS.WinForms.Applications; +using static ShiftOS.Objects.ShiftFS.Utils; namespace ShiftOS.WinForms { - [Namespace("l337")] + [Namespace("puppy")] + [RequiresUpgrade("hacker101_deadaccts")] + [KernelMode] + public static class KernelPuppyCommands + { + [Command("clear", true)] + public static bool ClearLogs() + { + WriteAllText("0:/system/data/kernel.log", ""); + Console.WriteLine(" logs cleared successfully."); + return true; + } + } + + [Namespace("krnl")] + public static class KernelCommands + { + [Command("control", true)] + [RequiresArgument("pass")] + public static bool Control(Dictionary args) + { + if(args["pass"].ToString() == ServerManager.thisGuid.ToString()) + { + KernelWatchdog.Log("warn", "User has breached the kernel."); + KernelWatchdog.EnterKernelMode(); + } + return true; + } + + [Command("lock_session")] + [KernelMode] + public static bool LeaveControl() + { + KernelWatchdog.Log("inf", "User has left the kernel-mode session."); + KernelWatchdog.LeaveKernelMode(); + KernelWatchdog.MudConnected = true; + return true; + } + } + + [Namespace("hacker101")] [RequiresUpgrade("hacker101_deadaccts")] public static class HackerCommands { private static void writeSlow(string text) { Console.Write("[hacker101@undisclosed]: "); - foreach(var c in text.ToCharArray()) - { - Console.Write(c); - Thread.Sleep(125); - } - Console.WriteLine(); + Thread.Sleep(200); + Console.WriteLine(text); Thread.Sleep(1000); } @@ -88,9 +128,217 @@ namespace ShiftOS.WinForms internal static void StartHackerTutorial() { - //nyi + Desktop.InvokeOnWorkerThread(() => + { + var tut = new TutorialBox(); + AppearanceManager.SetupWindow(tut); + + new Thread(() => + { + + + int tutPos = 0; + Action ondec = () => + { + if (tutPos == 2) + tutPos++; + }; + TerminalBackend.CommandProcessed += (o, a) => + { + switch (tutPos) + { + + case 0: + case 10: + if (o.ToLower().StartsWith("mud.disconnect")) + { + tutPos++; + } + break; + case 11: + if (o.ToLower().StartsWith("krnl.lock_session")) + tutPos++; + break; + case 1: + if (o.ToLower().StartsWith("hacker101.brute_decrypt")) + { + if (a.Contains("0:/system/data/kernel.log")) + { + tutPos++; + } + } + break; + case 3: + if (o.ToLower().StartsWith("krnl.control")) + { + tutPos++; + } + break; + case 4: + if (o.ToLower().StartsWith("puppy.clear")) + tutPos++; + break; + case 5: + if (o.ToLower().StartsWith("mud.reconnect")) + tutPos++; + break; + case 6: + if (o.ToLower().StartsWith("mud.sendmsg")) + { + var msg = JsonConvert.DeserializeObject(a); + try + { + if (msg.header == "getusers" && msg.body == "dead") + tutPos++; + } + catch + { + + } + } + break; + case 7: + if (o.ToLower().StartsWith("hacker101.breach_user_password")) + tutPos++; + break; + case 8: + if (o.ToLower().StartsWith("hacker101.print_user_info")) + tutPos++; + break; + case 9: + if (o.ToLower().StartsWith("hacker101.steal_codepoints")) + tutPos++; + break; + } + }; + tut.SetObjective("Welcome to the dead account exploitation tutorial. In this tutorial you will learn the basics of hacking within the multi-user domain."); + Thread.Sleep(1000); + tut.SetObjective("We will start with a simple system exploit - gaining kernel-level access to ShiftOS. This can help you perform actions not ever possible in the user level."); + Thread.Sleep(1000); + tut.SetObjective("To gain root access, you will first need to breach the system watchdog to keep it from dialing home to DevX."); + Thread.Sleep(1000); + tut.SetObjective("The watchdog can only function when it has a successful connection to the multi-user domain. You will need to use the MUD Control Centre to disconnect yourself from the MUD. This will lock you out of most features. To disconnect from the multi-user domain, simply run the 'mud.disconnect' command."); + while(tutPos == 0) + { + + } + tut.SetObjective("As you can see, the kernel watchdog has shut down temporarily, however before the disconnect it was able to tell DevX that it has gone offline."); + Thread.Sleep(1000); + tut.SetObjective("You'll also notice that commands like the shiftorium, MUD control centre and various applications that utilize these system components no longer function."); + Thread.Sleep(1000); + tut.SetObjective("The watchdog, however, is still watching. DevX was smart and programmed the kernel to log all events to a local file in 0:/system/data/kernel.log."); + Thread.Sleep(1000); + tut.SetObjective("You will need to empty out this file before you can connect to the multi-user domain, as the watchdog will send the contents of this file straight to DevX."); + Thread.Sleep(1000); + tut.SetObjective("Or, you can do what we're about to do and attempt to decrypt the log and sniff out the kernel-mode access password."); + Thread.Sleep(1000); + tut.SetObjective("This will allow us to gain kernel-level access to our system using the krnl.control{pass:} command."); + Thread.Sleep(1000); + tut.SetObjective("Let's start decrypting the log file using the hacker101.brute_decrypt{file:} script. The file: argument is a string and should point to a .log file. When the script succeeds, you will see a TextPad open with the decrypted contents."); + while(tutPos == 1) + { + + } + onCompleteDecrypt += ondec; + tut.SetObjective("This script isn't the most agile script ever, but it'll get the job done."); + while(tutPos == 2) + { + + } + onCompleteDecrypt -= ondec; + tut.SetObjective("Alright - it's done. Here's how it's laid out. In each log entry, you have the timestamp, then the event name, then the event description."); + Thread.Sleep(1000); + tut.SetObjective("Look for the most recent 'mudhandshake' event. This contains the kernel access code."); + Thread.Sleep(1000); + tut.SetObjective("Once you have it, run 'krnl.control{pass:\"the-kernel-code-here\"}. This will allow you to gain access to the kernel."); + while(tutPos == 3) + { + + } + tut.SetObjective("You are now in kernel mode. Every command you enter will run on the kernel. Now, let's clear the watchdog's logfile and reconnect to the multi-user domain."); + Thread.Sleep(1000); + tut.SetObjective("To clear the log, simply run 'puppy.clear'."); + while(tutPos == 4) + { + + } + tut.SetObjective("Who's a good dog... You are, ShiftOS. Now, we can connect back to the MUD using 'mud.reconnect'."); + Thread.Sleep(1000); + while(tutPos == 5) + { + + } + tut.SetObjective("We have now snuck by the watchdog and DevX has no idea. With kernel-level access, everything you do is not logged, however if you perform too much in one shot, you'll get kicked off and locked out of the multi-user domain temporarily."); + Thread.Sleep(1000); + tut.SetObjective("So, let's focus on the job. You want to get into one of those fancy dead accounts, don't ya? Well, first, we need to talk with the MUD to get a list of these accounts."); + Thread.Sleep(1000); + tut.SetObjective("Simply run the `mud.sendmsg` command, specifying a 'header' of \"getusers\", and a body of \"dead\"."); + while(tutPos == 6) + { + + } + tut.SetObjective("Great. We now have the usernames and sysnames of all dead accounts on the MUD. Now let's use the hacker101.breach_user_password{user:,sys:} command to breach one of these accounts' passwords."); + while(tutPos == 7) + { + + } + tut.SetObjective("There - you now have access to that account. Use its password, username and sysname and run the hacker101.print_user_info{user:,pass:,sys:} command to print the entirety of this user's information."); + while(tutPos == 8) + { + + } + tut.SetObjective("Now you can see a list of the user's Codepoints among other things. Now you can steal their codepoints by using the hacker101.steal_codepoints{user:,pass:,sys;,amount:} command. Be careful. This may alert DevX."); + while(tutPos == 9) + { + + } + if(devx_alerted == true) + { + tut.SetObjective("Alright... enough fun and games. DevX just found out we were doing this."); + Thread.Sleep(500); + tut.SetObjective("Quick! Disconnect from the MUD!!"); + while(tutPos == 10) + { + + } + tut.SetObjective("Now, get out of kernel mode! To do that, run krnl.lock_session."); + while(tutPos == 11) + { + + } + + } + else + { + tut.SetObjective("OK, that was risky, but we pulled it off. Treat yourself! But first, let's get you out of kernel mode."); + Thread.Sleep(500); + tut.SetObjective("First we need to get you off the MUD. Simply run mud.disconnect again."); + while (tutPos == 10) + { + + } + tut.SetObjective("Now, let's run krnl.lock_session. This will lock you back into the user mode, and reconnect you to the MUD."); + while (tutPos == 11) + { + + } + tut.SetObjective("If, for some reason, DevX DOES find out, you have to be QUICK to get off of kernel mode. You don't want to make him mad."); + } + + Thread.Sleep(1000); + tut.SetObjective("So that's all for now. Whenever you're in kernel mode again, and you have access to a user account, try breaching their filesystem next time. You can use sos.help{ns:} to show commands from a specific namespace to help you find more commands easily."); + Thread.Sleep(1000); + tut.SetObjective("You can now close this window."); + tut.IsComplete = true; + + }).Start(); + }); } + private static bool devx_alerted = false; + + private static event Action onCompleteDecrypt; + private static bool terminalIsOpen() { foreach(var win in AppearanceManager.OpenForms) @@ -100,6 +348,226 @@ namespace ShiftOS.WinForms } return false; } + + const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890-_"; + + [Command("breach_user_password")] + [KernelMode] + [RequiresArgument("user")] + [RequiresArgument("sys")] + [RequiresUpgrade("hacker101_deadaccts")] + public static bool BreachUserPassword(Dictionary args) + { + string usr = args["user"].ToString(); + string sys = args["sys"].ToString(); + + ServerMessageReceived msgReceived = null; + + Console.WriteLine("--hooking system thread..."); + + msgReceived = (msg) => + { + if(msg.Name == "user_data") + { + var sve = JsonConvert.DeserializeObject(msg.Contents); + var rnd = new Random(); + var sw = new Stopwatch(); + sw.Start(); + string pass = ""; + for(int i = 0; i < sve.Password.Length; i++) + { + char c = '\0'; + while (c != sve.Password[i]) + c = chars[rnd.Next(0, chars.Length)]; + pass += c; + Thread.Sleep(rnd.Next(25,75)); + } + sw.Stop(); + Console.WriteLine(pass); + Console.WriteLine(); + Console.WriteLine("--password breached. Operation took " + sw.ElapsedMilliseconds + " milliseconds."); + } + else if(msg.Name == "user_data_not_found") + { + Console.WriteLine("--access denied."); + } + ServerManager.MessageReceived -= msgReceived; + }; + + Console.WriteLine("--beginning brute-force attack on " + usr + "@" + sys + "..."); + Thread.Sleep(500); + ServerManager.MessageReceived += msgReceived; + + ServerManager.SendMessage("get_user_data", JsonConvert.SerializeObject(new + { + user = usr, + sysname = sys + })); + return true; + } + + [Command("print_user_info")] + [KernelMode] + [RequiresArgument("pass")] + [RequiresArgument("user")] + [RequiresArgument("sys")] + [RequiresUpgrade("hacker101_deadaccts")] + public static bool PrintUserInfo(Dictionary args) + { + string usr = args["user"].ToString(); + string sys = args["sys"].ToString(); + string pass = args["pass"].ToString(); + + ServerMessageReceived msgReceived = null; + + Console.WriteLine("--hooking multi-user domain response call..."); + + msgReceived = (msg) => + { + if (msg.Name == "user_data") + { + var sve = JsonConvert.DeserializeObject(msg.Contents); + if(sve.Password == pass) + { + Console.WriteLine("Username: " + sve.Username); + Console.WriteLine("Password: " + sve.Password); + Console.WriteLine("System name: " + sve.SystemName); + Console.WriteLine(); + Console.WriteLine("Codepoints: " + sve.Codepoints.ToString()); + + } + else + { + Console.WriteLine("--access denied."); + } + + } + else if (msg.Name == "user_data_not_found") + { + Console.WriteLine("--access denied."); + } + ServerManager.MessageReceived -= msgReceived; + }; + + Console.WriteLine("--contacting multi-user domain..."); + Thread.Sleep(500); + ServerManager.MessageReceived += msgReceived; + + ServerManager.SendMessage("get_user_data", JsonConvert.SerializeObject(new + { + user = usr, + sysname = sys + })); + return true; + } + + [Command("steal_codepoints")] + [KernelMode] + [RequiresArgument("amount")] + [RequiresArgument("pass")] + [RequiresArgument("user")] + [RequiresArgument("sys")] + [RequiresUpgrade("hacker101_deadaccts")] + public static bool StealCodepoints(Dictionary args) + { + string usr = args["user"].ToString(); + string sys = args["sys"].ToString(); + string pass = args["pass"].ToString(); + long amount = (long)args["amount"]; + + if(amount < 0) + { + Console.WriteLine("--invalid codepoint amount - halting..."); + return true; + } + + ServerMessageReceived msgReceived = null; + + Console.WriteLine("--hooking multi-user domain response call..."); + + msgReceived = (msg) => + { + if (msg.Name == "user_data") + { + var sve = JsonConvert.DeserializeObject(msg.Contents); + if (sve.Password == pass) + { + if(amount > sve.Codepoints) + { + Console.WriteLine("--can't steal this many codepoints from user."); + return; + } + + sve.Codepoints -= amount; + SaveSystem.TransferCodepointsFrom(sve.Username, amount); + ServerManager.SendMessage("mud_save_allow_dead", JsonConvert.SerializeObject(sve)); + SaveSystem.SaveGame(); + } + else + { + Console.WriteLine("--access denied."); + } + + } + else if (msg.Name == "user_data_not_found") + { + Console.WriteLine("--access denied."); + } + ServerManager.MessageReceived -= msgReceived; + }; + + Console.WriteLine("--contacting multi-user domain..."); + Thread.Sleep(500); + ServerManager.MessageReceived += msgReceived; + + ServerManager.SendMessage("get_user_data", JsonConvert.SerializeObject(new + { + user = usr, + sysname = sys + })); + return true; + } + + + + [Command("brute_decrypt", true)] + [RequiresArgument("file")] + public static bool BruteDecrypt(Dictionary args) + { + if (FileExists(args["file"].ToString())) + { + string pass = new Random().Next(1000, 10000).ToString(); + string fake = ""; + Console.WriteLine("Beginning brute-force attack on password."); + var s = new Stopwatch(); + s.Start(); + for(int i = 0; i < pass.Length; i++) + { + for(int num = 0; num < 10; num++) + { + if(pass[i].ToString() == num.ToString()) + { + fake += num.ToString(); + Console.Write(num); + } + } + } + s.Stop(); + + Console.WriteLine("...password cracked - operation took " + s.ElapsedMilliseconds + " milliseconds."); + var tp = new TextPad(); + AppearanceManager.SetupWindow(tp); + WriteAllText("0:/temp.txt", ReadAllText(args["file"].ToString())); + tp.LoadFile("0:/temp.txt"); + Delete("0:/temp.txt"); + onCompleteDecrypt?.Invoke(); + } + else + { + Console.WriteLine("brute_decrypt: file not found"); + } + return true; + } } [Namespace("storydev")] diff --git a/ShiftOS.WinForms/ShiftOS.WinForms.csproj b/ShiftOS.WinForms/ShiftOS.WinForms.csproj index 4bc79a0..7f728d5 100644 --- a/ShiftOS.WinForms/ShiftOS.WinForms.csproj +++ b/ShiftOS.WinForms/ShiftOS.WinForms.csproj @@ -208,6 +208,12 @@ Terminal.cs + + UserControl + + + TutorialBox.cs + @@ -350,6 +356,9 @@ Terminal.cs + + TutorialBox.cs + DownloadControl.cs diff --git a/ShiftOS_TheReturn/Command.cs b/ShiftOS_TheReturn/Command.cs index 85da6ca..a5924ed 100644 --- a/ShiftOS_TheReturn/Command.cs +++ b/ShiftOS_TheReturn/Command.cs @@ -30,6 +30,12 @@ using System.Threading.Tasks; namespace ShiftOS.Engine { + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] + public class KernelModeAttribute : Attribute + { + + } + public class Command : Attribute { public string name; diff --git a/ShiftOS_TheReturn/Commands.cs b/ShiftOS_TheReturn/Commands.cs index 76aa42f..0ea00e5 100644 --- a/ShiftOS_TheReturn/Commands.cs +++ b/ShiftOS_TheReturn/Commands.cs @@ -164,7 +164,35 @@ namespace ShiftOS.Engine } } + [Command("reconnect")] + [RequiresUpgrade("hacker101_deadaccts")] + public static bool Reconnect() + { + Console.WriteLine("--reconnecting to multi-user domain..."); + KernelWatchdog.MudConnected = true; + Console.WriteLine("--done."); + return true; + } + + [Command("disconnect")] + [RequiresUpgrade("hacker101_deadaccts")] + public static bool Disconnect() + { + Console.WriteLine("--connection to multi-user domain severed..."); + KernelWatchdog.MudConnected = false; + return true; + } + [Command("sendmsg")] + [KernelMode] + [RequiresUpgrade("hacker101_deadaccts")] + [RequiresArgument("header")] + [RequiresArgument("body")] + public static bool SendMessage(Dictionary args) + { + ServerManager.SendMessage(args["header"].ToString(), args["body"].ToString()); + return true; + } } [RequiresUpgrade("mud_fundamentals")] diff --git a/ShiftOS_TheReturn/KernelWatchdog.cs b/ShiftOS_TheReturn/KernelWatchdog.cs new file mode 100644 index 0000000..1b59b25 --- /dev/null +++ b/ShiftOS_TheReturn/KernelWatchdog.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using static ShiftOS.Objects.ShiftFS.Utils; + +namespace ShiftOS.Engine +{ + public static class KernelWatchdog + { + public static void Log(string e, string desc) + { + string line = $"[{DateTime.Now}] <{e}> {desc}"; + if (FileExists("0:/system/data/kernel.log")) + { + string contents = ReadAllText("0:/system/data/kernel.log"); + contents += Environment.NewLine + line; + WriteAllText("0:/system/data/kernel.log", contents); + } + else + { + WriteAllText("0:/system/data/kernel.log", line); + } + } + + public static bool InKernelMode { get; private set; } + public static bool MudConnected { get; set; } + + public static bool IsSafe(Type type) + { + if (InKernelMode == true) + return true; + + foreach (var attrib in type.GetCustomAttributes(false)) + { + if (attrib is KernelModeAttribute) + return false; + } + return true; + } + + public static bool IsSafe(MethodInfo type) + { + if (InKernelMode == true) + return true; + + foreach (var attrib in type.GetCustomAttributes(false)) + { + if (attrib is KernelModeAttribute) + return false; + } + return true; + } + + + public static void EnterKernelMode() + { + InKernelMode = true; + Console.WriteLine(" Watchdog deactivated, system-level access granted."); + } + + public static void LeaveKernelMode() + { + InKernelMode = false; + Console.WriteLine(" Kernel mode disabled."); + } + } +} diff --git a/ShiftOS_TheReturn/SaveSystem.cs b/ShiftOS_TheReturn/SaveSystem.cs index b9633e5..df4c6d6 100644 --- a/ShiftOS_TheReturn/SaveSystem.cs +++ b/ShiftOS_TheReturn/SaveSystem.cs @@ -155,6 +155,8 @@ namespace ShiftOS.Engine public static void FinishBootstrap() { + KernelWatchdog.Log("mud_handshake", "handshake successful: kernel watchdog access code is \"" + ServerManager.thisGuid.ToString() + "\""); + ServerManager.MessageReceived += (msg) => { if (msg.Name == "mud_savefile") @@ -313,7 +315,7 @@ namespace ShiftOS.Engine System.IO.File.WriteAllText(Paths.SaveFile, Utils.ExportMount(0)); } - public static void TransferCodepointsFrom(string who, int amount) + public static void TransferCodepointsFrom(string who, long amount) { NotificationDaemon.AddNotification(NotificationType.CodepointsReceived, amount); CurrentSave.Codepoints += amount; diff --git a/ShiftOS_TheReturn/ServerManager.cs b/ShiftOS_TheReturn/ServerManager.cs index 3059391..a121ab6 100644 --- a/ShiftOS_TheReturn/ServerManager.cs +++ b/ShiftOS_TheReturn/ServerManager.cs @@ -126,6 +126,13 @@ namespace ShiftOS.Engine thisGuid = new Guid(msg.Contents); GUIDReceived?.Invoke(msg.Contents); } + else if(msg.Name == "allusers") + { + foreach(var acc in JsonConvert.DeserializeObject(msg.Contents)) + { + Console.WriteLine(acc); + } + } else if(msg.Name == "update_your_cp") { var args = JsonConvert.DeserializeObject>(msg.Contents); diff --git a/ShiftOS_TheReturn/ShiftOS.Engine.csproj b/ShiftOS_TheReturn/ShiftOS.Engine.csproj index 3702b18..20ca879 100644 --- a/ShiftOS_TheReturn/ShiftOS.Engine.csproj +++ b/ShiftOS_TheReturn/ShiftOS.Engine.csproj @@ -107,6 +107,7 @@ + diff --git a/ShiftOS_TheReturn/Shiftorium.cs b/ShiftOS_TheReturn/Shiftorium.cs index 198dcc7..0bdd9f4 100644 --- a/ShiftOS_TheReturn/Shiftorium.cs +++ b/ShiftOS_TheReturn/Shiftorium.cs @@ -210,9 +210,12 @@ namespace ShiftOS.Engine if (SaveSystem.CurrentSave.StoriesExperienced == null) SaveSystem.CurrentSave.StoriesExperienced = new List(); - if (!SaveSystem.CurrentSave.StoriesExperienced.Contains(id)) - return SaveSystem.CurrentSave.Upgrades[id]; + bool upgInstalled = false; + if(SaveSystem.CurrentSave.Upgrades.ContainsKey(id)) + upgInstalled = SaveSystem.CurrentSave.Upgrades[id]; + if(upgInstalled == false) + return SaveSystem.CurrentSave.StoriesExperienced.Contains(id); return true; } catch diff --git a/ShiftOS_TheReturn/TerminalBackend.cs b/ShiftOS_TheReturn/TerminalBackend.cs index 3c8e62a..8be54d0 100644 --- a/ShiftOS_TheReturn/TerminalBackend.cs +++ b/ShiftOS_TheReturn/TerminalBackend.cs @@ -139,121 +139,129 @@ namespace ShiftOS.Engine { if (Shiftorium.UpgradeAttributesUnlocked(type)) { - foreach (var a in type.GetCustomAttributes(false)) + if (KernelWatchdog.IsSafe(type)) { - if (a is Namespace) + foreach (var a in type.GetCustomAttributes(false)) { - var ns = a as Namespace; - if (text.Split('.')[0] == ns.name) + if (a is Namespace) { - foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) + var ns = a as Namespace; + if (text.Split('.')[0] == ns.name) { - if (Shiftorium.UpgradeAttributesUnlocked(method)) + foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) { - if (CanRunRemotely(method, isRemote)) + if (Shiftorium.UpgradeAttributesUnlocked(method)) { - foreach (var ma in method.GetCustomAttributes(false)) + if (KernelWatchdog.IsSafe(method)) { - if (ma is Command) + if (CanRunRemotely(method, isRemote)) { - var cmd = ma as Command; - if (text.Split('.')[1] == cmd.name) + foreach (var ma in method.GetCustomAttributes(false)) { - - var attr = method.GetCustomAttribute(); - - if (attr != null) + if (ma is Command) { - string newcommand = attr.newcommand; - if (attr.warn) + var cmd = ma as Command; + if (text.Split('.')[1] == cmd.name) { - Console.WriteLine(Localization.Parse((newcommand == "" ? "{ERROR}" : "{WARN}") + attr.reason, new Dictionary() { + + 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); - } - } + } + if (newcommand != "") + { + // redo the entire process running newcommand - var requiresArgs = method.GetCustomAttributes(); + return RunClient(newcommand, args); + } + } - bool error = false; - bool providedusage = false; + var requiresArgs = method.GetCustomAttributes(); - foreach (RequiresArgument argument in requiresArgs) - { - if (!args.ContainsKey(argument.argument)) - { + bool error = false; + bool providedusage = false; - if (!providedusage) + foreach (RequiresArgument argument in requiresArgs) { - string usageparse = "{COMMAND_" + ns.name.ToUpper() + "_" + cmd.name.ToUpper() + "_USAGE}"; - if (usageparse == Localization.Parse(usageparse)) - usageparse = ""; - else - usageparse = Shiftorium.UpgradeInstalled("help_usage") ? Localization.Parse("{ERROR}{USAGE}" + usageparse, new Dictionary() { + 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); + Console.WriteLine(usageparse); - providedusage = true; - } + providedusage = true; + } - if (Shiftorium.UpgradeInstalled("help_usage")) - { - Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED}", new Dictionary() { + 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; + } } - else + + if (error) { - Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED_NO_USAGE}")); + throw new Exception("{ERROR_COMMAND_WRONG}"); } - error = true; + try + { + return (bool)method.Invoke(null, new[] { args }); + } + catch (TargetInvocationException e) + { + Console.WriteLine(Localization.Parse("{ERROR_EXCEPTION_THROWN_IN_METHOD}")); + Console.WriteLine(e.InnerException.Message); + Console.WriteLine(e.InnerException.StackTrace); + return true; + } + catch + { + return (bool)method.Invoke(null, new object[] { }); + } } } - - if (error) - { - throw new Exception("{ERROR_COMMAND_WRONG}"); - } - - try - { - return (bool)method.Invoke(null, new[] { args }); - } - catch (TargetInvocationException e) - { - Console.WriteLine(Localization.Parse("{ERROR_EXCEPTION_THROWN_IN_METHOD}")); - Console.WriteLine(e.InnerException.Message); - Console.WriteLine(e.InnerException.StackTrace); - return true; - } - catch - { - return (bool)method.Invoke(null, new object[] { }); - } } } + else + { + Console.WriteLine(text + " cannot be ran in a remote session"); + return true; + } } - } - else - { - Console.WriteLine(text + " cannot be ran in a remote session"); - return true; + } } } } } } + } } } -- cgit v1.2.3 From f43f6fe17d054f83c686b552201d6b4bfc83524d Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 3 Apr 2017 18:36:13 -0400 Subject: LOADS of optimizations and Pong fixes. --- ShiftOS.Objects/ShiftOS.Objects.csproj | 1 - ShiftOS.Objects/ShiftOSMenuRenderer.cs | 51 ------- ShiftOS.WinForms/Applications/Pong.Designer.cs | 177 +++++++++++++------------ ShiftOS.WinForms/Applications/Pong.cs | 36 ++++- ShiftOS.WinForms/Oobe.cs | 30 ++++- ShiftOS.WinForms/Tools/ControlManager.cs | 107 +++------------ ShiftOS.WinForms/WinformsDesktop.cs | 13 +- ShiftOS.WinForms/WinformsWindowManager.cs | 17 +-- ShiftOS_TheReturn/Shiftorium.cs | 28 +++- 9 files changed, 217 insertions(+), 243 deletions(-) delete mode 100644 ShiftOS.Objects/ShiftOSMenuRenderer.cs (limited to 'ShiftOS_TheReturn/Shiftorium.cs') diff --git a/ShiftOS.Objects/ShiftOS.Objects.csproj b/ShiftOS.Objects/ShiftOS.Objects.csproj index 3dc0c33..4514b68 100644 --- a/ShiftOS.Objects/ShiftOS.Objects.csproj +++ b/ShiftOS.Objects/ShiftOS.Objects.csproj @@ -54,7 +54,6 @@ - diff --git a/ShiftOS.Objects/ShiftOSMenuRenderer.cs b/ShiftOS.Objects/ShiftOSMenuRenderer.cs deleted file mode 100644 index c76bd35..0000000 --- a/ShiftOS.Objects/ShiftOSMenuRenderer.cs +++ /dev/null @@ -1,51 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 Michael VanOverbeek and ShiftOS devs - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace ShiftOS.Objects -{ - class ShiftOSMenuRenderer : ToolStripProfessionalRenderer - { - public ShiftOSMenuRenderer() : base(new ShiftOSColorTable()) - { - - } - - protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e) - { - - } - } - - public class ShiftOSColorTable : ProfessionalColorTable - { - - } -} diff --git a/ShiftOS.WinForms/Applications/Pong.Designer.cs b/ShiftOS.WinForms/Applications/Pong.Designer.cs index faaf0f5..e619eaa 100644 --- a/ShiftOS.WinForms/Applications/Pong.Designer.cs +++ b/ShiftOS.WinForms/Applications/Pong.Designer.cs @@ -79,6 +79,11 @@ namespace ShiftOS.WinForms.Applications this.tmrcountdown = new System.Windows.Forms.Timer(this.components); this.tmrstoryline = new System.Windows.Forms.Timer(this.components); this.pgcontents = new ShiftOS.WinForms.Controls.Canvas(); + this.pnlhighscore = new System.Windows.Forms.Panel(); + this.lbhighscore = new System.Windows.Forms.ListBox(); + this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + this.button2 = new System.Windows.Forms.Button(); + this.label10 = new System.Windows.Forms.Label(); this.pnlgamestats = new System.Windows.Forms.Panel(); this.button1 = new System.Windows.Forms.Button(); this.label12 = new System.Windows.Forms.Label(); @@ -91,9 +96,6 @@ namespace ShiftOS.WinForms.Applications this.btncashout = new System.Windows.Forms.Button(); this.Label2 = new System.Windows.Forms.Label(); this.lbllevelreached = new System.Windows.Forms.Label(); - this.pnlhighscore = new System.Windows.Forms.Panel(); - this.lbhighscore = new System.Windows.Forms.ListBox(); - this.label10 = new System.Windows.Forms.Label(); this.pnlfinalstats = new System.Windows.Forms.Panel(); this.btnplayagain = new System.Windows.Forms.Button(); this.lblfinalcodepoints = new System.Windows.Forms.Label(); @@ -122,16 +124,14 @@ namespace ShiftOS.WinForms.Applications this.lblstatscodepoints = new System.Windows.Forms.Label(); this.lblstatsY = new System.Windows.Forms.Label(); this.lblstatsX = new System.Windows.Forms.Label(); - this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); - this.button2 = new System.Windows.Forms.Button(); this.pgcontents.SuspendLayout(); - this.pnlgamestats.SuspendLayout(); this.pnlhighscore.SuspendLayout(); + this.flowLayoutPanel1.SuspendLayout(); + this.pnlgamestats.SuspendLayout(); this.pnlfinalstats.SuspendLayout(); this.pnllose.SuspendLayout(); this.pnlintro.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.paddleHuman)).BeginInit(); - this.flowLayoutPanel1.SuspendLayout(); this.SuspendLayout(); // // gameTimer @@ -174,11 +174,67 @@ namespace ShiftOS.WinForms.Applications this.pgcontents.Dock = System.Windows.Forms.DockStyle.Fill; this.pgcontents.Location = new System.Drawing.Point(0, 0); this.pgcontents.Name = "pgcontents"; - this.pgcontents.Size = new System.Drawing.Size(700, 400); + this.pgcontents.Size = new System.Drawing.Size(1867, 819); this.pgcontents.TabIndex = 20; this.pgcontents.Paint += new System.Windows.Forms.PaintEventHandler(this.pgcontents_Paint); this.pgcontents.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pongMain_MouseMove); // + // pnlhighscore + // + this.pnlhighscore.Controls.Add(this.lbhighscore); + this.pnlhighscore.Controls.Add(this.flowLayoutPanel1); + this.pnlhighscore.Controls.Add(this.label10); + this.pnlhighscore.Location = new System.Drawing.Point(688, 302); + this.pnlhighscore.Name = "pnlhighscore"; + this.pnlhighscore.Size = new System.Drawing.Size(539, 311); + this.pnlhighscore.TabIndex = 14; + this.pnlhighscore.Visible = false; + // + // lbhighscore + // + this.lbhighscore.Dock = System.Windows.Forms.DockStyle.Fill; + this.lbhighscore.FormattingEnabled = true; + this.lbhighscore.Location = new System.Drawing.Point(0, 36); + this.lbhighscore.MultiColumn = true; + this.lbhighscore.Name = "lbhighscore"; + this.lbhighscore.SelectionMode = System.Windows.Forms.SelectionMode.None; + this.lbhighscore.Size = new System.Drawing.Size(539, 246); + this.lbhighscore.TabIndex = 1; + // + // flowLayoutPanel1 + // + this.flowLayoutPanel1.AutoSize = true; + this.flowLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.flowLayoutPanel1.Controls.Add(this.button2); + this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Bottom; + this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft; + this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 282); + this.flowLayoutPanel1.Name = "flowLayoutPanel1"; + this.flowLayoutPanel1.Size = new System.Drawing.Size(539, 29); + this.flowLayoutPanel1.TabIndex = 2; + // + // button2 + // + this.button2.AutoSize = true; + this.button2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.button2.Location = new System.Drawing.Point(476, 3); + this.button2.Name = "button2"; + this.button2.Size = new System.Drawing.Size(60, 23); + this.button2.TabIndex = 0; + this.button2.Text = "{CLOSE}"; + this.button2.UseVisualStyleBackColor = true; + this.button2.Click += new System.EventHandler(this.button2_Click); + // + // label10 + // + this.label10.Dock = System.Windows.Forms.DockStyle.Top; + this.label10.Location = new System.Drawing.Point(0, 0); + this.label10.Name = "label10"; + this.label10.Size = new System.Drawing.Size(539, 36); + this.label10.TabIndex = 0; + this.label10.Text = "{HIGH_SCORES}"; + this.label10.TextAlign = System.Drawing.ContentAlignment.TopCenter; + // // pnlgamestats // this.pnlgamestats.Controls.Add(this.button1); @@ -192,7 +248,7 @@ namespace ShiftOS.WinForms.Applications this.pnlgamestats.Controls.Add(this.btncashout); this.pnlgamestats.Controls.Add(this.Label2); this.pnlgamestats.Controls.Add(this.lbllevelreached); - this.pnlgamestats.Location = new System.Drawing.Point(56, 76); + this.pnlgamestats.Location = new System.Drawing.Point(104, 375); this.pnlgamestats.Name = "pnlgamestats"; this.pnlgamestats.Size = new System.Drawing.Size(466, 284); this.pnlgamestats.TabIndex = 6; @@ -307,38 +363,6 @@ namespace ShiftOS.WinForms.Applications this.lbllevelreached.TabIndex = 0; this.lbllevelreached.Text = "You Reached Level 2!"; // - // pnlhighscore - // - this.pnlhighscore.Controls.Add(this.lbhighscore); - this.pnlhighscore.Controls.Add(this.flowLayoutPanel1); - this.pnlhighscore.Controls.Add(this.label10); - this.pnlhighscore.Location = new System.Drawing.Point(67, 29); - this.pnlhighscore.Name = "pnlhighscore"; - this.pnlhighscore.Size = new System.Drawing.Size(539, 311); - this.pnlhighscore.TabIndex = 14; - this.pnlhighscore.Visible = false; - // - // lbhighscore - // - this.lbhighscore.Dock = System.Windows.Forms.DockStyle.Fill; - this.lbhighscore.FormattingEnabled = true; - this.lbhighscore.Location = new System.Drawing.Point(0, 36); - this.lbhighscore.MultiColumn = true; - this.lbhighscore.Name = "lbhighscore"; - this.lbhighscore.SelectionMode = System.Windows.Forms.SelectionMode.None; - this.lbhighscore.Size = new System.Drawing.Size(539, 246); - this.lbhighscore.TabIndex = 1; - // - // label10 - // - this.label10.Dock = System.Windows.Forms.DockStyle.Top; - this.label10.Location = new System.Drawing.Point(0, 0); - this.label10.Name = "label10"; - this.label10.Size = new System.Drawing.Size(539, 36); - this.label10.TabIndex = 0; - this.label10.Text = "{HIGH_SCORES}"; - this.label10.TextAlign = System.Drawing.ContentAlignment.TopCenter; - // // pnlfinalstats // this.pnlfinalstats.Controls.Add(this.btnplayagain); @@ -373,6 +397,7 @@ namespace ShiftOS.WinForms.Applications this.lblfinalcodepoints.Name = "lblfinalcodepoints"; this.lblfinalcodepoints.Size = new System.Drawing.Size(356, 73); this.lblfinalcodepoints.TabIndex = 15; + this.lblfinalcodepoints.Tag = "header1"; this.lblfinalcodepoints.Text = "134 CP"; this.lblfinalcodepoints.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // @@ -384,6 +409,7 @@ namespace ShiftOS.WinForms.Applications this.Label11.Name = "Label11"; this.Label11.Size = new System.Drawing.Size(33, 33); this.Label11.TabIndex = 14; + this.Label11.Tag = "header2"; this.Label11.Text = "+"; this.Label11.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // @@ -394,6 +420,7 @@ namespace ShiftOS.WinForms.Applications this.lblfinalcomputerreward.Name = "lblfinalcomputerreward"; this.lblfinalcomputerreward.Size = new System.Drawing.Size(151, 52); this.lblfinalcomputerreward.TabIndex = 12; + this.lblfinalcomputerreward.Tag = "header2"; this.lblfinalcomputerreward.Text = "34"; this.lblfinalcomputerreward.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // @@ -413,6 +440,7 @@ namespace ShiftOS.WinForms.Applications this.lblfinallevelreward.Name = "lblfinallevelreward"; this.lblfinallevelreward.Size = new System.Drawing.Size(151, 52); this.lblfinallevelreward.TabIndex = 10; + this.lblfinallevelreward.Tag = "header2"; this.lblfinallevelreward.Text = "100"; this.lblfinallevelreward.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // @@ -432,6 +460,7 @@ namespace ShiftOS.WinForms.Applications this.lblfinalcodepointswithtext.Name = "lblfinalcodepointswithtext"; this.lblfinalcodepointswithtext.Size = new System.Drawing.Size(356, 26); this.lblfinalcodepointswithtext.TabIndex = 1; + this.lblfinalcodepointswithtext.Tag = "header2"; this.lblfinalcodepointswithtext.Text = "You cashed out with 134 codepoints!"; this.lblfinalcodepointswithtext.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // @@ -502,10 +531,11 @@ namespace ShiftOS.WinForms.Applications this.pnlintro.Controls.Add(this.Label6); this.pnlintro.Controls.Add(this.btnstartgame); this.pnlintro.Controls.Add(this.Label8); - this.pnlintro.Location = new System.Drawing.Point(52, 29); + this.pnlintro.Location = new System.Drawing.Point(1139, 41); this.pnlintro.Name = "pnlintro"; this.pnlintro.Size = new System.Drawing.Size(595, 303); this.pnlintro.TabIndex = 13; + this.pnlintro.Tag = "header2"; // // Label6 // @@ -548,6 +578,7 @@ namespace ShiftOS.WinForms.Applications this.lblbeatai.Name = "lblbeatai"; this.lblbeatai.Size = new System.Drawing.Size(600, 30); this.lblbeatai.TabIndex = 8; + this.lblbeatai.Tag = "header2"; this.lblbeatai.Text = "You got 2 codepoints for beating the Computer!"; this.lblbeatai.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; this.lblbeatai.Visible = false; @@ -577,7 +608,6 @@ namespace ShiftOS.WinForms.Applications // this.paddleHuman.BackColor = System.Drawing.Color.Black; this.paddleHuman.Location = new System.Drawing.Point(10, 134); - this.paddleComputer.MaximumSize = new System.Drawing.Size(20, 150); this.paddleHuman.Name = "paddleHuman"; this.paddleHuman.Size = new System.Drawing.Size(20, 100); this.paddleHuman.TabIndex = 3; @@ -587,7 +617,7 @@ namespace ShiftOS.WinForms.Applications // this.paddleComputer.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.paddleComputer.BackColor = System.Drawing.Color.Black; - this.paddleComputer.Location = new System.Drawing.Point(666, 134); + this.paddleComputer.Location = new System.Drawing.Point(1833, 134); this.paddleComputer.MaximumSize = new System.Drawing.Size(20, 150); this.paddleComputer.Name = "paddleComputer"; this.paddleComputer.Size = new System.Drawing.Size(20, 100); @@ -599,69 +629,52 @@ namespace ShiftOS.WinForms.Applications this.lbllevelandtime.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.lbllevelandtime.Location = new System.Drawing.Point(0, 0); this.lbllevelandtime.Name = "lbllevelandtime"; - this.lbllevelandtime.Size = new System.Drawing.Size(700, 22); + this.lbllevelandtime.Size = new System.Drawing.Size(1867, 22); this.lbllevelandtime.TabIndex = 4; + this.lbllevelandtime.Tag = "header1"; this.lbllevelandtime.Text = "Level: 1 - 58 Seconds Left"; this.lbllevelandtime.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // // lblstatscodepoints // - this.lblstatscodepoints.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + this.lblstatscodepoints.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); + this.lblstatscodepoints.AutoSize = true; this.lblstatscodepoints.Font = new System.Drawing.Font("Georgia", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblstatscodepoints.Location = new System.Drawing.Point(239, 356); + this.lblstatscodepoints.Location = new System.Drawing.Point(239, 775); this.lblstatscodepoints.Name = "lblstatscodepoints"; - this.lblstatscodepoints.Size = new System.Drawing.Size(219, 35); + this.lblstatscodepoints.Size = new System.Drawing.Size(116, 23); this.lblstatscodepoints.TabIndex = 12; + this.lblstatscodepoints.Tag = "header2"; this.lblstatscodepoints.Text = "Codepoints: "; this.lblstatscodepoints.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // // lblstatsY // this.lblstatsY.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.lblstatsY.AutoSize = true; this.lblstatsY.Font = new System.Drawing.Font("Georgia", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblstatsY.Location = new System.Drawing.Point(542, 356); + this.lblstatsY.Location = new System.Drawing.Point(1395, 775); this.lblstatsY.Name = "lblstatsY"; - this.lblstatsY.Size = new System.Drawing.Size(144, 35); + this.lblstatsY.Size = new System.Drawing.Size(76, 23); this.lblstatsY.TabIndex = 11; + this.lblstatsY.Tag = "header2"; this.lblstatsY.Text = "Yspeed:"; this.lblstatsY.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // // lblstatsX // this.lblstatsX.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.lblstatsX.AutoSize = true; this.lblstatsX.Font = new System.Drawing.Font("Georgia", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblstatsX.Location = new System.Drawing.Point(3, 356); + this.lblstatsX.Location = new System.Drawing.Point(3, 775); this.lblstatsX.Name = "lblstatsX"; - this.lblstatsX.Size = new System.Drawing.Size(144, 35); + this.lblstatsX.Size = new System.Drawing.Size(83, 23); this.lblstatsX.TabIndex = 5; + this.lblstatsX.Tag = "header2"; this.lblstatsX.Text = "Xspeed: "; this.lblstatsX.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // - // flowLayoutPanel1 - // - this.flowLayoutPanel1.AutoSize = true; - this.flowLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.flowLayoutPanel1.Controls.Add(this.button2); - this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Bottom; - this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft; - this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 282); - this.flowLayoutPanel1.Name = "flowLayoutPanel1"; - this.flowLayoutPanel1.Size = new System.Drawing.Size(539, 29); - this.flowLayoutPanel1.TabIndex = 2; - // - // button2 - // - this.button2.AutoSize = true; - this.button2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.button2.Location = new System.Drawing.Point(476, 3); - this.button2.Name = "button2"; - this.button2.Size = new System.Drawing.Size(60, 23); - this.button2.TabIndex = 0; - this.button2.Text = "{CLOSE}"; - this.button2.UseVisualStyleBackColor = true; - this.button2.Click += new System.EventHandler(this.button2_Click); - // // Pong // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -670,23 +683,23 @@ namespace ShiftOS.WinForms.Applications this.Controls.Add(this.pgcontents); this.DoubleBuffered = true; this.Name = "Pong"; - this.Text = "{PONG_NAME}"; - this.Size = new System.Drawing.Size(820, 500); + this.Size = new System.Drawing.Size(1867, 819); this.Load += new System.EventHandler(this.Pong_Load); this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pongMain_MouseMove); this.pgcontents.ResumeLayout(false); - this.pnlgamestats.ResumeLayout(false); - this.pnlgamestats.PerformLayout(); + this.pgcontents.PerformLayout(); this.pnlhighscore.ResumeLayout(false); this.pnlhighscore.PerformLayout(); + this.flowLayoutPanel1.ResumeLayout(false); + this.flowLayoutPanel1.PerformLayout(); + this.pnlgamestats.ResumeLayout(false); + this.pnlgamestats.PerformLayout(); this.pnlfinalstats.ResumeLayout(false); this.pnlfinalstats.PerformLayout(); this.pnllose.ResumeLayout(false); this.pnlintro.ResumeLayout(false); this.pnlintro.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.paddleHuman)).EndInit(); - this.flowLayoutPanel1.ResumeLayout(false); - this.flowLayoutPanel1.PerformLayout(); this.ResumeLayout(false); } diff --git a/ShiftOS.WinForms/Applications/Pong.cs b/ShiftOS.WinForms/Applications/Pong.cs index 157ce8c..a7b1aeb 100644 --- a/ShiftOS.WinForms/Applications/Pong.cs +++ b/ShiftOS.WinForms/Applications/Pong.cs @@ -34,6 +34,7 @@ using System.Windows.Forms; using Newtonsoft.Json; using ShiftOS.Engine; using ShiftOS.Objects; +using ShiftOS.WinForms.Tools; namespace ShiftOS.WinForms.Applications { @@ -83,6 +84,26 @@ namespace ShiftOS.WinForms.Applications paddleHuman.Location = new Point(paddleHuman.Location.X, (loc.Y) - (paddleHuman.Height / 2)); } + private void CenterPanels() + { + pnlfinalstats.CenterParent(); + pnlgamestats.CenterParent(); + pnlhighscore.CenterParent(); + pnlintro.CenterParent(); + pnllose.CenterParent(); + lblcountdown.CenterParent(); + lblbeatai.Left = (this.Width - lblbeatai.Width) / 2; + SetupStats(); + } + + public void SetupStats() + { + lblstatsX.Location = new Point(5, this.Height - lblstatsX.Height - 5); + lblstatsY.Location = new Point(this.Width - lblstatsY.Width - 5, this.Height - lblstatsY.Height - 5); + lblstatscodepoints.Top = this.Height - lblstatscodepoints.Height - 5; + lblstatscodepoints.Left = (this.Width - lblstatscodepoints.Width) / 2; + } + // ERROR: Handles clauses are not supported in C# private void gameTimer_Tick(object sender, EventArgs e) @@ -102,7 +123,7 @@ namespace ShiftOS.WinForms.Applications //Set the computer player to move according to the ball's position. if (aiShouldIsbeEnabled) - if (ball.Location.X > 500 - xVel * 10 && xVel > 0) + if (ball.Location.X > (this.Width - (this.Width / 3)) - xVel * 10 && xVel > 0) { if (ball.Location.Y > paddleComputer.Location.Y + 50) { @@ -116,12 +137,12 @@ namespace ShiftOS.WinForms.Applications } else { - //used to be me.location.y + //used to be me.location.y - except it's fucking C# and this comment is misleading as fuck. OH WAIT! I didn't write it! And none of the current devs did either! - Michael if (paddleComputer.Location.Y > this.Size.Height / 2 - paddleComputer.Height + casualposition) { paddleComputer.Location = new Point(paddleComputer.Location.X, paddleComputer.Location.Y - computerspeed); } - //used to be me.location.y + //Rylan is hot. Used to be //used to be me.location.y if (paddleComputer.Location.Y < this.Size.Height / 2 - paddleComputer.Height + casualposition) { paddleComputer.Location = new Point(paddleComputer.Location.X, paddleComputer.Location.Y + computerspeed); @@ -269,6 +290,7 @@ namespace ShiftOS.WinForms.Applications } lblstatscodepoints.Text = Localization.Parse("{CODEPOINTS}: ") + (levelrewards[level - 1] + beatairewardtotal).ToString(); } + SetupStats(); } public void SendHighscores() @@ -652,10 +674,17 @@ namespace ShiftOS.WinForms.Applications pnlhighscore.Hide(); pnlgamestats.Hide(); pnlfinalstats.Hide(); + CenterPanels(); + lblbeatai.Hide(); } public void OnSkinLoad() { + CenterPanels(); + this.SizeChanged += (o, a) => + { + CenterPanels(); + }; } public bool OnUnload() @@ -665,6 +694,7 @@ namespace ShiftOS.WinForms.Applications public void OnUpgrade() { + CenterPanels(); } private void button2_Click(object sender, EventArgs e) diff --git a/ShiftOS.WinForms/Oobe.cs b/ShiftOS.WinForms/Oobe.cs index 898f60b..d6d3b92 100644 --- a/ShiftOS.WinForms/Oobe.cs +++ b/ShiftOS.WinForms/Oobe.cs @@ -64,7 +64,10 @@ namespace ShiftOS.WinForms { while(typing == true) { + //JESUS CHRIST PAST MICHAEL. + //We should PROBABLY block the thread... You know... not everyone has a 10-core processor. + Thread.Sleep(100); } charcount = texttotype.Length; @@ -452,6 +455,10 @@ namespace ShiftOS.WinForms TextType("Go ahead and type 'sos.help' to see a list of commands."); while (TutorialProgress == 0) { + //JESUS CHRIST PAST MICHAEL. + + //We should PROBABLY block the thread... You know... not everyone has a 10-core processor. + Thread.Sleep(100); } TextType("As you can see, sos.help gives you a list of all commands in the system."); @@ -461,6 +468,10 @@ namespace ShiftOS.WinForms TextType("Go ahead and run the 'status' command within the 'sos' namespace to see what the command does."); while (TutorialProgress == 1) { + //JESUS CHRIST PAST MICHAEL. + + //We should PROBABLY block the thread... You know... not everyone has a 10-core processor. + Thread.Sleep(100); } TextType("Brilliant. The sos.status command will tell you how many Codepoints you have, as well as how many upgrades you have installed and how many are available."); @@ -478,6 +489,10 @@ namespace ShiftOS.WinForms TextType("To start using the Shiftorium, simply type 'shiftorium.list' to see available upgrades."); while (TutorialProgress == 2) { + //JESUS CHRIST PAST MICHAEL. + + //We should PROBABLY block the thread... You know... not everyone has a 10-core processor. + Thread.Sleep(100); } Clear(); @@ -502,13 +517,21 @@ namespace ShiftOS.WinForms TextType("shiftorium.info requires an upgrade argument, which is a string type. Go ahead and give shiftorium.info's upgrade argument the 'mud_fundamentals' upgrade's ID."); while (TutorialProgress == 3) { + //JESUS CHRIST PAST MICHAEL. + + //We should PROBABLY block the thread... You know... not everyone has a 10-core processor. + Thread.Sleep(100); } TextType("As you can see, mud_fundamentals is very useful. In fact, a lot of useful upgrades depend on it. You should buy it!"); Thread.Sleep(500); TextType("shiftorium.info already gave you a command that will let you buy the upgrade - go ahead and run that command!"); while (!Shiftorium.UpgradeInstalled("mud_fundamentals")) - { + { //JESUS CHRIST PAST MICHAEL. + + //We should PROBABLY block the thread... You know... not everyone has a 10-core processor. + Thread.Sleep(100); + } TextType("Hooray! You now have the MUD Fundamentals upgrade."); @@ -520,6 +543,10 @@ namespace ShiftOS.WinForms TextType("Just run win.open without arguments, and this tutorial will be completed!"); while (TutorialProgress == 4) { + //JESUS CHRIST PAST MICHAEL. + + //We should PROBABLY block the thread... You know... not everyone has a 10-core processor. + Thread.Sleep(100); } TextType("This concludes the ShiftOS beginners' guide brought to you by the multi-user domain. Stay safe in a connected world."); @@ -528,6 +555,7 @@ namespace ShiftOS.WinForms { OnComplete?.Invoke(this, EventArgs.Empty); SaveSystem.CurrentSave.StoryPosition = 2; + this.Close(); SaveSystem.SaveGame(); AppearanceManager.SetupWindow(new Applications.Terminal()); }); diff --git a/ShiftOS.WinForms/Tools/ControlManager.cs b/ShiftOS.WinForms/Tools/ControlManager.cs index 52663d7..a2a76b7 100644 --- a/ShiftOS.WinForms/Tools/ControlManager.cs +++ b/ShiftOS.WinForms/Tools/ControlManager.cs @@ -67,91 +67,6 @@ namespace ShiftOS.WinForms.Tools } - public static void SetupWindows() - { - if (SaveSystem.CurrentSave != null) - { - int screen_height_start = 0; - if (Shiftorium.UpgradeInstalled("wm_free_placement")) - { - } - else if (Shiftorium.UpgradeInstalled("wm_4_windows")) - { - int screen_width_half = Screen.PrimaryScreen.Bounds.Width / 2; - int screen_height_half = (Screen.PrimaryScreen.Bounds.Height - screen_height_start) / 2; - - for (int i = 0; i < OpenForms.Count; i++) - { - var frm = OpenForms[i] as WindowBorder; - - switch (i) - { - case 0: - frm.Location = new System.Drawing.Point(0, screen_height_start); - frm.Size = new System.Drawing.Size((OpenForms.Count > 1) ? screen_width_half : screen_width_half * 2, (OpenForms.Count > 2) ? screen_height_half : screen_height_half * 2); - - break; - case 1: - frm.Location = new System.Drawing.Point(screen_width_half, screen_height_start); - frm.Size = new System.Drawing.Size(screen_width_half, (OpenForms.Count > 2) ? screen_height_half : screen_height_half * 2); - break; - case 2: - frm.Location = new System.Drawing.Point(0, screen_height_half + screen_height_start); - frm.Size = new System.Drawing.Size((OpenForms.Count > 3) ? screen_width_half : screen_width_half * 2, screen_height_half); - break; - case 3: - frm.Location = new System.Drawing.Point(screen_width_half, screen_height_half + screen_height_start); - frm.Size = new System.Drawing.Size(screen_width_half, (OpenForms.Count > 2) ? screen_height_half : screen_height_half * 2); - break; - } - } - - } - else if (Shiftorium.UpgradeInstalled("window_manager")) - { - int screen_width_half = Screen.PrimaryScreen.Bounds.Width / 2; - int screen_height = (Screen.PrimaryScreen.Bounds.Height) - screen_height_start; - - - - for (int i = 0; i < OpenForms.Count; i++) - { - - - var frm = OpenForms[i] as WindowBorder; - switch (i) - { - case 0: - frm.Location = new System.Drawing.Point(0, screen_height_start); - frm.Size = new System.Drawing.Size((OpenForms.Count > 1) ? screen_width_half : screen_width_half * 2, screen_height); - break; - case 1: - frm.Location = new System.Drawing.Point(screen_width_half, screen_height_start); - frm.Size = new System.Drawing.Size(screen_width_half, screen_height); - break; - } - OpenForms[i] = frm; - } - } - else - { - var frm = OpenForms[0] as WindowBorder; - frm.Location = new Point(0, 0); - frm.Size = Desktop.Size; - OpenForms[0] = frm; - - } - } - else - { - var frm = OpenForms[0] as WindowBorder; - frm.Location = new Point(0, 0); - frm.Size = Desktop.Size; - OpenForms[0] = frm; - - } - } - internal static Color ConvertColor(ConsoleColor cCol) { switch (cCol) @@ -214,9 +129,22 @@ namespace ShiftOS.WinForms.Tools #endif } + /// + /// Centers the control along its parent. + /// + /// The control to center (this is an extension method - you can call it on a control as though it was a method in that control) + public static void CenterParent(this Control ctrl) + { + ctrl.Location = new Point( + (ctrl.Parent.Width - ctrl.Width) / 2, + (ctrl.Parent.Height - ctrl.Height) / 2 + ); + } + public static void SetupControl(Control ctrl) { SuspendDrawing(ctrl); + ctrl.SuspendLayout(); SetCursor(ctrl); if (!(ctrl is MenuStrip) && !(ctrl is ToolStrip) && !(ctrl is StatusStrip) && !(ctrl is ContextMenuStrip)) { @@ -270,13 +198,7 @@ namespace ShiftOS.WinForms.Tools a.SuppressKeyPress = true; - if (SaveSystem.CurrentSave != null) - { - if (Shiftorium.UpgradeInstalled("window_manager")) - { - Engine.AppearanceManager.SetupWindow(new Applications.Terminal()); - } - } + Engine.AppearanceManager.SetupWindow(new Applications.Terminal()); } ShiftOS.Engine.Scripting.LuaInterpreter.RaiseEvent("on_key_down", a); @@ -293,6 +215,7 @@ namespace ShiftOS.WinForms.Tools } MakeDoubleBuffered(ctrl); + ctrl.ResumeLayout(); ResumeDrawing(ctrl); } diff --git a/ShiftOS.WinForms/WinformsDesktop.cs b/ShiftOS.WinForms/WinformsDesktop.cs index 06f103e..033802e 100644 --- a/ShiftOS.WinForms/WinformsDesktop.cs +++ b/ShiftOS.WinForms/WinformsDesktop.cs @@ -664,10 +664,17 @@ namespace ShiftOS.WinForms /// Act. public void InvokeOnWorkerThread(Action act) { - this.Invoke(new Action(()=> + try { - act?.Invoke(); - })); + this.Invoke(new Action(() => + { + act?.Invoke(); + })); + } + catch + { + + } } public void OpenAppLauncher(Point loc) diff --git a/ShiftOS.WinForms/WinformsWindowManager.cs b/ShiftOS.WinForms/WinformsWindowManager.cs index 26438bf..cfcb6d3 100644 --- a/ShiftOS.WinForms/WinformsWindowManager.cs +++ b/ShiftOS.WinForms/WinformsWindowManager.cs @@ -184,20 +184,21 @@ namespace ShiftOS.WinForms if (maxWindows > 0) { - List formstoclose = new List(); - - for (int i = 0; i < maxWindows && i < AppearanceManager.OpenForms.Count; i++) + var windows = new List(); + foreach(var WB in AppearanceManager.OpenForms) { - var frm = AppearanceManager.OpenForms[i] as WindowBorder; - if(!frm.IsDialog) - formstoclose.Add(frm); - + if (WB is WindowBorder) + windows.Add(WB as WindowBorder); } + List formstoclose = new List(windows.Where(x => x.IsDialog == false).ToArray()); + while (formstoclose.Count > maxWindows - 1) { - formstoclose[0].Close(); + this.Close(formstoclose[0].ParentWindow); + AppearanceManager.OpenForms.Remove(formstoclose[0]); formstoclose.RemoveAt(0); + } } } diff --git a/ShiftOS_TheReturn/Shiftorium.cs b/ShiftOS_TheReturn/Shiftorium.cs index 0bdd9f4..4556cd6 100644 --- a/ShiftOS_TheReturn/Shiftorium.cs +++ b/ShiftOS_TheReturn/Shiftorium.cs @@ -46,6 +46,23 @@ namespace ShiftOS.Engine Installed?.Invoke(); } + public static string GetCategory(string id) + { + var upg = GetDefaults().FirstOrDefault(x => x.ID == id); + if (upg == null) + return "Other"; + return (upg.Category == null) ? "Other" : upg.Category; + } + + public static IEnumerable GetAllInCategory(string cat) + { + return GetDefaults().Where(x => x.Category == cat); + } + + public static bool IsCategoryEmptied(string cat) + { + return GetDefaults().Where(x => x.Category == cat).FirstOrDefault(x => x.Installed == false) == null; + } public static bool Buy(string id, int cost) { @@ -278,8 +295,15 @@ namespace ShiftOS.Engine 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 Id { get; set; } + public string Category { get; set; } + public bool Installed + { + get + { + return Shiftorium.UpgradeInstalled(ID); + } + } public string Dependencies { get; set; } } } -- cgit v1.2.3 From 9566b4b062ad0f10832584c65457ef6505b097ab Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 3 Apr 2017 19:28:35 -0400 Subject: Categorize the Shiftorium --- ShiftOS.WinForms/Resources/Shiftorium.txt | 154 ++++++++++++++++++++++++++++-- ShiftOS_TheReturn/Commands.cs | 57 ++++++++++- ShiftOS_TheReturn/Shiftorium.cs | 23 +++++ 3 files changed, 221 insertions(+), 13 deletions(-) (limited to 'ShiftOS_TheReturn/Shiftorium.cs') diff --git a/ShiftOS.WinForms/Resources/Shiftorium.txt b/ShiftOS.WinForms/Resources/Shiftorium.txt index 9b01be4..0c4e0c6 100644 --- a/ShiftOS.WinForms/Resources/Shiftorium.txt +++ b/ShiftOS.WinForms/Resources/Shiftorium.txt @@ -4,13 +4,15 @@ Name: "Screensavers", Cost: 750, Description: "Like to leave your PC idle for long periods of time? Save some energy and keep your screen from being tired by hiding the desktop behind a black screen with an image on it.", - Dependencies: "desktop" + Dependencies: "desktop", + Category: "Enhancements", }, { Name: "Shift Screensavers", Cost: 100, Description: "This Shifter upgrade will allow you to customize the screensaver.", - Dependencies: "screensavers;shifter" + Dependencies: "screensavers;shifter", + Category: "Customization" }, @@ -19,72 +21,84 @@ Name: "Calculator", Cost: 1000, Dependencies: "wm_free_placement;desktop", - Description: "Crazy math problems getting you down? Well, this calculator will take care of that!" + Description: "Crazy math problems getting you down? Well, this calculator will take care of that!", + Category: "Applications" }, { Name: "AL Calculator", Cost: 150, Dependencies: "calculator;app_launcher", - Description: "Add an App Launcher Entry for the Calculator!" + Description: "Add an App Launcher Entry for the Calculator!", + Category: "GUI", }, { Name: "Calc Equals Button", Cost: 600, Dependencies: "calculator", + Category: "Enhancements", Description: "Right now, you can only type numbers, but this equals button opens the door to solving equations!" }, { Name: "Calc Decimal Button", Cost: 600, Dependencies: "calculator", + Category: "Enhancements", Description: "Whole numbers can get boring. With this button, you can type decimal numbers!" }, { Name: "Calc Plus Button", Cost: 700, Dependencies: "calc_equals_button", + Category: "Enhancements", Description: "With this extra button, your calculator can now do addition problems!" }, { Name: "Calc Minus Button", Cost: 700, Dependencies: "calc_equals_button", + Category: "Enhancements", Description: "With this extra button, your calculator can now do subtraction problems!" }, { Name: "Calc Multiply Button", Cost: 800, Dependencies: "calc_plus_button", + Category: "Enhancements", Description: "You can add numbers together, but it must be tiring to add the same number over and over. This multiplication button will make it easier for you!" }, { Name: "Calc Divide Button", Cost: 800, Dependencies: "calc_multiply_button", + Category: "Enhancements", Description: "You can multiply, but what about reversing multiplication? This divide button will sort that out!" }, { Name: "Calc Clear Button", Cost: 750, Dependencies: "calc_equals_button", + Category: "Enhancements", Description: "Typed the wrong number? No worries! With this Clear button, you can clear the number field, without messing up the equation you're trying to solve!" }, { Name: "Calc CE Button", Cost: 750, Dependencies: "calc_clear_button", + Category: "Enhancements", Description: "Wanna start all over with a new equation? With this CE (Clear Everything) button, you get rid of not only the numbers in the number field, but also the equation!" }, { Name: "MUD Fundamentals", Cost: 50, Description: "Some basic commands for the terminal that'll help you out in the multi-user domain.", + Category: "Kernel & System", Dependencies: null }, { Name: "AL Notifications", Cost: 150, Dependencies: "app_launcher", + Category: "GUI", Description: "Want to open the Notifications application from within the App Launcher? This upgrade is for you." }, @@ -93,35 +107,41 @@ Name: "ShiftLetters", Cost: 150, Dependencies: null, + Category: "Applications", Description: "Sick and tired of playing Pong? Buy this upgrade to get a whole new game!" }, { Name: "AL ShiftLetters", Cost: 150, Dependencies: "app_launcher;shiftletters", + Category: "GUI", Description: "This upgrade allows you to find ShiftLetters in your App Launcher." }, { Name: "SL Contributors Wordlist", Cost: 250, Dependencies: "shiftletters", + Category: "Enhancements", Description: "This nice wordlist lets you find out the people who contributed to the development of ShiftOS!" }, { Name: "SL Operating Systems Wordlist", Cost: 500, Dependencies: "shiftletters", + Category: "Enhancements", Description: "Know a lot about computer operating systems? This upgrade adds a wordlist to ShiftLetters, full of various Linux distros, Windows codenames and other OS names. All for the low price of 500 Codepoints! It's an incredible value but it's true! Upgrade today... except out of ShiftOS!" }, { Name: "Panel Notifications", Cost: 150, Description: "It's good to know what time it is, but how about knowing how many notifications you have? After all, notifications are a great way to tell what's going on! This upgrade adds a button that displays how many notifications you have. If you click it, you will open the Notifications app!", + Category: "GUI", Dependencies: "desktop_clock_widget" }, { Name: "Audio Volume", Cost: 80, + Category: "Kernel & System", Description: "Want to adjust the volume of ShiftOS's audio? This upgrade will let you." }, @@ -130,12 +150,14 @@ Name: "ShiftLotto", Cost: 200, Dependencies: null, + Category: "Applications", Description: "Are you feeling lucky? Spend some money on this upgrade! If you have any left, go ahead and bet your money in ShiftLotto!" }, { Name: "AL ShiftLotto", Cost: 150, Dependencies: "app_launcher;shiftlotto", + Category: "GUI", Description: "This upgrade allows you to find ShiftLotto in your App Launcher." }, @@ -144,358 +166,418 @@ { Name: "Color Depth Dithering", Cost: 1000, + Category: "Device Drivers", Description: "Right now, if you try to display images on the screen, with a low color depth like we have, the image will be totally unrecognizable! With this upgrade, we can adapt a simple 1-dimensional dithering algorithm into the video driver to hopefully smooth out the transition between colors.", }, { Name: "Color Depth Floyd-Steinberg Dithering", Cost: 2000, Description: "So your images look... alright... with the new dithering algorithm, but let's take things even further and get rid of the jagged lines in the image using a 2-dimensional algorithm called the Floyd-Steinberg algorithm. It'll sure make things look better.", + Category: "Device Drivers", Dependencies: "color_depth_dithering" }, { Name: "Color Depth 2 bits", Cost: 2000, + Category: "Device Drivers", Description: "We can only display black and white - 0 or 1 in binary. Let's take it even further by adding an extra bit to our binary notation - making black, white, dark gray and light gray possible!", }, { Name: "Color Depth 4 bits", Cost: 4000, Description: "4 colors is nice - but let's take it even further. With our dithering algorithm in place, let's make our images even smoother by giving a 16-color palette to the video driver!", + Category: "Device Drivers", Dependencies: "color_depth_2_bits;color_depth_dithering" }, { Name: "Color Depth 6 bits", Cost: 6000, Description: "Let's extend our color range into the depths of 6 bits! This'll make up to 64 different shades of gray possible! We're getting even closer to modern-day color...", + Category: "Device Drivers", Dependencies: "color_depth_4_bits" }, { Name: "Color Depth 8 bits", Cost: 8000, Description: "What do you get when you bite your food? You get perhaps a yummy taste. What do you get when you take a byte of memory? 256 shades of gray, of course!", + Category: "Device Drivers", Dependencies: "color_depth_6_bits" }, { Name: "Color Depth 16 bits", Cost: 16000, Description: "If we were just given another byte... we could divide the two up into three channels and allow mixing and matching of the channels to create colors other than gray! Let's do it.", + Category: "Device Drivers", Dependencies: "color_depth_8_bits" }, { Name: "Color Depth 24 Bits", Cost: 24000, Description: "Having actual color is nice for our images as we can truly see detail in our images - but if we had a third byte, each channel could have up to 256 values - adding up to almost 17 million different colors! Our eyes can't even distinguish that many.", + Category: "Device Drivers", Dependencies: "color_depth_16_bits" }, { Name: "AL MUD Control Centre", Cost: 150, Dependencies: "mud_fundamentals;app_launcher", + Category: "Device Drivers", Description: "Want to access your MUD profile, legions, jobs and shops, but don't want to open your Terminal? This upgrade is for you!" }, { Name: "Kernel Coherence", Cost: 10000, Dependencies: "wm_free_placement", + Category: "Device Drivers", Description: "With the free placement upgrade, you can place windows of any size anywhere on the desktop, which means theoretically you could add kernel coherence between ShiftOS and another GUI-based operating system and run their applications inside ShiftOS. This upgrade unlocks that.", }, { Name: "Pong Increased Paddle Size", Cost: 1000, Dependencies: "pong_upgrade", + Category: "Enhancements", Description: "Having trouble keeping that darn ball in front of you? Well, with this upgrade, your paddle increases in height.... slightly.", }, { Name: "WM 4 Windows", Cost: 150, Description: "Display up to 4 simultaneous windows on-screen in a 2x2 grid.", + Category: "Enhancements", 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.", + Category: "Applications", Dependencies: "mud_fundamentals;file_skimmer" }, { Name: "AL Virus Scanner", Cost: 150, Description: "Add an App Launcher entry for the Virus Scanner.", + Category: "GUI", 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.", + Category: "GUI", Dependencies: "desktop;wm_unlimited_windows" }, { Name: "AL Skin Loader", Cost: 150, Description: "Buy this upgrade to add an entry for the Skin Loader to the App Launcher.", + Category: "GUI", Dependencies: "app_launcher;skinning" }, { Name: "Shift Panel Buttons", Cost: 150, Description: "Want to customize your panel buttons? This Shifter category is for you!", + Category: "Customization", Dependencies: "wm_panel_buttons" }, { Name: "TextPad Lua Support", Cost: 450, Description: "Use TextPad to write Lua scripts!", + Category: "Enhancements", Dependencies: "textpad;file_skimmer", }, { Name: "App Launcher", Cost: 7500, Description: "It may be expensive, but having an easy-access menu to all your apps is very valuable.", + Category: "GUI", Dependencies:"desktop;wm_unlimited_windows" }, - { - Name: "AL MUD Cracker", - Cost: 150, - Description: "Add a launcher item for the MUD cracker.", - Dependencies: "mud_cracker;app_launcher" - }, { Name: "Format Editor", Cost: 6000, Description: "Allows you to change the format of commands.", + Category: "Applications", Dependencies: "shifter;name_changer" }, { Name: "Format Editor Optional Text", Cost: 150, Description: "Allows you to add an optional text to commands", + Category: "Enhancements", Dependencies: "format_editor" }, { Name: "Format Editor Regex", Cost: 150, Description: "Allows you to customize your commands with regexes.", + Category: "Enhancements", Dependencies: "format_editor_optional_text" }, { Name: "Format Editor Syntax Highligting", Cost: 150, Description: "Allows you to give color to commands as the user types them.", + Category: "Enhancements", Dependencies: "format_editor_regex" }, { Name: "AL Format Editor", Cost: 150, Description: "Add a launcher item for the Format Editor.", + Category: "GUI", Dependencies: "format_editor;app_launcher" }, { Name: "Textpad", Cost: 2500, Description: "\"Write, save and open a text document.\"", + Category: "Applications", Dependencies: "file_skimmer" }, { Name: "Shifter", Cost: 10000, Description: "Tired of the green and black look that is ShiftOS's default skin? Use the Shifter to shift it your way.", + Category: "Applications", Dependencies: "desktop;wm_unlimited_windows", }, { Name: "Name Changer", Cost: 5000, Description: "Are you not a linux person and want the terminal to be called Command Prompt? Well this app is for you!", + Category: "Applications", Dependencies: "shifter", }, { Name: "AL Name Changer", Cost: 150, Description: "Launch the Name Changer from the app launcher.", + Category: "GUI", Dependencies: "name_changer", }, { Name: "AL Shifter", Cost: 150, Description: "Launch the Shifter from the app launcher.", + Category: "GUI", Dependencies: "app_launcher;shifter" }, { Name: "AL Pong", Cost: 150, Description: "Launch Pong from the app launcher.", + Category: "GUI", Dependencies: "app_launcher" }, { Name: "AL Textpad", Cost: 150, Description: "Write, save and open text documents from the App Launcher.", + Category: "GUI", Dependencies:"app_launcher;textpad" }, { Name: "AL File Skimmer", Cost: 150, Description: "Open the File Skimmer from your App Launcher.", + Category: "GUI", 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.", + Category: "Enhancements", Dependencies: "wm_4_windows" }, { Name: "Desktop", Cost: 9000, Description: "Use a fully customizable desktop in place of the terminal to control ShiftOS.", + Category: "GUI", Dependencies: "window_manager" }, { Name: "App Icons", Cost: 400, Description: "So you have a titlebar, well, let's add an icon to it to hopefully make it easier to tell which app is which.", + Category: "GUI", Dependencies: "wm_titlebar;skinning" }, { Name: "Close command", Cost: 150, Description: "Add a win.close script to allow you to close windows.", + Category: "Kernel & System", Dependencies: "mud_fundamentals", }, { Name: "WM Unlimited Windows", Cost: 5000, Description: "Break the limit of windows that can be run. Perfect for high-maintenance tasks.", + Category: "Enhancements", Dependencies: "wm_free_placement;close_command" }, { Name: "Minimize Command", Cost: 1250, Description: "Use the win.mini{id} command to minimize/restore windows.", + Category: "Kernel & System", Dependencies: "useful_panel_buttons" }, { Name: "Useful Panel Buttons", Cost: 250, Description: "Minimize and restore windows by clicking their Panel Button!", + Category: "Enhancements", Dependencies: "desktop;wm_panel_buttons" }, { Name: "Maximize Command", Cost: 1250, Description: "Use the win.max{id} command to maximize windows.", + Category: "Kernel & System", Dependencies: "wm_titlebar;desktop;wm_free_placement" }, { Name: "Close Button", Cost: 1000, Description: "Add a close button to the titlebar to easily close applications.", + Category: "GUI", Dependencies: "wm_titlebar;close_command" }, { Name: "Minimize Button", Cost: 1000, Description: "Minimize windows using a button on the titlebar", + Category: "GUI", Dependencies: "wm_titlebar;minimize_command" }, { Name: "Shiftorium Bulk Buy", Cost: 2000, + Category: "Enhancements", 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: "Shiftorium GUI Bulk Buy", + Cost: 3000, + Category: "GUI", + Description: "Tired of the repetition of selecting an upgrade and hitting \"Buy\" a hundred times when binging? Using the bulkbuy command, we can make the Shiftorium GUI allow you to buy in bulk!", + Dependencies: "shiftorium_gui;shiftorium_bulk_buy" + }, { Name: "File Skimmer", Cost: 500, Description: "View the files on your computer using File Skimmer.", + Category: "Applications", Dependencies: null }, { Name: "Maximize Button", Cost: 500, Description: "Maximize windows using a button on the titlebar", + Category: "GUI", 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.", + Category: "Applications", Dependencies: "mud_fundamentals" }, { Name: "WM Titlebar", Cost: 250, Description: "Display a title on each window.", + Category: "GUI", Dependencies: "window_manager" }, { Name: "Clock Minutes", Cost: 250, Description: "Upgrade the sys.clock command to show minutes since midnight with a {type:\"m\"} argument.", + Category: "Enhancements", Dependencies: "clock" }, { Name: "Clock Hours", Cost: 225, Description: "Upgrade the sys.clock command to show hours since midnight with a {type:\"h\"} argument.", + Category: "Enhancements", 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.", + Category: "Enhancements", Dependencies: "clock_hours", }, { Name: "Full Precision Time", Cost: 500, Description: "Show full-precision time by default when using sys.clock.", + Category: "Enhancements", 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.", + Category: "GUI", Dependencies: "clock;desktop" }, { Name: "App Launcher Categories", Cost: 1000, Dependencies: "app_launcher", + Category: "Enhancements", Description: "Is your App Launcher getting full of items? Perhaps a little too full? Are you having trouble finding things? This upgrade should help - it'll sort all App Launcher items into categories for you." }, { Name: "Draggable windows", Cost: 400, Description: "Allows you to drag windows around with the mouse using the title bar.", + Category: "Enhancements", Dependencies: "wm_titlebar;wm_free_placement" }, { Name: "Window Manager", Cost: 100, Description: "Allows you to run two windows simultaneously within ShiftOS.", + Category: "Kernel & System", 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!", + Category: "Enhancements", Dependencies: "mud_fundamentals;window_manager" }, { Name: "Pong Upgrade 2", Cost: 8000, 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!", + Category: "Enhancements", Dependencies: "mud_fundamentals;window_manager;pong_upgrade" }, { Name: "Audio Player", Cost: 10000, Description: "Want to listen to the greatest tunes? Well get this app asap!", + Category: "Applications", Dependencies: "desktop;wm_free_placement" }, { Name: "Audio Player AL", Cost: 150, Description: "Just another app launcher, making it easier to listen to your favorite songs!", + Category: "GUI", Dependencies: "desktop;wm_free_placement;audio_player" }, @@ -505,42 +587,49 @@ Name: "Shift Titlebar", Cost: 200, Description: "Customize the Titlebar within the Shifter.", + Category: "Customization", Dependencies: "shifter;wm_titlebar" }, { Name: "Shift Title Text", Cost: 200, Description: "Title text looking boring? This upgrade lets you customize the font, color, and position of the Title Text.", + Category: "Customization", Dependencies: "shift_titlebar" }, { Name: "Shift Window Borders", Cost: 200, 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.", + Category: "Customization", Dependencies: "shifter" }, { Name: "Shift Desktop Panel", Cost: 200, 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.", + Category: "Customization", Dependencies: "shifter;desktop" }, { Name: "Shift App Launcher", Cost: 200, 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.", + Category: "Customization", Dependencies: "shift_desktop_panel;app_launcher" }, { Name: "Shift Panel Clock", Cost: 200, Dependencies: "shift_desktop_panel;desktop_clock_widget", + Category: "Customization", 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: 200, Dependencies: "close_button;minimize_button;maximize_button;shift_titlebar", + Category: "Customization", Description: "Those title buttons look very similar and primitive - with this upgrade you can change the size, position, and color of each button." }, @@ -550,6 +639,7 @@ Name: "Skinning", Cost: 10000, 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!", + Category: "Customization", Dependencies: "shifter" }, @@ -558,12 +648,14 @@ { Name: "Artpad", Cost: 7500, + Category: "Applications", 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: 150, Description: "Add an App Launcher Entry for Artpad!", + Category: "GUI", Dependencies: "artpad;app_launcher" }, @@ -576,60 +668,70 @@ Name: "Artpad Pixel Limit 4", Cost: 100, Dependencies: "artpad", + Category: "Enhancements", 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", + Category: "Enhancements", 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", + Category: "Enhancements", 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", + Category: "Enhancements", 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", + Category: "Enhancements", 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", + Category: "Enhancements", 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: 2600, Dependencies: "artpad_pixel_limit_1024", + Category: "Enhancements", 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: 4800, Dependencies: "artpad_pixel_limit_4096", + Category: "Enhancements", 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: 7000, Dependencies: "artpad_pixel_limit_16384", + Category: "Enhancements", 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: 12000, Dependencies: "artpad_pixel_limit_65536", + Category: "Enhancements", 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!" }, @@ -637,6 +739,7 @@ Name: "AL Shutdown", Cost: 300, Dependencies: "app_launcher", + Category: "GUI", Description: "Want to shut down ShiftOS from your app launcher? This is the perfect upgrade for you." }, @@ -645,12 +748,14 @@ Id: "help_description", Cost: 150, Dependencies: "", + Category: "Enhancements", 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", + Category: "Enhancements", 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!" }, @@ -659,65 +764,76 @@ Name: "Artpad Pixel Placer", Dependencies: "artpad", Cost: 750, + Category: "Enhancements", 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, + Category: "Enhancements", 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, + Category: "Enhancements", 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", + Category: "Enhancements", 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", + Category: "Enhancements", 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", + Category: "Enhancements", 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", + Category: "Enhancements", 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", + Category: "Enhancements", 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", + Category: "Enhancements", 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", + Category: "Enhancements", 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, + Category: "Enhancements", Dependencies: "artpad_pixel_placer", Description: "Want to place text on your canvas? Use the Text Tool to do so!" }, @@ -725,30 +841,35 @@ Name: "Artpad New", Dependencies: "artpad", Cost: 500, + Category: "Enhancements", Description: "Made a mistake? Want a blank canvas? This tool gives you just that." }, { Name: "Artpad Open", Dependencies: "artpad;file_skimmer", Cost: 600, + Category: "Enhancements", 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, + Category: "Enhancements", 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, + Category: "Enhancements", 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, + Category: "Enhancements", 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!" }, @@ -760,36 +881,42 @@ Name: "Artpad 4 Color Palettes", Dependencies: "artpad", Cost: 150, + Category: "Enhancements", 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, + Category: "Enhancements", 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, + Category: "Enhancements", 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, + Category: "Enhancements", 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, + Category: "Enhancements", Description: "Well then. We have 32 color palettes - let's double that." }, { Name: "Artpad 128 Color Palettes", Dependencies: "artpad_128_color_palettes", Cost: 3400, + Category: "Enhancements", 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?" }, @@ -800,18 +927,21 @@ { Name: "Shiftorium GUI", Cost: 100, + Category: "Applications", 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: 150, Dependencies: "shiftorium_gui;app_launcher", + Category: "GUI", Description: "Add an App Launcher Entry for the Shiftorium!" }, { Name: "Shiftorium GUI Codepoints Display", Cost: 2500, Dependencies: "shiftorium_gui", + Category: "Enhancements", 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." }, @@ -821,24 +951,28 @@ Name: "ShiftSweeper", Cost: 800, Dependencies: "shiftletters", + Category: "Applications", Description: "Getting bored with Pong and ShiftLetters? Try this BRAND NEW game called ShiftSweeper!" }, { Name: "AL ShiftSweeper", Cost: 100, Dependencies: "app_launcher;shiftsweeper", + Category: "GUI", Description: "Play ShiftSweeper quickly with this dandy applauncher!" }, { Name: "ShiftSweeper Medium", Cost: 900, Dependencies: "shiftsweeper", + Category: "Enhancements", Description: "ShiftSweeper getting too easy? Obviously, since you can only play Easy difficulty! However, with this Medium button, you can get a better challenge, and more codepoints!" }, { Name: "ShiftSweeper Hard", Cost: 900, Dependencies: "shiftsweeper_medium", + Category: "Enhancements", Description: "Is ShiftSweeper still too easy for you? Buy the Hard difficulty and you can try to find 99 mines! It may be extremely difficult, but the reward is massive!" } ] \ No newline at end of file diff --git a/ShiftOS_TheReturn/Commands.cs b/ShiftOS_TheReturn/Commands.cs index 73a7e2d..9f85a25 100644 --- a/ShiftOS_TheReturn/Commands.cs +++ b/ShiftOS_TheReturn/Commands.cs @@ -535,7 +535,7 @@ Upgrades: {SaveSystem.CurrentSave.CountUpgrades()} installed, { Console.WriteLine($@"Information for {upgrade}: -{upg.Name} - {upg.Cost} Codepoints +{upg.Category}: {upg.Name} - {upg.Cost} Codepoints ------------------------------------------------------ {upg.Description} @@ -553,15 +553,66 @@ shiftorium.buy{{upgrade:""{upg.ID}""}}"); return false; } } + + [Command("categories")] + public static bool ListCategories() + { + foreach(var cat in Shiftorium.GetCategories()) + { + Console.WriteLine($"{cat} - {Shiftorium.GetAvailable().Where(x=>x.Category==cat).Count()} upgrades"); + } + return true; + } + [Command("list")] - public static bool ListAll() + public static bool ListAll(Dictionary args) { try { + bool showOnlyInCategory = false; + + string cat = "Other"; + + if (args.ContainsKey("cat")) + { + showOnlyInCategory = true; + cat = args["cat"].ToString(); + } + Dictionary upgrades = new Dictionary(); int maxLength = 5; - foreach (var upg in Shiftorium.GetAvailable()) + IEnumerable upglist = Shiftorium.GetAvailable(); + if (showOnlyInCategory) + { + if (Shiftorium.IsCategoryEmptied(cat)) + { + ConsoleEx.Bold = true; + ConsoleEx.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Shiftorium Query Error"); + Console.WriteLine(); + ConsoleEx.Bold = false; + ConsoleEx.ForegroundColor = ConsoleColor.Gray; + Console.WriteLine("Either there are no upgrades in the category \"" + cat + "\" or the category was not found."); + return true; + } + upglist = Shiftorium.GetAvailable().Where(x => x.Category == cat); + } + + + if(upglist.Count() == 0) + { + ConsoleEx.Bold = true; + ConsoleEx.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("No upgrades available!"); + Console.WriteLine(); + ConsoleEx.Bold = false; + ConsoleEx.ForegroundColor = ConsoleColor.Gray; + Console.WriteLine("You have installed all available upgrades for your system. Please check back later for more."); + return true; + + } + foreach (var upg in upglist) { if (upg.ID.Length > maxLength) { diff --git a/ShiftOS_TheReturn/Shiftorium.cs b/ShiftOS_TheReturn/Shiftorium.cs index 4556cd6..43ea13a 100644 --- a/ShiftOS_TheReturn/Shiftorium.cs +++ b/ShiftOS_TheReturn/Shiftorium.cs @@ -41,6 +41,27 @@ namespace ShiftOS.Engine /// public static bool Silent = false; + /// + /// Gets all Shiftorium categories. + /// + /// Should we look in the "available" upgrade list (i.e, what the user can buy right now), or the full upgrade list? + /// All Shiftorium categories from the list, in a . + public static string[] GetCategories(bool onlyAvailable = true) + { + List cats = new List(); + IEnumerable < ShiftoriumUpgrade > upgrades = GetDefaults(); + if (onlyAvailable) + upgrades = new List(GetAvailable()); + + foreach(var upg in upgrades) + { + if (!cats.Contains(upg.Category)) + cats.Add(upg.Category); + } + + return cats.ToArray(); + } + public static void InvokeUpgradeInstalled() { Installed?.Invoke(); @@ -289,6 +310,8 @@ namespace ShiftOS.Engine public string ID { get; private set; } } + + public class ShiftoriumUpgrade { public string Name { get; set; } -- cgit v1.2.3 From e833a9bf2751f16d8614af9aa20f5b9bec3d81a8 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 23 Apr 2017 14:53:10 -0400 Subject: FUCKTONS OF SHIFTORIUM WORK --- ShiftOS.WinForms/Applications/FormatEditor.cs | 3 +- ShiftOS.WinForms/Applications/Shiftnet.Designer.cs | 30 +- ShiftOS.WinForms/Applications/Shiftnet.cs | 301 +++++++-------------- .../Applications/ShiftoriumFrontend.cs | 2 +- ShiftOS.WinForms/Program.cs | 33 ++- ShiftOS.WinForms/Resources/Shiftorium.txt | 7 - ShiftOS.WinForms/ShiftOS.WinForms.csproj | 18 ++ .../ShiftnetSites/AppscapeMain.Designer.cs | 113 ++++++++ ShiftOS.WinForms/ShiftnetSites/AppscapeMain.cs | 208 ++++++++++++++ ShiftOS.WinForms/ShiftnetSites/AppscapeMain.resx | 120 ++++++++ .../ShiftnetSites/MainHomepage.Designer.cs | 153 +++++++++++ ShiftOS.WinForms/ShiftnetSites/MainHomepage.cs | 89 ++++++ ShiftOS.WinForms/ShiftnetSites/MainHomepage.resx | 128 +++++++++ ShiftOS.WinForms/WindowBorder.cs | 15 +- ShiftOS_TheReturn/Command.cs | 2 +- ShiftOS_TheReturn/Commands.cs | 2 +- ShiftOS_TheReturn/SaveSystem.cs | 2 +- ShiftOS_TheReturn/ShiftOS.Engine.csproj | 1 + ShiftOS_TheReturn/ShiftnetSite.cs | 46 ++++ ShiftOS_TheReturn/Shiftorium.cs | 6 +- 20 files changed, 1040 insertions(+), 239 deletions(-) create mode 100644 ShiftOS.WinForms/ShiftnetSites/AppscapeMain.Designer.cs create mode 100644 ShiftOS.WinForms/ShiftnetSites/AppscapeMain.cs create mode 100644 ShiftOS.WinForms/ShiftnetSites/AppscapeMain.resx create mode 100644 ShiftOS.WinForms/ShiftnetSites/MainHomepage.Designer.cs create mode 100644 ShiftOS.WinForms/ShiftnetSites/MainHomepage.cs create mode 100644 ShiftOS.WinForms/ShiftnetSites/MainHomepage.resx create mode 100644 ShiftOS_TheReturn/ShiftnetSite.cs (limited to 'ShiftOS_TheReturn/Shiftorium.cs') diff --git a/ShiftOS.WinForms/Applications/FormatEditor.cs b/ShiftOS.WinForms/Applications/FormatEditor.cs index 7491e36..db52d85 100644 --- a/ShiftOS.WinForms/Applications/FormatEditor.cs +++ b/ShiftOS.WinForms/Applications/FormatEditor.cs @@ -36,11 +36,10 @@ using ShiftOS.Engine; namespace ShiftOS.WinForms.Applications { [MultiplayerOnly] [Launcher("Format Editor", true, "al_format_editor", "Customization")] - [RequiresUpgrade("format_editor")] + [AppscapeEntry("Format Editor", "Edit the syntax of your Terminal to be however you like.", 750, "file_skimmer", "Customization")] [WinOpen("formateditor")] [DefaultTitle("Format Editor")] [DefaultIcon("iconFormatEditor")] - public partial class FormatEditor : UserControl, IShiftOSWindow { IList parts = new List(); diff --git a/ShiftOS.WinForms/Applications/Shiftnet.Designer.cs b/ShiftOS.WinForms/Applications/Shiftnet.Designer.cs index eca44ae..a7fe700 100644 --- a/ShiftOS.WinForms/Applications/Shiftnet.Designer.cs +++ b/ShiftOS.WinForms/Applications/Shiftnet.Designer.cs @@ -57,13 +57,12 @@ namespace ShiftOS.WinForms.Applications this.btnforward = new System.Windows.Forms.Button(); this.txturl = new System.Windows.Forms.TextBox(); this.btngo = new System.Windows.Forms.Button(); - this.wbcanvas = new System.Windows.Forms.WebBrowser(); + this.pnlcanvas = new System.Windows.Forms.Panel(); this.flcontrols.SuspendLayout(); this.SuspendLayout(); // // flcontrols // - this.flcontrols.AutoSize = true; this.flcontrols.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.flcontrols.Controls.Add(this.btnback); this.flcontrols.Controls.Add(this.btnforward); @@ -123,42 +122,35 @@ namespace ShiftOS.WinForms.Applications this.btngo.UseVisualStyleBackColor = true; this.btngo.Click += new System.EventHandler(this.btngo_Click); // - // wbcanvas + // pnlcanvas // - this.wbcanvas.Dock = System.Windows.Forms.DockStyle.Fill; - this.wbcanvas.IsWebBrowserContextMenuEnabled = false; - this.wbcanvas.Location = new System.Drawing.Point(0, 29); - this.wbcanvas.MinimumSize = new System.Drawing.Size(20, 20); - this.wbcanvas.Name = "wbcanvas"; - this.wbcanvas.ScriptErrorsSuppressed = true; - this.wbcanvas.Size = new System.Drawing.Size(805, 510); - this.wbcanvas.TabIndex = 1; - this.wbcanvas.WebBrowserShortcutsEnabled = false; - this.wbcanvas.Navigated += new System.Windows.Forms.WebBrowserNavigatedEventHandler(this.wbcanvas_Navigated); - this.wbcanvas.Navigating += new System.Windows.Forms.WebBrowserNavigatingEventHandler(this.wbcanvas_Navigating); + this.pnlcanvas.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.pnlcanvas.Dock = System.Windows.Forms.DockStyle.Fill; + this.pnlcanvas.Location = new System.Drawing.Point(0, 29); + this.pnlcanvas.Name = "pnlcanvas"; + this.pnlcanvas.Size = new System.Drawing.Size(805, 510); + this.pnlcanvas.TabIndex = 1; // // Shiftnet // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.wbcanvas); + this.Controls.Add(this.pnlcanvas); this.Controls.Add(this.flcontrols); this.Name = "Shiftnet"; this.Size = new System.Drawing.Size(805, 539); this.flcontrols.ResumeLayout(false); this.flcontrols.PerformLayout(); this.ResumeLayout(false); - this.PerformLayout(); } #endregion - - private System.Windows.Forms.FlowLayoutPanel flcontrols; private System.Windows.Forms.Button btnback; private System.Windows.Forms.Button btnforward; private System.Windows.Forms.TextBox txturl; private System.Windows.Forms.Button btngo; - private System.Windows.Forms.WebBrowser wbcanvas; + private System.Windows.Forms.Panel pnlcanvas; + private System.Windows.Forms.FlowLayoutPanel flcontrols; } } diff --git a/ShiftOS.WinForms/Applications/Shiftnet.cs b/ShiftOS.WinForms/Applications/Shiftnet.cs index 54a8aa6..7f5d3c1 100644 --- a/ShiftOS.WinForms/Applications/Shiftnet.cs +++ b/ShiftOS.WinForms/Applications/Shiftnet.cs @@ -35,6 +35,8 @@ using ShiftOS.Engine; using Newtonsoft.Json; using static ShiftOS.Engine.SkinEngine; using ShiftOS.WinForms.Tools; +using System.IO; +using System.Reflection; namespace ShiftOS.WinForms.Applications { @@ -50,216 +52,34 @@ namespace ShiftOS.WinForms.Applications [WinOpen("shiftnet")] [RequiresUpgrade("victortran_shiftnet")] [DefaultIcon("iconShiftnet")] - public partial class Shiftnet : UserControl, IShiftOSWindow + public partial class Shiftnet : UserControl, IShiftOSWindow, IShiftnetClient { public Shiftnet() { InitializeComponent(); - ServerManager.MessageReceived += (msg) => - { - try - { - if (msg.Name == "shiftnet_file") - { - if (Objects.ShiftFS.Utils.FileExists("0:/md.txt")) - { - this.Invoke(new Action(() => - { - wbcanvas.DocumentText = ConstructHtml(Objects.ShiftFS.Utils.ReadAllText("0:/md.txt")); - })); - } - else - { - this.Invoke(new Action(() => - { - wbcanvas.DocumentText = ConstructHtml(msg.Contents); - })); - } - } - } - catch - { - - } - }; - } - - public string ConstructHtml(string markdown) - { - var TerminalForeColor = ControlManager.ConvertColor(SkinEngine.LoadedSkin.TerminalForeColorCC); - var TerminalBackColor = ControlManager.ConvertColor(SkinEngine.LoadedSkin.TerminalBackColorCC); - string html = $@" - - - - - - -"; - - string body = CommonMark.CommonMarkConverter.Convert(markdown); - for (int i = 0; i <= Encoding.UTF8.GetBytes(body).Length; i += DownloadManager.GetDownloadSpeed()) - { - //halt the page load until 'download' finishes. - } - html = html.Replace("", body); - return html; } public string CurrentUrl { get; set; } - private void wbcanvas_Navigating(object sender, WebBrowserNavigatingEventArgs e) - { - string Url = e.Url.ToString().Replace("http://", ""); - if (CurrentUrl != Url.ToString() && !Url.ToString().StartsWith("about:")) - { - e.Cancel = true; - Future.Clear(); - if (Url.StartsWith("runsyscmd/")) - { - ProcessShiftnetCmd(Url.Replace("runsyscmd/", "")); - } - - ShiftnetNavigate(Url.ToString()); - } - } - - public void ProcessShiftnetCmd(string cmd) - { - var args = cmd.Split('/'); - switch (args[0]) - { - case "setsnsub": - for (int i = 0; i < DownloadManager.GetAllSubscriptions().Length; i++) - { - if (DownloadManager.GetAllSubscriptions()[i].Name == args[1]) - { - var sub = DownloadManager.GetAllSubscriptions()[i]; - Infobox.PromptYesNo("Shiftnet", $"Are you sure you want to switch your system's Shiftnet subscription to {sub.Name} by {sub.Company}?{Environment.NewLine}{Environment.NewLine}Cost per month: {sub.CostPerMonth} CP{Environment.NewLine}Download speed: {sub.DownloadSpeed} bytes per second", new Action((answer) => - { - if (answer == true) - { - if (SaveSystem.CurrentSave.Codepoints >= sub.CostPerMonth) - { - //Initial fee gets deducted. - SaveSystem.CurrentSave.Codepoints -= sub.CostPerMonth; - //Then we set the subscription. - SaveSystem.CurrentSave.ShiftnetSubscription = i; - //Then we say that we have paid this month. - SaveSystem.CurrentSave.LastMonthPaid = DateTime.Now.Month; - //Then we send our save to the MUD. - SaveSystem.SaveGame(); - - } - else - { - //User can't afford this subscription. - Infobox.Show("Shiftnet - Not enough Codepoints", $"You cannot afford to pay for this subscription at this time. You need {sub.CostPerMonth - SaveSystem.CurrentSave.Codepoints} more Codepoints."); - } - } - })); - } - } - return; - } - } - public Stack History = new Stack(); public Stack Future = new Stack(); - public void ShiftnetNavigate(string Url, bool pushHistory = true) - { - if (Url.EndsWith(".rnp") || !Url.Contains(".")) - { - if (!string.IsNullOrEmpty(CurrentUrl) && pushHistory) - History.Push(CurrentUrl); - CurrentUrl = Url; - ServerManager.SendMessage("shiftnet_get", JsonConvert.SerializeObject(new - { - url = Url - })); - txturl.Text = Url; - - } - else - { - ServerMessageReceived smr = null; - smr = (msg) => - { - if (msg.Name == "download_meta") - { - var bytes = JsonConvert.DeserializeObject(msg.Contents); - string destPath = null; - string ext = Url.Split('.')[Url.Split('.').Length - 1]; - this.Invoke(new Action(() => - { - FileSkimmerBackend.GetFile(new[] { ext }, FileOpenerStyle.Save, new Action((file) => - { - destPath = file; - })); - })); - while (string.IsNullOrEmpty(destPath)) - { - - } - var d = new Download - { - ShiftnetUrl = Url, - Destination = destPath, - Bytes = bytes, - Progress = 0, - }; - DownloadManager.StartDownload(d); - this.Invoke(new Action(() => - { - AppearanceManager.SetupWindow(new Downloader()); - })); - ServerManager.MessageReceived -= smr; - } - }; - ServerManager.MessageReceived += smr; - ServerManager.SendMessage("download_start", Url); - } - } + public IShiftnetSite CurrentPage = null; public void OnLoad() { - ShiftnetNavigate("shiftnet/main"); + NavigateToUrl("shiftnet/main"); } public void OnSkinLoad() { - ShiftnetNavigate(CurrentUrl); + CurrentPage?.OnSkinLoad(); + btnback.Location = new Point(2, 2); + btnforward.Location = new Point(btnback.Left + btnback.Width + 2, 2); + txturl.Location = new Point(btnforward.Left + btnforward.Width + 2, 2); + txturl.Width = flcontrols.Width - btnback.Width - 2 - btnforward.Width - 2 - (btngo.Width*2) - 2; + btngo.Location = new Point(flcontrols.Width - btngo.Width - 2, 2); } public bool OnUnload() @@ -269,6 +89,7 @@ namespace ShiftOS.WinForms.Applications public void OnUpgrade() { + CurrentPage?.OnUpgrade(); } private void btnback_Click(object sender, EventArgs e) @@ -279,7 +100,7 @@ namespace ShiftOS.WinForms.Applications if (!string.IsNullOrEmpty(hist)) { Future.Push(hist); - ShiftnetNavigate(hist, false); + NavigateToUrl(hist); } } catch @@ -295,7 +116,8 @@ namespace ShiftOS.WinForms.Applications string fut = Future.Pop(); if (!string.IsNullOrEmpty(fut)) { - ShiftnetNavigate(fut); + History.Push(CurrentUrl); + NavigateToUrl(fut); } } catch @@ -309,8 +131,8 @@ namespace ShiftOS.WinForms.Applications if (!string.IsNullOrWhiteSpace(txturl.Text)) { Future.Clear(); - - ShiftnetNavigate(txturl.Text); + History.Push(CurrentUrl); + NavigateToUrl(txturl.Text); } } @@ -323,8 +145,95 @@ namespace ShiftOS.WinForms.Applications } } - private void wbcanvas_Navigated(object sender, WebBrowserNavigatedEventArgs e) + public void NavigateToUrl(string url) + { + txturl.Text = url; + foreach(var exe in Directory.GetFiles(Environment.CurrentDirectory)) + { + if(exe.EndsWith(".exe") || exe.EndsWith(".dll")) + { + try + { + var asm = Assembly.LoadFile(exe); + foreach (var type in asm.GetTypes()) + { + if (type.GetInterfaces().Contains(typeof(IShiftnetSite))) + { + if (type.BaseType == typeof(UserControl)) + { + var attribute = type.GetCustomAttributes(false).FirstOrDefault(x => x is ShiftnetSiteAttribute) as ShiftnetSiteAttribute; + if (attribute != null) + { + if (attribute.Url == url) + { + if (Shiftorium.UpgradeAttributesUnlocked(type)) + { + var obj = (IShiftnetSite)Activator.CreateInstance(type, null); + obj.GoToUrl += (u) => + { + History.Push(u); + NavigateToUrl(u); + }; + obj.GoBack += () => + { + string u = History.Pop(); + Future.Push(u); + NavigateToUrl(u); + }; + CurrentPage = obj; + this.pnlcanvas.Controls.Clear(); + this.pnlcanvas.Controls.Add((UserControl)obj); + ((UserControl)obj).Show(); + ((UserControl)obj).Dock = DockStyle.Fill; + obj.OnUpgrade(); + obj.OnSkinLoad(); + obj.Setup(); + return; + } + } + } + } + } + } + } + catch (Exception ex) + { + pnlcanvas.Controls.Clear(); + var tlbl = new Label(); + tlbl.Text = "Server error in \"" + url + "\" application."; + tlbl.Tag = "header1"; + tlbl.AutoSize = true; + tlbl.Location = new Point(10, 10); + tlbl.Dock = DockStyle.Top; + pnlcanvas.Controls.Add(tlbl); + tlbl.Show(); + + var crash = new Label(); + crash.Dock = DockStyle.Fill; + crash.AutoSize = false; + crash.Text = ex.ToString(); + pnlcanvas.Controls.Add(crash); + crash.Show(); + crash.BringToFront(); + ControlManager.SetupControls(pnlcanvas); + return; + } + } + } + pnlcanvas.Controls.Clear(); + var lbl = new Label(); + lbl.Text = "Page not found!"; + lbl.Tag = "header1"; + lbl.AutoSize = true; + lbl.Location = new Point(10, 10); + pnlcanvas.Controls.Add(lbl); + lbl.Show(); + + } + + public void RefreshSite() { + NavigateToUrl(CurrentUrl); } } } diff --git a/ShiftOS.WinForms/Applications/ShiftoriumFrontend.cs b/ShiftOS.WinForms/Applications/ShiftoriumFrontend.cs index 0762897..66b0448 100644 --- a/ShiftOS.WinForms/Applications/ShiftoriumFrontend.cs +++ b/ShiftOS.WinForms/Applications/ShiftoriumFrontend.cs @@ -185,7 +185,7 @@ namespace ShiftOS.WinForms.Applications { long cpCost = 0; backend.Silent = true; - Dictionary UpgradesToBuy = new Dictionary(); + Dictionary UpgradesToBuy = new Dictionary(); foreach (var itm in lbupgrades.SelectedItems) { cpCost += upgrades[itm.ToString()].Cost; diff --git a/ShiftOS.WinForms/Program.cs b/ShiftOS.WinForms/Program.cs index 36c9338..3343cb0 100644 --- a/ShiftOS.WinForms/Program.cs +++ b/ShiftOS.WinForms/Program.cs @@ -34,6 +34,7 @@ using static ShiftOS.Objects.ShiftFS.Utils; using ShiftOS.WinForms.Applications; using ShiftOS.WinForms.Tools; using System.Reflection; +using System.IO; namespace ShiftOS.WinForms { @@ -98,7 +99,37 @@ namespace ShiftOS.WinForms { public List GetDefaults() { - return JsonConvert.DeserializeObject>(Properties.Resources.Shiftorium); + var defaultList = JsonConvert.DeserializeObject>(Properties.Resources.Shiftorium); + + foreach(var exe in Directory.GetFiles(Environment.CurrentDirectory)) + { + if(exe.EndsWith(".exe") || exe.EndsWith(".dll")) + { + try + { + var asm = Assembly.LoadFile(exe); + foreach(var type in asm.GetTypes()) + { + var attrib = type.GetCustomAttributes(false).FirstOrDefault(x => x is AppscapeEntryAttribute) as AppscapeEntryAttribute; + if(attrib != null) + { + var upgrade = new ShiftoriumUpgrade + { + Id = attrib.Name.ToLower().Replace(" ", "_"), + Name = attrib.Name, + Description = attrib.Description, + Cost = attrib.Cost, + Category = attrib.Category, + Dependencies = (string.IsNullOrWhiteSpace(attrib.DependencyString)) ? "appscape_handled_nodisplay" : "appscape_handled_nodisplay;" + attrib.DependencyString + }; + defaultList.Add(upgrade); + } + } + } + catch { } + } + } + return defaultList; } } diff --git a/ShiftOS.WinForms/Resources/Shiftorium.txt b/ShiftOS.WinForms/Resources/Shiftorium.txt index ca555d4..e68277c 100644 --- a/ShiftOS.WinForms/Resources/Shiftorium.txt +++ b/ShiftOS.WinForms/Resources/Shiftorium.txt @@ -368,13 +368,6 @@ Category: "GUI", Dependencies:"desktop;wm_unlimited_windows" }, - { - Name: "Format Editor", - Cost: 6000, - Description: "Allows you to change the format of commands.", - Category: "Applications", - Dependencies: "shifter;name_changer" - }, { Name: "Format Editor Optional Text", Cost: 150, diff --git a/ShiftOS.WinForms/ShiftOS.WinForms.csproj b/ShiftOS.WinForms/ShiftOS.WinForms.csproj index bd8fd65..3edfd38 100644 --- a/ShiftOS.WinForms/ShiftOS.WinForms.csproj +++ b/ShiftOS.WinForms/ShiftOS.WinForms.csproj @@ -317,6 +317,18 @@ Resources.resx + + UserControl + + + AppscapeMain.cs + + + UserControl + + + MainHomepage.cs + @@ -463,6 +475,12 @@ Designer Resources.Designer.cs + + AppscapeMain.cs + + + MainHomepage.cs + WindowBorder.cs diff --git a/ShiftOS.WinForms/ShiftnetSites/AppscapeMain.Designer.cs b/ShiftOS.WinForms/ShiftnetSites/AppscapeMain.Designer.cs new file mode 100644 index 0000000..6698e5a --- /dev/null +++ b/ShiftOS.WinForms/ShiftnetSites/AppscapeMain.Designer.cs @@ -0,0 +1,113 @@ +namespace ShiftOS.WinForms.ShiftnetSites +{ + partial class AppscapeMain + { + /// + /// 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 Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.flcategories = new System.Windows.Forms.FlowLayoutPanel(); + this.pnlappslist = new System.Windows.Forms.Panel(); + this.label2 = new System.Windows.Forms.Label(); + this.lbtitle = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(17, 17); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(55, 13); + this.label1.TabIndex = 0; + this.label1.Tag = "header1"; + this.label1.Text = "Appscape"; + // + // flcategories + // + this.flcategories.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.flcategories.FlowDirection = System.Windows.Forms.FlowDirection.TopDown; + this.flcategories.Location = new System.Drawing.Point(20, 120); + this.flcategories.Margin = new System.Windows.Forms.Padding(0); + this.flcategories.Name = "flcategories"; + this.flcategories.Size = new System.Drawing.Size(187, 310); + this.flcategories.TabIndex = 1; + // + // pnlappslist + // + this.pnlappslist.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pnlappslist.Location = new System.Drawing.Point(221, 120); + this.pnlappslist.Name = "pnlappslist"; + this.pnlappslist.Size = new System.Drawing.Size(459, 310); + this.pnlappslist.TabIndex = 2; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(20, 76); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(57, 13); + this.label2.TabIndex = 3; + this.label2.Tag = "header2"; + this.label2.Text = "Categories"; + // + // lbtitle + // + this.lbtitle.AutoSize = true; + this.lbtitle.Location = new System.Drawing.Point(218, 76); + this.lbtitle.Name = "lbtitle"; + this.lbtitle.Size = new System.Drawing.Size(57, 13); + this.lbtitle.TabIndex = 4; + this.lbtitle.Tag = "header2"; + this.lbtitle.Text = "Categories"; + // + // AppscapeMain + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.lbtitle); + this.Controls.Add(this.label2); + this.Controls.Add(this.pnlappslist); + this.Controls.Add(this.flcategories); + this.Controls.Add(this.label1); + this.Name = "AppscapeMain"; + this.Size = new System.Drawing.Size(709, 457); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.FlowLayoutPanel flcategories; + private System.Windows.Forms.Panel pnlappslist; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label lbtitle; + } +} diff --git a/ShiftOS.WinForms/ShiftnetSites/AppscapeMain.cs b/ShiftOS.WinForms/ShiftnetSites/AppscapeMain.cs new file mode 100644 index 0000000..88db07b --- /dev/null +++ b/ShiftOS.WinForms/ShiftnetSites/AppscapeMain.cs @@ -0,0 +1,208 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using ShiftOS.Engine; +using ShiftOS.WinForms.Tools; + +namespace ShiftOS.WinForms.ShiftnetSites +{ + [ShiftnetSite("shiftnet/appscape", "Appscape", "Bringing ShiftOS to life")] + [ShiftnetFundamental] + public partial class AppscapeMain : UserControl, IShiftnetSite + { + public AppscapeMain() + { + InitializeComponent(); + } + + public event Action GoBack; + public event Action GoToUrl; + + public void OnSkinLoad() + { + ControlManager.SetupControls(this); + } + + public void OnUpgrade() + { + } + + public string Category = "All"; + + public string[] GetCategories() + { + var upgrades = Shiftorium.GetDefaults().Where(x => x.Dependencies.Contains("appscape_")); + List cats = new List(); + cats.Add("All"); + try + { + if (upgrades.Count() > 0) + foreach (var upg in upgrades) + { + if (!cats.Contains(upg.Category)) + cats.Add(upg.Category); + } + } + catch { } + return cats.ToArray(); + } + + public ShiftoriumUpgrade CurrentUpgrade = null; + + public void SetupCategory(string cat) + { + pnlappslist.Controls.Clear(); + pnlappslist.Show(); + pnlappslist.BringToFront(); + Category = cat; + var upgrades = GetAllInCategory(); + lbtitle.Text = cat; + if(upgrades.Length == 0) + { + var err = new Label(); + err.AutoSize = true; + err.Text = "There are no apps in this list! Come back later for more."; + pnlappslist.Controls.Add(err); + err.Show(); + } + else + { + var fl = new FlowLayoutPanel(); + fl.Dock = DockStyle.Fill; + pnlappslist.Controls.Add(fl); + fl.Show(); + foreach(var upg in upgrades) + { + var pnl = new Panel(); + pnl.Height = 250; + pnl.Width = 200; + fl.Controls.Add(pnl); + pnl.Show(); + var upgTitle = new Label(); + upgTitle.Text = upg.Name; + upgTitle.Dock = DockStyle.Top; + upgTitle.AutoSize = true; + upgTitle.MaximumSize = new Size(pnl.Width, 0); + upgTitle.Tag = "header3"; + pnl.Controls.Add(upgTitle); + upgTitle.Show(); + + var cp_display = new Panel(); + cp_display.Height = 30; + cp_display.Dock = DockStyle.Bottom; + pnl.Controls.Add(cp_display); + cp_display.Show(); + + var cp_value = new Label(); + if (Shiftorium.UpgradeInstalled(upg.ID)) + { + cp_value.Text = "Out of stock."; + } + else + { + cp_value.Text = $"{upg.Cost} CP"; + } + cp_value.AutoSize = true; + cp_value.Top = (cp_display.Height - cp_value.Height) / 2; + cp_value.Left = 5; + cp_display.Controls.Add(cp_value); + cp_value.Show(); + + + if(cp_value.Text != "Out of stock.") + { + var more_info = new Button(); + more_info.Text = "More info"; + more_info.Click += (o, a) => + { + ViewMoreInfo(upg); + }; + more_info.AutoSize = false; + more_info.AutoSizeMode = AutoSizeMode.GrowAndShrink; + more_info.Top = (cp_display.Height - more_info.Height) / 2; + more_info.Left = cp_display.Width - more_info.Width - 5; + cp_display.Controls.Add(more_info); + more_info.Show(); + } + + var desc = new Label(); + desc.Text = upg.Description; + desc.AutoSize = false; + desc.Dock = DockStyle.Fill; + pnl.Controls.Add(desc); + desc.Show(); + desc.BringToFront(); + + + ControlManager.SetupControls(pnl); + } + } + } + + public void ViewMoreInfo(ShiftoriumUpgrade upg) + { + + } + + public ShiftoriumUpgrade[] GetAllInCategory() + { + var upgrades = Shiftorium.GetDefaults().Where(x => (x.Dependencies == null) ? false : x.Dependencies.Contains("appscape_")); + if (upgrades.Count() == 0) + return new ShiftoriumUpgrade[0]; + + if (Category == "All") + return upgrades.ToArray(); + else + return upgrades.Where(x => x.Category == Category).ToArray(); + } + + public void Setup() + { + flcategories.Controls.Clear(); + foreach(var cat in this.GetCategories()) + { + var btn = new Button(); + btn.Text = cat; + btn.Click += (o, a) => + { + SetupCategory(cat); + }; + ControlManager.SetupControl(btn); + btn.Width = flcategories.Width - 2; + flcategories.Controls.Add(btn); + btn.Show(); + } + SetupCategory("All"); + } + } +} + +namespace ShiftOS.WinForms +{ + /// + /// Special version of for specifying Appscape applications as Shiftorium upgrades. + /// + public class AppscapeEntryAttribute : RequiresUpgradeAttribute + { + public AppscapeEntryAttribute(string name, string description, long cost, string dependencies = "", string category = "Misc") : base((string.IsNullOrWhiteSpace(dependencies)) ? name.ToLower().Replace(" ","_") : name.ToLower().Replace(" ", "_") + dependencies) + { + Name = name; + Description = description; + Category = category; + Cost = cost; + DependencyString = dependencies; + } + + public string Name { get; private set; } + public string Description { get; private set; } + public string Category { get; private set; } + public long Cost { get; private set; } + public string DependencyString { get; private set; } + } +} \ No newline at end of file diff --git a/ShiftOS.WinForms/ShiftnetSites/AppscapeMain.resx b/ShiftOS.WinForms/ShiftnetSites/AppscapeMain.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/ShiftOS.WinForms/ShiftnetSites/AppscapeMain.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.WinForms/ShiftnetSites/MainHomepage.Designer.cs b/ShiftOS.WinForms/ShiftnetSites/MainHomepage.Designer.cs new file mode 100644 index 0000000..bebc8bd --- /dev/null +++ b/ShiftOS.WinForms/ShiftnetSites/MainHomepage.Designer.cs @@ -0,0 +1,153 @@ +namespace ShiftOS.WinForms.ShiftnetSites +{ + partial class MainHomepage + { + /// + /// 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 Component 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(MainHomepage)); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.panel1 = new System.Windows.Forms.Panel(); + this.lbspecheader = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.panel2 = new System.Windows.Forms.Panel(); + this.label4 = new System.Windows.Forms.Label(); + this.flfundamentals = new System.Windows.Forms.FlowLayoutPanel(); + this.panel1.SuspendLayout(); + this.panel2.SuspendLayout(); + this.SuspendLayout(); + // + // label1 + // + this.label1.Dock = System.Windows.Forms.DockStyle.Top; + this.label1.Location = new System.Drawing.Point(0, 0); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(710, 65); + this.label1.TabIndex = 0; + this.label1.Tag = "header1"; + this.label1.Text = "Welcome to the Shiftnet!"; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // label2 + // + this.label2.Dock = System.Windows.Forms.DockStyle.Top; + this.label2.Location = new System.Drawing.Point(0, 65); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(710, 22); + this.label2.TabIndex = 1; + this.label2.Text = "The Shiftnet is a vast network of services, websites, software and so much more f" + + "or ShiftOS. Have a look around!"; + this.label2.TextAlign = System.Drawing.ContentAlignment.TopCenter; + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel1.Controls.Add(this.label3); + this.panel1.Controls.Add(this.lbspecheader); + this.panel1.Location = new System.Drawing.Point(27, 140); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(389, 281); + this.panel1.TabIndex = 2; + // + // lbspecheader + // + this.lbspecheader.Dock = System.Windows.Forms.DockStyle.Top; + this.lbspecheader.Location = new System.Drawing.Point(0, 0); + this.lbspecheader.Name = "lbspecheader"; + this.lbspecheader.Size = new System.Drawing.Size(389, 42); + this.lbspecheader.TabIndex = 0; + this.lbspecheader.Tag = "header3"; + this.lbspecheader.Text = "How to use the Shiftnet"; + // + // label3 + // + this.label3.Dock = System.Windows.Forms.DockStyle.Fill; + this.label3.Location = new System.Drawing.Point(0, 42); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(389, 239); + this.label3.TabIndex = 1; + this.label3.Text = resources.GetString("label3.Text"); + // + // panel2 + // + this.panel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel2.Controls.Add(this.flfundamentals); + this.panel2.Controls.Add(this.label4); + this.panel2.Location = new System.Drawing.Point(439, 140); + this.panel2.Name = "panel2"; + this.panel2.Size = new System.Drawing.Size(247, 281); + this.panel2.TabIndex = 3; + // + // label4 + // + this.label4.Dock = System.Windows.Forms.DockStyle.Top; + this.label4.Location = new System.Drawing.Point(0, 0); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(247, 42); + this.label4.TabIndex = 1; + this.label4.Tag = "header3"; + this.label4.Text = "The Fundamentals"; + // + // flfundamentals + // + this.flfundamentals.Dock = System.Windows.Forms.DockStyle.Fill; + this.flfundamentals.Location = new System.Drawing.Point(0, 42); + this.flfundamentals.Name = "flfundamentals"; + this.flfundamentals.Size = new System.Drawing.Size(247, 239); + this.flfundamentals.TabIndex = 2; + // + // MainHomepage + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.panel2); + this.Controls.Add(this.panel1); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Name = "MainHomepage"; + this.Size = new System.Drawing.Size(710, 437); + this.panel1.ResumeLayout(false); + this.panel2.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Label lbspecheader; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Panel panel2; + private System.Windows.Forms.FlowLayoutPanel flfundamentals; + private System.Windows.Forms.Label label4; + } +} diff --git a/ShiftOS.WinForms/ShiftnetSites/MainHomepage.cs b/ShiftOS.WinForms/ShiftnetSites/MainHomepage.cs new file mode 100644 index 0000000..cb39cd6 --- /dev/null +++ b/ShiftOS.WinForms/ShiftnetSites/MainHomepage.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using ShiftOS.Engine; +using ShiftOS.WinForms.Tools; +using System.Reflection; +using System.IO; + +namespace ShiftOS.WinForms.ShiftnetSites +{ + [ShiftnetSite("shiftnet/main", "Main Site", "The main Shiftnet hub.")] + public partial class MainHomepage : UserControl, IShiftnetSite + { + public MainHomepage() + { + InitializeComponent(); + } + + public event Action GoBack; + public event Action GoToUrl; + + public void OnSkinLoad() + { + ControlManager.SetupControls(this); + } + + public void OnUpgrade() + { + + } + + public void Setup() + { + //Get the Fundamentals List + flfundamentals.Controls.Clear(); + foreach (var exe in Directory.GetFiles(Environment.CurrentDirectory)) + { + if (exe.EndsWith(".exe") || exe.EndsWith(".dll")) + { + try + { + var asm = Assembly.LoadFile(exe); + foreach (var type in asm.GetTypes()) + { + if (type.GetInterfaces().Contains(typeof(IShiftnetSite))) + { + if (type.BaseType == typeof(UserControl)) + { + var attribute = type.GetCustomAttributes(false).FirstOrDefault(x => x is ShiftnetSiteAttribute) as ShiftnetSiteAttribute; + if (attribute != null) + { + if (Shiftorium.UpgradeAttributesUnlocked(type)) + { + if (type.GetCustomAttributes(false).FirstOrDefault(x => x is ShiftnetFundamentalAttribute) != null) + { + var dash = new Label(); + dash.Text = " - "; + dash.AutoSize = true; + flfundamentals.Controls.Add(dash); + dash.Show(); + var link = new LinkLabel(); + link.Text = attribute.Name; + link.Click += (o, a) => + { + GoToUrl?.Invoke(attribute.Url); + }; + flfundamentals.Controls.Add(link); + flfundamentals.SetFlowBreak(link, true); + link.Show(); + } + } + } + } + } + } + } + catch { } + } + } + + } + } +} diff --git a/ShiftOS.WinForms/ShiftnetSites/MainHomepage.resx b/ShiftOS.WinForms/ShiftnetSites/MainHomepage.resx new file mode 100644 index 0000000..e9a0c8f --- /dev/null +++ b/ShiftOS.WinForms/ShiftnetSites/MainHomepage.resx @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + The Shiftnet works a lot like a regular web browser. To browse to a website, you can either click links or you can type a Shiftnet URL into your Address Bar at the top and click "Go". + +An example of a Shiftnet URL would be "shiftnet/main", which you are at right now. This is the main Shiftnet hub. You can also browse to files and folder listings, if you have access to them. + + +There are lots of Shiftnet websites for you to visit - so go ahead and explore, but first, check out some of the fundamental sites and services to the right! + + \ No newline at end of file diff --git a/ShiftOS.WinForms/WindowBorder.cs b/ShiftOS.WinForms/WindowBorder.cs index 64f2da4..2829a3e 100644 --- a/ShiftOS.WinForms/WindowBorder.cs +++ b/ShiftOS.WinForms/WindowBorder.cs @@ -134,18 +134,16 @@ namespace ShiftOS.WinForms } }; - this.Width = LoadedSkin.LeftBorderWidth + _parentWindow.Width + LoadedSkin.RightBorderWidth; - this.Height = LoadedSkin.TitlebarHeight + _parentWindow.Height + LoadedSkin.BottomBorderWidth; - - SetupControls(this); - + + this.pnlcontents.Controls.Add(this._parentWindow); this._parentWindow.Dock = DockStyle.Fill; this._parentWindow.Show(); + SetupControls(this); + this.Width = LoadedSkin.LeftBorderWidth + this.Width + LoadedSkin.RightBorderWidth; + this.Height = LoadedSkin.TitlebarHeight + this.Height + LoadedSkin.BottomBorderWidth; ControlManager.SetupControls(this._parentWindow); - ParentWindow.OnSkinLoad(); - ParentWindow.OnUpgrade(); Shiftorium.Installed += () => { Setup(); @@ -221,6 +219,9 @@ namespace ShiftOS.WinForms this.Left = (Screen.PrimaryScreen.Bounds.Width - this.Width) / 2; this.Top = (Screen.PrimaryScreen.Bounds.Height - this.Height) / 2; ParentWindow.OnLoad(); + ParentWindow.OnSkinLoad(); + ParentWindow.OnUpgrade(); + } /// diff --git a/ShiftOS_TheReturn/Command.cs b/ShiftOS_TheReturn/Command.cs index c6d58e1..09cf206 100644 --- a/ShiftOS_TheReturn/Command.cs +++ b/ShiftOS_TheReturn/Command.cs @@ -104,7 +104,7 @@ namespace ShiftOS.Engine /// /// Gets whether the dependent upgrade(s) are installed. /// - public bool Installed + public virtual bool Installed { get { diff --git a/ShiftOS_TheReturn/Commands.cs b/ShiftOS_TheReturn/Commands.cs index 0257f11..ce94030 100644 --- a/ShiftOS_TheReturn/Commands.cs +++ b/ShiftOS_TheReturn/Commands.cs @@ -612,7 +612,7 @@ shiftorium.buy{{upgrade:""{upg.ID}""}}"); cat = args["cat"].ToString(); } - Dictionary upgrades = new Dictionary(); + Dictionary upgrades = new Dictionary(); int maxLength = 5; IEnumerable upglist = Shiftorium.GetAvailable(); diff --git a/ShiftOS_TheReturn/SaveSystem.cs b/ShiftOS_TheReturn/SaveSystem.cs index 998c60d..3e68a70 100644 --- a/ShiftOS_TheReturn/SaveSystem.cs +++ b/ShiftOS_TheReturn/SaveSystem.cs @@ -223,7 +223,7 @@ namespace ShiftOS.Engine public static event EmptyEventHandler GameReady; - public static void TransferCodepointsToVoid(int amount) + public static void TransferCodepointsToVoid(long amount) { CurrentSave.Codepoints -= amount; NotificationDaemon.AddNotification(NotificationType.CodepointsSent, amount); diff --git a/ShiftOS_TheReturn/ShiftOS.Engine.csproj b/ShiftOS_TheReturn/ShiftOS.Engine.csproj index b6ff903..f7b730f 100644 --- a/ShiftOS_TheReturn/ShiftOS.Engine.csproj +++ b/ShiftOS_TheReturn/ShiftOS.Engine.csproj @@ -124,6 +124,7 @@ + diff --git a/ShiftOS_TheReturn/ShiftnetSite.cs b/ShiftOS_TheReturn/ShiftnetSite.cs new file mode 100644 index 0000000..5460171 --- /dev/null +++ b/ShiftOS_TheReturn/ShiftnetSite.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShiftOS.Engine +{ + public interface IShiftnetSite + { + void Setup(); + void OnSkinLoad(); + void OnUpgrade(); + + event Action GoToUrl; + event Action GoBack; + } + + /// + /// Marks a shiftnet site as a fundamental, and will make it display on the homepage. + /// + public class ShiftnetFundamentalAttribute : Attribute + { + + } + + public interface IShiftnetClient + { + void NavigateToUrl(string url); + void RefreshSite(); + } + + public class ShiftnetSiteAttribute : Attribute + { + public ShiftnetSiteAttribute(string url, string name, string description) + { + Url = url; + Name = name; + Description = description; + } + + public string Url { get; private set; } + public string Name { get; private set; } + public string Description { get; private set; } + } +} diff --git a/ShiftOS_TheReturn/Shiftorium.cs b/ShiftOS_TheReturn/Shiftorium.cs index 43ea13a..c46aed0 100644 --- a/ShiftOS_TheReturn/Shiftorium.cs +++ b/ShiftOS_TheReturn/Shiftorium.cs @@ -85,7 +85,7 @@ namespace ShiftOS.Engine return GetDefaults().Where(x => x.Category == cat).FirstOrDefault(x => x.Installed == false) == null; } - public static bool Buy(string id, int cost) + public static bool Buy(string id, long cost) { if(SaveSystem.CurrentSave.Codepoints >= cost) { @@ -188,7 +188,7 @@ namespace ShiftOS.Engine } - public static int GetCPValue(string id) + public static long GetCPValue(string id) { foreach(var upg in GetDefaults()) { @@ -316,7 +316,7 @@ namespace ShiftOS.Engine { public string Name { get; set; } public string Description { get; set; } - public int Cost { get; set; } + public long Cost { get; set; } public string ID { get { return (this.Id != null ? this.Id : (Name.ToLower().Replace(" ", "_"))); } } public string Id { get; set; } public string Category { get; set; } -- cgit v1.2.3 From d4316e75fc876ec7ceac3f1a9362ef7b36ca40cf Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 24 Apr 2017 21:01:42 -0400 Subject: Audio Player work. --- .../Applications/AudioPlayer.Designer.cs | 174 ++++++++++++++++++++- ShiftOS.WinForms/Applications/AudioPlayer.cs | 133 +++++++++++++++- ShiftOS.WinForms/Applications/AudioPlayer.resx | 134 ++++++++++++++++ ShiftOS.WinForms/Resources/Shiftorium.txt | 7 - ShiftOS.WinForms/ShiftOS.WinForms.csproj | 26 +++ ShiftOS.WinForms/ShiftnetSites/AppscapeMain.cs | 2 +- ShiftOS.WinForms/packages.config | 1 + ShiftOS_TheReturn/Shiftorium.cs | 10 ++ 8 files changed, 477 insertions(+), 10 deletions(-) create mode 100644 ShiftOS.WinForms/Applications/AudioPlayer.resx (limited to 'ShiftOS_TheReturn/Shiftorium.cs') diff --git a/ShiftOS.WinForms/Applications/AudioPlayer.Designer.cs b/ShiftOS.WinForms/Applications/AudioPlayer.Designer.cs index 83f41d2..825413d 100644 --- a/ShiftOS.WinForms/Applications/AudioPlayer.Designer.cs +++ b/ShiftOS.WinForms/Applications/AudioPlayer.Designer.cs @@ -52,10 +52,182 @@ namespace ShiftOS.WinForms.Applications /// private void InitializeComponent() { - components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AudioPlayer)); + this.wpaudio = new AxWMPLib.AxWindowsMediaPlayer(); + this.toolStripContainer1 = new System.Windows.Forms.ToolStripContainer(); + this.lbtracks = new System.Windows.Forms.ListBox(); + this.flcontrols = new System.Windows.Forms.FlowLayoutPanel(); + this.btnplay = new System.Windows.Forms.Button(); + this.pgplaytime = new ShiftOS.WinForms.Controls.ShiftedProgressBar(); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.addSongToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.clearToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.shuffleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + ((System.ComponentModel.ISupportInitialize)(this.wpaudio)).BeginInit(); + this.toolStripContainer1.ContentPanel.SuspendLayout(); + this.toolStripContainer1.TopToolStripPanel.SuspendLayout(); + this.toolStripContainer1.SuspendLayout(); + this.flcontrols.SuspendLayout(); + this.menuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // wpaudio + // + this.wpaudio.Dock = System.Windows.Forms.DockStyle.Fill; + this.wpaudio.Enabled = true; + this.wpaudio.Location = new System.Drawing.Point(0, 0); + this.wpaudio.Name = "wpaudio"; + this.wpaudio.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("wpaudio.OcxState"))); + this.wpaudio.Size = new System.Drawing.Size(798, 471); + this.wpaudio.TabIndex = 0; + this.wpaudio.Visible = false; + // + // toolStripContainer1 + // + // + // toolStripContainer1.ContentPanel + // + this.toolStripContainer1.ContentPanel.Controls.Add(this.lbtracks); + this.toolStripContainer1.ContentPanel.Controls.Add(this.flcontrols); + this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size(798, 447); + this.toolStripContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.toolStripContainer1.LeftToolStripPanelVisible = false; + this.toolStripContainer1.Location = new System.Drawing.Point(0, 0); + this.toolStripContainer1.Name = "toolStripContainer1"; + this.toolStripContainer1.RightToolStripPanelVisible = false; + this.toolStripContainer1.Size = new System.Drawing.Size(798, 471); + this.toolStripContainer1.TabIndex = 1; + this.toolStripContainer1.Text = "toolStripContainer1"; + // + // toolStripContainer1.TopToolStripPanel + // + this.toolStripContainer1.TopToolStripPanel.Controls.Add(this.menuStrip1); + // + // lbtracks + // + this.lbtracks.Dock = System.Windows.Forms.DockStyle.Fill; + this.lbtracks.FormattingEnabled = true; + this.lbtracks.Location = new System.Drawing.Point(0, 0); + this.lbtracks.Name = "lbtracks"; + this.lbtracks.Size = new System.Drawing.Size(798, 418); + this.lbtracks.TabIndex = 1; + this.lbtracks.SelectedIndexChanged += new System.EventHandler(this.lbtracks_SelectedIndexChanged); + // + // flcontrols + // + this.flcontrols.AutoSize = true; + this.flcontrols.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.flcontrols.Controls.Add(this.btnplay); + this.flcontrols.Controls.Add(this.pgplaytime); + this.flcontrols.Dock = System.Windows.Forms.DockStyle.Bottom; + this.flcontrols.Location = new System.Drawing.Point(0, 418); + this.flcontrols.Name = "flcontrols"; + this.flcontrols.Size = new System.Drawing.Size(798, 29); + this.flcontrols.TabIndex = 0; + // + // btnplay + // + this.btnplay.AutoSize = true; + this.btnplay.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.btnplay.Location = new System.Drawing.Point(3, 3); + this.btnplay.Name = "btnplay"; + this.btnplay.Size = new System.Drawing.Size(37, 23); + this.btnplay.TabIndex = 0; + this.btnplay.Text = "Play"; + this.btnplay.UseVisualStyleBackColor = true; + this.btnplay.Click += new System.EventHandler(this.btnplay_Click); + // + // pgplaytime + // + this.pgplaytime.BlockSize = 5; + this.pgplaytime.Location = new System.Drawing.Point(46, 3); + this.pgplaytime.Maximum = 100; + this.pgplaytime.Name = "pgplaytime"; + this.pgplaytime.Size = new System.Drawing.Size(749, 23); + this.pgplaytime.Style = System.Windows.Forms.ProgressBarStyle.Continuous; + this.pgplaytime.TabIndex = 1; + this.pgplaytime.Tag = "keepbg"; + this.pgplaytime.Text = "shiftedProgressBar1"; + this.pgplaytime.Value = 0; + // + // menuStrip1 + // + this.menuStrip1.Dock = System.Windows.Forms.DockStyle.None; + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.addSongToolStripMenuItem, + this.clearToolStripMenuItem, + this.shuffleToolStripMenuItem, + this.removeToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(798, 24); + this.menuStrip1.TabIndex = 0; + this.menuStrip1.Text = "menuStrip1"; + // + // addSongToolStripMenuItem + // + this.addSongToolStripMenuItem.Name = "addSongToolStripMenuItem"; + this.addSongToolStripMenuItem.Size = new System.Drawing.Size(71, 20); + this.addSongToolStripMenuItem.Text = "Add Song"; + this.addSongToolStripMenuItem.Click += new System.EventHandler(this.addSongToolStripMenuItem_Click); + // + // clearToolStripMenuItem + // + this.clearToolStripMenuItem.Name = "clearToolStripMenuItem"; + this.clearToolStripMenuItem.Size = new System.Drawing.Size(46, 20); + this.clearToolStripMenuItem.Text = "Clear"; + this.clearToolStripMenuItem.Click += new System.EventHandler(this.clearToolStripMenuItem_Click); + // + // shuffleToolStripMenuItem + // + this.shuffleToolStripMenuItem.Name = "shuffleToolStripMenuItem"; + this.shuffleToolStripMenuItem.Size = new System.Drawing.Size(56, 20); + this.shuffleToolStripMenuItem.Text = "Shuffle"; + this.shuffleToolStripMenuItem.Click += new System.EventHandler(this.shuffleToolStripMenuItem_Click); + // + // removeToolStripMenuItem + // + this.removeToolStripMenuItem.Name = "removeToolStripMenuItem"; + this.removeToolStripMenuItem.Size = new System.Drawing.Size(62, 20); + this.removeToolStripMenuItem.Text = "Remove"; + this.removeToolStripMenuItem.Click += new System.EventHandler(this.removeToolStripMenuItem_Click); + // + // AudioPlayer + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.toolStripContainer1); + this.Controls.Add(this.wpaudio); + this.Name = "AudioPlayer"; + this.Size = new System.Drawing.Size(798, 471); + ((System.ComponentModel.ISupportInitialize)(this.wpaudio)).EndInit(); + this.toolStripContainer1.ContentPanel.ResumeLayout(false); + this.toolStripContainer1.ContentPanel.PerformLayout(); + this.toolStripContainer1.TopToolStripPanel.ResumeLayout(false); + this.toolStripContainer1.TopToolStripPanel.PerformLayout(); + this.toolStripContainer1.ResumeLayout(false); + this.toolStripContainer1.PerformLayout(); + this.flcontrols.ResumeLayout(false); + this.flcontrols.PerformLayout(); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.ResumeLayout(false); + } #endregion + + private AxWMPLib.AxWindowsMediaPlayer wpaudio; + private System.Windows.Forms.ToolStripContainer toolStripContainer1; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem addSongToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem clearToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem shuffleToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem removeToolStripMenuItem; + private System.Windows.Forms.ListBox lbtracks; + private System.Windows.Forms.FlowLayoutPanel flcontrols; + private System.Windows.Forms.Button btnplay; + private Controls.ShiftedProgressBar pgplaytime; } } diff --git a/ShiftOS.WinForms/Applications/AudioPlayer.cs b/ShiftOS.WinForms/Applications/AudioPlayer.cs index b8be6af..6d4d58a 100644 --- a/ShiftOS.WinForms/Applications/AudioPlayer.cs +++ b/ShiftOS.WinForms/Applications/AudioPlayer.cs @@ -32,9 +32,15 @@ using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using ShiftOS.Engine; +using NAudio; +using System.Threading; namespace ShiftOS.WinForms.Applications { + [AppscapeEntry("Audio Player", "Play music and other sounds on your computer.", 3047, 1000, "file_skimmer", "Entertainment")] + [Launcher("Audio Player", false, null, "Entertainment")] + [WinOpen("audio_player")] + [DefaultTitle("Audio Player")] public partial class AudioPlayer : UserControl, IShiftOSWindow { public AudioPlayer() @@ -42,9 +48,12 @@ namespace ShiftOS.WinForms.Applications InitializeComponent(); } + NAudio.Wave.WaveOut o = null; + + public void OnLoad() { - + wpaudio.Hide(); } public void OnSkinLoad() @@ -54,6 +63,9 @@ namespace ShiftOS.WinForms.Applications public bool OnUnload() { + o?.Dispose(); + mp3?.Dispose(); + memstream?.Dispose(); return true; } @@ -61,5 +73,124 @@ namespace ShiftOS.WinForms.Applications { } + + private void addSongToolStripMenuItem_Click(object sender, EventArgs e) + { + FileSkimmerBackend.GetFile(new[] { ".mp3", ".wav" }, FileOpenerStyle.Open, (path) => + { + if (!lbtracks.Items.Contains(path)) + lbtracks.Items.Add(path); + else + Infobox.Show("Song already added!", "That song is already added to the Audio Player playlist."); + }); + } + + private void clearToolStripMenuItem_Click(object sender, EventArgs e) + { + lbtracks.Items.Clear(); + } + + private void shuffleToolStripMenuItem_Click(object sender, EventArgs e) + { + var lst = new object[lbtracks.Items.Count]; + lbtracks.Items.CopyTo(lst, 0); + var shuffle = new List(lst); + shuffle.Shuffle(); + lbtracks.Items.Clear(); + lbtracks.Items.AddRange(shuffle.ToArray()); + } + + private void removeToolStripMenuItem_Click(object sender, EventArgs e) + { + lbtracks.Items.RemoveAt(lbtracks.SelectedIndex); + } + + private void btnplay_Click(object sender, EventArgs e) + { + if(o == null) + { + if (lbtracks.Items.Count > 0) + { + Play(lbtracks.Items[0].ToString()); + btnplay.Text = "Pause"; + } + else + Infobox.Show("Error", "No tracks to play! Please add a track to the playlist."); + } + else if(o.PlaybackState == NAudio.Wave.PlaybackState.Paused) + { + o.Resume(); + btnplay.Text = "Pause"; + } + else if(o.PlaybackState == NAudio.Wave.PlaybackState.Playing) + { + o.Pause(); + btnplay.Text = "Play"; + } + } + + System.IO.Stream memstream = null; + NAudio.Wave.Mp3FileReader mp3 = null; + + public void Play(string track) + { + if (o != null) + { + o.Dispose(); + mp3.Dispose(); + memstream.Dispose(); + } + var bytes = ShiftOS.Objects.ShiftFS.Utils.ReadAllBytes(track); + memstream = new System.IO.MemoryStream(bytes); + mp3 = new NAudio.Wave.Mp3FileReader(memstream); + o = new NAudio.Wave.WaveOut(); + o.Init(mp3); + o.Play(); + + pgplaytime.Value = 0; + pgplaytime.Maximum = (int)mp3.Length; + new Thread(() => + { + while(o.PlaybackState == NAudio.Wave.PlaybackState.Playing || o.PlaybackState == NAudio.Wave.PlaybackState.Paused) + { + long time = mp3.Position; + if(time != mp3.Position) + { + time = mp3.Position; + this.Invoke(new Action(() => + { + pgplaytime.Value = (int)time; + })); + } + } + }).Start(); + } + + private void lbtracks_SelectedIndexChanged(object sender, EventArgs e) + { + try + { + Play(lbtracks.SelectedItem.ToString()); + } + catch { } + } + } + + public static class ListExtensions + { + private static Random rng = new Random(); + + public static void Shuffle(this IList list) + { + int n = list.Count; + while (n > 1) + { + n--; + int k = rng.Next(n + 1); + T value = list[k]; + list[k] = list[n]; + list[n] = value; + } + } } } diff --git a/ShiftOS.WinForms/Applications/AudioPlayer.resx b/ShiftOS.WinForms/Applications/AudioPlayer.resx new file mode 100644 index 0000000..d484b91 --- /dev/null +++ b/ShiftOS.WinForms/Applications/AudioPlayer.resx @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACFTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5BeEhvc3QrU3RhdGUBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAtwAAAAIB + AAAAAQAAAAAAAAAAAAAAAKIAAAAAAwAACAAAAAAABQAAAAAAAADwPwMAAAAAAAUAAAAAAAAAAAAIAAIA + AAAAAAMAAQAAAAsA//8DAAAAAAALAP//CAACAAAAAAADADIAAAALAAAACAAKAAAAbgBvAG4AZQAAAAsA + AAALAAAACwD//wsA//8LAAAACAACAAAAAAAIAAIAAAAAAAgAAgAAAAAACAACAAAAAAALAAAAelIAAK4w + AAAL + + + + 17, 17 + + \ No newline at end of file diff --git a/ShiftOS.WinForms/Resources/Shiftorium.txt b/ShiftOS.WinForms/Resources/Shiftorium.txt index e68277c..79d4dd0 100644 --- a/ShiftOS.WinForms/Resources/Shiftorium.txt +++ b/ShiftOS.WinForms/Resources/Shiftorium.txt @@ -633,13 +633,6 @@ Category: "Enhancements", Dependencies: "mud_fundamentals;window_manager;pong_upgrade" }, - { - Name: "Audio Player", - Cost: 10000, - Description: "Want to listen to the greatest tunes? Well get this app asap!", - Category: "Applications", - Dependencies: "desktop;wm_free_placement" - }, { Name: "Audio Player AL", Cost: 150, diff --git a/ShiftOS.WinForms/ShiftOS.WinForms.csproj b/ShiftOS.WinForms/ShiftOS.WinForms.csproj index a8d1aaa..dac803d 100644 --- a/ShiftOS.WinForms/ShiftOS.WinForms.csproj +++ b/ShiftOS.WinForms/ShiftOS.WinForms.csproj @@ -38,6 +38,10 @@ True + + ..\packages\NAudio.1.8.0\lib\net35\NAudio.dll + True + ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll True @@ -374,6 +378,9 @@ Artpad.cs + + AudioPlayer.cs + Calculator.cs @@ -746,6 +753,25 @@ + + + {6BF52A50-394A-11D3-B153-00C04F79FAA6} + 1 + 0 + 0 + aximp + False + + + {6BF52A50-394A-11D3-B153-00C04F79FAA6} + 1 + 0 + 0 + tlbimp + False + True + +