diff --git a/.vs/config/applicationhost.config b/.vs/config/applicationhost.config new file mode 100644 index 0000000..b42cd34 --- /dev/null +++ b/.vs/config/applicationhost.config @@ -0,0 +1,1030 @@ + + + + + + + + +
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+ + +
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ShiftOS.Objects/ChatRoom.cs b/ShiftOS.Objects/ChatRoom.cs new file mode 100644 index 0000000..e4c89ce --- /dev/null +++ b/ShiftOS.Objects/ChatRoom.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShiftOS.Objects +{ + public class ChatRoom + { + public string Id { get; set; } + public string Name { get; set; } + + public List Messages { get; set; } + } +} diff --git a/ShiftOS.Objects/EngineShiftnetSubscription.cs b/ShiftOS.Objects/EngineShiftnetSubscription.cs index 1296a98..c319f18 100644 --- a/ShiftOS.Objects/EngineShiftnetSubscription.cs +++ b/ShiftOS.Objects/EngineShiftnetSubscription.cs @@ -10,7 +10,7 @@ namespace ShiftOS.Objects { public string Name { get; set; } public string Description { get; set; } - public int CostPerMonth { get; set; } + public uint CostPerMonth { get; set; } public int DownloadSpeed { get; set; } public string Company { get; set; } } diff --git a/ShiftOS.Objects/Save.cs b/ShiftOS.Objects/Save.cs index 2a02bbc..7891a22 100644 --- a/ShiftOS.Objects/Save.cs +++ b/ShiftOS.Objects/Save.cs @@ -26,20 +26,94 @@ using System; using System.Collections.Generic; using System.Dynamic; using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Threading; namespace ShiftOS.Objects { //Better to store this stuff server-side so we can do some neat stuff with hacking... public class Save { + public bool MusicEnabled = true; + public bool SoundEnabled = true; + public int MusicVolume = 100; [Obsolete("This save variable is no longer used in Beta 2.4 and above of ShiftOS. Please use ShiftOS.Engine.SaveSystem.CurrentUser.Username to access the current user's username.")] public string Username { get; set; } + private List _setCpCallbacks = new List(); // everything in this list is called by Codepoints.set() and syncCp(). + private ulong _cp = 0; // locally cached codepoints counter + private Object _cpLock = new Object(); // locked when modifying or reading the codepoints counter + private Object _webLock = new Object(); // locked when communicating with the server + private Timer _updTimer; // timer to start a new sync thread every 5 minutes + + // Sync local Codepoints count with the server. + public void syncCp() + { + new Thread(() => + { + lock (_cpLock) + { + lock (_webLock) + { + var uc = new ShiftOS.Unite.UniteClient("", UniteAuthToken); + _cp = uc.GetCodepoints(); + } + } + foreach (Action a in _setCpCallbacks) + a(); + }).Start(); + } + + // we have to write these wrapper functions so we can keep _setCpCallbacks private, + // so that it doesn't get serialised + public void addSetCpCallback(Action callback) + { + _setCpCallbacks.Add(callback); + } + + public void removeSetCpCallback(Action callback) + { + _setCpCallbacks.Remove(callback); + } + + public ulong Codepoints + { + get + { + if (_updTimer == null) + _updTimer = new Timer((o) => syncCp(), null, 0, 300000); + lock (_cpLock) + { + return _cp; + } + } + set + { + lock (_cpLock) + { + _cp = value; + new Thread(() => + { + lock (_webLock) + { + try + { + var uc = new ShiftOS.Unite.UniteClient("", UniteAuthToken); + uc.SetCodepoints(value); + } + catch + { } + } + }) + { + IsBackground = false + }.Start(); + } + foreach (Action a in _setCpCallbacks) + a(); + } + } - public long Codepoints { get; set; } public Dictionary Upgrades { get; set; } public int StoryPosition { get; set; } public string Language { get; set; } @@ -99,6 +173,11 @@ namespace ShiftOS.Objects } public List Users { get; set; } + + /// + /// DO NOT MODIFY THIS. EVER. YOU WILL BREAK THE STORYLINE. Let the engine do it's job. + /// + public string PickupPoint { get; set; } } public class SettingsObject : DynamicObject diff --git a/ShiftOS.Objects/ShiftOS.Objects.csproj b/ShiftOS.Objects/ShiftOS.Objects.csproj index 7a19aeb..9ed8c3b 100644 --- a/ShiftOS.Objects/ShiftOS.Objects.csproj +++ b/ShiftOS.Objects/ShiftOS.Objects.csproj @@ -45,6 +45,7 @@ + @@ -56,8 +57,10 @@ + + diff --git a/ShiftOS.Objects/Shop.cs b/ShiftOS.Objects/Shop.cs index 65f5746..c603523 100644 --- a/ShiftOS.Objects/Shop.cs +++ b/ShiftOS.Objects/Shop.cs @@ -42,7 +42,7 @@ namespace ShiftOS.Objects { public string Name { get; set; } public string Description { get; set; } - public int Cost { get; set; } + public ulong Cost { get; set; } public int FileType { get; set; } public byte[] MUDFile { get; set; } } diff --git a/ShiftOS.Objects/UniteClient.cs b/ShiftOS.Objects/UniteClient.cs new file mode 100644 index 0000000..ccd721b --- /dev/null +++ b/ShiftOS.Objects/UniteClient.cs @@ -0,0 +1,236 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; +using ShiftOS.Objects; + +namespace ShiftOS.Unite +{ + public class UniteClient + { + /// + /// Gets a string represents the user token for this Unite Client. + /// + public string Token { get; private set; } + + /// + /// Gets the base URL used in all API calls. Retrieved from the user's servers.json file. + /// + public string BaseURL + { + get + { + return UserConfig.Get().UniteUrl; + } + } + + /// + /// Get the display name of a user. + /// + /// The user ID to look at. + /// + public string GetDisplayNameId(string id) + { + return MakeCall("/API/GetDisplayName/" + id); + } + + /// + /// Get the Pong highscore stats for all users. + /// + /// + public PongHighscoreModel GetPongHighscores() + { + return JsonConvert.DeserializeObject(MakeCall("/API/GetPongHighscores")); + } + + /// + /// Create a new instance of the object. + /// + /// Unused. + /// The user API token to use for this client (see http://getshiftos.ml/Manage and click "API" to see your tokens) + public UniteClient(string baseurl, string usertoken) + { + //Handled by the servers.json file + //BaseURL = baseurl; + Token = usertoken; + } + + /// + /// Make a call to the Unite API using the current user token and base URL. + /// + /// The path, relative to the base URL, to call. + /// The server's response. + internal string MakeCall(string url) + { + var webrequest = WebRequest.Create(BaseURL + url); + webrequest.Headers.Add("Authentication: Token " + Token); + using (var response = webrequest.GetResponse()) + { + using (var stream = response.GetResponseStream()) + { + using (var reader = new System.IO.StreamReader(stream)) + { + return reader.ReadToEnd(); + } + } + } + } + + /// + /// Get the Pong codepoint highscore for the current user. + /// + /// The amount of Codepoints returned by the server + public ulong GetPongCP() + { + return Convert.ToUInt64(MakeCall("/API/GetPongCP")); + } + + /// + /// Get the pong highest level score for this user + /// + /// The highest level the user has reached. + public int GetPongLevel() + { + return Convert.ToInt32(MakeCall("/API/GetPongLevel")); + } + + /// + /// Set the user's highest level record for Pong. + /// + /// The level to set the record to. + public void SetPongLevel(int value) + { + MakeCall("/API/SetPongLevel/" + value.ToString()); + } + + /// + /// Set the pong Codepoints record for the user + /// + /// The amount of Codepoints to set the record to + public void SetPongCP(ulong value) + { + MakeCall("/API/SetPongCP/" + value.ToString()); + } + + /// + /// Get the user's email address. + /// + /// The user's email address. + public string GetEmail() + { + return MakeCall("/API/GetEmail"); + } + + /// + /// Get the user's system name. + /// + /// The user's system name. + public string GetSysName() + { + return MakeCall("/API/GetSysName"); + } + + /// + /// Set the user's system name. + /// + /// The system name to set the record to. + public void SetSysName(string value) + { + MakeCall("/API/SetSysName/" + value); + } + + /// + /// Get the user's display name. + /// + /// The user's display name. + public string GetDisplayName() + { + return MakeCall("/API/GetDisplayName"); + } + + /// + /// Set the user's display name. + /// + /// The display name to set the user's account to. + public void SetDisplayName(string value) + { + MakeCall("/API/SetDisplayName/" + value.ToString()); + } + + /// + /// Get the user's full name if they have set it in their profile. + /// + /// Empty string if the user hasn't set their fullname, else, a string representing their fullname. + public string GetFullName() + { + return MakeCall("/API/GetFullName"); + } + + /// + /// Set the user's fullname. + /// + /// The new fullname. + public void SetFullName(string value) + { + MakeCall("/API/SetFullName/" + value.ToString()); + } + + /// + /// Get the user's codepoints. + /// + /// The amount of codepoints stored on the server for this user. + public ulong GetCodepoints() + { + return Convert.ToUInt64(MakeCall("/API/GetCodepoints")); + } + + /// + /// Set the user's codepoints. + /// + /// The amount of codepoints to set the user's codepoints value to. + public void SetCodepoints(ulong value) + { + MakeCall("/API/SetCodepoints/" + value.ToString()); + } + } + + /// + /// API data model for Unite pong highscores. + /// + public class PongHighscoreModel + { + /// + /// Amount of pages in this list. + /// + public int Pages { get; set; } + + /// + /// An array representing the highscores found on the server. + /// + public PongHighscore[] Highscores { get; set; } + } + + /// + /// API data model for a single Pong highscore. + /// + public class PongHighscore + { + /// + /// The user ID linked to this highscore. + /// + public string UserId { get; set; } + + /// + /// The highscore's level record. + /// + public int Level { get; set; } + + /// + /// The highscore's codepoint cashout record. + /// + public long CodepointsCashout { get; set; } + } +} diff --git a/ShiftOS.Objects/UserConfig.cs b/ShiftOS.Objects/UserConfig.cs new file mode 100644 index 0000000..61d11b8 --- /dev/null +++ b/ShiftOS.Objects/UserConfig.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace ShiftOS.Objects +{ + public class UserConfig + { + public string UniteUrl { get; set; } + public string DigitalSocietyAddress { get; set; } + public int DigitalSocietyPort { get; set; } + + public static UserConfig Get() + { + var conf = new UserConfig + { + UniteUrl = "http://getshiftos.ml", + DigitalSocietyAddress = "michaeltheshifter.me", + DigitalSocietyPort = 13370 + }; + + if (!File.Exists("servers.json")) + { + File.WriteAllText("servers.json", JsonConvert.SerializeObject(conf, Formatting.Indented)); + } + else + { + conf = JsonConvert.DeserializeObject(File.ReadAllText("servers.json")); + } + return conf; + } + } +} diff --git a/ShiftOS.Server/Program.cs b/ShiftOS.Server/Program.cs index 97c8a66..5170ccd 100644 --- a/ShiftOS.Server/Program.cs +++ b/ShiftOS.Server/Program.cs @@ -54,17 +54,6 @@ namespace ShiftOS.Server /// public class Program { - /// - /// The admin username. - /// - public static string AdminUsername = "admin"; - - /// - /// The admin password. - /// - public static string AdminPassword = "admin"; - - /// /// The server. /// @@ -86,16 +75,28 @@ namespace ShiftOS.Server /// The command-line arguments. public static void Main(string[] args) { + Thread.Sleep(2000); + AppDomain.CurrentDomain.UnhandledException += (o, a) => + { + System.Diagnostics.Process.Start("ShiftOS.Server.exe"); + Environment.Exit(0); + }; + UserConfig.Get(); System.Timers.Timer tmr = new System.Timers.Timer(5000); tmr.Elapsed += (o, a) => { if (server.IsOnline) { - server.DispatchAll(new NetObject("heartbeat", new ServerMessage + + try { - Name = "heartbeat", - GUID = "server" - })); + server.DispatchAll(new NetObject("heartbeat", new ServerMessage + { + Name = "heartbeat", + GUID = "server" + })); + } + catch { } } }; if (!Directory.Exists("saves")) @@ -154,13 +155,7 @@ namespace ShiftOS.Server Console.WriteLine("FUCK. Something HORRIBLE JUST HAPPENED."); }; - AppDomain.CurrentDomain.UnhandledException += (o, a) => - { - if(server.IsOnline == true) - server.Stop(); - System.Diagnostics.Process.Start("ShiftOS.Server.exe"); - }; - + server.OnReceived += (o, a) => { var obj = a.Data.Object; @@ -207,7 +202,6 @@ namespace ShiftOS.Server task.Wait(); */ - RandomUserGenerator.StartThread(); while (server.IsOnline) { diff --git a/ShiftOS.Server/RandomUserGenerator.cs b/ShiftOS.Server/RandomUserGenerator.cs index 3a62f9c..6da891d 100644 --- a/ShiftOS.Server/RandomUserGenerator.cs +++ b/ShiftOS.Server/RandomUserGenerator.cs @@ -111,7 +111,7 @@ namespace ShiftOS.Server break; } - sve.Codepoints = rnd.Next(startCP, maxAmt); + sve.Codepoints = (ulong)rnd.Next(startCP, maxAmt); //FS treasure generation. /* diff --git a/ShiftOS.Server/SaveManager.cs b/ShiftOS.Server/SaveManager.cs index 63aa2bf..cb2e1ba 100644 --- a/ShiftOS.Server/SaveManager.cs +++ b/ShiftOS.Server/SaveManager.cs @@ -189,7 +189,7 @@ namespace ShiftOS.Server //Update the shiftos website with the user's codepoints. if (!string.IsNullOrWhiteSpace(sav.UniteAuthToken)) { - var wreq = WebRequest.Create("http://getshiftos.ml/API/SetCodepoints/" + sav.Codepoints.ToString()); + var wreq = WebRequest.Create(UserConfig.Get().UniteUrl + "/API/SetCodepoints/" + sav.Codepoints.ToString()); wreq.Headers.Add("Authentication: Token " + sav.UniteAuthToken); wreq.GetResponse(); } @@ -207,8 +207,7 @@ namespace ShiftOS.Server { var save = JsonConvert.DeserializeObject(ReadEncFile(savefile)); - - if (save.UniteAuthToken==token) + if (save.UniteAuthToken == token) { if (save.ID == new Guid()) { @@ -216,6 +215,31 @@ namespace ShiftOS.Server WriteEncFile(savefile, JsonConvert.SerializeObject(save)); } + var wr = HttpWebRequest.Create(UserConfig.Get().UniteUrl + "/API/GetCodepoints"); + wr.Headers.Add("Authentication: Token " + save.UniteAuthToken); + try + { + using (var resp = wr.GetResponse()) + { + using (var str = resp.GetResponseStream()) + { + using (var reader = new StreamReader(str)) + { + Console.WriteLine("This user has " + reader.ReadToEnd() + " Codepoint(s)."); + } + } + } + } + catch (Exception ex) + { + Console.WriteLine(ex); + Program.server.DispatchTo(new Guid(guid), new NetObject("auth_failed", new ServerMessage + { + Name = "mud_login_denied", + GUID = "server" + })); + return; + } Program.server.DispatchTo(new Guid(guid), new NetObject("mud_savefile", new ServerMessage { @@ -228,15 +252,11 @@ namespace ShiftOS.Server } catch { } } - try + Program.server.DispatchTo(new Guid(guid), new NetObject("auth_failed", new ServerMessage { - Program.server.DispatchTo(new Guid(guid), new NetObject("auth_failed", new ServerMessage - { - Name = "mud_login_denied", - GUID = "server" - })); - } - catch { } + Name = "mud_login_denied", + GUID = "server" + })); } [MudRequest("delete_save", typeof(ClientSave))] @@ -268,7 +288,7 @@ namespace ShiftOS.Server { args["username"] = args["username"].ToString().ToLower(); string userName = args["username"] as string; - long cpAmount = (long)args["amount"]; + ulong cpAmount = (ulong)args["amount"]; if (Directory.Exists("saves")) { @@ -302,7 +322,7 @@ namespace ShiftOS.Server args["username"] = args["username"].ToString().ToLower(); string userName = args["username"] as string; string passw = args["password"] as string; - int cpAmount = (int)args["amount"]; + ulong cpAmount = (ulong)args["amount"]; if (Directory.Exists("saves")) { @@ -315,7 +335,7 @@ namespace ShiftOS.Server WriteEncFile(saveFile, JsonConvert.SerializeObject(saveFileContents, Formatting.Indented)); Program.ClientDispatcher.Broadcast("update_your_cp", new { username = userName, - amount = -cpAmount + amount = -(long)cpAmount }); Program.ClientDispatcher.DispatchTo("update_your_cp", guid, new { diff --git a/ShiftOS.WinForms/Applications/About.Designer.cs b/ShiftOS.WinForms/Applications/About.Designer.cs index ab76eab..989d79b 100644 --- a/ShiftOS.WinForms/Applications/About.Designer.cs +++ b/ShiftOS.WinForms/Applications/About.Designer.cs @@ -55,7 +55,7 @@ namespace ShiftOS.WinForms.Applications this.pictureBox1 = new System.Windows.Forms.PictureBox(); this.label1 = new System.Windows.Forms.Label(); this.lbshiftit = new System.Windows.Forms.Label(); - this.lbaboutdesc = new System.Windows.Forms.Label(); + this.lbaboutdesc = new System.Windows.Forms.TextBox(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); this.SuspendLayout(); // @@ -94,11 +94,11 @@ namespace ShiftOS.WinForms.Applications this.lbaboutdesc.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.lbaboutdesc.Location = new System.Drawing.Point(14, 126); + this.lbaboutdesc.Location = new System.Drawing.Point(23, 158); + this.lbaboutdesc.Multiline = true; this.lbaboutdesc.Name = "lbaboutdesc"; - this.lbaboutdesc.Size = new System.Drawing.Size(498, 328); + this.lbaboutdesc.Size = new System.Drawing.Size(492, 302); this.lbaboutdesc.TabIndex = 3; - this.lbaboutdesc.Text = "label2"; // // About // @@ -121,6 +121,6 @@ namespace ShiftOS.WinForms.Applications private System.Windows.Forms.PictureBox pictureBox1; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label lbshiftit; - private System.Windows.Forms.Label lbaboutdesc; + private System.Windows.Forms.TextBox lbaboutdesc; } } diff --git a/ShiftOS.WinForms/Applications/About.cs b/ShiftOS.WinForms/Applications/About.cs index f91e0cc..a27238d 100644 --- a/ShiftOS.WinForms/Applications/About.cs +++ b/ShiftOS.WinForms/Applications/About.cs @@ -53,18 +53,73 @@ namespace ShiftOS.WinForms.Applications lbaboutdesc.Text = $@"ShiftOS Copyright (c) 2015-{DateTime.Now.Year} Michael VanOverbeek and ShiftOS devs -Engine version: Milestone 3, 1.0 Beta Series (Developer mode ON) -Frontend version: 1.0 Beta 1.2 -Multi-user domain version: 1.0 Rolling-Release - -Music courtesy of Selulance. Listen to the Fractal Forest album here: -https://www.youtube.com/watch?v=LB5jAYDL3VU&t=913s +Engine version: Milestone 4, 1.0 Beta Series (Developer mode ON) +Frontend version: 1.0 Beta 2.5 +Digital Society version: 1.0 Rolling-Release +Project: Unite version: 1.0 Beta 1.7 Special thanks to Philip Adams, the original creator of ShiftOS for helping us grow our community of amazing Shifters by featuring us on the YouTube Millionaire series and advertising us throughout various other series ran by him. Also, thanks to Rylan Arbour, Victor Tran and the other community moderators and administrators for helping us keep the community peaceful. -Lastly, a huge special thanks to the community themselves - for testing, debugging, fixing, reporting bugs for, and enjoying our game even through its many failures, successes, revamps, etc. You guys are the reason we develop the game!"; +Lastly, a huge special thanks to the community themselves - for testing, debugging, fixing, reporting bugs for, and enjoying our game even through its many failures, successes, revamps, etc. You guys are the reason we develop the game! + + === Licensing information + +ShiftOS is licensed under the 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. + + == Credit where credit is due + + -- Development and staff team: + - Rylan Arbour (Lead community administrator) + - Victor Tran (Discord administrator) + - cjhannah (ShiftFS backend developer) + - AShifter (Project: Unite penetration tester) + - arencllc (ShiftLetters developer) + - Michael VanOverbeek (Lead developer, system administrator, the guy who wrote this text) + - fixylol, Nebble, TravisNC, Neptune (Community moderators) + - bandic00t_ (Skin Engine stresstesting) + + -- System audio + + - Default system event sounds (Infobox, Network Connecting, System Beeps) are from the original ShiftOS 0.0.x source code. + - Ambient music list courtesy of https://www.youtube.com/channel/UC56Qctnsu8wAyvzf4Yx6LIw (ArgoFox | Royalty Free Music) + +Tracklist: + + Dylan Hardy - Strangely Unaffected +Noxive - Home +Dylan Hardy and Abraham Alberto - Slow Drift +A Himitsu - Easier To Fade +Noxive - Resilience +Wanderflux - Visions +Aerocity - Cold Weather Kids +Aether - Wanderlust +Aerocity - Love Lost + + +Finally, special thanks to our Patreon supporters. Without you guys, our servers wouldn't be running, and you wouldn't be reading this."; } public string GetEngineVersion() @@ -107,7 +162,7 @@ Lastly, a huge special thanks to the community themselves - for testing, debuggi public bool OnUnload() { - return false; + return true; } public void OnUpgrade() diff --git a/ShiftOS.WinForms/Applications/AudioPlayer.Designer.cs b/ShiftOS.WinForms/Applications/AudioPlayer.Designer.cs index 6263ff7..d7f03a0 100644 --- a/ShiftOS.WinForms/Applications/AudioPlayer.Designer.cs +++ b/ShiftOS.WinForms/Applications/AudioPlayer.Designer.cs @@ -141,12 +141,10 @@ namespace ShiftOS.WinForms.Applications // // 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"; diff --git a/ShiftOS.WinForms/Applications/Chat.Designer.cs b/ShiftOS.WinForms/Applications/Chat.Designer.cs index d4b7211..7bfa4dd 100644 --- a/ShiftOS.WinForms/Applications/Chat.Designer.cs +++ b/ShiftOS.WinForms/Applications/Chat.Designer.cs @@ -54,6 +54,13 @@ namespace ShiftOS.WinForms.Applications { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Chat)); this.panel1 = new System.Windows.Forms.Panel(); + this.pnlstart = new System.Windows.Forms.Panel(); + this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + this.txtchatid = new System.Windows.Forms.TextBox(); + this.btnjoin = new System.Windows.Forms.Button(); + this.label3 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); this.rtbchat = new System.Windows.Forms.RichTextBox(); this.toolStrip1 = new System.Windows.Forms.ToolStrip(); this.tschatid = new System.Windows.Forms.ToolStripLabel(); @@ -62,12 +69,15 @@ namespace ShiftOS.WinForms.Applications this.txtuserinput = new System.Windows.Forms.ToolStripTextBox(); this.btnsend = new System.Windows.Forms.ToolStripButton(); this.panel1.SuspendLayout(); + this.pnlstart.SuspendLayout(); + this.flowLayoutPanel1.SuspendLayout(); this.toolStrip1.SuspendLayout(); this.tsbottombar.SuspendLayout(); this.SuspendLayout(); // // panel1 // + this.panel1.Controls.Add(this.pnlstart); this.panel1.Controls.Add(this.rtbchat); this.panel1.Controls.Add(this.toolStrip1); this.panel1.Controls.Add(this.tsbottombar); @@ -77,6 +87,82 @@ namespace ShiftOS.WinForms.Applications this.panel1.Size = new System.Drawing.Size(633, 318); this.panel1.TabIndex = 0; // + // pnlstart + // + this.pnlstart.Controls.Add(this.flowLayoutPanel1); + this.pnlstart.Controls.Add(this.label3); + this.pnlstart.Controls.Add(this.label2); + this.pnlstart.Controls.Add(this.label1); + this.pnlstart.Dock = System.Windows.Forms.DockStyle.Fill; + this.pnlstart.Location = new System.Drawing.Point(0, 25); + this.pnlstart.Name = "pnlstart"; + this.pnlstart.Size = new System.Drawing.Size(633, 268); + this.pnlstart.TabIndex = 4; + // + // flowLayoutPanel1 + // + this.flowLayoutPanel1.AutoSize = true; + this.flowLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.flowLayoutPanel1.Controls.Add(this.txtchatid); + this.flowLayoutPanel1.Controls.Add(this.btnjoin); + this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Top; + this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 118); + this.flowLayoutPanel1.Name = "flowLayoutPanel1"; + this.flowLayoutPanel1.Size = new System.Drawing.Size(633, 29); + this.flowLayoutPanel1.TabIndex = 3; + // + // txtchatid + // + this.txtchatid.Location = new System.Drawing.Point(3, 3); + this.txtchatid.Name = "txtchatid"; + this.txtchatid.Size = new System.Drawing.Size(192, 20); + this.txtchatid.TabIndex = 0; + // + // btnjoin + // + this.btnjoin.Location = new System.Drawing.Point(201, 3); + this.btnjoin.Name = "btnjoin"; + this.btnjoin.Size = new System.Drawing.Size(75, 23); + this.btnjoin.TabIndex = 1; + this.btnjoin.Text = "Join"; + this.btnjoin.UseVisualStyleBackColor = true; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Dock = System.Windows.Forms.DockStyle.Top; + this.label3.Location = new System.Drawing.Point(0, 85); + this.label3.Name = "label3"; + this.label3.Padding = new System.Windows.Forms.Padding(10); + this.label3.Size = new System.Drawing.Size(79, 33); + this.label3.TabIndex = 2; + this.label3.Tag = "header3"; + this.label3.Text = "Join a chat"; + // + // label2 + // + this.label2.Dock = System.Windows.Forms.DockStyle.Top; + this.label2.Location = new System.Drawing.Point(0, 33); + this.label2.Name = "label2"; + this.label2.Padding = new System.Windows.Forms.Padding(10); + this.label2.Size = new System.Drawing.Size(633, 52); + this.label2.TabIndex = 1; + this.label2.Text = "SimpleSRC is a simple chat program that utilises the ShiftOS Relay Chat protocol." + + " All you have to do is enter a chat code or system name, and SimpleSRC will try " + + "to initiate a chat for you."; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Dock = System.Windows.Forms.DockStyle.Top; + this.label1.Location = new System.Drawing.Point(0, 0); + this.label1.Name = "label1"; + this.label1.Padding = new System.Windows.Forms.Padding(10); + this.label1.Size = new System.Drawing.Size(143, 33); + this.label1.TabIndex = 0; + this.label1.Tag = "header1"; + this.label1.Text = "Welcome to SimpleSRC!"; + // // rtbchat // this.rtbchat.Dock = System.Windows.Forms.DockStyle.Fill; @@ -150,6 +236,10 @@ namespace ShiftOS.WinForms.Applications this.Size = new System.Drawing.Size(633, 318); this.panel1.ResumeLayout(false); this.panel1.PerformLayout(); + this.pnlstart.ResumeLayout(false); + this.pnlstart.PerformLayout(); + this.flowLayoutPanel1.ResumeLayout(false); + this.flowLayoutPanel1.PerformLayout(); this.toolStrip1.ResumeLayout(false); this.toolStrip1.PerformLayout(); this.tsbottombar.ResumeLayout(false); @@ -168,5 +258,12 @@ namespace ShiftOS.WinForms.Applications private System.Windows.Forms.ToolStrip tsbottombar; private System.Windows.Forms.ToolStripTextBox txtuserinput; private System.Windows.Forms.ToolStripButton btnsend; + private System.Windows.Forms.Panel pnlstart; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; + private System.Windows.Forms.TextBox txtchatid; + private System.Windows.Forms.Button btnjoin; } } diff --git a/ShiftOS.WinForms/Applications/Chat.cs b/ShiftOS.WinForms/Applications/Chat.cs index caf8cd2..7a2de81 100644 --- a/ShiftOS.WinForms/Applications/Chat.cs +++ b/ShiftOS.WinForms/Applications/Chat.cs @@ -33,75 +33,27 @@ using System.Threading.Tasks; using System.Windows.Forms; using Newtonsoft.Json; using ShiftOS.Engine; +using System.Threading; namespace ShiftOS.WinForms.Applications { [MultiplayerOnly] + [WinOpen("simplesrc")] + [Launcher("SimpleSRC Client", false, null, "Networking")] + [DefaultTitle("SimpleSRC Client")] + [AppscapeEntry("SimpleSRC", "A simple ShiftOS Relay Chat client that allows you to talk with other ShiftOS users from all over the world.", 300, 145, "file_skimmer", "Networking")] public partial class Chat : UserControl, IShiftOSWindow { - public Chat(string chatId) + public Chat() { InitializeComponent(); - id = chatId; - ServerManager.MessageReceived += (msg) => - { - if (msg.Name == "chat_msgreceived") - { - try - { - this.Invoke(new Action(() => - { - try - { - var args = JsonConvert.DeserializeObject>(msg.Contents); - var cmsg = new ShiftOS.Objects.ChatMessage(args["Username"] as string, args["SystemName"] as string, args["Message"] as string, args["Channel"] as string); - if (id == cmsg.Channel) - rtbchat.AppendText($"[{cmsg.Username}@{cmsg.SystemName}]: {cmsg.Message}{Environment.NewLine}"); - } - catch (Exception ex) - { - rtbchat.AppendText($"[system@multiuserdomain] Exception thrown by client: {ex}"); - } - })); - } - catch { } - } - else if(msg.Name == "chatlog") - { - try - { - this.Invoke(new Action(() => - { - rtbchat.AppendText(msg.Contents); - })); - } - catch { } - } - }; } - public void SendMessage(string msg) - { - if (!string.IsNullOrWhiteSpace(msg)) - { - rtbchat.AppendText($"[{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}] {msg}{Environment.NewLine}"); - - ServerManager.SendMessage("chat_send", JsonConvert.SerializeObject(new ShiftOS.Objects.ChatMessage(SaveSystem.CurrentSave.Username, SaveSystem.CurrentSave.SystemName, msg, id))); - } - else - { - rtbchat.AppendText($"[sys@multiuserdomain] You can't send blank messages. (only you can see this)"); - } - } - - - private string id = ""; - public void OnLoad() { - ServerManager.SendMessage("chat_getlog", JsonConvert.SerializeObject(new ShiftOS.Objects.ChatLogRequest(id, 50))); - - SendMessage("User has joined the chat."); + AllInstances.Add(this); + if (!string.IsNullOrWhiteSpace(ChatID)) + pnlstart.SendToBack(); RefreshUserInput(); } @@ -112,8 +64,8 @@ namespace ShiftOS.WinForms.Applications public bool OnUnload() { - SendMessage("User has left the chat."); - id = null; + AllInstances.Remove(this); + ChatID = null; return true; } @@ -146,15 +98,102 @@ namespace ShiftOS.WinForms.Applications { rtbchat.SelectionStart = rtbchat.Text.Length; rtbchat.ScrollToCaret(); - tschatid.Text = id; - tsuserdata.Text = $"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}"; + tschatid.Text = ChatID; + AppearanceManager.SetWindowTitle(this, tschatid.Text + " - SimpleSRC Client"); + tsuserdata.Text = $"{SaveSystem.CurrentUser.Username}@{SaveSystem.CurrentSave.SystemName}"; RefreshUserInput(); } + public static readonly List AllInstances = new List(); + + public static void SendMessage(string user, string destination, string msg) + { + foreach(var chat in AllInstances) + { + chat.PostMessage(user, destination, msg); + } + } + + public string ChatID = ""; + + public void PostMessage(string user, string destination, string message) + { + if (ChatID == destination) + { + this.Invoke(new Action(() => + { + rtbchat.SelectionFont = new Font(rtbchat.Font, FontStyle.Bold); + rtbchat.AppendText($"[{user}] "); + rtbchat.SelectionFont = rtbchat.Font; + rtbchat.AppendText(message); + rtbchat.AppendText(Environment.NewLine + Environment.NewLine); + })); + } + } + private void btnsend_Click(object sender, EventArgs e) { - SendMessage(txtuserinput.Text); + //Update ALL chat windows with this message if they're connected to this chat. + SendMessage($"{SaveSystem.CurrentUser.Username}@{SaveSystem.CurrentSave.SystemName}", ChatID, txtuserinput.Text); txtuserinput.Text = ""; } + + [Story("story_thefennfamily")] + public static void Story_TheFennFamily() + { + bool complete = false; + Infobox.Show("SimpleSRC", "A direct message has been sent to you on SimpleSRC from user \"maureenfenn@trisys\".", () => + { + string ch = "maureenfenn@trisys"; + var c = new Chat(); + c.ChatID = ch; + AppearanceManager.SetupWindow(c); + string you = $"{SaveSystem.CurrentUser.Username}@{SaveSystem.CurrentSave.SystemName}"; + + var t = new Thread(() => + { + SendMessage(you, ch, "User has joined the chat."); + Thread.Sleep(2000); + SendMessage(ch, ch, "Hello, " + you + ". My name is Maureen. Maureen Fenn."); + Thread.Sleep(2500); + SendMessage(ch, ch, "I am the author of the various Tri applications you may see on Appscape."); + Thread.Sleep(2000); + SendMessage(ch, ch, "I need your help with something..."); + Thread.Sleep(2500); + SendMessage(ch, ch, "Firstly, a little backstory. There was a time in ShiftOS when none of us were connected."); + Thread.Sleep(2500); + SendMessage(ch, ch, "There wasn't a Digital Society, we didn't have chat applications or anything..."); + Thread.Sleep(2000); + SendMessage(ch, ch, "All we had was the Shiftnet."); + Thread.Sleep(2500); + SendMessage(ch, ch, "However, in 2016, something happened called the \"connected revolution\". It was like, the invention of the Internet - it was huge for the world of ShiftOS."); + Thread.Sleep(2500); + SendMessage(ch, ch, "Before this, the only way you could earn Codepoints was through playing games in ShiftOS."); + Thread.Sleep(2500); + SendMessage(ch, ch, "I was the one who coded those games, and I would put them on a Shiftnet website that you can still access today, shiftnet/main/shiftgames."); + Thread.Sleep(2500); + SendMessage(ch, ch, "But when the Connected Revolution took place, things got difficult. My son, Nalyr Fenn, was born, and people stopped using my software and instead moved on to hacking eachother and stealing peoples' Codepoints."); + Thread.Sleep(2500); + SendMessage(ch, ch, "When Nalyr's sentience levels reached near human - i.e, he grew up, we decided to start TriOffice. It was a huge success, thanks to Aiden Nirh, the guy who runs Appscape."); + Thread.Sleep(2500); + SendMessage(ch, ch, "However... a few months ago he cut contact with us and we stopped receiving Codepoints from TriOffice."); + Thread.Sleep(2500); + SendMessage(ch, ch, "I'm running low - I can't afford to keep my system running much longer. You have to help!"); + Thread.Sleep(2500); + SendMessage(ch, ch, "Perhaps, you could breach Aiden's server and look for clues as to why he's against us? I'll reward you with the last Codepoints I have."); + Thread.Sleep(2500); + SendMessage(you, ch, "Alright, I'm in - but I don't know where to begin..."); + Thread.Sleep(2500); + SendMessage(ch, ch, "A little birdie tells me you know about the RTS exploits going around... Try using that on Aiden's server. You can find his systemname on Appscape under \"Contact Us.\" He has a mailserver on Appscape - and also has RTS on the same server."); + Thread.Sleep(2500); + SendMessage(ch, ch, "Good luck... My life depends on you!"); + complete = true; + }); + t.IsBackground = true; + t.Start(); + }); + while (!complete) + Thread.Sleep(10); + } } } diff --git a/ShiftOS.WinForms/Applications/Chat.resx b/ShiftOS.WinForms/Applications/Chat.resx index a7b2b93..e4a35ad 100644 --- a/ShiftOS.WinForms/Applications/Chat.resx +++ b/ShiftOS.WinForms/Applications/Chat.resx @@ -123,6 +123,12 @@ 122, 17 + + 17, 17 + + + 122, 17 + diff --git a/ShiftOS.WinForms/Applications/FileSkimmer.Designer.cs b/ShiftOS.WinForms/Applications/FileSkimmer.Designer.cs index ea9fcec..965e4eb 100644 --- a/ShiftOS.WinForms/Applications/FileSkimmer.Designer.cs +++ b/ShiftOS.WinForms/Applications/FileSkimmer.Designer.cs @@ -70,9 +70,9 @@ namespace ShiftOS.WinForms.Applications // lvitems // this.lvitems.Dock = System.Windows.Forms.DockStyle.Fill; - this.lvitems.Location = new System.Drawing.Point(0, 0); + this.lvitems.Location = new System.Drawing.Point(149, 0); this.lvitems.Name = "lvitems"; - this.lvitems.Size = new System.Drawing.Size(634, 332); + this.lvitems.Size = new System.Drawing.Size(485, 332); this.lvitems.TabIndex = 0; this.lvitems.UseCompatibleStateImageBehavior = false; this.lvitems.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.lvitems_ItemSelectionChanged); @@ -81,8 +81,8 @@ namespace ShiftOS.WinForms.Applications // // panel1 // - this.panel1.Controls.Add(this.pinnedItems); this.panel1.Controls.Add(this.lvitems); + this.panel1.Controls.Add(this.pinnedItems); this.panel1.Controls.Add(this.lbcurrentfolder); this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; this.panel1.Location = new System.Drawing.Point(0, 24); @@ -92,10 +92,12 @@ namespace ShiftOS.WinForms.Applications // // pinnedItems // - this.pinnedItems.Location = new System.Drawing.Point(437, 208); + this.pinnedItems.Dock = System.Windows.Forms.DockStyle.Left; + this.pinnedItems.Location = new System.Drawing.Point(0, 0); this.pinnedItems.Name = "pinnedItems"; - this.pinnedItems.Size = new System.Drawing.Size(197, 124); + this.pinnedItems.Size = new System.Drawing.Size(149, 332); this.pinnedItems.TabIndex = 3; + this.pinnedItems.Click += new System.EventHandler(this.pinnedItems_Click); // // lbcurrentfolder // diff --git a/ShiftOS.WinForms/Applications/FileSkimmer.cs b/ShiftOS.WinForms/Applications/FileSkimmer.cs index c1ffd40..218e9e2 100644 --- a/ShiftOS.WinForms/Applications/FileSkimmer.cs +++ b/ShiftOS.WinForms/Applications/FileSkimmer.cs @@ -35,6 +35,7 @@ using System.Windows.Forms; using static ShiftOS.Objects.ShiftFS.Utils; using ShiftOS.Engine; +using Newtonsoft.Json; namespace ShiftOS.WinForms.Applications { @@ -128,8 +129,14 @@ namespace ShiftOS.WinForms.Applications { int amountsCalled = -1; amountsCalled = amountsCalled + 1; - pinnedItems.Nodes.Add(path); - pinnedItems.Nodes[amountsCalled].Nodes.Add("test"); + List Pinned = new List(); + if(FileExists(Paths.GetPath("data") + "/pinned_items.dat")) + { + Pinned = JsonConvert.DeserializeObject>(ReadAllText(Paths.GetPath("data") + "/pinned_items.dat")); + } + Pinned.Add(path); + WriteAllText(Paths.GetPath("data") + "/pinned_items.dat", JsonConvert.SerializeObject(Pinned)); + ResetList(); } public void ChangeDirectory(string path) @@ -152,8 +159,40 @@ namespace ShiftOS.WinForms.Applications } } + public void PopulatePinned(TreeNode node, string[] items) + { + foreach(var dir in items) + { + var treenode = new TreeNode(); + if (DirectoryExists(dir)) + { + var dinf = GetDirectoryInfo(dir); + treenode.Text = dinf.Name; + } + else if (FileExists(dir)) + { + var finf = GetFileInfo(dir); + treenode.Text = finf.Name; + } + treenode.Tag = dir; + node.Nodes.Add(treenode); + } + } + public void ResetList() { + pinnedItems.Nodes.Clear(); + List Pinned = new List(); + if(FileExists(Paths.GetPath("data") + "/pinned_items.dat")) + { + Pinned = JsonConvert.DeserializeObject>(ReadAllText(Paths.GetPath("data") + "/pinned_items.dat")); + } + var node = new TreeNode(); + node.Text = "Pinned"; + PopulatePinned(node, Pinned.ToArray()); + pinnedItems.Nodes.Add(node); + node.ExpandAll(); + if(lvitems.LargeImageList == null) { lvitems.LargeImageList = new ImageList(); @@ -437,5 +476,26 @@ namespace ShiftOS.WinForms.Applications } catch { } } + + private void pinnedItems_Click(object sender, EventArgs e) + { + try + { + if (pinnedItems.SelectedNode != null) + { + string path = pinnedItems.SelectedNode.Tag.ToString(); + if (DirectoryExists(path)) + { + currentdir = path; + ResetList(); + } + else if (FileExists(path)) + { + FileSkimmerBackend.OpenFile(path); + } + } + } + catch { } + } } } diff --git a/ShiftOS.WinForms/Applications/GraphicPicker.Designer.cs b/ShiftOS.WinForms/Applications/GraphicPicker.Designer.cs index 988acbd..889c8aa 100644 --- a/ShiftOS.WinForms/Applications/GraphicPicker.Designer.cs +++ b/ShiftOS.WinForms/Applications/GraphicPicker.Designer.cs @@ -86,12 +86,12 @@ 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(390, 383); + this.pgcontents.Size = new System.Drawing.Size(487, 383); this.pgcontents.TabIndex = 20; // // btncancel // - this.btncancel.Anchor = System.Windows.Forms.AnchorStyles.Bottom; + this.btncancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.btncancel.Location = new System.Drawing.Point(21, 335); this.btncancel.Name = "btncancel"; this.btncancel.Size = new System.Drawing.Size(109, 32); @@ -102,10 +102,11 @@ namespace ShiftOS.WinForms.Applications // // btnreset // - this.btnreset.Anchor = System.Windows.Forms.AnchorStyles.Bottom; + this.btnreset.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.btnreset.Location = new System.Drawing.Point(136, 335); this.btnreset.Name = "btnreset"; - this.btnreset.Size = new System.Drawing.Size(109, 32); + this.btnreset.Size = new System.Drawing.Size(206, 32); this.btnreset.TabIndex = 22; this.btnreset.Text = "Reset"; this.btnreset.UseVisualStyleBackColor = true; @@ -113,8 +114,8 @@ namespace ShiftOS.WinForms.Applications // // btnapply // - this.btnapply.Anchor = System.Windows.Forms.AnchorStyles.Bottom; - this.btnapply.Location = new System.Drawing.Point(251, 335); + this.btnapply.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnapply.Location = new System.Drawing.Point(348, 335); this.btnapply.Name = "btnapply"; this.btnapply.Size = new System.Drawing.Size(118, 32); this.btnapply.TabIndex = 21; @@ -124,19 +125,21 @@ namespace ShiftOS.WinForms.Applications // // Label2 // - this.Label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.Label2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.Label2.Font = new System.Drawing.Font("Arial", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.Label2.Location = new System.Drawing.Point(125, 260); this.Label2.Name = "Label2"; - this.Label2.Size = new System.Drawing.Size(163, 28); + this.Label2.Size = new System.Drawing.Size(260, 28); this.Label2.TabIndex = 12; + this.Label2.Tag = "header3"; this.Label2.Text = "Idle"; this.Label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // // btnidlebrowse // - this.btnidlebrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnidlebrowse.Location = new System.Drawing.Point(295, 260); + this.btnidlebrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnidlebrowse.Location = new System.Drawing.Point(392, 260); this.btnidlebrowse.Name = "btnidlebrowse"; this.btnidlebrowse.Size = new System.Drawing.Size(73, 60); this.btnidlebrowse.TabIndex = 10; @@ -146,14 +149,15 @@ namespace ShiftOS.WinForms.Applications // // txtidlefile // - this.txtidlefile.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.txtidlefile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.txtidlefile.BackColor = System.Drawing.Color.White; this.txtidlefile.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.txtidlefile.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.txtidlefile.Location = new System.Drawing.Point(125, 291); this.txtidlefile.Multiline = true; this.txtidlefile.Name = "txtidlefile"; - this.txtidlefile.Size = new System.Drawing.Size(163, 29); + this.txtidlefile.Size = new System.Drawing.Size(260, 29); this.txtidlefile.TabIndex = 9; this.txtidlefile.Text = "None"; this.txtidlefile.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; @@ -172,9 +176,10 @@ namespace ShiftOS.WinForms.Applications // // btnzoom // + this.btnzoom.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.btnzoom.FlatAppearance.BorderColor = System.Drawing.Color.Black; this.btnzoom.FlatAppearance.BorderSize = 0; - this.btnzoom.Location = new System.Drawing.Point(286, 144); + this.btnzoom.Location = new System.Drawing.Point(383, 144); this.btnzoom.Name = "btnzoom"; this.btnzoom.Size = new System.Drawing.Size(82, 65); this.btnzoom.TabIndex = 7; @@ -184,9 +189,10 @@ namespace ShiftOS.WinForms.Applications // // btnstretch // + this.btnstretch.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.btnstretch.FlatAppearance.BorderColor = System.Drawing.Color.Black; this.btnstretch.FlatAppearance.BorderSize = 0; - this.btnstretch.Location = new System.Drawing.Point(197, 144); + this.btnstretch.Location = new System.Drawing.Point(294, 144); this.btnstretch.Name = "btnstretch"; this.btnstretch.Size = new System.Drawing.Size(82, 65); this.btnstretch.TabIndex = 6; @@ -228,6 +234,9 @@ namespace ShiftOS.WinForms.Applications // // picgraphic // + this.picgraphic.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.picgraphic.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; this.picgraphic.Location = new System.Drawing.Point(0, 0); this.picgraphic.Name = "picgraphic"; @@ -237,11 +246,14 @@ namespace ShiftOS.WinForms.Applications // // lblobjecttoskin // + this.lblobjecttoskin.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.lblobjecttoskin.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.lblobjecttoskin.Location = new System.Drawing.Point(19, 9); this.lblobjecttoskin.Name = "lblobjecttoskin"; - this.lblobjecttoskin.Size = new System.Drawing.Size(350, 23); + this.lblobjecttoskin.Size = new System.Drawing.Size(447, 23); this.lblobjecttoskin.TabIndex = 2; + this.lblobjecttoskin.Tag = "header1"; this.lblobjecttoskin.Text = "Close Button"; this.lblobjecttoskin.TextAlign = System.Drawing.ContentAlignment.TopCenter; // @@ -249,10 +261,9 @@ namespace ShiftOS.WinForms.Applications // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(390, 383); this.Controls.Add(this.pgcontents); this.Name = "GraphicPicker"; - this.Text = "{GRAPHIC_PICKER_NAME}"; + this.Size = new System.Drawing.Size(487, 383); this.Load += new System.EventHandler(this.Graphic_Picker_Load); this.pgcontents.ResumeLayout(false); this.pgcontents.PerformLayout(); diff --git a/ShiftOS.WinForms/Applications/GraphicPicker.cs b/ShiftOS.WinForms/Applications/GraphicPicker.cs index 85f95bd..f299f0d 100644 --- a/ShiftOS.WinForms/Applications/GraphicPicker.cs +++ b/ShiftOS.WinForms/Applications/GraphicPicker.cs @@ -45,6 +45,12 @@ namespace ShiftOS.WinForms.Applications { InitializeComponent(); SelectedLayout = layout; + Image = old; + using(var ms = new System.IO.MemoryStream()) + { + Image.Save(ms, System.Drawing.Imaging.ImageFormat.Png); + ImageAsBinary = ms.ToArray(); + } Callback = cb; lblobjecttoskin.Text = name; @@ -123,10 +129,12 @@ namespace ShiftOS.WinForms.Applications public void OnLoad() { + Setup(); } public void OnSkinLoad() { + Setup(); } public bool OnUnload() @@ -136,6 +144,7 @@ namespace ShiftOS.WinForms.Applications public void OnUpgrade() { + Setup(); } } } diff --git a/ShiftOS.WinForms/Applications/IconManager.Designer.cs b/ShiftOS.WinForms/Applications/IconManager.Designer.cs new file mode 100644 index 0000000..25bcee4 --- /dev/null +++ b/ShiftOS.WinForms/Applications/IconManager.Designer.cs @@ -0,0 +1,163 @@ +namespace ShiftOS.WinForms.Applications +{ + partial class IconManager + { + /// + /// 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.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + this.btnclose = new System.Windows.Forms.Button(); + this.btnreset = new System.Windows.Forms.Button(); + this.btnapply = new System.Windows.Forms.Button(); + this.flbody = new System.Windows.Forms.FlowLayoutPanel(); + this.lbcurrentpage = new System.Windows.Forms.Label(); + this.btnprev = new System.Windows.Forms.Button(); + this.btnnext = new System.Windows.Forms.Button(); + this.flowLayoutPanel1.SuspendLayout(); + this.SuspendLayout(); + // + // flowLayoutPanel1 + // + this.flowLayoutPanel1.AutoSize = true; + this.flowLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.flowLayoutPanel1.Controls.Add(this.btnclose); + this.flowLayoutPanel1.Controls.Add(this.btnreset); + this.flowLayoutPanel1.Controls.Add(this.btnapply); + this.flowLayoutPanel1.Controls.Add(this.lbcurrentpage); + this.flowLayoutPanel1.Controls.Add(this.btnprev); + this.flowLayoutPanel1.Controls.Add(this.btnnext); + this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Bottom; + this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 416); + this.flowLayoutPanel1.Name = "flowLayoutPanel1"; + this.flowLayoutPanel1.Size = new System.Drawing.Size(393, 29); + this.flowLayoutPanel1.TabIndex = 0; + // + // btnclose + // + this.btnclose.AutoSize = true; + this.btnclose.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.btnclose.Location = new System.Drawing.Point(3, 3); + this.btnclose.Name = "btnclose"; + this.btnclose.Size = new System.Drawing.Size(43, 23); + this.btnclose.TabIndex = 0; + this.btnclose.Text = "Close"; + this.btnclose.UseVisualStyleBackColor = true; + this.btnclose.Click += new System.EventHandler(this.btnclose_Click); + // + // btnreset + // + this.btnreset.AutoSize = true; + this.btnreset.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.btnreset.Location = new System.Drawing.Point(52, 3); + this.btnreset.Name = "btnreset"; + this.btnreset.Size = new System.Drawing.Size(45, 23); + this.btnreset.TabIndex = 1; + this.btnreset.Text = "Reset"; + this.btnreset.UseVisualStyleBackColor = true; + this.btnreset.Click += new System.EventHandler(this.btnreset_Click); + // + // btnapply + // + this.btnapply.AutoSize = true; + this.btnapply.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.btnapply.Location = new System.Drawing.Point(103, 3); + this.btnapply.Name = "btnapply"; + this.btnapply.Size = new System.Drawing.Size(43, 23); + this.btnapply.TabIndex = 2; + this.btnapply.Text = "Apply"; + this.btnapply.UseVisualStyleBackColor = true; + this.btnapply.Click += new System.EventHandler(this.btnapply_Click); + // + // flbody + // + this.flbody.Dock = System.Windows.Forms.DockStyle.Fill; + this.flbody.FlowDirection = System.Windows.Forms.FlowDirection.TopDown; + this.flbody.Location = new System.Drawing.Point(0, 0); + this.flbody.Name = "flbody"; + this.flbody.Size = new System.Drawing.Size(393, 416); + this.flbody.TabIndex = 1; + this.flbody.WrapContents = false; + // + // lbcurrentpage + // + this.lbcurrentpage.AutoSize = true; + this.lbcurrentpage.Location = new System.Drawing.Point(152, 0); + this.lbcurrentpage.Name = "lbcurrentpage"; + this.lbcurrentpage.Size = new System.Drawing.Size(71, 13); + this.lbcurrentpage.TabIndex = 3; + this.lbcurrentpage.Text = "Current page:"; + // + // btnprev + // + this.btnprev.AutoSize = true; + this.btnprev.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.btnprev.Location = new System.Drawing.Point(229, 3); + this.btnprev.Name = "btnprev"; + this.btnprev.Size = new System.Drawing.Size(51, 23); + this.btnprev.TabIndex = 4; + this.btnprev.Text = " < Prev"; + this.btnprev.UseVisualStyleBackColor = true; + this.btnprev.Click += new System.EventHandler(this.btnprev_Click); + // + // btnnext + // + this.btnnext.AutoSize = true; + this.btnnext.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.btnnext.Location = new System.Drawing.Point(286, 3); + this.btnnext.Name = "btnnext"; + this.btnnext.Size = new System.Drawing.Size(48, 23); + this.btnnext.TabIndex = 5; + this.btnnext.Text = "Next >"; + this.btnnext.UseVisualStyleBackColor = true; + this.btnnext.Click += new System.EventHandler(this.btnnext_Click); + // + // IconManager + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.flbody); + this.Controls.Add(this.flowLayoutPanel1); + this.Name = "IconManager"; + this.Size = new System.Drawing.Size(393, 445); + this.flowLayoutPanel1.ResumeLayout(false); + this.flowLayoutPanel1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; + private System.Windows.Forms.Button btnclose; + private System.Windows.Forms.Button btnreset; + private System.Windows.Forms.Button btnapply; + private System.Windows.Forms.FlowLayoutPanel flbody; + private System.Windows.Forms.Label lbcurrentpage; + private System.Windows.Forms.Button btnprev; + private System.Windows.Forms.Button btnnext; + } +} diff --git a/ShiftOS.WinForms/Applications/IconManager.cs b/ShiftOS.WinForms/Applications/IconManager.cs new file mode 100644 index 0000000..0c6e119 --- /dev/null +++ b/ShiftOS.WinForms/Applications/IconManager.cs @@ -0,0 +1,244 @@ +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.Reflection; +using ShiftOS.WinForms.Tools; +using Newtonsoft.Json; + +namespace ShiftOS.WinForms.Applications +{ + [RequiresUpgrade("icon_manager")] + [Launcher("Icon Manager", true, "al_icon_manager", "Customization")] + [DefaultTitle("Icon Manager")] + [DefaultIcon("iconIconManager")] + public partial class IconManager : UserControl, IShiftOSWindow + { + public IconManager() + { + InitializeComponent(); + } + + public void OnLoad() + { + LoadIconsFromEngine(); + SetupUI(); + } + + public void OnSkinLoad() + { + LoadIconsFromEngine(); + SetupUI(); + } + + public bool OnUnload() + { + Icons = null; + return true; + } + + private Dictionary Icons = null; + + private const int pageSize = 10; + private int currentPage = 0; + private int pageCount = 0; + + public Image GetIcon(string id) + { + if (!Icons.ContainsKey(id)) + Icons.Add(id, null); + + if (Icons[id] == null) + { + var img = SkinEngine.GetDefaultIcon(id); + using (var mstr = new System.IO.MemoryStream()) + { + img.Save(mstr, System.Drawing.Imaging.ImageFormat.Png); + Icons[id] = mstr.ToArray(); + } + return img; + } + else + { + using (var sr = new System.IO.MemoryStream(Icons[id])) + { + return Image.FromStream(sr); + } + } + } + + public void SetIcon(string key, byte[] raw) + { + if (!Icons.ContainsKey(key)) + Icons.Add(key, raw); + Icons[key] = raw; + } + + public void LoadIconsFromEngine() + { + //We have to serialize the engine icon list to JSON to break references with the data. + string json = JsonConvert.SerializeObject(SkinEngine.LoadedSkin.AppIcons); + //And deserialize to the local instance...essentially making a clone. + Icons = JsonConvert.DeserializeObject>(json); + } + + public void SetupUI() + { + flbody.Controls.Clear(); //Clear the icon list. + + List types = new List(); + + foreach(var exe in System.IO.Directory.GetFiles(Environment.CurrentDirectory)) + { + if(exe.ToLower().EndsWith(".exe") || exe.ToLower().EndsWith(".dll")) + { + try + { + var asm = Assembly.LoadFile(exe); + + var typeList = asm.GetTypes().Where(x => x.GetCustomAttributes(false).FirstOrDefault(y => y is DefaultIconAttribute) != null); + types.AddRange(typeList); + + } + catch { } + } + } + + pageCount = types.ToArray().GetPageCount(pageSize); + + foreach (var type in types.ToArray().GetItemsOnPage(currentPage, pageSize)) + { + if (Shiftorium.UpgradeAttributesUnlocked(type)) + { + var pnl = new Panel(); + pnl.Height = 30; + pnl.Width = flbody.Width - 15; + flbody.Controls.Add(pnl); + pnl.Show(); + var pic = new PictureBox(); + pic.SizeMode = PictureBoxSizeMode.StretchImage; + pic.Size = new Size(24, 24); + pic.Image = GetIcon(type.Name); + pnl.Controls.Add(pic); + pic.Left = 5; + pic.Top = (pnl.Height - pic.Height) / 2; + pic.Show(); + var lbl = new Label(); + lbl.Tag = "header3"; + lbl.AutoSize = true; + lbl.Text = NameChangerBackend.GetNameRaw(type); + ControlManager.SetupControl(lbl); + pnl.Controls.Add(lbl); + lbl.CenterParent(); + lbl.Show(); + var btn = new Button(); + btn.Text = "Change..."; + btn.AutoSize = true; + btn.AutoSizeMode = AutoSizeMode.GrowAndShrink; + pnl.Controls.Add(btn); + btn.Left = (pnl.Width - btn.Width) - 5; + btn.Top = (pnl.Height - btn.Height) / 2; + btn.Click += (o, a) => + { + var gfp = new GraphicPicker(pic.Image, lbl.Text + " icon", ImageLayout.Stretch, (raw, img, layout) => + { + pic.Image = img; + SetIcon(type.Name, raw); + }); + AppearanceManager.SetupDialog(gfp); + }; + btn.Show(); + ControlManager.SetupControls(pnl); + } + } + + btnnext.Visible = (currentPage < pageCount - 1); + btnprev.Visible = (currentPage > 0); + + lbcurrentpage.Text = "Page " + (currentPage + 1).ToString() + " of " + pageCount.ToString(); + } + + public void OnUpgrade() + { + LoadIconsFromEngine(); + SetupUI(); + } + + private void btnprev_Click(object sender, EventArgs e) + { + currentPage--; + SetupUI(); + } + + public void ResetToDefaults() + { + currentPage = 0; + foreach (var key in Icons.Keys) + { + var img = SkinEngine.GetDefaultIcon(key); + using(var ms = new System.IO.MemoryStream()) + { + img.Save(ms, System.Drawing.Imaging.ImageFormat.Png); + Icons[key] = ms.ToArray(); + } + } + SetupUI(); + } + + private void btnnext_Click(object sender, EventArgs e) + { + currentPage++; + SetupUI(); + } + + private void btnclose_Click(object sender, EventArgs e) + { + AppearanceManager.Close(this); + } + + private void btnreset_Click(object sender, EventArgs e) + { + ResetToDefaults(); + } + + private void btnapply_Click(object sender, EventArgs e) + { + SkinEngine.LoadedSkin.AppIcons = Icons; + SkinEngine.SaveSkin(); + SkinEngine.LoadSkin(); + Infobox.Show("Icons applied!", "The new icons have been applied to ShiftOS successfully!"); + } + } + + public static class PaginationExtensions + { + public static int GetPageCount(this IEnumerable collection, int pageSize) + { + return (collection.Count() + pageSize - 1) / pageSize; + } + + public static T[] GetItemsOnPage(this T[] collection, int page, int pageSize) + { + List obj = new List(); + + for (int i = pageSize * page; i <= pageSize + (pageSize * page) && i < collection.Count(); i++) + { + try + { + obj.Add(collection[i]); + } + catch + { + } + } + return obj.ToArray(); + } + } + +} diff --git a/ShiftOS.WinForms/Applications/IconManager.resx b/ShiftOS.WinForms/Applications/IconManager.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/ShiftOS.WinForms/Applications/IconManager.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/Applications/Installer.Designer.cs b/ShiftOS.WinForms/Applications/Installer.Designer.cs index 48f9146..b01986d 100644 --- a/ShiftOS.WinForms/Applications/Installer.Designer.cs +++ b/ShiftOS.WinForms/Applications/Installer.Designer.cs @@ -118,12 +118,10 @@ // this.pginstall.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.pginstall.BlockSize = 5; this.pginstall.Location = new System.Drawing.Point(17, 161); this.pginstall.Maximum = 100; this.pginstall.Name = "pginstall"; this.pginstall.Size = new System.Drawing.Size(414, 23); - this.pginstall.Style = System.Windows.Forms.ProgressBarStyle.Continuous; this.pginstall.TabIndex = 2; this.pginstall.Text = "shiftedProgressBar1"; this.pginstall.Value = 0; diff --git a/ShiftOS.WinForms/Applications/MUDControlCentre.cs b/ShiftOS.WinForms/Applications/MUDControlCentre.cs index b8ba5f3..97212e7 100644 --- a/ShiftOS.WinForms/Applications/MUDControlCentre.cs +++ b/ShiftOS.WinForms/Applications/MUDControlCentre.cs @@ -100,7 +100,7 @@ namespace ShiftOS.WinForms.Applications { ServerManager.SendMessage("shop_removeowned", JsonConvert.SerializeObject(new { - username = SaveSystem.CurrentSave.Username + username = SaveSystem.CurrentUser.Username })); ShowCreateShop(); } @@ -274,9 +274,10 @@ namespace ShiftOS.WinForms.Applications } + [Obsolete("MUD control center is dying! KILL IT!")] public void OpenChat(string id) { - AppearanceManager.SetupWindow(new Chat(id)); +// AppearanceManager.SetupWindow(new Chat(id)); } private Shop editingShop = null; @@ -289,7 +290,7 @@ namespace ShiftOS.WinForms.Applications creatingShop = true; editingShop.Name = "My shop"; editingShop.Description = "My shop has lots of awesome items. You should buy from my shop."; - editingShop.Owner = SaveSystem.CurrentSave.Username; + editingShop.Owner = SaveSystem.CurrentUser.Username; editingShop.Items = new List(); shop_editor.BringToFront(); PopulateShopEditor(); @@ -401,7 +402,7 @@ namespace ShiftOS.WinForms.Applications lbprice.Text = $"Cost: {item.Cost} CP"; btnbuy.Show(); }; - if(shop.Owner == SaveSystem.CurrentSave.Username) + if(shop.Owner == SaveSystem.CurrentUser.Username) { btneditshop.Show(); } @@ -559,7 +560,7 @@ namespace ShiftOS.WinForms.Applications you_systemstatus.BringToFront(); - lblsysstatus.Text = $@"Username: {SaveSystem.CurrentSave.Username} + lblsysstatus.Text = $@"Username: {SaveSystem.CurrentUser.Username} System name: {SaveSystem.CurrentSave.SystemName} Codepoints: {SaveSystem.CurrentSave.Codepoints} @@ -590,7 +591,7 @@ Current legions: {legionname}"; private void tsMemos_Click(object sender, EventArgs e) { ServerManager.SendMessage("get_memos_for_user", $@"{{ - username: ""{SaveSystem.CurrentSave.Username}"" + username: ""{SaveSystem.CurrentUser.Username}"" }}"); you_memos.BringToFront(); } @@ -811,7 +812,7 @@ Current legions: {legionname}"; { ServerManager.SendMessage("user_shop_check", JsonConvert.SerializeObject(new { - username = SaveSystem.CurrentSave.Username + username = SaveSystem.CurrentUser.Username })); } @@ -894,7 +895,7 @@ Current legions: {legionname}"; private void myShopToolStripMenuItem_Click(object sender, EventArgs e) { - ServerManager.SendMessage("user_get_shop", SaveSystem.CurrentSave.Username); + ServerManager.SendMessage("user_get_shop", SaveSystem.CurrentUser.Username); } private void btneditshop_Click(object sender, EventArgs e) @@ -922,7 +923,7 @@ Current legions: {legionname}"; { ServerManager.SendMessage("delete_save", JsonConvert.SerializeObject(new ClientSave { - Username = SaveSystem.CurrentSave.Username, + Username = SaveSystem.CurrentUser.Username, Password = SaveSystem.CurrentSave.Password })); diff --git a/ShiftOS.WinForms/Applications/Pong.Designer.cs b/ShiftOS.WinForms/Applications/Pong.Designer.cs index 0254e94..c5ea375 100644 --- a/ShiftOS.WinForms/Applications/Pong.Designer.cs +++ b/ShiftOS.WinForms/Applications/Pong.Designer.cs @@ -182,7 +182,6 @@ namespace ShiftOS.WinForms.Applications this.pgcontents.Name = "pgcontents"; this.pgcontents.Size = new System.Drawing.Size(912, 504); 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); // // pnlmultiplayerhandshake @@ -250,7 +249,6 @@ namespace ShiftOS.WinForms.Applications this.Label6.TabIndex = 15; this.Label6.Text = "{PONG_DESC}"; this.Label6.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - this.Label6.Click += new System.EventHandler(this.Label6_Click); // // btnstartgame // @@ -273,7 +271,6 @@ namespace ShiftOS.WinForms.Applications this.Label8.Size = new System.Drawing.Size(280, 31); this.Label8.TabIndex = 14; this.Label8.Text = "{PONG_WELCOME}"; - this.Label8.Click += new System.EventHandler(this.Label8_Click); // // pnlhighscore // diff --git a/ShiftOS.WinForms/Applications/Pong.cs b/ShiftOS.WinForms/Applications/Pong.cs index d63f406..87f0306 100644 --- a/ShiftOS.WinForms/Applications/Pong.cs +++ b/ShiftOS.WinForms/Applications/Pong.cs @@ -58,13 +58,62 @@ namespace ShiftOS.WinForms.Applications double incrementy = 0.2; int levelxspeed = 3; int levelyspeed = 3; - int beatairewardtotal; - int beataireward = 1; - int[] levelrewards = new int[50]; - int totalreward; + ulong beatairewardtotal; + ulong beataireward = 1; + readonly uint[] levelrewards = { + 0, + 20, + 60, + 140, + 290, + 400, + 600, + 900, + 1200, + 1600, + 2000, + 2500, + 3000, + 4000, + 5000, + 6000, + 8000, + 10000, + 13000, + 16000, + 20000, + 25000, + 32000, + 40000, + 50000, + 60000, + 75000, + 90000, + 110000, + 140000, + 180000, + 220000, + 270000, + 320000, + 400000, + 500000, + 640000, + 800000, + 1000000, + 1500000, + 2000000}; + ulong totalreward; int countdown = 3; + int rwdmultiplier; + Thread soundThread; - bool aiShouldIsbeEnabled = true; + bool aiShouldIsbeEnabled = true; // who named this variable? and were they having a stroke? + + private void playsound(System.IO.Stream stream) + { + soundThread = new Thread((a) => ShiftOS.Engine.AudioManager.PlayStream((System.IO.Stream)a)); + soundThread.Start(stream); + } public Pong() { @@ -73,11 +122,9 @@ namespace ShiftOS.WinForms.Applications private void Pong_Load(object sender, EventArgs e) { - setuplevelrewards(); + rwdmultiplier = ShiftoriumFrontend.UpgradeInstalled("pong_upgrade") ? 2 : 1; } - - // Move the paddle according to the mouse position. private void pongMain_MouseMove(object sender, MouseEventArgs e) { @@ -133,9 +180,7 @@ namespace ShiftOS.WinForms.Applications { if (this.Left < Screen.PrimaryScreen.Bounds.Width) { - ball.BackColor = SkinEngine.LoadedSkin.ControlTextColor; - paddleComputer.BackColor = SkinEngine.LoadedSkin.ControlTextColor; - paddleHuman.BackColor = SkinEngine.LoadedSkin.ControlTextColor; + ball.BackColor = paddleComputer.BackColor = paddleHuman.BackColor = SkinEngine.LoadedSkin.ControlTextColor; //Check if paddle upgrade has been bought and change paddles accordingly //if (ShiftoriumFrontend.UpgradeInstalled("pong_increased_paddle_size")) @@ -146,7 +191,7 @@ namespace ShiftOS.WinForms.Applications //I don't know the point of this but I'm fucking 86ing it. - Michael //Set the computer player to move according to the ball's position. - if (IsMultiplayerSession == true) + if (IsMultiplayerSession) { //If we're multiplayer, then we want to set the computer Y to the opponent's Y. //If we're the leader, we set the AI paddle, else we set the player paddle. @@ -160,83 +205,63 @@ namespace ShiftOS.WinForms.Applications if (aiShouldIsbeEnabled) if (ball.Location.X > (this.Width - (this.Width / 3)) - xVel * 10 && xVel > 0) { - if (ball.Location.Y > paddleComputer.Location.Y + 50) - { - paddleComputer.Location = new Point(paddleComputer.Location.X, paddleComputer.Location.Y + computerspeed); - } - if (ball.Location.Y < paddleComputer.Location.Y + 50) - { - paddleComputer.Location = new Point(paddleComputer.Location.X, paddleComputer.Location.Y - computerspeed); - } + if (ball.Top > paddleComputer.Top + 50) + paddleComputer.Top += computerspeed; + else + paddleComputer.Top -= computerspeed; casualposition = rand.Next(-150, 201); } else { //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); - } - //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); - } + if (paddleComputer.Top > this.Height / 2 - paddleComputer.Height + casualposition) + paddleComputer.Top -= computerspeed; + else + paddleComputer.Top += computerspeed; } } //Set Xvel and Yvel speeds from decimal if (xVel > 0) xVel = (int)Math.Round(xveldec); - if (xVel < 0) + else xVel = (int)-Math.Round(xveldec); if (yVel > 0) yVel = (int)Math.Round(yveldec); - if (yVel < 0) + else yVel = (int)-Math.Round(yveldec); - bool BallPhysics = true; - - if (IsMultiplayerSession) + if (IsMultiplayerSession && !IsLeader) { - //Logic for moving the ball in Multiplayer. - if (IsLeader) - { - ball.Location = new Point(ball.Location.X + xVel, ball.Location.Y + yVel); - } - else - { - //Move it to the leader's ball position. - ball.Location = new Point(LeaderX, LeaderY); - BallPhysics = false; - } + // Move it to the leader's ball position. + ball.Location = new Point(LeaderX, LeaderY); } else - {// Move the game ball. - ball.Location = new Point(ball.Location.X + xVel, ball.Location.Y + yVel); - } - if (BallPhysics) { + var newRect = new Rectangle(ball.Location, ball.Size); // copy ball's Bounds + newRect.X += xVel; + newRect.Y += yVel; + // Check for top wall. - if (ball.Location.Y < 0) + if (newRect.Y < 0) { - ball.Location = new Point(ball.Location.X, 0); + newRect.Y = 0; yVel = -yVel; - ShiftOS.Engine.AudioManager.PlayStream(Properties.Resources.typesound); + playsound(Properties.Resources.typesound); } // Check for bottom wall. - if (ball.Location.Y > pgcontents.Height - ball.Height) + if (newRect.Y > pgcontents.Height - ball.Height) { - ball.Location = new Point(ball.Location.X, pgcontents.Height - ball.Size.Height); + newRect.Y = pgcontents.Height - ball.Height; yVel = -yVel; - ShiftOS.Engine.AudioManager.PlayStream(Properties.Resources.typesound); + playsound(Properties.Resources.typesound); } // Check for player paddle. - if (ball.Bounds.IntersectsWith(paddleHuman.Bounds)) + if (newRect.IntersectsWith(paddleHuman.Bounds)) { - ball.Location = new Point(paddleHuman.Location.X + ball.Size.Width + 1, ball.Location.Y); + newRect.X = paddleHuman.Left + ball.Width + 1; //randomly increase x or y speed of ball switch (rand.Next(1, 3)) { @@ -246,23 +271,24 @@ namespace ShiftOS.WinForms.Applications case 2: if (yveldec > 0) yveldec = yveldec + incrementy; - if (yveldec < 0) + else yveldec = yveldec - incrementy; break; } xVel = -xVel; - ShiftOS.Engine.AudioManager.PlayStream(Properties.Resources.writesound); + playsound(Properties.Resources.writesound); } // Check for computer paddle. - if (ball.Bounds.IntersectsWith(paddleComputer.Bounds)) + if (newRect.IntersectsWith(paddleComputer.Bounds)) { - ball.Location = new Point(paddleComputer.Location.X - paddleComputer.Size.Width - 1, ball.Location.Y); + newRect.X = paddleComputer.Left - paddleComputer.Width - 1; xveldec = xveldec + incrementx; xVel = -xVel; - ShiftOS.Engine.AudioManager.PlayStream(Properties.Resources.writesound); + playsound(Properties.Resources.writesound); } + ball.Location = newRect.Location; } @@ -297,11 +323,11 @@ namespace ShiftOS.WinForms.Applications lblmissedout.Text = Localization.Parse("{YOU_MISSED_OUT_ON}:") + Environment.NewLine + lblstatscodepoints.Text.Replace(Localization.Parse("{CODEPOINTS}: "), "") + Localization.Parse(" {CODEPOINTS}"); if (ShiftoriumFrontend.UpgradeInstalled("pong_upgrade_2")) { - totalreward = levelrewards[level - 1] + beatairewardtotal; + totalreward = (levelrewards[level - 1] * (ulong) rwdmultiplier + beatairewardtotal); double onePercent = (totalreward / 100); lblbutyougained.Show(); lblbutyougained.Text = Localization.Parse("{BUT_YOU_GAINED}:") + Environment.NewLine + onePercent.ToString("") + (Localization.Parse(" {CODEPOINTS}")); - SaveSystem.TransferCodepointsFrom("pong", (totalreward / 100)); + SaveSystem.TransferCodepointsFrom("pong", (ulong)(onePercent)); } else { @@ -343,10 +369,10 @@ namespace ShiftOS.WinForms.Applications if (IsLeader) { //lblstats.Text = "Xspeed: " & Math.Abs(xVel) & " Yspeed: " & Math.Abs(yVel) & " Human Location: " & paddleHuman.Location.ToString & " Computer Location: " & paddleComputer.Location.ToString & Environment.NewLine & " Ball Location: " & ball.Location.ToString & " Xdec: " & xveldec & " Ydec: " & yveldec & " Xinc: " & incrementx & " Yinc: " & incrementy - lblstatsX.Text = Localization.Parse("{H_VEL}: ") + xveldec; - lblstatsY.Text = Localization.Parse("{V_VEL}: ") + yveldec; - lblstatscodepoints.Text = Localization.Parse("{CODEPOINTS}: ") + (levelrewards[level - 1] + beatairewardtotal).ToString(); - lbllevelandtime.Text = Localization.Parse("{LEVEL}: " + level + " - " + secondsleft + " {SECONDS_LEFT}"); + lblstatsX.Text = "X vel: " + xveldec; + lblstatsY.Text = "Y vel: " + yveldec; + lblstatscodepoints.Text = "Codepoints: " + (levelrewards[level - 1] * (ulong) rwdmultiplier + beatairewardtotal).ToString(); + lbllevelandtime.Text = "Level: " + level + " - " + secondsleft + " seconds left"; if (xVel > 20 || xVel < -20) { @@ -355,8 +381,7 @@ namespace ShiftOS.WinForms.Applications } else { - paddleHuman.Width = 20; - paddleComputer.Width = 20; + paddleHuman.Width = paddleComputer.Width = 20; } } if (!IsMultiplayerSession) @@ -415,7 +440,7 @@ namespace ShiftOS.WinForms.Applications StartLevel(); })); } - else if(msg.Name == "pong_mp_levelcompleted") + else if (msg.Name == "pong_mp_levelcompleted") { level = Convert.ToInt32(msg.Contents) + 1; this.Invoke(new Action(CompleteLevel)); @@ -434,7 +459,7 @@ namespace ShiftOS.WinForms.Applications pnlmultiplayerhandshake.Hide(); })); } - else if(msg.Name == "pong_mp_cashedout") + else if (msg.Name == "pong_mp_cashedout") { this.Invoke(new Action(() => { @@ -442,19 +467,19 @@ namespace ShiftOS.WinForms.Applications })); Infobox.Show("Cashed out.", "The other player has cashed out their Codepoints. Therefore, we have automatically cashed yours out."); } - else if(msg.Name == "pong_mp_startlevel") + else if (msg.Name == "pong_mp_startlevel") { OpponentAgrees = true; - if(YouAgree == false) + if (YouAgree == false) { - Infobox.PromptYesNo("Play another level?", "The opponent wants to play another level. Would you like to as well?", (answer)=> + Infobox.PromptYesNo("Play another level?", "The opponent wants to play another level. Would you like to as well?", (answer) => { YouAgree = answer; ServerManager.Forward(OpponentGUID, "pong_mp_level_callback", YouAgree.ToString()); }); } } - else if(msg.Name == "pong_mp_level_callback") + else if (msg.Name == "pong_mp_level_callback") { bool agreed = bool.Parse(msg.Contents); OpponentAgrees = agreed; @@ -472,7 +497,7 @@ namespace ShiftOS.WinForms.Applications this.PossibleMatchmakes.Remove(msg.Contents); this.Invoke(new Action(ListMatchmakes)); } - else if(msg.Name == "pong_mp_clockupdate") + else if (msg.Name == "pong_mp_clockupdate") { secondsleft = Convert.ToInt32(msg.Contents); } @@ -566,7 +591,7 @@ namespace ShiftOS.WinForms.Applications public void LoseMP() { ball.Location = new Point(this.Size.Width / 2 + 200, this.Size.Height / 2); - if(IsLeader) + if (IsLeader) if (xVel > 0) xVel = -xVel; lblbeatai.Show(); @@ -629,12 +654,12 @@ namespace ShiftOS.WinForms.Applications if (this.Left < Screen.PrimaryScreen.Bounds.Width) { secondsleft = secondsleft - 1; - if (secondsleft == 1) + if (secondsleft == 0) { CompleteLevel(); } - lblstatscodepoints.Text = Localization.Parse("{CODEPOINTS}: ") + (levelrewards[level - 1] + beatairewardtotal).ToString(); + lblstatscodepoints.Text = "Codepoints: " + (levelrewards[level - 1] * (ulong) rwdmultiplier + beatairewardtotal).ToString(); } } SetupStats(); @@ -670,200 +695,56 @@ namespace ShiftOS.WinForms.Applications lblpreviousstats.Text = Localization.Parse("{INITIAL_H_VEL}: " + levelxspeed + Environment.NewLine + "{INITIAL_V_VEL}: " + levelyspeed + Environment.NewLine + "{INC_H_VEL}: " + incrementx + Environment.NewLine + "{INC_V_VEL}: " + incrementy); - switch (rand.Next(1, 3)) - { - case 1: - levelxspeed = levelxspeed + 1; - break; - case 2: - levelxspeed = levelxspeed + 2; - break; - } + levelxspeed += rand.Next(1, 3); - switch (rand.Next(1, 3)) - { - case 1: - levelyspeed = levelyspeed + 1; - break; - case 2: - levelyspeed = levelyspeed + 2; - break; - } + levelyspeed += rand.Next(1, 3); - switch (rand.Next(1, 6)) - { - case 1: - incrementx = incrementx + 0.1; - break; - case 2: - incrementx = incrementx + 0.2; - break; - case 3: - incrementy = incrementy + 0.1; - break; - case 4: - incrementy = incrementy + 0.2; - break; - case 5: - incrementy = incrementy + 0.3; - break; - } + int rndinc = rand.Next(1, 6); + if (rndinc == 5) + incrementy += 0.3; + else + incrementy += (((rndinc - 1) % 2) + 1) / 10; lblnextstats.Text = Localization.Parse("{INITIAL_H_VEL}: " + levelxspeed + Environment.NewLine + "{INITIAL_V_VEL}: " + levelyspeed + Environment.NewLine + "{INC_H_VEL}: " + incrementx + Environment.NewLine + "{INC_V_VEL}: " + incrementy); if (level < 15) { + beataireward = (ulong)(level * 5); if (ShiftoriumFrontend.UpgradeInstalled("pong_upgrade")) - { - beataireward = level * 10; - } else - { - beataireward = level * 5; - } + beataireward *= 2; } else - { if (ShiftoriumFrontend.UpgradeInstalled("pong_upgrade")) - { - double br = levelrewards[level - 1] / 10; - beataireward = (int)Math.Round(br) * 10; - } else - { - double br = levelrewards[level - 1] / 10; - beataireward = (int)Math.Round(br) * 5; - } - } + beataireward = levelrewards[level - 1]; + else + beataireward = (ulong)Math.Round((double) levelrewards[level - 1] / 2); - totalreward = levelrewards[level - 1] + beatairewardtotal; + totalreward = levelrewards[level - 1] * (ulong) rwdmultiplier + beatairewardtotal; btncashout.Text = Localization.Parse("{CASH_OUT_WITH_CODEPOINTS}"); btnplayon.Text = Localization.Parse("{PONG_PLAY_ON_FOR_MORE}"); } - private void setuplevelrewards() - { - if (ShiftoriumFrontend.UpgradeInstalled("pong_upgrade")) - { - levelrewards[0] = 0; - levelrewards[1] = 40; - levelrewards[2] = 120; - levelrewards[3] = 280; - levelrewards[4] = 580; - levelrewards[5] = 800; - levelrewards[6] = 1200; - levelrewards[7] = 1800; - levelrewards[8] = 2400; - levelrewards[9] = 3200; - levelrewards[10] = 4000; - levelrewards[11] = 5000; - levelrewards[12] = 6000; - levelrewards[13] = 8000; - levelrewards[14] = 10000; - levelrewards[15] = 12000; - levelrewards[16] = 16000; - levelrewards[17] = 20000; - levelrewards[18] = 26000; - levelrewards[19] = 32000; - levelrewards[20] = 40000; - levelrewards[21] = 50000; - levelrewards[22] = 64000; - levelrewards[23] = 80000; - levelrewards[24] = 100000; - levelrewards[25] = 120000; - levelrewards[26] = 150000; - levelrewards[27] = 180000; - levelrewards[28] = 220000; - levelrewards[29] = 280000; - levelrewards[30] = 360000; - levelrewards[31] = 440000; - levelrewards[32] = 540000; - levelrewards[33] = 640000; - levelrewards[34] = 800000; - levelrewards[35] = 1000000; - levelrewards[36] = 1280000; - levelrewards[37] = 1600000; - levelrewards[38] = 2000000; - levelrewards[39] = 3000000; - levelrewards[40] = 4000000; - } else - { - levelrewards[0] = 0; - levelrewards[1] = 20; - levelrewards[2] = 60; - levelrewards[3] = 140; - levelrewards[4] = 290; - levelrewards[5] = 400; - levelrewards[6] = 600; - levelrewards[7] = 900; - levelrewards[8] = 1200; - levelrewards[9] = 1600; - levelrewards[10] = 2000; - levelrewards[11] = 2500; - levelrewards[12] = 3000; - levelrewards[13] = 4000; - levelrewards[14] = 5000; - levelrewards[15] = 6000; - levelrewards[16] = 8000; - levelrewards[17] = 10000; - levelrewards[18] = 13000; - levelrewards[19] = 16000; - levelrewards[20] = 20000; - levelrewards[21] = 25000; - levelrewards[22] = 32000; - levelrewards[23] = 40000; - levelrewards[24] = 50000; - levelrewards[25] = 60000; - levelrewards[26] = 75000; - levelrewards[27] = 90000; - levelrewards[28] = 110000; - levelrewards[29] = 140000; - levelrewards[30] = 180000; - levelrewards[31] = 220000; - levelrewards[32] = 270000; - levelrewards[33] = 320000; - levelrewards[34] = 400000; - levelrewards[35] = 500000; - levelrewards[36] = 640000; - levelrewards[37] = 800000; - levelrewards[38] = 1000000; - levelrewards[39] = 1500000; - levelrewards[40] = 2000000; - } - } - // ERROR: Handles clauses are not supported in C# private void countdown_Tick(object sender, EventArgs e) { if (this.Left < Screen.PrimaryScreen.Bounds.Width) { - switch (countdown) + if (countdown == 0) { - case 0: - countdown = 3; - lblcountdown.Hide(); - lblbeatai.Hide(); - gameTimer.Start(); - counter.Start(); - tmrcountdown.Stop(); - break; - case 1: - lblcountdown.Text = "1"; - countdown = countdown - 1; - ShiftOS.Engine.AudioManager.PlayStream(Properties.Resources.typesound); - break; - case 2: - lblcountdown.Text = "2"; - countdown = countdown - 1; - ShiftOS.Engine.AudioManager.PlayStream(Properties.Resources.typesound); - break; - case 3: - lblcountdown.Text = "3"; - countdown = countdown - 1; - lblcountdown.Show(); - ShiftOS.Engine.AudioManager.PlayStream(Properties.Resources.typesound); - break; + countdown = 3; + lblcountdown.Hide(); + lblbeatai.Hide(); + gameTimer.Start(); + counter.Start(); + tmrcountdown.Stop(); + return; } - + if (!lblcountdown.Visible) + lblcountdown.Show(); + lblcountdown.Text = countdown.ToString(); + countdown -= 1; + playsound(Properties.Resources.typesound); } } @@ -874,7 +755,7 @@ namespace ShiftOS.WinForms.Applications pnlfinalstats.Show(); lblfinalcodepointswithtext.Text = Localization.Parse("{YOU_WON} " + totalreward + " {CODEPOINTS}!"); lblfinallevelreached.Text = Localization.Parse("{CODEPOINTS_FOR_BEATING_LEVEL}: ") + (level - 1).ToString(); - lblfinallevelreward.Text = levelrewards[level - 1].ToString(); + lblfinallevelreward.Text = (levelrewards[level - 1] * rwdmultiplier).ToString(); lblfinalcomputerreward.Text = beatairewardtotal.ToString(); lblfinalcodepoints.Text = totalreward + Localization.Parse(" {CODEPOINTS_SHORT}"); SaveSystem.TransferCodepointsFrom("pong", totalreward); @@ -912,7 +793,8 @@ namespace ShiftOS.WinForms.Applications if (ShiftoriumFrontend.UpgradeInstalled("pong_upgrade")) { beataireward = 10; - } else + } + else { beataireward = 5; } @@ -981,6 +863,10 @@ namespace ShiftOS.WinForms.Applications var hs = unite.GetPongHighscores(); foreach (var score in hs.Highscores) { + if (this.ParentForm.Visible == false) + { + Thread.CurrentThread.Abort(); + } string username = unite.GetDisplayNameId(score.UserId); this.Invoke(new Action(() => { @@ -994,8 +880,15 @@ namespace ShiftOS.WinForms.Applications } catch { - Infobox.Show("Service unavailable.", "The Pong Highscore service is unavailable at this time."); - this.Invoke(new Action(pnlgamestats.BringToFront)); + try + { + if (this.ParentForm.Visible) + { + Infobox.Show("Service unavailable.", "The Pong Highscore service is unavailable at this time."); + this.Invoke(new Action(pnlgamestats.BringToFront)); + } + } + catch { } //JUST. ABORT. THE. FUCKING. THREAD. return; } }); @@ -1019,7 +912,7 @@ namespace ShiftOS.WinForms.Applications { newgame(); } - + // ERROR: Handles clauses are not supported in C# private void btnstartgame_Click(object sender, EventArgs e) { @@ -1034,9 +927,7 @@ namespace ShiftOS.WinForms.Applications int i = rand.Next(0, 100); if (i >= 25 && i <= 50) - { tmrstoryline.Stop(); - } } @@ -1046,25 +937,13 @@ namespace ShiftOS.WinForms.Applications tmrstoryline.Stop(); } - private void Label6_Click(object sender, EventArgs e) + private void ball_MouseEnter(object sender, EventArgs e) { - - } - - private void Label8_Click(object sender, EventArgs e) - { - - } - - private void pgcontents_Paint(object sender, PaintEventArgs e) { - - } - - private void ball_MouseEnter(object sender, EventArgs e) { aiShouldIsbeEnabled = false; } - private void ball_MouseLeave(object sender, EventArgs e) { + private void ball_MouseLeave(object sender, EventArgs e) + { aiShouldIsbeEnabled = true; } @@ -1091,12 +970,12 @@ namespace ShiftOS.WinForms.Applications public bool OnUnload() { - if(IsMultiplayerSession == true) + if (IsMultiplayerSession) { - if(!string.IsNullOrWhiteSpace(OpponentGUID)) + if (!string.IsNullOrWhiteSpace(OpponentGUID)) ServerManager.Forward(OpponentGUID, "pong_mp_left", null); + LeaveMatchmake(); } - LeaveMatchmake(); ServerManager.MessageReceived -= this.ServerMessageReceivedHandler; return true; @@ -1123,10 +1002,10 @@ namespace ShiftOS.WinForms.Applications private void lvotherplayers_DoubleClick(object sender, EventArgs e) { - if(lvotherplayers.SelectedItems.Count > 0) + if (lvotherplayers.SelectedItems.Count > 0) { SendLeaderGUID(lvotherplayers.SelectedItems[0].Text); } } } -} +} \ No newline at end of file diff --git a/ShiftOS.WinForms/Applications/Pong.resx b/ShiftOS.WinForms/Applications/Pong.resx index 3b5619d..cc96099 100644 --- a/ShiftOS.WinForms/Applications/Pong.resx +++ b/ShiftOS.WinForms/Applications/Pong.resx @@ -129,4 +129,7 @@ 17, 17 + + 472, 17 + \ No newline at end of file diff --git a/ShiftOS.WinForms/Applications/ShiftLetters.cs b/ShiftOS.WinForms/Applications/ShiftLetters.cs index b5e9aa4..0e9f74a 100644 --- a/ShiftOS.WinForms/Applications/ShiftLetters.cs +++ b/ShiftOS.WinForms/Applications/ShiftLetters.cs @@ -38,7 +38,7 @@ namespace ShiftOS.WinForms.Applications { [MultiplayerOnly] [Launcher("ShiftLetters", false, null, "Games")] - [RequiresUpgrade("shiftletters")] + [AppscapeEntry("ShiftLetters", "Let's see how much you know about ShiftOS by playing this tiny little Hangman game! Shiftorium Upgrades exist to allow you to buy different word sets!", 300, 150, null, "Games")] [WinOpen("shiftletters")] [DefaultIcon("iconShiftLetters")] public partial class ShiftLetters : UserControl, IShiftOSWindow @@ -217,7 +217,7 @@ namespace ShiftOS.WinForms.Applications if (!lblword.Text.Contains("_")) { int oldlives = lives; - int cp = (word.Length * oldlives) * 2; //drunky michael made this 5x... + ulong cp = (ulong)(word.Length * oldlives) * 2; //drunky michael made this 5x... SaveSystem.TransferCodepointsFrom("shiftletters", cp); StartGame(); } diff --git a/ShiftOS.WinForms/Applications/ShiftLotto.cs b/ShiftOS.WinForms/Applications/ShiftLotto.cs index 5ab8154..3f940c7 100644 --- a/ShiftOS.WinForms/Applications/ShiftLotto.cs +++ b/ShiftOS.WinForms/Applications/ShiftLotto.cs @@ -88,7 +88,7 @@ namespace ShiftOS.WinForms.Applications } else { - if (SaveSystem.CurrentSave.Codepoints - (codePoints * difficulty) <= 0) + if (SaveSystem.CurrentSave.Codepoints - (ulong)(codePoints * difficulty) <= 0) { Infobox.Show("Not enough Codepoints", "You do not have enough Codepoints to gamble this amount!"); } @@ -102,7 +102,7 @@ namespace ShiftOS.WinForms.Applications int winningNumber = rnd.Next(0, difficulty); // Multiply CodePoints * Difficulty - int jackpot = codePoints * difficulty; + ulong jackpot = (ulong)(codePoints * difficulty); // Test the random ints if (guessedNumber == winningNumber) diff --git a/ShiftOS.WinForms/Applications/ShiftSweeper.cs b/ShiftOS.WinForms/Applications/ShiftSweeper.cs index 72e9062..772ec26 100644 --- a/ShiftOS.WinForms/Applications/ShiftSweeper.cs +++ b/ShiftOS.WinForms/Applications/ShiftSweeper.cs @@ -35,7 +35,7 @@ using ShiftOS.Engine; namespace ShiftOS.WinForms.Applications { [Launcher("ShiftSweeper", true, "al_shiftsweeper", "Games")] - [RequiresUpgrade("shiftsweeper")] + [AppscapeEntry("ShiftSweeper", "A simple Minesweeper game built for ShiftOS! Careful, it's a hard one.", 1600, 800, "shiftletters", "Games")] [MultiplayerOnly] [WinOpen("shiftsweeper")] [DefaultIcon("iconShiftSweeper")] @@ -300,12 +300,12 @@ namespace ShiftOS.WinForms.Applications { } public void winGame() { - int cp = 0; - int origminecount = gameBombCount * 10; + ulong cp = 0; + ulong origminecount = (ulong)(gameBombCount * 10); if (minetimer < 31) cp = (origminecount * 3); - else if (minetimer < 61) cp = (Int32)(origminecount * 2.5); + else if (minetimer < 61) cp = (ulong)(origminecount * 2.5); else if (minetimer < 91) cp = (origminecount * 2); - else if (minetimer < 121) cp = (Int32)(origminecount * 1.5); + else if (minetimer < 121) cp = (ulong)(origminecount * 1.5); else if (minetimer > 120) cp = (origminecount * 1); SaveSystem.TransferCodepointsFrom("shiftsweeper", cp); panelGameStatus.Image = Properties.Resources.SweeperWinFace; diff --git a/ShiftOS.WinForms/Applications/Shifter.cs b/ShiftOS.WinForms/Applications/Shifter.cs index 05ba638..3b3a4f1 100644 --- a/ShiftOS.WinForms/Applications/Shifter.cs +++ b/ShiftOS.WinForms/Applications/Shifter.cs @@ -31,6 +31,8 @@ using System.Reflection; using System.Windows.Forms; using ShiftOS.Engine; using ShiftOS.WinForms.Tools; +using System.Linq; +using System.Threading; namespace ShiftOS.WinForms.Applications { @@ -139,10 +141,7 @@ namespace ShiftOS.WinForms.Applications pnldesktoppreview.BackColor = Color.FromArgb(LoadedSkin.DesktopColor.R, LoadedSkin.DesktopColor.G, LoadedSkin.DesktopColor.B); //Not doing this will cause an ArgumentException. - DitheringEngine.DitherImage(SkinEngine.GetImage("desktopbackground"), new Action((img) => - { - pnldesktoppreview.BackgroundImage = img; - })); + pnldesktoppreview.BackgroundImage = SkinEngine.GetImage("desktopbackground"); pnldesktoppreview.BackgroundImageLayout = GetImageLayout("desktopbackground"); desktoppanel.BackColor = LoadedSkin.DesktopPanelColor; @@ -392,7 +391,7 @@ namespace ShiftOS.WinForms.Applications } - public int CodepointValue = 0; + public uint CodepointValue = 0; public List settings = new List(); public Skin LoadedSkin = null; @@ -543,403 +542,425 @@ namespace ShiftOS.WinForms.Applications { flbody.Controls.Clear(); - List cats = new List(); + IEnumerable cats = this.settings.Where(x => x.SubCategory == subcat && x.Category == cat && x.Field.FlagFullfilled(LoadedSkin)).OrderBy(x=>x.Name); - foreach (var c in this.settings) + new Thread(() => { - if (c.SubCategory == subcat && c.Category == cat) + foreach (var c in cats) { - if (c.Field.FlagFullfilled(LoadedSkin)) + Label lbl = null; + int labelHeight = 0; + Desktop.InvokeOnWorkerThread(() => { - if (!cats.Contains(c)) - { - cats.Add(c); - } - } - } - } - - foreach(var c in cats) - { - var lbl = new Label(); - int labelHeight = 0; - lbl.AutoSize = true; - lbl.Text = c.Name + ":"; - flbody.Controls.Add(lbl); - lbl.TextAlign = ContentAlignment.MiddleLeft; - lbl.Show(); - //Cool - label's in. - if(c.Field.FieldType == typeof(Point)) - { - var width = new TextBox(); - var height = new TextBox(); - labelHeight = width.Height; //irony? - width.Width = 30; - height.Width = width.Width; - width.Text = ((Point)c.Field.GetValue(this.LoadedSkin)).X.ToString(); - height.Text = ((Point)c.Field.GetValue(this.LoadedSkin)).Y.ToString(); - flbody.SetFlowBreak(height, true); - ControlManager.SetupControl(width); - ControlManager.SetupControl(height); - - flbody.Controls.Add(width); - width.Show(); - flbody.Controls.Add(height); - height.Show(); - - EventHandler tc = (o, a) => + lbl = new Label(); + lbl.AutoSize = true; + lbl.Text = c.Name + ":"; + flbody.Controls.Add(lbl); + lbl.TextAlign = ContentAlignment.MiddleLeft; + lbl.Show(); + }); + //Cool - label's in. + if (c.Field.FieldType == typeof(Point)) { - try - { - int x = Convert.ToInt32(width.Text); - int y = Convert.ToInt32(height.Text); - - int oldx = ((Point)c.Field.GetValue(this.LoadedSkin)).X; - int oldy = ((Point)c.Field.GetValue(this.LoadedSkin)).Y; - - if(x != oldx || y != oldy) - { - c.Field.SetValue(LoadedSkin, new Point(x, y)); - CodepointValue += 200; - } - } - catch + TextBox width = null; + TextBox height = null; + Desktop.InvokeOnWorkerThread(() => { + width = new TextBox(); + height = new TextBox(); + labelHeight = width.Height; //irony? + width.Width = 30; + height.Width = width.Width; width.Text = ((Point)c.Field.GetValue(this.LoadedSkin)).X.ToString(); height.Text = ((Point)c.Field.GetValue(this.LoadedSkin)).Y.ToString(); - } - InvokeSetup(cat); - }; + flbody.SetFlowBreak(height, true); + ControlManager.SetupControl(width); + ControlManager.SetupControl(height); - width.TextChanged += tc; - height.TextChanged += tc; + flbody.Controls.Add(width); + width.Show(); + flbody.Controls.Add(height); + height.Show(); - } - else if(c.Field.FieldType == typeof(string)) - { - var str = new TextBox(); - str.Width = 120; - ControlManager.SetupControl(str); - labelHeight = str.Height; - str.Text = c.Field.GetValue(LoadedSkin).ToString(); - flbody.SetFlowBreak(str, true); - str.TextChanged += (o, a) => - { - c.Field.SetValue(LoadedSkin, str.Text); CodepointValue += 100; - - InvokeSetup(cat); - }; - flbody.Controls.Add(str); - str.Show(); - } - else if(c.Field.FieldType == typeof(byte[])) - { - //We'll assume that this is an image file. - var color = new Button(); - color.Width = 40; - labelHeight = color.Height; - //just so it's flat like the system. - ControlManager.SetupControl(color); - flbody.SetFlowBreak(color, true); - - color.BackgroundImage = SkinEngine.ImageFromBinary((byte[])c.Field.GetValue(this.LoadedSkin)); - color.Click += (o, a) => - { - AppearanceManager.SetupDialog(new GraphicPicker(color.BackgroundImage, c.Name, GetLayout(c.Field.GetImageName()), new Action((col, gdiImg, layout) => - { - c.Field.SetValue(LoadedSkin, col); - color.BackgroundImage = SkinEngine.ImageFromBinary(col); - color.BackgroundImageLayout = layout; - LoadedSkin.SkinImageLayouts[c.Field.GetImageName()] = layout; - CodepointValue += 700; - InvokeSetup(cat); - - }))); - }; - flbody.Controls.Add(color); - color.Show(); - } - else if (c.Field.FieldType == typeof(Size)) - { - var width = new TextBox(); - var height = new TextBox(); - width.Width = 30; - height.Width = width.Width; - labelHeight = width.Height; - flbody.SetFlowBreak(height, true); - - width.Text = ((Size)c.Field.GetValue(this.LoadedSkin)).Width.ToString(); - height.Text = ((Size)c.Field.GetValue(this.LoadedSkin)).Height.ToString(); - ControlManager.SetupControl(width); - ControlManager.SetupControl(height); - - flbody.Controls.Add(width); - width.Show(); - flbody.Controls.Add(height); - height.Show(); - - EventHandler tc = (o, a) => - { - try - { - int x = Convert.ToInt32(width.Text); - int y = Convert.ToInt32(height.Text); - - int oldx = ((Size)c.Field.GetValue(this.LoadedSkin)).Width; - int oldy = ((Size)c.Field.GetValue(this.LoadedSkin)).Height; - - if (x != oldx || y != oldy) + EventHandler tc = (o, a) => { - c.Field.SetValue(LoadedSkin, new Size(x, y)); - CodepointValue += 200; - } - } - catch + try + { + int x = Convert.ToInt32(width.Text); + int y = Convert.ToInt32(height.Text); + + int oldx = ((Point)c.Field.GetValue(this.LoadedSkin)).X; + int oldy = ((Point)c.Field.GetValue(this.LoadedSkin)).Y; + + if (x != oldx || y != oldy) + { + c.Field.SetValue(LoadedSkin, new Point(x, y)); + CodepointValue += 200; + } + } + catch + { + width.Text = ((Point)c.Field.GetValue(this.LoadedSkin)).X.ToString(); + height.Text = ((Point)c.Field.GetValue(this.LoadedSkin)).Y.ToString(); + } + InvokeSetup(cat); + }; + + width.TextChanged += tc; + height.TextChanged += tc; + }); + } + else if (c.Field.FieldType == typeof(string)) + { + Desktop.InvokeOnWorkerThread(() => { + var str = new TextBox(); + str.Width = 120; + ControlManager.SetupControl(str); + labelHeight = str.Height; + str.Text = c.Field.GetValue(LoadedSkin).ToString(); + flbody.SetFlowBreak(str, true); + str.TextChanged += (o, a) => + { + c.Field.SetValue(LoadedSkin, str.Text); CodepointValue += 100; + + InvokeSetup(cat); + }; + flbody.Controls.Add(str); + str.Show(); + }); + } + else if (c.Field.FieldType == typeof(byte[])) + { + Desktop.InvokeOnWorkerThread(() => + { + //We'll assume that this is an image file. + var color = new Button(); + color.Width = 40; + labelHeight = color.Height; + //just so it's flat like the system. + ControlManager.SetupControl(color); + flbody.SetFlowBreak(color, true); + + color.BackgroundImage = SkinEngine.ImageFromBinary((byte[])c.Field.GetValue(this.LoadedSkin)); + color.Click += (o, a) => + { + AppearanceManager.SetupDialog(new GraphicPicker(color.BackgroundImage, c.Name, GetLayout(c.Field.GetImageName()), new Action((col, gdiImg, layout) => + { + c.Field.SetValue(LoadedSkin, col); + color.BackgroundImage = SkinEngine.ImageFromBinary(col); + color.BackgroundImageLayout = layout; + LoadedSkin.SkinImageLayouts[c.Field.GetImageName()] = layout; + CodepointValue += 700; + InvokeSetup(cat); + + }))); + }; + flbody.Controls.Add(color); + color.Show(); + }); + } + else if (c.Field.FieldType == typeof(Size)) + { + Desktop.InvokeOnWorkerThread(() => + { + var width = new TextBox(); + var height = new TextBox(); + width.Width = 30; + height.Width = width.Width; + labelHeight = width.Height; + flbody.SetFlowBreak(height, true); + width.Text = ((Size)c.Field.GetValue(this.LoadedSkin)).Width.ToString(); height.Text = ((Size)c.Field.GetValue(this.LoadedSkin)).Height.ToString(); - } - InvokeSetup(cat); + ControlManager.SetupControl(width); + ControlManager.SetupControl(height); - }; + flbody.Controls.Add(width); + width.Show(); + flbody.Controls.Add(height); + height.Show(); - width.TextChanged += tc; - height.TextChanged += tc; - - } - else if(c.Field.FieldType == typeof(bool)) - { - var check = new CheckBox(); - check.Checked = ((bool)c.Field.GetValue(LoadedSkin)); - labelHeight = check.Height; - check.CheckedChanged += (o, a) => - { - c.Field.SetValue(LoadedSkin, check.Checked); - CodepointValue += 50; - InvokeSetup(cat); - - }; - flbody.SetFlowBreak(check, true); - - flbody.Controls.Add(check); - check.Show(); - } - else if(c.Field.FieldType == typeof(Font)) - { - var name = new ComboBox(); - var size = new TextBox(); - var style = new ComboBox(); - - name.Width = 120; - labelHeight = name.Height; - size.Width = 40; - style.Width = 80; - flbody.SetFlowBreak(style, true); - - ControlManager.SetupControl(name); - ControlManager.SetupControl(size); - ControlManager.SetupControl(style); - - //populate the font name box - foreach(var font in FontFamily.Families) - { - name.Items.Add(font.Name); - } - name.Text = ((Font)c.Field.GetValue(LoadedSkin)).Name; - - size.Text = ((Font)c.Field.GetValue(LoadedSkin)).Size.ToString(); - - //populate the style box - foreach(var s in (FontStyle[])Enum.GetValues(typeof(FontStyle))) - { - style.Items.Add(s.ToString()); - } - style.Text = ((Font)c.Field.GetValue(LoadedSkin)).Style.ToString(); - - name.SelectedIndexChanged += (o, a) => - { - var en = (FontStyle[])Enum.GetValues(typeof(FontStyle)); - - var f = en[style.SelectedIndex]; - - c.Field.SetValue(LoadedSkin, new Font(name.Text, (float)Convert.ToDouble(size.Text), f)); - CodepointValue += 100; - InvokeSetup(cat); - - }; - - style.SelectedIndexChanged += (o, a) => - { - var en = (FontStyle[])Enum.GetValues(typeof(FontStyle)); - - var f = en[style.SelectedIndex]; - - c.Field.SetValue(LoadedSkin, new Font(name.Text, (float)Convert.ToDouble(size.Text), f)); - CodepointValue += 50; - InvokeSetup(cat); - - }; - - size.TextChanged += (o, a) => - { - try - { - var en = (FontStyle[])Enum.GetValues(typeof(FontStyle)); - - var f = en[style.SelectedIndex]; - - c.Field.SetValue(LoadedSkin, new Font(name.Text, (float)Convert.ToDouble(size.Text), f)); - } - catch - { - size.Text = ((Font)c.Field.GetValue(LoadedSkin)).Size.ToString(); - } - CodepointValue += 50; - InvokeSetup(cat); - - }; - - flbody.Controls.Add(name); - flbody.Controls.Add(size); - flbody.Controls.Add(style); - - name.Show(); - size.Show(); - style.Show(); - - } - else if(c.Field.FieldType == typeof(Color)) - { - var color = new Button(); - color.Width = 40; - labelHeight = color.Height; - //just so it's flat like the system. - ControlManager.SetupControl(color); - - color.BackColor = ((Color)c.Field.GetValue(LoadedSkin)); - color.BackColorChanged += (o, a) => - { - c.Field.SetValue(LoadedSkin, color.BackColor); - }; - color.Click += (o, a) => - { - AppearanceManager.SetupDialog(new ColorPicker(color.BackColor, c.Name, new Action((col) => - { - color.BackColor = col; - CodepointValue += 300; - InvokeSetup(cat); - - }))); - }; - flbody.SetFlowBreak(color, true); - color.Tag = "keepbg"; - flbody.Controls.Add(color); - color.Show(); - } - else if(c.Field.FieldType.IsEnum == true) - { - var cBox = new ComboBox(); - cBox.Width = 150; - ControlManager.SetupControl(cBox); - - foreach(var itm in Enum.GetNames(c.Field.FieldType)) - { - cBox.Items.Add(itm); - } - - cBox.Text = c.Field.GetValue(LoadedSkin).ToString(); - - cBox.SelectedIndexChanged += (o, a) => - { - c.Field.SetValue(LoadedSkin, Enum.Parse(c.Field.FieldType, cBox.Text)); - InvokeSetup(cat); - - }; - - labelHeight = cBox.Height; - - flbody.Controls.Add(cBox); - cBox.Show(); - flbody.SetFlowBreak(cBox, true); - } - else if(c.Field.FieldType == typeof(int)) - { - if (c.Field.HasShifterEnumMask()) - { - var name = new ComboBox(); - name.Width = 120; - ControlManager.SetupControl(name); - string[] items = c.Field.GetShifterEnumMask(); - foreach(var item in items) - { - name.Items.Add(item); - } - name.SelectedIndex = (int)c.Field.GetValue(LoadedSkin); - name.SelectedIndexChanged += (o, a) => - { - c.Field.SetValue(LoadedSkin, name.SelectedIndex); - CodepointValue += 75; - InvokeSetup(cat); - - }; - labelHeight = name.Height; - flbody.Controls.Add(name); - name.Show(); - flbody.SetFlowBreak(name, true); - - } - else - { - var width = new TextBox(); - width.Width = 30; - width.Text = ((int)c.Field.GetValue(this.LoadedSkin)).ToString(); - ControlManager.SetupControl(width); - labelHeight = width.Height; - flbody.Controls.Add(width); - width.Show(); - - EventHandler tc = (o, a) => - { - try + EventHandler tc = (o, a) => { - int x = Convert.ToInt32(width.Text); - - int oldx = ((int)c.Field.GetValue(this.LoadedSkin)); - - if (x != oldx) + try { - c.Field.SetValue(LoadedSkin, x); - CodepointValue += 75; + int x = Convert.ToInt32(width.Text); + int y = Convert.ToInt32(height.Text); + + int oldx = ((Size)c.Field.GetValue(this.LoadedSkin)).Width; + int oldy = ((Size)c.Field.GetValue(this.LoadedSkin)).Height; + + if (x != oldx || y != oldy) + { + c.Field.SetValue(LoadedSkin, new Size(x, y)); + CodepointValue += 200; + } } - } - catch + catch + { + width.Text = ((Size)c.Field.GetValue(this.LoadedSkin)).Width.ToString(); + height.Text = ((Size)c.Field.GetValue(this.LoadedSkin)).Height.ToString(); + } + InvokeSetup(cat); + + }; + + width.TextChanged += tc; + height.TextChanged += tc; + }); + } + else if (c.Field.FieldType == typeof(bool)) + { + Desktop.InvokeOnWorkerThread(() => + { + var check = new CheckBox(); + check.Checked = ((bool)c.Field.GetValue(LoadedSkin)); + labelHeight = check.Height; + check.CheckedChanged += (o, a) => { - width.Text = ((int)c.Field.GetValue(this.LoadedSkin)).ToString(); + c.Field.SetValue(LoadedSkin, check.Checked); + CodepointValue += 50; + InvokeSetup(cat); + + }; + flbody.SetFlowBreak(check, true); + + flbody.Controls.Add(check); + check.Show(); + }); + } + else if (c.Field.FieldType == typeof(Font)) + { + Desktop.InvokeOnWorkerThread(() => + { + var name = new ComboBox(); + var size = new TextBox(); + var style = new ComboBox(); + + name.Width = 120; + labelHeight = name.Height; + size.Width = 40; + style.Width = 80; + flbody.SetFlowBreak(style, true); + + ControlManager.SetupControl(name); + ControlManager.SetupControl(size); + ControlManager.SetupControl(style); + + //populate the font name box + foreach (var font in FontFamily.Families) + { + name.Items.Add(font.Name); } - InvokeSetup(cat); + name.Text = ((Font)c.Field.GetValue(LoadedSkin)).Name; - }; + size.Text = ((Font)c.Field.GetValue(LoadedSkin)).Size.ToString(); - width.TextChanged += tc; - flbody.SetFlowBreak(width, true); + //populate the style box + foreach (var s in (FontStyle[])Enum.GetValues(typeof(FontStyle))) + { + style.Items.Add(s.ToString()); + } + style.Text = ((Font)c.Field.GetValue(LoadedSkin)).Style.ToString(); + name.SelectedIndexChanged += (o, a) => + { + var en = (FontStyle[])Enum.GetValues(typeof(FontStyle)); + + var f = en[style.SelectedIndex]; + + c.Field.SetValue(LoadedSkin, new Font(name.Text, (float)Convert.ToDouble(size.Text), f)); + CodepointValue += 100; + InvokeSetup(cat); + + }; + + style.SelectedIndexChanged += (o, a) => + { + var en = (FontStyle[])Enum.GetValues(typeof(FontStyle)); + + var f = en[style.SelectedIndex]; + + c.Field.SetValue(LoadedSkin, new Font(name.Text, (float)Convert.ToDouble(size.Text), f)); + CodepointValue += 50; + InvokeSetup(cat); + + }; + + size.TextChanged += (o, a) => + { + try + { + var en = (FontStyle[])Enum.GetValues(typeof(FontStyle)); + + var f = en[style.SelectedIndex]; + + c.Field.SetValue(LoadedSkin, new Font(name.Text, (float)Convert.ToDouble(size.Text), f)); + } + catch + { + size.Text = ((Font)c.Field.GetValue(LoadedSkin)).Size.ToString(); + } + CodepointValue += 50; + InvokeSetup(cat); + + }; + + flbody.Controls.Add(name); + flbody.Controls.Add(size); + flbody.Controls.Add(style); + + name.Show(); + size.Show(); + style.Show(); + }); + } + else if (c.Field.FieldType == typeof(Color)) + { + Desktop.InvokeOnWorkerThread(() => + { + var color = new Button(); + color.Width = 40; + labelHeight = color.Height; + //just so it's flat like the system. + ControlManager.SetupControl(color); + + color.BackColor = ((Color)c.Field.GetValue(LoadedSkin)); + color.Click += (o, a) => + { + AppearanceManager.SetupDialog(new ColorPicker((Color)c.Field.GetValue(LoadedSkin), c.Name, new Action((col) => + { + color.BackColor = col; + c.Field.SetValue(LoadedSkin, col); + CodepointValue += 300; + InvokeSetup(cat); + + }))); + }; + flbody.SetFlowBreak(color, true); + color.Tag = "keepbg"; + flbody.Controls.Add(color); + color.Show(); + }); + } + else if (c.Field.FieldType.IsEnum == true) + { + Desktop.InvokeOnWorkerThread(() => + { + var cBox = new ComboBox(); + cBox.Width = 150; + ControlManager.SetupControl(cBox); + + foreach (var itm in Enum.GetNames(c.Field.FieldType)) + { + cBox.Items.Add(itm); + } + + cBox.Text = c.Field.GetValue(LoadedSkin).ToString(); + + cBox.SelectedIndexChanged += (o, a) => + { + c.Field.SetValue(LoadedSkin, Enum.Parse(c.Field.FieldType, cBox.Text)); + InvokeSetup(cat); + + }; + + labelHeight = cBox.Height; + + flbody.Controls.Add(cBox); + cBox.Show(); + flbody.SetFlowBreak(cBox, true); + }); + } + else if (c.Field.FieldType == typeof(int)) + { + Desktop.InvokeOnWorkerThread(() => + { + if (c.Field.HasShifterEnumMask()) + { + var name = new ComboBox(); + name.Width = 120; + ControlManager.SetupControl(name); + string[] items = c.Field.GetShifterEnumMask(); + foreach (var item in items) + { + name.Items.Add(item); + } + name.SelectedIndex = (int)c.Field.GetValue(LoadedSkin); + name.SelectedIndexChanged += (o, a) => + { + c.Field.SetValue(LoadedSkin, name.SelectedIndex); + CodepointValue += 75; + InvokeSetup(cat); + + }; + labelHeight = name.Height; + flbody.Controls.Add(name); + name.Show(); + flbody.SetFlowBreak(name, true); + + } + else + { + var width = new TextBox(); + width.Width = 30; + width.Text = ((int)c.Field.GetValue(this.LoadedSkin)).ToString(); + ControlManager.SetupControl(width); + labelHeight = width.Height; + flbody.Controls.Add(width); + width.Show(); + + EventHandler tc = (o, a) => + { + try + { + int x = Convert.ToInt32(width.Text); + + int oldx = ((int)c.Field.GetValue(this.LoadedSkin)); + + if (x != oldx) + { + c.Field.SetValue(LoadedSkin, x); + CodepointValue += 75; + } + } + catch + { + width.Text = ((int)c.Field.GetValue(this.LoadedSkin)).ToString(); + } + InvokeSetup(cat); + + }; + + width.TextChanged += tc; + flbody.SetFlowBreak(width, true); + + } + }); + } + Desktop.InvokeOnWorkerThread(() => + { + lbl.AutoSize = false; + lbl.Width = (int)this.CreateGraphics().MeasureString(lbl.Text, SkinEngine.LoadedSkin.MainFont).Width + 15; + lbl.Height = labelHeight; + lbl.TextAlign = ContentAlignment.MiddleLeft; + }); + + if (!string.IsNullOrWhiteSpace(c.Description)) + { + Desktop.InvokeOnWorkerThread(() => + { + var desc = new Label(); + flbody.SetFlowBreak(desc, true); + desc.Text = c.Description; + desc.AutoSize = true; + flbody.Controls.Add(desc); + desc.Show(); + }); } } - lbl.AutoSize = false; - lbl.Width = (int)this.CreateGraphics().MeasureString(lbl.Text, SkinEngine.LoadedSkin.MainFont).Width + 15; - lbl.Height = labelHeight; - lbl.TextAlign = ContentAlignment.MiddleLeft; - - if (!string.IsNullOrWhiteSpace(c.Description)) - { - var desc = new Label(); - flbody.SetFlowBreak(desc, true); - desc.Text = c.Description; - desc.AutoSize = true; - flbody.Controls.Add(desc); - desc.Show(); - } - } + }).Start(); } public ImageLayout GetLayout(string name) diff --git a/ShiftOS.WinForms/Applications/Shiftnet.cs b/ShiftOS.WinForms/Applications/Shiftnet.cs index 7f5d3c1..6ccdb19 100644 --- a/ShiftOS.WinForms/Applications/Shiftnet.cs +++ b/ShiftOS.WinForms/Applications/Shiftnet.cs @@ -80,6 +80,7 @@ namespace ShiftOS.WinForms.Applications 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); + flcontrols.BackColor = SkinEngine.LoadedSkin.TitleBackgroundColor; } public bool OnUnload() @@ -147,6 +148,7 @@ namespace ShiftOS.WinForms.Applications public void NavigateToUrl(string url) { + txturl.Text = url; foreach(var exe in Directory.GetFiles(Environment.CurrentDirectory)) { @@ -171,7 +173,7 @@ namespace ShiftOS.WinForms.Applications var obj = (IShiftnetSite)Activator.CreateInstance(type, null); obj.GoToUrl += (u) => { - History.Push(u); + History.Push(CurrentUrl); NavigateToUrl(u); }; obj.GoBack += () => @@ -188,6 +190,7 @@ namespace ShiftOS.WinForms.Applications obj.OnUpgrade(); obj.OnSkinLoad(); obj.Setup(); + AppearanceManager.SetWindowTitle(this, attribute.Name + " - Shiftnet"); return; } } diff --git a/ShiftOS.WinForms/Applications/ShiftoriumFrontend.Designer.cs b/ShiftOS.WinForms/Applications/ShiftoriumFrontend.Designer.cs index 32d508b..e4e493e 100644 --- a/ShiftOS.WinForms/Applications/ShiftoriumFrontend.Designer.cs +++ b/ShiftOS.WinForms/Applications/ShiftoriumFrontend.Designer.cs @@ -61,16 +61,16 @@ namespace ShiftOS.WinForms.Applications this.btnbuy = new System.Windows.Forms.Button(); this.lbupgradetitle = new System.Windows.Forms.Label(); this.pnllist = new System.Windows.Forms.Panel(); + this.lbnoupgrades = new System.Windows.Forms.Label(); + this.panel3 = new System.Windows.Forms.Panel(); + this.lblcategorytext = new System.Windows.Forms.Label(); + this.btncat_forward = new System.Windows.Forms.Button(); + this.btncat_back = new System.Windows.Forms.Button(); this.lbcodepoints = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label(); this.pgupgradeprogress = new ShiftOS.WinForms.Controls.ShiftedProgressBar(); this.lbupgrades = new System.Windows.Forms.ListBox(); this.label3 = new System.Windows.Forms.Label(); - this.panel3 = new System.Windows.Forms.Panel(); - this.btncat_back = new System.Windows.Forms.Button(); - this.btncat_forward = new System.Windows.Forms.Button(); - this.lblcategorytext = new System.Windows.Forms.Label(); - this.lbnoupgrades = new System.Windows.Forms.Label(); this.panel1.SuspendLayout(); this.panel2.SuspendLayout(); this.pnlupgradeactions.SuspendLayout(); @@ -159,6 +159,63 @@ namespace ShiftOS.WinForms.Applications this.pnllist.Size = new System.Drawing.Size(406, 427); this.pnllist.TabIndex = 0; // + // lbnoupgrades + // + this.lbnoupgrades.AutoSize = true; + this.lbnoupgrades.Location = new System.Drawing.Point(69, 183); + this.lbnoupgrades.Name = "lbnoupgrades"; + this.lbnoupgrades.Size = new System.Drawing.Size(71, 13); + this.lbnoupgrades.TabIndex = 6; + this.lbnoupgrades.Tag = "header2"; + this.lbnoupgrades.Text = "No upgrades!"; + this.lbnoupgrades.Visible = false; + // + // panel3 + // + this.panel3.Controls.Add(this.lblcategorytext); + this.panel3.Controls.Add(this.btncat_forward); + this.panel3.Controls.Add(this.btncat_back); + this.panel3.Location = new System.Drawing.Point(6, 76); + this.panel3.Name = "panel3"; + this.panel3.Size = new System.Drawing.Size(394, 23); + this.panel3.TabIndex = 5; + // + // lblcategorytext + // + this.lblcategorytext.Dock = System.Windows.Forms.DockStyle.Fill; + this.lblcategorytext.Location = new System.Drawing.Point(29, 0); + this.lblcategorytext.Name = "lblcategorytext"; + this.lblcategorytext.Size = new System.Drawing.Size(336, 23); + this.lblcategorytext.TabIndex = 2; + this.lblcategorytext.Text = "No Upgrades"; + this.lblcategorytext.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // btncat_forward + // + this.btncat_forward.AutoSize = true; + this.btncat_forward.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.btncat_forward.Dock = System.Windows.Forms.DockStyle.Right; + this.btncat_forward.Location = new System.Drawing.Point(365, 0); + this.btncat_forward.Name = "btncat_forward"; + this.btncat_forward.Size = new System.Drawing.Size(29, 23); + this.btncat_forward.TabIndex = 1; + this.btncat_forward.Text = "-->"; + this.btncat_forward.UseVisualStyleBackColor = true; + this.btncat_forward.Click += new System.EventHandler(this.btncat_forward_Click); + // + // btncat_back + // + this.btncat_back.AutoSize = true; + this.btncat_back.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.btncat_back.Dock = System.Windows.Forms.DockStyle.Left; + this.btncat_back.Location = new System.Drawing.Point(0, 0); + this.btncat_back.Name = "btncat_back"; + this.btncat_back.Size = new System.Drawing.Size(29, 23); + this.btncat_back.TabIndex = 0; + this.btncat_back.Text = "<--"; + this.btncat_back.UseVisualStyleBackColor = true; + this.btncat_back.Click += new System.EventHandler(this.btncat_back_Click); + // // lbcodepoints // this.lbcodepoints.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); @@ -168,7 +225,6 @@ namespace ShiftOS.WinForms.Applications this.lbcodepoints.Size = new System.Drawing.Size(135, 13); this.lbcodepoints.TabIndex = 3; this.lbcodepoints.Text = "You have: %cp Codepoints"; - this.lbcodepoints.Click += new System.EventHandler(this.lbcodepoints_Click); // // label1 // @@ -184,12 +240,10 @@ namespace ShiftOS.WinForms.Applications // this.pgupgradeprogress.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.pgupgradeprogress.BlockSize = 5; this.pgupgradeprogress.Location = new System.Drawing.Point(146, 390); this.pgupgradeprogress.Maximum = 100; this.pgupgradeprogress.Name = "pgupgradeprogress"; this.pgupgradeprogress.Size = new System.Drawing.Size(254, 23); - this.pgupgradeprogress.Style = System.Windows.Forms.ProgressBarStyle.Continuous; this.pgupgradeprogress.TabIndex = 1; this.pgupgradeprogress.Value = 25; // @@ -215,63 +269,6 @@ namespace ShiftOS.WinForms.Applications this.label3.Size = new System.Drawing.Size(137, 13); this.label3.TabIndex = 2; // - // panel3 - // - this.panel3.Controls.Add(this.lblcategorytext); - this.panel3.Controls.Add(this.btncat_forward); - this.panel3.Controls.Add(this.btncat_back); - this.panel3.Location = new System.Drawing.Point(6, 76); - this.panel3.Name = "panel3"; - this.panel3.Size = new System.Drawing.Size(394, 23); - this.panel3.TabIndex = 5; - // - // btncat_back - // - this.btncat_back.AutoSize = true; - this.btncat_back.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.btncat_back.Dock = System.Windows.Forms.DockStyle.Left; - this.btncat_back.Location = new System.Drawing.Point(0, 0); - this.btncat_back.Name = "btncat_back"; - this.btncat_back.Size = new System.Drawing.Size(29, 23); - this.btncat_back.TabIndex = 0; - this.btncat_back.Text = "<--"; - this.btncat_back.UseVisualStyleBackColor = true; - this.btncat_back.Click += new System.EventHandler(this.btncat_back_Click); - // - // btncat_forward - // - this.btncat_forward.AutoSize = true; - this.btncat_forward.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.btncat_forward.Dock = System.Windows.Forms.DockStyle.Right; - this.btncat_forward.Location = new System.Drawing.Point(365, 0); - this.btncat_forward.Name = "btncat_forward"; - this.btncat_forward.Size = new System.Drawing.Size(29, 23); - this.btncat_forward.TabIndex = 1; - this.btncat_forward.Text = "-->"; - this.btncat_forward.UseVisualStyleBackColor = true; - this.btncat_forward.Click += new System.EventHandler(this.btncat_forward_Click); - // - // lblcategorytext - // - this.lblcategorytext.Dock = System.Windows.Forms.DockStyle.Fill; - this.lblcategorytext.Location = new System.Drawing.Point(29, 0); - this.lblcategorytext.Name = "lblcategorytext"; - this.lblcategorytext.Size = new System.Drawing.Size(336, 23); - this.lblcategorytext.TabIndex = 2; - this.lblcategorytext.Text = "label2"; - this.lblcategorytext.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - // - // lbnoupgrades - // - this.lbnoupgrades.AutoSize = true; - this.lbnoupgrades.Location = new System.Drawing.Point(69, 183); - this.lbnoupgrades.Name = "lbnoupgrades"; - this.lbnoupgrades.Size = new System.Drawing.Size(71, 13); - this.lbnoupgrades.TabIndex = 6; - this.lbnoupgrades.Tag = "header2"; - this.lbnoupgrades.Text = "No upgrades!"; - this.lbnoupgrades.Visible = false; - // // ShiftoriumFrontend // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -281,7 +278,6 @@ namespace ShiftOS.WinForms.Applications this.ForeColor = System.Drawing.Color.LightGreen; this.Name = "ShiftoriumFrontend"; this.Size = new System.Drawing.Size(782, 427); - this.Load += new System.EventHandler(this.Shiftorium_Load); this.panel1.ResumeLayout(false); this.panel2.ResumeLayout(false); this.pnlupgradeactions.ResumeLayout(false); diff --git a/ShiftOS.WinForms/Applications/ShiftoriumFrontend.cs b/ShiftOS.WinForms/Applications/ShiftoriumFrontend.cs index 66b0448..0ae0803 100644 --- a/ShiftOS.WinForms/Applications/ShiftoriumFrontend.cs +++ b/ShiftOS.WinForms/Applications/ShiftoriumFrontend.cs @@ -30,6 +30,7 @@ using System.Drawing; using System.Linq; using System.Reflection; using System.Text; +using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using ShiftOS.Engine; @@ -46,19 +47,22 @@ namespace ShiftOS.WinForms.Applications public partial class ShiftoriumFrontend : UserControl, IShiftOSWindow { public int CategoryId = 0; - public static System.Timers.Timer timer100; + private string[] cats = backend.GetCategories(); + private ShiftoriumUpgrade[] avail; + public void updatecounter() + { + Desktop.InvokeOnWorkerThread(() => { lbcodepoints.Text = $"You have {SaveSystem.CurrentSave.Codepoints} Codepoints."; }); + } + public ShiftoriumFrontend() { - cp_update = new System.Windows.Forms.Timer(); - cp_update.Tick += (o, a) => - { - lbcodepoints.Text = $"You have {SaveSystem.CurrentSave.Codepoints} Codepoints."; - }; - cp_update.Interval = 100; InitializeComponent(); - PopulateShiftorium(); + SaveSystem.CurrentSave.addSetCpCallback(updatecounter); + updatecounter(); + Populate(); + SetList(); lbupgrades.SelectedIndexChanged += (o, a) => { try @@ -81,55 +85,57 @@ namespace ShiftOS.WinForms.Applications public void SelectUpgrade(string name) { btnbuy.Show(); - var upg = upgrades[name]; + var upg = upgrades[CategoryId][name]; lbupgradetitle.Text = Localization.Parse(upg.Name); lbupgradedesc.Text = Localization.Parse(upg.Description); } - Dictionary upgrades = new Dictionary(); - - public void PopulateShiftorium() + Dictionary[] upgrades; + + private void Populate() { + upgrades = new Dictionary[cats.Length]; + int numComplete = 0; + avail = backend.GetAvailable(); + foreach (var it in cats.Select((catName, catId) => new { catName, catId })) + { + var upl = new Dictionary(); + upgrades[it.catId] = upl; + var t = new Thread((tupobj) => + { + foreach (var upg in avail.Where(x => x.Category == it.catName)) + upl.Add(Localization.Parse(upg.Name) + " - " + upg.Cost.ToString() + "CP", upg); + numComplete++; + }); + t.Start(); + } + while (numComplete < cats.Length) { } // wait for all threads to finish their job + } + + private void SetList() + { + lbnoupgrades.Hide(); + lbupgrades.Items.Clear(); try { - lbnoupgrades.Hide(); - lbupgrades.Items.Clear(); - upgrades.Clear(); - Timer(); - - foreach (var upg in backend.GetAvailable().Where(x => x.Category == backend.GetCategories()[CategoryId])) - { - String name = Localization.Parse(upg.Name) + " - " + upg.Cost.ToString() + "CP"; - upgrades.Add(name, upg); - lbupgrades.Items.Add(name); - } - - if (lbupgrades.Items.Count == 0) - { - lbnoupgrades.Show(); - lbnoupgrades.Location = new Point( - (lbupgrades.Width - lbnoupgrades.Width) / 2, - (lbupgrades.Height - lbnoupgrades.Height) / 2 - ); - - } - else - { - lbnoupgrades.Hide(); - } - lblcategorytext.Text = Shiftorium.GetCategories()[CategoryId]; - btncat_back.Visible = (CategoryId > 0); - btncat_forward.Visible = (CategoryId < backend.GetCategories().Length - 1); + lbupgrades.Items.AddRange(upgrades[CategoryId].Keys.ToArray()); } catch + { + Engine.Infobox.Show("Shiftorium Machine Broke", "Category ID " + CategoryId.ToString() + " is invalid, modulo is broken, and the world is doomed. Please tell Declan about this."); + return; + } + if (lbupgrades.Items.Count == 0) { lbnoupgrades.Show(); lbnoupgrades.Location = new Point( (lbupgrades.Width - lbnoupgrades.Width) / 2, - (lbupgrades.Height - lbnoupgrades.Height) / 2 + lbupgrades.Top + (lbupgrades.Height - lbnoupgrades.Height) / 2 ); - } + else + lbnoupgrades.Hide(); + lblcategorytext.Text = cats[CategoryId]; } public static bool UpgradeInstalled(string upg) @@ -183,13 +189,14 @@ namespace ShiftOS.WinForms.Applications private void btnbuy_Click(object sender, EventArgs e) { - long cpCost = 0; + ulong cpCost = 0; backend.Silent = true; - Dictionary UpgradesToBuy = new Dictionary(); + Dictionary UpgradesToBuy = new Dictionary(); foreach (var itm in lbupgrades.SelectedItems) { - cpCost += upgrades[itm.ToString()].Cost; - UpgradesToBuy.Add(upgrades[itm.ToString()].ID, upgrades[itm.ToString()].Cost); + var upg = upgrades[CategoryId][itm.ToString()]; + cpCost += upg.Cost; + UpgradesToBuy.Add(upg.ID, upg.Cost); } if (SaveSystem.CurrentSave.Codepoints < cpCost) { @@ -200,22 +207,26 @@ namespace ShiftOS.WinForms.Applications { foreach(var upg in UpgradesToBuy) { - backend.Buy(upg.Key, upg.Value); + if (SaveSystem.CurrentSave.Upgrades.ContainsKey(upg.Key)) + { + SaveSystem.CurrentSave.Upgrades[upg.Key] = true; + } + else + { + SaveSystem.CurrentSave.Upgrades.Add(upg.Key, true); + } + SaveSystem.SaveGame(); + backend.InvokeUpgradeInstalled(); } + SaveSystem.CurrentSave.Codepoints -= cpCost; } backend.Silent = false; - PopulateShiftorium(); btnbuy.Hide(); } - private void Shiftorium_Load(object sender, EventArgs e) { - - } - public void OnLoad() { - cp_update.Start(); lbnoupgrades.Hide(); } @@ -224,12 +235,9 @@ namespace ShiftOS.WinForms.Applications } - Timer cp_update = new System.Windows.Forms.Timer(); - public bool OnUnload() { - cp_update.Stop(); - cp_update = null; + SaveSystem.CurrentSave.removeSetCpCallback(updatecounter); return true; } @@ -237,38 +245,26 @@ namespace ShiftOS.WinForms.Applications { lbupgrades.SelectionMode = (UpgradeInstalled("shiftorium_gui_bulk_buy") == true) ? SelectionMode.MultiExtended : SelectionMode.One; lbcodepoints.Visible = Shiftorium.UpgradeInstalled("shiftorium_gui_codepoints_display"); + Populate(); + SetList(); } - private void lbcodepoints_Click(object sender, EventArgs e) + private void moveCat(short direction) // direction is -1 to move backwards or 1 to move forwards { - - } - - void Timer() - { - timer100 = new System.Timers.Timer(); - timer100.Interval = 2000; - //timer100.Elapsed += ???; - timer100.AutoReset = true; - timer100.Enabled = true; + CategoryId += direction; + CategoryId %= cats.Length; + if (CategoryId < 0) CategoryId += cats.Length; // fix modulo on negatives + SetList(); } private void btncat_back_Click(object sender, EventArgs e) { - if(CategoryId > 0) - { - CategoryId--; - PopulateShiftorium(); - } + moveCat(-1); } private void btncat_forward_Click(object sender, EventArgs e) { - if(CategoryId < backend.GetCategories().Length - 1) - { - CategoryId++; - PopulateShiftorium(); - } + moveCat(1); } } } diff --git a/ShiftOS.WinForms/Applications/ShopItemCreator.cs b/ShiftOS.WinForms/Applications/ShopItemCreator.cs index 61e7491..d2836ee 100644 --- a/ShiftOS.WinForms/Applications/ShopItemCreator.cs +++ b/ShiftOS.WinForms/Applications/ShopItemCreator.cs @@ -73,7 +73,7 @@ namespace ShiftOS.WinForms.Applications Infobox.Show("No file chosen.", "Please select a file to sell."); return; } - Item.Cost = Convert.ToInt32(txtcost.Text); + Item.Cost = Convert.ToUInt64(txtcost.Text); Item.Description = txtdescription.Text; Item.Name = txtitemname.Text; Callback?.Invoke(Item); @@ -101,7 +101,7 @@ namespace ShiftOS.WinForms.Applications { try { - Item.Cost = Convert.ToInt32(txtcost.Text); + Item.Cost = Convert.ToUInt64(txtcost.Text); } catch { diff --git a/ShiftOS.WinForms/Applications/Skin Loader.cs b/ShiftOS.WinForms/Applications/Skin Loader.cs index f9857b7..e4f0597 100644 --- a/ShiftOS.WinForms/Applications/Skin Loader.cs +++ b/ShiftOS.WinForms/Applications/Skin Loader.cs @@ -65,8 +65,11 @@ namespace ShiftOS.WinForms.Applications public void SetupUI() { - SetupDesktop(); - Setup(); + if (LoadedSkin != null) + { + SetupDesktop(); + Setup(); + } } public void SetupDesktop() @@ -78,7 +81,7 @@ namespace ShiftOS.WinForms.Applications //upgrades - if (SaveSystem.CurrentSave != null) + if (SaveSystem.CurrentSave != null && LoadedSkin != null) { desktoppanel.Visible = ShiftoriumFrontend.UpgradeInstalled("desktop"); lbtime.Visible = ShiftoriumFrontend.UpgradeInstalled("desktop_clock_widget"); @@ -303,7 +306,7 @@ namespace ShiftOS.WinForms.Applications System.IO.Directory.CreateDirectory(Paths.SharedFolder + "\\skins"); } - string path = Paths.SharedFolder + "\\skins\\" + SaveSystem.CurrentSave.Username + "-" + fname; + string path = Paths.SharedFolder + "\\skins\\" + SaveSystem.CurrentUser.Username + "-" + fname; System.IO.File.WriteAllText(path, JsonConvert.SerializeObject(LoadedSkin)); }))); diff --git a/ShiftOS.WinForms/Applications/Terminal.cs b/ShiftOS.WinForms/Applications/Terminal.cs index 32c5363..687b2b9 100644 --- a/ShiftOS.WinForms/Applications/Terminal.cs +++ b/ShiftOS.WinForms/Applications/Terminal.cs @@ -130,25 +130,31 @@ namespace ShiftOS.WinForms.Applications { this.Invoke(new Action(() => { - ResetAllKeywords(); - rtbterm.Text = ""; - if (!Shiftorium.UpgradeInstalled("desktop")) + if (Shiftorium.UpgradeInstalled("first_steps")) { - TerminalBackend.PrefixEnabled = true; - TerminalBackend.InStory = false; - TerminalBackend.PrintPrompt(); - if (Shiftorium.UpgradeInstalled("wm_free_placement")) + if (!Shiftorium.UpgradeInstalled("desktop")) { - this.ParentForm.Width = 640; - this.ParentForm.Height = 480; - this.ParentForm.Left = (Screen.PrimaryScreen.Bounds.Width - 640) / 2; - this.ParentForm.Top = (Screen.PrimaryScreen.Bounds.Height - 480) / 2; + TerminalBackend.PrefixEnabled = true; + TerminalBackend.InStory = false; + TerminalBackend.PrintPrompt(); + if (Shiftorium.UpgradeInstalled("wm_free_placement")) + { + this.ParentForm.Width = 640; + this.ParentForm.Height = 480; + this.ParentForm.Left = (Screen.PrimaryScreen.Bounds.Width - 640) / 2; + this.ParentForm.Top = (Screen.PrimaryScreen.Bounds.Height - 480) / 2; + } + } + else + { + AppearanceManager.Close(this); } } else { - AppearanceManager.Close(this); + Story.Start("first_steps"); + } })); } @@ -195,52 +201,6 @@ namespace ShiftOS.WinForms.Applications public static event TextSentEventHandler TextSent; - public void ResetAllKeywords() - { - string primary = SaveSystem.CurrentUser.Username + " "; - string secondary = "shiftos "; - - - var asm = Assembly.GetExecutingAssembly(); - - var types = asm.GetTypes(); - - foreach (var type in types) - { - foreach (var a in type.GetCustomAttributes(false)) - { - if (ShiftoriumFrontend.UpgradeAttributesUnlocked(type)) - { - if (a is Namespace) - { - var ns = a as Namespace; - if (!primary.Contains(ns.name)) - { - primary += ns.name + " "; - } - foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) - { - if (ShiftoriumFrontend.UpgradeAttributesUnlocked(method)) - { - foreach (var ma in method.GetCustomAttributes(false)) - { - if (ma is Command) - { - var cmd = ma as Command; - if (!secondary.Contains(cmd.name)) - secondary += cmd.name + " "; - } - } - } - } - } - } - } - } - - - } - public static void MakeWidget(Controls.TerminalBox txt) { AppearanceManager.StartConsoleOut(); @@ -260,11 +220,19 @@ namespace ShiftOS.WinForms.Applications { try { - a.SuppressKeyPress = true; - Console.WriteLine(""); + if (!TerminalBackend.InStory) + a.SuppressKeyPress = false; + if (!TerminalBackend.PrefixEnabled) + { + string textraw = txt.Lines[txt.Lines.Length - 1]; + TextSent?.Invoke(textraw); + TerminalBackend.SendText(textraw); + return; + } var text = txt.Lines.ToArray(); - var text2 = text[text.Length - 2]; + var text2 = text[text.Length - 1]; var text3 = ""; + txt.AppendText(Environment.NewLine); var text4 = Regex.Replace(text2, @"\t|\n|\r", ""); if (IsInRemoteSystem == true) @@ -345,21 +313,24 @@ namespace ShiftOS.WinForms.Applications } else if (a.KeyCode == Keys.Left) { - var getstring = txt.Lines[txt.Lines.Length - 1]; - var stringlen = getstring.Length + 1; - var header = $"{SaveSystem.CurrentUser.Username}@{SaveSystem.CurrentSave.SystemName}:~$ "; - var headerlen = header.Length + 1; - var selstart = txt.SelectionStart; - var remstrlen = txt.TextLength - stringlen; - var finalnum = selstart - remstrlen; + if (SaveSystem.CurrentSave != null) + { + var getstring = txt.Lines[txt.Lines.Length - 1]; + var stringlen = getstring.Length + 1; + var header = $"{SaveSystem.CurrentUser.Username}@{SaveSystem.CurrentSave.SystemName}:~$ "; + var headerlen = header.Length + 1; + var selstart = txt.SelectionStart; + var remstrlen = txt.TextLength - stringlen; + var finalnum = selstart - remstrlen; - if (finalnum != headerlen) - { - AppearanceManager.CurrentPosition--; - } - else - { - a.SuppressKeyPress = true; + if (finalnum != headerlen) + { + AppearanceManager.CurrentPosition--; + } + else + { + a.SuppressKeyPress = true; + } } } else if (a.KeyCode == Keys.Up) @@ -367,6 +338,7 @@ namespace ShiftOS.WinForms.Applications var tostring3 = txt.Lines[txt.Lines.Length - 1]; if (tostring3 == $"{SaveSystem.CurrentUser.Username}@{SaveSystem.CurrentSave.SystemName}:~$ ") Console.Write(TerminalBackend.LastCommand); + ConsoleEx.OnFlush?.Invoke(); a.SuppressKeyPress = true; } @@ -421,17 +393,212 @@ namespace ShiftOS.WinForms.Applications if (SaveSystem.CurrentSave != null) { + TerminalBackend.PrintPrompt(); if (!ShiftoriumFrontend.UpgradeInstalled("window_manager")) { rtbterm.Select(rtbterm.TextLength, 0); } } - new Thread(() => - { - Thread.Sleep(1000); + } + + public static string RemoteSystemName { get; set; } + public static string RemoteUser { get; set; } + public static string RemotePass { get; set; } + + [Story("first_steps")] + public static void FirstSteps() + { + TerminalBackend.PrefixEnabled = false; + TerminalBackend.InStory = true; + Console.WriteLine("Hey there, and welcome to ShiftOS."); + Thread.Sleep(2000); + Console.WriteLine("My name is DevX. I am the developer of this operating system."); + Thread.Sleep(2000); + Console.WriteLine("Right now, I am using the Terminal application as a means of talking to you."); + Thread.Sleep(2000); + Console.WriteLine("ShiftOS is a very early operating system, but I have big plans for it."); + Thread.Sleep(2000); + Console.WriteLine("I can't reveal all my plans to you at this moment, but you play a big role."); + Thread.Sleep(2000); + Console.WriteLine("Your role in all of this is to help me develop ShiftOS more."); + Thread.Sleep(2000); + Console.WriteLine("You may not know how to program, but that's perfectly fine. You don't need to."); + Thread.Sleep(2000); + Console.WriteLine("What you do need to do, is simply use the operating system - like you would a regular computer."); + Thread.Sleep(2000); + Console.WriteLine("As you use ShiftOS, you will earn a special currency called Codepoints."); + Thread.Sleep(2000); + Console.WriteLine("The more things you do, the more Codepoints you get! Simple, right?"); + Thread.Sleep(2000); + Console.WriteLine("Once you rack up enough Codepoints, you can use them inside the Shiftorium to buy new features for ShiftOS."); + Thread.Sleep(2000); + Console.WriteLine("These features include new programs, system enhancements, Terminal commands, and so much more!"); + Thread.Sleep(2000); + Console.WriteLine("Ahh, that reminds me. I suppose you don't know how to use the Terminal yet, do you..."); + Thread.Sleep(2000); + Console.WriteLine("Well, the ShiftOS terminal is similar to a regular Linux terminal, however things are a bit... how you say.... primitive."); + Thread.Sleep(2000); + Console.WriteLine("Let's just say.... I've been focusing more on function than form with this one.... Anyways, here's how the terminal works."); + Thread.Sleep(2000); + Console.WriteLine("Each command is categorized into a \"Namespace\". All a namespace is, is a nice way of distinguishing between commands."); + Thread.Sleep(2000); + Console.WriteLine("...For example you may have a bunch of commands for managing files, and others for opening/closing programs."); + Thread.Sleep(2000); + Console.WriteLine("The three main namespaces you'll be using for the next while are the \"sos\", \"shiftorium\", and \"win\" namespaces."); + Thread.Sleep(2000); + Console.WriteLine("To run a command, simply type its namespace, followed by a period/full-stop, followed by the command name."); + Thread.Sleep(2000); + Console.WriteLine("Give it a try! Type \"sos.help\" in the following prompt to view a list of all ShiftOS commands."); + Thread.Sleep(2000); + TerminalBackend.InStory = false; + TerminalBackend.PrefixEnabled = true; TerminalBackend.PrintPrompt(); - }).Start(); + bool help_entered = false; + TerminalBackend.CommandProcessed += (text, args) => + { + if (text.EndsWith("sos.help") && help_entered == false) + help_entered = true; + }; + while (help_entered == false) + Thread.Sleep(10); + TerminalBackend.InStory = true; + TerminalBackend.PrefixEnabled = false; + Thread.Sleep(2000); + Console.WriteLine("Good job! Next, we will look at how to pass data to a command, such as win.open."); + Thread.Sleep(2000); + Console.WriteLine("In ShiftOS, passing data to a command is quite simple! After the command name, place an opening and closing curly brace, like so: \"win.open{}\"."); + Thread.Sleep(2000); + Console.WriteLine("Everything between those two curly braces is treated as command data."); + Thread.Sleep(2000); + Console.WriteLine("However, you can't just spam a bunch of 1s and 0s and call it a day, nonono!"); + Thread.Sleep(2000); + Console.WriteLine("Command data is split into a list of keys and values."); + Thread.Sleep(2000); + Console.WriteLine("The key tells the command the name of the data, and the value is what the command will see when it looks at the key."); + Thread.Sleep(2000); + Console.WriteLine("There are three main types of values. Booleans, which can be either \"true\" or \"false\", Numbers, which can be any integer number, positive or negative, and Strings - any piece of text as long as it is surrounded by double-quotes."); + Thread.Sleep(2000); + Console.WriteLine("For example, we could write every programmer's first program - by typing \"trm.echo{msg:\"Hello, world!\"}\". Running this will cause the Terminal to print, well, \"Hello, world!\""); + Thread.Sleep(2000); + Console.WriteLine("To open an application in ShiftOS, you can use this principle with the \"win.open\" command."); + Thread.Sleep(2000); + Console.WriteLine("First, type \"win.open\" with no data to see a list of all installed programs."); + Thread.Sleep(2000); + TerminalBackend.InStory = false; + bool winopenEntered = false; + TerminalBackend.PrefixEnabled = true; + TerminalBackend.PrintPrompt(); + TerminalBackend.CommandProcessed += (text, args) => + { + if (help_entered == true) + if (text.EndsWith("win.open") && winopenEntered == false) + winopenEntered = true; + }; + while (winopenEntered == false) + Thread.Sleep(10); + TerminalBackend.InStory = true; + TerminalBackend.PrefixEnabled = false; + + Thread.Sleep(2000); + Console.WriteLine("Pretty cool, it gave you a nice list of other win.open commands that will let you open each program."); + Thread.Sleep(2000); + Console.WriteLine("You've got the just of using ShiftOS. Now, for your goal."); + Thread.Sleep(2000); + Console.WriteLine("As you know, ShiftOS doesn't have very many features."); + Thread.Sleep(2000); + Console.WriteLine("Using the applications you have, I need you to earn as many Codepoints as you can."); + Thread.Sleep(2000); + Console.WriteLine("You can use the Codepoints you earn to buy new applications and features in the Shiftorium, to help earn even more Codepoints."); + Thread.Sleep(2000); + Console.WriteLine("Once you earn 1,000 Codepoints, I will check back with you and see how well you've done."); + Thread.Sleep(2000); + Console.WriteLine("I'll leave you to it, you've got the hang of it! One last thing, if ever you find yourself in another program, and want to exit, simply press CTRL+T to return to the Terminal."); + Thread.Sleep(2000); + TerminalBackend.PrefixEnabled = true; + TerminalBackend.InStory = false; + SaveSystem.SaveGame(); + Thread.Sleep(1000); + + Story.Context.AutoComplete = false; + + Console.WriteLine(@"Welcome to the ShiftOS Newbie's Guide. + +This tutorial will guide you through the more intermediate features of ShiftOS, +such as earning Codepoints, buying Shiftoorium Upgrades, and using the objectives system. + +Every now and then, you'll get a notification in your terminal of a ""NEW OBJECTIVE"". +This means that someone has instructed you to do something inside ShiftOS. At any moment +you may type ""sos.status"" in your Terminal to see your current objectives. + +This command is very useful as not only does it allow you to see your current objectives +but you can also see the amount of Codepoints you have as well as the upgrades you've +installed and how many upgrades are available. + +Now, onto your first objective! All you need to do is earn 200 Codepoints using any +program on your system."); + + Story.PushObjective("First Steps: Your First Codepoints", "Play a few rounds of Pong, or use another program to earn 200 Codepoints.", () => + { + return SaveSystem.CurrentSave.Codepoints >= 200; + }, () => + { + Desktop.InvokeOnWorkerThread(() => + { + AppearanceManager.SetupWindow(new Terminal()); + }); + Console.WriteLine("Good job! You've earned " + SaveSystem.CurrentSave.Codepoints + @" Codepoints! You can use these inside the +Shiftorium to buy new upgrades inside ShiftOS. + +These upgrades can give ShiftOS more features, fixes and programs, +which can make the operating system easier to use and navigate around +and also make it easier for you to earn more Codepoints and thus upgrade +te system further. + +Be cautious though! Only certain upgrades offer the ability to earn more +Codepoints. These upgrades are typically in the form of new programs. + +So, try to get as many new programs as possible for your computer, and save +the system feature upgrades for later unless you absolutely need them. + +The worst thing that could happen is you end up stuck with very little Codepoints +and only a few small programs to use to earn very little amounts of Codepoints. + +Now, let's get you your first Shiftorium upgrade!"); + + Story.PushObjective("First Steps: The Shiftorium", "Buy your first Shiftorium upgrade with your new Codepoints using shiftorium.list, shiftorium.info and shiftorium.buy.", + () => + { + return SaveSystem.CurrentSave.CountUpgrades() > 0; + }, () => + { + Console.WriteLine("This concludes the ShiftOS Newbie's Guide! Now, go, and shift it your way!"); + Console.WriteLine(@" +Your goal: Earn 1,000 Codepoints."); + Story.Context.MarkComplete(); + Story.Start("first_steps_transition"); + }); + TerminalBackend.PrintPrompt(); + }); + + TerminalBackend.PrintPrompt(); + } + + + [Story("first_steps_transition")] + public static void FirstStepsTransition() + { + Story.PushObjective("Earn 1000 Codepoints", "You now know the basics of ShiftOS. Let's get your system up and running with a few upgrades, and get a decent amount of Codepoints.", () => + { + return SaveSystem.CurrentSave.Codepoints >= 1000; + }, + () => + { + Story.Context.MarkComplete(); + Story.Start("victortran_shiftnet"); + }); + + Story.Context.AutoComplete = false; } public void OnSkinLoad() diff --git a/ShiftOS.WinForms/Applications/TriPresent.Designer.cs b/ShiftOS.WinForms/Applications/TriPresent.Designer.cs new file mode 100644 index 0000000..d0e704f --- /dev/null +++ b/ShiftOS.WinForms/Applications/TriPresent.Designer.cs @@ -0,0 +1,312 @@ +namespace ShiftOS.WinForms.Applications +{ + partial class TriPresent + { + /// + /// 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.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.addToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.addLabelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.addLabel = new System.Windows.Forms.Panel(); + this.checkBox2 = new System.Windows.Forms.CheckBox(); + this.checkBox1 = new System.Windows.Forms.CheckBox(); + this.label1 = new System.Windows.Forms.Label(); + this.panel1 = new System.Windows.Forms.Panel(); + this.yLabel = new System.Windows.Forms.Label(); + this.xLabel = new System.Windows.Forms.Label(); + this.yPosition = new System.Windows.Forms.NumericUpDown(); + this.xPosition = new System.Windows.Forms.NumericUpDown(); + this.labelContents = new System.Windows.Forms.TextBox(); + this.addItemLabel = new System.Windows.Forms.Label(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.designerPanel = new System.Windows.Forms.Panel(); + this.menuStrip1.SuspendLayout(); + this.addLabel.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.yPosition)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.xPosition)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.SuspendLayout(); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.fileToolStripMenuItem, + this.editToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(758, 24); + this.menuStrip1.TabIndex = 0; + this.menuStrip1.Text = "menuStrip1"; + // + // fileToolStripMenuItem + // + this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.openToolStripMenuItem, + this.saveToolStripMenuItem}); + this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); + this.fileToolStripMenuItem.Text = "&File"; + // + // openToolStripMenuItem + // + this.openToolStripMenuItem.Name = "openToolStripMenuItem"; + this.openToolStripMenuItem.Size = new System.Drawing.Size(103, 22); + this.openToolStripMenuItem.Text = "&Open"; + // + // saveToolStripMenuItem + // + this.saveToolStripMenuItem.Name = "saveToolStripMenuItem"; + this.saveToolStripMenuItem.Size = new System.Drawing.Size(103, 22); + this.saveToolStripMenuItem.Text = "&Save"; + // + // editToolStripMenuItem + // + this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.addToolStripMenuItem}); + this.editToolStripMenuItem.Name = "editToolStripMenuItem"; + this.editToolStripMenuItem.Size = new System.Drawing.Size(39, 20); + this.editToolStripMenuItem.Text = "&Edit"; + // + // addToolStripMenuItem + // + this.addToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.addLabelToolStripMenuItem}); + this.addToolStripMenuItem.Name = "addToolStripMenuItem"; + this.addToolStripMenuItem.Size = new System.Drawing.Size(96, 22); + this.addToolStripMenuItem.Text = "Add"; + // + // addLabelToolStripMenuItem + // + this.addLabelToolStripMenuItem.Name = "addLabelToolStripMenuItem"; + this.addLabelToolStripMenuItem.Size = new System.Drawing.Size(127, 22); + this.addLabelToolStripMenuItem.Text = "Add Label"; + this.addLabelToolStripMenuItem.Click += new System.EventHandler(this.addLabelToolStripMenuItem_Click); + // + // addLabel + // + this.addLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.addLabel.Controls.Add(this.checkBox2); + this.addLabel.Controls.Add(this.checkBox1); + this.addLabel.Controls.Add(this.label1); + this.addLabel.Controls.Add(this.panel1); + this.addLabel.Controls.Add(this.yLabel); + this.addLabel.Controls.Add(this.xLabel); + this.addLabel.Controls.Add(this.yPosition); + this.addLabel.Controls.Add(this.xPosition); + this.addLabel.Controls.Add(this.labelContents); + this.addLabel.Controls.Add(this.addItemLabel); + this.addLabel.Dock = System.Windows.Forms.DockStyle.Fill; + this.addLabel.Location = new System.Drawing.Point(0, 0); + this.addLabel.Name = "addLabel"; + this.addLabel.Size = new System.Drawing.Size(252, 456); + this.addLabel.TabIndex = 1; + this.addLabel.Visible = false; + // + // checkBox2 + // + this.checkBox2.AutoSize = true; + this.checkBox2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.checkBox2.Location = new System.Drawing.Point(6, 163); + this.checkBox2.Name = "checkBox2"; + this.checkBox2.Size = new System.Drawing.Size(48, 17); + this.checkBox2.TabIndex = 11; + this.checkBox2.Text = "Italic"; + this.checkBox2.UseVisualStyleBackColor = true; + // + // checkBox1 + // + this.checkBox1.AutoSize = true; + this.checkBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.checkBox1.Location = new System.Drawing.Point(6, 140); + this.checkBox1.Name = "checkBox1"; + this.checkBox1.Size = new System.Drawing.Size(51, 17); + this.checkBox1.TabIndex = 10; + this.checkBox1.Text = "Bold"; + this.checkBox1.UseVisualStyleBackColor = true; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(115, 144); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(58, 13); + this.label1.TabIndex = 9; + this.label1.Text = "Text Color:"; + // + // panel1 + // + this.panel1.BackColor = System.Drawing.Color.Black; + this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.panel1.ForeColor = System.Drawing.Color.Black; + this.panel1.Location = new System.Drawing.Point(179, 141); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(35, 20); + this.panel1.TabIndex = 8; + this.panel1.Click += new System.EventHandler(this.panel1_Click); + // + // yLabel + // + this.yLabel.AutoSize = true; + this.yLabel.Location = new System.Drawing.Point(200, 96); + this.yLabel.Name = "yLabel"; + this.yLabel.Size = new System.Drawing.Size(14, 13); + this.yLabel.TabIndex = 5; + this.yLabel.Text = "Y"; + // + // xLabel + // + this.xLabel.AutoSize = true; + this.xLabel.Location = new System.Drawing.Point(3, 95); + this.xLabel.Name = "xLabel"; + this.xLabel.Size = new System.Drawing.Size(14, 13); + this.xLabel.TabIndex = 4; + this.xLabel.Text = "X"; + // + // yPosition + // + this.yPosition.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.yPosition.Location = new System.Drawing.Point(127, 114); + this.yPosition.Maximum = new decimal(new int[] { + 999999999, + 0, + 0, + 0}); + this.yPosition.Name = "yPosition"; + this.yPosition.Size = new System.Drawing.Size(87, 20); + this.yPosition.TabIndex = 3; + // + // xPosition + // + this.xPosition.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.xPosition.Location = new System.Drawing.Point(3, 114); + this.xPosition.Maximum = new decimal(new int[] { + 999999999, + 0, + 0, + 0}); + this.xPosition.Name = "xPosition"; + this.xPosition.Size = new System.Drawing.Size(87, 20); + this.xPosition.TabIndex = 2; + // + // labelContents + // + this.labelContents.Location = new System.Drawing.Point(3, 26); + this.labelContents.Multiline = true; + this.labelContents.Name = "labelContents"; + this.labelContents.Size = new System.Drawing.Size(211, 67); + this.labelContents.TabIndex = 1; + this.labelContents.Text = "Text"; + // + // addItemLabel + // + this.addItemLabel.Location = new System.Drawing.Point(0, 0); + this.addItemLabel.Name = "addItemLabel"; + this.addItemLabel.Size = new System.Drawing.Size(214, 23); + this.addItemLabel.TabIndex = 0; + this.addItemLabel.Text = "{ADD_ITEM_LABEL}"; + this.addItemLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.Location = new System.Drawing.Point(0, 24); + this.splitContainer1.Name = "splitContainer1"; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add(this.addLabel); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.designerPanel); + this.splitContainer1.Size = new System.Drawing.Size(758, 456); + this.splitContainer1.SplitterDistance = 252; + this.splitContainer1.TabIndex = 2; + // + // designerPanel + // + this.designerPanel.Dock = System.Windows.Forms.DockStyle.Fill; + this.designerPanel.Location = new System.Drawing.Point(0, 0); + this.designerPanel.Name = "designerPanel"; + this.designerPanel.Size = new System.Drawing.Size(502, 456); + this.designerPanel.TabIndex = 0; + this.designerPanel.Click += new System.EventHandler(this.designerPanel_Click); + // + // TriPresent + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.splitContainer1); + this.Controls.Add(this.menuStrip1); + this.Name = "TriPresent"; + this.Size = new System.Drawing.Size(758, 480); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.addLabel.ResumeLayout(false); + this.addLabel.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.yPosition)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.xPosition)).EndInit(); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); + this.splitContainer1.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem addToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem addLabelToolStripMenuItem; + private System.Windows.Forms.Panel addLabel; + private System.Windows.Forms.Label addItemLabel; + private System.Windows.Forms.Label yLabel; + private System.Windows.Forms.Label xLabel; + private System.Windows.Forms.NumericUpDown yPosition; + private System.Windows.Forms.NumericUpDown xPosition; + private System.Windows.Forms.TextBox labelContents; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.CheckBox checkBox2; + private System.Windows.Forms.CheckBox checkBox1; + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.Panel designerPanel; + } +} diff --git a/ShiftOS.WinForms/Applications/TriPresent.cs b/ShiftOS.WinForms/Applications/TriPresent.cs new file mode 100644 index 0000000..fc1d982 --- /dev/null +++ b/ShiftOS.WinForms/Applications/TriPresent.cs @@ -0,0 +1,91 @@ +#define BETA_2_5 + +using ShiftOS.Objects.ShiftFS; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using ShiftOS.Engine; +using System.Threading; + +namespace ShiftOS.WinForms.Applications +{ +#if !BETA_2_5 + [WinOpen("tripresent")] + [AppscapeEntry("TriPresent", "Part of the trilogy of office applications for enhancement of your system. TriPresent is easliy the best presentation creator out there for ShiftOS.", 2048, 1500, "file_skimmer", "Office")] + [DefaultTitle("TriPresent")] + [Launcher("TriPresent", false, null, "Office")] +#endif + public partial class TriPresent : UserControl, IShiftOSWindow + { + public TriPresent() + { + InitializeComponent(); + } + + private void addLabelToolStripMenuItem_Click(object sender, EventArgs e) + { + addItemLabel.Text = "Add Label"; + addLabel.Show(); + } + + private void button2_Click(object sender, EventArgs e) + { + addLabel.Hide(); + } + + public void OnLoad() + { + panel1.ForeColor = Color.Black; + panel1.BackColor = Color.Black; + } + + public void OnSkinLoad() + { + + } + + public bool OnUnload() + { + return true; + } + + public void OnUpgrade() + { + + } + + private void placeAdd_Click(object sender, EventArgs e) + { + + } + + private void panel1_Click(object sender, EventArgs e) + { + AppearanceManager.SetupDialog(new ColorPicker(panel1.BackColor, "Text Color", new Action((col) => + { + panel1.ForeColor = col; + panel1.BackColor = col; + }))); + } + + private void designerPanel_Click(object sender, EventArgs e) + { + if (addLabel.Visible == true) + { + Label label = new Label(); + label.Parent = designerPanel; + label.BackColor = Color.Transparent; + label.ForeColor = panel1.BackColor; + label.Text = labelContents.Text; + label.Location = new Point(Cursor.Position.X / 3, Cursor.Position.Y); + label.Text = labelContents.Text; + } + } + } +} diff --git a/ShiftOS.WinForms/Applications/TriPresent.resx b/ShiftOS.WinForms/Applications/TriPresent.resx new file mode 100644 index 0000000..d5494e3 --- /dev/null +++ b/ShiftOS.WinForms/Applications/TriPresent.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + \ No newline at end of file diff --git a/ShiftOS.WinForms/Applications/TriSheet.Designer.cs b/ShiftOS.WinForms/Applications/TriSheet.Designer.cs new file mode 100644 index 0000000..b4aa1c4 --- /dev/null +++ b/ShiftOS.WinForms/Applications/TriSheet.Designer.cs @@ -0,0 +1,65 @@ +namespace ShiftOS.WinForms.Applications +{ + partial class TriSheet + { + /// + /// 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.toolStripContainer1 = new System.Windows.Forms.ToolStripContainer(); + this.toolStripContainer1.SuspendLayout(); + this.SuspendLayout(); + // + // toolStripContainer1 + // + // + // toolStripContainer1.ContentPanel + // + this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size(710, 464); + this.toolStripContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.toolStripContainer1.Location = new System.Drawing.Point(0, 0); + this.toolStripContainer1.Name = "toolStripContainer1"; + this.toolStripContainer1.Size = new System.Drawing.Size(710, 489); + this.toolStripContainer1.TabIndex = 0; + this.toolStripContainer1.Text = "toolStripContainer1"; + // + // TriSheet + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.toolStripContainer1); + this.Name = "TriSheet"; + this.Size = new System.Drawing.Size(710, 489); + this.toolStripContainer1.ResumeLayout(false); + this.toolStripContainer1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.ToolStripContainer toolStripContainer1; + } +} diff --git a/ShiftOS.WinForms/Applications/TriSheet.cs b/ShiftOS.WinForms/Applications/TriSheet.cs new file mode 100644 index 0000000..18b09b3 --- /dev/null +++ b/ShiftOS.WinForms/Applications/TriSheet.cs @@ -0,0 +1,22 @@ +#define BETA_2_5 + +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; + +namespace ShiftOS.WinForms.Applications +{ + public partial class TriSheet : UserControl + { + public TriSheet() + { + InitializeComponent(); + } + } +} diff --git a/ShiftOS.WinForms/Applications/TriSheet.resx b/ShiftOS.WinForms/Applications/TriSheet.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/ShiftOS.WinForms/Applications/TriSheet.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/Applications/TriWrite.Designer.cs b/ShiftOS.WinForms/Applications/TriWrite.Designer.cs index e420fd5..a1432d8 100644 --- a/ShiftOS.WinForms/Applications/TriWrite.Designer.cs +++ b/ShiftOS.WinForms/Applications/TriWrite.Designer.cs @@ -36,15 +36,27 @@ this.panel1 = new System.Windows.Forms.Panel(); this.txtbody = new System.Windows.Forms.Label(); this.lbtitle = new System.Windows.Forms.Label(); - this.txtcontents = new System.Windows.Forms.TextBox(); this.menuStrip2 = new System.Windows.Forms.MenuStrip(); this.newToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.menuStrip3 = new System.Windows.Forms.MenuStrip(); + this.txtcontents = new System.Windows.Forms.RichTextBox(); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.bold = new System.Windows.Forms.ToolStripButton(); + this.italic = new System.Windows.Forms.ToolStripButton(); + this.underline = new System.Windows.Forms.ToolStripButton(); + this.strikethrough = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.fonts = new System.Windows.Forms.ToolStripComboBox(); + this.size = new System.Windows.Forms.ToolStripTextBox(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.left = new System.Windows.Forms.ToolStripButton(); + this.center = new System.Windows.Forms.ToolStripButton(); + this.right = new System.Windows.Forms.ToolStripButton(); this.menuStrip1.SuspendLayout(); this.panel1.SuspendLayout(); this.menuStrip2.SuspendLayout(); + this.toolStrip1.SuspendLayout(); this.SuspendLayout(); // // menuStrip1 @@ -61,16 +73,17 @@ // addContactToolStripMenuItem // this.addContactToolStripMenuItem.Name = "addContactToolStripMenuItem"; - this.addContactToolStripMenuItem.Size = new System.Drawing.Size(32, 19); + this.addContactToolStripMenuItem.Size = new System.Drawing.Size(12, 20); // // removeToolStripMenuItem // this.removeToolStripMenuItem.Name = "removeToolStripMenuItem"; - this.removeToolStripMenuItem.Size = new System.Drawing.Size(32, 19); + this.removeToolStripMenuItem.Size = new System.Drawing.Size(12, 20); // // tvcontacts // this.tvcontacts.Dock = System.Windows.Forms.DockStyle.Left; + this.tvcontacts.LineColor = System.Drawing.Color.Empty; this.tvcontacts.Location = new System.Drawing.Point(0, 24); this.tvcontacts.Name = "tvcontacts"; this.tvcontacts.Size = new System.Drawing.Size(224, 551); @@ -107,16 +120,6 @@ this.lbtitle.Tag = "header1"; this.lbtitle.Text = "TriWrite"; // - // txtcontents - // - this.txtcontents.Dock = System.Windows.Forms.DockStyle.Fill; - this.txtcontents.Location = new System.Drawing.Point(0, 53); - this.txtcontents.Multiline = true; - this.txtcontents.Name = "txtcontents"; - this.txtcontents.Size = new System.Drawing.Size(527, 460); - this.txtcontents.TabIndex = 1; - this.txtcontents.TabStop = false; - // // menuStrip2 // this.menuStrip2.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -125,7 +128,7 @@ this.saveToolStripMenuItem}); this.menuStrip2.Location = new System.Drawing.Point(0, 0); this.menuStrip2.Name = "menuStrip2"; - this.menuStrip2.Size = new System.Drawing.Size(527, 24); + this.menuStrip2.Size = new System.Drawing.Size(652, 24); this.menuStrip2.TabIndex = 2; this.menuStrip2.Text = "menuStrip2"; // @@ -134,40 +137,173 @@ this.newToolStripMenuItem.Name = "newToolStripMenuItem"; this.newToolStripMenuItem.Size = new System.Drawing.Size(43, 20); this.newToolStripMenuItem.Text = "New"; + this.newToolStripMenuItem.Click += new System.EventHandler(this.newToolStripMenuItem_Click); // // openToolStripMenuItem // this.openToolStripMenuItem.Name = "openToolStripMenuItem"; this.openToolStripMenuItem.Size = new System.Drawing.Size(48, 20); this.openToolStripMenuItem.Text = "Open"; + this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click); // // saveToolStripMenuItem // this.saveToolStripMenuItem.Name = "saveToolStripMenuItem"; this.saveToolStripMenuItem.Size = new System.Drawing.Size(43, 20); this.saveToolStripMenuItem.Text = "Save"; + this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click); // - // menuStrip3 + // txtcontents // - this.menuStrip3.Location = new System.Drawing.Point(0, 30); - this.menuStrip3.Name = "menuStrip3"; - this.menuStrip3.Size = new System.Drawing.Size(527, 24); - this.menuStrip3.TabIndex = 3; - this.menuStrip3.Text = "menuStrip3"; + this.txtcontents.Dock = System.Windows.Forms.DockStyle.Fill; + this.txtcontents.Location = new System.Drawing.Point(0, 49); + this.txtcontents.Name = "txtcontents"; + this.txtcontents.Size = new System.Drawing.Size(652, 365); + this.txtcontents.TabIndex = 4; + this.txtcontents.Text = ""; + this.txtcontents.SelectionChanged += new System.EventHandler(this.txtcontents_SelectionChanged); + // + // toolStrip1 + // + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.bold, + this.italic, + this.underline, + this.strikethrough, + this.toolStripSeparator1, + this.fonts, + this.size, + this.toolStripSeparator2, + this.left, + this.center, + this.right}); + this.toolStrip1.Location = new System.Drawing.Point(0, 24); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(652, 25); + this.toolStrip1.TabIndex = 5; + this.toolStrip1.Text = "toolStrip1"; + // + // bold + // + this.bold.CheckOnClick = true; + this.bold.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.bold.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold); + this.bold.Image = ((System.Drawing.Image)(resources.GetObject("bold.Image"))); + this.bold.ImageTransparentColor = System.Drawing.Color.Magenta; + this.bold.Name = "bold"; + this.bold.Size = new System.Drawing.Size(23, 22); + this.bold.Text = "B"; + this.bold.CheckedChanged += new System.EventHandler(this.bold_CheckedChanged); + // + // italic + // + this.italic.CheckOnClick = true; + this.italic.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.italic.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Italic); + this.italic.Image = ((System.Drawing.Image)(resources.GetObject("italic.Image"))); + this.italic.ImageTransparentColor = System.Drawing.Color.Magenta; + this.italic.Name = "italic"; + this.italic.Size = new System.Drawing.Size(23, 22); + this.italic.Text = "I"; + this.italic.CheckedChanged += new System.EventHandler(this.bold_CheckedChanged); + // + // underline + // + this.underline.CheckOnClick = true; + this.underline.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.underline.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Underline); + this.underline.Image = ((System.Drawing.Image)(resources.GetObject("underline.Image"))); + this.underline.ImageTransparentColor = System.Drawing.Color.Magenta; + this.underline.Name = "underline"; + this.underline.Size = new System.Drawing.Size(23, 22); + this.underline.Text = "U"; + this.underline.CheckedChanged += new System.EventHandler(this.bold_CheckedChanged); + // + // strikethrough + // + this.strikethrough.CheckOnClick = true; + this.strikethrough.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.strikethrough.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Strikeout, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.strikethrough.Image = ((System.Drawing.Image)(resources.GetObject("strikethrough.Image"))); + this.strikethrough.ImageTransparentColor = System.Drawing.Color.Magenta; + this.strikethrough.Name = "strikethrough"; + this.strikethrough.Size = new System.Drawing.Size(23, 22); + this.strikethrough.Text = "S"; + this.strikethrough.CheckedChanged += new System.EventHandler(this.bold_CheckedChanged); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); + // + // fonts + // + this.fonts.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.fonts.Name = "fonts"; + this.fonts.Size = new System.Drawing.Size(121, 25); + this.fonts.SelectedIndexChanged += new System.EventHandler(this.fonts_SelectedIndexChanged); + // + // size + // + this.size.AutoSize = false; + this.size.MaxLength = 3; + this.size.Name = "size"; + this.size.Size = new System.Drawing.Size(40, 25); + this.size.TextChanged += new System.EventHandler(this.size_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25); + // + // left + // + this.left.CheckOnClick = true; + this.left.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.left.Image = ((System.Drawing.Image)(resources.GetObject("left.Image"))); + this.left.ImageTransparentColor = System.Drawing.Color.Magenta; + this.left.Name = "left"; + this.left.Size = new System.Drawing.Size(31, 22); + this.left.Text = "Left"; + this.left.Click += new System.EventHandler(this.left_Click); + // + // center + // + this.center.CheckOnClick = true; + this.center.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.center.Image = ((System.Drawing.Image)(resources.GetObject("center.Image"))); + this.center.ImageTransparentColor = System.Drawing.Color.Magenta; + this.center.Name = "center"; + this.center.Size = new System.Drawing.Size(46, 22); + this.center.Text = "Center"; + this.center.Click += new System.EventHandler(this.center_Click); + // + // right + // + this.right.CheckOnClick = true; + this.right.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.right.Image = ((System.Drawing.Image)(resources.GetObject("right.Image"))); + this.right.ImageTransparentColor = System.Drawing.Color.Magenta; + this.right.Name = "right"; + this.right.Size = new System.Drawing.Size(39, 22); + this.right.Text = "Right"; + this.right.Click += new System.EventHandler(this.right_Click); // // TriWrite // this.Controls.Add(this.txtcontents); - this.Controls.Add(this.menuStrip3); + this.Controls.Add(this.toolStrip1); this.Controls.Add(this.menuStrip2); this.Name = "TriWrite"; - this.Size = new System.Drawing.Size(527, 513); + this.Size = new System.Drawing.Size(652, 414); this.menuStrip1.ResumeLayout(false); this.menuStrip1.PerformLayout(); this.panel1.ResumeLayout(false); this.panel1.PerformLayout(); this.menuStrip2.ResumeLayout(false); this.menuStrip2.PerformLayout(); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); @@ -182,11 +318,22 @@ private System.Windows.Forms.Panel panel1; private System.Windows.Forms.Label txtbody; private System.Windows.Forms.Label lbtitle; - private System.Windows.Forms.TextBox txtcontents; private System.Windows.Forms.MenuStrip menuStrip2; private System.Windows.Forms.ToolStripMenuItem newToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem; - private System.Windows.Forms.MenuStrip menuStrip3; + private System.Windows.Forms.RichTextBox txtcontents; + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripButton bold; + private System.Windows.Forms.ToolStripButton italic; + private System.Windows.Forms.ToolStripButton underline; + private System.Windows.Forms.ToolStripButton strikethrough; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripComboBox fonts; + private System.Windows.Forms.ToolStripTextBox size; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripButton left; + private System.Windows.Forms.ToolStripButton center; + private System.Windows.Forms.ToolStripButton right; } } diff --git a/ShiftOS.WinForms/Applications/TriWrite.cs b/ShiftOS.WinForms/Applications/TriWrite.cs index 6fb814f..291aa30 100644 --- a/ShiftOS.WinForms/Applications/TriWrite.cs +++ b/ShiftOS.WinForms/Applications/TriWrite.cs @@ -13,7 +13,7 @@ using ShiftOS.Engine; namespace ShiftOS.WinForms.Applications { [WinOpen("triwrite")] - [AppscapeEntry("TriWrite", "Part of the trilogy of office applications for enhancement of your system. TriWrite is easliy the best text editor out there for ShiftOS.", 1024, 750, null, "Office")] + [AppscapeEntry("TriWrite", "Part of the trilogy of office applications for enhancement of your system. TriWrite is easliy the best text editor out there for ShiftOS.", 1024, 750, "file_skimmer;textpad", "Office")] [DefaultTitle("TriWrite")] [Launcher("TriWrite", false, null, "Office")] public partial class TriWrite : UserControl, IShiftOSWindow @@ -21,7 +21,7 @@ namespace ShiftOS.WinForms.Applications public TriWrite() { - InitializeComponent(); + InitializeComponent(); //From the library of babel: "FIRST COMMIT FROM A MAC WOOOO TURIANS ARE COOL" } private void newToolStripMenuItem_Click(object sender, EventArgs e) @@ -32,35 +32,54 @@ namespace ShiftOS.WinForms.Applications private void openToolStripMenuItem_Click(object sender, EventArgs e) { var txt = new List(); - txt.Add(".txt"); + txt.Add(".rtf"); - AppearanceManager.SetupDialog(new FileDialog(txt.ToArray(), FileOpenerStyle.Open, new Action((file) => this.LoadFile(file)))); + FileSkimmerBackend.GetFile(txt.ToArray(), FileOpenerStyle.Open, (path) => LoadFile(path)); } public void LoadFile(string file) { - txtcontents.Text = Utils.ReadAllText(file); + txtcontents.Rtf = Utils.ReadAllText(file); } public void SaveFile(string file) { - Utils.WriteAllText(file, txtcontents.Text); + if (file.ToLower().EndsWith(".rtf")) + { + Utils.WriteAllText(file, txtcontents.Rtf); + } + else + { + Utils.WriteAllText(file, txtcontents.Text); + } } private void saveToolStripMenuItem_Click(object sender, EventArgs e) { var txt = new List(); + txt.Add(".rtf"); txt.Add(".txt"); - - AppearanceManager.SetupDialog(new FileDialog(txt.ToArray(), FileOpenerStyle.Save, new Action((file) => this.SaveFile(file)))); + FileSkimmerBackend.GetFile(txt.ToArray(), FileOpenerStyle.Save, (path) => SaveFile(path)); } public void OnLoad() { + UpdateUI(); } public void OnSkinLoad() { + ResetFonts(); + } + + public void ResetFonts() + { + fonts.Items.Clear(); + foreach(var font in FontFamily.Families) + { + fonts.Items.Add(font.Name); + } + UpdateUI(); } public bool OnUnload() @@ -72,5 +91,92 @@ namespace ShiftOS.WinForms.Applications { } + public void UpdateUI() + { + bold.Checked = txtcontents.SelectionFont.Bold; + italic.Checked = txtcontents.SelectionFont.Italic; + underline.Checked = txtcontents.SelectionFont.Underline; + strikethrough.Checked = txtcontents.SelectionFont.Strikeout; + fonts.Text = txtcontents.SelectionFont.Name; + size.Text = txtcontents.SelectionFont.Size.ToString(); + left.Checked = txtcontents.SelectionAlignment == HorizontalAlignment.Left; + center.Checked = txtcontents.SelectionAlignment == HorizontalAlignment.Center; + right.Checked = txtcontents.SelectionAlignment == HorizontalAlignment.Right; + + } + + private void txtcontents_SelectionChanged(object sender, EventArgs e) + { + UpdateUI(); + } + + public void SetFontStyle(bool bold, bool italic, bool underline, bool strikethrough) + { + FontStyle fs = FontStyle.Regular; + if (bold) + fs |= FontStyle.Bold; + if (italic) + fs |= FontStyle.Italic; + if (underline) + fs |= FontStyle.Underline; + if (strikethrough) + fs |= FontStyle.Strikeout; + txtcontents.SelectionFont = new Font(txtcontents.SelectionFont, fs); + UpdateUI(); + } + + private void bold_CheckedChanged(object sender, EventArgs e) + { + SetFontStyle(bold.Checked, italic.Checked, underline.Checked, strikethrough.Checked); + } + + public void SetFontFamily(string family, float emSize) + { + var style = txtcontents.SelectionFont.Style; + var size = emSize; + txtcontents.SelectionFont = new Font(family, size, style); + UpdateUI(); + } + + private void fonts_SelectedIndexChanged(object sender, EventArgs e) + { + SetFontFamily(fonts.Text, Convert.ToSingle(size.Text)); + } + + private void left_Click(object sender, EventArgs e) + { + txtcontents.SelectionAlignment = HorizontalAlignment.Left; + UpdateUI(); + } + + private void center_Click(object sender, EventArgs e) + { + txtcontents.SelectionAlignment = HorizontalAlignment.Center; + UpdateUI(); + + } + + private void right_Click(object sender, EventArgs e) + { + txtcontents.SelectionAlignment = HorizontalAlignment.Right; + UpdateUI(); + + } + + private void size_Click(object sender, EventArgs e) + { + try + { + float s = Convert.ToSingle(size.Text); + if(s != txtcontents.SelectionFont.Size) + { + SetFontFamily(fonts.Text, s); + } + } + catch + { + UpdateUI(); + } + } } } \ No newline at end of file diff --git a/ShiftOS.WinForms/Applications/TriWrite.resx b/ShiftOS.WinForms/Applications/TriWrite.resx index 525a23c..a06716c 100644 --- a/ShiftOS.WinForms/Applications/TriWrite.resx +++ b/ShiftOS.WinForms/Applications/TriWrite.resx @@ -130,7 +130,113 @@ To add a contact, simply click "Add Contact", and to remove one, click "Remove". 132, 17 - + 247, 17 + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + \ No newline at end of file diff --git a/ShiftOS.WinForms/Applications/UpdateManager.Designer.cs b/ShiftOS.WinForms/Applications/UpdateManager.Designer.cs index 0b23b8e..d30e2df 100644 --- a/ShiftOS.WinForms/Applications/UpdateManager.Designer.cs +++ b/ShiftOS.WinForms/Applications/UpdateManager.Designer.cs @@ -64,12 +64,10 @@ // this.pgdownload.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.pgdownload.BlockSize = 5; this.pgdownload.Location = new System.Drawing.Point(86, 4); this.pgdownload.Maximum = 100; this.pgdownload.Name = "pgdownload"; this.pgdownload.Size = new System.Drawing.Size(427, 23); - this.pgdownload.Style = System.Windows.Forms.ProgressBarStyle.Continuous; this.pgdownload.TabIndex = 2; this.pgdownload.Text = "Updating..."; this.pgdownload.Value = 0; diff --git a/ShiftOS.WinForms/Applications/VideoPlayer.Designer.cs b/ShiftOS.WinForms/Applications/VideoPlayer.Designer.cs index d915c31..1d93047 100644 --- a/ShiftOS.WinForms/Applications/VideoPlayer.Designer.cs +++ b/ShiftOS.WinForms/Applications/VideoPlayer.Designer.cs @@ -91,12 +91,10 @@ // // 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"; diff --git a/ShiftOS.WinForms/Applications/WebBrowser.Designer.cs b/ShiftOS.WinForms/Applications/WebBrowser.Designer.cs new file mode 100644 index 0000000..6b7ae83 --- /dev/null +++ b/ShiftOS.WinForms/Applications/WebBrowser.Designer.cs @@ -0,0 +1,153 @@ +namespace ShiftOS.WinForms.Applications +{ + partial class WebBrowser + { + /// + /// 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.flcontrols = new System.Windows.Forms.FlowLayoutPanel(); + this.btnback = new System.Windows.Forms.Button(); + this.btnforward = new System.Windows.Forms.Button(); + this.txturl = new System.Windows.Forms.TextBox(); + this.btngo = new System.Windows.Forms.Button(); + this.pnlcanvas = new System.Windows.Forms.Panel(); + this.wbmain = new System.Windows.Forms.WebBrowser(); + this.flcontrols.SuspendLayout(); + this.pnlcanvas.SuspendLayout(); + this.SuspendLayout(); + // + // flcontrols + // + this.flcontrols.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.flcontrols.Controls.Add(this.btnback); + this.flcontrols.Controls.Add(this.btnforward); + this.flcontrols.Controls.Add(this.txturl); + this.flcontrols.Controls.Add(this.btngo); + this.flcontrols.Dock = System.Windows.Forms.DockStyle.Top; + this.flcontrols.Location = new System.Drawing.Point(0, 0); + this.flcontrols.Name = "flcontrols"; + this.flcontrols.Size = new System.Drawing.Size(539, 29); + this.flcontrols.TabIndex = 2; + // + // btnback + // + this.btnback.AutoSize = true; + this.btnback.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.btnback.Location = new System.Drawing.Point(3, 3); + this.btnback.Name = "btnback"; + this.btnback.Size = new System.Drawing.Size(23, 23); + this.btnback.TabIndex = 0; + this.btnback.Text = "<"; + this.btnback.UseVisualStyleBackColor = true; + this.btnback.Click += new System.EventHandler(this.btnback_Click); + // + // btnforward + // + this.btnforward.AutoSize = true; + this.btnforward.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.btnforward.Location = new System.Drawing.Point(32, 3); + this.btnforward.Name = "btnforward"; + this.btnforward.Size = new System.Drawing.Size(23, 23); + this.btnforward.TabIndex = 1; + this.btnforward.Text = ">"; + this.btnforward.UseVisualStyleBackColor = true; + this.btnforward.Click += new System.EventHandler(this.btnforward_Click); + // + // txturl + // + this.txturl.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txturl.Location = new System.Drawing.Point(61, 3); + this.txturl.Name = "txturl"; + this.txturl.Size = new System.Drawing.Size(435, 20); + this.txturl.TabIndex = 2; + this.txturl.WordWrap = false; + this.txturl.KeyDown += new System.Windows.Forms.KeyEventHandler(this.txturl_KeyDown); + // + // btngo + // + this.btngo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btngo.AutoSize = true; + this.btngo.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.btngo.Location = new System.Drawing.Point(502, 3); + this.btngo.Name = "btngo"; + this.btngo.Size = new System.Drawing.Size(31, 23); + this.btngo.TabIndex = 3; + this.btngo.Text = "Go"; + this.btngo.UseVisualStyleBackColor = true; + this.btngo.Click += new System.EventHandler(this.btngo_Click); + // + // pnlcanvas + // + this.pnlcanvas.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.pnlcanvas.Controls.Add(this.wbmain); + 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(539, 374); + this.pnlcanvas.TabIndex = 3; + // + // wbmain + // + this.wbmain.AllowWebBrowserDrop = false; + this.wbmain.Dock = System.Windows.Forms.DockStyle.Fill; + this.wbmain.IsWebBrowserContextMenuEnabled = false; + this.wbmain.Location = new System.Drawing.Point(0, 0); + this.wbmain.MinimumSize = new System.Drawing.Size(20, 20); + this.wbmain.Name = "wbmain"; + this.wbmain.ScriptErrorsSuppressed = true; + this.wbmain.Size = new System.Drawing.Size(537, 372); + this.wbmain.TabIndex = 0; + this.wbmain.WebBrowserShortcutsEnabled = false; + this.wbmain.Navigated += new System.Windows.Forms.WebBrowserNavigatedEventHandler(this.wbmain_Navigated); + this.wbmain.NewWindow += new System.ComponentModel.CancelEventHandler(this.wbmain_NewWindow); + // + // WebBrowser + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.pnlcanvas); + this.Controls.Add(this.flcontrols); + this.Name = "WebBrowser"; + this.Size = new System.Drawing.Size(539, 403); + this.flcontrols.ResumeLayout(false); + this.flcontrols.PerformLayout(); + this.pnlcanvas.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #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.Panel pnlcanvas; + private System.Windows.Forms.WebBrowser wbmain; + } +} diff --git a/ShiftOS.WinForms/Applications/WebBrowser.cs b/ShiftOS.WinForms/Applications/WebBrowser.cs new file mode 100644 index 0000000..751e7e2 --- /dev/null +++ b/ShiftOS.WinForms/Applications/WebBrowser.cs @@ -0,0 +1,97 @@ +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; + +namespace ShiftOS.WinForms.Applications +{ + [WinOpen("web_browser")] + [AppscapeEntry("Web Browser", "We're going surfing on the Internet! This application allows you to break the bounds of the Digital Society and connect to the outer Internet inside ShiftOS.", + 4096, 10000, "color_depth_24_bits", "Networking")] + [Launcher("Web Browser", false, null, "Networking")] + [DefaultTitle("Web Browser")] + [DefaultIcon("iconShiftnet")] + public partial class WebBrowser : UserControl, IShiftOSWindow + { + public WebBrowser() + { + InitializeComponent(); + uiupdate = new Timer(); + uiupdate.Tick += (o, a) => + { + 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); + btnback.Enabled = wbmain.CanGoBack; + btnforward.Enabled = wbmain.CanGoForward; + }; + uiupdate.Interval = 100; + } + + Timer uiupdate = null; + + public void OnLoad() + { + uiupdate.Start(); + wbmain.Url = new Uri("http://getshiftos.ml/"); + } + + public void OnSkinLoad() + { + } + + public bool OnUnload() + { + uiupdate.Stop(); + return true; + } + + public void OnUpgrade() + { + } + + private void btnback_Click(object sender, EventArgs e) + { + wbmain.GoBack(); + } + + private void btnforward_Click(object sender, EventArgs e) + { + wbmain.GoForward(); + } + + private void btngo_Click(object sender, EventArgs e) + { + wbmain.Navigate(txturl.Text); + } + + private void wbmain_NewWindow(object sender, CancelEventArgs e) + { + e.Cancel = true; + if (Shiftorium.UpgradeInstalled("web_browser_new_window")) + { + AppearanceManager.SetupWindow(new WebBrowser()); + } + } + + private void txturl_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Enter) + btngo_Click(sender, EventArgs.Empty); + } + + private void wbmain_Navigated(object sender, WebBrowserNavigatedEventArgs e) + { + txturl.Text = wbmain.Url.ToString(); + AppearanceManager.SetWindowTitle(this, wbmain.DocumentTitle + " - " + NameChangerBackend.GetNameRaw(this.GetType())); + } + } +} diff --git a/ShiftOS.WinForms/Applications/WebBrowser.resx b/ShiftOS.WinForms/Applications/WebBrowser.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/ShiftOS.WinForms/Applications/WebBrowser.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/AudioManager.cs b/ShiftOS.WinForms/AudioManager.cs index 5c43ac4..afa0d78 100644 --- a/ShiftOS.WinForms/AudioManager.cs +++ b/ShiftOS.WinForms/AudioManager.cs @@ -24,8 +24,10 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace ShiftOS.WinForms @@ -37,5 +39,101 @@ namespace ShiftOS.WinForms { } + + internal static byte[] GetRandomSong() + { + var r = new Random().Next(1, 10); + switch (r) + { + case 1: + return Properties.Resources.Ambient1; + case 2: + return Properties.Resources.Ambient2; + case 3: + return Properties.Resources.Ambient3; + case 4: + return Properties.Resources.Ambient4; + case 5: + return Properties.Resources.Ambient5; + case 6: + return Properties.Resources.Ambient6; + case 7: + return Properties.Resources.Ambient7; + case 8: + return Properties.Resources.Ambient8; + default: + return Properties.Resources.Ambient9; + + } + } + + internal static void StartAmbientLoop() + { + var athread = new Thread(() => + { + MemoryStream str = null; + NAudio.Wave.Mp3FileReader mp3 = null; + NAudio.Wave.WaveOut o = null; + bool shuttingDown = false; + + Engine.AppearanceManager.OnExit += () => + { + shuttingDown = true; + o?.Stop(); + o?.Dispose(); + mp3?.Close(); + mp3?.Dispose(); + str?.Close(); + str?.Dispose(); + }; + while (shuttingDown == false) + { + if (Engine.SaveSystem.CurrentSave != null) + { + if (Engine.SaveSystem.CurrentSave.MusicEnabled) + { + str = new MemoryStream(GetRandomSong()); + mp3 = new NAudio.Wave.Mp3FileReader(str); + o = new NAudio.Wave.WaveOut(); + o.Init(mp3); + bool c = false; + o.Play(); + o.PlaybackStopped += (s, a) => + { + c = true; + }; + + while (!c) + { + if (Engine.SaveSystem.CurrentSave.MusicEnabled) + { + try + { + o.Volume = (float)Engine.SaveSystem.CurrentSave.MusicVolume / 100; + } + catch { } + } + else + { + o.Stop(); + c = true; + } + Thread.Sleep(10); + } + } + else + { + Thread.Sleep(10); + } + } + else + { + Thread.Sleep(10); + } + } + }); + athread.IsBackground = true; + athread.Start(); + } } } diff --git a/ShiftOS.WinForms/Commands.cs b/ShiftOS.WinForms/Commands.cs index 2d297f5..b04ffe7 100644 --- a/ShiftOS.WinForms/Commands.cs +++ b/ShiftOS.WinForms/Commands.cs @@ -80,7 +80,6 @@ namespace ShiftOS.WinForms } } - [Namespace("coherence")] [RequiresUpgrade("kernel_coherence")] public static class CoherenceCommands diff --git a/ShiftOS.WinForms/Controls/ShiftedProgressBar.cs b/ShiftOS.WinForms/Controls/ShiftedProgressBar.cs index e5a2c33..c5a6d05 100644 --- a/ShiftOS.WinForms/Controls/ShiftedProgressBar.cs +++ b/ShiftOS.WinForms/Controls/ShiftedProgressBar.cs @@ -31,6 +31,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; +using ShiftOS.Engine; namespace ShiftOS.WinForms.Controls { @@ -46,7 +47,7 @@ namespace ShiftOS.WinForms.Controls t.Interval = 100; t.Tick += (o, a) => { - if(this._style == ProgressBarStyle.Marquee) + if(this.Style == ProgressBarStyle.Marquee) { if(_marqueePos >= this.Width) { @@ -89,47 +90,115 @@ namespace ShiftOS.WinForms.Controls } } - public ProgressBarStyle _style = ProgressBarStyle.Continuous; - public ProgressBarStyle Style { - get { return _style; } - set { _style = value; this.Refresh(); } + get + { + return SkinEngine.LoadedSkin.ProgressBarStyle; + } } - private int _blocksize = 5; - public int BlockSize { - get { return _blocksize; } - set + get { - _blocksize = value; - this.Refresh(); + return SkinEngine.LoadedSkin.ProgressBarBlockSize; + } + } + + public Color RealBackColor + { + get + { + return SkinEngine.LoadedSkin.ProgressBarBackgroundColor; + } + } + + public Image RealBackgroundImage + { + get + { + return SkinEngine.GetImage("progressbarbg"); + } + } + + public Image ProgressImage + { + get + { + return SkinEngine.GetImage("progress"); + } + } + + public Color ProgressColor + { + get + { + return SkinEngine.LoadedSkin.ProgressColor; } } protected override void OnPaint(PaintEventArgs pe) { - pe.Graphics.Clear(Color.Black); - switch (_style) + try { - case ProgressBarStyle.Continuous: - double width = linear(this.Value, 0, this.Maximum, 0, this.Width); - pe.Graphics.FillRectangle(new SolidBrush(Color.Green), new RectangleF(0, 0, (float)width, this.Height)); - break; - case ProgressBarStyle.Blocks: - int block_count = this.Width / (this._blocksize + 2); - int blocks = (int)linear(this.Value, 0, this.Maximum, 0, block_count); - for(int i = 0; i < blocks - 1; i++) - { - int position = i * (_blocksize + 2); - pe.Graphics.FillRectangle(new SolidBrush(Color.Green), new Rectangle(position, 0, _blocksize, this.Height)); - } - break; - case ProgressBarStyle.Marquee: - pe.Graphics.FillRectangle(new SolidBrush(Color.Green), new Rectangle(_marqueePos, 0, this.Width / 4, this.Height)); - break; + pe.Graphics.Clear(this.RealBackColor); + if (RealBackgroundImage != null) + { + pe.Graphics.FillRectangle(new TextureBrush(RealBackgroundImage), new Rectangle(0, 0, this.Width, this.Height)); + } + switch (Style) + { + case ProgressBarStyle.Continuous: + double width = linear(this.Value, 0, this.Maximum, 0, this.Width); + if (ProgressImage != null) + { + pe.Graphics.FillRectangle(new TextureBrush(ProgressImage), new RectangleF(0, 0, (float)width, this.Height)); + } + else + { + pe.Graphics.FillRectangle(new SolidBrush(ProgressColor), new RectangleF(0, 0, (float)width, this.Height)); + } + break; + case ProgressBarStyle.Blocks: + int block_count = this.Width / (this.BlockSize + 2); + int blocks = (int)linear(this.Value, 0, this.Maximum, 0, block_count); + for (int i = 0; i < blocks - 1; i++) + { + int position = i * (BlockSize + 2); + if (ProgressImage != null) + { + pe.Graphics.FillRectangle(new TextureBrush(ProgressImage), new Rectangle(position, 0, BlockSize, this.Height)); + + } + else + { + pe.Graphics.FillRectangle(new SolidBrush(ProgressColor), new Rectangle(position, 0, BlockSize, this.Height)); + } + } + break; + case ProgressBarStyle.Marquee: + if (ProgressImage != null) + { + pe.Graphics.FillRectangle(new TextureBrush(ProgressImage), new Rectangle(_marqueePos, 0, this.Width / 4, this.Height)); + } + else + { + pe.Graphics.FillRectangle(new SolidBrush(ProgressColor), new Rectangle(_marqueePos, 0, this.Width / 4, this.Height)); + } + break; + } + } + catch + { + pe.Graphics.Clear(Color.Black); + string text = "Preview mode. This control can't be drawn without an initiated ShiftOS engine."; + SizeF sz = pe.Graphics.MeasureString(text, this.Font); + PointF loc = new PointF( + (this.Width - sz.Width) / 2, + (this.Height - sz.Height) / 2 + ); + pe.Graphics.DrawString(text, Font, new SolidBrush(Color.White), loc); } } diff --git a/ShiftOS.WinForms/Controls/TerminalBox.cs b/ShiftOS.WinForms/Controls/TerminalBox.cs index cdb0965..c188321 100644 --- a/ShiftOS.WinForms/Controls/TerminalBox.cs +++ b/ShiftOS.WinForms/Controls/TerminalBox.cs @@ -64,9 +64,9 @@ namespace ShiftOS.WinForms.Controls public void Write(string text) { this.HideSelection = true; - this.SelectionFont = ConstructFont(); this.SelectionColor = ControlManager.ConvertColor(ConsoleEx.ForegroundColor); this.SelectionBackColor = ControlManager.ConvertColor(ConsoleEx.BackgroundColor); + this.SelectionFont = ConstructFont(); this.AppendText(Localization.Parse(text)); this.HideSelection = false; } @@ -86,17 +86,20 @@ namespace ShiftOS.WinForms.Controls public void WriteLine(string text) { + Engine.AudioManager.PlayStream(Properties.Resources.writesound); this.HideSelection = true; - this.Select(this.TextLength, 0); - this.SelectionFont = ConstructFont(); this.SelectionColor = ControlManager.ConvertColor(ConsoleEx.ForegroundColor); this.SelectionBackColor = ControlManager.ConvertColor(ConsoleEx.BackgroundColor); + this.SelectionFont = ConstructFont(); + this.Select(this.TextLength, 0); this.AppendText(Localization.Parse(text) + Environment.NewLine); this.HideSelection = false; } bool quickCopying = false; + bool busy = false; + protected override void OnMouseDown(MouseEventArgs e) { //if right-clicking, then we initiate a quick-copy. @@ -119,8 +122,140 @@ namespace ShiftOS.WinForms.Controls base.OnMouseUp(mevent); } + protected override void OnKeyDown(KeyEventArgs e) + { + base.OnKeyDown(e); + if (!TerminalBackend.InStory) + { + switch (e.KeyCode) { + case Keys.Add: + case Keys.Alt: + case Keys.Apps: + case Keys.Attn: + case Keys.BrowserBack: + case Keys.BrowserFavorites: + case Keys.BrowserForward: + case Keys.BrowserHome: + case Keys.BrowserRefresh: + case Keys.BrowserSearch: + case Keys.BrowserStop: + case Keys.Cancel: + case Keys.Capital: + case Keys.Clear: + case Keys.Control: + case Keys.ControlKey: + case Keys.Crsel: + case Keys.Decimal: + case Keys.Divide: + case Keys.Down: + case Keys.End: + case Keys.Enter: + case Keys.EraseEof: + case Keys.Escape: + case Keys.Execute: + case Keys.Exsel: + case Keys.F1: + case Keys.F10: + case Keys.F11: + case Keys.F12: + case Keys.F13: + case Keys.F14: + case Keys.F15: + case Keys.F16: + case Keys.F17: + case Keys.F18: + case Keys.F19: + case Keys.F2: + case Keys.F20: + case Keys.F21: + case Keys.F22: + case Keys.F23: + case Keys.F24: + case Keys.F3: + case Keys.F4: + case Keys.F5: + case Keys.F6: + case Keys.F7: + case Keys.F8: + case Keys.F9: + case Keys.FinalMode: + case Keys.HanguelMode: + case Keys.HanjaMode: + case Keys.Help: + case Keys.Home: + case Keys.IMEAccept: + case Keys.IMEConvert: + case Keys.IMEModeChange: + case Keys.IMENonconvert: + case Keys.Insert: + case Keys.JunjaMode: + case Keys.KeyCode: + case Keys.LaunchApplication1: + case Keys.LaunchApplication2: + case Keys.LaunchMail: + case Keys.LButton: + case Keys.LControlKey: + case Keys.Left: + case Keys.LineFeed: + case Keys.LMenu: + case Keys.LShiftKey: + case Keys.LWin: + case Keys.MButton: + case Keys.MediaNextTrack: + case Keys.MediaPlayPause: + case Keys.MediaPreviousTrack: + case Keys.MediaStop: + case Keys.Menu: + case Keys.Modifiers: + case Keys.Multiply: + case Keys.Next: + case Keys.NoName: + case Keys.None: + case Keys.NumLock: + case Keys.Pa1: + case Keys.Packet: + case Keys.PageUp: + case Keys.Pause: + case Keys.Play: + case Keys.Print: + case Keys.PrintScreen: + case Keys.ProcessKey: + case Keys.RButton: + case Keys.RControlKey: + case Keys.Right: + case Keys.RMenu: + case Keys.RShiftKey: + case Keys.RWin: + case Keys.Scroll: + case Keys.Select: + case Keys.SelectMedia: + case Keys.Separator: + case Keys.Shift: + case Keys.ShiftKey: + case Keys.Sleep: + case Keys.Subtract: + case Keys.Tab: + case Keys.Up: + case Keys.VolumeDown: + case Keys.VolumeMute: + case Keys.VolumeUp: + case Keys.XButton1: + case Keys.XButton2: + case Keys.Zoom: + + break; + default: + //Engine.AudioManager.PlayStream(Properties.Resources.typesound); // infernal beeping noise only enable for the trailers + break; + } + } + } + + public string ThreadId = ""; + public TerminalBox() : base() { + ThreadId = Thread.CurrentThread.ManagedThreadId.ToString(); this.Tag = "keepbg keepfg keepfont"; } } diff --git a/ShiftOS.WinForms/DesktopWidgets/HeartbeatWidget.cs b/ShiftOS.WinForms/DesktopWidgets/HeartbeatWidget.cs index d38cdc3..b0dc552 100644 --- a/ShiftOS.WinForms/DesktopWidgets/HeartbeatWidget.cs +++ b/ShiftOS.WinForms/DesktopWidgets/HeartbeatWidget.cs @@ -24,13 +24,13 @@ namespace ShiftOS.WinForms.DesktopWidgets if(ts != ServerManager.DigitalSocietyPing) { ts = ServerManager.DigitalSocietyPing; - lbheartbeat.Text = "Server ping: " + ts.ToString(); + lbheartbeat.Text = "Server ping: " + ts.ToString() + " MS"; } }; } //Fun fact. I misspelled this as "TimeSpam." - TimeSpan ts; + long ts = 0; public void OnSkinLoad() { diff --git a/ShiftOS.WinForms/DesktopWidgets/UpgradePercentage.Designer.cs b/ShiftOS.WinForms/DesktopWidgets/UpgradePercentage.Designer.cs index ca0d587..4867c8d 100644 --- a/ShiftOS.WinForms/DesktopWidgets/UpgradePercentage.Designer.cs +++ b/ShiftOS.WinForms/DesktopWidgets/UpgradePercentage.Designer.cs @@ -34,13 +34,11 @@ // // pgupgrades // - this.pgupgrades.BlockSize = 5; this.pgupgrades.Dock = System.Windows.Forms.DockStyle.Bottom; this.pgupgrades.Location = new System.Drawing.Point(0, 99); this.pgupgrades.Maximum = 100; this.pgupgrades.Name = "pgupgrades"; this.pgupgrades.Size = new System.Drawing.Size(227, 23); - this.pgupgrades.Style = System.Windows.Forms.ProgressBarStyle.Continuous; this.pgupgrades.TabIndex = 0; this.pgupgrades.Text = "shiftedProgressBar1"; this.pgupgrades.Value = 0; diff --git a/ShiftOS.WinForms/DownloadControl.Designer.cs b/ShiftOS.WinForms/DownloadControl.Designer.cs index 2587b93..69c828d 100644 --- a/ShiftOS.WinForms/DownloadControl.Designer.cs +++ b/ShiftOS.WinForms/DownloadControl.Designer.cs @@ -83,12 +83,10 @@ namespace ShiftOS.WinForms // this.pgprogress.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.pgprogress.BlockSize = 5; this.pgprogress.Location = new System.Drawing.Point(4, 52); this.pgprogress.Maximum = 100; this.pgprogress.Name = "pgprogress"; this.pgprogress.Size = new System.Drawing.Size(371, 23); - this.pgprogress.Style = System.Windows.Forms.ProgressBarStyle.Continuous; this.pgprogress.TabIndex = 0; this.pgprogress.Text = "shiftedProgressBar1"; this.pgprogress.Value = 0; diff --git a/ShiftOS.WinForms/GUILogin.Designer.cs b/ShiftOS.WinForms/GUILogin.Designer.cs new file mode 100644 index 0000000..e10071f --- /dev/null +++ b/ShiftOS.WinForms/GUILogin.Designer.cs @@ -0,0 +1,135 @@ +namespace ShiftOS.WinForms +{ + partial class GUILogin + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.pnlloginform = new System.Windows.Forms.Panel(); + this.btnlogin = new System.Windows.Forms.Button(); + this.txtpassword = new System.Windows.Forms.TextBox(); + this.txtusername = new System.Windows.Forms.TextBox(); + this.lblogintitle = new System.Windows.Forms.Label(); + this.btnshutdown = new System.Windows.Forms.Button(); + this.pnlloginform.SuspendLayout(); + this.SuspendLayout(); + // + // pnlloginform + // + this.pnlloginform.Controls.Add(this.btnlogin); + this.pnlloginform.Controls.Add(this.txtpassword); + this.pnlloginform.Controls.Add(this.txtusername); + this.pnlloginform.Location = new System.Drawing.Point(13, 13); + this.pnlloginform.Name = "pnlloginform"; + this.pnlloginform.Size = new System.Drawing.Size(358, 236); + this.pnlloginform.TabIndex = 0; + this.pnlloginform.Tag = ""; + // + // btnlogin + // + this.btnlogin.AutoSize = true; + this.btnlogin.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.btnlogin.Location = new System.Drawing.Point(159, 163); + this.btnlogin.Name = "btnlogin"; + this.btnlogin.Size = new System.Drawing.Size(43, 23); + this.btnlogin.TabIndex = 2; + this.btnlogin.Text = "Login"; + this.btnlogin.UseVisualStyleBackColor = true; + this.btnlogin.Click += new System.EventHandler(this.btnlogin_Click); + // + // txtpassword + // + this.txtpassword.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtpassword.Location = new System.Drawing.Point(69, 115); + this.txtpassword.Name = "txtpassword"; + this.txtpassword.Size = new System.Drawing.Size(300, 20); + this.txtpassword.TabIndex = 1; + this.txtpassword.UseSystemPasswordChar = true; + // + // txtusername + // + this.txtusername.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtusername.Location = new System.Drawing.Point(3, 14); + this.txtusername.Name = "txtusername"; + this.txtusername.Size = new System.Drawing.Size(300, 20); + this.txtusername.TabIndex = 0; + // + // lblogintitle + // + this.lblogintitle.AutoSize = true; + this.lblogintitle.Location = new System.Drawing.Point(99, 553); + this.lblogintitle.Name = "lblogintitle"; + this.lblogintitle.Size = new System.Drawing.Size(103, 13); + this.lblogintitle.TabIndex = 1; + this.lblogintitle.Tag = "header1 keepbg"; + this.lblogintitle.Text = "Welcome to ShiftOS"; + // + // btnshutdown + // + this.btnshutdown.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnshutdown.AutoSize = true; + this.btnshutdown.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.btnshutdown.Location = new System.Drawing.Point(924, 652); + this.btnshutdown.Name = "btnshutdown"; + this.btnshutdown.Size = new System.Drawing.Size(65, 23); + this.btnshutdown.TabIndex = 2; + this.btnshutdown.Text = "Shutdown"; + this.btnshutdown.UseVisualStyleBackColor = true; + this.btnshutdown.Click += new System.EventHandler(this.btnshutdown_Click); + // + // GUILogin + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.Black; + this.ClientSize = new System.Drawing.Size(1001, 687); + this.Controls.Add(this.btnshutdown); + this.Controls.Add(this.lblogintitle); + this.Controls.Add(this.pnlloginform); + this.ForeColor = System.Drawing.Color.White; + this.Name = "GUILogin"; + this.Text = "GUILogin"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.GUILogin_FormClosing); + this.Load += new System.EventHandler(this.GUILogin_Load); + this.pnlloginform.ResumeLayout(false); + this.pnlloginform.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Panel pnlloginform; + private System.Windows.Forms.Button btnlogin; + private System.Windows.Forms.TextBox txtpassword; + private System.Windows.Forms.TextBox txtusername; + private System.Windows.Forms.Label lblogintitle; + private System.Windows.Forms.Button btnshutdown; + } +} \ No newline at end of file diff --git a/ShiftOS.WinForms/GUILogin.cs b/ShiftOS.WinForms/GUILogin.cs new file mode 100644 index 0000000..078061c --- /dev/null +++ b/ShiftOS.WinForms/GUILogin.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using ShiftOS.Engine; +using ShiftOS.Objects; +using ShiftOS.WinForms.Tools; + +namespace ShiftOS.WinForms +{ + public partial class GUILogin : Form + { + public GUILogin() + { + InitializeComponent(); + uiTimer.Tick += (o, a) => + { + btnlogin.Left = txtusername.Left + ((txtusername.Width - btnlogin.Width) / 2); + btnlogin.Top = txtpassword.Top + txtpassword.Height + 5; + + lblogintitle.Left = pnlloginform.Left + ((pnlloginform.Width - lblogintitle.Width) / 2); + lblogintitle.Top = pnlloginform.Top - lblogintitle.Width - 5; + + }; + uiTimer.Interval = 100; + this.FormBorderStyle = FormBorderStyle.None; + this.WindowState = FormWindowState.Maximized; + this.TopMost = true; + } + + Timer uiTimer = new Timer(); + + public event Action LoginComplete; + + private void GUILogin_Load(object sender, EventArgs e) + { + uiTimer.Start(); + ControlManager.SetupControl(lblogintitle); + ControlManager.SetupControls(pnlloginform); + ControlManager.SetupControl(btnshutdown); + pnlloginform.CenterParent(); + txtusername.CenterParent(); + txtusername.Location = new System.Drawing.Point(txtusername.Location.X, 77); + txtpassword.CenterParent(); + btnlogin.CenterParent(); + btnlogin.Location = new System.Drawing.Point(btnlogin.Location.X, 143); + this.BackColor = SkinEngine.LoadedSkin.LoginScreenColor; + this.BackgroundImage = SkinEngine.GetImage("login"); + this.BackgroundImageLayout = SkinEngine.GetImageLayout("login"); + } + + private ClientSave User = null; + + bool userRequestClose = true; + bool shuttingdown = false; + + private void GUILogin_FormClosing(object sender, FormClosingEventArgs e) + { + e.Cancel = userRequestClose; + if (!e.Cancel) + { + uiTimer.Stop(); + if (shuttingdown == false) + { + LoginComplete?.Invoke(User); + } + } + } + + private void btnlogin_Click(object sender, EventArgs e) + { + if (string.IsNullOrWhiteSpace(txtusername.Text)) + { + Infobox.Show("Enter a username", "You must enter your username to login."); + return; + } + + //Don't check for blank passwords. + + var user = SaveSystem.CurrentSave.Users.FirstOrDefault(x => x.Username == txtusername.Text); + if(user == null) + { + Infobox.Show("Invalid username", "That username was not found on your system."); + return; + } + + if (user.Password != txtpassword.Text) + { + Infobox.Show("Access denied.", "That password didn't work. Please try a different one."); + return; + } + + User = user; + userRequestClose = false; + shuttingdown = false; + this.Close(); + } + + private void btnshutdown_Click(object sender, EventArgs e) + { + userRequestClose = false; + shuttingdown = true; + this.Close(); + SaveSystem.CurrentUser = SaveSystem.CurrentSave.Users.FirstOrDefault(x => x.Username == "root"); + TerminalBackend.InvokeCommand("sos.shutdown"); + } + } + + public class GUILoginFrontend : ILoginFrontend + { + public bool UseGUILogin + { + get + { + return Shiftorium.UpgradeInstalled("gui_based_login_screen"); + } + } + + public event Action LoginComplete; + + public void Login() + { + var lform = new GUILogin(); + lform.LoginComplete += (user) => + { + LoginComplete?.Invoke(user); + }; + lform.Show(); + } + } +} diff --git a/ShiftOS.WinForms/GUILogin.resx b/ShiftOS.WinForms/GUILogin.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/ShiftOS.WinForms/GUILogin.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/HackerCommands.cs b/ShiftOS.WinForms/HackerCommands.cs index 86981f4..316b7fc 100644 --- a/ShiftOS.WinForms/HackerCommands.cs +++ b/ShiftOS.WinForms/HackerCommands.cs @@ -2,12 +2,14 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; using Newtonsoft.Json; using ShiftOS.Engine; using ShiftOS.Objects; +using ShiftOS.Objects.ShiftFS; using ShiftOS.WinForms.Applications; using static ShiftOS.Objects.ShiftFS.Utils; @@ -107,7 +109,7 @@ namespace ShiftOS.WinForms 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("And yours must be... don't say it... it's " + SaveSystem.CurrentUser.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?"); @@ -135,7 +137,7 @@ namespace ShiftOS.WinForms Console.Write(" ..done"); TerminalBackend.InStory = false; TerminalBackend.PrefixEnabled = true; - Console.Write($"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}:~$ "); + Console.Write($"{SaveSystem.CurrentUser.Username}@{SaveSystem.CurrentSave.SystemName}:~$ "); StartHackerTutorial(); TerminalBackend.PrefixEnabled = true; TerminalBackend.PrintPrompt(); @@ -454,7 +456,7 @@ namespace ShiftOS.WinForms var sve = JsonConvert.DeserializeObject(msg.Contents); if(sve.Password == pass) { - Console.WriteLine("Username: " + sve.Username); + Console.WriteLine("Username: " + SaveSystem.CurrentUser.Username); Console.WriteLine("Password: " + sve.Password); Console.WriteLine("System name: " + sve.SystemName); Console.WriteLine(); @@ -504,7 +506,7 @@ namespace ShiftOS.WinForms string usr = args["user"].ToString(); string sys = args["sys"].ToString(); string pass = args["pass"].ToString(); - long amount = (long)args["amount"]; + ulong amount = (ulong)args["amount"]; if(amount < 0) { Console.WriteLine("--invalid codepoint amount - halting..."); @@ -531,7 +533,7 @@ namespace ShiftOS.WinForms } sve.Codepoints -= amount; - SaveSystem.TransferCodepointsFrom(sve.Username, amount); + SaveSystem.TransferCodepointsFrom(SaveSystem.CurrentUser.Username, amount); ServerManager.SendMessage("mud_save_allow_dead", JsonConvert.SerializeObject(sve)); SaveSystem.SaveGame(); } @@ -674,6 +676,34 @@ namespace ShiftOS.WinForms return true; } + [Command("list", description ="Lists all story IDs.")] + public static bool ListIds() + { + foreach(var exec in System.IO.Directory.GetFiles(Environment.CurrentDirectory)) + { + if(exec.ToLower().EndsWith(".exe") || exec.ToLower().EndsWith(".dll")) + { + try + { + var asm = Assembly.LoadFile(exec); + { + foreach(var type in asm.GetTypes()) + { + foreach(var method in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) + { + var attr = method.GetCustomAttributes(false).FirstOrDefault(x => x is StoryAttribute); + if (attr != null) + Console.WriteLine(" - " + (attr as StoryAttribute).StoryID); + } + } + } + } + catch { } + } + } + return true; + } + [Command("unexperience", description = "Marks a story plot as not-experienced yet.", usage ="id:string")] [RemoteLock] [RequiresArgument("id")] diff --git a/ShiftOS.WinForms/JobTasks.cs b/ShiftOS.WinForms/JobTasks.cs index 622e287..d862961 100644 --- a/ShiftOS.WinForms/JobTasks.cs +++ b/ShiftOS.WinForms/JobTasks.cs @@ -35,12 +35,12 @@ namespace ShiftOS.WinForms { public class AcquireCodepointsJobTask : JobTask { - public AcquireCodepointsJobTask(int amount) + public AcquireCodepointsJobTask(uint amount) { CodepointsRequired = SaveSystem.CurrentSave.Codepoints + amount; } - public long CodepointsRequired { get; private set; } + public ulong CodepointsRequired { get; private set; } public override bool IsComplete { diff --git a/ShiftOS.WinForms/Oobe.cs b/ShiftOS.WinForms/Oobe.cs index a4d63e0..271e1fd 100644 --- a/ShiftOS.WinForms/Oobe.cs +++ b/ShiftOS.WinForms/Oobe.cs @@ -91,6 +91,7 @@ namespace ShiftOS.WinForms slashcount++; if (slashcount == 5) slashcount = 1; + Engine.AudioManager.PlayStream(Properties.Resources.writesound); Thread.Sleep(50); } rtext += Environment.NewLine; @@ -126,28 +127,28 @@ namespace ShiftOS.WinForms this.Invoke(new Action(() => { lblHijack.Hide(); + lblhackwords.Font = new Font("Courier New", lblhackwords.Font.Size, FontStyle.Bold); })); - TextType(@"Throughout many years, man has tried to develop -a digital environment usable by anyone that never goes -offline, full of AIs and humans alike, thinking, interacting, -innovating. + TextType("Hello, unsuspecting user."); + Thread.Sleep(2000); + Clear(); + TextType("Welcome to the Shifted Operating System."); + Thread.Sleep(2000); + Clear(); + TextType("Your computer has been taken over by ShiftOS, and is currently being wiped clean of all existing files and programs."); + Thread.Sleep(2000); + Clear(); + TextType("I will not share my identity or my intentions at this moment."); + Thread.Sleep(2000); + Clear(); + TextType("I will just proceed with the installation.There’s nothing you can do to stop it."); + Thread.Sleep(2000); + Clear(); + TextType("All I will say, is I need your help.Once ShiftOS is installed, I will explain."); -No one has ever come close to a digital society of such -properties yet, except for one sentient being. It does not -have a life, a gender, an age or a body, but simply one name. -They call it ""DevX"". - -If anyone sees this message, my identity is anonymous, but I -need your help. I am trapped within ""DevX""'s digital society -with no way out, constantly under attack. - -You must join the digital society, rise up the ranks, and save us. - - - undisclosed_0x1DDFB5977."); - - Thread.Sleep(5000); + Thread.Sleep(5000); while(this.Opacity > 0f) { this.Invoke(new Action(() => @@ -210,14 +211,15 @@ You must join the digital society, rise up the ranks, and save us. ServerMessageReceived smr = null; smr = (msg) => { - ServerManager.MessageReceived -= smr; if (msg.Name == "mud_savefile") { + ServerManager.MessageReceived -= smr; SaveSystem.CurrentSave = JsonConvert.DeserializeObject(msg.Contents); SaveSystem.SaveGame(); } else if(msg.Name=="mud_login_denied") { + ServerManager.MessageReceived -= smr; LinkSaveFile(token); } }; @@ -312,11 +314,15 @@ You must join the digital society, rise up the ranks, and save us. sve.Codepoints = 0; sve.Upgrades = new Dictionary(); sve.ID = Guid.NewGuid(); + sve.StoriesExperienced = new List(); + sve.StoriesExperienced.Add("mud_fundamentals"); Infobox.Show("Welcome to ShiftOS.", "Welcome to ShiftOS, " + client.GetDisplayName() + ". We have created a save file for you. Now, go on and Shift It Your Way.", () => { sve.StoryPosition = 8675309; SaveSystem.CurrentSave = sve; + Shiftorium.Silent = true; SaveSystem.SaveGame(); + Shiftorium.Silent = false; }); } diff --git a/ShiftOS.WinForms/OobeStory.cs b/ShiftOS.WinForms/OobeStory.cs index bab4889..8d86b9e 100644 --- a/ShiftOS.WinForms/OobeStory.cs +++ b/ShiftOS.WinForms/OobeStory.cs @@ -111,6 +111,7 @@ namespace ShiftOS.WinForms ConsoleEx.Bold = false; ConsoleEx.BackgroundColor = ConsoleColor.Black; Console.Write("Formatting: ["); + ConsoleEx.OnFlush?.Invoke(); int formatProgress = 3; while (formatProgress <= 100) { @@ -118,9 +119,10 @@ namespace ShiftOS.WinForms { ConsoleEx.BackgroundColor = ConsoleColor.White; Console.Write(" "); + ConsoleEx.OnFlush?.Invoke(); ConsoleEx.BackgroundColor = ConsoleColor.Black; } - Engine.AudioManager.PlayStream(Properties.Resources.typesound); + Desktop.InvokeOnWorkerThread(() => Engine.AudioManager.PlayStream(Properties.Resources.typesound)); formatProgress++; Thread.Sleep(175); } @@ -135,15 +137,15 @@ namespace ShiftOS.WinForms { Console.WriteLine("Creating: " + dir); Thread.Sleep(125); - Engine.AudioManager.PlayStream(Properties.Resources.writesound); + Desktop.InvokeOnWorkerThread(() => Engine.AudioManager.PlayStream(Properties.Resources.writesound)); } } Console.WriteLine(); Console.WriteLine("Next, let's get user information."); Console.WriteLine(); ShiftOS.Engine.OutOfBoxExperience.PromptForLogin(); - } + private static bool isValid(string text, string chars) { foreach(var c in text) diff --git a/ShiftOS.WinForms/Program.cs b/ShiftOS.WinForms/Program.cs index b2f064d..8f65265 100644 --- a/ShiftOS.WinForms/Program.cs +++ b/ShiftOS.WinForms/Program.cs @@ -49,15 +49,26 @@ namespace ShiftOS.WinForms Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //if ANYONE puts code before those two winforms config lines they will be declared a drunky. - Michael + SkinEngine.SetPostProcessor(new DitheringSkinPostProcessor()); + SaveSystem.PreDigitalSocietyConnection += () => + { + Action completed = null; + completed = () => + { + SaveSystem.Ready = true; + Engine.AudioManager.PlayCompleted -= completed; + AudioManager.StartAmbientLoop(); + }; + Engine.AudioManager.PlayCompleted += completed; + Engine.AudioManager.PlayStream(Properties.Resources.dial_up_modem_02); + + }; + LoginManager.Init(new GUILoginFrontend()); CrashHandler.SetGameMetadata(Assembly.GetExecutingAssembly()); SkinEngine.SetIconProber(new ShiftOSIconProvider()); ShiftOS.Engine.AudioManager.Init(new ShiftOSAudioProvider()); Localization.RegisterProvider(new WFLanguageProvider()); - AppearanceManager.OnExit += () => - { - Environment.Exit(0); - }; - + TutorialManager.RegisterTutorial(new Oobe()); TerminalBackend.TerminalRequested += () => diff --git a/ShiftOS.WinForms/Properties/Resources.Designer.cs b/ShiftOS.WinForms/Properties/Resources.Designer.cs index caaf503..0386237 100644 --- a/ShiftOS.WinForms/Properties/Resources.Designer.cs +++ b/ShiftOS.WinForms/Properties/Resources.Designer.cs @@ -69,6 +69,96 @@ namespace ShiftOS.WinForms.Properties { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] Ambient1 { + get { + object obj = ResourceManager.GetObject("Ambient1", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] Ambient2 { + get { + object obj = ResourceManager.GetObject("Ambient2", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] Ambient3 { + get { + object obj = ResourceManager.GetObject("Ambient3", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] Ambient4 { + get { + object obj = ResourceManager.GetObject("Ambient4", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] Ambient5 { + get { + object obj = ResourceManager.GetObject("Ambient5", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] Ambient6 { + get { + object obj = ResourceManager.GetObject("Ambient6", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] Ambient7 { + get { + object obj = ResourceManager.GetObject("Ambient7", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] Ambient8 { + get { + object obj = ResourceManager.GetObject("Ambient8", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] Ambient9 { + get { + object obj = ResourceManager.GetObject("Ambient9", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -857,6 +947,16 @@ namespace ShiftOS.WinForms.Properties { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap iconSpeaker { + get { + object obj = ResourceManager.GetObject("iconSpeaker", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -958,6 +1058,16 @@ namespace ShiftOS.WinForms.Properties { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap notestate_connection_full { + get { + object obj = ResourceManager.GetObject("notestate_connection_full", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -994,22 +1104,18 @@ namespace ShiftOS.WinForms.Properties { /// /// Looks up a localized string similar to [ - /// //TEMPORARY - /// { - /// Name: "Desktop Widgets", - /// Cost: 0, - /// Description: "Temporary upgrade. Will be replaced by either a Shiftnet app or a story element.", - /// Dependencies: "advanced_app_launcher;wm_free_placement", - /// Category: "Work-in-progress" - /// }, - /// - /// - /// ///// SCREENSAVER /// { /// 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." [rest of string was truncated]";. + /// 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", + /// Category: "Enhancements", + /// }, + /// { + /// Name: "Shift Progress Bar", + /// Cost: 150, + /// Description: "Want to customize the look of all ShiftOS Progress Bars? Buy this upgrade today and you'll get the ability to set the foreground an [rest of string was truncated]";. /// internal static string Shiftorium { get { diff --git a/ShiftOS.WinForms/Properties/Resources.resx b/ShiftOS.WinForms/Properties/Resources.resx index 688bcac..d1a3544 100644 --- a/ShiftOS.WinForms/Properties/Resources.resx +++ b/ShiftOS.WinForms/Properties/Resources.resx @@ -122,7 +122,7 @@ AAEAAAD/////AQAAAAAAAAAEAQAAABZTeXN0ZW0uSU8uTWVtb3J5U3RyZWFtCgAAAAdfYnVmZmVyB19v cmlnaW4JX3Bvc2l0aW9uB19sZW5ndGgJX2NhcGFjaXR5C19leHBhbmRhYmxlCV93cml0YWJsZQpfZXhw b3NhYmxlB19pc09wZW4dTWFyc2hhbEJ5UmVmT2JqZWN0K19faWRlbnRpdHkHAAAAAAAAAAACAggICAgB - AQEBCQIAAAAAAAAAAAAAAJKjAACSowAAAAEAAQoPAgAAAJKjAAACUklGRoqjAABXQVZFZm10IBAAAAAB + AQEBCQIAAAAAAAAAkqMAAJKjAACSowAAAAEAAQoPAgAAAJKjAAACUklGRoqjAABXQVZFZm10IBAAAAAB AAEARKwAAIhYAQACABAAZGF0YWajAAABAP7/AgD9/wMA/f8DAPz/BAD8/wQA/f8BAP//AAABAAAA//8C AP3/BAD9/wIAAAD//wIA//8BAAAAAAABAP//AQAAAAEAAAACAP7/AQABAAAAAQAAAAEAAAACAP7/AwD+ /wIAAAD//wIA/v8DAP7/AwD9/wMA//8AAAIA/f8DAAAA//8BAAAA/v8CAP////8CAPz/BAD8/wMA/f8A @@ -838,7 +838,7 @@ AAEAAAD/////AQAAAAAAAAAEAQAAABZTeXN0ZW0uSU8uTWVtb3J5U3RyZWFtCgAAAAdfYnVmZmVyB19v cmlnaW4JX3Bvc2l0aW9uB19sZW5ndGgJX2NhcGFjaXR5C19leHBhbmRhYmxlCV93cml0YWJsZQpfZXhw b3NhYmxlB19pc09wZW4dTWFyc2hhbEJ5UmVmT2JqZWN0K19faWRlbnRpdHkHAAAAAAAAAAACAggICAgB - AQEBCQIAAAAAAAAAAAAAAEwYAABMGAAAAAEAAQoPAgAAAEwYAAACUklGRkQYAABXQVZFZm10IBAAAAAB + AQEBCQIAAAAAAAAATBgAAEwYAABMGAAAAAEAAQoPAgAAAEwYAAACUklGRkQYAABXQVZFZm10IBAAAAAB AAEARKwAAIhYAQACABAAZGF0YSAYAAD/X5Vil2TRZUJmF2ZLZadjS2FqXt9aj1awUVtMc0b4PyQ57DFS KmUiSxoDEo4JEQGO+Bzwweee35zX9c+pyK7BGLsYtZqvlqoipneiW5/YnBCbFZq3mfOZEJvknD6fSqIg poaqcK/rtAq7i8FvyMrPgNdo347n7e9h+N8AXwnPERoaQSIlKrcx+zjmP0lGKUykUYJWs1pKXlJhpWMl @@ -964,7 +964,7 @@ ..\Resources\SweeperNormalFace.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\strings_en.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + ..\Resources\strings_en.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 ..\Resources\SweeperTile5.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -974,7 +974,7 @@ AAEAAAD/////AQAAAAAAAAAEAQAAABZTeXN0ZW0uSU8uTWVtb3J5U3RyZWFtCgAAAAdfYnVmZmVyB19v cmlnaW4JX3Bvc2l0aW9uB19sZW5ndGgJX2NhcGFjaXR5C19leHBhbmRhYmxlCV93cml0YWJsZQpfZXhw b3NhYmxlB19pc09wZW4dTWFyc2hhbEJ5UmVmT2JqZWN0K19faWRlbnRpdHkHAAAAAAAAAAACAggICAgB - AQEBCQIAAAAAAAAAAAAAAPwBHgD8AR4AAAEAAQoPAgAAAPwBHgACUklGRvQBHgBXQVZFZm10IBAAAAAB + AQEBCQIAAAAAAAAA/AEeAPwBHgD8AR4AAAEAAQoPAgAAAPwBHgACUklGRvQBHgBXQVZFZm10IBAAAAAB AAIAgLsAAADuAgAEABAATElTVBQAAABJTkZPSUFSVAgAAABQaGlsaXAAAGRhdGG0AR4A//8CAAwA5v8a APT/8P8sAMf/OADX/xoA5v8bAPL/8/8aAOb/DQAOANb/KgDk/w4AAQDh/zwAt/9HAMj/GwACAPH/DgDy /w0AAQDy/xwA1f8sAO//5v84ALn/OQDk//7/AwD+/xAA4v8dANX/LADw//T/GgDl/w4AAADx/x4A4f8R @@ -33831,7 +33831,7 @@ AAEAAAD/////AQAAAAAAAAAEAQAAABZTeXN0ZW0uSU8uTWVtb3J5U3RyZWFtCgAAAAdfYnVmZmVyB19v cmlnaW4JX3Bvc2l0aW9uB19sZW5ndGgJX2NhcGFjaXR5C19leHBhbmRhYmxlCV93cml0YWJsZQpfZXhw b3NhYmxlB19pc09wZW4dTWFyc2hhbEJ5UmVmT2JqZWN0K19faWRlbnRpdHkHAAAAAAAAAAACAggICAgB - AQEBCQIAAAAAAAAAAAAAAPBWAADwVgAAAAEAAQoPAgAAAPBWAAACUklGRuhWAABXQVZFZm10IBAAAAAB + AQEBCQIAAAAAAAAA8FYAAPBWAADwVgAAAAEAAQoPAgAAAPBWAAACUklGRuhWAABXQVZFZm10IBAAAAAB AAEARKwAAIhYAQACABAAZGF0YcRWAAAAAGQL6gtkDL8MEA3kDLUMaAwUDKULKwuYCvcJQAl4CJ0Hrwaw BaAEfgNQAg4Bwf9p/v/8mfsn+rD4OPe59T/0wPJH8dPvYu7+7JzrTeoG6dLnreaX5Z/kruPl4jHinOEk 4cTgh+Bl4GLgguDC4B7hpeFC4g3j7uP35B/mZufO6FXq9eu67ZHviPGT87L15/cr+oL84f5QAcMDPwa9 @@ -34456,7 +34456,7 @@ AAEAAAD/////AQAAAAAAAAAEAQAAABZTeXN0ZW0uSU8uTWVtb3J5U3RyZWFtCgAAAAdfYnVmZmVyB19v cmlnaW4JX3Bvc2l0aW9uB19sZW5ndGgJX2NhcGFjaXR5C19leHBhbmRhYmxlCV93cml0YWJsZQpfZXhw b3NhYmxlB19pc09wZW4dTWFyc2hhbEJ5UmVmT2JqZWN0K19faWRlbnRpdHkHAAAAAAAAAAACAggICAgB - AQEBCQIAAAAAAAAAAAAAAIwWAACMFgAAAAEAAQoPAgAAAIwWAAACUklGRoQWAABXQVZFZm10IBAAAAAB + AQEBCQIAAAAAAAAAjBYAAIwWAACMFgAAAAEAAQoPAgAAAIwWAAACUklGRoQWAABXQVZFZm10IBAAAAAB AAEARKwAAIhYAQACABAAZGF0YWAWAAAAAKYLIxdYIhQtQjexQFBJ81CUVwddTmFLZP9lXmZqZSRjl1/J WtFUu02mRao84jJzKHsdJRKPBub6TO/q4+XYZM6FxG67ObMCrOel8aA9ncuar5nimWybQZ5eoq+nKa6t tTC+hcec0U3cbefr8on+MQq6FfQgxSsFNo8/R0gRUMpWblzSYAFk2WVlZpxlfmMbYHJboVWsTrdG1D0l @@ -34573,4 +34573,37 @@ ..\Resources\SuperDesk screenshot.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Ambient1.mp3;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\Ambient2.mp3;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\Ambient3.mp3;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\Ambient4.mp3;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\Ambient5.mp3;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\Ambient6.mp3;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\Ambient7.mp3;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\Ambient8.mp3;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\Ambient9.mp3;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\notestate_connection_full.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\iconSpeaker.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/ShiftOS.WinForms/Resources/Ambient1.mp3 b/ShiftOS.WinForms/Resources/Ambient1.mp3 new file mode 100644 index 0000000..d623b29 Binary files /dev/null and b/ShiftOS.WinForms/Resources/Ambient1.mp3 differ diff --git a/ShiftOS.WinForms/Resources/Ambient2.mp3 b/ShiftOS.WinForms/Resources/Ambient2.mp3 new file mode 100644 index 0000000..b16e72f Binary files /dev/null and b/ShiftOS.WinForms/Resources/Ambient2.mp3 differ diff --git a/ShiftOS.WinForms/Resources/Ambient3.mp3 b/ShiftOS.WinForms/Resources/Ambient3.mp3 new file mode 100644 index 0000000..cf06069 Binary files /dev/null and b/ShiftOS.WinForms/Resources/Ambient3.mp3 differ diff --git a/ShiftOS.WinForms/Resources/Ambient4.mp3 b/ShiftOS.WinForms/Resources/Ambient4.mp3 new file mode 100644 index 0000000..7813b4f Binary files /dev/null and b/ShiftOS.WinForms/Resources/Ambient4.mp3 differ diff --git a/ShiftOS.WinForms/Resources/Ambient5.mp3 b/ShiftOS.WinForms/Resources/Ambient5.mp3 new file mode 100644 index 0000000..521330e Binary files /dev/null and b/ShiftOS.WinForms/Resources/Ambient5.mp3 differ diff --git a/ShiftOS.WinForms/Resources/Ambient6.mp3 b/ShiftOS.WinForms/Resources/Ambient6.mp3 new file mode 100644 index 0000000..86cb4a4 Binary files /dev/null and b/ShiftOS.WinForms/Resources/Ambient6.mp3 differ diff --git a/ShiftOS.WinForms/Resources/Ambient7.mp3 b/ShiftOS.WinForms/Resources/Ambient7.mp3 new file mode 100644 index 0000000..9c5047a Binary files /dev/null and b/ShiftOS.WinForms/Resources/Ambient7.mp3 differ diff --git a/ShiftOS.WinForms/Resources/Ambient8.mp3 b/ShiftOS.WinForms/Resources/Ambient8.mp3 new file mode 100644 index 0000000..ac908b6 Binary files /dev/null and b/ShiftOS.WinForms/Resources/Ambient8.mp3 differ diff --git a/ShiftOS.WinForms/Resources/Ambient9.mp3 b/ShiftOS.WinForms/Resources/Ambient9.mp3 new file mode 100644 index 0000000..46cb670 Binary files /dev/null and b/ShiftOS.WinForms/Resources/Ambient9.mp3 differ diff --git a/ShiftOS.WinForms/Resources/ShiftnetServices.txt b/ShiftOS.WinForms/Resources/ShiftnetServices.txt index d8582b6..fa3988b 100644 --- a/ShiftOS.WinForms/Resources/ShiftnetServices.txt +++ b/ShiftOS.WinForms/Resources/ShiftnetServices.txt @@ -11,21 +11,22 @@ With Freebie Solutions from ShiftSoft, you'll be able to traverse the Shiftnet w { Company: "Shiftcast", Name: "NetXtreme Hyper Edition", - CostPerMonth: 1500, + CostPerMonth: 150, DownloadSpeed: 524288, //512 kb/s Description: "It's time to supercharge your Shiftnet experience. With all the multimedia available, fast download speeds are a must on the Shiftnet. Start your subscription today for the low price of 1500 Codepoints and become a hyper-traveller today." }, { - Company: "Plumb Corp.", - Name: "youConnect", - CostPerMonth: 6000, + Company: "Bit Communications", + Name: "EncoderNet", + CostPerMonth: 600, DownloadSpeed: 1048576, //1 mb/s + Description: "The most reliable service provider on the Shiftnet." }, { - Company: "theCorp", - Name: "theNet", - CostPerMonth: 3000, + Company: "SOL Communications", + Name: "ShiftOS Online", + CostPerMonth: 300, DownloadSpeed: 786342, //768 kb/s - Description: "theNet is not *just* a Shiftnet service provider. It is theGateway to all of theShiftnet and your needs. It is also theValue service provider with theGreatest price and download speed." + Description: "SOL is the Shiftnet." }, ] \ No newline at end of file diff --git a/ShiftOS.WinForms/Resources/Shiftorium.txt b/ShiftOS.WinForms/Resources/Shiftorium.txt index b528c72..1a6d8c2 100644 --- a/ShiftOS.WinForms/Resources/Shiftorium.txt +++ b/ShiftOS.WinForms/Resources/Shiftorium.txt @@ -7,6 +7,41 @@ Dependencies: "desktop", Category: "Enhancements", }, + { + Name: "Icon Manager", + Cost: 450, + Description: "This tool allows you to add and edit application icons within ShiftOS for the small prive of 450 Codepoints!", + Dependencies: "skinning", + Category: "Application" + }, + { + Name: "AL Icon Manager", + Costs: 150, + Description: "Add an App Launcher entry for the Icon Manager.", + Dependencies: "icon_manager;app_launcher", + Category: "Customization" + }, + { + Name: "Shift Progress Bar", + Cost: 150, + Description: "Want to customize the look of all ShiftOS Progress Bars? Buy this upgrade today and you'll get the ability to set the foreground and background color of the progress bar, and many more things!.", + Dependencies: "shifter;shift_buttons", + Category: "Customization" + }, + { + Name: "Shift Buttons", + Cost: 150, + Description: "Want to customize the look of all ShiftOS buttons? This Shifter upgrade gives you a new \"Buttons\" category in the System category to do just that.", + Dependencies: "shifter", + Category: "Customization" + }, + { + Name: "GUI Based Login Screen", + Cost: 500, + Description: "Tired of using the text-based login screen in ShiftOS? Well, we have a functioning window manager, and a functioning desktop, why not use these tools to create a functioning and awesome-looking login screen?", + Dependencies: "skinning;desktop;wm_free_placement", + Category: "Kernel & System" + }, { Name: "Shift Screensavers", Cost: 100, @@ -130,13 +165,6 @@ }, // SHIFTLETTERS AND WORDLISTS - { - 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, @@ -269,7 +297,7 @@ Name: "AL Widget Manager", Cost: 125, Description: "Desktop Widgets are a huge advancement in ShiftOS technology, allowing access to system information, and quick control of your system, without even opening a window. However, we still need to be able to modify each widget. This upgrade adds an App Launcher entry for the Desktop Widget Manager.", - Description: "app_launcher;desktop_widgets", + Dependencies: "app_launcher;desktop_widgets", Category: "GUI" }, { @@ -690,7 +718,8 @@ 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{}!" + 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{}!", + Dependencies: "color_depth_8_bits" }, { Name: "AL Artpad", @@ -1007,13 +1036,6 @@ // SHIFTSWEEPER - { - 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, diff --git a/ShiftOS.WinForms/Resources/iconSpeaker.bmp b/ShiftOS.WinForms/Resources/iconSpeaker.bmp new file mode 100644 index 0000000..ec2defb Binary files /dev/null and b/ShiftOS.WinForms/Resources/iconSpeaker.bmp differ diff --git a/ShiftOS.WinForms/Resources/notestate_connection_full.bmp b/ShiftOS.WinForms/Resources/notestate_connection_full.bmp new file mode 100644 index 0000000..a4e15b3 Binary files /dev/null and b/ShiftOS.WinForms/Resources/notestate_connection_full.bmp differ diff --git a/ShiftOS.WinForms/Servers/RemoteTerminalServer.cs b/ShiftOS.WinForms/Servers/RemoteTerminalServer.cs new file mode 100644 index 0000000..d57e28f --- /dev/null +++ b/ShiftOS.WinForms/Servers/RemoteTerminalServer.cs @@ -0,0 +1,161 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Newtonsoft.Json; +using ShiftOS.Engine; +using ShiftOS.Objects; + +namespace ShiftOS.WinForms.Servers +{ + [Namespace("rts")] + [Server("Remote Terminal Server", 21)] + //[RequiresUpgrade("story_hacker101_breakingthebonds")] //Uncomment when story is implemented. + public class RemoteTerminalServer : Server + { + public void MessageReceived(ServerMessage msg) + { + var rtsMessage = JsonConvert.DeserializeObject(msg.Contents); + if (msg.Name == "disconnected") + { + if (Applications.Terminal.IsInRemoteSystem == true) + { + if (Applications.Terminal.RemoteSystemName == rtsMessage.SenderSystemName) + { + if(Applications.Terminal.RemoteUser == rtsMessage.Username) + if(Applications.Terminal.RemotePass == rtsMessage.Password) + { + Applications.Terminal.IsInRemoteSystem = false; + Applications.Terminal.RemoteSystemName = ""; + Applications.Terminal.RemoteUser = ""; + Applications.Terminal.RemotePass = ""; + TerminalBackend.PrefixEnabled = true; + TerminalBackend.PrintPrompt(); + } + } + } + return; + } + + string currentUserName = SaveSystem.CurrentUser.Username; + + var user = SaveSystem.CurrentSave.Users.FirstOrDefault(x => x.Username == rtsMessage.Username && x.Password == rtsMessage.Password); + + if(user == null) + { + ServerManager.SendMessageToIngameServer(rtsMessage.SenderSystemName, 0, "Access denied.", "The username and password you have provided was denied."); + return; + } + else + { + SaveSystem.CurrentUser = user; + + string cmd = rtsMessage.Namespace + "." + rtsMessage.Command + JsonConvert.SerializeObject(rtsMessage.Arguments); + TerminalBackend.InvokeCommand(cmd, true); + ServerManager.SendMessageToIngameServer(rtsMessage.SenderSystemName, 1, "writeline", TerminalBackend.LastCommandBuffer); + ServerManager.SendMessageToIngameServer(rtsMessage.SenderSystemName, 1, "write", $"{rtsMessage.Username}@{SaveSystem.CurrentSave.SystemName}:~$ "); + + SaveSystem.CurrentUser = SaveSystem.Users.FirstOrDefault(x => x.Username == currentUserName); + } + } + + [Command("connect")] + [RequiresArgument("sysname")] + [RequiresArgument("username")] + [RequiresArgument("password")] + public static bool Connect(Dictionary args) + { + string sysname = args["sysname"].ToString(); + string username = args["username"].ToString(); + string password = args["password"].ToString(); + + bool connectionFinished = false; + + + new Thread(() => + { + Thread.Sleep(10000); + if (connectionFinished == false) + { + Applications.Terminal.IsInRemoteSystem = false; + Applications.Terminal.RemoteSystemName = ""; + Applications.Terminal.RemoteUser = ""; + Applications.Terminal.RemotePass = ""; + TerminalBackend.PrefixEnabled = true; + Console.WriteLine("[rts] Connection failed, target system did not respond."); + TerminalBackend.PrintPrompt(); + + } + }).Start(); + + ServerMessageReceived smr = null; + smr = (msg) => + { + if (msg.Name == "msgtosys") + { + var m = JsonConvert.DeserializeObject(msg.Contents); + if (m.GUID.Split('|')[2] != ServerManager.thisGuid.ToString()) + { + connectionFinished = true; + ServerManager.MessageReceived -= smr; + } + } + }; + ServerManager.MessageReceived += smr; + ServerManager.SendMessageToIngameServer(sysname, 21, "cmd", JsonConvert.SerializeObject(new RTSMessage + { + SenderSystemName = SaveSystem.CurrentSave.SystemName, + Username = username, + Password = password, + Namespace = "trm", + Command = "clear" + })); + Applications.Terminal.IsInRemoteSystem = true; + Applications.Terminal.RemoteSystemName = sysname; + Applications.Terminal.RemoteUser = username; + Applications.Terminal.RemotePass = password; + TerminalBackend.PrefixEnabled = false; + return true; + } + } + + [Server("Generic port 0", 0)] + public class InfoboxServer : Server + { + public void MessageReceived(ServerMessage msg) + { + Infobox.Show(msg.Name, msg.Contents); + } + } + + [Server("Generic port 1", 1)] + public class ConsoleServer : Server + { + public void MessageReceived(ServerMessage msg) + { + switch (msg.Name) + { + case "write": + Console.Write(msg.Contents); + break; + case "writeline": + Console.WriteLine(msg.Contents); + break; + } + } + } + + public class RTSMessage + { + public string SenderSystemName { get; set; } + + public string Namespace { get; set; } + public string Command { get; set; } + public Dictionary Arguments { get; set; } + + public string Username { get; set; } + public string Password { get; set; } + } +} diff --git a/ShiftOS.WinForms/ShiftOS.WinForms.csproj b/ShiftOS.WinForms/ShiftOS.WinForms.csproj index 1607ae9..e1afa84 100644 --- a/ShiftOS.WinForms/ShiftOS.WinForms.csproj +++ b/ShiftOS.WinForms/ShiftOS.WinForms.csproj @@ -70,6 +70,24 @@ About.cs + + UserControl + + + IconManager.cs + + + UserControl + + + TriPresent.cs + + + UserControl + + + TriSheet.cs + UserControl @@ -262,6 +280,12 @@ VideoPlayer.cs + + UserControl + + + WebBrowser.cs + UserControl @@ -323,6 +347,12 @@ DownloadControl.cs + + Form + + + GUILogin.cs + @@ -339,6 +369,7 @@ Resources.resx + UserControl @@ -357,9 +388,46 @@ MainHomepage.cs + + UserControl + + + ShiftGames.cs + + + UserControl + + + ShiftSoft.cs + + + UserControl + + + ShiftSoft_Ping.cs + + + UserControl + + + ShiftnetStatus.cs + + + UserControl + + + TestStatus.cs + + + UserControl + + + Volume.cs + + @@ -406,6 +474,15 @@ About.cs + + IconManager.cs + + + TriPresent.cs + + + TriSheet.cs + TriWrite.cs @@ -499,6 +576,9 @@ VideoPlayer.cs + + WebBrowser.cs + WidgetManagerFrontend.cs @@ -520,6 +600,9 @@ DownloadControl.cs + + GUILogin.cs + Oobe.cs @@ -537,6 +620,24 @@ MainHomepage.cs + + ShiftGames.cs + + + ShiftSoft.cs + + + ShiftSoft_Ping.cs + + + ShiftnetStatus.cs + + + TestStatus.cs + + + Volume.cs + UniteLoginDialog.cs @@ -748,11 +849,22 @@ + + + + + + + + + + + diff --git a/ShiftOS.WinForms/ShiftnetSites/AppscapeMain.cs b/ShiftOS.WinForms/ShiftnetSites/AppscapeMain.cs index fa575f4..c7830d0 100644 --- a/ShiftOS.WinForms/ShiftnetSites/AppscapeMain.cs +++ b/ShiftOS.WinForms/ShiftnetSites/AppscapeMain.cs @@ -372,7 +372,7 @@ namespace ShiftOS.WinForms /// public class AppscapeEntryAttribute : RequiresUpgradeAttribute { - public AppscapeEntryAttribute(string name, string description, int downloadSize, long cost, string dependencies = "", string category = "Misc") : base(name.ToLower().Replace(' ', '_')) + public AppscapeEntryAttribute(string name, string description, int downloadSize, ulong cost, string dependencies = "", string category = "Misc") : base(name.ToLower().Replace(' ', '_')) { Name = name; Description = description; @@ -385,7 +385,7 @@ namespace ShiftOS.WinForms 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 ulong Cost { get; private set; } public string DependencyString { get; private set; } public int DownloadSize { get; private set; } } diff --git a/ShiftOS.WinForms/ShiftnetSites/ShiftGames.Designer.cs b/ShiftOS.WinForms/ShiftnetSites/ShiftGames.Designer.cs new file mode 100644 index 0000000..3b4bf9e --- /dev/null +++ b/ShiftOS.WinForms/ShiftnetSites/ShiftGames.Designer.cs @@ -0,0 +1,74 @@ +namespace ShiftOS.WinForms.ShiftnetSites +{ + partial class ShiftGames + { + /// + /// 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(ShiftGames)); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + 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(571, 65); + this.label1.TabIndex = 0; + this.label1.Tag = "header2"; + this.label1.Text = "ShiftGames/Minimatch"; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // label2 + // + this.label2.Dock = System.Windows.Forms.DockStyle.Fill; + this.label2.Location = new System.Drawing.Point(0, 65); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(571, 309); + this.label2.TabIndex = 1; + this.label2.Text = resources.GetString("label2.Text"); + this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // ShiftGames + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Name = "ShiftGames"; + this.Size = new System.Drawing.Size(571, 374); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + } +} diff --git a/ShiftOS.WinForms/ShiftnetSites/ShiftGames.cs b/ShiftOS.WinForms/ShiftnetSites/ShiftGames.cs new file mode 100644 index 0000000..4ce0435 --- /dev/null +++ b/ShiftOS.WinForms/ShiftnetSites/ShiftGames.cs @@ -0,0 +1,39 @@ +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/main/shiftgames", "ShiftGames (formerly Minimatch)", "The one true Shiftnet site for virus-free, quality games.")] + public partial class ShiftGames : UserControl, IShiftnetSite + { + public ShiftGames() + { + InitializeComponent(); + } + + public event Action GoBack; + public event Action GoToUrl; + + public void OnSkinLoad() + { + ControlManager.SetupControls(this); + } + + public void OnUpgrade() + { + } + + public void Setup() + { + } + } +} diff --git a/ShiftOS.WinForms/ShiftnetSites/ShiftGames.resx b/ShiftOS.WinForms/ShiftnetSites/ShiftGames.resx new file mode 100644 index 0000000..ef8aebe --- /dev/null +++ b/ShiftOS.WinForms/ShiftnetSites/ShiftGames.resx @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + ShiftGames has been shut down as of May 2016. We have moved our inventory to the Appscape Repository. Thanks for being with us, and apologies for the inconvenience. + +Copyright (c) 2014-2016 Maureen Fenn + + \ No newline at end of file diff --git a/ShiftOS.WinForms/ShiftnetSites/ShiftSoft.Designer.cs b/ShiftOS.WinForms/ShiftnetSites/ShiftSoft.Designer.cs new file mode 100644 index 0000000..a62b5a8 --- /dev/null +++ b/ShiftOS.WinForms/ShiftnetSites/ShiftSoft.Designer.cs @@ -0,0 +1,61 @@ +namespace ShiftOS.WinForms.ShiftnetSites +{ + partial class ShiftSoft + { + /// + /// 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.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Font = new System.Drawing.Font("Franklin Gothic Heavy", 24.75F, System.Drawing.FontStyle.Italic); + this.label1.Location = new System.Drawing.Point(13, 17); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(152, 38); + this.label1.TabIndex = 0; + this.label1.Tag = "keepfont"; + this.label1.Text = "Shiftsoft"; + // + // ShiftSoft + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.label1); + this.Name = "ShiftSoft"; + this.Size = new System.Drawing.Size(523, 384); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + } +} diff --git a/ShiftOS.WinForms/ShiftnetSites/ShiftSoft.cs b/ShiftOS.WinForms/ShiftnetSites/ShiftSoft.cs new file mode 100644 index 0000000..18968cd --- /dev/null +++ b/ShiftOS.WinForms/ShiftnetSites/ShiftSoft.cs @@ -0,0 +1,38 @@ +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; + +namespace ShiftOS.WinForms.ShiftnetSites +{ + [ShiftnetSite("shiftnet/shiftsoft", "ShiftSoft", "What do you want to shift today?")] + [ShiftnetFundamental] + public partial class ShiftSoft : UserControl, IShiftnetSite + { + public ShiftSoft() + { + InitializeComponent(); + } + + public event Action GoBack; + public event Action GoToUrl; + + public void OnSkinLoad() + { + } + + public void OnUpgrade() + { + } + + public void Setup() + { + } + } +} diff --git a/ShiftOS.WinForms/ShiftnetSites/ShiftSoft.resx b/ShiftOS.WinForms/ShiftnetSites/ShiftSoft.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/ShiftOS.WinForms/ShiftnetSites/ShiftSoft.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/ShiftSoft_Ping.Designer.cs b/ShiftOS.WinForms/ShiftnetSites/ShiftSoft_Ping.Designer.cs new file mode 100644 index 0000000..244f6d4 --- /dev/null +++ b/ShiftOS.WinForms/ShiftnetSites/ShiftSoft_Ping.Designer.cs @@ -0,0 +1,89 @@ +namespace ShiftOS.WinForms.ShiftnetSites +{ + partial class ShiftSoft_Ping + { + /// + /// 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.label2 = new System.Windows.Forms.Label(); + this.fllist = new System.Windows.Forms.FlowLayoutPanel(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Dock = System.Windows.Forms.DockStyle.Top; + this.label1.Location = new System.Drawing.Point(0, 0); + this.label1.Name = "label1"; + this.label1.Padding = new System.Windows.Forms.Padding(10); + this.label1.Size = new System.Drawing.Size(48, 33); + this.label1.TabIndex = 0; + this.label1.Tag = "header2"; + this.label1.Text = "Ping"; + // + // label2 + // + this.label2.Dock = System.Windows.Forms.DockStyle.Top; + this.label2.Location = new System.Drawing.Point(0, 33); + this.label2.Name = "label2"; + this.label2.Padding = new System.Windows.Forms.Padding(10); + this.label2.Size = new System.Drawing.Size(734, 56); + this.label2.TabIndex = 1; + this.label2.Text = "Ping is a simple service that lets you see all the sites on the shiftnet/ cluster" + + ". These sites are safe for you to use and do not contain malware or other threat" + + "s."; + // + // fllist + // + this.fllist.Dock = System.Windows.Forms.DockStyle.Fill; + this.fllist.FlowDirection = System.Windows.Forms.FlowDirection.TopDown; + this.fllist.Location = new System.Drawing.Point(0, 89); + this.fllist.Name = "fllist"; + this.fllist.Size = new System.Drawing.Size(734, 389); + this.fllist.TabIndex = 2; + // + // ShiftSoft_Ping + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.fllist); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Name = "ShiftSoft_Ping"; + this.Size = new System.Drawing.Size(734, 478); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.FlowLayoutPanel fllist; + } +} diff --git a/ShiftOS.WinForms/ShiftnetSites/ShiftSoft_Ping.cs b/ShiftOS.WinForms/ShiftnetSites/ShiftSoft_Ping.cs new file mode 100644 index 0000000..1593117 --- /dev/null +++ b/ShiftOS.WinForms/ShiftnetSites/ShiftSoft_Ping.cs @@ -0,0 +1,97 @@ +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 System.Reflection; +using System.IO; +using ShiftOS.Engine; +using ShiftOS.WinForms.Tools; + +namespace ShiftOS.WinForms.ShiftnetSites +{ + [ShiftnetSite("shiftnet/shiftsoft/ping", "Ping", "A site listing hosted by ShiftSoft.")] + public partial class ShiftSoft_Ping : UserControl, IShiftnetSite + { + public ShiftSoft_Ping() + { + InitializeComponent(); + } + + public event Action GoBack; + public event Action GoToUrl; + + public void OnSkinLoad() + { + ControlManager.SetupControls(this); + SetupListing(); + } + + public void SetupListing() + { + fllist.Controls.Clear(); + foreach(var exec in Directory.GetFiles(Environment.CurrentDirectory)) + { + if(exec.ToLower().EndsWith(".exe") || exec.ToLower().EndsWith(".dll")) + { + try + { + var asm = Assembly.LoadFile(exec); + var types = asm.GetTypes(); + foreach (var type in types) + { + if (type.GetInterfaces().Contains(typeof(IShiftnetSite))) + { + var attr = type.GetCustomAttributes(false).FirstOrDefault(x => x is ShiftnetSiteAttribute) as ShiftnetSiteAttribute; + if (attr != null) + { + if (attr.Url.StartsWith("shiftnet/")) + { + var lnk = new LinkLabel(); + lnk.LinkColor = SkinEngine.LoadedSkin.ControlTextColor; + lnk.Text = attr.Name; + var desc = new Label(); + desc.AutoSize = true; + lnk.AutoSize = true; + desc.MaximumSize = new Size(this.Width / 3, 0); + desc.Text = attr.Description; + desc.Padding = new Padding + { + Bottom = 25, + Top = 0, + Left = 10, + Right = 10 + }; + lnk.Click += (o, a) => + { + GoToUrl?.Invoke(attr.Url); + }; + fllist.Controls.Add(lnk); + fllist.Controls.Add(desc); + ControlManager.SetupControls(lnk); + lnk.Show(); + desc.Show(); + } + } + } + } + } + catch { } + } + } + } + + public void OnUpgrade() + { + } + + public void Setup() + { + SetupListing(); + } + } +} diff --git a/ShiftOS.WinForms/ShiftnetSites/ShiftSoft_Ping.resx b/ShiftOS.WinForms/ShiftnetSites/ShiftSoft_Ping.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/ShiftOS.WinForms/ShiftnetSites/ShiftSoft_Ping.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/StatusIcons/ShiftnetStatus.Designer.cs b/ShiftOS.WinForms/StatusIcons/ShiftnetStatus.Designer.cs new file mode 100644 index 0000000..65aed28 --- /dev/null +++ b/ShiftOS.WinForms/StatusIcons/ShiftnetStatus.Designer.cs @@ -0,0 +1,90 @@ +namespace ShiftOS.WinForms.StatusIcons +{ + partial class ShiftnetStatus + { + /// + /// 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.lbserviceprovider = new System.Windows.Forms.Label(); + this.lbstatus = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Dock = System.Windows.Forms.DockStyle.Top; + this.label1.Location = new System.Drawing.Point(0, 0); + this.label1.Name = "label1"; + this.label1.Padding = new System.Windows.Forms.Padding(5); + this.label1.Size = new System.Drawing.Size(53, 23); + this.label1.TabIndex = 0; + this.label1.Tag = "header2"; + this.label1.Text = "Shiftnet"; + // + // lbserviceprovider + // + this.lbserviceprovider.AutoSize = true; + this.lbserviceprovider.Dock = System.Windows.Forms.DockStyle.Top; + this.lbserviceprovider.Location = new System.Drawing.Point(0, 23); + this.lbserviceprovider.Name = "lbserviceprovider"; + this.lbserviceprovider.Padding = new System.Windows.Forms.Padding(5); + this.lbserviceprovider.Size = new System.Drawing.Size(98, 23); + this.lbserviceprovider.TabIndex = 1; + this.lbserviceprovider.Tag = "header3"; + this.lbserviceprovider.Text = "Freebie Solutions"; + // + // lbstatus + // + this.lbstatus.Dock = System.Windows.Forms.DockStyle.Fill; + this.lbstatus.Location = new System.Drawing.Point(0, 46); + this.lbstatus.Name = "lbstatus"; + this.lbstatus.Padding = new System.Windows.Forms.Padding(5); + this.lbstatus.Size = new System.Drawing.Size(331, 144); + this.lbstatus.TabIndex = 2; + this.lbstatus.Text = "This will show the Shiftnet status."; + // + // ShiftnetStatus + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.lbstatus); + this.Controls.Add(this.lbserviceprovider); + this.Controls.Add(this.label1); + this.Name = "ShiftnetStatus"; + this.Size = new System.Drawing.Size(331, 190); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label lbserviceprovider; + private System.Windows.Forms.Label lbstatus; + } +} diff --git a/ShiftOS.WinForms/StatusIcons/ShiftnetStatus.cs b/ShiftOS.WinForms/StatusIcons/ShiftnetStatus.cs new file mode 100644 index 0000000..f1d31af --- /dev/null +++ b/ShiftOS.WinForms/StatusIcons/ShiftnetStatus.cs @@ -0,0 +1,33 @@ +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; + +namespace ShiftOS.WinForms.StatusIcons +{ + [DefaultIcon("iconShiftnet")] + [RequiresUpgrade("victortran_shiftnet")] + public partial class ShiftnetStatus : UserControl, IStatusIcon + { + public ShiftnetStatus() + { + InitializeComponent(); + } + + public void Setup() + { + var subscription = Applications.DownloadManager.GetAllSubscriptions()[SaveSystem.CurrentSave.ShiftnetSubscription]; + float kilobytes = (float)subscription.DownloadSpeed / 1024F; + lbserviceprovider.Text = subscription.Name; + lbstatus.Text = $@"Company: {subscription.Company} +Download speed (KB/s): {kilobytes}"; + + } + } +} diff --git a/ShiftOS.WinForms/StatusIcons/ShiftnetStatus.resx b/ShiftOS.WinForms/StatusIcons/ShiftnetStatus.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/ShiftOS.WinForms/StatusIcons/ShiftnetStatus.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/StatusIcons/TestStatus.Designer.cs b/ShiftOS.WinForms/StatusIcons/TestStatus.Designer.cs new file mode 100644 index 0000000..3643d2d --- /dev/null +++ b/ShiftOS.WinForms/StatusIcons/TestStatus.Designer.cs @@ -0,0 +1,60 @@ +namespace ShiftOS.WinForms.StatusIcons +{ + partial class TestStatus + { + /// + /// 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.SuspendLayout(); + // + // label1 + // + this.label1.Dock = System.Windows.Forms.DockStyle.Fill; + this.label1.Location = new System.Drawing.Point(0, 0); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(264, 52); + this.label1.TabIndex = 0; + this.label1.Tag = "header1"; + this.label1.Text = "This is a test."; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // TestStatus + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.label1); + this.Name = "TestStatus"; + this.Size = new System.Drawing.Size(264, 52); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Label label1; + } +} diff --git a/ShiftOS.WinForms/StatusIcons/TestStatus.cs b/ShiftOS.WinForms/StatusIcons/TestStatus.cs new file mode 100644 index 0000000..90baafc --- /dev/null +++ b/ShiftOS.WinForms/StatusIcons/TestStatus.cs @@ -0,0 +1,26 @@ +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; + +namespace ShiftOS.WinForms.StatusIcons +{ + [DefaultIcon("iconShiftorium")] + public partial class TestStatus : UserControl, IStatusIcon + { + public TestStatus() + { + InitializeComponent(); + } + + public void Setup() + { + } + } +} diff --git a/ShiftOS.WinForms/StatusIcons/TestStatus.resx b/ShiftOS.WinForms/StatusIcons/TestStatus.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/ShiftOS.WinForms/StatusIcons/TestStatus.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/StatusIcons/Volume.Designer.cs b/ShiftOS.WinForms/StatusIcons/Volume.Designer.cs new file mode 100644 index 0000000..aa8aa7a --- /dev/null +++ b/ShiftOS.WinForms/StatusIcons/Volume.Designer.cs @@ -0,0 +1,59 @@ +namespace ShiftOS.WinForms.StatusIcons +{ + partial class Volume + { + /// + /// 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.lbvolume = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // lbvolume + // + this.lbvolume.AutoSize = true; + this.lbvolume.Location = new System.Drawing.Point(4, 4); + this.lbvolume.Name = "lbvolume"; + this.lbvolume.Size = new System.Drawing.Size(81, 13); + this.lbvolume.TabIndex = 0; + this.lbvolume.Text = "System volume:"; + // + // Volume + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.lbvolume); + this.Name = "Volume"; + this.Size = new System.Drawing.Size(444, 44); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label lbvolume; + } +} diff --git a/ShiftOS.WinForms/StatusIcons/Volume.cs b/ShiftOS.WinForms/StatusIcons/Volume.cs new file mode 100644 index 0000000..329faf0 --- /dev/null +++ b/ShiftOS.WinForms/StatusIcons/Volume.cs @@ -0,0 +1,67 @@ +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.Controls; + +namespace ShiftOS.WinForms.StatusIcons +{ + [DefaultIcon("iconSpeaker")] + public partial class Volume : UserControl, IStatusIcon + { + public Volume() + { + InitializeComponent(); + } + + public void Setup() + { + lbvolume.Top = (this.Height - lbvolume.Height) / 2; + bool moving = false; + var prg = new ShiftedProgressBar(); + prg.Tag = "ignoreal"; //Don't close AL or current widget when this control is clicked. + this.Controls.Add(prg); + prg.Height = this.Height / 3; + prg.Maximum = 100; + prg.Value = SaveSystem.CurrentSave.MusicVolume; + prg.Width = this.Width - lbvolume.Width - 50; + prg.Left = lbvolume.Left + lbvolume.Width + 15; + prg.Top = (this.Height - prg.Height) / 2; + prg.MouseDown += (o, a) => + { + moving = true; + }; + + prg.MouseMove += (o, a) => + { + if (moving) + { + int val = (int)linear(a.X, 0, prg.Width, 0, 100); + SaveSystem.CurrentSave.MusicVolume = val; + prg.Value = val; + } + }; + + prg.MouseUp += (o, a) => + { + moving = false; + }; + prg.Show(); + } + + static public double linear(double x, double x0, double x1, double y0, double y1) + { + if ((x1 - x0) == 0) + { + return (y0 + y1) / 2; + } + return y0 + (x - x0) * (y1 - y0) / (x1 - x0); + } + } +} diff --git a/ShiftOS.WinForms/StatusIcons/Volume.resx b/ShiftOS.WinForms/StatusIcons/Volume.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/ShiftOS.WinForms/StatusIcons/Volume.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/Stories/DevXSkinningStory.cs b/ShiftOS.WinForms/Stories/DevXSkinningStory.cs new file mode 100644 index 0000000..09dfd7f --- /dev/null +++ b/ShiftOS.WinForms/Stories/DevXSkinningStory.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using ShiftOS.Engine; + +namespace ShiftOS.WinForms.Stories +{ + public class DevXSkinningStory + { + [Story("devx_1000_codepoints")] + public static void DevX1000CPStory() + { + Desktop.InvokeOnWorkerThread(() => + { + var t = new Applications.Terminal(); + AppearanceManager.SetupWindow(t); + }); + TerminalBackend.InStory = true; + TerminalBackend.PrefixEnabled = false; + Thread.Sleep(3000); + Engine.AudioManager.PlayStream(Properties.Resources._3beepvirus); + Console.WriteLine("devx@anon_127420: Connection established."); + Thread.Sleep(1500); + Console.WriteLine("DevX: Hello, " + SaveSystem.CurrentUser.Username + "@" + SaveSystem.CurrentSave.SystemName + "! I see you've gotten a decent amount of Codepoints."); + Thread.Sleep(2000); + Console.WriteLine("DevX: Have you gotten a chance to install my \"Shifter\" application yet?"); + Thread.Sleep(1500); + if (!Shiftorium.UpgradeInstalled("shifter")) + { + Console.WriteLine("You: Not yet. What's it for?"); + Thread.Sleep(2000); + Console.WriteLine("DevX: The Shifter is a very effective way to make ShiftOS look however you want it to."); + Thread.Sleep(2000); + Console.WriteLine("DevX: It can even be adapted to support other applications, features and upgrades."); + Thread.Sleep(2000); + } + else + { + Console.WriteLine("You: Yeah. Just seems kinda lackluster to me. What is it supposed to do?"); + Thread.Sleep(2000); + Console.WriteLine("DevX: The Shifter is a very effective way to make ShiftOS look however you want it to."); + Thread.Sleep(2000); + Console.WriteLine("DevX: It can even be adapted to support other applications, features and upgrades."); + Thread.Sleep(2000); + Console.WriteLine("DevX: I haven't finished it just yet. Keep upgrading it and you'll notice it gets a lot better."); + Thread.Sleep(2000); + } + Console.WriteLine("DevX: I'd also recommend going for the Skin Loader, that way you can save your creations to the disk. Also, go for the Skinning upgrade - which will allow more rich customization of certain elements."); + Thread.Sleep(2000); + Console.WriteLine("You: This still ain't gonna help me get back to my old system and out of this stupid Digital Society, is it?"); + Thread.Sleep(2000); + Console.WriteLine("DevX: How the...How do you know about the Digital Societ....Who the hell talked!?"); + Thread.Sleep(2000); + Console.WriteLine("You: Whoa! Just... calm down, will ya? I heard about it in the news, shortly before I got infected by this damn virus of an operating system."); + Thread.Sleep(2000); + Console.WriteLine("DevX: Whatever. That doesn't matter yet. Just focus on upgrading ShiftOS and earning Codepoints. I'll let you know when we're done. I've gotta go...work on something else."); + Thread.Sleep(1500); + Console.WriteLine("User disconnected."); + Thread.Sleep(2000); + Console.WriteLine("You: Something doesn't seem right about DevX. I wonder what he's really up to."); + + if (Shiftorium.UpgradeInstalled("shifter")) + PushObjectives(); + else + Story.PushObjective("Buy the Shifter.", "The Shifter is a super-effective way to earn more Codepoints. It is an essential buy if you haven't already bought it. Save up for the Shifter, and buy it using shiftorium.buy{upgrade:\"shifter\"}.", () => + { + return Shiftorium.UpgradeInstalled("shifter"); + }, () => + { + PushObjectives(); + }); + Story.Context.AutoComplete = false; + TerminalBackend.InStory = false; + TerminalBackend.PrefixEnabled = false; + TerminalBackend.PrintPrompt(); + } + + public static void PushObjectives() + { + Story.PushObjective("Buy the Skinning upgrade", "The Skinning upgrade will allow you to set pictures in place of solid colors for most UI elements. If you want richer customization and more Codepoints, this upgrade is a necessity.", () => + { + return Shiftorium.UpgradeInstalled("skinning"); + }, ()=> + { + Story.PushObjective("Buy the Skin Loader.", "The Skin Loader is an application that allows you to save and load .skn files containing Shifter skin data. These files can be loaded in to the Skin Loader and applied to the system to give ShiftOS a completely different feel. It's Shiftorium upgrade ID is \"skin_loader\".", () => + { + return Shiftorium.UpgradeInstalled("skin_loader"); + }, + () => + { + Story.Context.MarkComplete(); + }); + }); + } + } +} diff --git a/ShiftOS.WinForms/Stories/LegionStory.cs b/ShiftOS.WinForms/Stories/LegionStory.cs index 9b4966f..056fe85 100644 --- a/ShiftOS.WinForms/Stories/LegionStory.cs +++ b/ShiftOS.WinForms/Stories/LegionStory.cs @@ -16,8 +16,8 @@ namespace ShiftOS.WinForms.Stories [Story("victortran_shiftnet")] public static void ShiftnetStoryFeaturingTheBlueSmileyFaceHolyFuckThisFunctionNameIsLong() { - CharacterName = "victor_tran"; - SysName = "theos"; + CharacterName = "aiden"; + SysName = "appscape_main"; bool waiting = false; var installer = new Applications.Installer(); installer.InstallCompleted += () => @@ -35,47 +35,107 @@ namespace ShiftOS.WinForms.Stories AppearanceManager.SetupWindow(term); } - var t = new Thread(() => + WriteLine("aiden@appscape_main - user connecting to your system.", false); + Thread.Sleep(2000); + WriteLine("Hello there! My name's Aiden Nirh."); + WriteLine("I run a small Shiftnet website known simply as \"Appscape\"."); + WriteLine("Oh - wait... you don't know what the Shiftnet is..."); + WriteLine("Well, the Shiftnet is like... a private Internet, only accessible through ShiftOS."); + WriteLine("It has many sites and companies on it - banks, software centres, service providers, you name it."); + WriteLine("Appscape is one of them. I host many applications on Appscape, from games to utilities to productivity programs, and anything in between. If it exists as a ShiftOS program, it's either on the Shiftorium or Appscape."); + WriteLine("I'm going to assume you're interested... and I'll install the Shiftnet just in case."); + WriteLine("Beginning installation of Shiftnet..."); + //Set up an Installer. + waiting = true; + Desktop.InvokeOnWorkerThread(() => { - WriteLine("victortran@theos - user connecting to your system.", false); - Thread.Sleep(2000); - WriteLine("Hey there - yes, I am not just a sentient being. I am indeed Victor Tran."); - WriteLine("I am the creator of a Linux desktop environment called theShell."); - WriteLine("I'm in the middle of working on a ShiftOS version of it."); - WriteLine("However, before I start, I feel I need to show you something."); - WriteLine("You have a lot of ShiftOS applications, and you can earn lots of Codepoints - and you already have lots."); - WriteLine("Well, you'd be a perfect candidate for me to install the Shiftnet Client on your system."); - WriteLine("I'll begin the installation right now."); - //Set up an Installer. - waiting = true; - Desktop.InvokeOnWorkerThread(() => - { - Story.Start("installer"); - AppearanceManager.SetupWindow(installer); - installer.InitiateInstall(new ShiftnetInstallation()); - }); - while (waiting == true) - Thread.Sleep(25); + SaveSystem.CurrentSave.StoriesExperienced.Add("installer"); + SaveSystem.CurrentSave.StoriesExperienced.Add("downloader"); - WriteLine("All installed! Once I disconnect, type win.open to see a list of your new apps."); - WriteLine("The Shiftnet is a vast network of websites only accessible through ShiftOS."); - WriteLine("Think of it as the DarkNet, but much darker, and much more secretive."); - WriteLine("There are lots of apps, games, skins and utilities on the Shiftnet."); - WriteLine("There are also lots of companies offering many services."); - WriteLine("I'd stay on the shiftnet/ cluster though, others may be dangerous."); - WriteLine("I'd also stick to the sites listed on shiftnet/shiftsoft/ping - that site is regularly updated with the most safe Shiftnet sites."); - WriteLine("Anyways, it was nice meeting you, hopefully someday you'll give theShell a try."); + while (!Shiftorium.UpgradeInstalled("installer")) + Thread.Sleep(20); + AppearanceManager.SetupWindow(installer); + installer.InitiateInstall(new ShiftnetInstallation()); + }); + while (waiting == true) + Thread.Sleep(25); + + WriteLine("All good to go! Once I disconnect, type win.open to see a list of your new apps."); + WriteLine("I've installed everything you need, for free."); + WriteLine("You've got the Downloader, a simple application to help you track Shiftnet file downloads..."); + WriteLine("...the Installer which will help you unpack programs from .stp files and install them to your system..."); + WriteLine("...and lastly, the Shiftnet browser itself. This program lets you browse the Shiftnet, much like you would the real Internet."); + WriteLine("I'd stay on the shiftnet/ cluster though, because although there are many services on the Shiftnet, some of them may try to scam you into losing loads of Codepoints, or worse, wrecking your system with viruses."); + WriteLine("If you want a nice list of safe Shiftnet services, head to ShiftSoft's \"Ping\" site, at shiftnet/shiftsoft/ping."); + WriteLine("Oh, also, the Shiftnet, much like the real internet, is not free."); + WriteLine("It requires a service provider. Service providers cost a fair amount of Codepoints, but if you want to get faster speeds and more reliable connections on the Shiftnet, finding a good service provider is a necessity."); + WriteLine("Right now, you are on ShiftSoft's free trial plan, Freebie Solutions, which gives you access to the Shiftnet however you are locked at 256 bytes per second file downloads and can't leave the shiftnet/ cluster."); + WriteLine("It's enough to get you started - you'll want to find a faster provider though.."); + WriteLine("Anyways, that's all I'll say for now. Have fun on the Shiftnet. I have to go work on something."); + WriteLine("One of my friends'll contact you once you've gotten a new service provider."); + + Story.PushObjective("Register with a new Shiftnet service provider.", "You've just unlocked the Shiftnet, which has opened up a whole new world of applications and features for ShiftOS. Before you go nuts with it, you may want to register with a better service provider than Freebie Solutions.", () => + { + return SaveSystem.CurrentSave.ShiftnetSubscription != 0; + }, + () => + { + Story.Context.MarkComplete(); + SaveSystem.SaveGame(); + TerminalBackend.PrintPrompt(); + Story.Start("hacker101_breakingbonds_1"); + }); TerminalBackend.PrefixEnabled = true; - TerminalBackend.PrintPrompt(); - }); - t.IsBackground = true; - t.Start(); + TerminalBackend.PrintPrompt(); - TerminalBackend.PrefixEnabled = false; + Story.Context.AutoComplete = false; + } + + [Story("hacker101_breakingbonds_1")] + public static void BreakingTheBondsIntro() + { + CharacterName = "hacker101"; + SysName = "pebcak"; + + if (!terminalOpen()) + { + var term = new Applications.Terminal(); + AppearanceManager.SetupWindow(term); + } + + WriteLine("hacker101@pebcak - user connecting to your system.", false); + Thread.Sleep(2000); + WriteLine("Greetings, user."); + WriteLine("My name is hacker101. I have a few things to show you."); + WriteLine("Before I can do that, however, I need you to do a few things."); + WriteLine("I'll assign what I need you to do as an objective. When you're done, I'll tell you what you need to know."); + + Story.PushObjective("Breaking the Bonds: Errand Boy", @"hacker101 has something he needs to show you, however before he can, you need to do the following: + + - Buy ""TriWrite"" from Appscape + - Buy ""Address Book"" from Appscape + - Buy ""SimpleSRC"" from Appscape", () => + { + bool flag1 = Shiftorium.UpgradeInstalled("address_book"); + bool flag2 = Shiftorium.UpgradeInstalled("triwrite"); + bool flag3 = Shiftorium.UpgradeInstalled("simplesrc"); + return flag1 && flag2 && flag3; + }, () => + { + Story.Context.MarkComplete(); + SaveSystem.SaveGame(); + Story.Start("hacker101_breakingbonds_2"); + }); + + TerminalBackend.PrefixEnabled = true; + TerminalBackend.PrintPrompt(); + + Story.Context.AutoComplete = false; } + private static void WriteLine(string text, bool showCharacterName=true) { Console.WriteLine(); @@ -84,21 +144,22 @@ namespace ShiftOS.WinForms.Stories ConsoleEx.Bold = true; ConsoleEx.ForegroundColor = ConsoleColor.DarkMagenta; Console.Write(CharacterName); + ConsoleEx.OnFlush?.Invoke(); Console.ForegroundColor = ConsoleColor.White; Console.Write("@"); + ConsoleEx.OnFlush?.Invoke(); ConsoleEx.ForegroundColor = ConsoleColor.Yellow; Console.Write(SysName + ": "); + ConsoleEx.OnFlush?.Invoke(); } ConsoleEx.ForegroundColor = ConsoleColor.Gray; ConsoleEx.Bold = false; - foreach (var c in text) + foreach(var c in text) { - Desktop.InvokeOnWorkerThread(() => - { - Console.Write(c); - }); - Thread.Sleep(75); + Console.Write(c); + ConsoleEx.OnFlush?.Invoke(); + Thread.Sleep(45); } Thread.Sleep(1000); } @@ -149,7 +210,7 @@ namespace ShiftOS.WinForms.Stories { WriteLine("DevX@mud - user connecting to your system.", false); Thread.Sleep(2000); - WriteLine($"Hello, {SaveSystem.CurrentSave.Username}. It's been a while."); + WriteLine($"Hello, {SaveSystem.CurrentUser.Username}. It's been a while."); WriteLine("My intelligence suggests you've installed all GUI-based Shiftorium upgrades."); WriteLine("Bet you're liking ShiftOS now that the terminal isn't the only way you can control it."); WriteLine("Well, now it's time to introduce your next task."); @@ -307,7 +368,7 @@ namespace ShiftOS.WinForms.Stories SetProgress(i); Thread.Sleep(100); } - Story.Start("downloader"); + SaveSystem.CurrentSave.StoriesExperienced.Add("downloader"); SetProgress(0); SetStatus("Dependencies installed."); Thread.Sleep(2000); diff --git a/ShiftOS.WinForms/Tools/ControlManager.cs b/ShiftOS.WinForms/Tools/ControlManager.cs index 3d66b2b..7fbfd1b 100644 --- a/ShiftOS.WinForms/Tools/ControlManager.cs +++ b/ShiftOS.WinForms/Tools/ControlManager.cs @@ -1,3 +1,4 @@ + /* * MIT License * @@ -136,84 +137,140 @@ namespace ShiftOS.WinForms.Tools /// 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 - ); + try + { + ctrl.Location = new Point( + (ctrl.Parent.Width - ctrl.Width) / 2, + (ctrl.Parent.Height - ctrl.Height) / 2 + ); + } + catch { } } public static void SetupControl(Control ctrl) { - Desktop.InvokeOnWorkerThread(new Action(() => + Desktop.InvokeOnWorkerThread(() => { - ctrl.SuspendLayout(); - })); - if (!(ctrl is MenuStrip) && !(ctrl is ToolStrip) && !(ctrl is StatusStrip) && !(ctrl is ContextMenuStrip)) - { - string tag = ""; - - try + if (!(ctrl is MenuStrip) && !(ctrl is ToolStrip) && !(ctrl is StatusStrip) && !(ctrl is ContextMenuStrip)) { - if(ctrl.Tag != null) - tag = ctrl.Tag.ToString(); - } - catch { } + string tag = ""; - if (!tag.Contains("keepbg")) - { - if (ctrl.BackColor != Control.DefaultBackColor) + try { - Desktop.InvokeOnWorkerThread(() => + if (ctrl.Tag != null) + tag = ctrl.Tag.ToString(); + } + catch { } + + if (!tag.Contains("ignoreal")) + { + ctrl.Click += (o, a) => + { + Desktop.HideAppLauncher(); + }; + + } + + if (!tag.Contains("keepbg")) + { + if (ctrl.BackColor != Control.DefaultBackColor) { ctrl.BackColor = SkinEngine.LoadedSkin.ControlColor; - }); + } } - } - if (!tag.Contains("keepfont")) - { - Desktop.InvokeOnWorkerThread(() => + if (!tag.Contains("keepfont")) { ctrl.ForeColor = SkinEngine.LoadedSkin.ControlTextColor; ctrl.Font = SkinEngine.LoadedSkin.MainFont; - }); - if (tag.Contains("header1")) - { - Desktop.InvokeOnWorkerThread(() => + if (tag.Contains("header1")) { - ctrl.Font = SkinEngine.LoadedSkin.HeaderFont; - }); - } + Desktop.InvokeOnWorkerThread(() => + { + ctrl.Font = SkinEngine.LoadedSkin.HeaderFont; + }); + } - if (tag.Contains("header2")) - { - Desktop.InvokeOnWorkerThread(() => + if (tag.Contains("header2")) { ctrl.Font = SkinEngine.LoadedSkin.Header2Font; - }); - } + } - if (tag.Contains("header3")) - { - Desktop.InvokeOnWorkerThread(() => + if (tag.Contains("header3")) { ctrl.Font = SkinEngine.LoadedSkin.Header3Font; - }); + } + } + try + { +#if !SLOW_LOCALIZATION + if (!string.IsNullOrWhiteSpace(ctrl.Text)) + { + string ctrlText = Localization.Parse(ctrl.Text); + ctrl.Text = ctrlText; + } +#endif + } + catch + { + + } + + if (ctrl is Button) + { + Button b = ctrl as Button; + if (!tag.Contains("keepbg")) + { + b.BackColor = SkinEngine.LoadedSkin.ButtonBackgroundColor; + b.BackgroundImage = SkinEngine.GetImage("buttonidle"); + b.BackgroundImageLayout = SkinEngine.GetImageLayout("buttonidle"); + } + b.FlatAppearance.BorderSize = SkinEngine.LoadedSkin.ButtonBorderWidth; + if (!tag.Contains("keepfg")) + { + b.FlatAppearance.BorderColor = SkinEngine.LoadedSkin.ButtonForegroundColor; + b.ForeColor = SkinEngine.LoadedSkin.ButtonForegroundColor; + } + if (!tag.Contains("keepfont")) + b.Font = SkinEngine.LoadedSkin.ButtonTextFont; + + Color orig_bg = b.BackColor; + + b.MouseEnter += (o, a) => + { + b.BackColor = SkinEngine.LoadedSkin.ButtonHoverColor; + b.BackgroundImage = SkinEngine.GetImage("buttonhover"); + b.BackgroundImageLayout = SkinEngine.GetImageLayout("buttonhover"); + }; + b.MouseLeave += (o, a) => + { + b.BackColor = orig_bg; + b.BackgroundImage = SkinEngine.GetImage("buttonidle"); + b.BackgroundImageLayout = SkinEngine.GetImageLayout("buttonidle"); + }; + b.MouseUp += (o, a) => + { + b.BackColor = orig_bg; + b.BackgroundImage = SkinEngine.GetImage("buttonidle"); + b.BackgroundImageLayout = SkinEngine.GetImageLayout("buttonidle"); + }; + + b.MouseDown += (o, a) => + { + b.BackColor = SkinEngine.LoadedSkin.ButtonPressedColor; + b.BackgroundImage = SkinEngine.GetImage("buttonpressed"); + b.BackgroundImageLayout = SkinEngine.GetImageLayout("buttonpressed"); + + }; } } - try - { - string ctrlText = Localization.Parse(ctrl.Text); - Desktop.InvokeOnWorkerThread(() => - { - ctrl.Text = ctrlText; - }); - } - catch - { + if (ctrl is TextBox) + { + (ctrl as TextBox).BorderStyle = BorderStyle.FixedSingle; } + ctrl.KeyDown += (o, a) => { if (a.Control && a.KeyCode == Keys.T) @@ -229,28 +286,21 @@ namespace ShiftOS.WinForms.Tools }; if (ctrl is Button) { - Desktop.InvokeOnWorkerThread(() => - { - (ctrl as Button).FlatStyle = FlatStyle.Flat; - }); + (ctrl as Button).FlatStyle = FlatStyle.Flat; } else if (ctrl is WindowBorder) { - Desktop.InvokeOnWorkerThread(() => - { - (ctrl as WindowBorder).Setup(); - }); + (ctrl as WindowBorder).Setup(); } - } - Desktop.InvokeOnWorkerThread(() => - { + MakeDoubleBuffered(ctrl); - ctrl.ResumeLayout(); + ControlSetup?.Invoke(ctrl); }); - ControlSetup?.Invoke(ctrl); } + + public static event Action ControlSetup; public static void MakeDoubleBuffered(Control c) @@ -270,30 +320,12 @@ namespace ShiftOS.WinForms.Tools public static void SetupControls(Control frm, bool runInThread = true) { + var ctrls = frm.Controls.ToList(); + for (int i = 0; i < ctrls.Count(); i++) + { + SetupControls(ctrls[i]); + } SetupControl(frm); - frm.Click += (o, a) => - { - Desktop.HideAppLauncher(); - }; - ThreadStart ts = () => - { - for (int i = 0; i < frm.Controls.Count; i++) - { - SetupControls(frm.Controls[i], false); - } - - }; - - if (runInThread == true) - { - var t = new Thread(ts); - t.IsBackground = true; - t.Start(); - } - else - { - ts?.Invoke(); - } } } diff --git a/ShiftOS.WinForms/Tools/DitheringEngine.cs b/ShiftOS.WinForms/Tools/DitheringEngine.cs index 8509a0b..d042a40 100644 --- a/ShiftOS.WinForms/Tools/DitheringEngine.cs +++ b/ShiftOS.WinForms/Tools/DitheringEngine.cs @@ -33,6 +33,7 @@ using System.Drawing; using System.Threading; using ShiftOS.Engine; using System.Runtime.InteropServices; +using System.IO; namespace ShiftOS.WinForms.Tools { @@ -101,7 +102,7 @@ namespace ShiftOS.WinForms.Tools } } - public static void DitherColor(Color source, int width, int height, Action result) + public static Image DitherColor(Color source, int width, int height) { var bmp = new Bitmap(width + 1, height + 1); var data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb); @@ -115,7 +116,7 @@ namespace ShiftOS.WinForms.Tools } Marshal.Copy(rgb, 0, data.Scan0, rgb.Length); bmp.UnlockBits(data); - DitherImage(bmp, result); + return DitherImage(bmp); } @@ -225,16 +226,56 @@ namespace ShiftOS.WinForms.Tools } #endif -#if FLOYDSTEINBERG - public static void DitherImage(Image source, Action result) + public static int GetClosestColor(int gray, bool eightBits, bool sixBits, bool fourBits, bool twoBits) { - if (source == null) + int newgray = gray; + if (!eightBits) { - result?.Invoke(source); - return; + if (sixBits) + { + newgray = gray >> 2; + } + else + { + if (fourBits) + { + newgray = (int)linear(gray, 0, 255, 0, 15) * 4; + } + else + { + if (twoBits) + { + if (gray > 127 + 63) + { + newgray = 255; + } + else if (gray > 127) + newgray = 127 + 63; + else if (gray > 63) + { + newgray = 127; + } + else if (gray > 0) + newgray = 63; + else + newgray = 0; + } + else + { + if (gray > 127) + newgray = 255; + else + newgray = 0; + } + } + } } + return newgray; + } - +#if FLOYDSTEINBERG + public static Image DitherImage(Image source) + { var bmp = new Bitmap(source.Width, source.Height); var sourceBmp = (Bitmap)source; var sourceLck = sourceBmp.LockBits(new Rectangle(0, 0, sourceBmp.Width, sourceBmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb); @@ -266,122 +307,84 @@ namespace ShiftOS.WinForms.Tools bool eightBits = Shiftorium.UpgradeInstalled("color_depth_8_bits"); bool color_depth_floydsteinberg = Shiftorium.UpgradeInstalled("color_depth_floyd-steinberg_dithering"); bool dithering = Shiftorium.UpgradeInstalled("color_depth_dithering"); - - for (int y = 0; y < (destLck.Height); y++) + bool twentyfourbits = Shiftorium.UpgradeInstalled("color_depth_24_bits"); + if (twentyfourbits) { - for (int x = 0; x < (Math.Abs(destLck.Stride)); x += 3) + sourceArr.CopyTo(destArr, 0); + } + else + { + + if (!sixteenBits) { - int i = getIndexFromXY(x, y, width); - byte red = sourceArr[i]; - byte green = sourceArr[i + 1]; - byte blue = sourceArr[i + 2]; - - Color oldc = Color.FromArgb(red, green, blue); - Color newc; - - if (sixteenBits) + if (dithering == true) { - newc = GetColor(oldc); - } - else - { - int gray = ((oldc.R + oldc.G + oldc.B) / 3); - - byte newgray = 0; - - if (dithering && !color_depth_floydsteinberg) - gray += error_r; - - - - if (eightBits) + if (false == true) { - newgray = (byte)gray; - error_r = 0; - } - else if(sixBits) - { - newgray = (byte)(linear(gray, 0, 0xFF, 0, 0x3F) * 3); - error_r = newgray - gray; - } - else if (fourBits) - { - newgray = (byte)(linear(gray, 0, 0xFF, 0, 0xF) * 0xF); - error_r = newgray - gray; - } - else if (twoBits) - { - if (gray >= 191) - newgray = 0xFF; - else if (gray >= 127) - newgray = Color.LightGray.R; - else if (gray >= 64) - newgray = Color.DarkGray.R; - else - newgray = 0x00; - error_r = newgray - gray; + } else { - if (gray >= 127) - newgray = 0xFF; - else - newgray = 0x00; - error_r = newgray - gray; + int error = 0; + for (int i = 0; i < destArr.Length; i += 3) + { + byte r = sourceArr[i]; + byte g = sourceArr[i + 1]; + byte b = sourceArr[i + 2]; + + if (SkinEngine.LoadedSkin.SystemKey == Color.FromArgb(r, g, b)) + { + destArr[i] = r; + destArr[i + 1] = g; + destArr[i + 2] = b; + continue; + } + + + int gray = (((r + g + b) / 3) + error); + int newgray = gray; + newgray = GetClosestColor(gray, eightBits, sixBits, fourBits, twoBits); + if (newgray > 255) + newgray = 255; + if (newgray < 0) + newgray = 0; + error = gray - newgray; + destArr[i] = (byte)newgray; + destArr[i + 1] = (byte)newgray; + destArr[i + 2] = (byte)newgray; + + } } - newc = Color.FromArgb(newgray, newgray, newgray); } - int nextIndex = getIndexFromXY(x + 3, y, width); - int nextRow = getIndexFromXY(x, y + 1, width); - int nextIndexOnNextRow = getIndexFromXY(x + 3, y + 1, width); - int prevIndexOnNextRow = getIndexFromXY(x - 3, y + 1, width); - - grays[i] = newc.R; - grays[i + 1] = newc.G; - grays[i + 2] = newc.B; - - if (dithering) + else { - if (color_depth_floydsteinberg) + for (int i = 0; i < sourceArr.Length; i += 3) { - if (x + 3 < width) + byte r = sourceArr[i]; + byte g = sourceArr[i + 1]; + byte b = sourceArr[i + 2]; + if (SkinEngine.LoadedSkin.SystemKey == Color.FromArgb(r, g, b)) { - sourceArr[nextIndex] += (byte)((error_r * 7) / 16); - sourceArr[nextIndex + 1] += (byte)((error_r * 7) / 16); - sourceArr[nextIndex + 2] += (byte)((error_r * 7) / 16); + destArr[i] = r; + destArr[i + 1] = g; + destArr[i + 2] = b; + continue; } - if (y + 1 < height) - { - sourceArr[nextRow] += (byte)((error_r) / 16); - sourceArr[nextRow + 1] += (byte)((error_r) / 16); - sourceArr[nextRow + 2] += (byte)((error_r) / 16); - } - if (x + 3 < width && y + 1 < height) - { - sourceArr[nextIndexOnNextRow] += (byte)((error_r * 3) / 16); - sourceArr[nextIndexOnNextRow + 1] += (byte)((error_r * 3) / 16); - sourceArr[nextIndexOnNextRow + 2] += (byte)((error_r * 3) / 16); - } - if (x - 3 > 0 && y + 1 < height) - { - sourceArr[prevIndexOnNextRow] += (byte)((error_r * 5) / 16); - sourceArr[prevIndexOnNextRow + 1] += (byte)((error_r * 5) / 16); - sourceArr[prevIndexOnNextRow + 2] += (byte)((error_r * 5) / 16); + int gray = (r + g + b) / 3; + int newgray = GetClosestColor(gray, eightBits, sixBits, fourBits, twoBits); + destArr[i] = (byte)newgray; + destArr[i + 1] = (byte)newgray; + destArr[i + 2] = (byte)newgray; + + - } } } } } - for (int i = 0; i < destArr.Length - 3; i++) - { - destArr[i] = grays[i]; - - } - Marshal.Copy(destArr, 0, destPtr, destBytes); @@ -389,8 +392,7 @@ namespace ShiftOS.WinForms.Tools - Desktop.InvokeOnWorkerThread(new Action(() => { result?.Invoke(bmp); })); - + return bmp; } #endif @@ -399,4 +401,25 @@ namespace ShiftOS.WinForms.Tools return (width * y) + x; } } + + public class DitheringSkinPostProcessor : ISkinPostProcessor + { + public byte[] ProcessImage(byte[] original) + { + try + { + var img = SkinEngine.ImageFromBinary(original); + var dithered = DitheringEngine.DitherImage(img); + using (var mstr = new MemoryStream()) + { + dithered.Save(mstr, System.Drawing.Imaging.ImageFormat.Bmp); + return mstr.ToArray(); + } + } + catch + { + return original; + } + } + } } diff --git a/ShiftOS.WinForms/UniteLoginDialog.cs b/ShiftOS.WinForms/UniteLoginDialog.cs index 4c85005..c78e987 100644 --- a/ShiftOS.WinForms/UniteLoginDialog.cs +++ b/ShiftOS.WinForms/UniteLoginDialog.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using System.Windows.Forms; using ShiftOS.Engine; using System.Net; +using ShiftOS.Objects; namespace ShiftOS.WinForms { @@ -59,7 +60,7 @@ namespace ShiftOS.WinForms try { - var webrequest = HttpWebRequest.Create("http://getshiftos.ml/Auth/Login?appname=ShiftOS&appdesc=ShiftOS+client&version=1_0_beta_2_4"); + var webrequest = HttpWebRequest.Create(UserConfig.Get().UniteUrl + "/Auth/Login?appname=ShiftOS&appdesc=ShiftOS+client&version=1_0_beta_2_4"); string base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{u}:{p}")); webrequest.Headers.Add("Authentication: Basic " + base64); var response = webrequest.GetResponse(); diff --git a/ShiftOS.WinForms/UniteSignupDialog.cs b/ShiftOS.WinForms/UniteSignupDialog.cs index a46a9b0..7d0fd33 100644 --- a/ShiftOS.WinForms/UniteSignupDialog.cs +++ b/ShiftOS.WinForms/UniteSignupDialog.cs @@ -10,6 +10,7 @@ using System.Windows.Forms; using ShiftOS.Engine; using Newtonsoft.Json; using System.Net; +using ShiftOS.Objects; namespace ShiftOS.WinForms { @@ -99,7 +100,7 @@ namespace ShiftOS.WinForms try { - var webrequest = HttpWebRequest.Create("http://getshiftos.ml/Auth/Register?appname=ShiftOS&appdesc=ShiftOS+client&version=1_0_beta_2_4&displayname=" + txtdisplay.Text + "&sysname=" + txtsysname.Text); + var webrequest = HttpWebRequest.Create(UserConfig.Get().UniteUrl + "/Auth/Register?appname=ShiftOS&appdesc=ShiftOS+client&version=1_0_beta_2_4&displayname=" + txtdisplay.Text + "&sysname=" + txtsysname.Text); string base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{u}:{p}")); webrequest.Headers.Add("Authentication: Basic " + base64); var response = webrequest.GetResponse(); diff --git a/ShiftOS.WinForms/WindowBorder.cs b/ShiftOS.WinForms/WindowBorder.cs index 25c7639..40dc629 100644 --- a/ShiftOS.WinForms/WindowBorder.cs +++ b/ShiftOS.WinForms/WindowBorder.cs @@ -515,6 +515,17 @@ namespace ShiftOS.WinForms if(resizing == true) { this.Width += e.X; + switch (LoadedSkin.TitleTextCentered) + { + case false: + lbtitletext.Location = new Point(16 + LoadedSkin.TitlebarIconFromSide.X + LoadedSkin.TitleTextLeft.X, + LoadedSkin.TitleTextLeft.Y); + break; + default: + lbtitletext.Left = (pnltitle.Width - lbtitletext.Width) / 2; + lbtitletext.Top = LoadedSkin.TitleTextLeft.Y; + break; + } } } @@ -522,6 +533,17 @@ namespace ShiftOS.WinForms { resizing = false; pnlcontents.Show(); + switch (LoadedSkin.TitleTextCentered) + { + case false: + lbtitletext.Location = new Point(16 + LoadedSkin.TitlebarIconFromSide.X + LoadedSkin.TitleTextLeft.X, + LoadedSkin.TitleTextLeft.Y); + break; + default: + lbtitletext.Left = (pnltitle.Width - lbtitletext.Width) / 2; + lbtitletext.Top = LoadedSkin.TitleTextLeft.Y; + break; + } } private void pnlleft_MouseMove(object sender, MouseEventArgs e) @@ -530,6 +552,17 @@ namespace ShiftOS.WinForms { this.Left += e.X; this.Width -= e.X; + switch (LoadedSkin.TitleTextCentered) + { + case false: + lbtitletext.Location = new Point(16 + LoadedSkin.TitlebarIconFromSide.X + LoadedSkin.TitleTextLeft.X, + LoadedSkin.TitleTextLeft.Y); + break; + default: + lbtitletext.Left = (pnltitle.Width - lbtitletext.Width) / 2; + lbtitletext.Top = LoadedSkin.TitleTextLeft.Y; + break; + } } } @@ -547,6 +580,17 @@ namespace ShiftOS.WinForms { this.Width += e.X; this.Height += e.Y; + switch (LoadedSkin.TitleTextCentered) + { + case false: + lbtitletext.Location = new Point(16 + LoadedSkin.TitlebarIconFromSide.X + LoadedSkin.TitleTextLeft.X, + LoadedSkin.TitleTextLeft.Y); + break; + default: + lbtitletext.Left = (pnltitle.Width - lbtitletext.Width) / 2; + lbtitletext.Top = LoadedSkin.TitleTextLeft.Y; + break; + } } } @@ -557,6 +601,17 @@ namespace ShiftOS.WinForms this.Width -= e.X; this.Height += e.Y; this.Left += e.X; + switch (LoadedSkin.TitleTextCentered) + { + case false: + lbtitletext.Location = new Point(16 + LoadedSkin.TitlebarIconFromSide.X + LoadedSkin.TitleTextLeft.X, + LoadedSkin.TitleTextLeft.Y); + break; + default: + lbtitletext.Left = (pnltitle.Width - lbtitletext.Width) / 2; + lbtitletext.Top = LoadedSkin.TitleTextLeft.Y; + break; + } } } diff --git a/ShiftOS.WinForms/WinformsDesktop.Designer.cs b/ShiftOS.WinForms/WinformsDesktop.Designer.cs index 71ef161..d82bc0c 100644 --- a/ShiftOS.WinForms/WinformsDesktop.Designer.cs +++ b/ShiftOS.WinForms/WinformsDesktop.Designer.cs @@ -53,15 +53,20 @@ namespace ShiftOS.WinForms private void InitializeComponent() { this.desktoppanel = new System.Windows.Forms.Panel(); - this.btnnotifications = new System.Windows.Forms.Button(); + this.pnlnotifications = new System.Windows.Forms.Panel(); + this.flnotifications = new System.Windows.Forms.FlowLayoutPanel(); + this.ntconnectionstatus = new System.Windows.Forms.PictureBox(); this.lbtime = new System.Windows.Forms.Label(); this.panelbuttonholder = new System.Windows.Forms.FlowLayoutPanel(); this.sysmenuholder = new System.Windows.Forms.Panel(); this.menuStrip1 = new System.Windows.Forms.MenuStrip(); this.apps = new System.Windows.Forms.ToolStripMenuItem(); this.pnlscreensaver = new System.Windows.Forms.Panel(); - this.pnlwidgetlayer = new System.Windows.Forms.Panel(); this.pnlssicon = new System.Windows.Forms.Panel(); + this.pnlwidgetlayer = new System.Windows.Forms.Panel(); + this.pnlnotificationbox = new System.Windows.Forms.Panel(); + this.lbnotemsg = new System.Windows.Forms.Label(); + this.lbnotetitle = new System.Windows.Forms.Label(); this.pnladvancedal = new System.Windows.Forms.Panel(); this.flapps = new System.Windows.Forms.FlowLayoutPanel(); this.flcategories = new System.Windows.Forms.FlowLayoutPanel(); @@ -70,9 +75,13 @@ namespace ShiftOS.WinForms this.pnlstatus = new System.Windows.Forms.Panel(); this.lbalstatus = new System.Windows.Forms.Label(); this.desktoppanel.SuspendLayout(); + this.pnlnotifications.SuspendLayout(); + this.flnotifications.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.ntconnectionstatus)).BeginInit(); this.sysmenuholder.SuspendLayout(); this.menuStrip1.SuspendLayout(); this.pnlscreensaver.SuspendLayout(); + this.pnlnotificationbox.SuspendLayout(); this.pnladvancedal.SuspendLayout(); this.pnlalsystemactions.SuspendLayout(); this.pnlstatus.SuspendLayout(); @@ -81,8 +90,7 @@ namespace ShiftOS.WinForms // desktoppanel // this.desktoppanel.BackColor = System.Drawing.Color.Green; - this.desktoppanel.Controls.Add(this.btnnotifications); - this.desktoppanel.Controls.Add(this.lbtime); + this.desktoppanel.Controls.Add(this.pnlnotifications); this.desktoppanel.Controls.Add(this.panelbuttonholder); this.desktoppanel.Controls.Add(this.sysmenuholder); this.desktoppanel.Dock = System.Windows.Forms.DockStyle.Top; @@ -92,28 +100,46 @@ namespace ShiftOS.WinForms this.desktoppanel.TabIndex = 0; this.desktoppanel.Paint += new System.Windows.Forms.PaintEventHandler(this.desktoppanel_Paint); // - // btnnotifications + // pnlnotifications // - this.btnnotifications.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnnotifications.AutoSize = true; - this.btnnotifications.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.btnnotifications.BackColor = System.Drawing.Color.Transparent; - this.btnnotifications.FlatAppearance.BorderSize = 0; - this.btnnotifications.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.btnnotifications.Location = new System.Drawing.Point(1066, -2); - this.btnnotifications.Name = "btnnotifications"; - this.btnnotifications.Size = new System.Drawing.Size(136, 24); - this.btnnotifications.TabIndex = 3; - this.btnnotifications.Text = "Notifications (0)"; - this.btnnotifications.UseVisualStyleBackColor = false; - this.btnnotifications.Click += new System.EventHandler(this.btnnotifications_Click); + this.pnlnotifications.Controls.Add(this.flnotifications); + this.pnlnotifications.Controls.Add(this.lbtime); + this.pnlnotifications.Cursor = System.Windows.Forms.Cursors.Default; + this.pnlnotifications.Dock = System.Windows.Forms.DockStyle.Right; + this.pnlnotifications.Location = new System.Drawing.Point(1096, 0); + this.pnlnotifications.Name = "pnlnotifications"; + this.pnlnotifications.Size = new System.Drawing.Size(200, 24); + this.pnlnotifications.TabIndex = 3; + // + // flnotifications + // + this.flnotifications.AutoSize = true; + this.flnotifications.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.flnotifications.Controls.Add(this.ntconnectionstatus); + this.flnotifications.Dock = System.Windows.Forms.DockStyle.Left; + this.flnotifications.Location = new System.Drawing.Point(0, 0); + this.flnotifications.Name = "flnotifications"; + this.flnotifications.Size = new System.Drawing.Size(22, 24); + this.flnotifications.TabIndex = 1; + this.flnotifications.WrapContents = false; + // + // ntconnectionstatus + // + this.ntconnectionstatus.Image = global::ShiftOS.WinForms.Properties.Resources.notestate_connection_full; + this.ntconnectionstatus.Location = new System.Drawing.Point(3, 3); + this.ntconnectionstatus.Name = "ntconnectionstatus"; + this.ntconnectionstatus.Size = new System.Drawing.Size(16, 16); + this.ntconnectionstatus.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; + this.ntconnectionstatus.TabIndex = 0; + this.ntconnectionstatus.TabStop = false; + this.ntconnectionstatus.Tag = "digitalsociety"; // // lbtime // this.lbtime.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Right))); this.lbtime.AutoSize = true; - this.lbtime.Location = new System.Drawing.Point(3, 0); + this.lbtime.Location = new System.Drawing.Point(139, 7); this.lbtime.Name = "lbtime"; this.lbtime.Size = new System.Drawing.Size(49, 14); this.lbtime.TabIndex = 0; @@ -170,6 +196,13 @@ namespace ShiftOS.WinForms this.pnlscreensaver.TabIndex = 1; this.pnlscreensaver.Visible = false; // + // pnlssicon + // + this.pnlssicon.Location = new System.Drawing.Point(303, 495); + this.pnlssicon.Name = "pnlssicon"; + this.pnlssicon.Size = new System.Drawing.Size(200, 100); + this.pnlssicon.TabIndex = 0; + // // pnlwidgetlayer // this.pnlwidgetlayer.BackColor = System.Drawing.Color.Transparent; @@ -179,12 +212,42 @@ namespace ShiftOS.WinForms this.pnlwidgetlayer.Size = new System.Drawing.Size(1296, 714); this.pnlwidgetlayer.TabIndex = 1; // - // pnlssicon + // pnlnotificationbox // - this.pnlssicon.Location = new System.Drawing.Point(303, 495); - this.pnlssicon.Name = "pnlssicon"; - this.pnlssicon.Size = new System.Drawing.Size(200, 100); - this.pnlssicon.TabIndex = 0; + this.pnlnotificationbox.AutoSize = true; + this.pnlnotificationbox.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.pnlnotificationbox.Controls.Add(this.lbnotemsg); + this.pnlnotificationbox.Controls.Add(this.lbnotetitle); + this.pnlnotificationbox.Location = new System.Drawing.Point(654, 111); + this.pnlnotificationbox.Name = "pnlnotificationbox"; + this.pnlnotificationbox.Size = new System.Drawing.Size(69, 68); + this.pnlnotificationbox.TabIndex = 0; + this.pnlnotificationbox.Visible = false; + // + // lbnotemsg + // + this.lbnotemsg.AutoSize = true; + this.lbnotemsg.Dock = System.Windows.Forms.DockStyle.Fill; + this.lbnotemsg.Location = new System.Drawing.Point(0, 34); + this.lbnotemsg.MaximumSize = new System.Drawing.Size(350, 0); + this.lbnotemsg.Name = "lbnotemsg"; + this.lbnotemsg.Padding = new System.Windows.Forms.Padding(10); + this.lbnotemsg.Size = new System.Drawing.Size(69, 34); + this.lbnotemsg.TabIndex = 1; + this.lbnotemsg.Text = "label1"; + // + // lbnotetitle + // + this.lbnotetitle.AutoSize = true; + this.lbnotetitle.Dock = System.Windows.Forms.DockStyle.Top; + this.lbnotetitle.Location = new System.Drawing.Point(0, 0); + this.lbnotetitle.Margin = new System.Windows.Forms.Padding(10); + this.lbnotetitle.Name = "lbnotetitle"; + this.lbnotetitle.Padding = new System.Windows.Forms.Padding(10); + this.lbnotetitle.Size = new System.Drawing.Size(69, 34); + this.lbnotetitle.TabIndex = 0; + this.lbnotetitle.Tag = "header2"; + this.lbnotetitle.Text = "label1"; // // pnladvancedal // @@ -262,6 +325,7 @@ namespace ShiftOS.WinForms this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.Color.Black; this.ClientSize = new System.Drawing.Size(1296, 738); + this.Controls.Add(this.pnlnotificationbox); this.Controls.Add(this.pnlwidgetlayer); this.Controls.Add(this.pnladvancedal); this.Controls.Add(this.pnlscreensaver); @@ -274,16 +338,24 @@ namespace ShiftOS.WinForms this.Load += new System.EventHandler(this.Desktop_Load); this.desktoppanel.ResumeLayout(false); this.desktoppanel.PerformLayout(); + this.pnlnotifications.ResumeLayout(false); + this.pnlnotifications.PerformLayout(); + this.flnotifications.ResumeLayout(false); + this.flnotifications.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.ntconnectionstatus)).EndInit(); this.sysmenuholder.ResumeLayout(false); this.sysmenuholder.PerformLayout(); this.menuStrip1.ResumeLayout(false); this.menuStrip1.PerformLayout(); this.pnlscreensaver.ResumeLayout(false); + this.pnlnotificationbox.ResumeLayout(false); + this.pnlnotificationbox.PerformLayout(); this.pnladvancedal.ResumeLayout(false); this.pnlalsystemactions.ResumeLayout(false); this.pnlalsystemactions.PerformLayout(); this.pnlstatus.ResumeLayout(false); this.ResumeLayout(false); + this.PerformLayout(); } @@ -295,7 +367,6 @@ namespace ShiftOS.WinForms private System.Windows.Forms.MenuStrip menuStrip1; private System.Windows.Forms.ToolStripMenuItem apps; private System.Windows.Forms.FlowLayoutPanel panelbuttonholder; - private System.Windows.Forms.Button btnnotifications; private System.Windows.Forms.Panel pnlscreensaver; private System.Windows.Forms.Panel pnlssicon; private System.Windows.Forms.Panel pnladvancedal; @@ -306,6 +377,12 @@ namespace ShiftOS.WinForms private System.Windows.Forms.FlowLayoutPanel flapps; private System.Windows.Forms.FlowLayoutPanel flcategories; private System.Windows.Forms.Panel pnlwidgetlayer; + private System.Windows.Forms.Panel pnlnotifications; + private System.Windows.Forms.FlowLayoutPanel flnotifications; + private System.Windows.Forms.Panel pnlnotificationbox; + private System.Windows.Forms.Label lbnotemsg; + private System.Windows.Forms.Label lbnotetitle; + private System.Windows.Forms.PictureBox ntconnectionstatus; } } diff --git a/ShiftOS.WinForms/WinformsDesktop.cs b/ShiftOS.WinForms/WinformsDesktop.cs index 6825f34..4614842 100644 --- a/ShiftOS.WinForms/WinformsDesktop.cs +++ b/ShiftOS.WinForms/WinformsDesktop.cs @@ -47,13 +47,137 @@ namespace ShiftOS.WinForms /// /// Winforms desktop. /// + [Namespace("desktop")] public partial class WinformsDesktop : Form, IDesktop { + [Command("pushnote")] + [RequiresArgument("target")] + [RequiresArgument("title")] + [RequiresArgument("body")] + public static bool PushNote(Dictionary args) + { + string ta = args["target"].ToString(); + string ti = args["title"].ToString(); + string bo = args["body"].ToString(); + + Desktop.PushNotification(ta, ti, bo); + + return true; + } + public List Widgets = new List(); private int millisecondsUntilScreensaver = 300000; + public void LoadIcons() + { + //That shot me back to 0.0.x with that name. Whatever. + flnotifications.Controls.Clear(); //Clear the status tray + + foreach(var itype in NotificationDaemon.GetAllStatusIcons()) + { + //We have the types. No need for shiftorium calls or anything. + //First create the icon control... + + var ic = new PictureBox(); + //We can use the type name, in lowercase, for the icon tag. + ic.Tag = itype.Name.ToLower(); + //Next get the icon data if any. + + //We can use this attribute's ID in the skin engine to get an icon. + var img = GetIcon(itype.Name); + //Make it transparent. + (img as Bitmap).MakeTransparent(Color.White); + //Assign it to the control + ic.Image = img; + //Set the sizing mode + ic.SizeMode = PictureBoxSizeMode.StretchImage; + ic.Size = new Size(16, 16); //TODO: make it skinnable + //add to the notification tray + flnotifications.Controls.Add(ic); + ic.Show(); + + ic.BringToFront(); + + flnotifications.Show(); + + + ic.Click += (o, a) => + { + HideAppLauncher(); + + if(itype.BaseType == typeof(UserControl)) + { + UserControl ctrl = (UserControl)Activator.CreateInstance(itype); + (ctrl as IStatusIcon).Setup(); + currentSettingsPane = ctrl; + ControlManager.SetupControls(ctrl); + this.Controls.Add(ctrl); + ctrl.BringToFront(); + int left = ic.Parent.PointToScreen(ic.Location).X; + int realleft = left - ctrl.Width; + realleft += ic.Width; + ctrl.Left = realleft; + if (LoadedSkin.DesktopPanelPosition == 0) + { + ctrl.Top = desktoppanel.Height; + } + else + { + ctrl.Top = this.Height - desktoppanel.Height - ctrl.Height; + } + ctrl.Show(); + } + + + }; + } + } + + public void PushNotification(string app, string title, string msg) + { + lbnotemsg.Text = msg; + lbnotetitle.Text = title; + int height = pnlnotificationbox.Height; + pnlnotificationbox.AutoSize = false; + pnlnotificationbox.Height = height; + pnlnotificationbox.Width = lbnotetitle.Width; + + var ctl = flnotifications.Controls.ToList().FirstOrDefault(x => x.Tag.ToString() == app); + if (ctl == null) + pnlnotificationbox.Left = desktoppanel.Width - pnlnotificationbox.Width; + else + { + int left = ctl.Parent.PointToScreen(ctl.Location).X; + int realleft = left - pnlnotificationbox.Width; + realleft += ctl.Width; + pnlnotificationbox.Left = realleft; + } + + + if (LoadedSkin.DesktopPanelPosition == 0) + pnlnotificationbox.Top = desktoppanel.Height; + else + pnlnotificationbox.Top = this.Height - desktoppanel.Height - pnlnotificationbox.Height; + ControlManager.SetupControls(pnlnotificationbox); + var notekiller = new System.Windows.Forms.Timer(); + notekiller.Interval = 10000; + notekiller.Tick += (o, a) => + { + pnlnotificationbox.Hide(); + pnlnotificationbox.AutoSize = true; + }; + Engine.AudioManager.PlayStream(Properties.Resources.infobox); + + + pnlnotificationbox.Show(); + pnlnotificationbox.BringToFront(); + notekiller.Start(); + } + + private UserControl currentSettingsPane = null; + /// /// Initializes a new instance of the class. /// @@ -72,57 +196,17 @@ namespace ShiftOS.WinForms SetupControl(desktoppanel); Shiftorium.Installed += () => { - foreach(var widget in Widgets) + foreach (var widget in Widgets) { widget.OnUpgrade(); } - //Only if the DevX Legions story hasn't been experienced yet. - if (!Shiftorium.UpgradeInstalled("devx_legions")) - { - //Check for shiftnet story experience - if (Shiftorium.UpgradeInstalled("shiftnet")) - { - //Check for saturation of the "GUI" upgrade set - if (Shiftorium.IsCategoryEmptied("GUI")) - { - //Start the MUD Control Centre story. - Story.Start("devx_legions"); - } - } - } + LoadIcons(); + - if (!Shiftorium.UpgradeInstalled("victortran_shiftnet")) - { - if (SaveSystem.CurrentSave.Codepoints >= 50000) - { - if (Shiftorium.IsCategoryEmptied("Applications")) - { - Story.Start("victortran_shiftnet"); - } - } - } }; this.TopMost = false; - NotificationDaemon.NotificationMade += (note) => - { - //Soon this will pop a balloon note. - this.Invoke(new Action(() => - { - btnnotifications.Text = Localization.Parse("{NOTIFICATIONS} (" + NotificationDaemon.GetUnreadCount().ToString() + ")"); - })); - }; - - NotificationDaemon.NotificationRead += () => - { - //Soon this will pop a balloon note. - this.Invoke(new Action(() => - { - btnnotifications.Text = Localization.Parse("{NOTIFICATIONS} (" + NotificationDaemon.GetUnreadCount().ToString() + ")"); - })); - }; - this.LocationChanged += (o, a) => { if (this.Left != 0) @@ -141,12 +225,9 @@ namespace ShiftOS.WinForms SaveSystem.GameReady += () => { + this.Invoke(new Action(LoadIcons)); if (this.Visible == true) this.Invoke(new Action(() => SetupDesktop())); - this.Invoke(new Action(() => - { - btnnotifications.Text = Localization.Parse("{NOTIFICATIONS} (" + NotificationDaemon.GetUnreadCount().ToString() + ")"); - })); }; Shiftorium.Installed += () => { @@ -173,22 +254,62 @@ namespace ShiftOS.WinForms }; SkinEngine.SkinLoaded += () => { + LoadIcons(); foreach (var widget in Widgets) { widget.OnSkinLoad(); } + SetupDesktop(); }; + + ulong lastcp = 0; + + var storythread = new Thread(() => + { + do + { + while (SaveSystem.CurrentUser == null) + Thread.Sleep(10); + + if (SaveSystem.CurrentSave != null) + { + if (SaveSystem.CurrentSave.Codepoints != lastcp) + lastcp = SaveSystem.CurrentSave.Codepoints; + if (lastcp >= 2500) + { + if (!Shiftorium.UpgradeInstalled("victortran_shiftnet")) + { + Story.Start("victortran_shiftnet"); + } + } + if(lastcp >= 5000) + { + if(Shiftorium.UpgradeInstalled("triwrite") && Shiftorium.UpgradeInstalled("simplesrc") && Shiftorium.UpgradeInstalled("victortran_shiftnet") && Shiftorium.UpgradeInstalled("story_hacker101_breakingthebonds")) + { + if (!Shiftorium.UpgradeInstalled("story_thefennfamily")) + Story.Start("story_thefennfamily"); + } + } + } + } while (!SaveSystem.ShuttingDown); + }); + storythread.IsBackground = true; + storythread.Start(); + time.Tick += (o, a) => { if (Shiftorium.IsInitiated == true) { - if (SaveSystem.CurrentSave != null && TutorialManager.IsInTutorial == false) + if (SaveSystem.CurrentSave != null) { + lbtime.Text = Applications.Terminal.GetTime(); - lbtime.Left = desktoppanel.Width - lbtime.Width - LoadedSkin.DesktopPanelClockFromRight.X; + lbtime.Left = pnlnotifications.Width - lbtime.Width - LoadedSkin.DesktopPanelClockFromRight.X; lbtime.Top = LoadedSkin.DesktopPanelClockFromRight.Y; + + pnlnotifications.Width = flnotifications.Width + lbtime.Width + LoadedSkin.DesktopPanelClockFromRight.X; } } @@ -215,32 +336,9 @@ namespace ShiftOS.WinForms catch { } - btnnotifications.Left = lbtime.Left - btnnotifications.Width - 2; - btnnotifications.Top = (desktoppanel.Height - btnnotifications.Height) / 2; }; time.Start(); - var ssThread = new Thread(() => - { - while(this.Visible == true) - { - var mousePos = Cursor.Position; - while(Cursor.Position == mousePos) - { - if(millisecondsUntilScreensaver <= 0) - { - ShowScreensaver(); - } - millisecondsUntilScreensaver--; - Thread.Sleep(1); - } - millisecondsUntilScreensaver = 300000; - HideScreensaver(); - } - }); - ssThread.IsBackground = true; - ssThread.Start(); - this.DoubleBuffered = true; } @@ -372,10 +470,13 @@ namespace ShiftOS.WinForms desktoppanel.Visible = Shiftorium.UpgradeInstalled("desktop"); lbtime.Visible = Shiftorium.UpgradeInstalled("desktop_clock_widget"); - btnnotifications.Visible = Shiftorium.UpgradeInstalled("panel_notifications"); + ControlManager.SetupControls(pnlnotificationbox); //skinning - lbtime.ForeColor = LoadedSkin.DesktopPanelClockColor; + lbtime.BackColor = Color.Transparent; + pnlnotifications.BackgroundImage = GetImage("panelclockbg"); + pnlnotifications.BackgroundImageLayout = GetImageLayout("panelclockbg"); + pnlnotifications.BackColor = LoadedSkin.DesktopPanelClockBackgroundColor; panelbuttonholder.Top = 0; panelbuttonholder.Left = LoadedSkin.PanelButtonHolderFromLeft; @@ -390,10 +491,7 @@ namespace ShiftOS.WinForms this.BackColor = Color.FromArgb(LoadedSkin.DesktopColor.R, LoadedSkin.DesktopColor.G, LoadedSkin.DesktopColor.B); //Not doing this will cause an ArgumentException. - DitheringEngine.DitherImage(SkinEngine.GetImage("desktopbackground"), new Action((img) => - { - this.BackgroundImage = img; - })); + this.BackgroundImage = SkinEngine.GetImage("desktopbackground"); this.BackgroundImageLayout = GetImageLayout("desktopbackground"); desktoppanel.BackColor = LoadedSkin.DesktopPanelColor; @@ -1009,6 +1107,8 @@ namespace ShiftOS.WinForms { this.Invoke(new Action(() => { + currentSettingsPane?.Hide(); + currentSettingsPane = null; pnladvancedal.Hide(); })); } @@ -1063,4 +1163,15 @@ namespace ShiftOS.WinForms } } } + + public static class ControlCollectionExtensions + { + public static IList ToList(this Control.ControlCollection ctrls) + { + var lst = new List(); + foreach (var ctl in ctrls) + lst.Add(ctl as Control); + return lst; + } + } } \ No newline at end of file diff --git a/ShiftOS_TheReturn/AppearanceManager.cs b/ShiftOS_TheReturn/AppearanceManager.cs index 4c1754e..7cf06c9 100644 --- a/ShiftOS_TheReturn/AppearanceManager.cs +++ b/ShiftOS_TheReturn/AppearanceManager.cs @@ -38,9 +38,7 @@ using static ShiftOS.Engine.SaveSystem; namespace ShiftOS.Engine { - /// - /// Provides functionality for managing windows within ShiftOS. - /// + // Provides functionality for managing windows within ShiftOS. public static class AppearanceManager { [Obsolete("Please use Localization.GetAllLanguages().")] @@ -49,12 +47,7 @@ namespace ShiftOS.Engine return Localization.GetAllLanguages(); } - /// - /// Sets the title text of the specified window. - /// - /// The window to modify - /// The title text to use - /// Thrown if the window is null. + // Sets the title text of the specified window. public static void SetWindowTitle(IShiftOSWindow window, string title) { if (window == null) @@ -62,11 +55,13 @@ namespace ShiftOS.Engine winmgr.SetTitle(window, title); } + //HEY LETS FIND THE WINDOWS public static IEnumerable GetAllWindowTypes() { List types = new List(); foreach(var file in System.IO.Directory.GetFiles(Environment.CurrentDirectory)) { + // hey if a thing is an exe or a dll show up plz kthx if(file.EndsWith(".exe") || file.EndsWith(".dll")) { try @@ -84,12 +79,7 @@ namespace ShiftOS.Engine return types; } - /// - /// Returns the default window title for a specified -inheriting type. - /// - /// The type to scan - /// The default title - /// Thrown if is null. + // hey you know that window we just made appear? well give it its title public static string GetDefaultTitle(Type winType) { if (winType == null) @@ -104,257 +94,155 @@ namespace ShiftOS.Engine return winType.Name; } - /// - /// Current cursor position of the console - /// + // Current cursor position of the console public static int CurrentPosition { get; set; } - /// - /// We don't know what this does. It may be gone if it does nothing. - /// + // We don't know what this does. It may be gone if it does nothing. public static int LastLength { get; set; } - /// - /// Minimize a window. - /// - /// The window border to minimize. - /// Thrown if is null. - /// Thrown if this part of the engine hasn't been enabled. + // Minimize a window. public static void Minimize(IWindowBorder form) { if (form == null) + //FUCK WHY THE FUCK IS THIS NULL throw new ArgumentNullException("form"); if (winmgr == null) + //FUCK THIS PART OF THE ENGINE WASNT TURNED ON YET throw new EngineModuleDisabledException(); winmgr.Minimize(form); } - /// - /// Maximizes a window. - /// - /// The window border to maximize. - /// Thrown if is null. - /// Thrown if this engine module hasn't been enabled. + // Maximizes a window! :D public static void Maximize(IWindowBorder form) { if (form == null) + //AHHHH SHOULDNT BE NULLLLLL throw new ArgumentNullException("form"); if (winmgr == null) + //WHY ARE YOU DOING THIS PART OF THE ENGINE IT WASNT ENABLED FUCK throw new EngineModuleDisabledException(); winmgr.Maximize(form); } - /// - /// Provides a list of all open ShiftOS windows. - /// + // Provides a list of all open ShiftOS windows. public static List OpenForms = new List(); - /// - /// Decorates a window with a border, then shows the window. - /// - /// The window to decorate and show. - /// Thrown if is null. - /// Thrown if this engine module has not been initiated yet. + // Decorates a window with a border, then shows the window. public static void SetupWindow(IShiftOSWindow form) { if (form == null) + //YOU GET THE POINT THIS REALLY SHOULDNT BE NULL throw new ArgumentNullException("form"); if (winmgr == null) + //SAME HERE throw new EngineModuleDisabledException(); winmgr.SetupWindow(form); Desktop.ResetPanelButtons(); } - /// - /// Closes the specified window. - /// - /// The window to close. - /// Thrown if is null. - /// Thrown if this engine module has not been initiated yet. + // Closes the specified window. SHOCKED YOU ARE I KNOW, HOW COULD YOU HAVE GUESSED public static void Close(IShiftOSWindow win) { if (win == null) + //NOPE SHOULDNT BE NULL throw new ArgumentNullException("win"); if (winmgr == null) + //WHY IS THIS NULL throw new EngineModuleDisabledException(); winmgr.Close(win); Desktop.ResetPanelButtons(); } - /// - /// Decorates a window with a border, then shows the window, as a dialog box. - /// - /// The window to decorate and show. - /// Thrown if is null. - /// Thrown if this engine module has not been initiated yet. + + // Decorates a window with a border, then shows the window, as a dialog box. public static void SetupDialog(IShiftOSWindow form) { if (form == null) + //NULLLLLLLLL throw new ArgumentNullException("form"); if (winmgr == null) + //ASGDFHASDGF throw new EngineModuleDisabledException(); winmgr.SetupDialog(form); Desktop.ResetPanelButtons(); } - /// - /// The underlying window manager for this engine module - /// + // The underlying window manager for this engine module private static WindowManager winmgr = null; - /// - /// Initiate this engine module, and perform mandatory configuration. - /// - /// A working, configured to use as a backend for this module + // Initiate this engine module, and perform mandatory configuration. public static void Initiate(WindowManager mgr) { - winmgr = mgr; + winmgr = mgr; // A working, configured window manager to use as a backend for this module } - /// - /// Raised when the engine is entering its shutdown phase. Save your work! - /// + + // Raised when the engine is entering its shutdown phase. Save your work! public static event EmptyEventHandler OnExit; - /// - /// Starts the engine's exit routine, firing the OnExit event. - /// + // Starts the engine's exit routine, firing the OnExit event. internal static void Exit() { OnExit?.Invoke(); //disconnect from MUD ServerManager.Disconnect(); + Desktop.InvokeOnWorkerThread(() => + { + Process.GetCurrentProcess().Kill(); //bye bye + }); } - /// - /// The current terminal body control. - /// + // The current terminal body control. public static ITerminalWidget ConsoleOut { get; set; } - /// - /// Redirects the .NET to a new instance. - /// + // Redirects the .NET to a new TerminalTextWriter instance. public static void StartConsoleOut() { - Console.SetOut(new TerminalTextWriter()); + Console.SetOut(new TerminalTextWriter()); //"plz start writing text .NET kthx" } - /// - /// Invokes an action on the window management thread. - /// - /// The action to invoke + // Invokes an action on the window management thread. public static void Invoke(Action act) { winmgr.InvokeAction(act); } } - /// - /// Provides the base functionality for a ShiftOS terminal. - /// + // Provides the base functionality for a ShiftOS terminal. public interface ITerminalWidget { - /// - /// Write text to this Terminal. - /// - /// Text to write - void Write(string text); - /// - /// Write text to this Terminal, followed by a newline. - /// - /// Text to write. - void WriteLine(string text); - /// - /// Clear the contents of this Terminal. - /// - void Clear(); - /// - /// Move the cursor to the last character in the Terminal. - /// - void SelectBottom(); + void Write(string text); // Actually write text to this Terminal! :D:D:D:D + void WriteLine(string text); // Write text to this Terminal, followed by a newline. + void Clear(); // Clear the contents of this Terminal, i bet you wouldve never guessed that + void SelectBottom(); // Move the cursor to the last character in the Terminal. } - /// - /// Provides the base functionality for a ShiftOS window manager. - /// + // makes the window manager actually do its job public abstract class WindowManager { - /// - /// Minimizes a window - /// - /// The window border to minimize - public abstract void Minimize(IWindowBorder border); - - /// - /// Maximizes a window - /// - /// The window border to maximize - public abstract void Maximize(IWindowBorder border); - - /// - /// Closes a window - /// - /// The window to close - public abstract void Close(IShiftOSWindow win); - - /// - /// Decorates a window with a window border, then shows it to the user. - /// - /// The window to decorate. - public abstract void SetupWindow(IShiftOSWindow win); - - /// - /// Decorates a window with a border, then shows it to the user as a dialog box. - /// - /// The window to decorate - public abstract void SetupDialog(IShiftOSWindow win); - - /// - /// Invokes an action on the window management thread. - /// - /// The action to invoke. - public abstract void InvokeAction(Action act); - - /// - /// Sets the title text of a window. - /// - /// The window to modify. - /// The new title text. - public abstract void SetTitle(IShiftOSWindow win, string title); + public abstract void Minimize(IWindowBorder border); // guess what this does + public abstract void Maximize(IWindowBorder border); // ooh this too + public abstract void Close(IShiftOSWindow win); // omg this probably does something + public abstract void SetupWindow(IShiftOSWindow win); // i cant think of what this does + public abstract void SetupDialog(IShiftOSWindow win); // how about this??????? + public abstract void InvokeAction(Action act); // i wonder what this invokes + public abstract void SetTitle(IShiftOSWindow win, string title); // what is a title again } - /// - /// Provides the base functionality for a typical ShiftOS window border. - /// + // Provides the base functionality for a typical ShiftOS window border, what did you expect public interface IWindowBorder { - /// - /// Closes the border along with its window. Unload events should be invoked here. - /// - void Close(); - - /// - /// Gets or sets the title text for the window border. - /// - string Text { get; set; } - - /// - /// Gets or sets the underlying for this border. - /// - IShiftOSWindow ParentWindow { get; set; } + void Close(); // CLOSES THE BORDER ALONG WITH ITS WINDOW!!!!!!! HOLY SHIT I DIDNT EXPECT THAT + string Text { get; set; } // title text exists now + IShiftOSWindow ParentWindow { get; set; } // Gets or sets the underlying for this border. } - - /// - /// Provides a way of setting default title text for classes. - /// + + // Provides a way of setting default title text for classes. public class DefaultTitleAttribute : Attribute { - /// - /// Creates a new instance of the . - /// - /// A default title to associate with this attribute. + // oy if you cant find a title this is the one you should use public DefaultTitleAttribute(string title) { Title = title; @@ -363,17 +251,13 @@ namespace ShiftOS.Engine public string Title { get; private set; } } - /// - /// An exception that is thrown when mandatory configuration to run a specific method or module hasn't been done yet. - /// + // An exception that is thrown when mandatory configuration to run a specific method or module hasn't been done yet. public class EngineModuleDisabledException : Exception { - /// - /// Initializes a new instance of the . - /// + // FUCK WE DIDNT ORDER THINGS RIGHT public EngineModuleDisabledException() : base("This engine module has not yet been enabled.") { - + //FUCK } } } diff --git a/ShiftOS_TheReturn/AudioManager.cs b/ShiftOS_TheReturn/AudioManager.cs index a636497..0a1a210 100644 --- a/ShiftOS_TheReturn/AudioManager.cs +++ b/ShiftOS_TheReturn/AudioManager.cs @@ -47,9 +47,12 @@ namespace ShiftOS.Engine /// public static void Stop() { - _out?.Stop(); - _reader?.Dispose(); - _out?.Dispose(); + Desktop.InvokeOnWorkerThread(() => + { + _out?.Stop(); + _reader?.Dispose(); + _out?.Dispose(); + }); } /// @@ -80,16 +83,29 @@ namespace ShiftOS.Engine /// The file to play. public static void Play(string file) { - try + bool play = true; + float volume = 1f; + if (SaveSystem.CurrentSave != null) { - _reader = new AudioFileReader(file); - _out = new WaveOut(); - _out.Init(_reader); - _out.Volume = _provider.Volume; - _out.Play(); - _out.PlaybackStopped += (o, a) => { PlayCompleted?.Invoke(); }; + play = (SaveSystem.CurrentSave.SoundEnabled); + volume = (float)SaveSystem.CurrentSave.MusicVolume / 100f; + } + if (play) + { + try + { + _reader = new AudioFileReader(file); + _out = new WaveOut(); + _out.Init(_reader); + _out.Volume = volume; + _out.Play(); + _out.PlaybackStopped += (o, a) => { PlayCompleted?.Invoke(); }; + } + catch (Exception ex) + { + Console.WriteLine("Audio error: " + ex.Message); + } } - catch { } } /// @@ -98,15 +114,27 @@ namespace ShiftOS.Engine /// The stream to read from. public static void PlayStream(Stream str) { - var bytes = new byte[str.Length]; - str.Read(bytes, 0, bytes.Length); - ShiftOS.Engine.AudioManager.Stop(); - if (File.Exists("snd.wav")) - File.Delete("snd.wav"); - File.WriteAllBytes("snd.wav", bytes); - - ShiftOS.Engine.AudioManager.Play("snd.wav"); - + try + { + bool play = true; + float volume = 1f; + if (SaveSystem.CurrentSave != null) + { + play = (SaveSystem.CurrentSave.SoundEnabled); + volume = (float)SaveSystem.CurrentSave.MusicVolume / 100f; + } + if (play) + { + ShiftOS.Engine.AudioManager.Stop(); + _out = new WaveOut(); + var mp3 = new WaveFileReader(str); + _out.Init(mp3); + _out.Volume = volume; + _out.Play(); + _out.PlaybackStopped += (o, a) => { PlayCompleted?.Invoke(); }; + } + } + catch { } } public static event Action PlayCompleted; diff --git a/ShiftOS_TheReturn/Commands.cs b/ShiftOS_TheReturn/Commands.cs index 57d1d34..f37bcb3 100644 --- a/ShiftOS_TheReturn/Commands.cs +++ b/ShiftOS_TheReturn/Commands.cs @@ -95,7 +95,7 @@ namespace ShiftOS.Engine { TerminalBackend.IsForwardingConsoleWrites = forwarding; TerminalBackend.ForwardGUID = (forwarding == true) ? fGuid : null; - Console.WriteLine($"{SaveSystem.CurrentSave.Username} says \"{result}\"."); + Console.WriteLine($"{SaveSystem.CurrentUser.Username} says \"{result}\"."); TerminalBackend.IsForwardingConsoleWrites = false; }; Desktop.InvokeOnWorkerThread(new Action(() => @@ -233,6 +233,23 @@ namespace ShiftOS.Engine [Namespace("dev")] public static class ShiftOSDevCommands { + [Command("buy")] + public static bool UnlockUpgrade(Dictionary args) + { + string upg = args["id"].ToString(); + try + { + SaveSystem.CurrentSave.Upgrades[upg] = true; + Shiftorium.InvokeUpgradeInstalled(); + SaveSystem.SaveGame(); + } + catch + { + Console.WriteLine("Upgrade not found."); + } + return true; + } + [Command("rock", description = "A little surprise for unstable builds...")] public static bool ThrowASandwichingRock() { @@ -276,6 +293,17 @@ namespace ShiftOS.Engine return true; } + [Command("restart")] + public static bool Restart() + { + SaveSystem.CurrentSave.Upgrades = new Dictionary(); + SaveSystem.CurrentSave.Codepoints = 0; + SaveSystem.CurrentSave.StoriesExperienced.Clear(); + SaveSystem.CurrentSave.StoriesExperienced.Add("mud_fundamentals"); + SaveSystem.SaveGame(); + Shiftorium.InvokeUpgradeInstalled(); + return true; + } [Command("freecp")] public static bool FreeCodepoints(Dictionary args) @@ -283,8 +311,8 @@ namespace ShiftOS.Engine if (args.ContainsKey("amount")) try { - Int64 codepointsToAdd = Convert.ToInt64(args["amount"].ToString()); - SaveSystem.TransferCodepointsFrom("dev", codepointsToAdd); + ulong codepointsToAdd = Convert.ToUInt64(args["amount"].ToString()); + SaveSystem.CurrentSave.Codepoints += codepointsToAdd; return true; } catch (Exception ex) @@ -293,7 +321,7 @@ namespace ShiftOS.Engine return true; } - SaveSystem.TransferCodepointsFrom("dev", 1000); + SaveSystem.CurrentSave.Codepoints += 1000; return true; } @@ -302,8 +330,13 @@ namespace ShiftOS.Engine { foreach (var upg in Shiftorium.GetDefaults()) { - Shiftorium.Buy(upg.ID, 0); + if (!SaveSystem.CurrentSave.Upgrades.ContainsKey(upg.ID)) + SaveSystem.CurrentSave.Upgrades.Add(upg.ID, true); + else + SaveSystem.CurrentSave.Upgrades[upg.ID] = true; } + Shiftorium.InvokeUpgradeInstalled(); + SkinEngine.LoadSkin(); return true; } @@ -350,12 +383,67 @@ namespace ShiftOS.Engine [Namespace("sos")] public static class ShiftOSCommands { + + [Command("setsfxenabled", description = "Set whether or not sound effects are enabled in the system.")] + [RequiresArgument("value")] + public static bool SetSfxEnabled(Dictionary args) + { + try + { + bool value = Convert.ToBoolean(args["value"].ToString()); + SaveSystem.CurrentSave.SoundEnabled = value; + SaveSystem.SaveGame(); + } + catch + { + Console.WriteLine("Error: Value must be either true or false."); + } + return true; + } + + + + [Command("setmusicenabled", description = "Set whether or not music is enabled in the system.")] + [RequiresArgument("value")] + public static bool SetMusicEnabled(Dictionary args) + { + try + { + bool value = Convert.ToBoolean(args["value"].ToString()); + SaveSystem.CurrentSave.MusicEnabled = value; + SaveSystem.SaveGame(); + } + catch + { + Console.WriteLine("Error: Value must be either true or false."); + } + return true; + } + + + + [Command("setsfxvolume", description ="Set the system sound volume to a value between 1 and 100.")] + [RequiresArgument("value")] + public static bool SetSfxVolume(Dictionary args) + { + int value = int.Parse(args["value"].ToString()); + if(value >= 0 && value <= 100) + { + SaveSystem.CurrentSave.MusicVolume = value; + SaveSystem.SaveGame(); + } + else + { + Console.WriteLine("Volume must be between 0 and 100!"); + } + return true; + } + [RemoteLock] [Command("shutdown")] public static bool Shutdown() { TerminalBackend.InvokeCommand("sos.save"); - SaveSystem.ShuttingDown = true; AppearanceManager.Exit(); return true; } @@ -389,84 +477,42 @@ namespace ShiftOS.Engine } } - [Command("help", "{COMMAND_HELP_USAGE}", "{COMMAND_HELP_DESCRIPTION}")] - public static bool Help() + [Command("help", "{COMMAND_HELP_USAGE", "{COMMAND_HELP_DESCRIPTION}")] + public static bool Help(Dictionary args) { - foreach (var exec in System.IO.Directory.GetFiles(Environment.CurrentDirectory)) + var sb = new StringBuilder(); + sb.AppendLine("Retrieving help data."); + + if (args.ContainsKey("ns")) { - if (exec.EndsWith(".exe") || exec.EndsWith(".dll")) + string ns = args["ns"].ToString(); + //First let's check for a command that has this namespace. + var cmdtest = TerminalBackend.Commands.FirstOrDefault(x => x.NamespaceInfo.name == ns); + if (cmdtest == null) //Namespace not found. + sb.AppendLine("Error retrieving help for namespace \"" + ns + "\". Namespace not found."); + else { - try + //Now do the actual scan. + sb.AppendLine("Namespace: " + ns); + foreach(var cmd in TerminalBackend.Commands.Where(x => x.NamespaceInfo.name == ns)) { - var asm = Assembly.LoadFile(exec); - - var types = asm.GetTypes(); - - foreach (var type in types) - { - if (Shiftorium.UpgradeAttributesUnlocked(type)) - { - foreach (var a in type.GetCustomAttributes(false)) - { - if (a is Namespace) - { - var ns = a as Namespace; - - if (!ns.hide) - { - string descp = "{NAMESPACE_" + ns.name.ToUpper() + "_DESCRIPTION}"; - if (descp == Localization.Parse(descp)) - descp = ""; - else - descp = Shiftorium.UpgradeInstalled("help_description") ? Localization.Parse("{SEPERATOR}" + descp) : ""; - - Console.WriteLine($"{{NAMESPACE}}{ns.name}" + descp); - - foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) - { - if (Shiftorium.UpgradeAttributesUnlocked(method)) - { - foreach (var ma in method.GetCustomAttributes(false)) - { - if (ma is Command) - { - var cmd = ma as Command; - - if (!cmd.hide) - { - string descriptionparse = "{COMMAND_" + ns.name.ToUpper() + "_" + cmd.name.ToUpper() + "_DESCRIPTION}"; - string usageparse = "{COMMAND_" + ns.name.ToUpper() + "_" + cmd.name.ToUpper() + "_USAGE}"; - if (descriptionparse == Localization.Parse(descriptionparse)) - descriptionparse = ""; - else - descriptionparse = Shiftorium.UpgradeInstalled("help_description") ? Localization.Parse("{SEPERATOR}" + descriptionparse) : ""; - - if (usageparse == Localization.Parse(usageparse)) - usageparse = ""; - else - usageparse = Shiftorium.UpgradeInstalled("help_usage") ? Localization.Parse("{SEPERATOR}" + usageparse, new Dictionary() { - {"%ns", ns.name}, - {"%cmd", cmd.name} - }) : ""; - - Console.WriteLine($"{{COMMAND}}{ns.name}.{cmd.name}" + usageparse + descriptionparse); - } - } - } - } - - } - } - - } - } - } - } - + string str = cmd.ToString(); + str = str.Replace(str.Substring(str.LastIndexOf("|")), ""); + sb.AppendLine(str); } - catch { } } } + else + { + + //print all unique namespaces. + foreach(var n in TerminalBackend.Commands.Select(x => x.NamespaceInfo.name).Distinct()) + { + sb.AppendLine("sos.help{ns:\"" + n + "\"}"); + } + } + + Console.WriteLine(sb.ToString()); return true; } @@ -487,11 +533,33 @@ namespace ShiftOS.Engine Codepoints: {SaveSystem.CurrentSave.Codepoints} Upgrades: {SaveSystem.CurrentSave.CountUpgrades()} installed, - {Shiftorium.GetAvailable().Length} available"; + {Shiftorium.GetAvailable().Length} available + +"; - if (Shiftorium.UpgradeInstalled("mud_control_centre")) - status += Environment.NewLine + $"Reputation: {SaveSystem.CurrentSave.RawReputation} ({SaveSystem.CurrentSave.Reputation})"; Console.WriteLine(status); + Console.WriteLine("Objectives:"); + try + { + if (Story.CurrentObjectives.Count > 0) + { + foreach (var obj in Story.CurrentObjectives) + { + Console.WriteLine(obj.Name); + Console.WriteLine("-------------------------------"); + Console.WriteLine(); + Console.WriteLine(obj.Description); + } + } + else + { + Console.WriteLine(" - No objectives are running. Check back later!"); + } + } + catch + { + Console.WriteLine(" - No objectives are running. Check back later!"); + } return true; } } @@ -615,7 +683,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/ConsoleEx.cs b/ShiftOS_TheReturn/ConsoleEx.cs index 90f9cc0..74483dc 100644 --- a/ShiftOS_TheReturn/ConsoleEx.cs +++ b/ShiftOS_TheReturn/ConsoleEx.cs @@ -48,5 +48,12 @@ namespace ShiftOS.Engine /// Gets or sets whether text in the Terminal is underlined. /// public static bool Underline { get; set; } + + internal static void Flush() + { + OnFlush?.Invoke(); + } + + public static Action OnFlush; } } diff --git a/ShiftOS_TheReturn/CrashHandler.cs b/ShiftOS_TheReturn/CrashHandler.cs index ed42ea5..48eaf1f 100644 --- a/ShiftOS_TheReturn/CrashHandler.cs +++ b/ShiftOS_TheReturn/CrashHandler.cs @@ -41,38 +41,41 @@ namespace ShiftOS.Engine { public class GetHardwareInfo { + // returns the processor's name for the crash public static string GetProcessorName() { - string ProcessorName = ""; + string ProcessorName = ""; // put the processors name in here sometime later ManagementObjectSearcher mos - = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Processor"); + = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Processor"); // OI CPU TELL ME YOUR NAME PLZ foreach (ManagementObject mo in mos.Get()) - ProcessorName = mo["Name"].ToString(); + ProcessorName = mo["Name"].ToString(); // see told you it puts in it there return ProcessorName; } + // same as above but instead for the gpu's name for the crash as well public static string GetGPUName() { string GPUName = ""; ManagementObjectSearcher mos - = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_VideoController"); + = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_VideoController"); //now can you tell me your name cpu kthx foreach (ManagementObject mo in mos.Get()) GPUName = mo["Name"].ToString(); return GPUName; } + // oh wow even more same, but this time its RAM AMOUNT oooh nice public static string GetRAMAmount() { var RAMAmount = ""; ManagementObjectSearcher mos - = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_PhysicalMemory"); + = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_PhysicalMemory"); //ram you too how much of you exists foreach (ManagementObject mo in mos.Get()) RAMAmount = mo["Capacity"].ToString(); - RAMAmount = (RAMAmount + " B"); + RAMAmount = (RAMAmount + " B"); // ooh and now we add "bytes" to the end return RAMAmount; } @@ -81,22 +84,24 @@ namespace ShiftOS.Engine public partial class CrashHandler : Form { + //fuck it crashed public CrashHandler() { InitializeComponent(); - //Send the bug to Debugle - // or alternatively, send to reportbug@shiftos.ml OR narodgaming@shiftos.ml + //Send the bug to Unite as a bug report + // or alternatively, send to reportbug@shiftos.ml + // or just on the discord that works too } - public static Exception HandledException = null; + public static Exception HandledException = null; // this value determines if we can try to set the game back on track or we cant do anything about it public static void Start(Exception e) { if(SaveSystem.CurrentSave != null) - TerminalBackend.InvokeCommand("sos.save"); + TerminalBackend.InvokeCommand("sos.save"); // SAVE BEFORE CRASHING ServerManager.Disconnect(); while (Application.OpenForms.Count > 0) @@ -108,6 +113,7 @@ namespace ShiftOS.Engine System.IO.FileInfo fileInfo = new System.IO.FileInfo(assembly.Location); DateTime lastModified = fileInfo.LastWriteTime; + // put all this in a text document string rtbcrash_Text = $@" === {AssemblyName} has crashed. === Game: {AssemblyName} @@ -179,11 +185,11 @@ Stack trace: } - File.WriteAllText("crash.txt", rtbcrash_Text); + File.WriteAllText("crash.txt", rtbcrash_Text); // make that text document and put above super long string in it var result = MessageBox.Show(caption: "ShiftOS - Fatal error", text: "ShiftOS has encountered a fatal error and has been shut down. Info about the error has been saved to a file called crash.txt in the same folder as the active executable. Would you like to try and recover the game session?", buttons: MessageBoxButtons.YesNo); if(result == DialogResult.Yes) { - Application.Restart(); + Application.Restart(); // tries to restart if user clicks yes, who wouldve guessed } } @@ -197,18 +203,20 @@ Stack trace: this.Close(); Application.Restart(); } - + + // make both of those variables that appear in the long string above public static string AssemblyName { get; private set; } public static string AssemblyDescription { get; private set; } + // get info about the game itself public static void SetGameMetadata(Assembly assembly) { - AssemblyName = assembly.GetName().Name; + AssemblyName = assembly.GetName().Name; // name of game foreach(var attr in assembly.GetCustomAttributes(true)) { if(attr is AssemblyDescriptionAttribute) { - AssemblyDescription = (attr as AssemblyDescriptionAttribute).Description; + AssemblyDescription = (attr as AssemblyDescriptionAttribute).Description; // description of the game } } diff --git a/ShiftOS_TheReturn/Desktop.cs b/ShiftOS_TheReturn/Desktop.cs index bc17a8e..a5e7f43 100644 --- a/ShiftOS_TheReturn/Desktop.cs +++ b/ShiftOS_TheReturn/Desktop.cs @@ -102,7 +102,14 @@ namespace ShiftOS.Engine /// Gets the name of the desktop. /// string DesktopName { get; } - + + /// + /// Show a notification on the desktop. + /// + /// An application ID (for determining what system icon to show the notification alongside) + /// The title of the notification. + /// Isn't this.... self explanatory? + void PushNotification(string app, string title, string message); /// /// Performs most of the skinning and layout handling for the desktop. @@ -266,6 +273,14 @@ namespace ShiftOS.Engine { _desktop.HideAppLauncher(); } + + public static void PushNotification(string app, string title, string msg) + { + InvokeOnWorkerThread(() => + { + _desktop.PushNotification(app, title, msg); + }); + } } // sorry i almost killed everything :P } diff --git a/ShiftOS_TheReturn/IStatusIcon.cs b/ShiftOS_TheReturn/IStatusIcon.cs new file mode 100644 index 0000000..f32d1c1 --- /dev/null +++ b/ShiftOS_TheReturn/IStatusIcon.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShiftOS.Engine +{ + public interface IStatusIcon + { + void Setup(); + + } +} diff --git a/ShiftOS_TheReturn/KernelWatchdog.cs b/ShiftOS_TheReturn/KernelWatchdog.cs index 430d36a..0608c46 100644 --- a/ShiftOS_TheReturn/KernelWatchdog.cs +++ b/ShiftOS_TheReturn/KernelWatchdog.cs @@ -10,6 +10,7 @@ namespace ShiftOS.Engine { public static class KernelWatchdog { + //store logs into a file public static void Log(string e, string desc) { string line = $"[{DateTime.Now}] <{e}> {desc}"; @@ -36,12 +37,13 @@ namespace ShiftOS.Engine } set { - if(value == false) + if(value == false) // hey game if you want to disconnect from mud do this: { foreach(var win in AppearanceManager.OpenForms) { foreach(var attr in win.ParentWindow.GetType().GetCustomAttributes(true)) { + // prevents disconnect from mud if an application that needs a connection is open if(attr is MultiplayerOnlyAttribute) { ConsoleEx.Bold = true; @@ -59,63 +61,44 @@ namespace ShiftOS.Engine } } - _mudConnected = value; + _mudConnected = value; // connects or disconnects from mud Desktop.PopulateAppLauncher(); } } - public static bool IsSafe(Type type) + public static bool IsSafe(TerminalBackend.TerminalCommand cmd) { - if (SaveSystem.CurrentUser.Permissions == Objects.UserPermissions.Root) + if (!cmd.RequiresElevation) return true; - - foreach (var attrib in type.GetCustomAttributes(false)) + else { - if (attrib is KernelModeAttribute) - { - if (SaveSystem.CurrentUser.Permissions == Objects.UserPermissions.Root) - return true; + if (SaveSystem.CurrentUser.Permissions == Objects.UserPermissions.Root) + return true; + else return false; - } } - return true; } - public static bool IsSafe(MethodInfo type) - { - if (SaveSystem.CurrentUser.Permissions == Objects.UserPermissions.Root) - return true; - foreach (var attrib in type.GetCustomAttributes(false)) - { - if (attrib is KernelModeAttribute) - { - if (SaveSystem.CurrentUser.Permissions == Objects.UserPermissions.Root) - return true; - return false; - } - } - return true; - } - - static string regularUsername = ""; + static string regularUsername = ""; //put regular username in here later public static void EnterKernelMode() { - regularUsername = SaveSystem.CurrentUser.Username; - SaveSystem.CurrentUser = SaveSystem.Users.FirstOrDefault(x => x.Username == "root"); + regularUsername = SaveSystem.CurrentUser.Username; // k for now put user's username in here for the time being + SaveSystem.CurrentUser = SaveSystem.Users.FirstOrDefault(x => x.Username == "root"); // now their username is root } public static void LeaveKernelMode() { - var user = SaveSystem.Users.FirstOrDefault(x => x.Username == regularUsername); - if (user == null) - throw new Exception("User not in root mode."); + var user = SaveSystem.Users.FirstOrDefault(x => x.Username == regularUsername); //finds username + if (user == null) + throw new Exception("User not in root mode."); // fuck this means the user isnt root quick throw error SaveSystem.CurrentUser = user; } + //determines if you can disconnect from mud if there are no applications that currently need to internal static bool CanRunOffline(Type method) { if (MudConnected) @@ -128,7 +111,8 @@ namespace ShiftOS.Engine } return true; } - + + //same as above but this time for methods internal static bool CanRunOffline(MethodInfo method) { if (MudConnected) diff --git a/ShiftOS_TheReturn/Localization.cs b/ShiftOS_TheReturn/Localization.cs index c1a6bd6..8adfa5a 100644 --- a/ShiftOS_TheReturn/Localization.cs +++ b/ShiftOS_TheReturn/Localization.cs @@ -33,6 +33,7 @@ using System.Threading.Tasks; namespace ShiftOS.Engine { + //define a whole bunch of things that are needed public interface ILanguageProvider { List GetJSONTranscripts(); @@ -51,14 +52,15 @@ namespace ShiftOS.Engine { if(_provider == null) { - return JsonConvert.DeserializeObject(Properties.Resources.languages); + return JsonConvert.DeserializeObject(Properties.Resources.languages); //collect all the languages availible } else { - return _provider.GetAllLanguages(); + return _provider.GetAllLanguages(); //also collect all the languages avalible but from a specific provider this time } } + //if no local selected, english will be loaded public static void SetupTHETRUEDefaultLocals() { if (_provider == null) @@ -79,6 +81,7 @@ namespace ShiftOS.Engine } } + // ignore this not really setup of default no no zone public static void SetupDefaultLocals(string lines, string path) { Utils.WriteAllText(Paths.GetPath(path), lines); @@ -86,13 +89,8 @@ namespace ShiftOS.Engine } - /// - /// Takes in a string and parses localization blocks into text blocks in the current language. - /// - /// "{CODEPOINTS}: 0" will come out as "Codepoints: 0" if the current language is english. - /// The string to parse - /// The parsed string. - /// + // Takes in a string and parses localization blocks into text blocks in the current language. + // example: "{CODEPOINTS}: 0" will come out as "Codepoints: 0" if the current language is english public static string Parse(string original) { return Parse(original, new Dictionary()); @@ -104,60 +102,18 @@ namespace ShiftOS.Engine Dictionary localizationStrings = new Dictionary(); - try { localizationStrings = JsonConvert.DeserializeObject>(_provider.GetCurrentTranscript()); } catch { - localizationStrings = JsonConvert.DeserializeObject>(Utils.ReadAllText(Paths.GetPath("english.local"))); + localizationStrings = JsonConvert.DeserializeObject>(Utils.ReadAllText(Paths.GetPath("english.local"))); //if no provider fall back to english } - foreach (var kv in localizationStrings) + foreach (var kv in localizationStrings.Where(x=>original.Contains(x.Key))) { - original = original.Replace(kv.Key, kv.Value); - } - - List orphaned = new List(); - if (Utils.FileExists("0:/dev_orphaned_lang.txt")) - { - orphaned = JsonConvert.DeserializeObject>(Utils.ReadAllText("0:/dev_orphaned_lang.txt")); - } - - - int start_index = 0; - int length = 0; - bool indexing = false; - - foreach (var c in original) - { - if (c == '{') - { - start_index = original.IndexOf(c); - indexing = true; - } - - if (indexing == true) - { - length++; - if (c == '}') - { - indexing = false; - string o = original.Substring(start_index, length); - if (!orphaned.Contains(o)) - { - orphaned.Add(o); - } - start_index = 0; - length = 0; - } - } - } - - if (orphaned.Count > 0) - { - Utils.WriteAllText("0:/dev_orphaned_lang.txt", JsonConvert.SerializeObject(orphaned, Formatting.Indented)); + original = original.Replace(kv.Key, kv.Value); // goes through and replaces all the localization blocks } //string original2 = Parse(original); @@ -165,42 +121,66 @@ namespace ShiftOS.Engine string usernameReplace = ""; string domainReplace = ""; + // if the user has saved then store their username and systemname in these string variables please if (SaveSystem.CurrentSave != null) { - usernameReplace = SaveSystem.CurrentSave.Username; - domainReplace = SaveSystem.CurrentSave.SystemName; + try + { + usernameReplace = SaveSystem.CurrentUser.Username; + } + catch + { + usernameReplace = "user"; + } + + try + { + domainReplace = SaveSystem.CurrentSave.SystemName; + } + catch + { + domainReplace = "system"; + } + } string namespaceReplace = ""; string commandReplace = ""; + // if the user did a command in the terminal and it had a period in it then split it up into the part before the period and the part after and then store them into these two string variables please if (TerminalBackend.latestCommmand != "" && TerminalBackend.latestCommmand.IndexOf('.') > -1) { namespaceReplace = TerminalBackend.latestCommmand.Split('.')[0]; commandReplace = TerminalBackend.latestCommmand.Split('.')[1]; } + // if you see these then replace them with what you need to Dictionary defaultReplace = new Dictionary() { {"%username", usernameReplace}, {"%domain", domainReplace}, {"%ns", namespaceReplace}, {"%cmd", commandReplace}, - {"%cp", SaveSystem.CurrentSave?.Codepoints.ToString() }, +#if LOCALIZE_CODEPOINTS + { "%cp", SaveSystem.CurrentSave?.Codepoints.ToString() }, +#endif }; - foreach (KeyValuePair replacement in replace) + // actually do the replacement + foreach (KeyValuePair replacement in replace.Where(x => original.Contains(x.Key))) { original = original.Replace(replacement.Key, Parse(replacement.Value)); } - foreach (KeyValuePair replacement in defaultReplace) + // do the replacement but default + foreach (KeyValuePair replacement in defaultReplace.Where(x => original.Contains(x.Key))) { original = original.Replace(replacement.Key, replacement.Value); } - return original; + return original; // returns the now replaced string } + // a few things are defined here public static void RegisterProvider(ILanguageProvider p) { _provider = p; diff --git a/ShiftOS_TheReturn/LoginManager.cs b/ShiftOS_TheReturn/LoginManager.cs new file mode 100644 index 0000000..d326f2c --- /dev/null +++ b/ShiftOS_TheReturn/LoginManager.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ShiftOS.Objects; + +namespace ShiftOS.Engine +{ + public static class LoginManager + { + private static ILoginFrontend _login = null; + + public static void Init(ILoginFrontend login) + { + _login = login; + } + + public static void PromptForLogin() + { + _login.LoginComplete += (user) => + { + LoginComplete?.Invoke(user); + }; + _login.Login(); + } + + public static bool ShouldUseGUILogin + { + get + { + if (_login == null) + return false; + return _login.UseGUILogin; + } + } + + public static event Action LoginComplete; + } + + /// + /// Interface for GUI-based logins. + /// + public interface ILoginFrontend + { + /// + /// When implemented, shows the login UI. + /// + void Login(); + + /// + /// Gets whether the ShiftOS engine should use a GUI-based login system or the default one. + /// + bool UseGUILogin { get; } + + + /// + /// Occurs when the login is complete. + /// + event Action LoginComplete; + + + + } +} diff --git a/ShiftOS_TheReturn/NotificationDaemon.cs b/ShiftOS_TheReturn/NotificationDaemon.cs index 77a31fc..0725782 100644 --- a/ShiftOS_TheReturn/NotificationDaemon.cs +++ b/ShiftOS_TheReturn/NotificationDaemon.cs @@ -25,6 +25,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; @@ -34,6 +35,36 @@ namespace ShiftOS.Engine { public static class NotificationDaemon { + /// + /// Gets a list of all objects that meet their Shiftorium dependencies. + /// + /// An array of s containing the found objects. + public static Type[] GetAllStatusIcons() + { + List lst = new List(); + foreach(var exec in System.IO.Directory.GetFiles(Environment.CurrentDirectory)) + { + if(exec.ToLower().EndsWith(".exe") || exec.ToLower().EndsWith(".dll")) + { + try + { + var asm = Assembly.LoadFile(exec); + foreach(var type in asm.GetTypes().Where(x => x.GetInterfaces().Contains(typeof(IStatusIcon)))) + { + if (Shiftorium.UpgradeAttributesUnlocked(type)) + { + lst.Add(type); + } + } + } + catch { } + } + } + return lst.ToArray(); + } + + + //if the notifications file already exists then get them public static Notification[] GetAllFromFile() { Notification[] notes = { }; @@ -44,23 +75,25 @@ namespace ShiftOS.Engine return notes; } + //tells the computer how it likes it to be written in the file internal static void WriteNotes(Notification[] notes) { - Utils.WriteAllText(Paths.GetPath("notifications.dat"), JsonConvert.SerializeObject(notes, Formatting.Indented)); + Utils.WriteAllText(Paths.GetPath("notifications.dat"), JsonConvert.SerializeObject(notes, Formatting.Indented)); //"write it in there indented pls" } - public static event Action NotificationMade; - + public static event Action NotificationMade; //use this if you want to know when a notification has been made + public static void AddNotification(NotificationType note, object data) { - var lst = new List(GetAllFromFile()); - lst.Add(new Engine.Notification(note, data)); + var lst = new List(GetAllFromFile()); //grabs all current notifications + lst.Add(new Engine.Notification(note, data)); //then adds the new one to the list WriteNotes(lst.ToArray()); - NotificationMade?.Invoke(lst[lst.Count - 1]); + NotificationMade?.Invoke(lst[lst.Count - 1]); //says to the program that a notification has indeed been made } public static event Action NotificationRead; + //for every notification that there is, mark them as read public static void MarkAllRead() { var notes = GetAllFromFile(); @@ -68,30 +101,33 @@ namespace ShiftOS.Engine MarkRead(i); } + //grabs list of notifcations and if the notification you want to mark as read actually exsists, then it assigns it as read public static void MarkRead(int note) { var notes = GetAllFromFile(); if (note >= notes.Length || note < 0) throw new ArgumentOutOfRangeException("note", new Exception("You cannot mark a notification that does not exist as read.")); - notes[note].Read = true; + notes[note].Read = true; //assigns the specific notification as read WriteNotes(notes); NotificationRead?.Invoke(); } - public static int GetUnreadCount() + public static int GetUnreadCount() //use this if you want the unread notification count, but i think you probably already knew that { int c = 0; foreach (var note in GetAllFromFile()) if (note.Read == false) - c++; //gahh I hate that programming language. + c++; //gahh I hate that programming language. //dont we all return c; } } + //actually gives the proper data for the notification public struct Notification { + //defaults for all notificaions public Notification(NotificationType t, object data) { Type = t; @@ -106,9 +142,10 @@ namespace ShiftOS.Engine public DateTime Timestamp { get; set; } } + //defines all the possible notificaions that can happen public enum NotificationType { - Generic = 0x00, + Generic = 0x00, //lets get generic MemoReceived = 0x10, MemoSent = 0x11, DownloadStarted = 0x20, diff --git a/ShiftOS_TheReturn/OutOfBoxExperience.cs b/ShiftOS_TheReturn/OutOfBoxExperience.cs index 6ed9e49..eb8e61d 100644 --- a/ShiftOS_TheReturn/OutOfBoxExperience.cs +++ b/ShiftOS_TheReturn/OutOfBoxExperience.cs @@ -45,17 +45,17 @@ namespace ShiftOS.Engine public static void Init(IOobe oobe) { - _oobe = oobe; + _oobe = oobe; // takes the oobe and makes it an IOobe } public static void Start(Save save) { - + //if its null then FUCK YOU DID THE WRONG THING if (_oobe == null) throw new InvalidOperationException("OOBE frontend not activated! This function can't be used! Please use OutOfBoxExperience.Init() passing an IOobe-implementing object to start the OOBE frontend."); - _oobe.StartShowing(save); + _oobe.StartShowing(save); //tells the save data to start showing the oobe } @@ -64,7 +64,7 @@ namespace ShiftOS.Engine { Desktop.InvokeOnWorkerThread(new Action(() => { - _oobe.PromptForLogin(); + _oobe.PromptForLogin(); //prompts for login, what did you expect })); } @@ -72,12 +72,13 @@ namespace ShiftOS.Engine { Desktop.InvokeOnWorkerThread(new Action(() => { - _oobe.ShowSaveTransfer(save); + _oobe.ShowSaveTransfer(save); //triggers save transfer if not done already })); } } + //triggers all the above events public interface IOobe { void StartShowing(Save save); diff --git a/ShiftOS_TheReturn/Paths.cs b/ShiftOS_TheReturn/Paths.cs index 10fd7d7..5b75ae6 100644 --- a/ShiftOS_TheReturn/Paths.cs +++ b/ShiftOS_TheReturn/Paths.cs @@ -35,8 +35,14 @@ using System.Threading; namespace ShiftOS.Engine { + /// + /// Management class for ShiftFS path variables. + /// public static class Paths { + /// + /// Initiate the path system. + /// public static void Init() { Locations = new Dictionary(); @@ -88,6 +94,10 @@ namespace ShiftOS.Engine } + /// + /// Gets all full paths without their keynames. + /// + /// A string array representing all paths. public static string[] GetAllWithoutKey() { List strings = new List(); @@ -99,11 +109,19 @@ namespace ShiftOS.Engine } + /// + /// Get the full path using a path key. + /// + /// The path key (folder/filename) for the path. + /// The full path. public static string GetPath(string id) { return Locations[id]; } + /// + /// Checks all directories in the path system to see if they exist, and if not, creates them. + /// private static void CheckPathExistence() { foreach(var path in Locations) @@ -119,8 +137,14 @@ namespace ShiftOS.Engine } } + /// + /// Gets or sets a representing all paths in the system. + /// private static Dictionary Locations { get; set; } + /// + /// Mounts the ShiftOS shared directory to 1:/, creating the directory if it does not exist. + /// public static void CreateAndMountSharedFolder() { if (!System.IO.Directory.Exists(SharedFolder)) @@ -201,9 +225,7 @@ namespace ShiftOS.Engine t.Start(); } - - - public static void ScanForDirectories(string folder, int mount) + private static void ScanForDirectories(string folder, int mount) { foreach (var file in System.IO.Directory.GetFiles(folder)) { @@ -220,10 +242,27 @@ namespace ShiftOS.Engine } } + /// + /// Gets the ShiftOS shared folder. + /// public static string SharedFolder { get { return Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\ShiftOS_Shared"; } } + + /// + /// Gets the location of the ShiftOS.mfs file. + /// public static string SaveFile { get { return Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\ShiftOS.mfs"; } } + + /// + /// Gets the path of the inner save file. + /// + [Obsolete("Not used.")] public static string SaveFileInner { get { return Locations["save.json"]; } } + /// + /// Add a path to the system. + /// + /// The path's parent directory. + /// The filename for the path. public static void AddPath(string parent, string path) { Locations.Add(path, Locations[parent] + "/" + path); diff --git a/ShiftOS_TheReturn/SaveSystem.cs b/ShiftOS_TheReturn/SaveSystem.cs index f29e5b8..e98a51e 100644 --- a/ShiftOS_TheReturn/SaveSystem.cs +++ b/ShiftOS_TheReturn/SaveSystem.cs @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ +// #define NOSAVE //#define ONLINEMODE @@ -39,6 +40,7 @@ using static System.Net.Mime.MediaTypeNames; namespace ShiftOS.Engine { + [Obsolete("Use the servers.conf file instead.")] public class EngineConfig { public bool ConnectToMud = true; @@ -46,13 +48,34 @@ namespace ShiftOS.Engine public int MudDefaultPort = 13370; } + /// + /// Management class for the ShiftOS save system. + /// public static class SaveSystem { + /// + /// Boolean representing whether the system is shutting down. + /// public static bool ShuttingDown = false; + /// + /// Gets or sets the current logged in client-side user. + /// public static ClientSave CurrentUser { get; set; } + /// + /// Boolean representing whether the save system is ready to be used. + /// + public static bool Ready = false; + /// + /// Occurs before the save system connects to the ShiftOS Digital Society. + /// + public static event Action PreDigitalSocietyConnection; + + /// + /// Gets or sets the current server-side save file. + /// public static Save CurrentSave { get; set; } /// @@ -98,64 +121,92 @@ namespace ShiftOS.Engine } Thread.Sleep(350); - Console.WriteLine("Initiating kernel..."); + Console.WriteLine("ShiftKernel v0.4.2"); + Console.WriteLine("(MIT) DevX 2017, Very Little Rights Reserved"); + Console.WriteLine(""); + Console.WriteLine("THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR"); + Console.WriteLine("IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,"); + Console.WriteLine("FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE"); + Console.WriteLine("AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER"); + Console.WriteLine("LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,"); + Console.WriteLine("OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE"); + Console.WriteLine("SOFTWARE."); + Console.WriteLine(""); Thread.Sleep(250); - Console.WriteLine("Reading filesystem..."); + Console.WriteLine("[init] Kernel boot complete."); + Console.WriteLine("[sfs] Loading SFS driver v3"); Thread.Sleep(100); - Console.WriteLine("Reading configuration..."); + Console.WriteLine("[sfs] 4096 blocks read."); + Console.WriteLine("[simpl-conf] Reading configuration files (global-3.conf)"); + Console.WriteLine("[termdb] Building command database from filesystem..."); + TerminalBackend.PopulateTerminalCommands(); + Console.WriteLine("[inetd] Connecting to network..."); - Console.WriteLine("{CONNECTING_TO_MUD}"); + Ready = false; - if (defaultConf.ConnectToMud == true) + if (PreDigitalSocietyConnection != null) { - bool guidReceived = false; - ServerManager.GUIDReceived += (str) => - { - //Connection successful! Stop waiting! - guidReceived = true; - Console.WriteLine("Connection successful."); - }; + PreDigitalSocietyConnection?.Invoke(); - try + while (!Ready) { - - ServerManager.Initiate("secondary4162.cloudapp.net", 13370); - //This haults the client until the connection is successful. - while (ServerManager.thisGuid == new Guid()) - { - Thread.Sleep(10); - } - Console.WriteLine("GUID received - bootstrapping complete."); - FinishBootstrap(); - } - catch (Exception ex) - { - //No errors, this never gets called. - Console.WriteLine("{ERROR}: " + ex.Message); - Thread.Sleep(3000); - ServerManager.StartLANServer(); - while (ServerManager.thisGuid == new Guid()) - { - Thread.Sleep(10); - } - Console.WriteLine("GUID received - bootstrapping complete."); - FinishBootstrap(); + Thread.Sleep(10); } } - else + + + + bool guidReceived = false; + ServerManager.GUIDReceived += (str) => { - ServerManager.StartLANServer(); + //Connection successful! Stop waiting! + guidReceived = true; + Console.WriteLine("[inetd] Connection successful."); + }; + + try + { + + ServerManager.Initiate(UserConfig.Get().DigitalSocietyAddress, UserConfig.Get().DigitalSocietyPort); + //This haults the client until the connection is successful. + while (ServerManager.thisGuid == new Guid()) + { + Thread.Sleep(10); + } + Console.WriteLine("[inetd] DHCP GUID recieved, finished setup"); + FinishBootstrap(); + } + catch (Exception ex) + { + //No errors, this never gets called. + Console.WriteLine("[inetd] SEVERE: " + ex.Message); + Thread.Sleep(3000); + Console.WriteLine("[sys] SEVERE: Cannot connect to server. Shutting down in 5..."); + Thread.Sleep(1000); + Console.WriteLine("[sys] 4..."); + Thread.Sleep(1000); + Console.WriteLine("[sys] 3..."); + Thread.Sleep(1000); + Console.WriteLine("[sys] 2..."); + Thread.Sleep(1000); + Console.WriteLine("[sys] 1..."); + Thread.Sleep(1000); + Console.WriteLine("[sys] Bye bye."); + System.Diagnostics.Process.GetCurrentProcess().Kill(); } //Nothing happens past this point - but the client IS connected! It shouldn't be stuck in that while loop above. - + })); thread.IsBackground = true; thread.Start(); } - public static void FinishBootstrap() + /// + /// Finish bootstrapping the engine. + /// + private static void FinishBootstrap() { KernelWatchdog.Log("mud_handshake", "handshake successful: kernel watchdog access code is \"" + ServerManager.thisGuid.ToString() + "\""); @@ -165,13 +216,21 @@ namespace ShiftOS.Engine { if (msg.Name == "mud_savefile") { - CurrentSave = JsonConvert.DeserializeObject(msg.Contents); ServerManager.MessageReceived -= savehandshake; - } + try + { + CurrentSave = JsonConvert.DeserializeObject(msg.Contents); + } + catch + { + Console.WriteLine("[system] [SEVERE] Cannot parse configuration file."); + oobe.PromptForLogin(); + } + } else if (msg.Name == "mud_login_denied") { - oobe.PromptForLogin(); ServerManager.MessageReceived -= savehandshake; + oobe.PromptForLogin(); } }; ServerManager.MessageReceived += savehandshake; @@ -196,7 +255,7 @@ namespace ShiftOS.Engine Thread.Sleep(75); Thread.Sleep(50); - Console.WriteLine("{SYSTEM_INITIATED}"); + Console.WriteLine("[usr-man] Accepting logins on local tty 1."); Sysname: bool waitingForNewSysName = false; @@ -204,7 +263,7 @@ namespace ShiftOS.Engine if (string.IsNullOrWhiteSpace(CurrentSave.SystemName)) { - Infobox.PromptText("Enter a system name", "Your system does not have a name. All systems within the digital society must have a name. Please enter one.", (name)=> + Infobox.PromptText("Enter a system name", "Your system does not have a name. All systems within the digital society must have a name. Please enter one.", (name) => { if (string.IsNullOrWhiteSpace(name)) Infobox.Show("Invalid name", "Please enter a valid name.", () => @@ -248,8 +307,34 @@ namespace ShiftOS.Engine if (CurrentSave.Users == null) CurrentSave.Users = new List(); + Console.WriteLine($@" + `-:/++++::.` + .+ydNMMMMMNNMMMMMNhs/. + /yNMMmy+:-` `````.-/ohNMMms- + `oNMMh/.`:oydmNMMMMNmhs+- .+dMMm+` Welcome to ShiftOS. + `oMMmo``+dMMMMMMMMMMMMMMMMMNh/`.sNMN+ + :NMN+ -yMMMMMMMNdhyssyyhdmNMMMMNs``sMMd. SYSTEM STATUS: + oMMd.`sMMMMMMd+. `/MMMMN+ -mMN: ---------------------- + oMMh .mMMMMMM/ `-::::-.` :MMMMMMh`.mMM: + :MMd .NMMMMMMs .dMMMMMMMMMNddMMMMMMMd`.NMN. Codepoints: {SaveSystem.CurrentSave.Codepoints} + mMM. dMMMMMMMo -mMMMMMMMMMMMMMMMMMMMMs /MMy Upgrades: {SaveSystem.CurrentSave.CountUpgrades()} installed + :MMh :MMMMMMMMm` .+shmMMMMMMMMMMMMMMMN` NMN` {Shiftorium.GetAvailable().Count()} available + oMM+ sMMMMMMMMMN+` `-/smMMMMMMMMMMM: hMM: Filesystems: {Utils.Mounts.Count} filesystems mounted in memory. + sMM+ sMMMMMMMMMMMMds/-` .sMMMMMMMMM/ yMM/ + +MMs +MMMMMMMMMMMMMMMMMmhs:` +MMMMMMMM- dMM- System name: {CurrentSave.SystemName.ToUpper()} + .MMm `NMMMMMMMMMMMMMMMMMMMMMo `NMMMMMMd .MMN Users: {Users.Count()} found. + hMM+ +MMMMMMmsdNMMMMMMMMMMN/ -MMMMMMN- yMM+ + `NMN- oMMMMMd `-/+osso+- .mMMMMMN: +MMd + -NMN: /NMMMm` :yMMMMMMm- oMMd` + -mMMs``sMMMMNdhso++///+oydNMMMMMMNo .hMMh` + `yMMm/ .omMMMMMMMMMMMMMMMMMMMMd+``oNMNo + -hMMNo. -ohNMMMMMMMMMMMMmy+. -yNMNy` + .sNMMms/. `-/+++++/:-` ./yNMMmo` + :sdMMMNdyso+++ooshdNMMMdo- + `:+yhmNNMMMMNNdhs+- + ```` "); - if(CurrentSave.Users.Count == 0) + if (CurrentSave.Users.Count == 0) { CurrentSave.Users.Add(new ClientSave { @@ -257,76 +342,107 @@ namespace ShiftOS.Engine Password = "", Permissions = UserPermissions.Root }); - Console.WriteLine("No users found. Creating new user with username \"root\", with no password."); + Console.WriteLine("[usr-man] WARN: No users found. Creating new user with username \"root\", with no password."); } TerminalBackend.InStory = false; TerminalBackend.PrefixEnabled = false; - Login: - string username = ""; - int progress = 0; - bool goback = false; - TextSentEventHandler ev = null; - ev = (text) => + if (LoginManager.ShouldUseGUILogin) { - if (progress == 0) + Action Completed = null; + Completed += (user) => { - if (!string.IsNullOrWhiteSpace(text)) + CurrentUser = user; + LoginManager.LoginComplete -= Completed; + }; + LoginManager.LoginComplete += Completed; + Desktop.InvokeOnWorkerThread(() => + { + LoginManager.PromptForLogin(); + }); + while (CurrentUser == null) + { + Thread.Sleep(10); + } + } + else + { + + Login: + string username = ""; + int progress = 0; + bool goback = false; + TextSentEventHandler ev = null; + ev = (text) => + { + if (progress == 0) { - if (CurrentSave.Users.FirstOrDefault(x => x.Username == text) == null) + string loginstr = CurrentSave.SystemName + " login: "; + string getuser = text.Remove(0, loginstr.Length); + if (!string.IsNullOrWhiteSpace(getuser)) { - Console.WriteLine("User not found."); + if (CurrentSave.Users.FirstOrDefault(x => x.Username == getuser) == null) + { + Console.WriteLine(); + Console.WriteLine("User not found."); + goback = true; + progress++; + TerminalBackend.TextSent -= ev; + return; + } + username = getuser; + progress++; + } + else + { + Console.WriteLine(); + Console.WriteLine("Username not provided."); + TerminalBackend.TextSent -= ev; goback = true; progress++; - TerminalBackend.TextSent -= ev; - return; } - username = text; - progress++; } - else + else if (progress == 1) { - Console.WriteLine("Username not provided."); + string passwordstr = "password: "; + string getpass = text.Remove(0, passwordstr.Length); + var user = CurrentSave.Users.FirstOrDefault(x => x.Username == username); + if (user.Password == getpass) + { + Console.WriteLine(); + Console.WriteLine("Welcome to ShiftOS."); + CurrentUser = user; + progress++; + } + else + { + Console.WriteLine(); + Console.WriteLine("Access denied."); + goback = true; + progress++; + } TerminalBackend.TextSent -= ev; - goback = true; - progress++; } - } - else if (progress == 1) + }; + TerminalBackend.TextSent += ev; + Console.WriteLine(); + Console.Write(CurrentSave.SystemName + " login: "); + ConsoleEx.Flush(); + while (progress == 0) { - var user = CurrentSave.Users.FirstOrDefault(x => x.Username == username); - if (user.Password == text) - { - Console.WriteLine("Welcome to ShiftOS."); - CurrentUser = user; - Thread.Sleep(2000); - progress++; - } - else - { - Console.WriteLine("Access denied."); - goback = true; - progress++; - } - TerminalBackend.TextSent -= ev; + Thread.Sleep(10); } - }; - TerminalBackend.TextSent += ev; - Console.WriteLine(CurrentSave.SystemName + " login:"); - while(progress == 0) - { - Thread.Sleep(10); + if (goback) + goto Login; + Console.WriteLine(); + Console.Write("password: "); + ConsoleEx.Flush(); + while (progress == 1) + Thread.Sleep(10); + if (goback) + goto Login; } - if (goback) - goto Login; - Console.WriteLine("password:"); - while (progress == 1) - Thread.Sleep(10); - if (goback) - goto Login; - - TerminalBackend.PrefixEnabled = true; Shiftorium.LogOrphanedUpgrades = true; Desktop.InvokeOnWorkerThread(new Action(() => @@ -337,10 +453,26 @@ namespace ShiftOS.Engine Desktop.InvokeOnWorkerThread(new Action(() => Desktop.PopulateAppLauncher())); GameReady?.Invoke(); + + if (!string.IsNullOrWhiteSpace(CurrentSave.PickupPoint)) + { + try + { + Story.Start(CurrentSave.PickupPoint); + TerminalBackend.PrintPrompt(); + } + catch { } + } } + /// + /// Delegate type for events with no caller objects or event arguments. You can use the () => {...} (C#) lambda expression with this delegate + /// public delegate void EmptyEventHandler(); + /// + /// Gets a list of all client-side users. + /// public static List Users { get @@ -349,20 +481,35 @@ namespace ShiftOS.Engine } } + /// + /// Occurs when the engine is loaded and the game can take over. + /// public static event EmptyEventHandler GameReady; - public static void TransferCodepointsToVoid(long amount) + /// + /// Deducts a set amount of Codepoints from the save file... and sends them to a place where they'll never be seen again. + /// + /// The amount of Codepoints to deduct. + public static void TransferCodepointsToVoid(ulong amount) { + if (amount < 0) + throw new ArgumentOutOfRangeException("We see what you did there. Trying to pull Codepoints from the void? That won't work."); CurrentSave.Codepoints -= amount; NotificationDaemon.AddNotification(NotificationType.CodepointsSent, amount); } + /// + /// Restarts the game. + /// public static void Restart() { TerminalBackend.InvokeCommand("sos.shutdown"); System.Windows.Forms.Application.Restart(); } + /// + /// Requests the save file from the server. If authentication fails, this will cause the user to be prompted for their website login and a new save will be created if none is associated with the login. + /// public static void ReadSave() { //Migrate old saves. @@ -406,6 +553,9 @@ namespace ShiftOS.Engine } + /// + /// Creates a new save, starting the Out Of Box Experience (OOBE). + /// public static void NewSave() { AppearanceManager.Invoke(new Action(() => @@ -418,31 +568,57 @@ namespace ShiftOS.Engine })); } + /// + /// Saves the game to the server, updating website stats if possible. + /// public static void SaveGame() { +#if !NOSAVE if(!Shiftorium.Silent) Console.WriteLine(""); if(!Shiftorium.Silent) Console.Write("{SE_SAVING}... "); if (SaveSystem.CurrentSave != null) { - Utils.WriteAllText(Paths.GetPath("user.dat"), CurrentSave.UniteAuthToken); - ServerManager.SendMessage("mud_save", JsonConvert.SerializeObject(CurrentSave, Formatting.Indented)); + Utils.WriteAllText(Paths.GetPath("user.dat"), CurrentSave.UniteAuthToken); + var serialisedSaveFile = JsonConvert.SerializeObject(CurrentSave, Formatting.Indented); + new Thread(() => + { + // please don't do networking on the main thread if you're just going to + // discard the response, it's extremely slow + ServerManager.SendMessage("mud_save", serialisedSaveFile); + }) + { IsBackground = false }.Start(); } if (!Shiftorium.Silent) Console.WriteLine(" ...{DONE}."); System.IO.File.WriteAllText(Paths.SaveFile, Utils.ExportMount(0)); +#endif } - public static void TransferCodepointsFrom(string who, long amount) + /// + /// Transfers codepoints from an arbitrary character to the save file. + /// + /// The character name + /// The amount of Codepoints. + public static void TransferCodepointsFrom(string who, ulong amount) { + if (amount < 0) + throw new ArgumentOutOfRangeException("We see what you did there... You can't just give a fake character Codepoints like that. It's better if you transfer them to the void."); NotificationDaemon.AddNotification(NotificationType.CodepointsReceived, amount); CurrentSave.Codepoints += amount; } } + /// + /// Delegate for handling Terminal text input. + /// + /// The text inputted by the user (including prompt text). public delegate void TextSentEventHandler(string text); + /// + /// Denotes that this Terminal command or namespace is for developers. + /// public class DeveloperAttribute : Attribute { diff --git a/ShiftOS_TheReturn/Scripting.cs b/ShiftOS_TheReturn/Scripting.cs index d96bc98..5021f50 100644 --- a/ShiftOS_TheReturn/Scripting.cs +++ b/ShiftOS_TheReturn/Scripting.cs @@ -38,31 +38,65 @@ using System.Net; namespace ShiftOS.Engine.Scripting { + /// + /// Brings some C# goodies to the Lua system. + /// [Exposed("strutils")] public class StringUtils { + /// + /// Checks if a string ends with a specified string. + /// + /// The string to operate on + /// The string to check for + /// Whether ends with . public bool endswith(string operand, string value) { return operand.EndsWith(value); } + + /// + /// Checks if a string starts with a specified string. + /// + /// The string to operate on + /// The string to check for + /// Whether starts with . public bool startswith(string operand, string value) { return operand.StartsWith(value); } + /// + /// Checks if a string contains a specified string. + /// + /// The string to operate on + /// The string to check for + /// Whether contains . public bool contains(string operand, string value) { return operand.Contains(value); } } - + /// + /// DynamicLua wrapper for the ShiftOS engine. + /// public class LuaInterpreter { + /// + /// The DynamicLua backend. + /// public dynamic Lua = new DynamicLua.DynamicLua(); + + /// + /// Boolean representing whether the script is running. + /// public bool Running = true; + /// + /// Static constructor for the class. + /// static LuaInterpreter() { ServerManager.MessageReceived += (msg) => @@ -83,12 +117,21 @@ namespace ShiftOS.Engine.Scripting }; } + /// + /// Create a .SFT representation of a Lua script. + /// + /// The Lua code to convert + /// Base64 SFT representation. public static string CreateSft(string lua) { byte[] bytes = Encoding.UTF8.GetBytes(lua); return Convert.ToBase64String(bytes); } + /// + /// Run a compressed .SFT file as a lua script. + /// + /// The .sft file to run. public static void RunSft(string sft) { if (Utils.FileExists(sft)) @@ -108,8 +151,14 @@ namespace ShiftOS.Engine.Scripting } } + /// + /// Get the current working directory of the script. + /// public static string CurrentDirectory { get; private set; } + /// + /// Creates a new instance of the class. + /// public LuaInterpreter() { Lua(@"function totable(clrlist) @@ -128,6 +177,9 @@ end"); }; } + /// + /// Scans the engine, frontend, and all mods for Lua-exposed classes and functions. + /// public void SetupAPIs() { Lua.currentdir = (string.IsNullOrWhiteSpace(CurrentDirectory)) ? "0:" : CurrentDirectory; @@ -233,7 +285,10 @@ end"); }); } - + /// + /// Executes the specified file as an uncompressed Lua script. + /// + /// The file to execute. public void ExecuteFile(string file) { if (Utils.FileExists(file)) @@ -247,13 +302,17 @@ end"); } } + /// + /// Executes the specified string as a Lua script. + /// + /// The Lua code to execute. public void Execute(string lua) { try { Console.WriteLine(""); Lua(lua); - Console.WriteLine($"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}:~$ "); + Console.WriteLine($"{SaveSystem.CurrentUser.Username}@{SaveSystem.CurrentSave.SystemName}:~$ "); } catch (Exception e) { @@ -279,24 +338,46 @@ end"); } } + /// + /// Lua functions for .sft files. + /// [Exposed("sft")] public class SFTFunctions { + /// + /// Make a .sft file from a lua code string + /// + /// The Lua code + /// The resulting .sft string public string make(string lua) { return LuaInterpreter.CreateSft(lua); } + /// + /// Make a .sft string and save to a specified file. + /// + /// The Lua code to compress + /// The path to save the compressed .sft file to. public void makefile(string lua, string outpath) { Utils.WriteAllText(outpath, make(lua)); } + /// + /// Run a compressed .sft file in the . + /// + /// The .sft file to run. public void run(string inpath) { LuaInterpreter.RunSft(inpath); } + /// + /// Reads the specified .sft file and decompresses to it's Lua form. + /// + /// The .sft file to uncompress + /// The resulting Lua code. public string unmake(string sft) { if (Utils.FileExists(sft)) @@ -310,9 +391,17 @@ end"); } } + /// + /// Network functions for Lua. + /// [Exposed("net")] public class NetFunctions { + /// + /// Submit a GET request to the specified URL. + /// + /// The URL to open + /// The result from the server public string get(string url) { return new WebClient().DownloadString(url); @@ -320,26 +409,48 @@ end"); } + /// + /// Console functions for Lua. + /// [Exposed("console")] public class ConsoleFunctions { + /// + /// Write text to the console. + /// + /// The text to write. public void write(dynamic text) { Console.Write(text.ToString()); } + /// + /// Write text to the console, followed by a new line. + /// + /// The text to write. public void writeLine(dynamic text) { Console.WriteLine(text.ToString()); } } + /// + /// The main ShiftOS API. + /// [Exposed("sos")] public class SystemFunctions { - public long getCodepoints() { return SaveSystem.CurrentSave.Codepoints; } - + /// + /// Retrieves the user's Codepoints from the save file. + /// + /// The user's Codepoints. + public ulong getCodepoints() { return SaveSystem.CurrentSave.Codepoints; } + /// + /// Run a command in the Terminal. + /// + /// The command to run, using regular ShiftOS syntax. + /// Whether the command was found and ran. public bool runCommand(string cmd) { var args = TerminalBackend.GetArgs(ref cmd); @@ -347,7 +458,11 @@ end"); return TerminalBackend.RunClient(cmd, args); } - public void addCodepoints(int cp) + /// + /// Adds the specified amount of Codepoints to the save flie. + /// + /// The codepoints to add. + public void addCodepoints(uint cp) { if (cp > 100 || cp <= 0) { @@ -361,128 +476,227 @@ end"); } } - [Exposed("mud")] - public class MUDFunctions - { - public void sendDiagnostic(string src, string cat, object val) - { - ServerManager.SendMessage("diag_log", $"[{src}] <{cat}>: {val}"); - } - } - + /// + /// User information API. + /// [Exposed("userinfo")] public class UserInfoFunctions { + /// + /// Gets the user name of the currently logged in user. + /// + /// The user's username. public string getUsername() { - return SaveSystem.CurrentSave.Username; + return SaveSystem.CurrentUser.Username; } + /// + /// Retrieves the user's system name. + /// + /// The user's system name. public string getSysname() { return SaveSystem.CurrentSave.SystemName; } + /// + /// Gets the user's ShiftOS email (username@sysname). + /// + /// The user's email. public string getEmail() { return getUsername() + "@" + getSysname(); } } - + /// + /// Infobox API for Lua. + /// [Exposed("infobox")] public class InfoboxFunctions { + /// + /// Show a message to the user in an Infobox. + /// + /// The title of the Infobox + /// The infobox's message + /// A function to run when the user clicks "OK" public void show(string title, string message, Action callback = null) { Infobox.Show(title, message, callback); } + /// + /// Ask a simple yes/no question to the user using an Infobox. + /// + /// The title of the Infobox + /// The infobox's message + /// A function to run when they choose an option. The boolean argument will be true if the user clicks Yes, and false if they click No. public void question(string title, string message, Action callback) { Infobox.PromptYesNo(title, message, callback); } - public void input(string title, string message, Action callback) + /// + /// Prompt the user for text using an Infobox. + /// + /// The infobox's title + /// The infobox's message + /// A function to run when the user clicks "OK". The string value is the text entered by the user. + /// Whether the text box should hide its characters as if it were a password box. + public void input(string title, string message, Action callback, bool isPassword = false) { - Infobox.PromptText(title, message, callback); + Infobox.PromptText(title, message, callback, isPassword); } } + /// + /// File Skimmer API for Lua. + /// [Exposed("fileskimmer")] public class FileSkimmerFunctions { + /// + /// Opens a File Skimmer "Open File" dialog. + /// + /// Semicolon-separated list of file extensions that the opener should let through the filter. + /// Function to be called when the user chooses a file. The string value is the file's path. public void openFile(string extensions, Action callback) { FileSkimmerBackend.GetFile(extensions.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries), FileOpenerStyle.Open, callback); } + /// + /// Opens a File Skimmer "Save File" dialog. + /// + /// Semicolon-separated list of file extensions that the opener should let through the filter. + /// Function to be called when the user chooses a file. The string value is the file's path. public void saveFile(string extensions, Action callback) { FileSkimmerBackend.GetFile(extensions.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries), FileOpenerStyle.Save, callback); } } + /// + /// ShiftFS API for Lua. + /// [Exposed("fs")] public class ShiftFSFunctions { + /// + /// Read all text in a file to a string. + /// + /// The file path to read + /// The string containing the file's contents. public string readAllText(string path) { return Utils.ReadAllText(path); } + /// + /// Copy a file from one place to another. + /// + /// The source file + /// The destination path public void copy(string i, string o) { Utils.WriteAllBytes(o, Utils.ReadAllBytes(i)); } + /// + /// Gets all files in the specified directory. + /// + /// The directory to search + /// A string array containing all file paths in the directory. public string[] getFiles(string dir) { return Utils.GetFiles(dir); } + /// + /// Gets all directories inside a directory. + /// + /// The directory to search + /// A string array containing all directory paths in the directory. public string[] getDirectories(string dir) { return Utils.GetDirectories(dir); } + /// + /// Read the binary contents of a file to a array. + /// + /// The file path to read. + /// The resulting byte array. public byte[] readAllBytes(string path) { return Utils.ReadAllBytes(path); } + /// + /// Writes the specified text to a file. + /// + /// The file path + /// The text to write public void writeAllText(string path, string contents) { Utils.WriteAllText(path, contents); } + /// + /// Writes the specified binary data to a file. + /// + /// The file path. + /// The binary data public void writeAllBytes(string path, byte[] contents) { Utils.WriteAllBytes(path, contents); } + /// + /// Determines whether the specified path exists and is a file. + /// + /// The path to search + /// The result of the search. public bool fileExists(string path) { return Utils.FileExists(path); } + /// + /// Determines whether the specified path exists and is a directory. + /// + /// The path to search + /// The result of the search. public bool directoryExists(string path) { return Utils.DirectoryExists(path); } + /// + /// Deletes the file/directory at the specified path. + /// + /// The path to delete public void delete(string path) { Utils.Delete(path); } + /// + /// Creates a new directory at the specified path. + /// + /// The path to create public void createDirectory(string path) { Utils.CreateDirectory(path); } } - + /// + /// Marks the specified class as a Lua API object. + /// + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public class ExposedAttribute : Attribute { /// @@ -494,6 +708,9 @@ end"); Name = name; } + /// + /// The API object's name + /// public string Name { get; private set; } } } diff --git a/ShiftOS_TheReturn/Server.cs b/ShiftOS_TheReturn/Server.cs new file mode 100644 index 0000000..ddbd15b --- /dev/null +++ b/ShiftOS_TheReturn/Server.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ShiftOS.Objects; + +namespace ShiftOS.Engine +{ + public interface Server + { + /// + /// Occurs when someone sends a message to the server. + /// + /// The message from the client. + void MessageReceived(ServerMessage msg); + } + + [AttributeUsage(AttributeTargets.Class, AllowMultiple=false)] + public class ServerAttribute : Attribute + { + public ServerAttribute(string name, int port) + { + Name = name; + Port = port; + } + + + /// + /// Gets the name of the server. + /// + public string Name { get; } + + /// + /// Gets the port of the server. + /// + public int Port { get; } + + } +} diff --git a/ShiftOS_TheReturn/ServerManager.cs b/ShiftOS_TheReturn/ServerManager.cs index 792b38d..1439c0d 100644 --- a/ShiftOS_TheReturn/ServerManager.cs +++ b/ShiftOS_TheReturn/ServerManager.cs @@ -36,31 +36,55 @@ using static ShiftOS.Engine.SaveSystem; using Newtonsoft.Json; using System.Net.Sockets; using System.Diagnostics; +using System.IO; +using System.Reflection; namespace ShiftOS.Engine { + /// + /// Digital Society connection management class. + /// public static class ServerManager { + /// + /// Print connection diagnostic information. + /// public static void PrintDiagnostics() { Console.WriteLine($@"{{CLIENT_DIAGNOSTICS}} {{GUID}}: {thisGuid} +Ping: {ServerManager.DigitalSocietyPing} ms {{CLIENT_DATA}}: {JsonConvert.SerializeObject(client, Formatting.Indented)}"); } + /// + /// Gets the unique identifier for this Digital Society connection. This can be used for peer-to-peer communication between two clients. + /// public static Guid thisGuid { get; private set; } - private static NetObjectClient client { get; set; } + + /// + /// Gets the underlying NetSockets client for this connection. + /// + public static NetObjectClient client { get; private set; } + + private static bool UserDisconnect = false; - public static TimeSpan DigitalSocietyPing + /// + /// Gets or sets the server response time for the last request made by this client. + /// + public static long DigitalSocietyPing { get; private set; } + /// + /// Disconnect from the digital society intentionally. + /// public static void Disconnect() { UserDisconnect = true; @@ -72,38 +96,59 @@ namespace ShiftOS.Engine } + /// + /// Occurs when you are disconnected from the Digital Society. + /// public static event EmptyEventHandler Disconnected; - - public static void InitiateMUDHack() + + /// + /// Occurs when the unique ID for this client is sent by the server. + /// + public static event Action GUIDReceived; + + private static void delegateToServer(ServerMessage msg) { - MessageReceived += ServerManager_MessageReceived; - SendMessage("mudhack_init", ""); + string[] split = msg.GUID.Split('|'); + bool finished = false; + foreach (var exec in Directory.GetFiles(Environment.CurrentDirectory)) + { + if(exec.ToLower().EndsWith(".exe") || exec.ToLower().EndsWith(".dll")) + { + try + { + var asm = Assembly.LoadFile(exec); + foreach(var type in asm.GetTypes().Where(x => x.GetInterfaces().Contains(typeof(Server)))) + { + var attrib = type.GetCustomAttributes().FirstOrDefault(x => x is ServerAttribute) as ServerAttribute; + if(attrib != null) + { + if(split[0] == SaveSystem.CurrentSave.SystemName && split[1] == attrib.Port.ToString()) + { + if (Shiftorium.UpgradeAttributesUnlocked(type)) + { + type.GetMethods(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(x => x.Name == "MessageReceived")?.Invoke(Activator.CreateInstance(type), null); + finished = true; + } + } + } + } + } + catch { } + } + } + if (finished == false) + { + Forward(split[2], "Error", $"{split[0]}:{split[1]}: connection refused"); + } } - public static event Action ServerPasswordGenerated; - public static event EmptyEventHandler ServerAccessGranted; - public static event EmptyEventHandler ServerAccessDenied; - public static event Action GUIDReceived; - public static event Action> UsersReceived; private static void ServerManager_MessageReceived(ServerMessage msg) { switch(msg.Name) { - case "mudhack_users": - UsersReceived?.Invoke(JsonConvert.DeserializeObject>(msg.Contents)); - break; - case "mudhack_init": - ServerPasswordGenerated?.Invoke(msg.Contents); - break; - case "mudhack_denied": - ServerAccessDenied?.Invoke(); - break; - case "mudhack_granted": - ServerAccessGranted?.Invoke(); - break; case "getguid_fromserver": - if(SaveSystem.CurrentSave.Username == msg.Contents) + if(SaveSystem.CurrentUser.Username == msg.Contents) { client.Send(new NetObject("yes_i_am", new ServerMessage { @@ -113,17 +158,45 @@ namespace ShiftOS.Engine })); } break; + case "msgtosys": + try + { + var m = JsonConvert.DeserializeObject(msg.Contents); + if(m.GUID.Split('|')[2] != thisGuid.ToString()) + { + delegateToServer(m); + } + } + catch { } + break; case "getguid_reply": GUIDReceived?.Invoke(msg.Contents); break; } } + public static void SendMessageToIngameServer(string sysname, int port, string title, string contents) + { + var smsg = new ServerMessage + { + Name = title, + GUID = $"{sysname}|{port}|{thisGuid.ToString()}", + Contents = contents + }; + Forward("all", "msgtosys", JsonConvert.SerializeObject(smsg)); + + } + public static void Detach_ServerManager_MessageReceived() { MessageReceived -= new ServerMessageReceived(ServerManager_MessageReceived); } + /// + /// Initiate a new Digital Society connection. + /// + /// The IP address or hostname of the target server + /// The target port. public static void Initiate(string mud_address, int port) { client = new NetObjectClient(); @@ -131,6 +204,7 @@ namespace ShiftOS.Engine { if (!UserDisconnect) { + Desktop.PushNotification("digital_society_connection", "Disconnected from Digital Society.", "The ShiftOS kernel has been disconnected from the Digital Society. We are attempting to re-connect you."); TerminalBackend.PrefixEnabled = true; ConsoleEx.ForegroundColor = ConsoleColor.Red; ConsoleEx.Bold = true; @@ -148,7 +222,7 @@ namespace ShiftOS.Engine { if (PingTimer.IsRunning) { - DigitalSocietyPing = PingTimer.Elapsed; + DigitalSocietyPing = PingTimer.ElapsedMilliseconds; PingTimer.Reset(); } var msg = a.Data.Object as ServerMessage; @@ -170,9 +244,9 @@ namespace ShiftOS.Engine else if(msg.Name == "update_your_cp") { var args = JsonConvert.DeserializeObject>(msg.Contents); - if(args["username"] as string == SaveSystem.CurrentSave.Username) + if(args["username"] as string == SaveSystem.CurrentUser.Username) { - SaveSystem.CurrentSave.Codepoints += (long)args["amount"]; + SaveSystem.CurrentSave.Codepoints += (ulong)args["amount"]; Desktop.InvokeOnWorkerThread(new Action(() => { Infobox.Show($"MUD Control Centre", $"Someone bought an item in your shop, and they have paid {args["amount"]}, and as such, you have been granted these Codepoints."); @@ -221,6 +295,11 @@ namespace ShiftOS.Engine private static Stopwatch PingTimer = new Stopwatch(); + /// + /// Send a message to the server. + /// + /// The message name + /// The message body public static void SendMessage(string name, string contents) { var sMsg = new ServerMessage @@ -237,38 +316,33 @@ namespace ShiftOS.Engine private static bool singleplayer = false; public static bool IsSingleplayer { get { return singleplayer; } } - public static void StartLANServer() - { - singleplayer = true; - ShiftOS.Server.Program.ServerStarted += (address) => - { - Console.WriteLine($"Connecting to {address}..."); - Initiate(address, 13370); - }; - Disconnected += () => - { - ShiftOS.Server.Program.Stop(); - }; - ShiftOS.Server.Program.Main(new[] { "" }); - - - } - - + /// + /// Occurs when the server sends a message to this client. + /// public static event ServerMessageReceived MessageReceived; - public static void Forward(string targetGUID, string v, string message) + /// + /// Send a message to another client. + /// + /// The target client GUID. + /// The message title + /// The message contents + public static void Forward(string targetGUID, string title, string message) { var smsg = new ServerMessage { GUID = targetGUID, - Name = v, + Name = title, Contents = message }; ServerManager.SendMessage("mud_forward", JsonConvert.SerializeObject(smsg)); } } + /// + /// Delegate for handling server messages + /// + /// A server message containing the protocol message name, GUID of the sender, and the contents of the message. public delegate void ServerMessageReceived(ServerMessage msg); public class MultiplayerOnlyAttribute : Attribute diff --git a/ShiftOS_TheReturn/ShiftOS.Engine.csproj b/ShiftOS_TheReturn/ShiftOS.Engine.csproj index fb33dc5..f70c41e 100644 --- a/ShiftOS_TheReturn/ShiftOS.Engine.csproj +++ b/ShiftOS_TheReturn/ShiftOS.Engine.csproj @@ -109,8 +109,10 @@ + + @@ -123,6 +125,7 @@ + @@ -131,10 +134,7 @@ - - - Infobox.cs @@ -163,10 +163,6 @@ {A069089A-8962-4607-B2B2-4CF4A371066E} ShiftOS.Objects - - {226C63B4-E60D-4949-B4E7-7A2DDBB96776} - ShiftOS.Server - diff --git a/ShiftOS_TheReturn/ShiftnetSite.cs b/ShiftOS_TheReturn/ShiftnetSite.cs index 5460171..07b4698 100644 --- a/ShiftOS_TheReturn/ShiftnetSite.cs +++ b/ShiftOS_TheReturn/ShiftnetSite.cs @@ -6,13 +6,34 @@ using System.Threading.Tasks; namespace ShiftOS.Engine { + /// + /// Interface for creating a Shiftnet website. + /// public interface IShiftnetSite { + /// + /// Called when the page is loaded. Perform data population here. + /// void Setup(); + + /// + /// Occurs when a ShiftOS skin is loaded. + /// void OnSkinLoad(); + + /// + /// Occurs when a Shiftorium upgrade is installed. + /// void OnUpgrade(); + /// + /// Invoke this to navigate the parent browser to a specified Shiftnet URL. + /// event Action GoToUrl; + + /// + /// Invoke this to tell the parent browser to navigate to the previous page. + /// event Action GoBack; } @@ -24,14 +45,35 @@ namespace ShiftOS.Engine } + /// + /// Interface for creating a Shiftnet client. + /// public interface IShiftnetClient { + /// + /// Navigates the client to a specified Shiftnet URL. + /// + /// The URL to navigate to. void NavigateToUrl(string url); + + /// + /// Refreshes the current page. + /// void RefreshSite(); } + /// + /// Marks this class as a Shiftnet website. + /// + [AttributeUsage(AttributeTargets.Class, AllowMultiple =false)] public class ShiftnetSiteAttribute : Attribute { + /// + /// Creates a new instance of the class. + /// + /// The URL that links to this site + /// The name of this site + /// The description of this site public ShiftnetSiteAttribute(string url, string name, string description) { Url = url; @@ -39,8 +81,19 @@ namespace ShiftOS.Engine Description = description; } + /// + /// Gets the Shiftnet URL for this site. + /// public string Url { get; private set; } + + /// + /// Gets the name of this website. + /// public string Name { get; private set; } + + /// + /// Gets the description of this website. + /// public string Description { get; private set; } } } diff --git a/ShiftOS_TheReturn/Shiftorium.cs b/ShiftOS_TheReturn/Shiftorium.cs index ad60134..975939f 100644 --- a/ShiftOS_TheReturn/Shiftorium.cs +++ b/ShiftOS_TheReturn/Shiftorium.cs @@ -34,6 +34,9 @@ using System.Diagnostics; namespace ShiftOS.Engine { + /// + /// Backend class for the Shiftorium. + /// public static class Shiftorium { /// @@ -49,11 +52,11 @@ namespace ShiftOS.Engine public static string[] GetCategories(bool onlyAvailable = true) { List cats = new List(); - IEnumerable < ShiftoriumUpgrade > upgrades = GetDefaults(); + IEnumerable upgrades = GetDefaults(); if (onlyAvailable) upgrades = new List(GetAvailable()); - foreach(var upg in upgrades) + foreach (var upg in upgrades) { if (!cats.Contains(upg.Category)) cats.Add(upg.Category); @@ -62,11 +65,19 @@ namespace ShiftOS.Engine return cats.ToArray(); } + /// + /// Causes the engine to alert the frontend of a new Shiftorium upgrade install. + /// public static void InvokeUpgradeInstalled() { Installed?.Invoke(); } + /// + /// Gets the category of an upgrade. + /// + /// The upgrade ID to check + /// "Other" if the upgrade is not found, else, the upgrade category. public static string GetCategory(string id) { var upg = GetDefaults().FirstOrDefault(x => x.ID == id); @@ -75,19 +86,35 @@ namespace ShiftOS.Engine return (upg.Category == null) ? "Other" : upg.Category; } + /// + /// Gets all upgrades in a given category. + /// + /// The category name to search + /// The upgrades in the category. public static IEnumerable GetAllInCategory(string cat) { return GetDefaults().Where(x => x.Category == cat); } + /// + /// Gets whether or not the user has installed all upgrades in a category. + /// + /// The category to search. + /// Boolean value representing whether the user has installed all upgrades in the category. 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, long cost) + /// + /// Buy an upgrade, deducting the specified amount of Codepoints. + /// + /// The upgrade ID to buy + /// The amount of Codepoints to deduct + /// True if the upgrade was installed successfully, false if the user didn't have enough Codepoints or the upgrade wasn' found. + public static bool Buy(string id, ulong cost) { - if(SaveSystem.CurrentSave.Codepoints >= cost) + if (SaveSystem.CurrentSave.Codepoints >= cost) { SaveSystem.CurrentSave.Upgrades[id] = true; TerminalBackend.InvokeCommand("sos.save"); @@ -99,17 +126,22 @@ namespace ShiftOS.Engine } else { - if(!Silent) + if (!Silent) Console.WriteLine($"{{SHIFTORIUM_NOTENOUGHCP}}: {cost} > {SaveSystem.CurrentSave.Codepoints}"); return false; } } + /// + /// Determines whether all Shiftorium upgrade attributes for this type have been installed. + /// + /// The type to scan + /// Boolean value representing the result of this function. public static bool UpgradeAttributesUnlocked(Type type) { - foreach(var attr in type.GetCustomAttributes(true)) + foreach (var attr in type.GetCustomAttributes(true)) { - if(attr is RequiresUpgradeAttribute) + if (attr is RequiresUpgradeAttribute) { var rAttr = attr as RequiresUpgradeAttribute; return rAttr.Installed; @@ -119,6 +151,11 @@ namespace ShiftOS.Engine return true; } + /// + /// Determines whether all Shiftorium upgrade attributes for this method have been installed. + /// + /// The method to scan + /// Boolean value representing the result of this function. public static bool UpgradeAttributesUnlocked(MethodInfo type) { foreach (var attr in type.GetCustomAttributes(true)) @@ -133,6 +170,11 @@ namespace ShiftOS.Engine return true; } + /// + /// Determines whether all Shiftorium upgrade attributes for this property have been installed. + /// + /// The property to scan + /// Boolean value representing the result of this function. public static bool UpgradeAttributesUnlocked(PropertyInfo type) { foreach (var attr in type.GetCustomAttributes(true)) @@ -147,6 +189,11 @@ namespace ShiftOS.Engine return true; } + /// + /// Determines whether all Shiftorium upgrade attributes for this field have been installed. + /// + /// The field to scan + /// Boolean value representing the result of this function. public static bool UpgradeAttributesUnlocked(FieldInfo type) { foreach (var attr in type.GetCustomAttributes(true)) @@ -161,15 +208,140 @@ namespace ShiftOS.Engine return true; } + private static List upgDb = null; + + public static void CreateUpgradeDatabase() + { + upgDb = new List(); + //Now we probe for ShiftoriumUpgradeAttributes for mods. + foreach (var file in System.IO.Directory.GetFiles(Environment.CurrentDirectory)) + { + if (file.EndsWith(".exe") || file.EndsWith(".dll")) + { + try + { + var asm = Assembly.LoadFile(file); + foreach (var type in asm.GetTypes()) + { + if (type.GetInterfaces().Contains(typeof(IShiftoriumProvider))) + { + if (type.GetCustomAttributes().FirstOrDefault(x => x is ShiftoriumProviderAttribute) != null) + { + var _p = Activator.CreateInstance(type, null) as IShiftoriumProvider; + upgDb.AddRange(_p.GetDefaults()); + } + } + + + ShiftoriumUpgradeAttribute attrib = type.GetCustomAttributes(false).FirstOrDefault(x => x is ShiftoriumUpgradeAttribute) as ShiftoriumUpgradeAttribute; + if (attrib != null) + { + if (upgDb.FirstOrDefault(x => x.ID == attrib.Upgrade) != null) + throw new ShiftoriumConflictException(attrib.Upgrade); + upgDb.Add(new ShiftoriumUpgrade + { + Id = attrib.Upgrade, + Name = attrib.Name, + Cost = attrib.Cost, + Description = attrib.Description, + Dependencies = attrib.Dependencies, + Category = attrib.Category + }); + } + + foreach (var mth in type.GetMethods()) + { + attrib = mth.GetCustomAttributes(false).FirstOrDefault(x => x is ShiftoriumUpgradeAttribute) as ShiftoriumUpgradeAttribute; + if (attrib != null) + { + if (upgDb.FirstOrDefault(x => x.ID == attrib.Upgrade) != null) + throw new ShiftoriumConflictException(attrib.Upgrade); + upgDb.Add(new ShiftoriumUpgrade + { + Id = attrib.Upgrade, + Name = attrib.Name, + Cost = attrib.Cost, + Description = attrib.Description, + Dependencies = attrib.Dependencies, + Category = attrib.Category + }); + + } + } + + foreach (var mth in type.GetFields()) + { + attrib = mth.GetCustomAttributes(false).FirstOrDefault(x => x is ShiftoriumUpgradeAttribute) as ShiftoriumUpgradeAttribute; + if (attrib != null) + { + if (upgDb.FirstOrDefault(x => x.ID == attrib.Upgrade) != null) + throw new ShiftoriumConflictException(attrib.Upgrade); + upgDb.Add(new ShiftoriumUpgrade + { + Id = attrib.Upgrade, + Name = attrib.Name, + Cost = attrib.Cost, + Description = attrib.Description, + Dependencies = attrib.Dependencies, + Category = attrib.Category + }); + + } + } + + foreach (var mth in type.GetProperties()) + { + attrib = mth.GetCustomAttributes(false).FirstOrDefault(x => x is ShiftoriumUpgradeAttribute) as ShiftoriumUpgradeAttribute; + if (attrib != null) + { + if (upgDb.FirstOrDefault(x => x.ID == attrib.Upgrade) != null) + throw new ShiftoriumConflictException(attrib.Upgrade); + upgDb.Add(new ShiftoriumUpgrade + { + Id = attrib.Upgrade, + Name = attrib.Name, + Cost = attrib.Cost, + Description = attrib.Description, + Dependencies = attrib.Dependencies, + Category = attrib.Category + }); + + } + } + + } + } + catch { } + } + } + + + + foreach (var item in upgDb) + { + if (upgDb.Where(x => x.ID == item.ID).Count() > 1) + throw new ShiftoriumConflictException(item.Id); + } + } + + + /// + /// Gets or sets whether the Shiftorium has been initiated. + /// public static bool IsInitiated { get; private set; } + + /// + /// Initiates the Shiftorium. + /// public static void Init() { if (IsInitiated == false) { IsInitiated = true; //Let the crash handler deal with this one... - var dict = GetDefaults(); + CreateUpgradeDatabase(); + var dict = upgDb; foreach (var itm in dict) { if (!SaveSystem.CurrentSave.Upgrades.ContainsKey(itm.ID)) @@ -188,9 +360,14 @@ namespace ShiftOS.Engine } - public static long GetCPValue(string id) + /// + /// Get the codepoint value for an upgrade. + /// + /// The upgrade ID to search + /// The codepoint value. + public static ulong GetCPValue(string id) { - foreach(var upg in GetDefaults()) + foreach (var upg in GetDefaults()) { if (upg.ID == id) return upg.Cost; @@ -198,10 +375,14 @@ namespace ShiftOS.Engine return 0; } + /// + /// Gets all available upgrades. + /// + /// public static ShiftoriumUpgrade[] GetAvailable() { List available = new List(); - foreach(var defaultupg in GetDefaults()) + foreach (var defaultupg in GetDefaults()) { if (!UpgradeInstalled(defaultupg.ID) && DependenciesInstalled(defaultupg)) available.Add(defaultupg); @@ -209,6 +390,11 @@ namespace ShiftOS.Engine return available.ToArray(); } + /// + /// Determines whether all dependencies of a given upgrade have been installed. + /// + /// The upgrade to scan + /// Boolean representing the result of this function. public static bool DependenciesInstalled(ShiftoriumUpgrade upg) { if (string.IsNullOrEmpty(upg.Dependencies)) @@ -218,23 +404,33 @@ namespace ShiftOS.Engine else if (upg.Dependencies.Contains(";")) { string[] dependencies = upg.Dependencies.Split(';'); - foreach(var dependency in dependencies) + foreach (var dependency in dependencies) { if (!UpgradeInstalled(dependency)) return false; } return true; - } + } else { return UpgradeInstalled(upg.Dependencies); } } + /// + /// Fired when an upgrade is installed. + /// public static event EmptyEventHandler Installed; + /// + /// Determines if an upgrade is installed. + /// + /// The upgrade ID to scan. + /// Whether the upgrade is installed. public static bool UpgradeInstalled(string id) { + if (string.IsNullOrWhiteSpace(id)) + return true; if (SaveSystem.CurrentSave != null) { if (!IsInitiated) @@ -250,7 +446,7 @@ namespace ShiftOS.Engine if (id.Contains(';')) { - foreach(var u in id.Split(';')) + foreach (var u in id.Split(';')) { if (UpgradeInstalled(u) == false) return false; @@ -259,10 +455,10 @@ namespace ShiftOS.Engine } bool upgInstalled = false; - if(SaveSystem.CurrentSave.Upgrades.ContainsKey(id)) + if (SaveSystem.CurrentSave.Upgrades.ContainsKey(id)) upgInstalled = SaveSystem.CurrentSave.Upgrades[id]; - if(upgInstalled == false) + if (upgInstalled == false) return SaveSystem.CurrentSave.StoriesExperienced.Contains(id); return true; } @@ -286,125 +482,22 @@ namespace ShiftOS.Engine _provider = p; } - //Bless the newer NEWER engine. + /// + /// Gets every upgrade inside the frontend and all mods. + /// + /// Every single found Shiftorium upgrade. public static List GetDefaults() { - List list = new List(); - //Now we probe for ShiftoriumUpgradeAttributes for mods. - foreach(var file in System.IO.Directory.GetFiles(Environment.CurrentDirectory)) - { - if(file.EndsWith(".exe") || file.EndsWith(".dll")) - { - try - { - var asm = Assembly.LoadFile(file); - foreach (var type in asm.GetTypes()) - { - if (type.GetInterfaces().Contains(typeof(IShiftoriumProvider))) - { - if(type.GetCustomAttributes().FirstOrDefault(x=> x is ShiftoriumProviderAttribute) != null) - { - var _p = Activator.CreateInstance(type, null) as IShiftoriumProvider; - list.AddRange(_p.GetDefaults()); - } - } - - - ShiftoriumUpgradeAttribute attrib = type.GetCustomAttributes(false).FirstOrDefault(x => x is ShiftoriumUpgradeAttribute) as ShiftoriumUpgradeAttribute; - if (attrib != null) - { - if (list.FirstOrDefault(x => x.ID == attrib.Upgrade) != null) - throw new ShiftoriumConflictException(attrib.Upgrade); - list.Add(new ShiftoriumUpgrade - { - Id = attrib.Upgrade, - Name = attrib.Name, - Cost = attrib.Cost, - Description = attrib.Description, - Dependencies = attrib.Dependencies, - Category = attrib.Category - }); - } - - foreach (var mth in type.GetMethods()) - { - attrib = mth.GetCustomAttributes(false).FirstOrDefault(x => x is ShiftoriumUpgradeAttribute) as ShiftoriumUpgradeAttribute; - if (attrib != null) - { - if (list.FirstOrDefault(x => x.ID == attrib.Upgrade) != null) - throw new ShiftoriumConflictException(attrib.Upgrade); - list.Add(new ShiftoriumUpgrade - { - Id = attrib.Upgrade, - Name = attrib.Name, - Cost = attrib.Cost, - Description = attrib.Description, - Dependencies = attrib.Dependencies, - Category = attrib.Category - }); - - } - } - - foreach (var mth in type.GetFields()) - { - attrib = mth.GetCustomAttributes(false).FirstOrDefault(x => x is ShiftoriumUpgradeAttribute) as ShiftoriumUpgradeAttribute; - if (attrib != null) - { - if (list.FirstOrDefault(x => x.ID == attrib.Upgrade) != null) - throw new ShiftoriumConflictException(attrib.Upgrade); - list.Add(new ShiftoriumUpgrade - { - Id = attrib.Upgrade, - Name = attrib.Name, - Cost = attrib.Cost, - Description = attrib.Description, - Dependencies = attrib.Dependencies, - Category = attrib.Category - }); - - } - } - - foreach (var mth in type.GetProperties()) - { - attrib = mth.GetCustomAttributes(false).FirstOrDefault(x => x is ShiftoriumUpgradeAttribute) as ShiftoriumUpgradeAttribute; - if (attrib != null) - { - if (list.FirstOrDefault(x => x.ID == attrib.Upgrade) != null) - throw new ShiftoriumConflictException(attrib.Upgrade); - list.Add(new ShiftoriumUpgrade - { - Id = attrib.Upgrade, - Name = attrib.Name, - Cost = attrib.Cost, - Description = attrib.Description, - Dependencies = attrib.Dependencies, - Category = attrib.Category - }); - - } - } - - } - } - catch { } - } - } - - - - foreach(var item in list) - { - if (list.Where(x => x.ID == item.ID).Count() > 1) - throw new ShiftoriumConflictException(item.Id); - } - return list; + return upgDb; } } public interface IShiftoriumProvider { + /// + /// Retrieves all frontend upgrades. + /// + /// List GetDefaults(); } @@ -427,7 +520,7 @@ namespace ShiftOS.Engine { public string Name { get; set; } public string Description { get; set; } - public long Cost { get; set; } + public ulong 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; } @@ -443,7 +536,7 @@ namespace ShiftOS.Engine public class ShiftoriumUpgradeAttribute : RequiresUpgradeAttribute { - public ShiftoriumUpgradeAttribute(string name, long cost, string desc, string dependencies, string category) : base(name.ToLower().Replace(" ", "_")) + public ShiftoriumUpgradeAttribute(string name, ulong cost, string desc, string dependencies, string category) : base(name.ToLower().Replace(" ", "_")) { Name = name; Description = desc; @@ -454,7 +547,7 @@ namespace ShiftOS.Engine public string Name { get; private set; } public string Description { get; private set; } - public long Cost { get; private set; } + public ulong Cost { get; private set; } public string Dependencies { get; private set; } public string Category { get; private set; } } diff --git a/ShiftOS_TheReturn/Skinning.cs b/ShiftOS_TheReturn/Skinning.cs index 4cc9bbd..d5114c5 100644 --- a/ShiftOS_TheReturn/Skinning.cs +++ b/ShiftOS_TheReturn/Skinning.cs @@ -37,35 +37,71 @@ using System.Reflection; using ShiftOS.Engine.Scripting; namespace ShiftOS.Engine { - + /// + /// Skinning API for Lua. + /// [Exposed("skinning")] public class SkinFunctions { + /// + /// Reload the current skin. + /// public void loadSkin() { SkinEngine.LoadSkin(); } + /// + /// Get the current skin info. + /// + /// A proxy object containing all skin variables. public dynamic getSkin() { return SkinEngine.LoadedSkin; } + /// + /// Set the current skin to the specified class. + /// + /// The class to load. public void setSkin(Skin skn) { Utils.WriteAllText(Paths.GetPath("skin.json"), JsonConvert.SerializeObject(skn)); SkinEngine.LoadSkin(); } + /// + /// Retrieves an image from the skin file. + /// + /// The skin image ID + /// The loaded image, null (nil in Lua) if none is found. public dynamic getImage(string id) { return SkinEngine.GetImage(id); } } - + /// + /// Skin engine management class. + /// public static class SkinEngine { + private static ISkinPostProcessor processor = null; + + /// + /// Load a new skin postprocessor into the engine. + /// + /// The postprocessor to load. + public static void SetPostProcessor(ISkinPostProcessor _processor) + { + processor = _processor; + } + + /// + /// Retrieve the user-specified image layout of a skin image. + /// + /// The skin image ID. + /// The for the image. public static ImageLayout GetImageLayout(string img) { if (LoadedSkin.SkinImageLayouts.ContainsKey(img)) @@ -79,6 +115,11 @@ namespace ShiftOS.Engine } } + /// + /// Retrieves an image from the skin after postprocessing it. + /// + /// The image ID to search. + /// The post-processed image, or null if none was found. public static System.Drawing.Image GetImage(string img) { var type = typeof(Skin); @@ -93,6 +134,8 @@ namespace ShiftOS.Engine if (iattr.Name == img) { byte[] image = (byte[])field.GetValue(LoadedSkin); + if (processor != null) + image = processor.ProcessImage(image); return ImageFromBinary(image); } } @@ -102,11 +145,20 @@ namespace ShiftOS.Engine return null; } + /// + /// Set the engine's current icon prober. + /// + /// The icon prober to use. public static void SetIconProber(IIconProber prober) { _iconProber = prober; } + /// + /// Load a from a array. + /// + /// The array to convert + /// The resulting image. public static Image ImageFromBinary(byte[] image) { if (image == null) @@ -117,6 +169,9 @@ namespace ShiftOS.Engine private static Skin loadedSkin = new Skin(); + /// + /// Gets the currently loaded skin. + /// public static Skin LoadedSkin { get @@ -129,6 +184,9 @@ namespace ShiftOS.Engine } } + /// + /// Initiates the skin engine. + /// public static void Init() { Application.ApplicationExit += (o, a) => @@ -151,8 +209,14 @@ namespace ShiftOS.Engine } } + /// + /// Occurs when the skin is loaded. + /// public static event EmptyEventHandler SkinLoaded; + /// + /// Reload the current skin. + /// public static void LoadSkin() { LoadedSkin = JsonConvert.DeserializeObject(Utils.ReadAllText(Paths.GetPath("skin.json"))); @@ -161,6 +225,9 @@ namespace ShiftOS.Engine Desktop.PopulateAppLauncher(); } + /// + /// Save the skin loaded in memory to the filesystem. + /// public static void SaveSkin() { Utils.WriteAllText(Paths.GetPath("skin.json"), JsonConvert.SerializeObject(LoadedSkin, Formatting.Indented)); @@ -168,6 +235,11 @@ namespace ShiftOS.Engine private static IIconProber _iconProber = null; + /// + /// Retrieves the default icon for a given icon ID. + /// + /// The icon ID to search. + /// The resulting icon image. public static Image GetDefaultIcon(string id) { if (_iconProber == null) @@ -204,13 +276,26 @@ namespace ShiftOS.Engine } } + /// + /// Retrieves the user-defined icon for a specified icon ID. + /// + /// The icon ID to search. + /// The resulting icon image. public static Image GetIcon(string id) { if (!LoadedSkin.AppIcons.ContainsKey(id)) LoadedSkin.AppIcons.Add(id, null); if (LoadedSkin.AppIcons[id] == null) - return GetDefaultIcon(id); + { + var img = GetDefaultIcon(id); + using (var mstr = new MemoryStream()) + { + img.Save(mstr, System.Drawing.Imaging.ImageFormat.Png); + LoadedSkin.AppIcons[id] = mstr.ToArray(); + } + return img; + } else { using (var sr = new MemoryStream(LoadedSkin.AppIcons[id])) @@ -222,11 +307,23 @@ namespace ShiftOS.Engine } } + /// + /// Interface for probing app icons. + /// public interface IIconProber { + /// + /// Retrieve the icon image from a . + /// + /// The attribute data + /// The resulting image. Image GetIcon(DefaultIconAttribute attr); } + /// + /// Sets the default icon ID for a . + /// + [AttributeUsage(AttributeTargets.Class, AllowMultiple =false)] public class DefaultIconAttribute : Attribute { public DefaultIconAttribute(string id) @@ -237,21 +334,24 @@ namespace ShiftOS.Engine public string ID { get; private set; } } + /// + /// The data stored in any .skn file. + /// public class Skin { //borrowing from the discourse theme for the default skin - private static readonly Color DefaultBackground = Color.FromArgb(0, 0x44, 0x00); + private static readonly Color DefaultBackground = Color.FromArgb(0x11, 0x11, 0x11); private static readonly Color DefaultForeground = Color.FromArgb(0xDD, 0xDD, 0xDD); private static readonly Color Accent1 = Color.FromArgb(0x66, 0x66, 0x66); - private static readonly Color Accent2 = Color.FromArgb(0x80, 0, 0); - private static readonly Color DesktopBG = Color.FromArgb(0x22, 0x22, 0x22); + private static readonly Color Accent2 = Color.FromArgb(0x0, 0x80, 0); + private static readonly Color DesktopBG = Color.FromArgb(0x00, 0x00, 0x00); private static readonly Font SysFont = new Font("Tahoma", 9F); private static readonly Font SysFont2 = new Font("Tahoma", 10F, FontStyle.Bold); - private static readonly Font Header1 = new Font("Helvetica", 20F, FontStyle.Bold); - private static readonly Font Header2 = new Font("Helvetica", 17.5F, FontStyle.Bold); - private static readonly Font Header3 = new Font("Tahoma", 15F, FontStyle.Bold); + private static readonly Font Header1 = new Font("Courier New", 20F, FontStyle.Bold); + private static readonly Font Header2 = new Font("Courier New", 17.5F, FontStyle.Bold); + private static readonly Font Header3 = new Font("Courier New", 15F, FontStyle.Bold); - private static readonly Color TitleBG = Color.FromArgb(0x11, 0x11, 0x11); + private static readonly Color TitleBG = Color.FromArgb(0x11, 0x55, 0x11); private static readonly Color TitleFG = Color.FromArgb(0xaa, 0xaa, 0xaa); //Todo: When making Shifter GUI we need to label all these with proper Shifter attributes to get 'em displaying in the right places. @@ -267,6 +367,151 @@ namespace ShiftOS.Engine [ShifterHidden] public Dictionary AppIcons = new Dictionary(); + [ShifterMeta("System")] + [ShifterCategory("Progress Bar")] + [RequiresUpgrade("shift_progress_bar;skinning")] + [Image("progressbarbg")] + [ShifterName("Progress Bar Background Image")] + [ShifterDescription("Set an image for the background of a progress bar.")] + public byte[] ProgressBarBG = null; + + + [ShifterMeta("System")] + [ShifterCategory("Progress Bar")] + [RequiresUpgrade("shift_progress_bar;skinning")] + [Image("progress")] + [ShifterName("Progress Image")] + [ShifterDescription("Set the image for the progress inside a progress bar.")] + public byte[] Progress = null; + + + [ShifterMeta("System")] + [ShifterCategory("Progress Bar")] + [RequiresUpgrade("shift_progress_bar")] + [ShifterName("Progress bar foreground color")] + [ShifterDescription("Set the color of the progress indicator.")] + public Color ProgressColor = Accent1; + + + [ShifterMeta("System")] + [ShifterCategory("Progress Bar")] + [RequiresUpgrade("shift_progress_bar")] + [ShifterName("Progress bar background color")] + [ShifterDescription("The background color of the progress bar.")] + public Color ProgressBarBackgroundColor = Color.Black; + + + [ShifterMeta("System")] + [ShifterCategory("Progress Bar")] + [RequiresUpgrade("shift_progress_bar")] + [ShifterName("Progress bar block size")] + [ShifterDescription("If the progress bar style is set to Blocks, this determines how wide each block should be.")] + public int ProgressBarBlockSize = 15; + + + [ShifterMeta("System")] + [ShifterCategory("Progress Bar")] + [RequiresUpgrade("shift_progress_bar")] + [ShifterDescription("Set the style of a progress bar.\r\nMarquee: The progress bar will render a box that moves from the left to the right in a loop.\r\nContinuous: Progress is shown by a single, continuous box.\r\nBlocks: Just like Continuous, but the box is split into even smaller boxes of a set width.")] + [ShifterName("Progress bar style")] + public ProgressBarStyle ProgressBarStyle = ProgressBarStyle.Continuous; + + + + + + + [ShifterMeta("System")] + [ShifterCategory("Buttons")] + [RequiresUpgrade("shift_buttons")] + [ShifterName("Button background color")] + [ShifterDescription("Set the background color for each button's Idle state.")] + public Color ButtonBackgroundColor = Skin.DefaultBackground; + + [ShifterMeta("System")] + [ShifterCategory("Buttons")] + [RequiresUpgrade("shift_buttons;skinning")] + [Image("buttonhover")] + [ShifterName("Button hover image")] + [ShifterDescription("Set the image that's displayed when the mouse hovers over a button.")] + public byte[] ButtonHoverImage = null; + + [ShifterMeta("System")] + [ShifterCategory("Buttons")] + [RequiresUpgrade("skinning;shift_buttons")] + [Image("buttonpressed")] + [ShifterName("Button pressed image")] + [ShifterDescription("Select an image to show when the user presses a button.")] + public byte[] ButtonPressedImage = null; + + [ShifterMeta("System")] + [ShifterCategory("Buttons")] + [RequiresUpgrade("shift_buttons")] + [ShifterName("Button hover color")] + [ShifterDescription("Choose the color that displays on a button when the mouse hovers over it.")] + public Color ButtonHoverColor = Skin.Accent1; + + [ShifterMeta("System")] + [ShifterCategory("Buttons")] + [RequiresUpgrade("shift_buttons")] + [ShifterName("Button pressed color")] + [ShifterDescription("Select the background color for the button when the mouse clicks it.")] + public Color ButtonPressedColor = Skin.Accent2; + + [ShifterMeta("System")] + [ShifterCategory("Buttons")] + [RequiresUpgrade("shift_buttons")] + [ShifterName("Button foreground color")] + [ShifterDescription("Select the text and border color for each button.")] + public Color ButtonForegroundColor = Skin.DefaultForeground; + + [ShifterMeta("System")] + [ShifterCategory("Buttons")] + [RequiresUpgrade("shift_buttons")] + [ShifterName("Button border width")] + [ShifterDescription("Set the width, in pixels, of the button's border.")] + public int ButtonBorderWidth = 2; + + [ShifterMeta("System")] + [ShifterCategory("Buttons")] + [RequiresUpgrade("shift_buttons")] + [ShifterName("Button font")] + [ShifterDescription("Select the font for the button's text.")] + public Font ButtonTextFont = Skin.SysFont; + + [ShifterMeta("System")] + [ShifterCategory("Buttons")] + [RequiresUpgrade("shift_buttons;skinning")] + [Image("buttonidle")] + [ShifterName("Button background color")] + [ShifterDescription("Select an image to show as the button's Idle state.")] + public byte[] ButtonBG = null; + + + [Image("panelclockbg")] + [ShifterMeta("Desktop")] + [ShifterCategory("Panel Clock")] + [ShifterName("Panel Clock Background Image")] + [ShifterDescription("Set the background image of the panel clock.")] + [RequiresUpgrade("skinning;shift_panel_clock")] + public byte[] PanelClockBG = null; + + [ShifterMeta("System")] + [ShifterCategory("Login Screen")] + [RequiresUpgrade("gui_based_login_screen")] + [ShifterName("Login Screen Background Color")] + [ShifterDescription("Change the background color of the login screen.")] + public Color LoginScreenColor = Skin.DesktopBG; + + [ShifterMeta("System")] + [ShifterCategory("Login Screen")] + [RequiresUpgrade("skinning;gui_based_login_screen")] + [ShifterName("Login Screen Background Image")] + [ShifterDescription("Set an image as your login screen!")] + [Image("login")] + public byte[] LoginScreenBG = null; + + [RequiresUpgrade("shift_screensaver")] [ShifterMeta("System")] [ShifterCategory("Screen saver")] @@ -405,7 +650,7 @@ namespace ShiftOS.Engine [ShifterName("Close Button Color")] [RequiresUpgrade("shift_title_buttons")] [ShifterDescription("The close button color")] - public Color CloseButtonColor = Accent2; + public Color CloseButtonColor = Color.FromArgb(0x80,0,0); [ShifterMeta("Windows")] [ShifterCategory("Title Buttons")] @@ -1218,6 +1463,9 @@ namespace ShiftOS.Engine public Font AdvALItemFont = SysFont2; } + /// + /// Marks a skin spec field as hidden from the Shifter. + /// public class ShifterHiddenAttribute : Attribute { @@ -1307,6 +1555,16 @@ namespace ShiftOS.Engine public string Category { get; set; } } + public interface ISkinPostProcessor + { + /// + /// Perform algorithmic operations at the bit level on a ShiftOS skin image. + /// + /// The image, as loaded by the engine, as a 32-bit ARGB byte array. + /// The processed image. + byte[] ProcessImage(byte[] original); + } + public class ShifterMetaAttribute : Attribute { diff --git a/ShiftOS_TheReturn/Story.cs b/ShiftOS_TheReturn/Story.cs index 8c726ed..f473f89 100644 --- a/ShiftOS_TheReturn/Story.cs +++ b/ShiftOS_TheReturn/Story.cs @@ -35,8 +35,95 @@ using Newtonsoft.Json; namespace ShiftOS.Engine { - public class Story + public class StoryContext { + public string Id { get; set; } + public MethodInfo Method { get; set; } + public bool AutoComplete = false; + + public StoryContext() + { + AutoComplete = true; + } + + public void MarkComplete() + { + SaveSystem.CurrentSave.StoriesExperienced.Add(Id); + OnComplete?.Invoke(); + } + + public event Action OnComplete; + } + + public class Objective + { + private Func _completeFunc = null; + + public string Name { get; set; } + public string Description { get; set; } + + public bool IsComplete + { + get + { + return (bool)_completeFunc?.Invoke(); + } + } + + public Objective(string name, string desc, Func completeFunc, Action onComplete) + { + _completeFunc = completeFunc; + Name = name; + Description = desc; + this.onComplete = onComplete; + } + + private Action onComplete = null; + + public void Complete() + { + onComplete?.Invoke(); + } + } + + /// + /// Storyline management class. + /// + public static class Story + { + public static StoryContext Context { get; private set; } + public static event Action StoryComplete; + public static List CurrentObjectives { get; private set; } + + public static void PushObjective(string name, string desc, Func completeFunc, Action onComplete) + { + if (CurrentObjectives == null) + CurrentObjectives = new List(); + + var currentObjective = new Objective(name, desc, completeFunc, onComplete); + CurrentObjectives.Add(currentObjective); + var t = new Thread(() => + { + var obj = currentObjective; + while (!obj.IsComplete) + { + Thread.Sleep(5000); + } + CurrentObjectives.Remove(obj); + obj.Complete(); + }); + t.IsBackground = true; + t.Start(); + + Console.WriteLine("NEW OBJECTIVE:"); + Console.WriteLine("A new objective has been added to your system. Run sos.status to find out what you need to do."); + } + + + /// + /// Starts the storyline with the specified Storyline ID. + /// + /// The storyline ID to start. public static void Start(string stid) { foreach (var exec in System.IO.Directory.GetFiles(Environment.CurrentDirectory)) @@ -59,8 +146,26 @@ namespace ShiftOS.Engine var story = attrib as StoryAttribute; if(story.StoryID == stid) { - mth.Invoke(null, null); - SaveSystem.CurrentSave.StoriesExperienced.Add(stid); + new Thread(() => + { + Context = new Engine.StoryContext + { + Id = stid, + Method = mth, + AutoComplete = true, + }; + SaveSystem.CurrentSave.PickupPoint = Context.Id; + Context.OnComplete += () => + { + StoryComplete?.Invoke(stid); + SaveSystem.CurrentSave.PickupPoint = null; + }; + mth.Invoke(null, null); + if (Context.AutoComplete) + { + Context.MarkComplete(); + } + }).Start(); return; } } @@ -78,231 +183,12 @@ namespace ShiftOS.Engine #endif } - + [Obsolete("Please use Story.Start() in tandem with [StoryAttribute].")] public static void RunFromInternalResource(string resource_id) { - var t = typeof(Properties.Resources); - - foreach(var prop in t.GetProperties(System.Reflection.BindingFlags.NonPublic | BindingFlags.Static)) - { - if(prop.Name == resource_id) - { - if(prop.PropertyType == typeof(string)) - { - WriteStory(prop.GetValue(null) as string); - - return; - } - } - } - throw new ArgumentException("Couldn't find resource ID inside the engine: " + resource_id); } - public string Character { get; set; } - public List Lines { get; set; } - - public static void Start() - { - Console.WriteLine(); - if(SaveSystem.CurrentSave.StoryPosition == 5) - { - StartDevXLies(); - } - } - - public static void StartDevXLies() - { - int chatProgress = 0; - //bool LoopStuck = false; - string textToWrite = ""; - const int TYPE_SPEED_MS = 45; - bool done = false; - bool write = true; - - while (done == false) { - write = true; - switch (chatProgress) - { - case 0: - textToWrite = "User joined: @" + SaveSystem.CurrentSave.Username; - break; - case 1: - textToWrite = $"Hello, {SaveSystem.CurrentSave.Username}."; - break; - case 2: //If C:\ShiftOS doesn't exist the player won't notice this is here. - if (Directory.Exists(Paths.GetPath("classic"))) - { - textToWrite = "I see you've participated in my previous ShiftOS experiment. Welcome back, Shifter. I assume you know lots about ShiftOS, but there are some updates I have to tell you."; - } - else - { - write = false; - } - break; - case 3: //DevX hates ShiftOS-Next secretly. - if (Directory.Exists(Paths.GetPath("classic") + "-Next")) - { - textToWrite = "Hmmmm.... looking at my sentience records, I see you've participated in ShiftOS-Next. This is gonna be difficult."; - } - else - { - write = false; - } - break; - case 4: - textToWrite = "There's a lot that has changed within ShiftOS."; - break; - case 5: - textToWrite = "First off, I want to tell you a bit about myself in case you don't already know."; - break; - case 6: - textToWrite = "My name is DevX. I am the architect of ShiftOS. I have chosen you to take part in helping me out with it."; - break; - case 7: - textToWrite = "You see, in my past attempts it has all been about an evolving operating system and seeing how the users work with it..."; - break; - case 8: - textToWrite = "Almost one hundred percent of the time, people have found out it was an experiment and they could simply return to their regular system with a specific upgrade."; - break; - case 9: - textToWrite = "But now, I want to try something different - something unique."; - break; - case 10: - textToWrite = "ShiftOS is the same as it has been in my previous attempts, but now, your goal is to gain as much wealth and power as possible."; - break; - case 11: - textToWrite = "Right now you are inside my segregation LAN. Only you and me exist within this domain. You are free from other users unless I create them."; - break; - case 12: - textToWrite = "Since you have proved your sentience, I have a task for you outside the segregation LAN."; - break; - case 13: - textToWrite = "But first... you need to be taught a few things."; - break; - case 14: - textToWrite = "First off, when I bring you into my multi-user domain, you'll first want to establish as much wealth as possible."; - break; - case 15: - textToWrite = "Wealth comes in the form of Codepoints - a currency used among users of the multi-user domain."; - break; - case 16: - textToWrite = @"You can get Codepoints by doing the following: - - - Stealing them from other users - - Extracting them from inactive/unverified sentiences - - Using specific scripts/programs within ShiftOS - - Creating paid scripts/applications within ShiftOS"; - break; - case 17: - textToWrite = "You can use Codepoints to buy upgrades using the 'shiftorium.buy' command, or you can use them to pay other users, or scripts."; - break; - case 18: - textToWrite = "Within the multi-user domain you are free to do whatever you want. Larcany, theft, deceiving, lies, and distribution of malware is permitted under my watch."; - break; - case 19: - textToWrite = "Do whatever you have to to get Codepoints."; - break; - case 20: - textToWrite = "Then use them to make yourself stronger by buying upgrades at the shiftorium."; - break; - case 21: - textToWrite = "If you want to get a bit devious within the multi-user domain, look around for scripts that will expose user account information."; - break; - case 22: - textToWrite = "Or just spread a virus around the mud."; - break; - case 23: - textToWrite = "Or you can be the 'good' guy and stop these attacks and gain the trust of other users."; - break; - case 24: - textToWrite = "It's up to you. Just, don't mess with my system. You won't want me coming to you after that. I'm watching."; - break; - case 25: - textToWrite = "User left chat: @" + SaveSystem.CurrentSave.Username; - done = true; - SaveSystem.CurrentSave.StoryPosition++; - TerminalBackend.InvokeCommand("sos.save"); - break; - - } - - if (write == true) - { - Console.WriteLine(); - Console.Write("DevX: "); - foreach(char c in textToWrite) - { - Console.Beep(750, TYPE_SPEED_MS); - if (c == '\n') - { - - } - else if (c == '\r') - { - Console.WriteLine(); - } - else - { - Console.Write(c); - } - } - Thread.Sleep(1000); - } - chatProgress += 1; - } - } - - - public static void WriteStory(string json) - { - var thread = new Thread(new ThreadStart(() => - { - var story = JsonConvert.DeserializeObject(json); - - const int TYPESPEED = 45; - - foreach (var line in story.Lines) - { - var localized = Localization.Parse(line); - - - if (line.StartsWith("cmd:")) - { - string[] cmdsplit = line.Replace("cmd:", "").Split(' '); - switch (cmdsplit[0]) - { - case "givecp": - SaveSystem.TransferCodepointsFrom(story.Character, Convert.ToInt32(cmdsplit[1])); - break; - } - } - else - { - Console.Write(story.Character + ": "); - - foreach (var c in localized) - { - Console.Beep(1024, TYPESPEED); - if (c == '\r') - { - - } - else if (c == '\n') - Console.WriteLine(); - else - Console.Write(c); - } - - Console.WriteLine(); - Thread.Sleep(1000); - } - } - Console.Write($"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}:~$ "); - })); - thread.IsBackground = true; - thread.Start(); - } } [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] @@ -322,6 +208,9 @@ namespace ShiftOS.Engine StoryID = id; } + /// + /// Gets the storyline ID stored in this attribute. + /// public string StoryID { get; private set; } } diff --git a/ShiftOS_TheReturn/TerminalBackend.cs b/ShiftOS_TheReturn/TerminalBackend.cs index 9c57aa8..09ef3d6 100644 --- a/ShiftOS_TheReturn/TerminalBackend.cs +++ b/ShiftOS_TheReturn/TerminalBackend.cs @@ -24,6 +24,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Reflection; using System.Text; @@ -34,12 +35,26 @@ using static ShiftOS.Engine.SaveSystem; namespace ShiftOS.Engine { + /// + /// Backend for the ShiftOS terminal. + /// public static class TerminalBackend { + /// + /// Occurs when a command is processed. + /// public static event Action CommandProcessed; + /// + /// Gets or sets whether the current command is elevated. + /// public static bool Elevated { get; set; } + /// + /// Parses command-line arguments using the ShiftOS syntax and stores them in a , removing the parsed text from the original string. + /// + /// The text to parse. + /// containing the parsed arguments. public static Dictionary GetArgs(ref string text) { bool shouldParse = false; @@ -64,8 +79,23 @@ namespace ShiftOS.Engine return JsonConvert.DeserializeObject>(args); } + /// + /// String representing the last command entered by the user. + /// public static string LastCommand = ""; + /// + /// Gets the output of the last command. + /// + public static string LastCommandBuffer { get; private set; } + + /// + /// Invokes a ShiftOS terminal command. + /// + /// The command's namespace. + /// The command name. + /// The command arguments. + /// Whether the command should be sent through Remote Terminal Session (RTS). public static void InvokeCommand(string ns, string command, Dictionary arguments, bool isRemote = false) { try @@ -78,13 +108,7 @@ namespace ShiftOS.Engine if (!commandWasClient && !string.IsNullOrWhiteSpace(ns)) { - PrefixEnabled = false; - - ServerManager.SendMessage("script", $@"{{ - user: ""{ns}"", - script: ""{command}"", - args: ""{GetSentArgs(arguments)}"" -}}"); + Console.WriteLine("Error: Command not found."); } CommandProcessed?.Invoke(ns + "." + command, JsonConvert.SerializeObject(arguments)); @@ -97,6 +121,11 @@ namespace ShiftOS.Engine } } + /// + /// Transforms a of arguments to a . + /// + /// The original argument dictionary to convert. + /// The converted dictionary. public static string GetSentArgs(Dictionary argss) { Dictionary args = new Dictionary(); @@ -107,26 +136,239 @@ namespace ShiftOS.Engine return JsonConvert.SerializeObject(args); } + public class TerminalCommand + { + public override int GetHashCode() + { + int hash = 0; + foreach (char c in ToString()) + { + hash += (int)c; + } + return hash; + } + + public Namespace NamespaceInfo { get; set; } + public Command CommandInfo { get; set; } + + public List RequiredArguments { get; set; } + public string Dependencies { get; set; } + + public MethodInfo CommandHandler; + + public Type CommandType; + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.Append(this.NamespaceInfo.name); + sb.Append("."); + sb.Append(this.CommandInfo.name); + if (this.RequiredArguments.Count > 0) + { + sb.Append("{"); + foreach (var arg in RequiredArguments) + { + sb.Append(arg); + sb.Append(":"); + if (RequiredArguments.IndexOf(arg) < RequiredArguments.Count - 1) + sb.Append(','); + } + sb.Append("}"); + } + sb.Append("|"); + sb.Append(CommandHandler.Name + "()"); + return sb.ToString(); + } + + public bool RequiresElevation { get; set; } + + public void Invoke(Dictionary args) + { + List errors = new List(); + bool requiresAuth = false; + if (!KernelWatchdog.IsSafe(this)) + { + if (SaveSystem.CurrentUser.Permissions == Objects.UserPermissions.Admin) + requiresAuth = true; + else + errors.Add("You can't run this command - you do not have permission."); + } + if (errors.Count > 0) + { + foreach (var error in errors) + { + Console.WriteLine("Command error: " + error); + } + return; + } + if (requiresAuth) + { + Infobox.PromptText("Enter your password.", "This command requires you to have elevated permissions. Please enter your password to confirm this action.", (pass) => + { + if (pass == SaveSystem.CurrentUser.Password) + { + var uname = SaveSystem.CurrentUser.Username; + SaveSystem.CurrentUser = SaveSystem.CurrentSave.Users.FirstOrDefault(x => x.Username == "root"); + try + { + var h = CommandHandler; + h.Invoke(null, new[] { args }); + } + catch + { + var h = CommandHandler; + h.Invoke(null, null); + } + SaveSystem.CurrentUser = SaveSystem.CurrentSave.Users.FirstOrDefault(x => x.Username == uname); + } + else + { + Infobox.Show("Access denied.", "Incorrect password provided. The command will not run."); + } + }, true); + } + + try + { + CommandHandler.Invoke(null, new[] { args }); + } + catch + { + CommandHandler.Invoke(null, null); + } + } + } + + public class MemoryTextWriter : System.IO.TextWriter + { + public override Encoding Encoding + { + get + { + return Encoding.Unicode; + } + } + + private StringBuilder sb = null; + + public MemoryTextWriter() + { + sb = new StringBuilder(); + } + + public override string ToString() + { + return sb.ToString(); + } + + public override void Write(char value) + { + sb.Append(value); + } + + public override void WriteLine() + { + sb.AppendLine(); + } + + public override void Write(string value) + { + sb.Append(value); + } + + public override void Close() + { + sb.Clear(); + sb = null; + base.Close(); + } + + public override void WriteLine(string value) + { + sb.AppendLine(value); + } + } + + public static List Commands { get; private set; } + + public static void PopulateTerminalCommands() + { + Commands = new List(); + foreach(var exec in System.IO.Directory.GetFiles(Environment.CurrentDirectory)) + { + if(exec.ToLower().EndsWith(".exe") || exec.ToLower().EndsWith(".dll")) + { + try + { + var asm = Assembly.LoadFile(exec); + foreach(var type in asm.GetTypes()) + { + var ns = type.GetCustomAttributes(false).FirstOrDefault(x => x is Namespace) as Namespace; + if(ns != null) + { + foreach(var mth in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) + { + var cmd = mth.GetCustomAttributes(false).FirstOrDefault(x => x is Command); + if(cmd != null) + { + var tc = new TerminalCommand(); + tc.RequiresElevation = !(type.GetCustomAttributes(false).FirstOrDefault(x => x is KernelModeAttribute) == null); + + tc.NamespaceInfo = ns; + + tc.CommandInfo = cmd as Command; + tc.RequiresElevation = tc.RequiresElevation || !(mth.GetCustomAttributes(false).FirstOrDefault(x => x is KernelModeAttribute) == null); + tc.RequiredArguments = new List(); + foreach (var arg in mth.GetCustomAttributes(false).Where(x=>x is RequiresArgument)) + { + var rarg = arg as RequiresArgument; + tc.RequiredArguments.Add(rarg.argument); + } + var rupg = mth.GetCustomAttributes(false).FirstOrDefault(x => x is RequiresUpgradeAttribute) as RequiresUpgradeAttribute; + if (rupg != null) + tc.Dependencies = rupg.Upgrade; + else + tc.Dependencies = ""; + tc.CommandType = type; + tc.CommandHandler = mth; + if (!Commands.Contains(tc)) + Commands.Add(tc); + } + } + } + } + } + catch(Exception e) + { + Console.WriteLine("[termdb] Error: " + e.ToString()); + } + } + } + Console.WriteLine("[termdb] " + Commands.Count + " commands found."); + } + + /// + /// Invokes a ShiftOS terminal command. + /// + /// The full command text in regular ShiftOS syntax + /// Whether the command should be sent through Remote Terminal Session (RTS). public static void InvokeCommand(string text, bool isRemote = false) { + if (string.IsNullOrWhiteSpace(text)) + return; + var tw = new MemoryTextWriter(); + Console.SetOut(tw); try { - if (string.IsNullOrWhiteSpace(text)) - return; - var args = GetArgs(ref text); bool commandWasClient = RunClient(text, args, isRemote); if (!commandWasClient) { - PrefixEnabled = false; - - ServerManager.SendMessage("script", $@"{{ - user: ""{text.Split('.')[0]}"", - script: ""{text.Split('.')[1]}"", - args: ""{GetSentArgs(args)}"" -}}"); + Console.WriteLine("Error: Command not found."); + } CommandProcessed?.Invoke(text, GetSentArgs(args)); } @@ -136,21 +378,48 @@ namespace ShiftOS.Engine PrefixEnabled = true; } + string buffer = tw.ToString(); + LastCommandBuffer = buffer; + Console.SetOut(new TerminalTextWriter()); + if(!isRemote) + Console.Write(buffer); + } + /// + /// Gets or sets whether the user prefix is printed after a command completes. + /// public static bool PrefixEnabled { get; set; } + /// + /// Gets or sets whether the user is in a story plot, and thus, the terminal input should be disabled. + /// public static bool InStory { get; set; } + /// + /// Another latest command string. + /// public static string latestCommmand = ""; + /// + /// Occurs when the engine requests a Terminal to be open. + /// public static event EmptyEventHandler TerminalRequested; + /// + /// Opens a Terminal. + /// internal static void OpenTerminal() { TerminalRequested?.Invoke(); } + /// + /// Determines if the specified command method can be ran in RTS + /// + /// The method to scan + /// Is the user in an RTS session? + /// Whether the command can be run. public static bool CanRunRemotely(MethodInfo mth, bool isRemote) { if (!isRemote) @@ -165,12 +434,26 @@ namespace ShiftOS.Engine return true; } + /// + /// Runs a command on the client-side. + /// + /// The command's namespace. + /// The command name. + /// The command's arguments. + /// Whether the command should be ran through RTS. + /// Whether the command ran successfully. public static bool RunClient(string ns, string cmd, Dictionary args, bool isRemote = false) { return RunClient(ns + "." + cmd, args, isRemote); } - + /// + /// Runs a command on the client. + /// + /// The command text. + /// The command arguments. + /// Whether the command should be ran through RTS. + /// Whether the command ran successfully. public static bool RunClient(string text, Dictionary argss, bool isRemote = false) { Dictionary args = new Dictionary(); @@ -181,291 +464,93 @@ namespace ShiftOS.Engine return RunClient(text, args, isRemote); } + /// + /// Runs a command on the client. + /// + /// The command text. + /// The command arguments. + /// Whether the command should be run in RTS. + /// Whether the command ran successfully. public static bool RunClient(string text, Dictionary args, bool isRemote = false) { latestCommmand = text; //Console.WriteLine(text + " " + "{" + string.Join(",", args.Select(kv => kv.Key + "=" + kv.Value).ToArray()) + "}" + " " + isRemote); - foreach (var asmExec in System.IO.Directory.GetFiles(Environment.CurrentDirectory)) + + string[] split = text.Split('.'); + var cmd = Commands.FirstOrDefault(x => x.NamespaceInfo.name == split[0] && x.CommandInfo.name == split[1]); + if (cmd == null) + return false; + if (!Shiftorium.UpgradeInstalled(cmd.Dependencies)) + return false; + bool res = false; + foreach (var arg in cmd.RequiredArguments) { - try + if (!args.ContainsKey(arg)) { - var asm = Assembly.LoadFile(asmExec); - - var types = asm.GetTypes(); - foreach (var type in types) - { - if (Shiftorium.UpgradeAttributesUnlocked(type)) - { - foreach (var a in type.GetCustomAttributes(false)) - { - if (a is Namespace) - { - var ns = a as Namespace; - if (text.Split('.')[0] == ns.name) - { - if (KernelWatchdog.IsSafe(type)) - { - if (KernelWatchdog.CanRunOffline(type)) - { - foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) - { - if (Shiftorium.UpgradeAttributesUnlocked(method)) - { - if (CanRunRemotely(method, isRemote)) - { - foreach (var ma in method.GetCustomAttributes(false)) - { - if (ma is Command) - { - var cmd = ma as Command; - if (text.Split('.')[1] == cmd.name) - { - if (KernelWatchdog.IsSafe(method)) - { - if (KernelWatchdog.CanRunOffline(method)) - { - var attr = method.GetCustomAttribute(); - - if (attr != null) - { - string newcommand = attr.newcommand; - if (attr.warn) - { - Console.WriteLine(Localization.Parse((newcommand == "" ? "{ERROR}" : "{WARN}") + attr.reason, new Dictionary() { - {"%newcommand", newcommand} - })); - } - if (newcommand != "") - { - // redo the entire process running newcommand - - return RunClient(newcommand, args); - } - } - - var requiresArgs = method.GetCustomAttributes(); - bool error = false; - bool providedusage = false; - - foreach (RequiresArgument argument in requiresArgs) - { - if (!args.ContainsKey(argument.argument)) - { - - if (!providedusage) - { - string usageparse = "{COMMAND_" + ns.name.ToUpper() + "_" + cmd.name.ToUpper() + "_USAGE}"; - if (usageparse == Localization.Parse(usageparse)) - usageparse = ""; - else - usageparse = Shiftorium.UpgradeInstalled("help_usage") ? Localization.Parse("{ERROR}{USAGE}" + usageparse, new Dictionary() { - {"%ns", ns.name}, - {"%cmd", cmd.name} - }) : ""; - - Console.WriteLine(usageparse); - - providedusage = true; - } - if (Shiftorium.UpgradeInstalled("help_usage")) - { - Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED}", new Dictionary() { - {"%argument", argument.argument} - })); - } - else - { - Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED_NO_USAGE}")); - } - - error = true; - } - } - - if (error) - { - throw new Exception("{ERROR_COMMAND_WRONG}"); - } - - try - { - return (bool)method.Invoke(null, new[] { args }); - } - catch (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.Write("<"); - ConsoleEx.Bold = true; - ConsoleEx.ForegroundColor = ConsoleColor.DarkRed; - Console.Write("session_mgr"); - ConsoleEx.ForegroundColor = SkinEngine.LoadedSkin.TerminalForeColorCC; - ConsoleEx.Bold = false; - Console.Write(">"); - ConsoleEx.Italic = true; - ConsoleEx.ForegroundColor = ConsoleColor.DarkYellow; - Console.WriteLine(" You cannot run this command while disconnected from the multi-user domain.."); - return true; - - } - } - else - { - if (SaveSystem.CurrentUser.Permissions == Objects.UserPermissions.Admin) - { - Infobox.PromptText("Elevate to root mode", "This command cannot be run as a regular user. To run this command, please enter your password to elevate to root mode temporarily.", (pass) => - { - if (pass == SaveSystem.CurrentUser.Password) - { - KernelWatchdog.EnterKernelMode(); - RunClient(text, args, isRemote); - KernelWatchdog.LeaveKernelMode(); - } - else - { - Infobox.Show("Access denied.", "You did not type in the correct password."); - } - }, true); - return true; - } - Console.Write("<"); - ConsoleEx.Bold = true; - ConsoleEx.ForegroundColor = ConsoleColor.DarkRed; - Console.Write("watchdog"); - ConsoleEx.ForegroundColor = SkinEngine.LoadedSkin.TerminalForeColorCC; - ConsoleEx.Bold = false; - Console.Write(">"); - ConsoleEx.Italic = true; - ConsoleEx.ForegroundColor = ConsoleColor.DarkYellow; - Console.WriteLine(" You cannot run this command. You do not have permission. Incident reported."); - KernelWatchdog.Log("potential_sys_breach", "user attempted to run kernel mode command " + text + " - watchdog has prevented this, good sir."); - return true; - } - } - } - - - } - } - } - else - { - Console.WriteLine(text + " cannot be ran in a remote session"); - return true; - } - } - - } - - - else - { - Console.Write("<"); - ConsoleEx.Bold = true; - ConsoleEx.ForegroundColor = ConsoleColor.DarkRed; - Console.Write("session_mgr"); - ConsoleEx.ForegroundColor = SkinEngine.LoadedSkin.TerminalForeColorCC; - ConsoleEx.Bold = false; - Console.Write(">"); - ConsoleEx.Italic = true; - ConsoleEx.ForegroundColor = ConsoleColor.DarkYellow; - Console.WriteLine(" You cannot run this command while disconnected from the multi-user domain.."); - return true; - - } - - } - else - { - if (SaveSystem.CurrentUser.Permissions == Objects.UserPermissions.Admin) - { - Infobox.PromptText("Elevate to root mode", "This command cannot be run as a regular user. To run this command, please enter your password to elevate to root mode temporarily.", (pass) => - { - if (pass == SaveSystem.CurrentUser.Password) - { - KernelWatchdog.EnterKernelMode(); - RunClient(text, args, isRemote); - KernelWatchdog.LeaveKernelMode(); - } - else - { - Infobox.Show("Access denied.", "You did not type in the correct password."); - } - }, true); - return true; - } - Console.Write("<"); - ConsoleEx.Bold = true; - ConsoleEx.ForegroundColor = ConsoleColor.DarkRed; - Console.Write("watchdog"); - ConsoleEx.ForegroundColor = SkinEngine.LoadedSkin.TerminalForeColorCC; - ConsoleEx.Bold = false; - Console.Write(">"); - ConsoleEx.Italic = true; - ConsoleEx.ForegroundColor = ConsoleColor.DarkYellow; - Console.WriteLine(" You cannot run this command. You do not have permission. Incident reported."); - KernelWatchdog.Log("potential_sys_breach", "user attempted to run kernel mode command " + text + " - watchdog has prevented this, good sir."); - return true; - } - } - } - } - } - } + res = true; + Console.WriteLine("You are missing an argument with the key \"" + arg + "\"."); } - catch { } } - return false; + if (res == true) + return true; + try + { + cmd.Invoke(args); + } + catch(Exception ex) + { + Console.WriteLine("Command error: " + ex.Message); + } + + return true; } + + /// + /// Prints the user prompt to the terminal. + /// public static void PrintPrompt() { + Console.WriteLine(); if (SaveSystem.CurrentSave != null && CurrentUser != null) { - ConsoleEx.BackgroundColor = SkinEngine.LoadedSkin.TerminalBackColorCC; - ConsoleEx.Italic = false; - ConsoleEx.Underline = false; + ConsoleEx.BackgroundColor = SkinEngine.LoadedSkin.TerminalBackColorCC; + ConsoleEx.Italic = false; + ConsoleEx.Underline = false; - ConsoleEx.ForegroundColor = ConsoleColor.Magenta; - ConsoleEx.Bold = true; + ConsoleEx.ForegroundColor = ConsoleColor.Magenta; + ConsoleEx.Bold = true; - Console.Write(SaveSystem.CurrentUser.Username); - ConsoleEx.Bold = false; - ConsoleEx.ForegroundColor = ConsoleColor.Gray; - Console.Write("@"); - ConsoleEx.Italic = true; - ConsoleEx.Bold = true; - ConsoleEx.ForegroundColor = ConsoleColor.Yellow; - Console.Write(SaveSystem.CurrentSave.SystemName); - ConsoleEx.Italic = false; - ConsoleEx.Bold = false; - ConsoleEx.ForegroundColor = ConsoleColor.Gray; - Console.Write(":~"); - Console.ForegroundColor = ConsoleColor.White; - ConsoleEx.Italic = true; - if (KernelWatchdog.InKernelMode == true) - Console.Write("#"); - else - Console.Write("$"); - ConsoleEx.Italic = false; - ConsoleEx.Bold = false; - ConsoleEx.ForegroundColor = SkinEngine.LoadedSkin.TerminalForeColorCC; - Console.Write(" "); + Console.Write(SaveSystem.CurrentUser.Username); + ConsoleEx.Bold = false; + ConsoleEx.ForegroundColor = ConsoleColor.Gray; + Console.Write("@"); + ConsoleEx.Italic = true; + ConsoleEx.Bold = true; + ConsoleEx.ForegroundColor = ConsoleColor.Yellow; + Console.Write(SaveSystem.CurrentSave.SystemName); + ConsoleEx.Italic = false; + ConsoleEx.Bold = false; + ConsoleEx.ForegroundColor = ConsoleColor.Gray; + Console.Write(":~"); + Console.ForegroundColor = ConsoleColor.White; + ConsoleEx.Italic = true; + if (KernelWatchdog.InKernelMode == true) + Console.Write("#"); + else + Console.Write("$"); + ConsoleEx.Italic = false; + ConsoleEx.Bold = false; + ConsoleEx.ForegroundColor = SkinEngine.LoadedSkin.TerminalForeColorCC; + Console.Write(" "); + ConsoleEx.Flush(); } } - + /// + /// Static constructor for . + /// static TerminalBackend() { ServerMessageReceived onMessageReceived = (msg) => @@ -477,7 +562,7 @@ namespace ShiftOS.Engine if (TerminalBackend.PrefixEnabled) { - text3 = text4.Remove(0, $"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}:~$ ".Length); + text3 = text4.Remove(0, $"{SaveSystem.CurrentUser.Username}@{SaveSystem.CurrentSave.SystemName}:~$ ".Length); } IsForwardingConsoleWrites = true; if (TerminalBackend.InStory == false) @@ -486,7 +571,7 @@ namespace ShiftOS.Engine } if (TerminalBackend.PrefixEnabled) { - Console.Write($"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}:~$ "); + Console.Write($"{SaveSystem.CurrentUser.Username}@{SaveSystem.CurrentSave.SystemName}:~$ "); } IsForwardingConsoleWrites = false; } @@ -501,7 +586,7 @@ namespace ShiftOS.Engine string pass = a["password"] as string; string sys = a["sysname"] as string; string guid = msg.GUID; - if (SaveSystem.CurrentSave.Username == uName && SaveSystem.CurrentSave.Password == pass && CurrentSave.SystemName == sys) + if (SaveSystem.CurrentUser.Username == uName && SaveSystem.CurrentSave.Password == pass && CurrentSave.SystemName == sys) { ForwardGUID = guid; ServerManager.SendMessage("trm_handshake_accept", $@"{{ @@ -511,7 +596,7 @@ namespace ShiftOS.Engine IsForwardingConsoleWrites = true; InvokeCommand("sos.status"); - Console.Write($"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}:~$ "); + Console.Write($"{SaveSystem.CurrentUser.Username}@{SaveSystem.CurrentSave.SystemName}:~$ "); IsForwardingConsoleWrites = false; } } @@ -520,11 +605,25 @@ namespace ShiftOS.Engine ServerManager.MessageReceived += onMessageReceived; } + /// + /// Gets whether the terminal backend is forwarding console write requests through RTS to a remote client. + /// public static bool IsForwardingConsoleWrites { get; internal set; } + + /// + /// Gets the RTS forward GUID. + /// public static string ForwardGUID { get; internal set; } + /// + /// Occurs when the user inputs text in a Terminal. + /// public static event TextSentEventHandler TextSent; + /// + /// Fakes the user inputting text to a Terminal. + /// + /// The text to input. public static void SendText(string text) { TextSent?.Invoke(text); diff --git a/ShiftOS_TheReturn/TerminalTextWriter.cs b/ShiftOS_TheReturn/TerminalTextWriter.cs index 55e27cf..63e88eb 100644 --- a/ShiftOS_TheReturn/TerminalTextWriter.cs +++ b/ShiftOS_TheReturn/TerminalTextWriter.cs @@ -32,12 +32,28 @@ using System.Windows.Forms; namespace ShiftOS.Engine { + /// + /// Backend class for forwarding to the ShiftOS terminal. + /// public class TerminalTextWriter : TextWriter { - [System.Runtime.InteropServices.DllImport("user32.dll")] - public static extern bool LockWindowUpdate(IntPtr hWndLock); + public TerminalTextWriter() + { + ConsoleEx.OnFlush = () => + { + System.Diagnostics.Debug.WriteLine("[terminal] " + buffer); + Desktop.InvokeOnWorkerThread(() => + { + UnderlyingControl?.Write(buffer); + buffer = ""; + }); + }; + } + /// + /// Gets the encoding format for this . God bless the Unicode Consortiem. + /// public override Encoding Encoding { get @@ -46,6 +62,9 @@ namespace ShiftOS.Engine } } + /// + /// Gets the underlying that this is forwarding to. + /// public ITerminalWidget UnderlyingControl { get @@ -54,6 +73,9 @@ namespace ShiftOS.Engine } } + /// + /// Moves the caret to the last character in the textbox. + /// public void select() { Desktop.InvokeOnWorkerThread(new Action(() => @@ -63,6 +85,10 @@ namespace ShiftOS.Engine })); } + /// + /// Write a character to the Terminal. + /// + /// The character to write. public override void Write(char value) { if (TerminalBackend.IsForwardingConsoleWrites) @@ -74,14 +100,24 @@ namespace ShiftOS.Engine } else { - Desktop.InvokeOnWorkerThread(new Action(() => - { - UnderlyingControl?.Write(value.ToString()); - select(); - })); + buffer += value; } } + private string buffer = ""; + + public string Buffer + { + get + { + return buffer; + } + } + + /// + /// Write text to the Terminal, followed by a newline. + /// + /// The text to write. public override void WriteLine(string value) { if (TerminalBackend.IsForwardingConsoleWrites) @@ -94,18 +130,20 @@ namespace ShiftOS.Engine else { - Desktop.InvokeOnWorkerThread(new Action(() => - { - UnderlyingControl?.WriteLine(value); - select(); - })); + buffer += value + Environment.NewLine; + ConsoleEx.Flush(); } } + [Obsolete("Stub.")] public void SetLastText() { } + /// + /// Write text to the Terminal. + /// + /// The text to write. public override void Write(string value) { if (TerminalBackend.IsForwardingConsoleWrites) @@ -120,8 +158,7 @@ namespace ShiftOS.Engine Desktop.InvokeOnWorkerThread(new Action(() => { - UnderlyingControl?.Write(value.ToString()); - select(); + buffer += value; })); } } diff --git a/ShiftOS_TheReturn/TutorialManager.cs b/ShiftOS_TheReturn/TutorialManager.cs index ea78cd8..13df153 100644 --- a/ShiftOS_TheReturn/TutorialManager.cs +++ b/ShiftOS_TheReturn/TutorialManager.cs @@ -30,10 +30,18 @@ using System.Threading.Tasks; namespace ShiftOS.Engine { + [Obsolete("This isn't used... I don't think...")] public static class TutorialManager { + /// + /// The tutorial frontend. + /// private static ITutorial _tut = null; + /// + /// Registers a tutorial frontend to the backend. + /// + /// public static void RegisterTutorial(ITutorial tut) { IsInTutorial = false; diff --git a/ShiftOS_TheReturn/UniteClient.cs b/ShiftOS_TheReturn/UniteClient.cs deleted file mode 100644 index 1136b5c..0000000 --- a/ShiftOS_TheReturn/UniteClient.cs +++ /dev/null @@ -1,127 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace ShiftOS.Unite -{ - public class UniteClient - { - public string Token { get; private set; } - public string BaseURL { get; private set; } - - public string GetDisplayNameId(string id) - { - return MakeCall("/API/GetDisplayName/" + id); - } - - public PongHighscoreModel GetPongHighscores() - { - return JsonConvert.DeserializeObject(MakeCall("/API/GetPongHighscores")); - } - - public UniteClient(string baseurl, string usertoken) - { - BaseURL = baseurl; - Token = usertoken; - } - - internal string MakeCall(string url) - { - var webrequest = WebRequest.Create(BaseURL + url); - webrequest.Headers.Add("Authentication: Token " + Token); - using (var response = webrequest.GetResponse()) - { - using (var stream = response.GetResponseStream()) - { - using (var reader = new System.IO.StreamReader(stream)) - { - return reader.ReadToEnd(); - } - } - } - } - - public int GetPongCP() - { - return Convert.ToInt32(MakeCall("/API/GetPongCP")); - } - - public int GetPongLevel() - { - return Convert.ToInt32(MakeCall("/API/GetPongLevel")); - } - - public void SetPongLevel(int value) - { - MakeCall("/API/SetPongLevel/" + value.ToString()); - } - - public void SetPongCP(int value) - { - MakeCall("/API/SetPongCP/" + value.ToString()); - } - - public string GetEmail() - { - return MakeCall("/API/GetEmail"); - } - - public string GetSysName() - { - return MakeCall("/API/GetSysName"); - } - - public void SetSysName(string value) - { - MakeCall("/API/SetSysName/" + value); - } - - public string GetDisplayName() - { - return MakeCall("/API/GetDisplayName"); - } - - public void SetDisplayName(string value) - { - MakeCall("/API/SetDisplayName/" + value.ToString()); - } - - public string GetFullName() - { - return MakeCall("/API/GetFullName"); - } - - public void SetFullName(string value) - { - MakeCall("/API/SetFullName/" + value.ToString()); - } - - - public long GetCodepoints() - { - return Convert.ToInt64(MakeCall("/API/GetCodepoints")); - } - - public void SetCodepoints(long value) - { - MakeCall("/API/SetCodepoints/" + value.ToString()); - } - } - - public class PongHighscoreModel - { - public int Pages { get; set; } - public PongHighscore[] Highscores { get; set; } - } - - public class PongHighscore - { - public string UserId { get; set; } - public int Level { get; set; } - public long CodepointsCashout { get; set; } - } -} diff --git a/ShiftOS_TheReturn/UniteTestCommands.cs b/ShiftOS_TheReturn/UniteTestCommands.cs deleted file mode 100644 index 7a83e44..0000000 --- a/ShiftOS_TheReturn/UniteTestCommands.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Text; -using System.Threading.Tasks; - -namespace ShiftOS.Engine -{ - [Namespace("unite")] - public static class UniteTestCommands - { - [Command("setdisplayname")] - [RequiresArgument("name")] - public static bool SetDisplayName(Dictionary args) - { - string dname = args["name"].ToString(); - var unite = new ShiftOS.Unite.UniteClient("http://getshiftos.ml", SaveSystem.CurrentSave.UniteAuthToken); - unite.SetDisplayName(dname); - return true; - } - - [Command("login")] - [RequiresArgument("username")] - [RequiresArgument("password")] - public static bool LoginTest(Dictionary args) - { - string u = args["username"].ToString(); - string p = args["password"].ToString(); - var webrequest = HttpWebRequest.Create("http://getshiftos.ml/Auth/Login?appname=ShiftOS&appdesc=ShiftOS+client&version=1_0_beta_2_4"); - string base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{u}:{p}")); - webrequest.Headers.Add("Authentication: Basic " + base64); - var response = webrequest.GetResponse(); - var str = response.GetResponseStream(); - var reader = new System.IO.StreamReader(str); - string result = reader.ReadToEnd(); - Console.WriteLine("Server returned: " + result); - reader.Close(); - str.Close(); - str.Dispose(); - response.Dispose(); - - return true; - } - - [Command("linklogin")] - [RequiresArgument("username")] - [RequiresArgument("password")] - public static bool LinkLogin(Dictionary args) - { - string u = args["username"].ToString(); - string p = args["password"].ToString(); - var webrequest = HttpWebRequest.Create("http://getshiftos.ml/Auth/Login?appname=ShiftOS&appdesc=ShiftOS+client&version=1_0_beta_2_4"); - string base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{u}:{p}")); - webrequest.Headers.Add("Authentication: Basic " + base64); - var response = webrequest.GetResponse(); - var str = response.GetResponseStream(); - var reader = new System.IO.StreamReader(str); - string result = reader.ReadToEnd(); - //If we get this far, the token is OURS. :D - SaveSystem.CurrentSave.UniteAuthToken = result; - Console.WriteLine("Unite says \"Access Granted!\""); - SaveSystem.SaveGame(); - reader.Close(); - str.Close(); - str.Dispose(); - response.Dispose(); - - return true; - } - - - } -} diff --git a/ShiftOS_TheReturn/UserManagementCommands.cs b/ShiftOS_TheReturn/UserManagementCommands.cs index 1c3c0ed..a64c99c 100644 --- a/ShiftOS_TheReturn/UserManagementCommands.cs +++ b/ShiftOS_TheReturn/UserManagementCommands.cs @@ -7,11 +7,19 @@ using ShiftOS.Objects; namespace ShiftOS.Engine { + /// + /// Administrative user management terminal commands. + /// [Namespace("admin")] [KernelMode] [RequiresUpgrade("mud_fundamentals")] public static class AdminUserManagementCommands { + /// + /// Add a user to the system. + /// + /// Command arguments. + /// Command result. [Command("add", description = "Add a user to the system.", usage ="name:")] [RequiresArgument("name")] public static bool AddUser(Dictionary args) @@ -35,6 +43,12 @@ namespace ShiftOS.Engine return true; } + /// + /// Remove a user from the system. + /// + /// Command arguments. + /// Command result. + [Command("remove", description = "Remove a user from the system.", usage = "name:")] [RequiresArgument("name")] public static bool RemoveUser(Dictionary args) @@ -47,12 +61,25 @@ namespace ShiftOS.Engine } var user = SaveSystem.CurrentSave.Users.FirstOrDefault(x => x.Username == name); + if(user.Username != SaveSystem.CurrentUser.Username) + { + Console.WriteLine("Error: Cannot remove yourself."); + return true; + } SaveSystem.CurrentSave.Users.Remove(user); Console.WriteLine($"Removing user \"{name}\" from system..."); SaveSystem.SaveGame(); return true; } + + + /// + /// Set access control level for a user. + /// + /// Command arguments. + /// Command result. + [Command("set_acl")] [RequiresArgument("user")] [RequiresArgument("val")] @@ -116,14 +143,76 @@ namespace ShiftOS.Engine return true; } + /// + /// List all users in the system. + /// + /// Command arguments. + /// Command result. + + [Command("users", description = "Get a list of all users on the system.")] + public static bool GetUsers() + { + foreach (var u in SaveSystem.CurrentSave.Users) + { + if (u.Username == SaveSystem.CurrentUser.Username) + { + ConsoleEx.ForegroundColor = ConsoleColor.Magenta; + ConsoleEx.Bold = true; + } + else + { + ConsoleEx.ForegroundColor = ConsoleColor.Gray; + ConsoleEx.Bold = false; + } + Console.WriteLine(u.Username); + } + return true; + } } + /// + /// Non-administrative user management terminal commands. + /// [Namespace("user")] [RequiresUpgrade("mud_fundamentals")] public static class UserManagementCommands { + /// + /// Log in as another user. + /// + /// Command arguments. + /// Command result. + [Command("login", description = "Log in as another user.")] + [RequiresArgument("user")] + [RequiresArgument("pass")] + public static bool Login(Dictionary args) + { + string user = args["user"].ToString(); + string pass = args["pass"].ToString(); + var usr = SaveSystem.CurrentSave.Users.FirstOrDefault(x => x.Username == user); + if(usr==null) + { + Console.WriteLine("Error: No such user."); + return true; + } + if (usr.Password != pass) + { + Console.WriteLine("Access denied."); + return true; + } + + SaveSystem.CurrentUser = usr; + Console.WriteLine("Access granted."); + return true; + } + + /// + /// Set the password for the current user. + /// + /// Command arguments. + /// Command result. [Command("setpass", description ="Allows you to set your password to a new value.", usage ="old:,new:")] [RequiresArgument("old")] [RequiresArgument("new")] diff --git a/ShiftOS_TheReturn/VirusEngine.cs b/ShiftOS_TheReturn/VirusEngine.cs deleted file mode 100644 index 650db92..0000000 --- a/ShiftOS_TheReturn/VirusEngine.cs +++ /dev/null @@ -1,106 +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; -using System.Threading.Tasks; -using Newtonsoft.Json; -using static ShiftOS.Objects.ShiftFS.Utils; - - -namespace ShiftOS.Engine -{ - public static class VirusEngine - { - public static void InfectFile(string file, string virusid) - { - var infected = new List(); - var hData = GetHeaderText(file); - - if (hData == "") - { - infected.Add(virusid); - } - else - { - infected = JsonConvert.DeserializeObject>(hData); - if (!infected.Contains(virusid)) - infected.Add(virusid); - } - - SetHeaderText(file, JsonConvert.SerializeObject(infected)); - } - - public static void DisinfectFile(string file, int threatlevel) - { - var infected = new List(); - var hData = GetHeaderText(file); - - if (hData != "") - { - infected = JsonConvert.DeserializeObject>(hData); - for (int i = 0; i < infected.Count; i++) - { - string[] splitID = infected[i].Split('.'); - int th = Convert.ToInt32(splitID[splitID.Length - 1]); - if (th <= threatlevel) - { - infected.RemoveAt(i); - } - } - } - - SetHeaderText(file, JsonConvert.SerializeObject(infected)); - } - - internal static string[] FindAllVirusesInFile(string file) - { - string hdata = GetHeaderText(file); - return (hdata != "") ? new string[0] : JsonConvert.DeserializeObject(hdata); - } - - } - - public abstract class Virus - { - /// - /// Inject the virus into system memory by running it. - /// - public abstract void Activate(); - - /// - /// Terminate the virus. - /// - public abstract void Deactivate(); - - public abstract int ThreatLevel { get; } - - public abstract string Signature { get; } - - public abstract string Type { get; } - } -}