diff options
| author | Michael VanOverbeek <[email protected]> | 2017-04-07 17:02:38 +0000 |
|---|---|---|
| committer | Michael VanOverbeek <[email protected]> | 2017-04-07 17:02:38 +0000 |
| commit | 3d48f3101aa25050e6b219fc1111293273a59fa4 (patch) | |
| tree | 40bf8d722245d02d87b0914a38e2b09673e093c0 | |
| parent | edf4aef6adf8a2a45c347f70804fc5ac93070576 (diff) | |
| parent | 3789b48df00e89fa6dcd7e27bb6885ba880504f6 (diff) | |
| download | shiftos_thereturn-3d48f3101aa25050e6b219fc1111293273a59fa4.tar.gz shiftos_thereturn-3d48f3101aa25050e6b219fc1111293273a59fa4.tar.bz2 shiftos_thereturn-3d48f3101aa25050e6b219fc1111293273a59fa4.zip | |
Merge branch 'master' of https://github.com/shiftos-game/ShiftOS
49 files changed, 7231 insertions, 1706 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d995742..8dd07d6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,12 +1,30 @@ # Contributing to ShiftOS -## Reporting Bugs +## Reporting Bugs / Suggesting Enhancements -Follow the `Templates/IssueTemplate.md` +### Issue Template -## Suggesting Enhancements +#### What you expected to happen -Follow the `Templates/IssueTemplate.md` +#### What actually happened + +#### Steps To Reproduce + + # What you expected to happen + + # What actually happened + + # Steps To Reproduce + +### Suggestion Template + +#### What should be added to the game/api + +#### Why it should be added + + # What should be added to the game/api + + # Why it should be added ## Pull Requests @@ -14,9 +32,14 @@ Follow our code style PublicVariableNames privateVariableNames CONSTANT_VARIABLE_NAMES PublicMethodNames privateMethodNames - ClassNames - - BracketsOnNewLines() + ClassNamesLikeThis { - + public Type VariableName; + + public void BracketsOnNewLines() + { + var variableName; + } } + +Insert licenses at the top of ALL `.cs` files @@ -6,16 +6,16 @@ The official, open-source, C# revamp of ShiftOS. ## License -We are licensed under the MIT license. A simple description is: +We are licensed under the [MIT license](https://github.com/shiftos-game/ShiftOS/blob/master/LICENSE). A simple description is: -1. Don't steal our code and call it yours -2. If you fork us, leave any copyright statements and license info at the top of all .cs files. You can use the InsertLicense executable to insert the statement into any code files missing the copyright statement. +1. Don't steal our code and claim ownership of it +2. Leave copyright statements and license info at the top of all .cs files. `InsertLicense.exe` can be used to add the license to all files without it. -### Using our code for your own front-end project +### Using our code for your own project -You may use the ShiftOS.Engine, ShiftOS.Objects, and ShiftOS.Server projects to create your own games. You must include the original license and link back to this in your game or credits. +You may use the ShiftOS.Engine, ShiftOS.Objects, and ShiftOS.Server projects to create your own games. You must include the original license and link back to [ShiftOS](https://github.com/shiftos-game/ShiftOS) in your `README` and in your game or credits. ## Contributing -See `CONTRIBUTING.md` +See [`CONTRIBUTING.md`](https://github.com/shiftos-game/ShiftOS/blob/master/CONTRIBUTING.md) diff --git a/ShiftOS.Objects/ShiftOS.Objects.csproj b/ShiftOS.Objects/ShiftOS.Objects.csproj index 3dc0c33..d9b8bf7 100644 --- a/ShiftOS.Objects/ShiftOS.Objects.csproj +++ b/ShiftOS.Objects/ShiftOS.Objects.csproj @@ -54,8 +54,8 @@ <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Save.cs" /> <Compile Include="ShiftFS.cs" /> - <Compile Include="ShiftOSMenuRenderer.cs" /> <Compile Include="Shop.cs" /> + <Compile Include="Unite\Download.cs" /> </ItemGroup> <ItemGroup> <None Include="packages.config" /> diff --git a/ShiftOS.Objects/ShiftOSMenuRenderer.cs b/ShiftOS.Objects/ShiftOSMenuRenderer.cs deleted file mode 100644 index c76bd35..0000000 --- a/ShiftOS.Objects/ShiftOSMenuRenderer.cs +++ /dev/null @@ -1,51 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 Michael VanOverbeek and ShiftOS devs - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace ShiftOS.Objects -{ - class ShiftOSMenuRenderer : ToolStripProfessionalRenderer - { - public ShiftOSMenuRenderer() : base(new ShiftOSColorTable()) - { - - } - - protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e) - { - - } - } - - public class ShiftOSColorTable : ProfessionalColorTable - { - - } -} diff --git a/ShiftOS.Objects/Unite/Download.cs b/ShiftOS.Objects/Unite/Download.cs new file mode 100644 index 0000000..089a98c --- /dev/null +++ b/ShiftOS.Objects/Unite/Download.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShiftOS.Objects.Unite +{ + public class Download + { + public string Id { get; set; } + public string Name { get; set; } + public string Changelog { get; set; } + public string DownloadUrl { get; set; } + public bool Obsolete { get; set; } + public DateTime PostDate { get; set; } + public string ReleasedBy { get; set; } + public string DevUpdateId { get; set; } + public string ScreenshotUrl { get; set; } + public bool IsStable { get; set; } + } +} diff --git a/ShiftOS.Server.WebAdmin/App.config b/ShiftOS.Server.WebAdmin/App.config deleted file mode 100644 index 2a7dffa..0000000 --- a/ShiftOS.Server.WebAdmin/App.config +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<configuration> - <startup> - <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> - </startup> - <runtime> - <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> - <dependentAssembly> - <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" /> - <bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" /> - </dependentAssembly> - <dependentAssembly> - <assemblyIdentity name="System.Interactive.Async" publicKeyToken="94bc3704cddfc263" culture="neutral" /> - <bindingRedirect oldVersion="0.0.0.0-3.0.1000.0" newVersion="3.0.1000.0" /> - </dependentAssembly> - </assemblyBinding> - </runtime> -</configuration>
\ No newline at end of file diff --git a/ShiftOS.Server.WebAdmin/Program.cs b/ShiftOS.Server.WebAdmin/Program.cs deleted file mode 100644 index 1e4a0b8..0000000 --- a/ShiftOS.Server.WebAdmin/Program.cs +++ /dev/null @@ -1,808 +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.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Nancy; -using Nancy.Authentication.Forms; -using Nancy.Bootstrapper; -using Nancy.Hosting.Self; -using Nancy.ModelBinding; -using Nancy.Security; -using Nancy.TinyIoc; -using Newtonsoft.Json; -using ShiftOS.Objects; - -namespace ShiftOS.Server.WebAdmin -{ - class Program - { - static void Main(string[] args) - { - var HostConf = new HostConfiguration(); - HostConf.UrlReservations.CreateAutomatically = true; - HostConf.RewriteLocalhost = true; - using(var nancy = new NancyHost(HostConf, new Uri("http://localhost:13371/mudadmin/"))) - { - nancy.Start(); - Console.WriteLine($"[{DateTime.Now}] <AdminPanel/NancyInit> Initiating on localhost:13371..."); - Console.ReadLine(); - } - } - } - - public static class PageBuilder - { - public static string Build(string page, Dictionary<string, string> templateParams = null) - { - string templatehtml = Properties.Resources.HtmlTemplate; - if (templateParams == null) - { - templateParams = new Dictionary<string, string>(); - } - if (!templateParams.ContainsKey("{logout}")) - { - templateParams.Add("{logout}", "<li><a href=\"/mudadmin/logout\">Log out</a></li>"); - } - if (SystemManager.MudIsRunning()) - { - templateParams.Add("{mud_power}", "<li><a href='/mudadmin/poweroff'><span class='glyphicon glyphicon-power-off'></span> Power off</a></li>"); - templateParams.Add("{mud_restart}", "<li><a href='/mudadmin/restart'><span class='glyphicon glyphicon-refresh'></span> Restart</a></li>"); - } - else - { - templateParams.Add("{mud_power}", "<li><a href='/mudadmin/poweron'><span class='glyphicon glyphicon-power-on'></span> Power on</a></li>"); - templateParams.Add("{mud_restart}", ""); - } - - if(templateParams["{logout}"] == "") - { - templateParams["{mud_power}"] = ""; - templateParams["{mud_restart}"] = ""; - - } - - switch (page) - { - case "status": - templatehtml = templatehtml.Replace("{body}", Properties.Resources.Status); - break; - case "login": - templatehtml = templatehtml.Replace("{body}", Properties.Resources.LoginView); - break; - case "initialsetup": - templatehtml = templatehtml.Replace("{body}", Properties.Resources.SetupView); - break; - } - try - { - foreach (var param in templateParams) - { - templatehtml = templatehtml.Replace(param.Key, param.Value); - } - } - catch { } - return templatehtml; - } - } - - public class MudUserIdentity : IUserIdentity - { - public MudUserIdentity(string username) - { - _username = username; - } - - public IEnumerable<string> Claims - { - get - { - return SystemManager.GetClaims(_username); - } - } - - private string _username = ""; - - public string UserName - { - get - { - return _username; - } - } - } - - public static class SystemManager - { - public static bool MudIsRunning() - { - var processes = System.Diagnostics.Process.GetProcessesByName("ShiftOS.Server"); - return processes.Length > 0; - } - - public static void KillMud() - { - var processes = System.Diagnostics.Process.GetProcessesByName("ShiftOS.Server"); - for(int i = 0; i < processes.Length; i++) - { - try - { - processes[i].Kill(); - } - catch - { - } - } - } - - public static List<string> GetClaims(string username) - { - foreach(var save in GetSaves()) - { - if (save.IsMUDAdmin) - { - return new List<string> { "User", "Admin" }; - } - } - return new List<string>(new[] { "User" }); - } - - public static Save[] GetSaves() - { - List<Save> saves = new List<Save>(); - if (Directory.Exists("saves")) - { - foreach(var saveFile in Directory.GetFiles("saves")) - { - try - { - saves.Add(JsonConvert.DeserializeObject<Save>(Server.Program.ReadEncFile(saveFile))); - } - catch { } - } - } - return saves.ToArray(); - } - - public static bool Login(string username, string password, out Guid id) - { - foreach (var user in GetSaves()) - { - if (user.Username == username && user.Password == password) - { - id = user.ID; - return true; - } - } - id = new Guid(); - return false; - } - - public static string BuildFormFromObject(object obj) - { - StringBuilder sb = new StringBuilder(); - sb.AppendLine("<form method='post' action=''><table class='table'>"); - foreach(var prop in obj.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)) - { - string name = ""; - string description = "No description."; - foreach(var attrib in prop.GetCustomAttributes(false)) - { - if(attrib is FriendlyNameAttribute) - { - name = (attrib as FriendlyNameAttribute).Name; - } - if(attrib is FriendlyDescriptionAttribute) - { - description = (attrib as FriendlyDescriptionAttribute).Description; - } - } - if (name != "") - { - sb.AppendLine("<tr>"); - - sb.AppendLine($@"<td width=""45%""> - <p><strong>{name}</strong></p> - <p>{description}</p> -</td> -<td>"); - if (prop.PropertyType == typeof(bool)) - { - string isChecked = ((bool)prop.GetValue(obj) == true) ? "checked" : ""; - sb.AppendLine($"<input class='form-control' type='checkbox' name='{prop.Name}' {isChecked}/>"); - } - else if (prop.PropertyType == typeof(string)) - { - sb.AppendLine($"<input class='form-control' type='text' name='{prop.Name}' value='{prop.GetValue(obj)}'/>"); - } - - sb.AppendLine("</td></tr>"); - } - else - { - sb.AppendLine($"<input type='hidden' name='{prop.Name}' value='{prop.GetValue(obj)}'/>"); - } - } - sb.AppendLine("<tr><td></td><td><input class='btn btn-default' type='submit'/></td></tr>"); - sb.AppendLine("</table></form>"); - return sb.ToString(); - } - - public static Channel GetChat(string id) - { - if (File.Exists("chats.json")) - foreach (var channel in JsonConvert.DeserializeObject<List<Channel>>(File.ReadAllText("chats.json"))) - { - if (channel.ID == id) - return channel; - } - return new Channel(); - } - - public static string BuildSaveListing(Save[] list) - { - StringBuilder sb = new StringBuilder(); - sb.AppendLine("<table class=\"table\">"); - - sb.AppendLine(@"<tr> - <td><strong>Username</strong></td> - <td><strong>System Name</strong></td> - <td><strong>Codepoints</strong></td> - <td><strong>Shiftorium Upgrades</strong></td> - <td><strong>Is MUD Admin</strong></td> - <td><strong>Actions</strong></td> -</tr>"); - - foreach(var save in list) - { - sb.AppendLine($@"<tr> - <td>{save.Username}</td> - <td>{save.SystemName}</td> - <td>{save.Codepoints}</td> - <td>{save.CountUpgrades()} installed, {save.Upgrades.Count} total</td> - <td>{save.IsMUDAdmin}</td> - <td> - <a href=""/mudadmin/toggleadmin/{save.Username}"" class=""btn btn-danger"">Toggle admin</a> - <a href=""/mudadmin/deletesave/{save.Username}"" class=""btn btn-danger"">Delete save</a> - </td> -</tr>"); - } - - sb.AppendLine("</table>"); - return sb.ToString(); - } - - - public static string GetAllChats() - { - StringBuilder sb = new StringBuilder(); - sb.AppendLine("<table class=\"table\">"); - sb.AppendLine($@"<tr><td><strong>ID</strong></td> - <td><strong>Name</strong></td> - <td><strong>Topic</strong></td> - <td><strong>Is Discord Relay</strong></td> - <td><strong>Discord channel ID</strong></td> - <td><strong>Discord Bot Token</strong></td> - <td><strong>Actions</strong></td></tr>"); - if (File.Exists("chats.json")) - { - foreach(var chat in JsonConvert.DeserializeObject<List<Channel>>(File.ReadAllText("chats.json"))) - { - sb.AppendLine($@"<tr> - <td>{chat.ID}</td> - <td>{chat.Name}</td> - <td>{chat.Topic}</td> - <td>{chat.IsDiscordProxy}</td> - <td>{chat.DiscordChannelID}</td> - <td>{chat.DiscordBotToken}</td> - <td> - <a href=""/mudadmin/editchat/{chat.ID}"" class=""btn btn-default""><span class=""glyphicon glyphicon-pencil""></span>Edit</a> - <a href=""#"" class=""btn btn-default"" data-toggle=""modal"" data-target=""#modal_{chat.ID}""><span class=""glyphicon glyphicon-delete""></span> Delete</a> - </td> -</tr>"); - sb.AppendLine(CreateModal(chat.ID, "Delete " + chat.Name + "?", "Are you sure you want to delete this chat?", "/deletechat/" + chat.ID)); - } - } - sb.AppendLine("</table>"); - return sb.ToString(); - } - - public static string CreateModal(string id, string title, string msg, string callbackUrl) - { - return $@"<div id=""modal_{id}"" class=""modal fade"" role=""dialog""> - <div class=""modal-dialog""> - - <!-- Modal content--> - <div class=""modal-content""> - <div class=""modal-header""> - <button type=""button"" class=""close"" data-dismiss=""modal"">×</button> - <h4 class=""modal-title"">{title}</h4> - </div> - <div class=""modal-body""> - <p>{msg}</p> - </div> - <div class=""modal-footer""> - <a href=""/mudadmin{callbackUrl}"" class=""btn btn-danger"">Yes</a> - <button type=""button"" class=""btn btn-default"" data-dismiss=""modal"">No</button> - </div> - </div> - - </div> -</div>"; - } - - public static string GetCPWorth() - { - if (System.IO.Directory.Exists("saves")) - { - long cp = 0; - - foreach(var file in System.IO.Directory.GetFiles("saves")) - { - if (file.EndsWith(".save")) - { - var save = JsonConvert.DeserializeObject<Save>(Server.Program.ReadEncFile(file)); - cp += save.Codepoints; - } - } - return cp.ToString(); - } - else - { - return "0"; - } - } - - public static string GetUserCount() - { - if (System.IO.Directory.Exists("saves")) - { - return System.IO.Directory.GetFiles("saves").Length.ToString(); - } - else - { - return "0"; - } - } - - public static MudUserIdentity GetIdentity(Guid id) - { - foreach (var user in GetSaves()) - { - if (user.ID == id) - { - return new WebAdmin.MudUserIdentity(user.Username); - } - } - return null; - } - - internal static void MakeAdmin(string username) - { - Save sav = null; - foreach(var save in GetSaves()) - { - if (save.Username == username) - sav = save; - } - if(sav != null) - { - sav.IsMUDAdmin = true; - Server.Program.WriteEncFile("saves/" + username + ".save", JsonConvert.SerializeObject(sav)); - } - } - - internal static Save[] GetAdmins() - { - var saves = new List<Save>(); - foreach(var save in GetSaves()) - { - if(save.IsMUDAdmin == true) - { - saves.Add(save); - } - } - return saves.ToArray(); - } - } - - public class MudUser - { - [FriendlyName("Username")] - [FriendlyDescription("The username you will appear as in-game.")] - public string Username { get; set; } - - [FriendlyName("Password")] - [FriendlyDescription("A password that you will use to log in to the admin panel and the game.")] - public string Password { get; set; } - - [FriendlyName("System name")] - [FriendlyDescription("An in-game hostname for your account. In ShiftOS, your user ID is always yourusername@yoursystemname. Be creative.")] - public string SystemName { get; set; } - - public Guid ID { get; set; } - } - - public class MudBootstrapper : DefaultNancyBootstrapper - { - protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines) - { - var formsAuthConfiguration = new FormsAuthenticationConfiguration(); - formsAuthConfiguration.RedirectUrl = "~/login"; - formsAuthConfiguration.UserMapper = container.Resolve<IUserMapper>(); - FormsAuthentication.Enable(pipelines, formsAuthConfiguration); - base.ApplicationStartup(container, pipelines); - } - } - - - public class MudUserMapper : IUserMapper - { - public IUserIdentity GetUserFromIdentifier(Guid identifier, NancyContext context) - { - return SystemManager.GetIdentity(identifier); - } - } - - public class LoginModule : NancyModule - { - public LoginModule() - { - Get["/login"] = parameters => - { - if (SystemManager.GetSaves().Length > 0) - { - if (SystemManager.GetAdmins().Length > 0) - { - return PageBuilder.Build("login", new Dictionary<string, string> - { - {"{logout}", "" } - }); - } - else - { - return PageBuilder.Build("initialsetup", new Dictionary<string, string> - { - {"{logout}", "" }, - {"{savelist}", BuildSaveList() } - }); - } - } - else - { - return PageBuilder.Build("bla", new Dictionary<string, string> - { - {"{body}", Properties.Resources.NoUsersFound }, - {"{user_create_form}", SystemManager.BuildFormFromObject(new MudUser()) } - }); - } - }; - - Get["/logout"] = parameters => - { - return this.Logout("~/"); - }; - - Post["/login"] = parameters => - { - if (SystemManager.GetSaves().Length > 0) - { - if (SystemManager.GetAdmins().Length == 0) - { - var user = this.Bind<LoginRequest>(); - SystemManager.MakeAdmin(user.username); - Guid id = new Guid(); - if(SystemManager.Login(user.username, user.password, out id) == true) - { - return this.Login(id); - } - return new UserModule().Redirect("/login"); - } - else - { - var user = this.Bind<LoginRequest>(); - Guid id = new Guid(); - if (SystemManager.Login(user.username, user.password, out id) == true) - { - return this.Login(id); - } - return new UserModule().Redirect("/login"); - } - } - else - { - var newUser = this.Bind<MudUser>(); - var save = new Save(); - save.Username = newUser.Username; - save.SystemName = newUser.SystemName; - save.Password = newUser.Password; - save.Codepoints = 0; - save.MyShop = ""; - save.Upgrades = new Dictionary<string, bool>(); - save.IsMUDAdmin = true; - save.StoryPosition = 1; - - if (!Directory.Exists("saves")) - Directory.CreateDirectory("saves"); - save.ID = Guid.NewGuid(); - - Server.Program.WriteEncFile("saves/" + save.Username + ".save", JsonConvert.SerializeObject(save)); - return this.Login(save.ID); - } - }; - } - - private string BuildSaveList() - { - StringBuilder sb = new StringBuilder(); - sb.AppendLine("<table class='table'>"); - sb.AppendLine($@"<tr> - <td><strong>Username</strong></td> - <td><strong>System name</strong></td> - <td><strong>Codepoints</strong></td> - <td><strong>Actions</strong></td> -</tr>"); - - foreach(var save in SystemManager.GetSaves()) - { - sb.AppendLine($@"<tr> - <td>{save.Username}</td> - <td>{save.SystemName}</td> - <td>{save.Codepoints}</td> - <td><form method='post' action=''> - <input type='hidden' name='username' value='{save.Username}'/><input type='hidden' name='password' value='{save.Password}'/> - <input type='submit' value='Choose' class='btn btn-default'/> - </form></td> -</tr>"); - } - - sb.AppendLine("</table>"); - return sb.ToString(); - } - } - - - - public class UserModule : NancyModule - { - public string Redirect(string url) - { - return $@"<html> - <head> - <meta http-equiv=""refresh"" content=""0; url=/mudadmin{url}"" /> - </ head> -</html>"; - } - - public UserModule() - { - this.RequiresAuthentication(); - this.RequiresClaims("Admin"); - Get["/"] = _ => - { - return Redirect("/status"); - }; - - Get["/toggleadmin/{id}"] = parameters => - { - string id = parameters.id; - for (int i = 0; i < SystemManager.GetSaves().Length; i++) - { - var save = SystemManager.GetSaves()[i]; - if(save.Username.ToString() == id) - { - save.IsMUDAdmin = !save.IsMUDAdmin; - Server.Program.WriteEncFile("saves/" + save.Username + ".save", JsonConvert.SerializeObject(save)); - } - } - return Redirect("/saves"); - - }; - - Get["/deletesave/{username}"] = parameters => - { - - - string id = parameters.username; - for (int i = 0; i < SystemManager.GetSaves().Length; i++) - { - if (SystemManager.GetSaves()[i].Username.ToString() == id) - { - File.Delete("saves/" + SystemManager.GetSaves()[i].Username + ".save"); - } - } - return Redirect("/saves"); - }; - - - Get["/saves"] = _ => - { - return PageBuilder.Build("bla", new Dictionary<string, string> - { - { "{body}", Properties.Resources.GenericTableList }, - { "{listtitle}", "Test subjects" }, - { "{listdesc}", "Below is a list of test subjects (save files) on your multi-user domain. You can see their username, system name, Codepoints, amount of installed upgrades, and you can also perform basic actions on each save." }, - { "{list}", SystemManager.BuildSaveListing(SystemManager.GetSaves()) } - }); - }; - - Get["/status"] = _ => - { - return statusBuilder(); - }; - - Get["/deletechat/{id}"] = parameters => - { - string chatID = parameters.id; - var chats = JsonConvert.DeserializeObject<List<Channel>>(File.ReadAllText("chats.json")); - for(int i = 0; i < chats.Count; i++) - { - try - { - if (chats[i].ID == chatID) - chats.RemoveAt(i); - } - catch { } - } - File.WriteAllText("chats.json", JsonConvert.SerializeObject(chats, Formatting.Indented)); - return Redirect("/chats"); - }; - - Get["/chats"] = _ => - { - return chatsListBuilder(); - }; - - Get["/createchat"] = _ => - { - return PageBuilder.Build("editchat", new Dictionary<string, string> - { - {"{body}", Properties.Resources.ChatEditTemplate }, - {"{form}", SystemManager.BuildFormFromObject(new Channel()) } - }); - }; - - Post["/createchat"] = parameters => - { - var chat = this.Bind<Channel>(); - chat.ID = chat.Name.ToLower().Replace(" ", "_"); - List<Channel> chats = new List<Channel>(); - if (File.Exists("chats.json")) - chats = JsonConvert.DeserializeObject<List<Channel>>(File.ReadAllText("chats.json")); - - bool chatExists = false; - - for (int i = 0; i < chats.Count; i++) - { - if (chats[i].ID == chat.ID) - { - chats[i] = chat; - chatExists = true; - } - } - - if (!chatExists) - { - chats.Add(chat); - } - - File.WriteAllText("chats.json", JsonConvert.SerializeObject(chats, Formatting.Indented)); - - return Redirect("/chats"); - }; - - Get["/editchat/{id}"] = parameters => - { - return PageBuilder.Build("editchat", new Dictionary<string, string> - { - {"{body}", Properties.Resources.ChatEditTemplate }, - {"{form}", SystemManager.BuildFormFromObject(SystemManager.GetChat(parameters.id)) } - }); - }; - - Post["/editchat/{id}"] = parameters => - { - var chat = this.Bind<Channel>(); - chat.ID = chat.Name.ToLower().Replace(" ", "_"); - List<Channel> chats = new List<Channel>(); - if (File.Exists("chats.json")) - chats = JsonConvert.DeserializeObject<List<Channel>>(File.ReadAllText("chats.json")); - - bool chatExists = false; - - for (int i = 0; i < chats.Count; i++) - { - if (chats[i].ID == chat.ID) - { - chats[i] = chat; - chatExists = true; - } - } - - if (!chatExists) - { - chats.Add(chat); - } - - File.WriteAllText("chats.json", JsonConvert.SerializeObject(chats, Formatting.Indented)); - return Redirect("/chats"); - }; - - Get["/poweron"] = _ => - { - if (!SystemManager.MudIsRunning()) - { - System.Diagnostics.Process.Start("ShiftOS.Server.exe"); - } - return Redirect("/"); - }; - - Get["/poweroff"] = _ => - { - if (SystemManager.MudIsRunning()) - { - SystemManager.KillMud(); - } - return Redirect("/"); - }; - Get["/restart"] = _ => - { - if (SystemManager.MudIsRunning()) - { - SystemManager.KillMud(); - } - return Redirect("/poweron"); - }; - } - - private string statusBuilder() - { - return PageBuilder.Build("status", new Dictionary<string, string>{ - { "{cp_worth}", SystemManager.GetCPWorth() }, - { "{user_count}", SystemManager.GetUserCount() }, - { "{system_time}", DateTime.Now.ToString() }, - }); - - } - - private string chatsListBuilder() - { - return PageBuilder.Build("bla", new Dictionary<string, string> - { - { "{body}", Properties.Resources.ChatListView }, - { "{chat_table}", SystemManager.GetAllChats() } - }); - } - } - - public class LoginRequest - { - public string username { get; set; } - public string password { get; set; } - } -} diff --git a/ShiftOS.Server.WebAdmin/Properties/AssemblyInfo.cs b/ShiftOS.Server.WebAdmin/Properties/AssemblyInfo.cs deleted file mode 100644 index 7a9d939..0000000 --- a/ShiftOS.Server.WebAdmin/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,60 +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.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ShiftOS.Server.WebAdmin")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ShiftOS.Server.WebAdmin")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("b29fdd06-e6fe-40a2-8258-283728ced81a")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/ShiftOS.Server.WebAdmin/Properties/Resources.Designer.cs b/ShiftOS.Server.WebAdmin/Properties/Resources.Designer.cs deleted file mode 100644 index 870aea3..0000000 --- a/ShiftOS.Server.WebAdmin/Properties/Resources.Designer.cs +++ /dev/null @@ -1,220 +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. - */ - -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// </auto-generated> -//------------------------------------------------------------------------------ - -namespace ShiftOS.Server.WebAdmin.Properties { - using System; - - - /// <summary> - /// A strongly-typed resource class, for looking up localized strings, etc. - /// </summary> - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// <summary> - /// Returns the cached ResourceManager instance used by this class. - /// </summary> - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ShiftOS.Server.WebAdmin.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// <summary> - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// </summary> - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// <summary> - /// Looks up a localized string similar to <h3>Create/edit chat</h3> - /// - ///<p>Please fill out the details below for your channel list to be modified.</p> - /// - ///{form}. - /// </summary> - internal static string ChatEditTemplate { - get { - return ResourceManager.GetString("ChatEditTemplate", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to <h3>Chats</h3> - /// - ///<p>On this page you can find a list of all chats in the system. Chats are a part of the multi-user domain that allows online players to talk to eachother in the 'MUD Chat' application.</p> - /// - ///<p>If you have a Discord server for your multi-user domain, you can also designate a ShiftOS chat to listen on a specific channel on your server. You will need to create a Discord Bot Token and specify the ID of the channel you want tolisten to.</p> - /// - ///<p>Once the chat is set up, you should see a bot [rest of string was truncated]";. - /// </summary> - internal static string ChatListView { - get { - return ResourceManager.GetString("ChatListView", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to <h3>{listtitle}</h3> - /// - ///<p>{listdesc}</p> - /// - ///{list}. - /// </summary> - internal static string GenericTableList { - get { - return ResourceManager.GetString("GenericTableList", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to <html> - /// <head> - /// <title>Multi-user domain &bull; ShiftOS</title> - /// <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> - /// - /// <link rel="stylesheet" href="http://getshiftos.ml/css/theme.css"/> - /// - /// <!-- Latest compiled and minified JavaScript --> - /// <script src="https://code.jquery.com/jquery-3.1.1.js" integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7C [rest of string was truncated]";. - /// </summary> - internal static string HtmlTemplate { - get { - return ResourceManager.GetString("HtmlTemplate", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to <h3>Access denied.</h3> - /// - ///<p>You require a higher authentication level to access this part of the multi-user domain. Please enter the username and password of whom has access to this sector.</p> - /// - ///<form method="post" action=""> - /// <table class="table"> - /// <tr> - /// <td><strong>Username:</strong></td> - /// <td><input class="form-control" type="text" name="username"/></td> - /// </tr> - /// <tr> - /// <td><strong>Password:</strong></td> - /// <td><input class="form-control" type="password" name="password"/></td> - /// </tr [rest of string was truncated]";. - /// </summary> - internal static string LoginView { - get { - return ResourceManager.GetString("LoginView", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to <h3>No users found.</h3> - /// - ///<p>Your multi-user domain is newly-created. Before you can use the admin panel, you must create a ShiftOS user to act as the administrator of the MUD.</p> - /// - ///{user_create_form}. - /// </summary> - internal static string NoUsersFound { - get { - return ResourceManager.GetString("NoUsersFound", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to <h1>Initial setup</h1> - /// - ///<p>This multi-user domain contains some users, however none of them are administrators. Please choose your user to make it an admin.</p> - /// - ///{savelist}. - /// </summary> - internal static string SetupView { - get { - return ResourceManager.GetString("SetupView", resourceCulture); - } - } - - /// <summary> - /// Looks up a localized string similar to <h3>System status</h3> - /// - ///<p>Below is a summary of this multi-user domain's status.</p> - /// - ///<div class="row"> - /// <div class="col-xs-6"> - /// <h4>MUD stats</h4> - /// <ul> - /// <li>This server is worth <strong>{cp_worth}</strong> Codepoints.</li> - /// <li>This server has <strong>{user_count}</strong> players registered.</li> - /// </ul> - /// </div> - /// <div class="col-xs-6"> - /// <h4>System environment</h4> - /// <ul> - /// <li><strong>Current system time:</strong> {system_time}</li> - /// </ul> - /// </div> - ///</div>. - /// </summary> - internal static string Status { - get { - return ResourceManager.GetString("Status", resourceCulture); - } - } - } -} diff --git a/ShiftOS.Server.WebAdmin/Properties/Resources.resx b/ShiftOS.Server.WebAdmin/Properties/Resources.resx deleted file mode 100644 index b756946..0000000 --- a/ShiftOS.Server.WebAdmin/Properties/Resources.resx +++ /dev/null @@ -1,145 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<root> - <!-- - Microsoft ResX Schema - - Version 2.0 - - The primary goals of this format is to allow a simple XML format - that is mostly human readable. The generation and parsing of the - various data types are done through the TypeConverter classes - associated with the data types. - - Example: - - ... ado.net/XML headers & schema ... - <resheader name="resmimetype">text/microsoft-resx</resheader> - <resheader name="version">2.0</resheader> - <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> - <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> - <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> - <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> - <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> - <value>[base64 mime encoded serialized .NET Framework object]</value> - </data> - <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> - <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> - <comment>This is a comment</comment> - </data> - - There are any number of "resheader" rows that contain simple - name/value pairs. - - Each data row contains a name, and value. The row also contains a - type or mimetype. Type corresponds to a .NET class that support - text/value conversion through the TypeConverter architecture. - Classes that don't support this are serialized and stored with the - mimetype set. - - The mimetype is used for serialized objects, and tells the - ResXResourceReader how to depersist the object. This is currently not - extensible. For a given mimetype the value must be set accordingly: - - Note - application/x-microsoft.net.object.binary.base64 is the format - that the ResXResourceWriter will generate, however the reader can - read any of the formats listed below. - - mimetype: application/x-microsoft.net.object.binary.base64 - value : The object must be serialized with - : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter - : and then encoded with base64 encoding. - - mimetype: application/x-microsoft.net.object.soap.base64 - value : The object must be serialized with - : System.Runtime.Serialization.Formatters.Soap.SoapFormatter - : and then encoded with base64 encoding. - - mimetype: application/x-microsoft.net.object.bytearray.base64 - value : The object must be serialized into a byte array - : using a System.ComponentModel.TypeConverter - : and then encoded with base64 encoding. - --> - <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> - <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> - <xsd:element name="root" msdata:IsDataSet="true"> - <xsd:complexType> - <xsd:choice maxOccurs="unbounded"> - <xsd:element name="metadata"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" /> - </xsd:sequence> - <xsd:attribute name="name" use="required" type="xsd:string" /> - <xsd:attribute name="type" type="xsd:string" /> - <xsd:attribute name="mimetype" type="xsd:string" /> - <xsd:attribute ref="xml:space" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="assembly"> - <xsd:complexType> - <xsd:attribute name="alias" type="xsd:string" /> - <xsd:attribute name="name" type="xsd:string" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="data"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> - <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> - </xsd:sequence> - <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> - <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> - <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> - <xsd:attribute ref="xml:space" /> - </xsd:complexType> - </xsd:element> - <xsd:element name="resheader"> - <xsd:complexType> - <xsd:sequence> - <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> - </xsd:sequence> - <xsd:attribute name="name" type="xsd:string" use="required" /> - </xsd:complexType> - </xsd:element> - </xsd:choice> - </xsd:complexType> - </xsd:element> - </xsd:schema> - <resheader name="resmimetype"> - <value>text/microsoft-resx</value> - </resheader> - <resheader name="version"> - <value>2.0</value> - </resheader> - <resheader name="reader"> - <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader> - <resheader name="writer"> - <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader> - <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> - <data name="ChatEditTemplate" type="System.Resources.ResXFileRef, System.Windows.Forms"> - <value>..\Resources\ChatEditTemplate.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value> - </data> - <data name="ChatListView" type="System.Resources.ResXFileRef, System.Windows.Forms"> - <value>..\Resources\ChatListView.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value> - </data> - <data name="GenericTableList" type="System.Resources.ResXFileRef, System.Windows.Forms"> - <value>..\Resources\GenericTableList.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value> - </data> - <data name="HtmlTemplate" type="System.Resources.ResXFileRef, System.Windows.Forms"> - <value>..\Resources\HtmlTemplate.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value> - </data> - <data name="LoginView" type="System.Resources.ResXFileRef, System.Windows.Forms"> - <value>..\Resources\LoginView.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value> - </data> - <data name="NoUsersFound" type="System.Resources.ResXFileRef, System.Windows.Forms"> - <value>..\Resources\NoUsersFound.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value> - </data> - <data name="SetupView" type="System.Resources.ResXFileRef, System.Windows.Forms"> - <value>..\Resources\SetupView.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value> - </data> - <data name="Status" type="System.Resources.ResXFileRef, System.Windows.Forms"> - <value>..\Resources\Status.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value> - </data> -</root>
\ No newline at end of file diff --git a/ShiftOS.Server.WebAdmin/Resources/ChatEditTemplate.txt b/ShiftOS.Server.WebAdmin/Resources/ChatEditTemplate.txt deleted file mode 100644 index 0c8a7b5..0000000 --- a/ShiftOS.Server.WebAdmin/Resources/ChatEditTemplate.txt +++ /dev/null @@ -1,5 +0,0 @@ -<h3>Create/edit chat</h3> - -<p>Please fill out the details below for your channel list to be modified.</p> - -{form}
\ No newline at end of file diff --git a/ShiftOS.Server.WebAdmin/Resources/ChatListView.txt b/ShiftOS.Server.WebAdmin/Resources/ChatListView.txt deleted file mode 100644 index eedfc07..0000000 --- a/ShiftOS.Server.WebAdmin/Resources/ChatListView.txt +++ /dev/null @@ -1,11 +0,0 @@ -<h3>Chats</h3> - -<p>On this page you can find a list of all chats in the system. Chats are a part of the multi-user domain that allows online players to talk to eachother in the 'MUD Chat' application.</p> - -<p>If you have a Discord server for your multi-user domain, you can also designate a ShiftOS chat to listen on a specific channel on your server. You will need to create a Discord Bot Token and specify the ID of the channel you want tolisten to.</p> - -<p>Once the chat is set up, you should see a bot join your Discord server. Once it does, any messages received by the server in that channel will be relayed into ShiftOS, and any messages received by the MUD in the ShiftOS channel will be relayed to Discord.</p> - -<a href="/mudadmin/createchat" class="btn btn-default"><span class="glyphicon glyphicon-plus"></span> Create chat</a> - -{chat_table}
\ No newline at end of file diff --git a/ShiftOS.Server.WebAdmin/Resources/GenericTableList.txt b/ShiftOS.Server.WebAdmin/Resources/GenericTableList.txt deleted file mode 100644 index 3cbfd6e..0000000 --- a/ShiftOS.Server.WebAdmin/Resources/GenericTableList.txt +++ /dev/null @@ -1,5 +0,0 @@ -<h3>{listtitle}</h3> - -<p>{listdesc}</p> - -{list}
\ No newline at end of file diff --git a/ShiftOS.Server.WebAdmin/Resources/HtmlTemplate.txt b/ShiftOS.Server.WebAdmin/Resources/HtmlTemplate.txt deleted file mode 100644 index 82893e9..0000000 --- a/ShiftOS.Server.WebAdmin/Resources/HtmlTemplate.txt +++ /dev/null @@ -1,58 +0,0 @@ -<html> - <head> - <title>Multi-user domain • ShiftOS</title> - <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> - - <link rel="stylesheet" href="http://getshiftos.ml/css/theme.css"/> - - <!-- Latest compiled and minified JavaScript --> - <script src="https://code.jquery.com/jquery-3.1.1.js" integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7CQR3HzTBuELA=" crossorigin="anonymous"></script> - <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> - </head> - <body> - <div class="navbar navbar-default"> - <div class+"navbar-header"> - <a class="navbar-brand" href="http://getshiftos.ml">ShiftOS</a> - </div> - <ul class="nav navbar-nav"> - <li> - <a href="/mudadmin/status">System status</a> - </li> - <li> - <a href="/mudadmin/saves">Test subjects</a> - </li> - <li> - <a href="#">Shiftnet (NYI)</a> - </li> - <li> - <a href="#">Scripts (NYI)</a> - </li> - <li> - <a href="#">Legions (NYI)</a> - </li> - <li> - <a href="/mudadmin/chats">Chats</a> - </li> - <li> - <a href="#">Shops (NYI)</a> - </li> - </ul> - <ul class="nav navbar-nav navbar-right"> - {mud_restart} - {mud_power} - {logout} - - </ul> - </div> - <!-- /#sidebar-wrapper --> - - <!-- Page Content --> - <div id="page-content-wrapper"> - <div class="container-fluid content"> - {body} - - <p style="text-align:center;"><em>ShiftOS - MUD admin panel - Copyright © 2017 ShiftOS developers</em></p> - </div> - </div> - </body> -</html>
\ No newline at end of file diff --git a/ShiftOS.Server.WebAdmin/Resources/LoginView.txt b/ShiftOS.Server.WebAdmin/Resources/LoginView.txt deleted file mode 100644 index d5e61cf..0000000 --- a/ShiftOS.Server.WebAdmin/Resources/LoginView.txt +++ /dev/null @@ -1,31 +0,0 @@ -<h3>Access denied.</h3> - -<p>You require a higher authentication level to access this part of the multi-user domain. Please enter the username and password of whom has access to this sector.</p> - -<form method="post" action=""> - <table class="table"> - <tr> - <td><strong>Username:</strong></td> - <td><input class="form-control" type="text" name="username"/></td> - </tr> - <tr> - <td><strong>Password:</strong></td> - <td><input class="form-control" type="password" name="password"/></td> - </tr> - <tr> - <td></td> - <td><input type="submit" class="btn btn-default"/></td> - </tr> - </table> -</form> - -<div class="row"> - <div class="col-xs-6"> - <h4>What are my credentials?</h4> - <p>If you do not know your credentials, you are not a ShiftOS developer with write-access to the GitHub repository and authorized access to the multi-user domain's backend, so we ask that you get off this site and try to hack the MUD in-game. Thank you.</p> - </div> - <div class="col-xs-6"> - <h4>I am a developer.</h4> - <p>Please contact Michael VanOverbeek if you are a developer and have not yet received your credentials.</p> - </div> -</div>
\ No newline at end of file diff --git a/ShiftOS.Server.WebAdmin/Resources/NoUsersFound.txt b/ShiftOS.Server.WebAdmin/Resources/NoUsersFound.txt deleted file mode 100644 index 7524fa5..0000000 --- a/ShiftOS.Server.WebAdmin/Resources/NoUsersFound.txt +++ /dev/null @@ -1,5 +0,0 @@ -<h3>No users found.</h3> - -<p>Your multi-user domain is newly-created. Before you can use the admin panel, you must create a ShiftOS user to act as the administrator of the MUD.</p> - -{user_create_form}
\ No newline at end of file diff --git a/ShiftOS.Server.WebAdmin/Resources/SetupView.txt b/ShiftOS.Server.WebAdmin/Resources/SetupView.txt deleted file mode 100644 index 9e83a45..0000000 --- a/ShiftOS.Server.WebAdmin/Resources/SetupView.txt +++ /dev/null @@ -1,5 +0,0 @@ -<h1>Initial setup</h1> - -<p>This multi-user domain contains some users, however none of them are administrators. Please choose your user to make it an admin.</p> - -{savelist}
\ No newline at end of file diff --git a/ShiftOS.Server.WebAdmin/Resources/Status.txt b/ShiftOS.Server.WebAdmin/Resources/Status.txt deleted file mode 100644 index b63d9cd..0000000 --- a/ShiftOS.Server.WebAdmin/Resources/Status.txt +++ /dev/null @@ -1,19 +0,0 @@ -<h3>System status</h3> - -<p>Below is a summary of this multi-user domain's status.</p> - -<div class="row"> - <div class="col-xs-6"> - <h4>MUD stats</h4> - <ul> - <li>This server is worth <strong>{cp_worth}</strong> Codepoints.</li> - <li>This server has <strong>{user_count}</strong> players registered.</li> - </ul> - </div> - <div class="col-xs-6"> - <h4>System environment</h4> - <ul> - <li><strong>Current system time:</strong> {system_time}</li> - </ul> - </div> -</div>
\ No newline at end of file diff --git a/ShiftOS.Server.WebAdmin/ShiftOS.Server.WebAdmin.csproj b/ShiftOS.Server.WebAdmin/ShiftOS.Server.WebAdmin.csproj deleted file mode 100644 index faec295..0000000 --- a/ShiftOS.Server.WebAdmin/ShiftOS.Server.WebAdmin.csproj +++ /dev/null @@ -1,126 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> - <PropertyGroup> - <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> - <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> - <ProjectGuid>{B29FDD06-E6FE-40A2-8258-283728CED81A}</ProjectGuid> - <OutputType>Exe</OutputType> - <AppDesignerFolder>Properties</AppDesignerFolder> - <RootNamespace>ShiftOS.Server.WebAdmin</RootNamespace> - <AssemblyName>ShiftOS.Server.WebAdmin</AssemblyName> - <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion> - <FileAlignment>512</FileAlignment> - <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> - <PlatformTarget>AnyCPU</PlatformTarget> - <DebugSymbols>true</DebugSymbols> - <DebugType>full</DebugType> - <Optimize>false</Optimize> - <OutputPath>bin\Debug\</OutputPath> - <DefineConstants>DEBUG;TRACE</DefineConstants> - <ErrorReport>prompt</ErrorReport> - <WarningLevel>4</WarningLevel> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> - <PlatformTarget>AnyCPU</PlatformTarget> - <DebugType>pdbonly</DebugType> - <Optimize>true</Optimize> - <OutputPath>bin\Release\</OutputPath> - <DefineConstants>TRACE</DefineConstants> - <ErrorReport>prompt</ErrorReport> - <WarningLevel>4</WarningLevel> - </PropertyGroup> - <ItemGroup> - <Reference Include="Nancy, Version=1.4.2.0, Culture=neutral, processorArchitecture=MSIL"> - <HintPath>..\packages\Nancy.1.4.3\lib\net40\Nancy.dll</HintPath> - <Private>True</Private> - </Reference> - <Reference Include="Nancy.Authentication.Forms, Version=1.4.1.0, Culture=neutral, processorArchitecture=MSIL"> - <HintPath>..\packages\Nancy.Authentication.Forms.1.4.1\lib\net40\Nancy.Authentication.Forms.dll</HintPath> - <Private>True</Private> - </Reference> - <Reference Include="Nancy.Authentication.Stateless, Version=1.4.1.0, Culture=neutral, processorArchitecture=MSIL"> - <HintPath>..\packages\Nancy.Authentication.Stateless.1.4.1\lib\net40\Nancy.Authentication.Stateless.dll</HintPath> - <Private>True</Private> - </Reference> - <Reference Include="Nancy.Hosting.Self, Version=1.4.1.0, Culture=neutral, processorArchitecture=MSIL"> - <HintPath>..\packages\Nancy.Hosting.Self.1.4.1\lib\net40\Nancy.Hosting.Self.dll</HintPath> - <Private>True</Private> - </Reference> - <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> - <HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath> - <Private>True</Private> - </Reference> - <Reference Include="System" /> - <Reference Include="System.Core" /> - <Reference Include="System.Xml.Linq" /> - <Reference Include="System.Data.DataSetExtensions" /> - <Reference Include="Microsoft.CSharp" /> - <Reference Include="System.Data" /> - <Reference Include="System.Net.Http" /> - <Reference Include="System.Xml" /> - </ItemGroup> - <ItemGroup> - <Compile Include="Program.cs" /> - <Compile Include="Properties\AssemblyInfo.cs" /> - <Compile Include="Properties\Resources.Designer.cs"> - <AutoGen>True</AutoGen> - <DesignTime>True</DesignTime> - <DependentUpon>Resources.resx</DependentUpon> - </Compile> - </ItemGroup> - <ItemGroup> - <None Include="App.config" /> - <None Include="packages.config" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="..\ShiftOS.Objects\ShiftOS.Objects.csproj"> - <Project>{A069089A-8962-4607-B2B2-4CF4A371066E}</Project> - <Name>ShiftOS.Objects</Name> - </ProjectReference> - <ProjectReference Include="..\ShiftOS.Server\ShiftOS.Server.csproj"> - <Project>{226c63b4-e60d-4949-b4e7-7a2ddbb96776}</Project> - <Name>ShiftOS.Server</Name> - </ProjectReference> - </ItemGroup> - <ItemGroup> - <EmbeddedResource Include="Properties\Resources.resx"> - <Generator>ResXFileCodeGenerator</Generator> - <LastGenOutput>Resources.Designer.cs</LastGenOutput> - </EmbeddedResource> - </ItemGroup> - <ItemGroup> - <None Include="Resources\HtmlTemplate.txt" /> - </ItemGroup> - <ItemGroup> - <None Include="Resources\LoginView.txt" /> - </ItemGroup> - <ItemGroup> - <None Include="Resources\SetupView.txt" /> - </ItemGroup> - <ItemGroup> - <None Include="Resources\Status.txt" /> - </ItemGroup> - <ItemGroup> - <None Include="Resources\ChatListView.txt" /> - </ItemGroup> - <ItemGroup> - <None Include="Resources\ChatEditTemplate.txt" /> - </ItemGroup> - <ItemGroup> - <None Include="Resources\NoUsersFound.txt" /> - </ItemGroup> - <ItemGroup> - <None Include="Resources\GenericTableList.txt" /> - </ItemGroup> - <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> - <!-- To modify your build process, add your task inside one of the targets below and uncomment it. - Other similar extension points exist, see Microsoft.Common.targets. - <Target Name="BeforeBuild"> - </Target> - <Target Name="AfterBuild"> - </Target> - --> -</Project>
\ No newline at end of file diff --git a/ShiftOS.Server.WebAdmin/packages.config b/ShiftOS.Server.WebAdmin/packages.config deleted file mode 100644 index a403e33..0000000 --- a/ShiftOS.Server.WebAdmin/packages.config +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<packages> - <package id="Nancy" version="1.4.3" targetFramework="net452" /> - <package id="Nancy.Authentication.Forms" version="1.4.1" targetFramework="net452" /> - <package id="Nancy.Authentication.Stateless" version="1.4.1" targetFramework="net452" /> - <package id="Nancy.Hosting.Self" version="1.4.1" targetFramework="net452" /> - <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" /> -</packages>
\ No newline at end of file diff --git a/ShiftOS.WinForms/Applications/FormatEditor.cs b/ShiftOS.WinForms/Applications/FormatEditor.cs new file mode 100644 index 0000000..7491e36 --- /dev/null +++ b/ShiftOS.WinForms/Applications/FormatEditor.cs @@ -0,0 +1,187 @@ +/* + * 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.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 { + [MultiplayerOnly] + [Launcher("Format Editor", true, "al_format_editor", "Customization")] + [RequiresUpgrade("format_editor")] + [WinOpen("formateditor")] + [DefaultTitle("Format Editor")] + [DefaultIcon("iconFormatEditor")] + + public partial class FormatEditor : UserControl, IShiftOSWindow { + + IList<CommandFormat> parts = new List<CommandFormat>(); + CommandParser parser = new CommandParser(); + IList<Panel> editorBoxes = new List<Panel>(); + + string commandMode = "namespace"; + int avcount = 0; + + public FormatEditor() { + InitializeComponent(); + } + + public void OnLoad() { + OnUpgrade(); + } + + public void OnSkinLoad() { } + + public bool OnUnload() { return true; } + + public void OnUpgrade() { + btnAddOptionalText.Visible = ShiftoriumFrontend.UpgradeInstalled("format_editor_optional_text"); + btnAddRegexText.Visible = ShiftoriumFrontend.UpgradeInstalled("format_editor_regex"); + btnAddColor.Visible = ShiftoriumFrontend.UpgradeInstalled("format_editor_syntax_highlighting"); + } + + private void addPart(CommandFormat part) { + parser.AddPart(part); + + addPart(part.Draw()); + } + + private void addPart(Control part) { + Panel container = new Panel(); + + Control drawnPart = part; + container.Size = drawnPart.Size; + container.Controls.Add(drawnPart); + + int woffset = 0; + if (editorBoxes.Count > 0) { + woffset = editorBoxes.Last().Width + editorBoxes.Last().Location.X; + } else { + woffset = 0; + } + + container.Location = new Point(woffset, 0); + editorBoxes.Add(container); + panelEditor.Controls.Add(container); + } + + private void btnAddText_Click(object sender, EventArgs e) { + addPart(new CommandFormatText()); + } + + private void btnAddOptionalText_Click(object sender, EventArgs e) { + addPart(new CommandFormatOptionalText()); + } + + private void btnAddRegexText_Click(object sender, EventArgs e) { + + } + + private void btnAddColor_Click(object sender, EventArgs e) { + + } + + private void btnAddCommand_Click(object sender, EventArgs e) { + switch (commandMode) { + case "namespace": + addPart(new CommandFormatNamespace()); + commandMode = "command"; + btnAddCommand.Text = "+ Command"; + break; + case "command": + addPart(new CommandFormatCommand()); + commandMode = "argument"; + btnAddCommand.Text = "+ Argument"; + break; + case "argument": + addPart(new CommandFormatArgument()); + commandMode = "value"; + btnAddCommand.Text = "+ \"Value\""; + break; + case "value": + addPart(new CommandFormatValue()); + avcount++; + if (avcount >= 2) { + commandMode = ""; + btnAddCommand.Text = ""; + btnAddCommand.Enabled = false; + }else { + commandMode = "argument"; + btnAddCommand.Text = "+ Argument"; + } + break; + } + } + + private void richTextBox1_TextChanged(object sender, EventArgs e) { + var result = parser.ParseCommand(richTextBox1.Text); + + if (result.Equals(default(KeyValuePair<KeyValuePair<string, string>, Dictionary<string, string>>))) { + lblExampleCommand.Text = "Syntax Error"; + } else { + string argvs = "{"; + + foreach (KeyValuePair<string, string> entry in result.Value) { + argvs += entry.Key + "=\"" + entry.Value + "\", "; + } + + argvs += "}"; + + lblExampleCommand.Text = result.Key + argvs; + } + } + + private void btnTest_Click(object sender, EventArgs e) { + + } + + private void btnSave_Click(object sender, EventArgs e) { + CurrentCommandParser.parser = parser; + + FileSkimmerBackend.GetFile(new string[] { ".cf" }, FileOpenerStyle.Save, new Action<string>((result) => { + Objects.ShiftFS.Utils.WriteAllText(result, parser.Save()); + })); + } + + private void btnLoad_Click(object sender, EventArgs e) { + FileSkimmerBackend.GetFile(new string[] { ".cf" }, FileOpenerStyle.Open, new Action<string>((result) => { + parser = CommandParser.Load(Objects.ShiftFS.Utils.ReadAllText(result)); + foreach(CommandFormat part in parser.parts) { + addPart(part.Draw()); + } + })); + } + + private void btnApply_Click(object sender, EventArgs e) { + CurrentCommandParser.parser = parser; + } + } +} diff --git a/ShiftOS.WinForms/Applications/Pong.Designer.cs b/ShiftOS.WinForms/Applications/Pong.Designer.cs new file mode 100644 index 0000000..e619eaa --- /dev/null +++ b/ShiftOS.WinForms/Applications/Pong.Designer.cs @@ -0,0 +1,757 @@ +/* + * 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. + */ + + +/* + * 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 ShiftOS.WinForms.Controls; + +namespace ShiftOS.WinForms.Applications +{ + partial class Pong + { + /// <summary> + /// Required designer variable. + /// </summary> + private System.ComponentModel.IContainer components = null; + + /// <summary> + /// Clean up any resources being used. + /// </summary> + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.gameTimer = new System.Windows.Forms.Timer(this.components); + this.counter = new System.Windows.Forms.Timer(this.components); + this.tmrcountdown = new System.Windows.Forms.Timer(this.components); + this.tmrstoryline = new System.Windows.Forms.Timer(this.components); + this.pgcontents = new ShiftOS.WinForms.Controls.Canvas(); + this.pnlhighscore = new System.Windows.Forms.Panel(); + this.lbhighscore = new System.Windows.Forms.ListBox(); + this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + this.button2 = new System.Windows.Forms.Button(); + this.label10 = new System.Windows.Forms.Label(); + this.pnlgamestats = new System.Windows.Forms.Panel(); + this.button1 = new System.Windows.Forms.Button(); + this.label12 = new System.Windows.Forms.Label(); + this.lblnextstats = new System.Windows.Forms.Label(); + this.Label7 = new System.Windows.Forms.Label(); + this.lblpreviousstats = new System.Windows.Forms.Label(); + this.Label4 = new System.Windows.Forms.Label(); + this.btnplayon = new System.Windows.Forms.Button(); + this.Label3 = new System.Windows.Forms.Label(); + this.btncashout = new System.Windows.Forms.Button(); + this.Label2 = new System.Windows.Forms.Label(); + this.lbllevelreached = new System.Windows.Forms.Label(); + this.pnlfinalstats = new System.Windows.Forms.Panel(); + this.btnplayagain = new System.Windows.Forms.Button(); + this.lblfinalcodepoints = new System.Windows.Forms.Label(); + this.Label11 = new System.Windows.Forms.Label(); + this.lblfinalcomputerreward = new System.Windows.Forms.Label(); + this.Label9 = new System.Windows.Forms.Label(); + this.lblfinallevelreward = new System.Windows.Forms.Label(); + this.lblfinallevelreached = new System.Windows.Forms.Label(); + this.lblfinalcodepointswithtext = new System.Windows.Forms.Label(); + this.pnllose = new System.Windows.Forms.Panel(); + this.lblmissedout = new System.Windows.Forms.Label(); + this.lblbutyougained = new System.Windows.Forms.Label(); + this.btnlosetryagain = new System.Windows.Forms.Button(); + this.Label5 = new System.Windows.Forms.Label(); + this.Label1 = new System.Windows.Forms.Label(); + this.pnlintro = new System.Windows.Forms.Panel(); + this.Label6 = new System.Windows.Forms.Label(); + this.btnstartgame = new System.Windows.Forms.Button(); + this.Label8 = new System.Windows.Forms.Label(); + this.lblbeatai = new System.Windows.Forms.Label(); + this.lblcountdown = new System.Windows.Forms.Label(); + this.ball = new ShiftOS.WinForms.Controls.Canvas(); + this.paddleHuman = new System.Windows.Forms.PictureBox(); + this.paddleComputer = new System.Windows.Forms.Panel(); + this.lbllevelandtime = new System.Windows.Forms.Label(); + this.lblstatscodepoints = new System.Windows.Forms.Label(); + this.lblstatsY = new System.Windows.Forms.Label(); + this.lblstatsX = new System.Windows.Forms.Label(); + this.pgcontents.SuspendLayout(); + this.pnlhighscore.SuspendLayout(); + this.flowLayoutPanel1.SuspendLayout(); + this.pnlgamestats.SuspendLayout(); + this.pnlfinalstats.SuspendLayout(); + this.pnllose.SuspendLayout(); + this.pnlintro.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.paddleHuman)).BeginInit(); + this.SuspendLayout(); + // + // gameTimer + // + this.gameTimer.Interval = 30; + this.gameTimer.Tick += new System.EventHandler(this.gameTimer_Tick); + // + // counter + // + this.counter.Interval = 1000; + this.counter.Tick += new System.EventHandler(this.counter_Tick); + // + // tmrcountdown + // + this.tmrcountdown.Interval = 1000; + this.tmrcountdown.Tick += new System.EventHandler(this.countdown_Tick); + // + // tmrstoryline + // + this.tmrstoryline.Interval = 1000; + this.tmrstoryline.Tick += new System.EventHandler(this.tmrstoryline_Tick); + // + // pgcontents + // + this.pgcontents.BackColor = System.Drawing.Color.White; + this.pgcontents.Controls.Add(this.pnlhighscore); + this.pgcontents.Controls.Add(this.pnlgamestats); + this.pgcontents.Controls.Add(this.pnlfinalstats); + this.pgcontents.Controls.Add(this.pnllose); + this.pgcontents.Controls.Add(this.pnlintro); + this.pgcontents.Controls.Add(this.lblbeatai); + this.pgcontents.Controls.Add(this.lblcountdown); + this.pgcontents.Controls.Add(this.ball); + this.pgcontents.Controls.Add(this.paddleHuman); + this.pgcontents.Controls.Add(this.paddleComputer); + this.pgcontents.Controls.Add(this.lbllevelandtime); + this.pgcontents.Controls.Add(this.lblstatscodepoints); + this.pgcontents.Controls.Add(this.lblstatsY); + this.pgcontents.Controls.Add(this.lblstatsX); + 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(1867, 819); + this.pgcontents.TabIndex = 20; + this.pgcontents.Paint += new System.Windows.Forms.PaintEventHandler(this.pgcontents_Paint); + this.pgcontents.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pongMain_MouseMove); + // + // pnlhighscore + // + this.pnlhighscore.Controls.Add(this.lbhighscore); + this.pnlhighscore.Controls.Add(this.flowLayoutPanel1); + this.pnlhighscore.Controls.Add(this.label10); + this.pnlhighscore.Location = new System.Drawing.Point(688, 302); + this.pnlhighscore.Name = "pnlhighscore"; + this.pnlhighscore.Size = new System.Drawing.Size(539, 311); + this.pnlhighscore.TabIndex = 14; + this.pnlhighscore.Visible = false; + // + // lbhighscore + // + this.lbhighscore.Dock = System.Windows.Forms.DockStyle.Fill; + this.lbhighscore.FormattingEnabled = true; + this.lbhighscore.Location = new System.Drawing.Point(0, 36); + this.lbhighscore.MultiColumn = true; + this.lbhighscore.Name = "lbhighscore"; + this.lbhighscore.SelectionMode = System.Windows.Forms.SelectionMode.None; + this.lbhighscore.Size = new System.Drawing.Size(539, 246); + this.lbhighscore.TabIndex = 1; + // + // flowLayoutPanel1 + // + this.flowLayoutPanel1.AutoSize = true; + this.flowLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.flowLayoutPanel1.Controls.Add(this.button2); + this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Bottom; + this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft; + this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 282); + this.flowLayoutPanel1.Name = "flowLayoutPanel1"; + this.flowLayoutPanel1.Size = new System.Drawing.Size(539, 29); + this.flowLayoutPanel1.TabIndex = 2; + // + // button2 + // + this.button2.AutoSize = true; + this.button2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.button2.Location = new System.Drawing.Point(476, 3); + this.button2.Name = "button2"; + this.button2.Size = new System.Drawing.Size(60, 23); + this.button2.TabIndex = 0; + this.button2.Text = "{CLOSE}"; + this.button2.UseVisualStyleBackColor = true; + this.button2.Click += new System.EventHandler(this.button2_Click); + // + // label10 + // + this.label10.Dock = System.Windows.Forms.DockStyle.Top; + this.label10.Location = new System.Drawing.Point(0, 0); + this.label10.Name = "label10"; + this.label10.Size = new System.Drawing.Size(539, 36); + this.label10.TabIndex = 0; + this.label10.Text = "{HIGH_SCORES}"; + this.label10.TextAlign = System.Drawing.ContentAlignment.TopCenter; + // + // pnlgamestats + // + this.pnlgamestats.Controls.Add(this.button1); + this.pnlgamestats.Controls.Add(this.label12); + this.pnlgamestats.Controls.Add(this.lblnextstats); + this.pnlgamestats.Controls.Add(this.Label7); + this.pnlgamestats.Controls.Add(this.lblpreviousstats); + this.pnlgamestats.Controls.Add(this.Label4); + this.pnlgamestats.Controls.Add(this.btnplayon); + this.pnlgamestats.Controls.Add(this.Label3); + this.pnlgamestats.Controls.Add(this.btncashout); + this.pnlgamestats.Controls.Add(this.Label2); + this.pnlgamestats.Controls.Add(this.lbllevelreached); + this.pnlgamestats.Location = new System.Drawing.Point(104, 375); + this.pnlgamestats.Name = "pnlgamestats"; + this.pnlgamestats.Size = new System.Drawing.Size(466, 284); + this.pnlgamestats.TabIndex = 6; + this.pnlgamestats.Visible = false; + // + // button1 + // + this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.button1.Location = new System.Drawing.Point(32, 223); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(191, 35); + this.button1.TabIndex = 10; + this.button1.Text = "{PONG_VIEW_HIGHSCORES}"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.btnhighscore_Click); + // + // label12 + // + this.label12.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label12.Location = new System.Drawing.Point(8, 187); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(245, 33); + this.label12.TabIndex = 9; + this.label12.Text = "{PONG_HIGHSCORE_EXP}"; + this.label12.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // lblnextstats + // + this.lblnextstats.AutoSize = true; + this.lblnextstats.Location = new System.Drawing.Point(278, 136); + this.lblnextstats.Name = "lblnextstats"; + this.lblnextstats.Size = new System.Drawing.Size(0, 13); + this.lblnextstats.TabIndex = 8; + // + // Label7 + // + this.Label7.AutoSize = true; + this.Label7.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Label7.Location = new System.Drawing.Point(278, 119); + this.Label7.Name = "Label7"; + this.Label7.Size = new System.Drawing.Size(124, 16); + this.Label7.TabIndex = 7; + this.Label7.Text = "Next Level Stats:"; + // + // lblpreviousstats + // + this.lblpreviousstats.AutoSize = true; + this.lblpreviousstats.Location = new System.Drawing.Point(278, 54); + this.lblpreviousstats.Name = "lblpreviousstats"; + this.lblpreviousstats.Size = new System.Drawing.Size(0, 13); + this.lblpreviousstats.TabIndex = 6; + // + // Label4 + // + this.Label4.AutoSize = true; + this.Label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Label4.Location = new System.Drawing.Point(278, 37); + this.Label4.Name = "Label4"; + this.Label4.Size = new System.Drawing.Size(154, 16); + this.Label4.TabIndex = 5; + this.Label4.Text = "Previous Level Stats:"; + // + // btnplayon + // + this.btnplayon.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnplayon.Location = new System.Drawing.Point(32, 147); + this.btnplayon.Name = "btnplayon"; + this.btnplayon.Size = new System.Drawing.Size(191, 35); + this.btnplayon.TabIndex = 4; + this.btnplayon.Text = "Play on for 3 codepoints!"; + this.btnplayon.UseVisualStyleBackColor = true; + this.btnplayon.Click += new System.EventHandler(this.btnplayon_Click); + // + // Label3 + // + this.Label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Label3.Location = new System.Drawing.Point(8, 111); + this.Label3.Name = "Label3"; + this.Label3.Size = new System.Drawing.Size(245, 33); + this.Label3.TabIndex = 3; + this.Label3.Text = "{PONG_PLAYON_DESC}"; + this.Label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // btncashout + // + this.btncashout.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btncashout.Location = new System.Drawing.Point(32, 73); + this.btncashout.Name = "btncashout"; + this.btncashout.Size = new System.Drawing.Size(191, 35); + this.btncashout.TabIndex = 2; + this.btncashout.Text = "Cash out with 1 codepoint!"; + this.btncashout.UseVisualStyleBackColor = true; + this.btncashout.Click += new System.EventHandler(this.btncashout_Click); + // + // Label2 + // + this.Label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Label2.Location = new System.Drawing.Point(8, 37); + this.Label2.Name = "Label2"; + this.Label2.Size = new System.Drawing.Size(245, 33); + this.Label2.TabIndex = 1; + this.Label2.Text = "{PONG_CASHOUT_DESC}"; + this.Label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // lbllevelreached + // + this.lbllevelreached.AutoSize = true; + this.lbllevelreached.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lbllevelreached.Location = new System.Drawing.Point(149, 6); + this.lbllevelreached.Name = "lbllevelreached"; + this.lbllevelreached.Size = new System.Drawing.Size(185, 20); + this.lbllevelreached.TabIndex = 0; + this.lbllevelreached.Text = "You Reached Level 2!"; + // + // pnlfinalstats + // + this.pnlfinalstats.Controls.Add(this.btnplayagain); + this.pnlfinalstats.Controls.Add(this.lblfinalcodepoints); + this.pnlfinalstats.Controls.Add(this.Label11); + this.pnlfinalstats.Controls.Add(this.lblfinalcomputerreward); + this.pnlfinalstats.Controls.Add(this.Label9); + this.pnlfinalstats.Controls.Add(this.lblfinallevelreward); + this.pnlfinalstats.Controls.Add(this.lblfinallevelreached); + this.pnlfinalstats.Controls.Add(this.lblfinalcodepointswithtext); + this.pnlfinalstats.Location = new System.Drawing.Point(172, 74); + this.pnlfinalstats.Name = "pnlfinalstats"; + this.pnlfinalstats.Size = new System.Drawing.Size(362, 226); + this.pnlfinalstats.TabIndex = 9; + this.pnlfinalstats.Visible = false; + // + // btnplayagain + // + this.btnplayagain.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnplayagain.Location = new System.Drawing.Point(5, 194); + this.btnplayagain.Name = "btnplayagain"; + this.btnplayagain.Size = new System.Drawing.Size(352, 29); + this.btnplayagain.TabIndex = 16; + this.btnplayagain.Text = "{PLAY}"; + this.btnplayagain.UseVisualStyleBackColor = true; + this.btnplayagain.Click += new System.EventHandler(this.btnplayagain_Click); + // + // lblfinalcodepoints + // + this.lblfinalcodepoints.Font = new System.Drawing.Font("Microsoft Sans Serif", 48F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblfinalcodepoints.Location = new System.Drawing.Point(3, 124); + this.lblfinalcodepoints.Name = "lblfinalcodepoints"; + this.lblfinalcodepoints.Size = new System.Drawing.Size(356, 73); + this.lblfinalcodepoints.TabIndex = 15; + this.lblfinalcodepoints.Tag = "header1"; + this.lblfinalcodepoints.Text = "134 CP"; + this.lblfinalcodepoints.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // Label11 + // + this.Label11.AutoSize = true; + this.Label11.Font = new System.Drawing.Font("Microsoft Sans Serif", 21.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Label11.Location = new System.Drawing.Point(162, 82); + this.Label11.Name = "Label11"; + this.Label11.Size = new System.Drawing.Size(33, 33); + this.Label11.TabIndex = 14; + this.Label11.Tag = "header2"; + this.Label11.Text = "+"; + this.Label11.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // lblfinalcomputerreward + // + this.lblfinalcomputerreward.Font = new System.Drawing.Font("Microsoft Sans Serif", 27.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblfinalcomputerreward.Location = new System.Drawing.Point(193, 72); + this.lblfinalcomputerreward.Name = "lblfinalcomputerreward"; + this.lblfinalcomputerreward.Size = new System.Drawing.Size(151, 52); + this.lblfinalcomputerreward.TabIndex = 12; + this.lblfinalcomputerreward.Tag = "header2"; + this.lblfinalcomputerreward.Text = "34"; + this.lblfinalcomputerreward.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // Label9 + // + this.Label9.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Label9.Location = new System.Drawing.Point(179, 31); + this.Label9.Name = "Label9"; + this.Label9.Size = new System.Drawing.Size(180, 49); + this.Label9.TabIndex = 11; + this.Label9.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // lblfinallevelreward + // + this.lblfinallevelreward.Font = new System.Drawing.Font("Microsoft Sans Serif", 27.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblfinallevelreward.Location = new System.Drawing.Point(12, 72); + this.lblfinallevelreward.Name = "lblfinallevelreward"; + this.lblfinallevelreward.Size = new System.Drawing.Size(151, 52); + this.lblfinallevelreward.TabIndex = 10; + this.lblfinallevelreward.Tag = "header2"; + this.lblfinallevelreward.Text = "100"; + this.lblfinallevelreward.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // lblfinallevelreached + // + this.lblfinallevelreached.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblfinallevelreached.Location = new System.Drawing.Point(3, 31); + this.lblfinallevelreached.Name = "lblfinallevelreached"; + this.lblfinallevelreached.Size = new System.Drawing.Size(170, 49); + this.lblfinallevelreached.TabIndex = 9; + this.lblfinallevelreached.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // lblfinalcodepointswithtext + // + this.lblfinalcodepointswithtext.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblfinalcodepointswithtext.Location = new System.Drawing.Point(3, 2); + this.lblfinalcodepointswithtext.Name = "lblfinalcodepointswithtext"; + this.lblfinalcodepointswithtext.Size = new System.Drawing.Size(356, 26); + this.lblfinalcodepointswithtext.TabIndex = 1; + this.lblfinalcodepointswithtext.Tag = "header2"; + this.lblfinalcodepointswithtext.Text = "You cashed out with 134 codepoints!"; + this.lblfinalcodepointswithtext.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // pnllose + // + this.pnllose.Controls.Add(this.lblmissedout); + this.pnllose.Controls.Add(this.lblbutyougained); + this.pnllose.Controls.Add(this.btnlosetryagain); + this.pnllose.Controls.Add(this.Label5); + this.pnllose.Controls.Add(this.Label1); + this.pnllose.Location = new System.Drawing.Point(209, 71); + this.pnllose.Name = "pnllose"; + this.pnllose.Size = new System.Drawing.Size(266, 214); + this.pnllose.TabIndex = 10; + this.pnllose.Visible = false; + // + // lblmissedout + // + this.lblmissedout.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblmissedout.Location = new System.Drawing.Point(3, 175); + this.lblmissedout.Name = "lblmissedout"; + this.lblmissedout.Size = new System.Drawing.Size(146, 35); + this.lblmissedout.TabIndex = 3; + this.lblmissedout.Text = "You Missed Out On: 500 Codepoints"; + this.lblmissedout.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // lblbutyougained + // + this.lblbutyougained.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblbutyougained.Location = new System.Drawing.Point(3, 125); + this.lblbutyougained.Name = "lblbutyougained"; + this.lblbutyougained.Size = new System.Drawing.Size(146, 35); + this.lblbutyougained.TabIndex = 3; + this.lblbutyougained.Text = "But you gained 5 Codepoints"; + this.lblbutyougained.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // btnlosetryagain + // + this.btnlosetryagain.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnlosetryagain.Location = new System.Drawing.Point(155, 176); + this.btnlosetryagain.Name = "btnlosetryagain"; + this.btnlosetryagain.Size = new System.Drawing.Size(106, 35); + this.btnlosetryagain.TabIndex = 2; + this.btnlosetryagain.Text = "Try Again"; + this.btnlosetryagain.UseVisualStyleBackColor = true; + this.btnlosetryagain.Click += new System.EventHandler(this.btnlosetryagain_Click); + // + // Label5 + // + this.Label5.Location = new System.Drawing.Point(7, 26); + this.Label5.Name = "Label5"; + this.Label5.Size = new System.Drawing.Size(260, 163); + this.Label5.TabIndex = 1; + // + // Label1 + // + this.Label1.Dock = System.Windows.Forms.DockStyle.Top; + this.Label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Label1.Location = new System.Drawing.Point(0, 0); + this.Label1.Name = "Label1"; + this.Label1.Size = new System.Drawing.Size(266, 16); + this.Label1.TabIndex = 0; + this.Label1.Text = "You lose!"; + this.Label1.TextAlign = System.Drawing.ContentAlignment.TopCenter; + // + // pnlintro + // + this.pnlintro.Controls.Add(this.Label6); + this.pnlintro.Controls.Add(this.btnstartgame); + this.pnlintro.Controls.Add(this.Label8); + this.pnlintro.Location = new System.Drawing.Point(1139, 41); + this.pnlintro.Name = "pnlintro"; + this.pnlintro.Size = new System.Drawing.Size(595, 303); + this.pnlintro.TabIndex = 13; + this.pnlintro.Tag = "header2"; + // + // Label6 + // + this.Label6.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Label6.Location = new System.Drawing.Point(3, 39); + this.Label6.Name = "Label6"; + this.Label6.Size = new System.Drawing.Size(589, 227); + 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 + // + this.btnstartgame.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.btnstartgame.Location = new System.Drawing.Point(186, 273); + this.btnstartgame.Name = "btnstartgame"; + this.btnstartgame.Size = new System.Drawing.Size(242, 28); + this.btnstartgame.TabIndex = 15; + this.btnstartgame.Text = "{PLAY}"; + this.btnstartgame.UseVisualStyleBackColor = true; + this.btnstartgame.Click += new System.EventHandler(this.btnstartgame_Click); + // + // Label8 + // + this.Label8.AutoSize = true; + this.Label8.Font = new System.Drawing.Font("Microsoft Sans Serif", 20.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Label8.ForeColor = System.Drawing.Color.Black; + this.Label8.Location = new System.Drawing.Point(250, 5); + this.Label8.Name = "Label8"; + 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); + // + // lblbeatai + // + this.lblbeatai.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblbeatai.Location = new System.Drawing.Point(47, 41); + this.lblbeatai.Name = "lblbeatai"; + this.lblbeatai.Size = new System.Drawing.Size(600, 30); + this.lblbeatai.TabIndex = 8; + this.lblbeatai.Tag = "header2"; + this.lblbeatai.Text = "You got 2 codepoints for beating the Computer!"; + this.lblbeatai.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.lblbeatai.Visible = false; + // + // lblcountdown + // + this.lblcountdown.Font = new System.Drawing.Font("Microsoft Sans Serif", 24F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblcountdown.Location = new System.Drawing.Point(182, 152); + this.lblcountdown.Name = "lblcountdown"; + this.lblcountdown.Size = new System.Drawing.Size(315, 49); + this.lblcountdown.TabIndex = 7; + this.lblcountdown.Text = "3"; + this.lblcountdown.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.lblcountdown.Visible = false; + // + // ball + // + this.ball.BackColor = System.Drawing.Color.Black; + this.ball.Location = new System.Drawing.Point(300, 152); + this.ball.Name = "ball"; + this.ball.Size = new System.Drawing.Size(20, 20); + this.ball.TabIndex = 2; + this.ball.MouseEnter += new System.EventHandler(this.ball_MouseEnter); + this.ball.MouseLeave += new System.EventHandler(this.ball_MouseLeave); + // + // paddleHuman + // + this.paddleHuman.BackColor = System.Drawing.Color.Black; + this.paddleHuman.Location = new System.Drawing.Point(10, 134); + this.paddleHuman.Name = "paddleHuman"; + this.paddleHuman.Size = new System.Drawing.Size(20, 100); + this.paddleHuman.TabIndex = 3; + this.paddleHuman.TabStop = false; + // + // paddleComputer + // + this.paddleComputer.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.paddleComputer.BackColor = System.Drawing.Color.Black; + this.paddleComputer.Location = new System.Drawing.Point(1833, 134); + this.paddleComputer.MaximumSize = new System.Drawing.Size(20, 150); + this.paddleComputer.Name = "paddleComputer"; + this.paddleComputer.Size = new System.Drawing.Size(20, 100); + this.paddleComputer.TabIndex = 1; + // + // lbllevelandtime + // + this.lbllevelandtime.Dock = System.Windows.Forms.DockStyle.Top; + this.lbllevelandtime.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lbllevelandtime.Location = new System.Drawing.Point(0, 0); + this.lbllevelandtime.Name = "lbllevelandtime"; + this.lbllevelandtime.Size = new System.Drawing.Size(1867, 22); + this.lbllevelandtime.TabIndex = 4; + this.lbllevelandtime.Tag = "header1"; + this.lbllevelandtime.Text = "Level: 1 - 58 Seconds Left"; + this.lbllevelandtime.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // lblstatscodepoints + // + this.lblstatscodepoints.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.lblstatscodepoints.AutoSize = true; + this.lblstatscodepoints.Font = new System.Drawing.Font("Georgia", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblstatscodepoints.Location = new System.Drawing.Point(239, 775); + this.lblstatscodepoints.Name = "lblstatscodepoints"; + this.lblstatscodepoints.Size = new System.Drawing.Size(116, 23); + this.lblstatscodepoints.TabIndex = 12; + this.lblstatscodepoints.Tag = "header2"; + this.lblstatscodepoints.Text = "Codepoints: "; + this.lblstatscodepoints.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // lblstatsY + // + this.lblstatsY.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.lblstatsY.AutoSize = true; + this.lblstatsY.Font = new System.Drawing.Font("Georgia", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblstatsY.Location = new System.Drawing.Point(1395, 775); + this.lblstatsY.Name = "lblstatsY"; + this.lblstatsY.Size = new System.Drawing.Size(76, 23); + this.lblstatsY.TabIndex = 11; + this.lblstatsY.Tag = "header2"; + this.lblstatsY.Text = "Yspeed:"; + this.lblstatsY.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // lblstatsX + // + this.lblstatsX.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.lblstatsX.AutoSize = true; + this.lblstatsX.Font = new System.Drawing.Font("Georgia", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblstatsX.Location = new System.Drawing.Point(3, 775); + this.lblstatsX.Name = "lblstatsX"; + this.lblstatsX.Size = new System.Drawing.Size(83, 23); + this.lblstatsX.TabIndex = 5; + this.lblstatsX.Tag = "header2"; + this.lblstatsX.Text = "Xspeed: "; + this.lblstatsX.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // Pong + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.White; + this.Controls.Add(this.pgcontents); + this.DoubleBuffered = true; + this.Name = "Pong"; + this.Size = new System.Drawing.Size(1867, 819); + this.Load += new System.EventHandler(this.Pong_Load); + this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pongMain_MouseMove); + this.pgcontents.ResumeLayout(false); + this.pgcontents.PerformLayout(); + this.pnlhighscore.ResumeLayout(false); + this.pnlhighscore.PerformLayout(); + this.flowLayoutPanel1.ResumeLayout(false); + this.flowLayoutPanel1.PerformLayout(); + this.pnlgamestats.ResumeLayout(false); + this.pnlgamestats.PerformLayout(); + this.pnlfinalstats.ResumeLayout(false); + this.pnlfinalstats.PerformLayout(); + this.pnllose.ResumeLayout(false); + this.pnlintro.ResumeLayout(false); + this.pnlintro.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.paddleHuman)).EndInit(); + this.ResumeLayout(false); + + } + internal System.Windows.Forms.Panel paddleComputer; + internal System.Windows.Forms.Timer gameTimer; + internal System.Windows.Forms.PictureBox paddleHuman; + internal System.Windows.Forms.Label lbllevelandtime; + internal System.Windows.Forms.Label lblstatsX; + internal System.Windows.Forms.Timer counter; + internal System.Windows.Forms.Panel pnlgamestats; + internal System.Windows.Forms.Label lblnextstats; + internal System.Windows.Forms.Label Label7; + internal System.Windows.Forms.Label lblpreviousstats; + internal System.Windows.Forms.Label Label4; + internal System.Windows.Forms.Button btnplayon; + internal System.Windows.Forms.Label Label3; + internal System.Windows.Forms.Button btncashout; + internal System.Windows.Forms.Label Label2; + internal System.Windows.Forms.Label lbllevelreached; + internal System.Windows.Forms.Label lblcountdown; + internal System.Windows.Forms.Timer tmrcountdown; + internal System.Windows.Forms.Label lblbeatai; + internal System.Windows.Forms.Panel pnlfinalstats; + internal System.Windows.Forms.Button btnplayagain; + internal System.Windows.Forms.Label lblfinalcodepoints; + internal System.Windows.Forms.Label Label11; + internal System.Windows.Forms.Label lblfinalcomputerreward; + internal System.Windows.Forms.Label Label9; + internal System.Windows.Forms.Label lblfinallevelreward; + internal System.Windows.Forms.Label lblfinallevelreached; + internal System.Windows.Forms.Label lblfinalcodepointswithtext; + internal System.Windows.Forms.Panel pnllose; + internal System.Windows.Forms.Label lblmissedout; + internal System.Windows.Forms.Label lblbutyougained; + internal System.Windows.Forms.Button btnlosetryagain; + internal System.Windows.Forms.Label Label5; + internal System.Windows.Forms.Label Label1; + internal System.Windows.Forms.Label lblstatscodepoints; + internal System.Windows.Forms.Label lblstatsY; + internal System.Windows.Forms.Panel pnlintro; + internal System.Windows.Forms.Label Label6; + internal System.Windows.Forms.Button btnstartgame; + internal System.Windows.Forms.Label Label8; + internal System.Windows.Forms.Timer tmrstoryline; + private System.Windows.Forms.Panel pnlhighscore; + private System.Windows.Forms.ListBox lbhighscore; + private System.Windows.Forms.Label label10; + internal Canvas pgcontents; + internal Canvas ball; + internal System.Windows.Forms.Button button1; + internal System.Windows.Forms.Label label12; + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; + private System.Windows.Forms.Button button2; + } +} diff --git a/ShiftOS.WinForms/Applications/Pong.cs b/ShiftOS.WinForms/Applications/Pong.cs new file mode 100644 index 0000000..a7b1aeb --- /dev/null +++ b/ShiftOS.WinForms/Applications/Pong.cs @@ -0,0 +1,705 @@ +/* + * 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.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using Newtonsoft.Json; +using ShiftOS.Engine; +using ShiftOS.Objects; +using ShiftOS.WinForms.Tools; + +namespace ShiftOS.WinForms.Applications +{ + [MultiplayerOnly] + [Launcher("Pong", true, "al_pong", "Games")] + [WinOpen("pong")] + [DefaultIcon("iconPong")] + public partial class Pong : UserControl, IShiftOSWindow + { + //I can assure you guaranteed that there is an acorn somewhere, in this place, and the sailors are looking for it + int xVel = 7; + int yVel = 8; + int computerspeed = 8; + int level = 1; + int secondsleft = 60; + int casualposition; + double xveldec = 3.0; + double yveldec = 3.0; + double incrementx = 0.4; + double incrementy = 0.2; + int levelxspeed = 3; + int levelyspeed = 3; + int beatairewardtotal; + int beataireward = 1; + int[] levelrewards = new int[50]; + int totalreward; + int countdown = 3; + + bool aiShouldIsbeEnabled = true; + + public Pong() + { + InitializeComponent(); + } + + private void Pong_Load(object sender, EventArgs e) + { + setuplevelrewards(); + } + + + + // Move the paddle according to the mouse position. + private void pongMain_MouseMove(object sender, MouseEventArgs e) + { + var loc = this.PointToClient(MousePosition); + paddleHuman.Location = new Point(paddleHuman.Location.X, (loc.Y) - (paddleHuman.Height / 2)); + } + + private void CenterPanels() + { + pnlfinalstats.CenterParent(); + pnlgamestats.CenterParent(); + pnlhighscore.CenterParent(); + pnlintro.CenterParent(); + pnllose.CenterParent(); + lblcountdown.CenterParent(); + lblbeatai.Left = (this.Width - lblbeatai.Width) / 2; + SetupStats(); + } + + public void SetupStats() + { + lblstatsX.Location = new Point(5, this.Height - lblstatsX.Height - 5); + lblstatsY.Location = new Point(this.Width - lblstatsY.Width - 5, this.Height - lblstatsY.Height - 5); + lblstatscodepoints.Top = this.Height - lblstatscodepoints.Height - 5; + lblstatscodepoints.Left = (this.Width - lblstatscodepoints.Width) / 2; + } + + + // ERROR: Handles clauses are not supported in C# + private void gameTimer_Tick(object sender, EventArgs e) + { + if (this.Left < Screen.PrimaryScreen.Bounds.Width) + { + ball.BackColor = SkinEngine.LoadedSkin.ControlTextColor; + paddleComputer.BackColor = SkinEngine.LoadedSkin.ControlTextColor; + paddleHuman.BackColor = SkinEngine.LoadedSkin.ControlTextColor; + + //Check if paddle upgrade has been bought and change paddles accordingly + if (ShiftoriumFrontend.UpgradeInstalled("pong_increased_paddle_size")) + { + paddleHuman.Height = 150; + paddleComputer.Height = 150; + } + + //Set the computer player to move according to the ball's position. + 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); + } + 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); + } + } + + //Set Xvel and Yvel speeds from decimal + if (xVel > 0) + xVel = (int)Math.Round(xveldec); + if (xVel < 0) + xVel = (int)-Math.Round(xveldec); + if (yVel > 0) + yVel = (int)Math.Round(yveldec); + if (yVel < 0) + yVel = (int)-Math.Round(yveldec); + + // Move the game ball. + ball.Location = new Point(ball.Location.X + xVel, ball.Location.Y + yVel); + + // Check for top wall. + if (ball.Location.Y < 0) + { + ball.Location = new Point(ball.Location.X, 0); + yVel = -yVel; + } + + // Check for bottom wall. + if (ball.Location.Y > pgcontents.Height - ball.Height) + { + ball.Location = new Point(ball.Location.X, pgcontents.Height - ball.Size.Height); + yVel = -yVel; + } + + // Check for player paddle. + if (ball.Bounds.IntersectsWith(paddleHuman.Bounds)) + { + ball.Location = new Point(paddleHuman.Location.X + ball.Size.Width, ball.Location.Y); + //randomly increase x or y speed of ball + switch (rand.Next(1, 3)) + { + case 1: + xveldec = xveldec + incrementx; + break; + case 2: + if (yveldec > 0) + yveldec = yveldec + incrementy; + if (yveldec < 0) + yveldec = yveldec - incrementy; + break; + } + xVel = -xVel; + } + + // Check for computer paddle. + if (ball.Bounds.IntersectsWith(paddleComputer.Bounds)) + { + ball.Location = new Point(paddleComputer.Location.X - paddleComputer.Size.Width + 1, ball.Location.Y); + xveldec = xveldec + incrementx; + xVel = -xVel; + } + + // Check for left wall. + if (ball.Location.X < -100) + { + ball.Location = new Point(this.Size.Width / 2 + 200, this.Size.Height / 2); + paddleComputer.Location = new Point(paddleComputer.Location.X, ball.Location.Y); + if (xVel > 0) + xVel = -xVel; + pnllose.Show(); + gameTimer.Stop(); + counter.Stop(); + 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; + 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)); + } + else + { + lblbutyougained.Hide(); + } + } + + // Check for right wall. + if (ball.Location.X > this.Width - ball.Size.Width - paddleComputer.Width + 100) + { + ball.Location = new Point(this.Size.Width / 2 + 200, this.Size.Height / 2); + paddleComputer.Location = new Point(paddleComputer.Location.X, ball.Location.Y); + if (xVel > 0) + xVel = -xVel; + beatairewardtotal = beatairewardtotal + beataireward; + lblbeatai.Show(); + lblbeatai.Text = Localization.Parse($"{{PONG_BEAT_AI_REWARD_SECONDARY}}: {beataireward}"); + tmrcountdown.Start(); + gameTimer.Stop(); + counter.Stop(); + } + + //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}"); + + if (xVel > 20 || xVel < -20) + { + paddleHuman.Width = Math.Abs(xVel); + paddleComputer.Width = Math.Abs(xVel); + } + else + { + paddleHuman.Width = 20; + paddleComputer.Width = 20; + } + + computerspeed = Math.Abs(yVel); + + // pgcontents.Refresh() + // pgcontents.CreateGraphics.FillRectangle(Brushes.Black, ball.Location.X, ball.Location.Y, ball.Width, ball.Height) + + } + } + + // ERROR: Handles clauses are not supported in C# + private void counter_Tick(object sender, EventArgs e) + { + if (this.Left < Screen.PrimaryScreen.Bounds.Width) + { + secondsleft = secondsleft - 1; + if (secondsleft == 1) + { + secondsleft = 60; + level = level + 1; + generatenextlevel(); + pnlgamestats.Show(); + pnlgamestats.BringToFront(); + pnlgamestats.Location = new Point((pgcontents.Width / 2) - (pnlgamestats.Width / 2), (pgcontents.Height / 2) - (pnlgamestats.Height / 2)); + + counter.Stop(); + gameTimer.Stop(); + SendHighscores(); + } + lblstatscodepoints.Text = Localization.Parse("{CODEPOINTS}: ") + (levelrewards[level - 1] + beatairewardtotal).ToString(); + } + SetupStats(); + } + + public void SendHighscores() + { + var highscore = new PongHighscore + { + UserName = $"{SaveSystem.CurrentSave.Username}@{SaveSystem.CurrentSave.SystemName}", + HighestLevel = level, + HighestCodepoints = totalreward + }; + ServerManager.SendMessage("pong_sethighscore", JsonConvert.SerializeObject(highscore)); + } + + // ERROR: Handles clauses are not supported in C# + private void btnplayon_Click(object sender, EventArgs e) + { + xveldec = levelxspeed; + yveldec = levelyspeed; + + secondsleft = 60; + + tmrcountdown.Start(); + lblbeatai.Text = Localization.Parse($"{{PONG_BEAT_AI_REWARD}}: {beataireward}"); + pnlgamestats.Hide(); + lblbeatai.Show(); + ball.Location = new Point(paddleHuman.Location.X + paddleHuman.Width + 50, paddleHuman.Location.Y + paddleHuman.Height / 2); + if (xVel < 0) + xVel = Math.Abs(xVel); + lbllevelandtime.Text = Localization.Parse("{LEVEL}: " + level + " - " + secondsleft + " {SECONDS_LEFT}"); + } + + //Increase the ball speed stats for the next level + private void generatenextlevel() + { + lbllevelreached.Text = Localization.Parse("{YOU_REACHED_LEVEL} " + level + "!"); + + 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; + } + + switch (rand.Next(1, 3)) + { + case 1: + levelyspeed = levelyspeed + 1; + break; + case 2: + levelyspeed = levelyspeed + 2; + break; + } + + 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; + } + + 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) + { + if (ShiftoriumFrontend.UpgradeInstalled("pong_upgrade")) + { + beataireward = level * 10; + } else + { + beataireward = level * 5; + } + } + 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; + } + } + + totalreward = levelrewards[level - 1] + 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) + { + case 0: + countdown = 3; + lblcountdown.Hide(); + lblbeatai.Hide(); + gameTimer.Start(); + counter.Start(); + tmrcountdown.Stop(); + break; + case 1: + lblcountdown.Text = "1"; + countdown = countdown - 1; + break; + case 2: + lblcountdown.Text = "2"; + countdown = countdown - 1; + break; + case 3: + lblcountdown.Text = "3"; + countdown = countdown - 1; + lblcountdown.Show(); + break; + } + + } + } + + // ERROR: Handles clauses are not supported in C# + private void btncashout_Click(object sender, EventArgs e) + { + pnlgamestats.Hide(); + 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(); + lblfinalcomputerreward.Text = beatairewardtotal.ToString(); + lblfinalcodepoints.Text = totalreward + Localization.Parse(" {CODEPOINTS_SHORT}"); + SaveSystem.TransferCodepointsFrom("pong", totalreward); + } + + private void newgame() + { + pnlfinalstats.Hide(); + pnllose.Hide(); + pnlintro.Hide(); + + level = 1; + totalreward = 0; + if (ShiftoriumFrontend.UpgradeInstalled("pong_upgrade")) + { + beataireward = 10; + } else + { + beataireward = 5; + } + beatairewardtotal = 0; + secondsleft = 60; + lblstatscodepoints.Text = Localization.Parse("{CODEPOINTS}: "); + //reset stats text + lblstatsX.Text = Localization.Parse("{H_VEL}: "); + lblstatsY.Text = Localization.Parse("{V_VEL}: "); + + levelxspeed = 3; + levelyspeed = 3; + + incrementx = 0.4; + incrementy = 0.2; + + xveldec = levelxspeed; + yveldec = levelyspeed; + + tmrcountdown.Start(); + lblbeatai.Text = Localization.Parse($"{{PONG_BEAT_AI_REWARD}}: {beataireward}"); + pnlgamestats.Hide(); + lblbeatai.Show(); + ball.Location = new Point(paddleHuman.Location.X + paddleHuman.Width + 50, (paddleHuman.Location.Y + paddleHuman.Height) / 2); + if (xVel < 0) + xVel = Math.Abs(xVel); + lbllevelandtime.Text = Localization.Parse("{{LEVEL}}: " + level + " - " + secondsleft + " {SECONDS_LEFT}"); + } + + public void btnhighscore_Click(object s, EventArgs a) + { + pnlhighscore.BringToFront(); + SetupHighScores(); + } + + public void SetupHighScores() + { + lbhighscore.Items.Clear(); + ServerManager.MessageReceived += (msg) => + { + if(msg.Name == "pong_highscores") + { + var hs = JsonConvert.DeserializeObject<List<PongHighscore>>(msg.Contents); + + var orderedhs = hs.OrderByDescending(i => i.HighestLevel); + + foreach(var score in orderedhs) + { + this.Invoke(new Action(() => + { + lbhighscore.Items.Add($"{score.UserName}\t\t\t{score.HighestLevel}\t\t{score.HighestCodepoints} CP"); + })); + } + } + }; + ServerManager.SendMessage("pong_gethighscores", null); + pnlhighscore.Show(); + } + + // ERROR: Handles clauses are not supported in C# + private void btnplayagain_Click(object sender, EventArgs e) + { + newgame(); + } + + // ERROR: Handles clauses are not supported in C# + private void btnlosetryagain_Click(object sender, EventArgs e) + { + newgame(); + } + + // ERROR: Handles clauses are not supported in C# + private void btnstartgame_Click(object sender, EventArgs e) + { + newgame(); + } + + Random rand = new Random(); + // ERROR: Handles clauses are not supported in C# + private void tmrstoryline_Tick(object sender, EventArgs e) + { + // Random chance of showing getshiftnet storyline + int i = rand.Next(0, 100); + + if (i >= 25 && i <= 50) + { + tmrstoryline.Stop(); + } + + } + + // ERROR: Handles clauses are not supported in C# + private void me_closing(object sender, FormClosingEventArgs e) + { + tmrstoryline.Stop(); + } + + private void Label6_Click(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) { + aiShouldIsbeEnabled = true; + } + + public void OnLoad() + { + pnlintro.BringToFront(); + pnlintro.Show(); + pnlhighscore.Hide(); + pnlgamestats.Hide(); + pnlfinalstats.Hide(); + CenterPanels(); + lblbeatai.Hide(); + } + + public void OnSkinLoad() + { + CenterPanels(); + this.SizeChanged += (o, a) => + { + CenterPanels(); + }; + } + + public bool OnUnload() + { + return true; + } + + public void OnUpgrade() + { + CenterPanels(); + } + + private void button2_Click(object sender, EventArgs e) + { + pnlhighscore.Hide(); + } + } +} diff --git a/ShiftOS.WinForms/Applications/ShiftoriumFrontend.Designer.cs b/ShiftOS.WinForms/Applications/ShiftoriumFrontend.Designer.cs new file mode 100644 index 0000000..32d508b --- /dev/null +++ b/ShiftOS.WinForms/Applications/ShiftoriumFrontend.Designer.cs @@ -0,0 +1,317 @@ +/* + * 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 ShiftOS.WinForms.Controls; + +namespace ShiftOS.WinForms.Applications +{ + partial class ShiftoriumFrontend + { + /// <summary> + /// Required designer variable. + /// </summary> + private System.ComponentModel.IContainer components = null; + + /// <summary> + /// Clean up any resources being used. + /// </summary> + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// <summary> + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// </summary> + private void InitializeComponent() + { + this.panel1 = new System.Windows.Forms.Panel(); + this.panel2 = new System.Windows.Forms.Panel(); + this.lbupgradedesc = new System.Windows.Forms.Label(); + this.pnlupgradeactions = new System.Windows.Forms.Panel(); + this.btnbuy = new System.Windows.Forms.Button(); + this.lbupgradetitle = new System.Windows.Forms.Label(); + this.pnllist = new System.Windows.Forms.Panel(); + 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(); + this.pnllist.SuspendLayout(); + this.panel3.SuspendLayout(); + this.SuspendLayout(); + // + // panel1 + // + this.panel1.Controls.Add(this.panel2); + this.panel1.Controls.Add(this.pnllist); + this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel1.Location = new System.Drawing.Point(0, 0); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(782, 427); + this.panel1.TabIndex = 0; + // + // panel2 + // + this.panel2.Controls.Add(this.lbupgradedesc); + this.panel2.Controls.Add(this.pnlupgradeactions); + this.panel2.Controls.Add(this.lbupgradetitle); + this.panel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel2.Location = new System.Drawing.Point(406, 0); + this.panel2.Name = "panel2"; + this.panel2.Size = new System.Drawing.Size(376, 427); + this.panel2.TabIndex = 1; + // + // lbupgradedesc + // + this.lbupgradedesc.Dock = System.Windows.Forms.DockStyle.Fill; + this.lbupgradedesc.Location = new System.Drawing.Point(0, 42); + this.lbupgradedesc.Name = "lbupgradedesc"; + this.lbupgradedesc.Size = new System.Drawing.Size(376, 348); + this.lbupgradedesc.TabIndex = 2; + this.lbupgradedesc.Text = "{SHIFTORIUM_EXP}"; + this.lbupgradedesc.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.lbupgradedesc.UseCompatibleTextRendering = true; + // + // pnlupgradeactions + // + this.pnlupgradeactions.Controls.Add(this.btnbuy); + this.pnlupgradeactions.Dock = System.Windows.Forms.DockStyle.Bottom; + this.pnlupgradeactions.Location = new System.Drawing.Point(0, 390); + this.pnlupgradeactions.Name = "pnlupgradeactions"; + this.pnlupgradeactions.Size = new System.Drawing.Size(376, 37); + this.pnlupgradeactions.TabIndex = 1; + // + // btnbuy + // + this.btnbuy.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnbuy.AutoSize = true; + this.btnbuy.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.btnbuy.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnbuy.Location = new System.Drawing.Point(327, 9); + this.btnbuy.Name = "btnbuy"; + this.btnbuy.Size = new System.Drawing.Size(37, 25); + this.btnbuy.TabIndex = 0; + this.btnbuy.Text = "Buy"; + this.btnbuy.UseVisualStyleBackColor = true; + this.btnbuy.Visible = false; + this.btnbuy.Click += new System.EventHandler(this.btnbuy_Click); + // + // lbupgradetitle + // + this.lbupgradetitle.Dock = System.Windows.Forms.DockStyle.Top; + this.lbupgradetitle.Location = new System.Drawing.Point(0, 0); + this.lbupgradetitle.Name = "lbupgradetitle"; + this.lbupgradetitle.Size = new System.Drawing.Size(376, 42); + this.lbupgradetitle.TabIndex = 0; + this.lbupgradetitle.Text = "{WELCOME_TO_SHIFTORIUM}"; + this.lbupgradetitle.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.lbupgradetitle.UseCompatibleTextRendering = true; + // + // pnllist + // + this.pnllist.Controls.Add(this.lbnoupgrades); + this.pnllist.Controls.Add(this.panel3); + this.pnllist.Controls.Add(this.lbcodepoints); + this.pnllist.Controls.Add(this.label1); + this.pnllist.Controls.Add(this.pgupgradeprogress); + this.pnllist.Controls.Add(this.lbupgrades); + this.pnllist.Dock = System.Windows.Forms.DockStyle.Left; + this.pnllist.Location = new System.Drawing.Point(0, 0); + this.pnllist.Name = "pnllist"; + this.pnllist.Size = new System.Drawing.Size(406, 427); + this.pnllist.TabIndex = 0; + // + // lbcodepoints + // + this.lbcodepoints.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.lbcodepoints.AutoSize = true; + this.lbcodepoints.Location = new System.Drawing.Point(128, 357); + this.lbcodepoints.Name = "lbcodepoints"; + 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 + // + this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(3, 399); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(137, 13); + this.label1.TabIndex = 2; + this.label1.Text = "{UPGRADE_PROGRESS}:"; + // + // pgupgradeprogress + // + 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; + // + // lbupgrades + // + this.lbupgrades.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.lbupgrades.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed; + this.lbupgrades.FormattingEnabled = true; + this.lbupgrades.Location = new System.Drawing.Point(3, 105); + this.lbupgrades.Name = "lbupgrades"; + this.lbupgrades.Size = new System.Drawing.Size(397, 238); + this.lbupgrades.TabIndex = 0; + this.lbupgrades.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.lbupgrades_DrawItem); + // + // label3 + // + this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(3, 399); + this.label3.Name = "label3"; + 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); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.Black; + this.Controls.Add(this.panel1); + 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); + this.pnlupgradeactions.PerformLayout(); + this.pnllist.ResumeLayout(false); + this.pnllist.PerformLayout(); + this.panel3.ResumeLayout(false); + this.panel3.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Panel panel2; + private System.Windows.Forms.Panel pnllist; + private System.Windows.Forms.ListBox lbupgrades; + private System.Windows.Forms.Label lbupgradedesc; + private System.Windows.Forms.Panel pnlupgradeactions; + private System.Windows.Forms.Label lbupgradetitle; + private System.Windows.Forms.Button btnbuy; + private ShiftedProgressBar pgupgradeprogress; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label lbcodepoints; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Panel panel3; + private System.Windows.Forms.Label lblcategorytext; + private System.Windows.Forms.Button btncat_forward; + private System.Windows.Forms.Button btncat_back; + private System.Windows.Forms.Label lbnoupgrades; + } +}
\ No newline at end of file diff --git a/ShiftOS.WinForms/Applications/ShiftoriumFrontend.cs b/ShiftOS.WinForms/Applications/ShiftoriumFrontend.cs new file mode 100644 index 0000000..0762897 --- /dev/null +++ b/ShiftOS.WinForms/Applications/ShiftoriumFrontend.cs @@ -0,0 +1,274 @@ +/* + * 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.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using ShiftOS.Engine; +using static ShiftOS.Engine.SkinEngine; +using backend = ShiftOS.Engine.Shiftorium; +namespace ShiftOS.WinForms.Applications +{ + [Launcher("Shiftorium", true, "al_shiftorium", "Utilities")] + [RequiresUpgrade("shiftorium_gui")] + [MultiplayerOnly] + [WinOpen("shiftorium")] + [DefaultTitle("Shiftorium")] + [DefaultIcon("iconShiftorium")] + public partial class ShiftoriumFrontend : UserControl, IShiftOSWindow + { + public int CategoryId = 0; + public static System.Timers.Timer timer100; + + + 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(); + lbupgrades.SelectedIndexChanged += (o, a) => + { + try + { + lbupgrades.Refresh(); + SelectUpgrade(lbupgrades.SelectedItem.ToString()); + } + catch { } + }; + this.pgupgradeprogress.Maximum = backend.GetDefaults().Count; + this.pgupgradeprogress.Value = SaveSystem.CurrentSave.CountUpgrades(); + backend.Installed += () => + { + this.pgupgradeprogress.Maximum = backend.GetDefaults().Count; + this.pgupgradeprogress.Value = SaveSystem.CurrentSave.CountUpgrades(); + }; + + } + + public void SelectUpgrade(string name) + { + btnbuy.Show(); + var upg = upgrades[name]; + lbupgradetitle.Text = Localization.Parse(upg.Name); + lbupgradedesc.Text = Localization.Parse(upg.Description); + } + + Dictionary<string, ShiftoriumUpgrade> upgrades = new Dictionary<string, ShiftoriumUpgrade>(); + + public void PopulateShiftorium() + { + 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); + } + catch + { + lbnoupgrades.Show(); + lbnoupgrades.Location = new Point( + (lbupgrades.Width - lbnoupgrades.Width) / 2, + (lbupgrades.Height - lbnoupgrades.Height) / 2 + ); + + } + } + + public static bool UpgradeInstalled(string upg) + { + return backend.UpgradeInstalled(upg); + } + + public static bool UpgradeAttributesUnlocked(FieldInfo finf) + { + return backend.UpgradeAttributesUnlocked(finf); + } + + public static bool UpgradeAttributesUnlocked(MethodInfo finf) + { + return backend.UpgradeAttributesUnlocked(finf); + } + + public static bool UpgradeAttributesUnlocked(Type finf) + { + return backend.UpgradeAttributesUnlocked(finf); + } + + public static bool UpgradeAttributesUnlocked(PropertyInfo finf) + { + return backend.UpgradeAttributesUnlocked(finf); + } + + private void lbupgrades_DrawItem(object sender, DrawItemEventArgs e) + { + var foreground = new SolidBrush(LoadedSkin.ControlTextColor); + var background = new SolidBrush(LoadedSkin.ControlColor); + + e.Graphics.FillRectangle(background, e.Bounds); + try + { + if (lbupgrades.GetSelected(e.Index) == true) + { + e.Graphics.FillRectangle(foreground, e.Bounds); + e.Graphics.DrawString(lbupgrades.Items[e.Index].ToString(), e.Font, background, e.Bounds.Location); + } + else + { + e.Graphics.FillRectangle(background, e.Bounds); + e.Graphics.DrawString(lbupgrades.Items[e.Index].ToString(), e.Font, foreground, e.Bounds.Location); + } + } + catch + { + } + } + + private void btnbuy_Click(object sender, EventArgs e) + { + long cpCost = 0; + backend.Silent = true; + Dictionary<string, int> UpgradesToBuy = new Dictionary<string, int>(); + foreach (var itm in lbupgrades.SelectedItems) + { + cpCost += upgrades[itm.ToString()].Cost; + UpgradesToBuy.Add(upgrades[itm.ToString()].ID, upgrades[itm.ToString()].Cost); + } + if (SaveSystem.CurrentSave.Codepoints < cpCost) + { + Infobox.Show("Insufficient Codepoints", $"You do not have enough Codepoints to perform this action. You need {cpCost - SaveSystem.CurrentSave.Codepoints} more."); + + } + else + { + foreach(var upg in UpgradesToBuy) + { + backend.Buy(upg.Key, upg.Value); + } + } + + backend.Silent = false; + PopulateShiftorium(); + btnbuy.Hide(); + } + + private void Shiftorium_Load(object sender, EventArgs e) { + + } + + public void OnLoad() + { + cp_update.Start(); + lbnoupgrades.Hide(); + } + + public void OnSkinLoad() + { + + } + + Timer cp_update = new System.Windows.Forms.Timer(); + + public bool OnUnload() + { + cp_update.Stop(); + cp_update = null; + return true; + } + + public void OnUpgrade() + { + lbupgrades.SelectionMode = (UpgradeInstalled("shiftorium_gui_bulk_buy") == true) ? SelectionMode.MultiExtended : SelectionMode.One; + lbcodepoints.Visible = Shiftorium.UpgradeInstalled("shiftorium_gui_codepoints_display"); + } + + private void lbcodepoints_Click(object sender, EventArgs e) + { + + } + + void Timer() + { + timer100 = new System.Timers.Timer(); + timer100.Interval = 2000; + //timer100.Elapsed += ???; + timer100.AutoReset = true; + timer100.Enabled = true; + } + + private void btncat_back_Click(object sender, EventArgs e) + { + if(CategoryId > 0) + { + CategoryId--; + PopulateShiftorium(); + } + } + + private void btncat_forward_Click(object sender, EventArgs e) + { + if(CategoryId < backend.GetCategories().Length - 1) + { + CategoryId++; + PopulateShiftorium(); + } + } + } +} diff --git a/ShiftOS.WinForms/Controls/TerminalBox.cs b/ShiftOS.WinForms/Controls/TerminalBox.cs new file mode 100644 index 0000000..bc2bcc0 --- /dev/null +++ b/ShiftOS.WinForms/Controls/TerminalBox.cs @@ -0,0 +1,123 @@ +/* + * 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.Drawing; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using ShiftOS.Engine; +using ShiftOS.WinForms.Tools; + +namespace ShiftOS.WinForms.Controls +{ + public class TerminalBox : RichTextBox, ITerminalWidget + { + public void SelectBottom() + { + try + { + this.Select(this.Text.Length, 0); + this.ScrollToCaret(); + } + catch { } + } + + protected override void Dispose(bool disposing) + { + if (disposing == true) + if(AppearanceManager.ConsoleOut == this) + AppearanceManager.ConsoleOut = null; + base.Dispose(disposing); + } + + protected override void OnClick(EventArgs e) + { + base.OnClick(e); + this.Select(this.TextLength, 0); + } + + public void Write(string text) + { + this.HideSelection = true; + this.Select(this.TextLength, 0); + this.SelectionFont = ConstructFont(); + this.SelectionColor = ControlManager.ConvertColor(ConsoleEx.ForegroundColor); + this.SelectionBackColor = ControlManager.ConvertColor(ConsoleEx.BackgroundColor); + this.AppendText(Localization.Parse(text)); + this.HideSelection = false; + } + + private Font ConstructFont() + { + FontStyle fs = FontStyle.Regular; + if (ConsoleEx.Bold) + fs = fs | FontStyle.Bold; + if (ConsoleEx.Italic) + fs = fs | FontStyle.Italic; + if (ConsoleEx.Underline) + fs = fs | FontStyle.Underline; + + return new Font(this.Font, fs); + } + + public void WriteLine(string text) + { + this.HideSelection = true; + this.Select(this.TextLength, 0); + this.SelectionFont = ConstructFont(); + this.SelectionColor = ControlManager.ConvertColor(ConsoleEx.ForegroundColor); + this.SelectionBackColor = ControlManager.ConvertColor(ConsoleEx.BackgroundColor); + this.AppendText(Localization.Parse(text) + Environment.NewLine); + this.HideSelection = false; + } + + bool quickCopying = false; + + protected override void OnMouseDown(MouseEventArgs e) + { + //if right-clicking, then we initiate a quick-copy. + if (e.Button == MouseButtons.Right) + quickCopying = true; + + //Override the mouse event so that it's a left-click at all times. + base.OnMouseDown(new MouseEventArgs(MouseButtons.Left, e.Clicks, e.X, e.Y, e.Delta)); + } + + protected override void OnMouseUp(MouseEventArgs mevent) + { + if(quickCopying == true) + { + if (!string.IsNullOrWhiteSpace(this.SelectedText)) + { + this.Copy(); + } + } + base.OnMouseUp(mevent); + } + } +} diff --git a/ShiftOS.WinForms/Oobe.cs b/ShiftOS.WinForms/Oobe.cs new file mode 100644 index 0000000..d6d3b92 --- /dev/null +++ b/ShiftOS.WinForms/Oobe.cs @@ -0,0 +1,568 @@ +/* + * 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.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using Newtonsoft.Json; +using ShiftOS.Engine; +using ShiftOS.Objects; +using ShiftOS.Objects.ShiftFS; + +namespace ShiftOS.WinForms +{ + public partial class Oobe : Form, IOobe, ITutorial + { + public Oobe() + { + InitializeComponent(); + this.FormBorderStyle = FormBorderStyle.None; + this.WindowState = FormWindowState.Maximized; + this.BackColor = Color.Black; + + } + + + string rtext; + string gtexttotype; + int charcount; + int slashcount; + Label textgeninput; + public bool upgraded = false; + + private bool typing = false; + + public void TextType(string texttotype) + { + while(typing == true) + { + //JESUS CHRIST PAST MICHAEL. + + //We should PROBABLY block the thread... You know... not everyone has a 10-core processor. + Thread.Sleep(100); + } + + charcount = texttotype.Length; + gtexttotype = texttotype; + slashcount = 1; + foreach (var c in gtexttotype) + { + typing = true; + rtext += c; + + this.Invoke(new Action(() => + { + textgeninput.Text = rtext + "|"; + })); + slashcount++; + if (slashcount == 5) + slashcount = 1; + Thread.Sleep(50); + } + rtext += Environment.NewLine; + typing = false; + } + + public Save MySave = null; + + public event EventHandler OnComplete; + + private int tutPrg = 0; + + public int TutorialProgress + { + get + { + return tutPrg; + } + + set + { + tutPrg = value; + } + } + + public void StartShowing(Save save) + { + var t = new Thread(new ThreadStart(() => + { + try + { + textgeninput = this.lblHijack; + TextType("Your system is now being hijacked."); + rtext = ""; + Thread.Sleep(1000); + textgeninput = this.lblhackwords; + this.Invoke(new Action(() => + { + lblHijack.Hide(); + })); + TextType("Hello, and welcome to ShiftOS."); + Thread.Sleep(500); + TextType("You have been cordially and involuntarily selected to participate in the development and testing of this operating system."); + Thread.Sleep(500); + TextType("My identity shall remain secret, but if you've been through this before, you'll know exactly who I am."); + Thread.Sleep(500); + TextType("But that doesn't matter."); + Thread.Sleep(500); + TextType("I will now begin to prepare your system for the installation of ShiftOS."); + Thread.Sleep(1000); + FakeSetupScreen fakeForm = null; + this.Invoke(new Action(() => + { + fakeForm = new FakeSetupScreen(this); + fakeForm.Show(); + MySave = save; + lblhackwords.GotFocus += (o, a) => + { + try + { + fakeForm.Invoke(new Action(() => + { + fakeForm.Focus(); + fakeForm.BringToFront(); + })); + } + catch { } + }; + fakeForm.TextSent += (txt) => + { + TextType(txt); + }; + })); + while (fakeForm?.Visible == true) + { + Thread.Sleep(10); + } + if (fakeForm.CreateNewSave == true) + { + TextType("That's all the information I need for now."); + Thread.Sleep(2000); + TextType("Beginning installation of ShiftOS on " + MySave.SystemName + "."); + Thread.Sleep(500); + TextType("Creating new user: " + MySave.Username); + TextType("...with 0 Codepoints, 0 installed upgrades, no legion, and no user shops..."); + MySave.Codepoints = 0; + MySave.CurrentLegions = new List<string>(); + MySave.MyShop = ""; + TextType("User created successfully."); + Thread.Sleep(450); + TextType("You may be wondering what all that meant... You see, in ShiftOS, your user account holds everything I need to know about you."); + Thread.Sleep(640); + TextType("It holds the amount of Codepoints you have - Codepoints are a special currency you can get by doing various tasks in ShiftOS."); + Thread.Sleep(500); + TextType("It also holds all the upgrades you've installed onto ShiftOS - features, applications, enhancements, patches, all that stuff."); + Thread.Sleep(500); + TextType("As for the legions and the shop thing, I'll reveal that to you when it becomes necessary."); + Thread.Sleep(500); + TextType("Your user account is stored on a server of mine called the multi-user domain. It holds every single user account, every script, every application, every thing within ShiftOS."); + Thread.Sleep(600); + TextType("Every time you boot ShiftOS, if you are connected to the Internet, you will immediately connect to the multi-user domain and ShiftOS will attempt to authenticate using the last "); + TextType("successful username and password pair."); + Thread.Sleep(500); + TextType("When you are in the MUD, you are in the middle of a free-for-all. I don't want it to be this way, it just is. I've employed you to help me develop and test the MUD and ShiftOS, "); + TextType("but you have a secondary task if you choose to accept it."); + Thread.Sleep(500); + TextType("There have been a few rebelious groups in the MUD - who have cracked ShiftOS's security barriers - and they're using these exploits to steal others' Codepoints, upgrades, "); + TextType("and even spread damaging viruses."); + Thread.Sleep(500); + TextType("I want you to stop them."); + Thread.Sleep(500); + TextType("Whoever can stop these hackers will gain eternal control over the multi-user domain. They will be given the ability to do as they please, so long as it doesn't interfere with my experiments."); + Thread.Sleep(500); + TextType("I have been installing ShiftOS on your system in the background as I was talking with you. Before I can set you free, I need to give you a tutorial on how to use the system."); + Thread.Sleep(500); + TextType("I will reboot your system in Tutorial Mode now. Complete the tutorial, and you shall be on your way."); + + Thread.Sleep(3000); + SaveSystem.CurrentSave = MySave; + SaveSystem.CurrentSave.StoryPosition = 1; + Utils.WriteAllText(Paths.GetPath("user.dat"), JsonConvert.SerializeObject(new + { + username = MySave.Username, + password = MySave.Password + })); + Shiftorium.Silent = true; + SaveSystem.SaveGame(); //Yknow, just incase it crashes. + } + else + { + TextType("Your login attempt was successful, " + SaveSystem.CurrentSave.Username + "."); + Thread.Sleep(500); + TextType($"According to my data on you, you have earned {SaveSystem.CurrentSave.Codepoints} Codepoints so far."); + Thread.Sleep(500); + TextType($"You have also acquired {SaveSystem.CurrentSave.CountUpgrades()} Shiftorium upgrades out of the {SaveSystem.CurrentSave.Upgrades.Count} available."); + Thread.Sleep(500); + TextType("I will now let you proceed to your system."); + Thread.Sleep(1000); + } + this.Invoke(new Action(this.Close)); + } + catch (Exception e) + { + TextType("I have experienced an error."); + TextType(e.ToString()); + } + })); + this.Show(); + this.BringToFront(); + this.TopMost = true; + t.IsBackground = true; + t.Start(); + } + + public void Clear() + { + this.Invoke(new Action(() => + { + rtext = ""; + textgeninput.Text = ""; + })); + } + + public void ShowSaveTransfer(Save save) + { + this.Show(); + var fSetup = new FakeSetupScreen(this, 7); + + var t = new Thread(() => + { + textgeninput = lblhackwords; + Clear(); + TextType("Welcome back to ShiftOS."); + Thread.Sleep(500); + TextType("Since your last time inside ShiftOS, the operating system has changed. Your user account is no longer stored on your local system."); + Thread.Sleep(500); + this.Invoke(new Action(() => + { + //UPS is drunky heaven over here... it's a liquor store, I think... - Drunk Michael + fSetup.UserReregistered += (u, p, s) => + { + save.Username = u; + save.Password = p; + save.SystemName = s; + SaveSystem.CurrentSave = save; + SaveSystem.CurrentSave.Upgrades = new Dictionary<string, bool>(); + Shiftorium.Init(); + + SaveSystem.SaveGame(); + if(Utils.FileExists(Paths.SaveFileInner)) + Utils.Delete(Paths.SaveFileInner); + this.Close(); + }; + fSetup.Show(); + })); + }); + t.IsBackground = true; + t.Start(); + } + + public void PromptForLogin() + { + this.Show(); + this.TopMost = true; + lblHijack.Text = ""; + textgeninput = lblhackwords; + + var fsw = new FakeSetupScreen(this, 10); + fsw.Show(); + fsw.TopMost = true; + fsw.DoneLoggingIn += () => + { + this.Close(); + }; + } + + public void StartTrailer() + { + while(AppearanceManager.OpenForms.Count > 0) + { + AppearanceManager.OpenForms[0].Close(); + } + + this.Show(); + this.TopMost = true; + this.TransparencyKey = Color.Magenta; + this.BackColor = this.TransparencyKey; + textgeninput = lblHijack; + textgeninput.BackColor = Color.Black; + textgeninput.Font = new Font("Lucida Console", 13F, FontStyle.Bold); + textgeninput.AutoSize = true; + textgeninput.TextAlign = ContentAlignment.MiddleCenter; + textgeninput.TextChanged += (o, a) => + { + textgeninput.Location = new Point( + (this.Width - textgeninput.Width) / 2, + (this.Height - textgeninput.Height) / 2 + ); + }; + var t = new Thread(() => + { + Clear(); + Thread.Sleep(5000); + TextType("Michael VanOverbeek"); + TextType("presents..."); + Thread.Sleep(2000); + Clear(); + Thread.Sleep(1000); + TextType("A community-developed game"); + Thread.Sleep(3000); + Clear(); + Thread.Sleep(1000); + this.Invoke(new Action(() => + { + textgeninput.Font = new Font("Lucida Console", 14F, FontStyle.Bold); + this.BackColor = Color.Black; + })); + TextType("Welcome to ShiftOS."); + Thread.Sleep(4000); + Clear(); + textgeninput = lblhackwords; + TextType("Hello."); + Thread.Sleep(500); + TextType("You have been cordially and involuntarily selected to participate in the development and testing of an experimental operating system called ShiftOS."); + Thread.Sleep(500); + TextType("I want ShiftOS to be the most advanced operating system in the world."); + Thread.Sleep(500); + TextType("In ShiftOS, you start out with nothing."); + Thread.Sleep(500); + TextType("And your goal is to upgrade the operating system from a barebones command line to a fully graphical operating system."); + Thread.Sleep(500); + TextType("Along the way, you'll meet many people - hackers, rebels, programmers, administrators and many more."); + Thread.Sleep(500); + TextType("You'll meet new friends and foes."); + Thread.Sleep(500); + TextType("Your goal: Take it over. Upgrade the operating system, and take over its multi-user domain."); + Thread.Sleep(500); + TextType("I won't reveal quite what you have to do, but if you can handle it, head over to http://getshiftos.ml/ and download the operating system now."); + Thread.Sleep(5000); + Clear(); + textgeninput = lblHijack; + TextType("Think you can handle it?"); + }); + t.IsBackground = false; + t.Start(); + } + + public void Start() + { + Shiftorium.Silent = false; + foreach(var frm in AppearanceManager.OpenForms) + { + (frm as Form).Invoke(new Action(() => { + frm.Close(); + })); + } + + TerminalBackend.CommandProcessed += (cmd, args) => + { + if(cmd == "sos.help") + { + if (TutorialProgress == 0) + TutorialProgress = 1; + } + else if(cmd == "sos.status") + { + if (TutorialProgress == 1) + TutorialProgress = 2; + + } + else if(cmd == "shiftorium.list") + { + if (TutorialProgress == 2) + { + TutorialProgress = 3; + SaveSystem.TransferCodepointsFrom("sys", 50); + } + } + else if(cmd == "shiftorium.info" && args == "{\"upgrade\":\"mud_fundamentals\"}") + { + if (TutorialProgress == 3) + TutorialProgress = 4; + } + else if(cmd == "win.open") + { + if (TutorialProgress == 4) + TutorialProgress = 5; + } + }; + if(this.Visible == false) + this.Show(); + var t = new Thread(() => + { + textgeninput = lblHijack; + Clear(); + textgeninput = lblhackwords; + Clear(); + + this.Invoke(new Action(() => + { + textgeninput.Font = SkinEngine.LoadedSkin.TerminalFont; + })); + TextType("ShiftOS has been installed successfully."); + Thread.Sleep(500); + TextType("Before you can continue to the operating system, here's a little tutorial on how to use it."); + Thread.Sleep(500); + TextType("Starting a Terminal..."); + Applications.Terminal term = null; + this.Invoke(new Action(() => + { + term = new Applications.Terminal(); + this.Controls.Add(term); + term.Location = new Point( + (this.Width - term.Width) / 2, + (this.Height - term.Height) / 2 + ); + term.Show(); + term.OnLoad(); + term.OnSkinLoad(); + term.OnUpgrade(); + })); + TextType("This little text box is called a Terminal."); + Thread.Sleep(500); + TextType("Normally, it would appear in full-screen, but this window is hosting it as a control so you can see this text as well."); + Thread.Sleep(500); + TextType("In ShiftOS, the Terminal is your main control centre for the operating system. You can see system status, check Codepoints, open other programs, buy upgrades, and more."); + Thread.Sleep(500); + TextType("Go ahead and type 'sos.help' to see a list of commands."); + while (TutorialProgress == 0) + { + //JESUS CHRIST PAST MICHAEL. + + //We should PROBABLY block the thread... You know... not everyone has a 10-core processor. + Thread.Sleep(100); + + } + TextType("As you can see, sos.help gives you a list of all commands in the system."); + Thread.Sleep(500); + TextType("You can run any command, by typing in their Namespace, followed by a period (.), followed by their Command Name."); + Thread.Sleep(500); + TextType("Go ahead and run the 'status' command within the 'sos' namespace to see what the command does."); + while (TutorialProgress == 1) + { + //JESUS CHRIST PAST MICHAEL. + + //We should PROBABLY block the thread... You know... not everyone has a 10-core processor. + Thread.Sleep(100); + + } + TextType("Brilliant. The sos.status command will tell you how many Codepoints you have, as well as how many upgrades you have installed and how many are available."); + Thread.Sleep(500); + TextType("Codepoints, as you know, are a special currency within ShiftOS. They are used to buy things within the multi-user domain, such as upgrades, scripts, and applications."); + Thread.Sleep(500); + TextType("You can earn Codepoints by doing things in ShiftOS - such as completing jobs for other users, making things like skins, scripts, documents, etc, and playing games like Pong."); + Thread.Sleep(500); + TextType("At times, you'll be given Codepoints to help complete a task. You will receive Codepoints from 'sys' - the multi-user domain itself."); + //SaveSystem.TransferCodepointsFrom("sys", 50); + TextType("Right now, you don't have any upgrades. Upgrades can give ShiftOS additional features and capabilities - like new core applications, supported file types, and new Terminal commands."); + Thread.Sleep(500); + TextType("You can easily get upgrades using the Shiftorium - a repository of approved ShiftOS upgrades."); + Thread.Sleep(500); + TextType("To start using the Shiftorium, simply type 'shiftorium.list' to see available upgrades."); + while (TutorialProgress == 2) + { + //JESUS CHRIST PAST MICHAEL. + + //We should PROBABLY block the thread... You know... not everyone has a 10-core processor. + Thread.Sleep(100); + + } + Clear(); + TextType("Right now, you have enough Codepoints to buy the 'mud_fundamentals' upgrade. You can use shiftorium.info to see information about this upgrade."); + Thread.Sleep(500); + TextType("Some commands, like shiftorium.info, require you to pass information to them in the form of arguments."); + Thread.Sleep(500); + TextType("Argument pairs sit at the end of the command, and are enclosed in curly braces."); + Thread.Sleep(500); + TextType("Inside these curly braces, you can input an argument key, followed by a colon, followed by the value. Then, if you need multiple arguments, you can put a comma after the value, and then insert another argument pair."); + Thread.Sleep(500); + TextType("There are different value types - numeric values, which can be any positive or negative 32-bit integer"); + Thread.Sleep(500); + TextType("Then there are boolean values which can be either 'true' or 'false'"); + Thread.Sleep(500); + TextType("Then there are string values, which are enclosed in double-quotes."); + Thread.Sleep(500); + TextType(" If for some reason you need to use a double-quote inside a string, you must escape it using a single backslash followed by the quote, like this: key:\"My \\\"awesome\\\" value.\""); + Thread.Sleep(500); + TextType("If you want to escape a backslash inside a string, simply type two backslashes instead of one - for example key:\"Back\\\\slash.\""); + Thread.Sleep(500); + TextType("shiftorium.info requires an upgrade argument, which is a string type. Go ahead and give shiftorium.info's upgrade argument the 'mud_fundamentals' upgrade's ID."); + while (TutorialProgress == 3) + { + //JESUS CHRIST PAST MICHAEL. + + //We should PROBABLY block the thread... You know... not everyone has a 10-core processor. + Thread.Sleep(100); + + } + TextType("As you can see, mud_fundamentals is very useful. In fact, a lot of useful upgrades depend on it. You should buy it!"); + Thread.Sleep(500); + TextType("shiftorium.info already gave you a command that will let you buy the upgrade - go ahead and run that command!"); + while (!Shiftorium.UpgradeInstalled("mud_fundamentals")) + { //JESUS CHRIST PAST MICHAEL. + + //We should PROBABLY block the thread... You know... not everyone has a 10-core processor. + Thread.Sleep(100); + + + } + TextType("Hooray! You now have the MUD Fundamentals upgrade."); + Thread.Sleep(500); + TextType("You can also earn more Codepoints by playing Pong. To open Pong, you can use the win.open command."); + Thread.Sleep(500); + TextType("If you run win.open without arguments, you can see a list of applications that you can open."); + Thread.Sleep(500); + TextType("Just run win.open without arguments, and this tutorial will be completed!"); + while (TutorialProgress == 4) + { + //JESUS CHRIST PAST MICHAEL. + + //We should PROBABLY block the thread... You know... not everyone has a 10-core processor. + Thread.Sleep(100); + + } + TextType("This concludes the ShiftOS beginners' guide brought to you by the multi-user domain. Stay safe in a connected world."); + Thread.Sleep(2000); + Desktop.InvokeOnWorkerThread(() => + { + OnComplete?.Invoke(this, EventArgs.Empty); + SaveSystem.CurrentSave.StoryPosition = 2; + this.Close(); + SaveSystem.SaveGame(); + AppearanceManager.SetupWindow(new Applications.Terminal()); + }); + + }); + t.IsBackground = true; + t.Start(); + } + } +} diff --git a/ShiftOS.WinForms/Program.cs b/ShiftOS.WinForms/Program.cs index 0578389..348360f 100644 --- a/ShiftOS.WinForms/Program.cs +++ b/ShiftOS.WinForms/Program.cs @@ -102,7 +102,6 @@ namespace ShiftOS.WinForms } } - public class WinformsFSFrontend : IFileSkimmer { diff --git a/ShiftOS.WinForms/Resources/Shiftorium.txt b/ShiftOS.WinForms/Resources/Shiftorium.txt index 12e3a1a..0c4e0c6 100644 --- a/ShiftOS.WinForms/Resources/Shiftorium.txt +++ b/ShiftOS.WinForms/Resources/Shiftorium.txt @@ -4,13 +4,15 @@ Name: "Screensavers", Cost: 750, Description: "Like to leave your PC idle for long periods of time? Save some energy and keep your screen from being tired by hiding the desktop behind a black screen with an image on it.", - Dependencies: "desktop" + Dependencies: "desktop", + Category: "Enhancements", }, { Name: "Shift Screensavers", Cost: 100, Description: "This Shifter upgrade will allow you to customize the screensaver.", - Dependencies: "screensavers;shifter" + Dependencies: "screensavers;shifter", + Category: "Customization" }, @@ -19,72 +21,84 @@ Name: "Calculator", Cost: 1000, Dependencies: "wm_free_placement;desktop", - Description: "Crazy math problems getting you down? Well, this calculator will take care of that!" + Description: "Crazy math problems getting you down? Well, this calculator will take care of that!", + Category: "Applications" }, { Name: "AL Calculator", Cost: 150, Dependencies: "calculator;app_launcher", - Description: "Add an App Launcher Entry for the Calculator!" + Description: "Add an App Launcher Entry for the Calculator!", + Category: "GUI", }, { Name: "Calc Equals Button", Cost: 600, Dependencies: "calculator", + Category: "Enhancements", Description: "Right now, you can only type numbers, but this equals button opens the door to solving equations!" }, { Name: "Calc Decimal Button", Cost: 600, Dependencies: "calculator", + Category: "Enhancements", Description: "Whole numbers can get boring. With this button, you can type decimal numbers!" }, { Name: "Calc Plus Button", Cost: 700, Dependencies: "calc_equals_button", + Category: "Enhancements", Description: "With this extra button, your calculator can now do addition problems!" }, { Name: "Calc Minus Button", Cost: 700, Dependencies: "calc_equals_button", + Category: "Enhancements", Description: "With this extra button, your calculator can now do subtraction problems!" }, { Name: "Calc Multiply Button", Cost: 800, Dependencies: "calc_plus_button", + Category: "Enhancements", Description: "You can add numbers together, but it must be tiring to add the same number over and over. This multiplication button will make it easier for you!" }, { Name: "Calc Divide Button", Cost: 800, Dependencies: "calc_multiply_button", + Category: "Enhancements", Description: "You can multiply, but what about reversing multiplication? This divide button will sort that out!" }, { Name: "Calc Clear Button", Cost: 750, Dependencies: "calc_equals_button", + Category: "Enhancements", Description: "Typed the wrong number? No worries! With this Clear button, you can clear the number field, without messing up the equation you're trying to solve!" }, { Name: "Calc CE Button", Cost: 750, Dependencies: "calc_clear_button", + Category: "Enhancements", Description: "Wanna start all over with a new equation? With this CE (Clear Everything) button, you get rid of not only the numbers in the number field, but also the equation!" }, { Name: "MUD Fundamentals", Cost: 50, Description: "Some basic commands for the terminal that'll help you out in the multi-user domain.", + Category: "Kernel & System", Dependencies: null }, { Name: "AL Notifications", Cost: 150, Dependencies: "app_launcher", + Category: "GUI", Description: "Want to open the Notifications application from within the App Launcher? This upgrade is for you." }, @@ -93,35 +107,41 @@ Name: "ShiftLetters", Cost: 150, Dependencies: null, + Category: "Applications", Description: "Sick and tired of playing Pong? Buy this upgrade to get a whole new game!" }, { Name: "AL ShiftLetters", Cost: 150, Dependencies: "app_launcher;shiftletters", + Category: "GUI", Description: "This upgrade allows you to find ShiftLetters in your App Launcher." }, { Name: "SL Contributors Wordlist", Cost: 250, Dependencies: "shiftletters", + Category: "Enhancements", Description: "This nice wordlist lets you find out the people who contributed to the development of ShiftOS!" }, { Name: "SL Operating Systems Wordlist", Cost: 500, Dependencies: "shiftletters", + Category: "Enhancements", Description: "Know a lot about computer operating systems? This upgrade adds a wordlist to ShiftLetters, full of various Linux distros, Windows codenames and other OS names. All for the low price of 500 Codepoints! It's an incredible value but it's true! Upgrade today... except out of ShiftOS!" }, { Name: "Panel Notifications", Cost: 150, Description: "It's good to know what time it is, but how about knowing how many notifications you have? After all, notifications are a great way to tell what's going on! This upgrade adds a button that displays how many notifications you have. If you click it, you will open the Notifications app!", + Category: "GUI", Dependencies: "desktop_clock_widget" }, { Name: "Audio Volume", Cost: 80, + Category: "Kernel & System", Description: "Want to adjust the volume of ShiftOS's audio? This upgrade will let you." }, @@ -130,12 +150,14 @@ Name: "ShiftLotto", Cost: 200, Dependencies: null, + Category: "Applications", Description: "Are you feeling lucky? Spend some money on this upgrade! If you have any left, go ahead and bet your money in ShiftLotto!" }, { Name: "AL ShiftLotto", Cost: 150, Dependencies: "app_launcher;shiftlotto", + Category: "GUI", Description: "This upgrade allows you to find ShiftLotto in your App Launcher." }, @@ -144,370 +166,418 @@ { Name: "Color Depth Dithering", Cost: 1000, + Category: "Device Drivers", Description: "Right now, if you try to display images on the screen, with a low color depth like we have, the image will be totally unrecognizable! With this upgrade, we can adapt a simple 1-dimensional dithering algorithm into the video driver to hopefully smooth out the transition between colors.", }, { Name: "Color Depth Floyd-Steinberg Dithering", Cost: 2000, Description: "So your images look... alright... with the new dithering algorithm, but let's take things even further and get rid of the jagged lines in the image using a 2-dimensional algorithm called the Floyd-Steinberg algorithm. It'll sure make things look better.", + Category: "Device Drivers", Dependencies: "color_depth_dithering" }, { Name: "Color Depth 2 bits", Cost: 2000, + Category: "Device Drivers", Description: "We can only display black and white - 0 or 1 in binary. Let's take it even further by adding an extra bit to our binary notation - making black, white, dark gray and light gray possible!", }, { Name: "Color Depth 4 bits", Cost: 4000, Description: "4 colors is nice - but let's take it even further. With our dithering algorithm in place, let's make our images even smoother by giving a 16-color palette to the video driver!", + Category: "Device Drivers", Dependencies: "color_depth_2_bits;color_depth_dithering" }, { Name: "Color Depth 6 bits", Cost: 6000, Description: "Let's extend our color range into the depths of 6 bits! This'll make up to 64 different shades of gray possible! We're getting even closer to modern-day color...", + Category: "Device Drivers", Dependencies: "color_depth_4_bits" }, { Name: "Color Depth 8 bits", Cost: 8000, Description: "What do you get when you bite your food? You get perhaps a yummy taste. What do you get when you take a byte of memory? 256 shades of gray, of course!", + Category: "Device Drivers", Dependencies: "color_depth_6_bits" }, { Name: "Color Depth 16 bits", Cost: 16000, Description: "If we were just given another byte... we could divide the two up into three channels and allow mixing and matching of the channels to create colors other than gray! Let's do it.", + Category: "Device Drivers", Dependencies: "color_depth_8_bits" }, { Name: "Color Depth 24 Bits", Cost: 24000, Description: "Having actual color is nice for our images as we can truly see detail in our images - but if we had a third byte, each channel could have up to 256 values - adding up to almost 17 million different colors! Our eyes can't even distinguish that many.", + Category: "Device Drivers", Dependencies: "color_depth_16_bits" }, { Name: "AL MUD Control Centre", Cost: 150, Dependencies: "mud_fundamentals;app_launcher", + Category: "Device Drivers", Description: "Want to access your MUD profile, legions, jobs and shops, but don't want to open your Terminal? This upgrade is for you!" }, { Name: "Kernel Coherence", Cost: 10000, Dependencies: "wm_free_placement", + Category: "Device Drivers", Description: "With the free placement upgrade, you can place windows of any size anywhere on the desktop, which means theoretically you could add kernel coherence between ShiftOS and another GUI-based operating system and run their applications inside ShiftOS. This upgrade unlocks that.", }, { Name: "Pong Increased Paddle Size", Cost: 1000, Dependencies: "pong_upgrade", + Category: "Enhancements", Description: "Having trouble keeping that darn ball in front of you? Well, with this upgrade, your paddle increases in height.... slightly.", }, { Name: "WM 4 Windows", Cost: 150, Description: "Display up to 4 simultaneous windows on-screen in a 2x2 grid.", + Category: "Enhancements", Dependencies: "window_manager" }, { Name: "Virus Scanner", Cost: 2000, Description: "Being inside the multi-user domain comes with many risks, one of which being viruses. The Virus Scanner can mitigate this threat by allowing you to scan the files on your system for any viruses and delete them for you.", + Category: "Applications", Dependencies: "mud_fundamentals;file_skimmer" }, { Name: "AL Virus Scanner", Cost: 150, Description: "Add an App Launcher entry for the Virus Scanner.", + Category: "GUI", Dependencies: "virus_scanner;app_launcher" }, { Name: "WM Panel Buttons", Cost: 200, Description: "Sometimes it's useful to have a list of windows that are open on your system so you can easily switch between them.", + Category: "GUI", Dependencies: "desktop;wm_unlimited_windows" }, { Name: "AL Skin Loader", Cost: 150, Description: "Buy this upgrade to add an entry for the Skin Loader to the App Launcher.", + Category: "GUI", Dependencies: "app_launcher;skinning" }, { Name: "Shift Panel Buttons", Cost: 150, Description: "Want to customize your panel buttons? This Shifter category is for you!", + Category: "Customization", Dependencies: "wm_panel_buttons" }, { Name: "TextPad Lua Support", Cost: 450, Description: "Use TextPad to write Lua scripts!", + Category: "Enhancements", Dependencies: "textpad;file_skimmer", }, { Name: "App Launcher", Cost: 7500, Description: "It may be expensive, but having an easy-access menu to all your apps is very valuable.", + Category: "GUI", Dependencies:"desktop;wm_unlimited_windows" }, { - Name: "MUD Cracker", - Cost: 500, - Description: "An application for cracking the current multi-user domain's admin password.", - Dependencies: "mud_fundamentals" - }, - { - Name: "AL MUD Cracker", - Cost: 150, - Description: "Add a launcher item for the MUD cracker.", - Dependencies: "mud_cracker;app_launcher" - }, - { Name: "Format Editor", Cost: 6000, Description: "Allows you to change the format of commands.", + Category: "Applications", Dependencies: "shifter;name_changer" }, { Name: "Format Editor Optional Text", Cost: 150, Description: "Allows you to add an optional text to commands", + Category: "Enhancements", Dependencies: "format_editor" }, { Name: "Format Editor Regex", Cost: 150, Description: "Allows you to customize your commands with regexes.", + Category: "Enhancements", Dependencies: "format_editor_optional_text" }, { Name: "Format Editor Syntax Highligting", Cost: 150, Description: "Allows you to give color to commands as the user types them.", + Category: "Enhancements", Dependencies: "format_editor_regex" }, { Name: "AL Format Editor", Cost: 150, Description: "Add a launcher item for the Format Editor.", + Category: "GUI", Dependencies: "format_editor;app_launcher" }, { Name: "Textpad", Cost: 2500, Description: "\"Write, save and open a text document.\"", + Category: "Applications", Dependencies: "file_skimmer" }, { Name: "Shifter", Cost: 10000, Description: "Tired of the green and black look that is ShiftOS's default skin? Use the Shifter to shift it your way.", + Category: "Applications", Dependencies: "desktop;wm_unlimited_windows", }, { Name: "Name Changer", Cost: 5000, Description: "Are you not a linux person and want the terminal to be called Command Prompt? Well this app is for you!", + Category: "Applications", Dependencies: "shifter", }, { Name: "AL Name Changer", Cost: 150, Description: "Launch the Name Changer from the app launcher.", + Category: "GUI", Dependencies: "name_changer", }, { Name: "AL Shifter", Cost: 150, Description: "Launch the Shifter from the app launcher.", + Category: "GUI", Dependencies: "app_launcher;shifter" }, { Name: "AL Pong", Cost: 150, Description: "Launch Pong from the app launcher.", + Category: "GUI", Dependencies: "app_launcher" }, { Name: "AL Textpad", Cost: 150, Description: "Write, save and open text documents from the App Launcher.", + Category: "GUI", Dependencies:"app_launcher;textpad" }, { Name: "AL File Skimmer", Cost: 150, Description: "Open the File Skimmer from your App Launcher.", + Category: "GUI", Dependencies:"app_launcher;file_skimmer" }, { Name: "WM Free Placement", Cost: 2000, Description: "Disable the grid system and allow windows to be freely positioned, moved, and overlapped.", + Category: "Enhancements", Dependencies: "wm_4_windows" }, { Name: "Desktop", Cost: 9000, Description: "Use a fully customizable desktop in place of the terminal to control ShiftOS.", + Category: "GUI", Dependencies: "window_manager" }, { Name: "App Icons", Cost: 400, Description: "So you have a titlebar, well, let's add an icon to it to hopefully make it easier to tell which app is which.", + Category: "GUI", Dependencies: "wm_titlebar;skinning" }, { Name: "Close command", Cost: 150, Description: "Add a win.close script to allow you to close windows.", + Category: "Kernel & System", Dependencies: "mud_fundamentals", }, { Name: "WM Unlimited Windows", Cost: 5000, Description: "Break the limit of windows that can be run. Perfect for high-maintenance tasks.", + Category: "Enhancements", Dependencies: "wm_free_placement;close_command" }, { Name: "Minimize Command", Cost: 1250, Description: "Use the win.mini{id} command to minimize/restore windows.", + Category: "Kernel & System", Dependencies: "useful_panel_buttons" }, { Name: "Useful Panel Buttons", Cost: 250, Description: "Minimize and restore windows by clicking their Panel Button!", - Dependencies: "desktop" + Category: "Enhancements", + Dependencies: "desktop;wm_panel_buttons" }, { Name: "Maximize Command", Cost: 1250, Description: "Use the win.max{id} command to maximize windows.", + Category: "Kernel & System", Dependencies: "wm_titlebar;desktop;wm_free_placement" }, { Name: "Close Button", Cost: 1000, Description: "Add a close button to the titlebar to easily close applications.", + Category: "GUI", Dependencies: "wm_titlebar;close_command" }, { Name: "Minimize Button", Cost: 1000, Description: "Minimize windows using a button on the titlebar", + Category: "GUI", Dependencies: "wm_titlebar;minimize_command" }, { Name: "Shiftorium Bulk Buy", Cost: 2000, + Category: "Enhancements", Description:"Tired of typing shiftorium.buy{} all the time? This upgrade will add a bulk buy command which allows you to specify a comma-separated list of upgrades to buy." }, { + Name: "Shiftorium GUI Bulk Buy", + Cost: 3000, + Category: "GUI", + Description: "Tired of the repetition of selecting an upgrade and hitting \"Buy\" a hundred times when binging? Using the bulkbuy command, we can make the Shiftorium GUI allow you to buy in bulk!", + Dependencies: "shiftorium_gui;shiftorium_bulk_buy" + }, + { Name: "File Skimmer", Cost: 500, Description: "View the files on your computer using File Skimmer.", + Category: "Applications", Dependencies: null }, { Name: "Maximize Button", Cost: 500, Description: "Maximize windows using a button on the titlebar", + Category: "GUI", Dependencies: "wm_titlebar;maximize_command" }, { Name: "Clock", Cost: 100, Description: "Adds a script that shows the amount of seconds that have passed since Midnight. Use 'sys.clock' to activate it.", + Category: "Applications", Dependencies: "mud_fundamentals" }, { Name: "WM Titlebar", Cost: 250, Description: "Display a title on each window.", + Category: "GUI", Dependencies: "window_manager" }, { Name: "Clock Minutes", Cost: 250, Description: "Upgrade the sys.clock command to show minutes since midnight with a {type:\"m\"} argument.", + Category: "Enhancements", Dependencies: "clock" }, { Name: "Clock Hours", Cost: 225, Description: "Upgrade the sys.clock command to show hours since midnight with a {type:\"h\"} argument.", + Category: "Enhancements", Dependencies: "clock_minutes" }, { Name: "Clock AM and PM", Cost: 75, Description: "Change the clock to be 12-hour based, showing whether the current time is ante-meridiem or post-meridiem.", + Category: "Enhancements", Dependencies: "clock_hours", }, { Name: "Full Precision Time", Cost: 500, Description: "Show full-precision time by default when using sys.clock.", + Category: "Enhancements", Dependencies: "clock_am_and_pm" }, { Name: "Desktop Clock Widget", Cost: 1000, Description: "Add a widget to the desktop which shows the results of sys.clock as text on the desktop.", + Category: "GUI", Dependencies: "clock;desktop" }, { - Name: "AL MUD Chat", - Cost: 150, - Description: "Adds an app launcher entry for the MUD chat application.", - Dependencies: "mud_fundamentals;app_launcher" - }, - { Name: "App Launcher Categories", Cost: 1000, Dependencies: "app_launcher", + Category: "Enhancements", Description: "Is your App Launcher getting full of items? Perhaps a little too full? Are you having trouble finding things? This upgrade should help - it'll sort all App Launcher items into categories for you." }, { Name: "Draggable windows", Cost: 400, Description: "Allows you to drag windows around with the mouse using the title bar.", + Category: "Enhancements", Dependencies: "wm_titlebar;wm_free_placement" }, { Name: "Window Manager", Cost: 100, Description: "Allows you to run two windows simultaneously within ShiftOS.", + Category: "Kernel & System", Dependencies: "mud_fundamentals" }, { Name: "Pong Upgrade", Cost: 4000, Description: "This upgrade makes pong double the codepoints you get from it so you can spend less time grinding!", + Category: "Enhancements", Dependencies: "mud_fundamentals;window_manager" }, { Name: "Pong Upgrade 2", Cost: 8000, Description: "So you lost in pong, it must be sad to lose all the codepoints you've gained. With this upgrade you can save 1 percent of the loss, so at least you get something for losing!", + Category: "Enhancements", Dependencies: "mud_fundamentals;window_manager;pong_upgrade" }, { Name: "Audio Player", Cost: 10000, Description: "Want to listen to the greatest tunes? Well get this app asap!", + Category: "Applications", Dependencies: "desktop;wm_free_placement" }, { Name: "Audio Player AL", Cost: 150, Description: "Just another app launcher, making it easier to listen to your favorite songs!", + Category: "GUI", Dependencies: "desktop;wm_free_placement;audio_player" }, @@ -517,42 +587,49 @@ Name: "Shift Titlebar", Cost: 200, Description: "Customize the Titlebar within the Shifter.", + Category: "Customization", Dependencies: "shifter;wm_titlebar" }, { Name: "Shift Title Text", Cost: 200, Description: "Title text looking boring? This upgrade lets you customize the font, color, and position of the Title Text.", + Category: "Customization", Dependencies: "shift_titlebar" }, { Name: "Shift Window Borders", Cost: 200, Description: "Want to customize the look of the ShiftOS window borders? Buy this upgrade and you can customize the color and thickness of the borders.", + Category: "Customization", Dependencies: "shifter" }, { Name: "Shift Desktop Panel", Cost: 200, Description: "Not liking your desktop panel the way it is? Buy this upgrade to allow you to change the color, height, and position of the desktop panel.", + Category: "Customization", Dependencies: "shifter;desktop" }, { Name: "Shift App Launcher", Cost: 200, Description: "You've made your desktop panel look very nice, but your app launcher looks kinda out of place. This upgrade will fix that, allowing you to change the position, size, and appearance of the app launcher button.", + Category: "Customization", Dependencies: "shift_desktop_panel;app_launcher" }, { Name: "Shift Panel Clock", Cost: 200, Dependencies: "shift_desktop_panel;desktop_clock_widget", + Category: "Customization", Description: "That clock is very simple - let's shift it! This upgrade allows you to customize the font and color of the panel clock." }, { Name: "Shift Title Buttons", Cost: 200, Dependencies: "close_button;minimize_button;maximize_button;shift_titlebar", + Category: "Customization", Description: "Those title buttons look very similar and primitive - with this upgrade you can change the size, position, and color of each button." }, @@ -562,6 +639,7 @@ Name: "Skinning", Cost: 10000, Description: "It may be expensive, but with this upgrade, you can break the limitations of using just solid colors and gradients for your skin and start using images!", + Category: "Customization", Dependencies: "shifter" }, @@ -570,12 +648,14 @@ { Name: "Artpad", Cost: 7500, + Category: "Applications", Description: "ArtPad is a very extensible tool that allows you to draw images within ShiftOS. Buy this upgrade to gain access to it through win.open{}!" }, { Name: "AL Artpad", Cost: 150, Description: "Add an App Launcher Entry for Artpad!", + Category: "GUI", Dependencies: "artpad;app_launcher" }, @@ -588,60 +668,70 @@ Name: "Artpad Pixel Limit 4", Cost: 100, Dependencies: "artpad", + Category: "Enhancements", Description: "Having ArtPad is great, but there's not much you can draw with only 2 pixels. Buy this upgrade to increase the breathing room your imagination can have." }, { Name: "Artpad Pixel Limit 8", Cost: 150, Dependencies: "artpad_pixel_limit_4", + Category: "Enhancements", Description: "With a 4 pixel limit, you can do some simple patterns and such, but it's still not great. Buy this upgrade to double the pixel limit and add even more possibilities!" }, { Name: "Artpad Pixel Limit 16", Cost: 200, Dependencies:"artpad_pixel_limit_8", + Category: "Enhancements", Description: "Now we can have 8-pixel images, but we still can't do much more than simple patterns and icons. Use this upgrade to double the max image size yet again and allow even more images!" }, { Name: "Artpad Pixel Limit 64", Cost: 600, Dependencies: "artpad_pixel_limit_16", + Category: "Enhancements", Description: "Alright. Now it's time to kick it into high-gear. Patterns and icons are fun, but let's increase the image size even more to allow higher-detail icons/patterns and small sprites!" }, { Name: "Artpad Pixel Limit 256", Cost: 1000, Dependencies: "artpad_pixel_limit_64", + Category: "Enhancements", Description: "We can create high resolution icons and patterns, but we still can't really do too much more than that. Buy this upgrade and you'll be able to have up to 256 pixels in an image!" }, { Name: "Artpad Pixel Limit 1024", Cost: 1250, Dependencies: "artpad_pixel_limit_256", + Category: "Enhancements", Description: "Let's make things even higher quality! With this upgrade, we'll be able to increase the image size by 4 times! ArtPad is really starting to advance." }, { Name: "Artpad Pixel Limit 4096", Cost: 2600, Dependencies: "artpad_pixel_limit_1024", + Category: "Enhancements", Description: "Now we can do 1024-pixel images, but how about increasing the limit by 4 times yet again? That'll leave even more room for imagination and drawings!" }, { Name: "Artpad Pixel Limit 16384", Cost: 4800, Dependencies: "artpad_pixel_limit_4096", + Category: "Enhancements", Description: "We're ever-so-slightly approaching limitless possibilities. With this upgrade, images in ArtPad will be able to have up to 16384 pixels. We can make desktop backgrounds for small monitors!" }, { Name: "Artpad Pixel Limit 65536", Cost: 7000, Dependencies: "artpad_pixel_limit_16384", + Category: "Enhancements", Description: "Wow! This might be the last time we'll have to deal with pixel limits. It's amazing how far we've came since 2-pixel gradients. Now let's go even further." }, { Name: "Artpad Limitless Pixels", Cost: 12000, Dependencies: "artpad_pixel_limit_65536", + Category: "Enhancements", Description: "We have a pretty high pixel limit, but with this upgrade, pixel limits are no more! With limitless pixels comes limitless creativity. Have fun!" }, @@ -649,6 +739,7 @@ Name: "AL Shutdown", Cost: 300, Dependencies: "app_launcher", + Category: "GUI", Description: "Want to shut down ShiftOS from your app launcher? This is the perfect upgrade for you." }, @@ -657,12 +748,14 @@ Id: "help_description", Cost: 150, Dependencies: "", + Category: "Enhancements", Description: "Dont understand what some commands do in the terminal? With this upgrade, it adds a handy little description to almost every command when you run the command sos.help!" }, { Name: "Help Usage", Cost: 150, Dependencies: "help_description", + Category: "Enhancements", Description: "You got descriptions on what some commands do in the terminal, but wouldn't it be handy to also see what the proper usage is for? Now you can with this upgrade!" }, @@ -671,65 +764,76 @@ Name: "Artpad Pixel Placer", Dependencies: "artpad", Cost: 750, + Category: "Enhancements", Description: "This tool extends the Pixel Setter to allow you to use your mouse to place pixels by clicking on the canvas." }, { Name: "Artpad PP Movement Mode", Dependencies: "artpad_pixel_placer", Cost: 500, + Category: "Enhancements", Description: "This tool extends the Pixel Placer and allows you to drag your mouse while the button is held down to draw pixels on the canvas." }, { Name: "Artpad Pencil", Dependencies: "artpad_pp_movement_mode", Cost: 1000, + Category: "Enhancements", Description: "Using the power of the Pixel Placer's movement mode, the Pencil can draw strokes of different thicknesses. Most tools will extend this tool." }, { Name: "Artpad Paintbrush", Cost: 1000, Dependencies: "artpad_pencil", + Category: "Enhancements", Description: "The Paintbrush allows you to draw more thick strokes on the canvas than the Pencil does." }, { Name: "Artpad Eraser", Cost: 500, Dependencies: "artpad_paintbrush;artpad_undo", + Category: "Enhancements", Description: "Undo not effective? Want to only erase a select bit of the canvas? Use this tool to get an eraser!" }, { Name: "Artpad Load", Cost: 350, Dependencies: "artpad;file_skimmer", + Category: "Enhancements", Description: "Want to start off from an existing masterpiece? This tool is for you. Select any .pic file and it'll be loaded onto the canvas!" }, { Name: "Artpad Line Tool", Cost: 800, Dependencies: "artpad_pp_movement_mode", + Category: "Enhancements", Description: "Using the power of linear interpolation and the Pixel Placer Movement Mode, the Line tool can help you draw straight lines from one point to another." }, { Name: "Artpad Rectangle Tool", Cost: 400, Dependencies: "artpad_line_tool", + Category: "Enhancements", Description: "With the line tool we are able to figure out the distance from point A to point B. Let's use that basic framework to draw rectangles!" }, { Name: "Artpad Oval Tool", Cost: 401, Dependencies: "artpad_line_tool", + Category: "Enhancements", Description: "Want to draw some ovals? With this tool, you can! It uses the data from the line tool to construct a circle as you drag the mouse." }, { Name: "Artpad Fill Tool", Cost: 1000, Dependencies: "artpad_pixel_placer", + Category: "Enhancements", Description: "The Pixel Placer is useful because we can grab pixel coordinates from the mouse, and determine how we can fill the area with a certain color - let's do that!" }, { Name: "Artpad Text Tool", Cost: 1500, + Category: "Enhancements", Dependencies: "artpad_pixel_placer", Description: "Want to place text on your canvas? Use the Text Tool to do so!" }, @@ -737,30 +841,35 @@ Name: "Artpad New", Dependencies: "artpad", Cost: 500, + Category: "Enhancements", Description: "Made a mistake? Want a blank canvas? This tool gives you just that." }, { Name: "Artpad Open", Dependencies: "artpad;file_skimmer", Cost: 600, + Category: "Enhancements", Description: "Want to edit an artpad picture? If you have the File Skimmer, then this tool is for you!" }, { Name: "Artpad Save", Dependencies: "artpad;file_skimmer", Cost: 1000, + Category: "Enhancements", Description: "Have you been working extra-hard on a masterpiece in ArtPad and want to save? This upgrade is a must-have!" }, { Name: "Artpad Undo", Dependencies: "artpad_new", Cost: 59, + Category: "Enhancements", Description: "Mistakes happen - but if you have to clear the canvas every time you mess up one single pixel it can get annoying. This tool will help mitigate that - you'll be able to make your last change magically disappear!" }, { Name: "Artpad Redo", Dependencies: "artpad_undo", Cost: 50, + Category: "Enhancements", Description: "Did you change your mind about that mistake you've undone? Want it back? This tool is for you. Note that the second you add something new after an undo, the undone change is wiped forever!" }, @@ -772,36 +881,42 @@ Name: "Artpad 4 Color Palettes", Dependencies: "artpad", Cost: 150, + Category: "Enhancements", Description: "Want to add an extra 2 colors to your palette? Buy this upgrade to do so!" }, { Name: "Artpad 8 Color Palettes", Dependencies: "artpad_4_color_palettes", Cost: 400, + Category: "Enhancements", Description: "Want to add an extra 4 color palette entries to your Artpad to have even more colors used at once? Buy this upgrade, and that will happen!" }, { Name: "Artpad 16 Color Palettes", Dependencies: "artpad_8_color_palettes", Cost: 600, + Category: "Enhancements", Description: "With this upgrade, you can have up to 16 different colors in your ArtPad palette. Good for drawing intense scenes without constantly selecting different colors." }, { Name: "Artpad 32 Color Palettes", Dependencies: "artpad_16_color_palettes", Cost: 850, + Category: "Enhancements", Description: "Having 16 different color palettes is nice, but you know what's nicer? Having 32!" }, { Name: "Artpad 64 Color Palettes", Dependencies: "artpad_32_color_palettes", Cost: 1700, + Category: "Enhancements", Description: "Well then. We have 32 color palettes - let's double that." }, { Name: "Artpad 128 Color Palettes", Dependencies: "artpad_128_color_palettes", Cost: 3400, + Category: "Enhancements", Description: "With this upgrade we'll be able to have 128 simultaneous colors in our palette. It may get a bit glitchy though... maybe a window manager upgrade could help?" }, @@ -812,18 +927,21 @@ { Name: "Shiftorium GUI", Cost: 100, + Category: "Applications", Description: "You may spend lots of time in your terminal - executing scripts, chatting, etc, but why make it so difficult and repetitive to upgrade your system? With this upgrade, a GUI will be added to the Shiftorium, and will be accessible using win.open{app:\"shiftorium\"}." }, { Name: "AL Shiftorium", Cost: 150, Dependencies: "shiftorium_gui;app_launcher", + Category: "GUI", Description: "Add an App Launcher Entry for the Shiftorium!" }, { Name: "Shiftorium GUI Codepoints Display", Cost: 2500, Dependencies: "shiftorium_gui", + Category: "Enhancements", Description: "In the shiftorium GUI but dont know what you can spend because you can't see how many code points are on hand? Well shop easy, because with this upgrade that is now possible! You have to restart the shiftorium for it to work." }, @@ -833,24 +951,28 @@ Name: "ShiftSweeper", Cost: 800, Dependencies: "shiftletters", + Category: "Applications", Description: "Getting bored with Pong and ShiftLetters? Try this BRAND NEW game called ShiftSweeper!" }, { Name: "AL ShiftSweeper", Cost: 100, Dependencies: "app_launcher;shiftsweeper", + Category: "GUI", Description: "Play ShiftSweeper quickly with this dandy applauncher!" }, { Name: "ShiftSweeper Medium", Cost: 900, Dependencies: "shiftsweeper", + Category: "Enhancements", Description: "ShiftSweeper getting too easy? Obviously, since you can only play Easy difficulty! However, with this Medium button, you can get a better challenge, and more codepoints!" }, { Name: "ShiftSweeper Hard", Cost: 900, Dependencies: "shiftsweeper_medium", + Category: "Enhancements", Description: "Is ShiftSweeper still too easy for you? Buy the Hard difficulty and you can try to find 99 mines! It may be extremely difficult, but the reward is massive!" } ]
\ No newline at end of file diff --git a/ShiftOS.WinForms/Resources/languages.txt b/ShiftOS.WinForms/Resources/languages.txt index ca34308..a452137 100644 --- a/ShiftOS.WinForms/Resources/languages.txt +++ b/ShiftOS.WinForms/Resources/languages.txt @@ -1,4 +1,4 @@ [ "english" - "deutsch - in beta" + "deutsch" ]
\ No newline at end of file diff --git a/ShiftOS.WinForms/Resources/strings_de.txt b/ShiftOS.WinForms/Resources/strings_de.txt index 5661c45..139ed69 100644 --- a/ShiftOS.WinForms/Resources/strings_de.txt +++ b/ShiftOS.WinForms/Resources/strings_de.txt @@ -48,7 +48,7 @@ Wenn eine Systemdatei von dem Virenscanner erkannt wird, wird sie ersetzt.", "{UPGRADES}":"Upgrades", "{APPLICATION}":"Anwendung", "{SCRIPT}":"Skript", - "{ERROR}":"Error", + "{ERROR}":"Fehler", "{SCRIPTS}":"Skripts", "{NULL}":"null", "{ID}":"ID Num", @@ -96,32 +96,32 @@ Wenn eine Systemdatei von dem Virenscanner erkannt wird, wird sie ersetzt.", "{CLIENT_DIAGNOSTICS}":"Client diagnostics", "{GUID}":"GUID", "{CLIENT_DATA}":"Client data", - "{CLOSE}":"Close", + "{CLOSE}":"Schlie�en", "{LOAD_DEFAULT}":"Load default", - "{IMPORT}":"Import", + "{IMPORT}":"Einf�hren", "{EXPORT}":"Export", "{APPLY}":"Apply", - "{TEMPLATE}":"Template", + "{TEMPLATE}":"Vorlage", "{H_VEL}":"Horizontal velocity", "{V_VEL}":"Vertical velocity", - "{LEVEL}":"Level", + "{LEVEL}":"Ebene", "{UPGRADE_DEVELOPMENT}":"Development Upgrade", "{UPGRADE_DEVELOPMENT_DESCRIPTION}":"Development Upgrade Don't Buy", - "{SECONDS_LEFT}":"seconds left", + "{SECONDS_LEFT}":"sekunden �brig", "{CASH_OUT_WITH_CODEPOINTS}":"Cash out with your codepoints", - "{PONG_PLAY_ON_FOR_MORE}":"Play on for more!", + "{PONG_PLAY_ON_FOR_MORE}":"Spiel f�r mehr!", "{YOU_REACHED_LEVEL}":"You've reached level", "{PONG_BEAT_AI_REWARD}":"Reward for beating AI (CP)", "{PONG_BEAT_AI_REWARD_SECONDARY}":"Codepoints for beating AI:", "{CODEPOINTS_FOR_BEATING_LEVEL}":"Codepoints for beating level", - "{YOU_WON}":"You won", - "{YOU_LOSE}":"You lose", + "{YOU_WON}":"Du gewinnst", + "{YOU_LOSE}":"Du verlierst", "{TRY_AGAIN}":"Try again", "{CODEPOINTS_SHORT}":"CP", "{TERMINAL_FORMATTING_DRIVE}":"Formatting drive... %percent %", "{INSTALLING_SHIFTOS}":"Installing ShiftOS on %domain.", "{YOU_MISSED_OUT_ON}":"You missed out on", - "{BUT_YOU_GAINED}":"But you gained", + "{BUT_YOU_GAINED}":"Aber du hast gewonnen", "{PONG_PLAYON_DESC}":"Or do you want to try your luck on the next level to increase your reward?", "{PONG_CASHOUT_DESC}":"Would you like the end the game now and cash out with your reward?", "{INITIAL_H_VEL}":"Initial H Vel", @@ -131,14 +131,14 @@ Wenn eine Systemdatei von dem Virenscanner erkannt wird, wird sie ersetzt.", "{MULTIPLAYER_ONLY}":"Program not compatible with single-user domain.", "{MULTIPLAYER_ONLY_EXP}":"This program cannot run within a single-user domain. You must be within a multi-user domain to use this program.", "{SHIFTER_SKIN_APPLIED}":"Shifter - Settings applied!", - "{YOU_HAVE_EARNED}":"You have earned", + "{YOU_HAVE_EARNED}":"Du hast bekommen", "{CREATING_PATH}":"Creating directory: %path", "{CREATING_FILE}":"Creating file: %path", "{SHIFTORIUM_HELP_DESCRIPTION}": "Help Descriptions", "{CREATING_USER}":"Creating user %username", "{SEPERATOR}":" - ", "{NAMESPACE}":"Namespace ", - "{COMMAND}": "| Command ", + "{COMMAND}": "| Befehl ", "{SHIFTOS_HAS_BEEN_INSTALLED}":"ShiftOS has been installed on %domain.", "{WARN}": "WARN: ", "{ERROR}": "!ERROR! ", @@ -150,15 +150,17 @@ Wenn eine Systemdatei von dem Virenscanner erkannt wird, wird sie ersetzt.", "{ERROR_COMMAND_WRONG}": "Check your syntax and try again", "{LOGIN_EXP}": "Login as the admin of the multi user domain.", - "{USAGE}": "Usage: ", + "{USAGE}": "Verwendung: ", "{NAMESPACE_SOS_DESCRIPTION}":"The ShiftOS Namespace", "{COMMAND_HELP_USAGE}":"%ns.%cmd{[topic:]}", - "{COMMAND_HELP_DESCRIPTION}":"Lists all commands", + "{COMMAND_HELP_DESCRIPTION}":"Listet alle Befehle auf", "{COMMAND_SOS_SHUTDOWN_USAGE}":"%ns.%cmd", "{COMMAND_SOS_SHUTDOWN_DESCRIPTION}":"Saves and shuts down ShiftOS", "{COMMAND_SOS_STATUS_USAGE}":"%ns.%cmd", "{COMMAND_SOS_STATUS_DESCRIPTION}":"Displays how many codepoints you have", + "{COMMAND_SOS_LANG_USAGE}":"%ns.%cmd{[language:\"english\"]}", + "{COMMAND_SOS_LANG_DESCRIPTION}":"Sprache �ndern.", "{COMMAND_DEV_CRASH_USAGE}":"%ns.%cmd", "{COMMAND_DEV_CRASH_DESCRIPTION}":"Shuts down ShiftOS forcefully", "{COMMAND_DEV_UNLOCKEVERYTHING_USAGE}":"%ns.%cmd", @@ -176,7 +178,7 @@ Wenn eine Systemdatei von dem Virenscanner erkannt wird, wird sie ersetzt.", "{COMMAND_DEV_MULTARG_USAGE}":"%ns.%cmd{id:,name:,type:}", "{COMMAND_DEV_MULTARG_DESCRIPTION}":"A command which requiers multiple arguments", - "{ERR_COMMAND_NOT_FOUND}":"Command not found.", + "{ERR_COMMAND_NOT_FOUND}":"Befehl nicht gefunden.", "{MUD_ERROR}":"MUD error", "{PROLOGUE_NO_USER_DETECTED}":"No user detected. Please enter a username.", @@ -199,24 +201,25 @@ Wenn eine Systemdatei von dem Virenscanner erkannt wird, wird sie ersetzt.", "{SENTIENCE_POSSIBLEHUMAN}":"Sentience: Possible human - user can perform actions based on a choice.", "{SENTIENCE_POSSIBLEHUMANPLUS}":"Sentience: Possible human+ - user can infer, and can pass arguments.", "{SENTIENCE_HUMAN}":"Sentience: Human. Thanks for your patience.", - "{SENTIENCE_INVALIDPASSWORD}":"The password you entered is invalid.", + "{SENTIENCE_INVALIDPASSWORD}":"Das eingegebene Passwort ist ung�ltig.", "{ARGS_PASSWORD}":"password", "{SHIFTOS_PLUS_MOTTO}":"ShiftOS, Shift it YOUR way.", "{SHIFTOS_VERSION_INFO}":"ShiftOS Version: ", - "{USER_NAME}":"Username", + "{USER_NAME}":"Benutzername", "{DISCOURSE_INTEGRATION}":"Discourse Integration", "{SYSTEM_NAME}":"System Name", "{USER_INFO}":"User Information", "{SELECT_LANG}":"Select language", "{WELCOME_TO_SHIFTOS}":"Welcome to ShiftOS Alpha!", - "{CREATE}":"Create", - "{INSTALL}":"Install", + "{CREATE}":"Erstellen", + "{INSTALL}":"Installieren", "{ALIAS}":"Alias:", "{OBSOLETE_SYS_SHUTDOWN}":"sys.shutdown is obsolete", "{PY_EXCEPTION}":"There was an error running python code.", "{LUA_ERROR}":"There was an error running lua code.", + "{LANGUAGE_CHANGED}":"Die Sprache wurde ge�ndert. Bitte �ndern Sie ShiftOS neu, damit �nderungen voll wirksam werden.", "{TERMINAL_NAME}":"Terminal", "{ARTPAD_NAME}":"Artpad", @@ -237,4 +240,6 @@ Wenn eine Systemdatei von dem Virenscanner erkannt wird, wird sie ersetzt.", "{DIALOG_NAME}":"Dialog", "{COLOR_PICKER_NAME}":"Color Picker", "{CHAT_NAME}":"Chat", + "{NOTIFICATIONS}":"Benachrichtigungen", + "{GERMAN_SECRET}":"guten tag polen ist anschluss", }
\ No newline at end of file diff --git a/ShiftOS.WinForms/Resources/strings_en.txt b/ShiftOS.WinForms/Resources/strings_en.txt index 54c9b54..f63f0e0 100644 --- a/ShiftOS.WinForms/Resources/strings_en.txt +++ b/ShiftOS.WinForms/Resources/strings_en.txt @@ -158,12 +158,14 @@ If a system file is deleted by the virus scanner, it will be replaced.", "{COMMAND_SOS_SHUTDOWN_DESCRIPTION}":"Saves and shuts down ShiftOS", "{COMMAND_SOS_STATUS_USAGE}":"%ns.%cmd", "{COMMAND_SOS_STATUS_DESCRIPTION}":"Displays how many codepoints you have", + "{COMMAND_SOS_LANG_USAGE}":"%ns.%cmd{language:\"deutsch\"}", + "{COMMAND_SOS_LANG_DESCRIPTION}":"Change the language.", "{COMMAND_DEV_CRASH_USAGE}":"%ns.%cmd", "{COMMAND_DEV_CRASH_DESCRIPTION}":"Shuts down ShiftOS forcefully", "{COMMAND_DEV_UNLOCKEVERYTHING_USAGE}":"%ns.%cmd", "{COMMAND_DEV_UNLOCKEVERYTHING_DESCRIPTION}":"Unlocks all shiftorium upgrades", - "{COMMAND_DEV_FREECP_USAGE}":"%ns.%cmd{[amount:1000]}", - "{COMMAND_DEV_FREECP_DESCRIPTION}":"Gives [ammount] codepoints", + "{COMMAND_DEV_FREECP_USAGE}":"%ns.%cmd{amount:1000}", + "{COMMAND_DEV_FREECP_DESCRIPTION}":"Gives [amount] codepoints", "{COMMAND_TRM_CLEAR_USAGE}":"%ns.%cmd", "{COMMAND_TRM_CLEAR_DESCRIPTION}":"Clears the terminal", "{COMMAND_SHIFTORIUM_BUY_USAGE}":"%ns.%cmd{upgrade:}", @@ -217,6 +219,7 @@ If a system file is deleted by the virus scanner, it will be replaced.", "{OBSOLETE_SYS_SHUTDOWN}":"sys.shutdown is obsolete", "{PY_EXCEPTION}":"There was an error running python code.", "{LUA_ERROR}":"There was an error running lua code.", + "{LANGUAGE_CHANGED}":"The language has been changed. Please restart ShiftOS for changes to take full effect.", "{TERMINAL_NAME}":"Terminal", "{ARTPAD_NAME}":"Artpad", @@ -237,4 +240,5 @@ If a system file is deleted by the virus scanner, it will be replaced.", "{DIALOG_NAME}":"Dialog", "{COLOR_PICKER_NAME}":"Color Picker", "{CHAT_NAME}":"Chat", + "{NOTIFICATIONS}":"Notifications", } diff --git a/ShiftOS.WinForms/Tools/ControlManager.cs b/ShiftOS.WinForms/Tools/ControlManager.cs new file mode 100644 index 0000000..a2a76b7 --- /dev/null +++ b/ShiftOS.WinForms/Tools/ControlManager.cs @@ -0,0 +1,248 @@ +/* + * 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.Drawing; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using ShiftOS.Engine; +using static ShiftOS.Engine.AppearanceManager; + + +namespace ShiftOS.WinForms.Tools +{ + public static class ControlManager + { + [DllImport("user32.dll")] + public static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam); + + private const int WM_SETREDRAW = 11; + + public static void SuspendDrawing(Control parent) + { + SendMessage(parent.Handle, WM_SETREDRAW, false, 0); + } + + public static void ResumeDrawing(Control parent) + { + SendMessage(parent.Handle, WM_SETREDRAW, true, 0); + parent.Refresh(); + } + + public static void Close(this UserControl ctrl) + { + for (int i = 0; i < AppearanceManager.OpenForms.Count; i++) + { + if (OpenForms[i].ParentWindow == ctrl) + { + (OpenForms[i] as Form).Close(); + return; + } + } + } + + + internal static Color ConvertColor(ConsoleColor cCol) + { + switch (cCol) + { + case ConsoleColor.Black: + return Color.Black; + case ConsoleColor.Gray: + return Color.Gray; + case ConsoleColor.DarkGray: + return Color.DarkGray; + case ConsoleColor.Blue: + return Color.Blue; + case ConsoleColor.Cyan: + return Color.Cyan; + case ConsoleColor.DarkBlue: + return Color.DarkBlue; + case ConsoleColor.DarkCyan: + return Color.DarkCyan; + case ConsoleColor.DarkGreen: + return Color.DarkGreen; + case ConsoleColor.DarkMagenta: + return Color.DarkMagenta; + case ConsoleColor.DarkRed: + return Color.DarkRed; + case ConsoleColor.DarkYellow: + return Color.YellowGreen; + case ConsoleColor.Yellow: + return Color.Yellow; + case ConsoleColor.Green: + return Color.Green; + case ConsoleColor.Magenta: + return Color.Magenta; + case ConsoleColor.Red: + return Color.Red; + case ConsoleColor.White: + return Color.White; + default: + return Color.Black; + } + + } + + public static void SetCursor(Control ctrl) + { +#if STUPID + if (!(ctrl is WebBrowser)) + { + var mouse = SkinEngine.GetImage("mouse"); + if (mouse == null) + mouse = Properties.Resources.DefaultMouse; + + var mBmp = new Bitmap(mouse); + mBmp.MakeTransparent(Color.FromArgb(1, 0, 1)); + var gfx = Graphics.FromImage(mBmp); + var handle = mBmp.GetHicon(); + + var cursor = new Cursor(handle); + ctrl.Cursor = cursor; + } +#endif + } + + /// <summary> + /// Centers the control along its parent. + /// </summary> + /// <param name="ctrl">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)</param> + public static void CenterParent(this Control ctrl) + { + ctrl.Location = new Point( + (ctrl.Parent.Width - ctrl.Width) / 2, + (ctrl.Parent.Height - ctrl.Height) / 2 + ); + } + + public static void SetupControl(Control ctrl) + { + SuspendDrawing(ctrl); + ctrl.SuspendLayout(); + SetCursor(ctrl); + if (!(ctrl is MenuStrip) && !(ctrl is ToolStrip) && !(ctrl is StatusStrip) && !(ctrl is ContextMenuStrip)) + { + string tag = ""; + + try + { + tag = ctrl.Tag.ToString(); + } + catch { } + + if (!tag.Contains("keepbg")) + { + if (ctrl.BackColor != Control.DefaultBackColor) + { + ctrl.BackColor = SkinEngine.LoadedSkin.ControlColor; + } + } + + ctrl.ForeColor = SkinEngine.LoadedSkin.ControlTextColor; + + ctrl.Font = SkinEngine.LoadedSkin.MainFont; + + if (tag.Contains("header1")) + { + ctrl.Font = SkinEngine.LoadedSkin.HeaderFont; + } + + if (tag.Contains("header2")) + { + ctrl.Font = SkinEngine.LoadedSkin.Header2Font; + } + + if (tag.Contains("header3")) + { + ctrl.Font = SkinEngine.LoadedSkin.Header3Font; + } + + try + { + ctrl.Text = Localization.Parse(ctrl.Text); + } + catch + { + + } + ctrl.KeyDown += (o, a) => + { + if (a.Control && a.KeyCode == Keys.T) + { + a.SuppressKeyPress = true; + + + Engine.AppearanceManager.SetupWindow(new Applications.Terminal()); + } + + ShiftOS.Engine.Scripting.LuaInterpreter.RaiseEvent("on_key_down", a); + //a.Handled = true; + }; + if (ctrl is Button) + { + (ctrl as Button).FlatStyle = FlatStyle.Flat; + } + else if (ctrl is WindowBorder) + { + (ctrl as WindowBorder).Setup(); + } + } + + MakeDoubleBuffered(ctrl); + ctrl.ResumeLayout(); + ResumeDrawing(ctrl); + } + + public static void MakeDoubleBuffered(Control c) + { + if (System.Windows.Forms.SystemInformation.TerminalServerSession) + return; + + System.Reflection.PropertyInfo aProp = + typeof(System.Windows.Forms.Control).GetProperty( + "DoubleBuffered", + System.Reflection.BindingFlags.NonPublic | + System.Reflection.BindingFlags.Instance); + + aProp.SetValue(c, true, null); + + } + + public static void SetupControls(Control frm) + { + SetupControl(frm); + + for (int i = 0; i < frm.Controls.Count; i++) + { + SetupControls(frm.Controls[i]); + } + } + + } +} diff --git a/ShiftOS.WinForms/WFLanguageProvider.cs b/ShiftOS.WinForms/WFLanguageProvider.cs index e762e7e..c11b6dc 100644 --- a/ShiftOS.WinForms/WFLanguageProvider.cs +++ b/ShiftOS.WinForms/WFLanguageProvider.cs @@ -42,13 +42,32 @@ namespace ShiftOS.WinForms public string GetCurrentTranscript() { + try + { + switch (SaveSystem.CurrentSave.Language) + { + case "deutsch": + return Properties.Resources.strings_de; + default: + return getDefault(); + + } + } + catch (NullReferenceException) + { + return getDefault(); + } + } + + public string GetLanguagePath() + { switch (SaveSystem.CurrentSave.Language) { - case "deutsch - in beta": - return Properties.Resources.strings_de; + case "deutsch": + return Paths.GetPath("deutsch.local"); default: - return getDefault(); - + return Paths.GetPath("english.local"); + } } @@ -65,6 +84,11 @@ namespace ShiftOS.WinForms Utils.WriteAllText(Paths.GetPath("english.local"), getDefault()); } + public void WriteTranscript() + { + Utils.WriteAllText(GetLanguagePath(), GetCurrentTranscript()); + } + private string getDefault() { return Properties.Resources.strings_en; diff --git a/ShiftOS.WinForms/WindowBorder.cs b/ShiftOS.WinForms/WindowBorder.cs new file mode 100644 index 0000000..4fba470 --- /dev/null +++ b/ShiftOS.WinForms/WindowBorder.cs @@ -0,0 +1,496 @@ +/* + * 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.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +using static ShiftOS.Engine.SkinEngine; +using System.Runtime.InteropServices; +using ShiftOS.Engine; +using ShiftOS.WinForms.Tools; +using ShiftOS.WinForms.Applications; + +/// <summary> +/// Window border. +/// </summary> +namespace ShiftOS.WinForms +{ + /// <summary> + /// Window border. + /// </summary> + public partial class WindowBorder : Form, IWindowBorder + { + /// <summary> + /// Raises the closing event. + /// </summary> + /// <param name="e">E.</param> + protected override void OnClosing(CancelEventArgs e) + { + if ((ParentWindow as IShiftOSWindow).OnUnload()) + { + if (!SaveSystem.ShuttingDown) + { + if(Engine.AppearanceManager.OpenForms.Contains(this)) + Engine.AppearanceManager.OpenForms.Remove(this); + Desktop.ResetPanelButtons(); + } + } + base.OnClosing(e); + } + + /// <summary> + /// The parent window. + /// </summary> + private UserControl _parentWindow = null; + + /// <summary> + /// Gets or sets the parent window. + /// </summary> + /// <value>The parent window.</value> + public IShiftOSWindow ParentWindow + { + get + { + return (IShiftOSWindow)_parentWindow; + } + set + { + _parentWindow = (UserControl)value; + } + } + + internal void SetTitle(string title) + { + lbtitletext.Text = title; + } + + /// <summary> + /// Initializes a new instance of the <see cref="ShiftOS.WinForms.WindowBorder"/> class. + /// </summary> + /// <param name="win">Window.</param> + public WindowBorder(UserControl win) + { + InitializeComponent(); + this._parentWindow = win; + Shiftorium.Installed += () => + { + try + { + this.ParentForm.Invoke(new Action(() => + { + Setup(); + })); + } + catch { } + }; + SkinEngine.SkinLoaded += () => + { + try + { + Setup(); + (ParentWindow as IShiftOSWindow).OnSkinLoad(); + ControlManager.SetupControls(this.pnlcontents); + } + catch + { + + } + }; + this.Width = LoadedSkin.LeftBorderWidth + _parentWindow.Width + LoadedSkin.RightBorderWidth; + this.Height = LoadedSkin.TitlebarHeight + _parentWindow.Height + LoadedSkin.BottomBorderWidth; + + this.pnlcontents.Controls.Add(this._parentWindow); + this._parentWindow.Dock = DockStyle.Fill; + this._parentWindow.Show(); + ControlManager.SetupControls(this._parentWindow); + + ParentWindow.OnSkinLoad(); + ParentWindow.OnUpgrade(); + Shiftorium.Installed += () => + { + Setup(); + ParentWindow.OnUpgrade(); + }; + + Desktop.ShowWindow(this); + + } + + /// <summary> + /// Universals the key down. + /// </summary> + /// <returns>The key down.</returns> + /// <param name="o">O.</param> + /// <param name="a">The alpha component.</param> + public static void Universal_KeyDown(object o, KeyEventArgs a) + { + if (a.Control && a.KeyCode == Keys.T) + { + a.SuppressKeyPress = true; + + + if (SaveSystem.CurrentSave != null) + { + if (Shiftorium.UpgradeInstalled("window_manager")) + { + Engine.AppearanceManager.SetupWindow(new Applications.Terminal()); + } + } + } + + ShiftOS.Engine.Scripting.LuaInterpreter.RaiseEvent("on_key_down", a); + } + + /// <summary> + /// Windows the border load. + /// </summary> + /// <returns>The border load.</returns> + /// <param name="sender">Sender.</param> + /// <param name="e">E.</param> + public void WindowBorder_Load(object sender, EventArgs e) + { + this.DoubleBuffered = true; + + this._parentWindow.TextChanged += (o, a) => + { + Setup(); + Desktop.ResetPanelButtons(); + + }; + + this.Left = (Screen.PrimaryScreen.Bounds.Width - this.Width) / 2; + this.Top = (Screen.PrimaryScreen.Bounds.Height - this.Height) / 2; + + if (!this.IsDialog) + { + Engine.AppearanceManager.OpenForms.Add(this); + } + + SaveSystem.GameReady += () => + { + if (Shiftorium.UpgradeInstalled("wm_free_placement")) + { + AppearanceManager.Invoke(new Action(() => + { + this.Left = (Screen.PrimaryScreen.Bounds.Width - this.Width) / 2; + this.Top = (Screen.PrimaryScreen.Bounds.Height - this.Height) / 2; + + })); + } + AppearanceManager.Invoke(new Action(() => + { + Setup(); + })); + }; + + ControlManager.SetupControls(this); + + Setup(); + + var sWin = (IShiftOSWindow)ParentWindow; + + sWin.OnLoad(); + } + + /// <summary> + /// Setup this instance. + /// </summary> + public void Setup() + { + this.lbtitletext.Text = NameChangerBackend.GetName(ParentWindow); + + if (SaveSystem.CurrentSave != null) + { + this.pnltitle.Visible = Shiftorium.UpgradeInstalled("wm_titlebar"); + this.pnlclose.Visible = Shiftorium.UpgradeInstalled("close_button"); + this.pnlminimize.Visible = (IsDialog == false) && Shiftorium.UpgradeInstalled("minimize_button"); + this.pnlmaximize.Visible = (IsDialog == false) && Shiftorium.UpgradeInstalled("maximize_button"); + SetupSkin(); + } + else + { + this.pnltitle.Visible = false; + this.pnlclose.Visible = false; + this.pnlminimize.Visible = false; + this.pnlmaximize.Visible = false; + + } + } + + /// <summary> + /// Setups the skin. + /// </summary> + /// <returns>The skin.</returns> + public void SetupSkin() + { + this.DoubleBuffered = true; + this.TransparencyKey = LoadedSkin.SystemKey; + pnltitle.Height = LoadedSkin.TitlebarHeight; + pnltitle.BackColor = LoadedSkin.TitleBackgroundColor; + pnltitle.BackgroundImage = GetImage("titlebar"); + pnltitleleft.Visible = LoadedSkin.ShowTitleCorners; + pnltitleright.Visible = LoadedSkin.ShowTitleCorners; + pnltitleleft.BackColor = LoadedSkin.TitleLeftCornerBackground; + pnltitleright.BackColor = LoadedSkin.TitleRightCornerBackground; + pnltitleleft.Width = LoadedSkin.TitleLeftCornerWidth; + pnltitleright.Width = LoadedSkin.TitleRightCornerWidth; + pnltitleleft.BackgroundImage = GetImage("titleleft"); + pnltitleleft.BackgroundImageLayout = GetImageLayout("titleleft"); + pnltitleright.BackgroundImage = GetImage("titleright"); + pnltitleright.BackgroundImageLayout = GetImageLayout("titleright"); + pnltitle.BackgroundImageLayout = GetImageLayout("titlebar"); //RETARD ALERT. WHY WASN'T THIS THERE WHEN IMAGELAYOUTS WERE FIRST IMPLEMENTED? + + lbtitletext.BackColor = (pnltitle.BackgroundImage != null) ? Color.Transparent : LoadedSkin.TitleBackgroundColor; + lbtitletext.ForeColor = LoadedSkin.TitleTextColor; + lbtitletext.Font = LoadedSkin.TitleFont; + + pnlleft.BackColor = LoadedSkin.BorderLeftBackground; + pnlleft.BackgroundImage = GetImage("leftborder"); + pnlleft.BackgroundImageLayout = GetImageLayout("leftborder"); + pnlleft.Width = LoadedSkin.LeftBorderWidth; + pnlright.BackColor = LoadedSkin.BorderRightBackground; + pnlright.BackgroundImage = GetImage("rightborder"); + pnlright.BackgroundImageLayout = GetImageLayout("rightborder"); + pnlright.Width = LoadedSkin.RightBorderWidth; + + pnlbottom.BackColor = LoadedSkin.BorderBottomBackground; + pnlbottom.BackgroundImage = GetImage("bottomborder"); + pnlbottom.BackgroundImageLayout = GetImageLayout("bottomborder"); + pnlbottom.Height = LoadedSkin.BottomBorderWidth; + + pnlbottomr.BackColor = LoadedSkin.BorderBottomRightBackground; + pnlbottomr.BackgroundImage = GetImage("bottomrborder"); + pnlbottomr.BackgroundImageLayout = GetImageLayout("bottomrborder"); + pnlbottoml.BackColor = LoadedSkin.BorderBottomLeftBackground; + pnlbottoml.BackgroundImage = GetImage("bottomlborder"); + pnlbottoml.BackgroundImageLayout = GetImageLayout("bottomlborder"); + + lbtitletext.ForeColor = LoadedSkin.TitleTextColor; + lbtitletext.Font = LoadedSkin.TitleFont; + pnlclose.BackColor = LoadedSkin.CloseButtonColor; + pnlclose.BackgroundImage = GetImage("closebutton"); + pnlclose.BackgroundImageLayout = GetImageLayout("closebutton"); + pnlminimize.BackColor = LoadedSkin.MinimizeButtonColor; + pnlminimize.BackgroundImage = GetImage("minimizebutton"); + pnlminimize.BackgroundImageLayout = GetImageLayout("minimizebutton"); + pnlmaximize.BackColor = LoadedSkin.MaximizeButtonColor; + pnlmaximize.BackgroundImage = GetImage("maximizebutton"); + pnlmaximize.BackgroundImageLayout = GetImageLayout("maximizebutton"); + + pnlclose.Size = LoadedSkin.CloseButtonSize; + pnlminimize.Size = LoadedSkin.MinimizeButtonSize; + pnlmaximize.Size = LoadedSkin.MaximizeButtonSize; + pnlclose.Location = FromRight(LoadedSkin.CloseButtonFromSide); + pnlminimize.Location = FromRight(LoadedSkin.MinimizeButtonFromSide); + pnlmaximize.Location = FromRight(LoadedSkin.MaximizeButtonFromSide); + pnlclose.Left -= pnlclose.Width; + pnlmaximize.Left -= pnlmaximize.Width; + pnlminimize.Left -= pnlminimize.Width; + + 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; + } + + if (Shiftorium.UpgradeInstalled("app_icons")) + { + pnlicon.Show(); + pnlicon.Size = new Size(16, 16); + pnlicon.BackColor = Color.Transparent; + pnlicon.BackgroundImage = GetIcon(this.ParentWindow.GetType().Name); + pnlicon.BackgroundImageLayout = ImageLayout.Stretch; + pnlicon.Location = LoadedSkin.TitlebarIconFromSide; + } + else + { + pnlicon.Hide(); + } + } + + /// <summary> + /// Froms the right. + /// </summary> + /// <returns>The right.</returns> + /// <param name="input">Input.</param> + public Point FromRight(Point input) + { + return new Point(pnltitle.Width - input.X, input.Y); + } + + /// <summary> + /// Lbtitletexts the click. + /// </summary> + /// <returns>The click.</returns> + /// <param name="sender">Sender.</param> + /// <param name="e">E.</param> + private void lbtitletext_Click(object sender, EventArgs e) + { + + } + + /// <summary> + /// Pnlcloses the click. + /// </summary> + /// <returns>The click.</returns> + /// <param name="sender">Sender.</param> + /// <param name="e">E.</param> + private void pnlclose_Click(object sender, EventArgs e) + { + this.Close(); + } + + /// <summary> + /// Pnlmaximizes the click. + /// </summary> + /// <returns>The click.</returns> + /// <param name="sender">Sender.</param> + /// <param name="e">E.</param> + private void pnlmaximize_Click(object sender, EventArgs e) + { + if (maximized == false) + Desktop.MaximizeWindow(this); + else + Desktop.RestoreWindow(this); + maximized = !maximized; + SetupSkin(); + } + + bool minimized = false; + bool maximized = false; + + public bool IsMinimized + { + get + { + return minimized; + } + } + + public bool IsMaximized + { + get + { + return maximized; + } + } + + + /// <summary> + /// Pnlminimizes the click. + /// </summary> + /// <returns>The click.</returns> + /// <param name="sender">Sender.</param> + /// <param name="e">E.</param> + private void pnlminimize_Click(object sender, EventArgs e) + { + if (minimized == false) + Desktop.MinimizeWindow(this); + else + Desktop.RestoreWindow(this); + minimized = !minimized; + } + + + /// <summary> + /// The W m NCLBUTTONDOW. + /// </summary> + public const int WM_NCLBUTTONDOWN = 0xA1; + /// <summary> + /// The H t CAPTIO. + /// </summary> + public const int HT_CAPTION = 0x2; + + /// <summary> + /// The is dialog. + /// </summary> + public bool IsDialog = false; + + + [DllImportAttribute("user32.dll")] + /// <summary> + /// Sends the message. + /// </summary> + /// <returns>The message.</returns> + /// <param name="hWnd">H window.</param> + /// <param name="Msg">Message.</param> + /// <param name="wParam">W parameter.</param> + /// <param name="lParam">L parameter.</param> + public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); + [DllImportAttribute("user32.dll")] + /// <summary> + /// Releases the capture. + /// </summary> + /// <returns>The capture.</returns> + public static extern bool ReleaseCapture(); + + /// <summary> + /// Pnltitles the mouse move. + /// </summary> + /// <returns>The mouse move.</returns> + /// <param name="sender">Sender.</param> + /// <param name="e">E.</param> + private void pnltitle_MouseMove(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left && Shiftorium.UpgradeInstalled("draggable_windows")) + { + ReleaseCapture(); + SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0); + } + } + + /// <summary> + /// Pnltitles the paint. + /// </summary> + /// <returns>The paint.</returns> + /// <param name="sender">Sender.</param> + /// <param name="e">E.</param> + private void pnltitle_Paint(object sender, PaintEventArgs e) { + + } + + /// <summary> + /// Lbtitletexts the mouse move. + /// </summary> + /// <returns>The mouse move.</returns> + /// <param name="sender">Sender.</param> + /// <param name="e">E.</param> + private void lbtitletext_MouseMove(object sender, MouseEventArgs e) { + pnltitle_MouseMove(sender, e); + } + } +} diff --git a/ShiftOS.WinForms/WinformsDesktop.cs b/ShiftOS.WinForms/WinformsDesktop.cs new file mode 100644 index 0000000..182c607 --- /dev/null +++ b/ShiftOS.WinForms/WinformsDesktop.cs @@ -0,0 +1,756 @@ +/* + * 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.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 static ShiftOS.Engine.SkinEngine; +using ShiftOS.WinForms.Tools; +using ShiftOS.WinForms.Applications; +using Newtonsoft.Json; +using ShiftOS.Engine.Scripting; +using System.Threading; + +/// <summary> +/// Winforms desktop. +/// </summary> +namespace ShiftOS.WinForms +{ + /// <summary> + /// Winforms desktop. + /// </summary> + public partial class WinformsDesktop : Form, IDesktop + { + private bool InScreensaver = false; + private int millisecondsUntilScreensaver = 300000; + + /// <summary> + /// Initializes a new instance of the <see cref="ShiftOS.WinForms.WinformsDesktop"/> class. + /// </summary> + public WinformsDesktop() + { + InitializeComponent(); + 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) + this.Left = 0; + if (this.Top != 0) + this.Top = 0; + }; + + this.SizeChanged += (o, a) => + { + if (this.ClientRectangle != Screen.PrimaryScreen.Bounds) + { + this.WindowState = FormWindowState.Maximized; + } + }; + + SaveSystem.GameReady += () => + { + if (this.Visible == true) + this.Invoke(new Action(() => SetupDesktop())); + this.Invoke(new Action(() => + { + btnnotifications.Text = Localization.Parse("{NOTIFICATIONS} (" + NotificationDaemon.GetUnreadCount().ToString() + ")"); + })); + }; + Shiftorium.Installed += () => + { + if (this.Visible == true) + this.Invoke(new Action(() => SetupDesktop())); + }; + var time = new System.Windows.Forms.Timer(); + time.Interval = 100; + this.KeyDown += (o, a) => + { + if (a.Control && a.KeyCode == Keys.T) + { + Engine.AppearanceManager.SetupWindow(new Applications.Terminal()); + } + /*if (a.Control && a.KeyCode == Keys.Tab) + { + // CtrlTabMenu + CtrlTabMenu.Show(); + if (a.Shift) CtrlTabMenu.CycleBack(); + else CtrlTabMenu.CycleForwards(); + }*/ //nyi + + ShiftOS.Engine.Scripting.LuaInterpreter.RaiseEvent("on_key_down", a); + }; + SkinEngine.SkinLoaded += () => + { + SetupDesktop(); + }; + time.Tick += (o, a) => + { + if (Shiftorium.IsInitiated == true) + { + if (SaveSystem.CurrentSave != null && TutorialManager.IsInTutorial == false) + { + lbtime.Text = Applications.Terminal.GetTime(); + lbtime.Left = desktoppanel.Width - lbtime.Width - LoadedSkin.DesktopPanelClockFromRight.X; + lbtime.Top = LoadedSkin.DesktopPanelClockFromRight.Y; + } + } + + try + { + if (SaveSystem.CurrentSave != null) + { + if (SaveSystem.CurrentSave.LastMonthPaid != DateTime.Now.Month) + { + if (SaveSystem.CurrentSave.Codepoints >= DownloadManager.GetAllSubscriptions()[SaveSystem.CurrentSave.ShiftnetSubscription].CostPerMonth) + { + SaveSystem.CurrentSave.Codepoints -= DownloadManager.GetAllSubscriptions()[SaveSystem.CurrentSave.ShiftnetSubscription].CostPerMonth; + SaveSystem.CurrentSave.LastMonthPaid = DateTime.Now.Month; + } + else + { + SaveSystem.CurrentSave.ShiftnetSubscription = 0; + SaveSystem.CurrentSave.LastMonthPaid = DateTime.Now.Month; + Infobox.Show("Shiftnet", "You do not have enough Codepoints to pay for your Shiftnet subscription this month. You have been downgraded to the free plan."); + } + } + } + } + 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(); + InScreensaver = true; + } + millisecondsUntilScreensaver--; + Thread.Sleep(1); + } + millisecondsUntilScreensaver = 300000; + InScreensaver = false; + HideScreensaver(); + } + }); + ssThread.IsBackground = true; + ssThread.Start(); + + this.DoubleBuffered = true; + } + + public void HideScreensaver() + { + if (ResetDesktop == true) + { + this.Invoke(new Action(() => + { + this.TopMost = false; + pnlscreensaver.Hide(); + Cursor.Show(); + SetupDesktop(); + ResetDesktop = false; + + })); + } + } + + private bool ResetDesktop = false; + + private void ShowScreensaver() + { + if (Shiftorium.UpgradeInstalled("screensavers")) + { + this.Invoke(new Action(() => + { + pnlscreensaver.Show(); + this.TopMost = true; + pnlssicon.Show(); + pnlssicon.BackColor = Color.Green; + pnlssicon.BackgroundImage = GetImage("screensaver"); + pnlssicon.BackgroundImageLayout = GetImageLayout("screensaver"); + + if (pnlssicon.BackgroundImage != null) + { + pnlssicon.Size = pnlssicon.BackgroundImage.Size; + } + + Cursor.Hide(); + + var t = new Thread(() => + { + var rnd = new Random(); + while (InScreensaver == true) + { + int x = rnd.Next(0, this.Width); + int y = rnd.Next(0, this.Height); + + this.Invoke(new Action(() => + { + pnlssicon.Location = new Point(x, y); + })); + + Thread.Sleep(5000); + } + ResetDesktop = true; + }); + t.IsBackground = true; + t.Start(); + })); + } + } + + + /// <summary> + /// Populates the panel buttons. + /// </summary> + /// <returns>The panel buttons.</returns> + public void PopulatePanelButtons() + { + if (DesktopFunctions.ShowDefaultElements == true) + { + panelbuttonholder.Controls.Clear(); + if (Shiftorium.IsInitiated == true) + { + if (Shiftorium.UpgradeInstalled("wm_panel_buttons")) + { + foreach (WindowBorder form in Engine.AppearanceManager.OpenForms) + { + if (form != null) + { + if (form.Visible == true) + { + EventHandler onClick = (o, a) => + { + if (form == focused) + { + if (form.IsMinimized) + { + RestoreWindow(form); + } + else + { + MinimizeWindow(form); + } + } + else + { + form.BringToFront(); + focused = form; + } + }; + + var pnlbtn = new Panel(); + pnlbtn.Margin = new Padding(2, LoadedSkin.PanelButtonFromTop, 0, 0); + pnlbtn.BackColor = LoadedSkin.PanelButtonColor; + pnlbtn.BackgroundImage = GetImage("panelbutton"); + pnlbtn.BackgroundImageLayout = GetImageLayout("panelbutton"); + + var pnlbtntext = new Label(); + pnlbtntext.Text = NameChangerBackend.GetName(form.ParentWindow); + pnlbtntext.AutoSize = true; + pnlbtntext.Location = LoadedSkin.PanelButtonFromLeft; + pnlbtntext.ForeColor = LoadedSkin.PanelButtonTextColor; + pnlbtntext.BackColor = Color.Transparent; + + pnlbtn.BackColor = LoadedSkin.PanelButtonColor; + if (pnlbtn.BackgroundImage != null) + { + pnlbtntext.BackColor = Color.Transparent; + } + pnlbtn.Size = LoadedSkin.PanelButtonSize; + pnlbtn.Tag = "keepbg"; + pnlbtntext.Tag = "keepbg"; + pnlbtn.Controls.Add(pnlbtntext); + this.panelbuttonholder.Controls.Add(pnlbtn); + pnlbtn.Show(); + pnlbtntext.Show(); + + if (Shiftorium.UpgradeInstalled("useful_panel_buttons")) + { + pnlbtn.Click += onClick; + pnlbtntext.Click += onClick; + } + pnlbtntext.Font = LoadedSkin.PanelButtonFont; + + } + } + } + } + } + } + + LuaInterpreter.RaiseEvent("on_panelbutton_populate", this); + } + + /// <summary> + /// Setups the desktop. + /// </summary> + /// <returns>The desktop.</returns> + public void SetupDesktop() + { + if (DesktopFunctions.ShowDefaultElements == true) + { + ToolStripManager.Renderer = new ShiftOSMenuRenderer(); + + this.DoubleBuffered = true; + this.FormBorderStyle = FormBorderStyle.None; + this.WindowState = FormWindowState.Maximized; + desktoppanel.BackColor = Color.Green; + + //upgrades + + if (Shiftorium.IsInitiated == true) + { + desktoppanel.Visible = Shiftorium.UpgradeInstalled("desktop"); + lbtime.Visible = Shiftorium.UpgradeInstalled("desktop_clock_widget"); + + btnnotifications.Visible = Shiftorium.UpgradeInstalled("panel_notifications"); + + //skinning + lbtime.ForeColor = LoadedSkin.DesktopPanelClockColor; + + panelbuttonholder.Top = 0; + panelbuttonholder.Left = LoadedSkin.PanelButtonHolderFromLeft; + panelbuttonholder.Height = desktoppanel.Height; + panelbuttonholder.BackColor = Color.Transparent; + panelbuttonholder.Margin = new Padding(0, 0, 0, 0); + + sysmenuholder.Visible = Shiftorium.UpgradeInstalled("app_launcher"); + + //The Color Picker can give us transparent colors - which Windows Forms fucking despises when dealing with form backgrounds. + //To compensate, we must recreate the desktop color and make the alpha channel '255'. + 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<Image>((img) => + { + this.BackgroundImage = img; + })); + this.BackgroundImageLayout = GetImageLayout("desktopbackground"); + desktoppanel.BackColor = LoadedSkin.DesktopPanelColor; + + var pnlimg = GetImage("desktoppanel"); + if (pnlimg != null) + { + var bmp = new Bitmap(pnlimg); + bmp.MakeTransparent(Color.FromArgb(1, 0, 1)); + pnlimg = bmp; + } + + desktoppanel.BackgroundImage = pnlimg; + if (desktoppanel.BackgroundImage != null) + { + desktoppanel.BackColor = Color.Transparent; + } + var appimg = GetImage("applauncher"); + if (appimg != null) + { + var bmp = new Bitmap(appimg); + bmp.MakeTransparent(Color.FromArgb(1, 0, 1)); + appimg = bmp; + } + menuStrip1.BackgroundImage = appimg; + lbtime.ForeColor = LoadedSkin.DesktopPanelClockColor; + lbtime.Font = LoadedSkin.DesktopPanelClockFont; + if (desktoppanel.BackgroundImage == null) + { + lbtime.BackColor = LoadedSkin.DesktopPanelClockBackgroundColor; + } + else + { + lbtime.BackColor = Color.Transparent; + } + apps.Text = LoadedSkin.AppLauncherText; + sysmenuholder.Location = LoadedSkin.AppLauncherFromLeft; + sysmenuholder.Size = LoadedSkin.AppLauncherHolderSize; + apps.Size = sysmenuholder.Size; + menuStrip1.Renderer = new ShiftOSMenuRenderer(new AppLauncherColorTable()); + desktoppanel.BackgroundImageLayout = GetImageLayout("desktoppanel"); + desktoppanel.Height = LoadedSkin.DesktopPanelHeight; + if (LoadedSkin.DesktopPanelPosition == 1) + { + desktoppanel.Dock = DockStyle.Bottom; + } + else + { + desktoppanel.Dock = DockStyle.Top; + } + } + } + else + { + desktoppanel.Hide(); + } + + LuaInterpreter.RaiseEvent("on_desktop_skin", this); + + PopulatePanelButtons(); + } + + public ToolStripMenuItem GetALCategoryWithName(string text) + { + foreach (ToolStripMenuItem menuitem in apps.DropDownItems) + { + if (menuitem.Text == text) + return menuitem; + } + + var itm = new ToolStripMenuItem(); + itm.Text = text; + apps.DropDownItems.Add(itm); + return itm; + } + + /// <summary> + /// Populates the app launcher. + /// </summary> + /// <returns>The app launcher.</returns> + /// <param name="items">Items.</param> + public void PopulateAppLauncher(LauncherItem[] items) + { + if (DesktopFunctions.ShowDefaultElements == true) + { + apps.DropDownItems.Clear(); + + Dictionary<string, List<ToolStripMenuItem>> sortedItems = new Dictionary<string, List<ToolStripMenuItem>>(); + + + + foreach (var kv in items) + { + var item = new ToolStripMenuItem(); + item.Text = (kv.LaunchType == null) ? kv.DisplayData.Name : Applications.NameChangerBackend.GetNameRaw(kv.LaunchType); + item.Image = (kv.LaunchType == null) ? null : SkinEngine.GetIcon(kv.LaunchType.Name); + item.Click += (o, a) => + { + if (kv is LuaLauncherItem) + { + var interpreter = new Engine.Scripting.LuaInterpreter(); + interpreter.ExecuteFile((kv as LuaLauncherItem).LaunchPath); + } + else + { + Engine.AppearanceManager.SetupWindow(Activator.CreateInstance(kv.LaunchType) as IShiftOSWindow); + } + + }; + if (sortedItems.ContainsKey(kv.DisplayData.Category)) + { + sortedItems[kv.DisplayData.Category].Add(item); + } + else + { + sortedItems.Add(kv.DisplayData.Category, new List<ToolStripMenuItem>()); + sortedItems[kv.DisplayData.Category].Add(item); + } + } + + foreach (var kv in sortedItems) + { + if (Shiftorium.IsInitiated == true) + { + if (Shiftorium.UpgradeInstalled("app_launcher_categories")) + { + var cat = GetALCategoryWithName(kv.Key); + foreach (var subItem in kv.Value) + { + cat.DropDownItems.Add(subItem); + } + } + + else + { + foreach (var subItem in kv.Value) + { + apps.DropDownItems.Add(subItem); + } + } + } + } + + if (Shiftorium.IsInitiated == true) + { + if (Shiftorium.UpgradeInstalled("al_shutdown")) + { + apps.DropDownItems.Add(new ToolStripSeparator()); + var item = new ToolStripMenuItem(); + item.Text = Localization.Parse("{SHUTDOWN}"); + item.Click += (o, a) => + { + TerminalBackend.InvokeCommand("sos.shutdown"); + }; + apps.DropDownItems.Add(item); + + } + } + } + LuaInterpreter.RaiseEvent("on_al_populate", items); + } + + + /// <summary> + /// Desktops the load. + /// </summary> + /// <returns>The load.</returns> + /// <param name="sender">Sender.</param> + /// <param name="e">E.</param> + private void Desktop_Load(object sender, EventArgs e) + { + + SaveSystem.Begin(); + + SetupDesktop(); + + SaveSystem.GameReady += () => + { + this.Invoke(new Action(() => + { + LuaInterpreter.RaiseEvent("on_desktop_load", this); + })); + }; + } + + /// <summary> + /// Shows the window. + /// </summary> + /// <returns>The window.</returns> + /// <param name="border">Border.</param> + public void ShowWindow(IWindowBorder border) + { + var brdr = border as Form; + focused = border; + brdr.GotFocus += (o, a) => + { + focused = border; + }; + brdr.FormBorderStyle = FormBorderStyle.None; + brdr.Show(); + brdr.TopMost = true; + } + + /// <summary> + /// Kills the window. + /// </summary> + /// <returns>The window.</returns> + /// <param name="border">Border.</param> + public void KillWindow(IWindowBorder border) + { + border.Close(); + } + + private IWindowBorder focused = null; + + public string DesktopName + { + get + { + return "ShiftOS Desktop"; + } + } + + + /// <summary> + /// Minimizes the window. + /// </summary> + /// <param name="brdr">Brdr.</param> + public void MinimizeWindow(IWindowBorder brdr) + { + var loc = (brdr as WindowBorder).Location; + var sz = (brdr as WindowBorder).Size; + (brdr as WindowBorder).Tag = JsonConvert.SerializeObject(new + { + Size = sz, + Location = loc + }); + (brdr as WindowBorder).Location = new Point(this.GetSize().Width * 2, this.GetSize().Height * 2); + } + + /// <summary> + /// Maximizes the window. + /// </summary> + /// <returns>The window.</returns> + /// <param name="brdr">Brdr.</param> + public void MaximizeWindow(IWindowBorder brdr) + { + int startY = (LoadedSkin.DesktopPanelPosition == 1) ? 0 : LoadedSkin.DesktopPanelHeight; + int h = this.GetSize().Height - LoadedSkin.DesktopPanelHeight; + var loc = (brdr as WindowBorder).Location; + var sz = (brdr as WindowBorder).Size; + (brdr as WindowBorder).Tag = JsonConvert.SerializeObject(new + { + Size = sz, + Location = loc + }); + (brdr as WindowBorder).Location = new Point(0, startY); + (brdr as WindowBorder).Size = new Size(this.GetSize().Width, h); + + } + + /// <summary> + /// Restores the window. + /// </summary> + /// <returns>The window.</returns> + /// <param name="brdr">Brdr.</param> + public void RestoreWindow(IWindowBorder brdr) + { + dynamic tag = JsonConvert.DeserializeObject<dynamic>((brdr as WindowBorder).Tag.ToString()); + (brdr as WindowBorder).Location = tag.Location; + (brdr as WindowBorder).Size = tag.Size; + + } + + /// <summary> + /// Invokes the on worker thread. + /// </summary> + /// <returns>The on worker thread.</returns> + /// <param name="act">Act.</param> + public void InvokeOnWorkerThread(Action act) + { + try + { + this.Invoke(new Action(() => + { + act?.Invoke(); + })); + } + catch + { + + } + } + + public void OpenAppLauncher(Point loc) + { + apps.DropDown.Left = loc.X; + apps.DropDown.Top = loc.Y; + apps.ShowDropDown(); + } + + /// <summary> + /// Gets the size. + /// </summary> + /// <returns>The size.</returns> + public Size GetSize() + { + return this.Size; + } + + private void btnnotifications_Click(object sender, EventArgs e) + { + AppearanceManager.SetupWindow(new Applications.Notifications()); + } + + private void desktoppanel_Paint(object sender, PaintEventArgs e) + { + e.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; + } + } + + [ShiftOS.Engine.Scripting.Exposed("desktop")] + public class DesktopFunctions + { + public static bool ShowDefaultElements = true; + + public dynamic getWindow() + { + return Desktop.CurrentDesktop; + } + + public void showDefaultElements(bool val) + { + ShowDefaultElements = val; + SkinEngine.LoadSkin(); + } + + public dynamic getOpenWindows() + { + return AppearanceManager.OpenForms; + } + + public string getALItemName(LauncherItem kv) + { + return (kv.LaunchType == null) ? kv.DisplayData.Name : Applications.NameChangerBackend.GetNameRaw(kv.LaunchType); + } + + public void openAppLauncher(Point loc) + { + Desktop.OpenAppLauncher(loc); + } + + public string getWindowTitle(IWindowBorder form) + { + return NameChangerBackend.GetName(form.ParentWindow); + } + + public void openApp(LauncherItem kv) + { + if (kv is LuaLauncherItem) + { + var interpreter = new Engine.Scripting.LuaInterpreter(); + interpreter.ExecuteFile((kv as LuaLauncherItem).LaunchPath); + } + else + { + Engine.AppearanceManager.SetupWindow(Activator.CreateInstance(kv.LaunchType) as IShiftOSWindow); + } + } + } +}
\ No newline at end of file diff --git a/ShiftOS.WinForms/WinformsWindowManager.cs b/ShiftOS.WinForms/WinformsWindowManager.cs new file mode 100644 index 0000000..cfcb6d3 --- /dev/null +++ b/ShiftOS.WinForms/WinformsWindowManager.cs @@ -0,0 +1,297 @@ +/* + * 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.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using ShiftOS.Engine; +using ShiftOS.WinForms.Tools; + +namespace ShiftOS.WinForms +{ + internal class WinformsWindowManager : WindowManager + { + public int DesktopHeight + { + get + { + return Desktop.Size.Height - ((Shiftorium.UpgradeInstalled("desktop") == true) ? SkinEngine.LoadedSkin.DesktopPanelHeight : 0); + } + } + + public int TopLocation + { + get + { + if (!Shiftorium.UpgradeInstalled("desktop")) + return 0; + return ((SkinEngine.LoadedSkin.DesktopPanelPosition == 0) ? SkinEngine.LoadedSkin.DesktopPanelHeight : 0); + } + } + + public override void Close(IShiftOSWindow win) + { + (win as UserControl).Close(); + } + + public override void InvokeAction(Action act) + { + Desktop.InvokeOnWorkerThread(act); + } + + public WinformsWindowManager() + { + Shiftorium.Installed += () => + { + SetupWindows(); + }; + } + + public override void Maximize(IWindowBorder form) + { + try + { + var deskSize = new Size(0, 0); + deskSize.Width = Screen.PrimaryScreen.Bounds.Width; + deskSize.Height = Screen.PrimaryScreen.Bounds.Height; + + deskSize.Height -= SkinEngine.LoadedSkin.DesktopPanelHeight; + + var deskStart = new Point((SkinEngine.LoadedSkin.DesktopPanelPosition == 0) ? SkinEngine.LoadedSkin.DesktopPanelHeight : 0, 0); + + (form as WindowBorder).Location = deskStart; + (form as WindowBorder).Size = deskSize; + + + } + catch + { + } + } + + public override void Minimize(IWindowBorder border) + { + try + { + + } + catch { } + } + + public override void SetTitle(IShiftOSWindow win, string title) + { + var wb = (win as UserControl).ParentForm as WindowBorder; + wb.SetTitle(title); + } + + public override void SetupDialog(IShiftOSWindow form) + { + if (!Shiftorium.UpgradeAttributesUnlocked(form.GetType())) + { + Console.WriteLine("{APP_NOT_FOUND}"); + return; + } + + var wb = new WindowBorder(form as UserControl); + wb.IsDialog = true; + + + wb.Show(); + } + + public override void SetupWindow(IShiftOSWindow form) + { + if (!AppearanceManager.CanOpenWindow(form)) + { + Infobox.Show("{MULTIPLAYER_ONLY}", "{MULTIPLAYER_ONLY_EXP}"); + return; + } + + foreach(var attr in form.GetType().GetCustomAttributes(true)) + { + if(attr is MultiplayerOnlyAttribute) + { + if(KernelWatchdog.MudConnected == false) + { + Infobox.PromptYesNo("Disconnected from MUD", "This application requires a connection to the MUD. Would you like to reconnect?", new Action<bool>((answer) => + { + if(answer == true) + { + KernelWatchdog.MudConnected = true; + SetupWindow(form); + } + })); + return; + } + } + } + + if (!Shiftorium.UpgradeAttributesUnlocked(form.GetType())) + { + Console.WriteLine("{APP_NOT_FOUND}"); + return; + } + + if (SaveSystem.CurrentSave != null) + { + if (!form.GetType().Name.Contains(typeof(Applications.Dialog).Name)) + { + int maxWindows = 0; + + //Window manager will step in here. + if (Shiftorium.UpgradeInstalled("wm_unlimited_windows")) + { + maxWindows = 0; + } + else if (Shiftorium.UpgradeInstalled("wm_4_windows")) + { + maxWindows = 4; + } + else if (Shiftorium.UpgradeInstalled("window_manager")) + { + maxWindows = 2; + } + else + { + maxWindows = 1; + } + + + if (maxWindows > 0) + { + var windows = new List<WindowBorder>(); + foreach(var WB in AppearanceManager.OpenForms) + { + if (WB is WindowBorder) + windows.Add(WB as WindowBorder); + } + + List<WindowBorder> formstoclose = new List<WindowBorder>(windows.Where(x => x.IsDialog == false).ToArray()); + + while (formstoclose.Count > maxWindows - 1) + { + this.Close(formstoclose[0].ParentWindow); + AppearanceManager.OpenForms.Remove(formstoclose[0]); + formstoclose.RemoveAt(0); + + } + } + } + } + + var wb = new WindowBorder(form as UserControl); + + FormClosedEventHandler onClose = (o,a)=> { }; + onClose = (o, a) => + { + SetupWindows(); + wb.FormClosed -= onClose; + }; + wb.FormClosed += onClose; + SetupWindows(); + } + + public void SetupWindows() + { + var windows = new List<WindowBorder>(); + foreach(var win in AppearanceManager.OpenForms) + { + if (win is WindowBorder) + if ((win as WindowBorder).IsDialog == false) + windows.Add(win as WindowBorder); + } + + if (Shiftorium.UpgradeInstalled("wm_free_placement")) + return; + + else if (windows.Count == 4) + { + var w1 = windows[0]; + var w2 = windows[1]; + var w3 = windows[2]; + var w4 = windows[3]; + w1.Location = new Point(0, TopLocation); + w1.Width = Desktop.Size.Width / 2; + w1.Height = DesktopHeight / 2; + w2.Left = w1.Width; + w2.Width = w1.Width; + w2.Height = w1.Height; + w2.Top = w1.Top; + w3.Top = w2.Height; + w3.Height = w1.Height; + w3.Left = 0; + w3.Width = w1.Width; + w4.Width = w3.Width; + w4.Top = w3.Top; + w4.Left = w3.Width; + w4.Height = w3.Height; + } + else if(windows.Count == 3) + { + var w1 = windows[0]; + var w2 = windows[1]; + var w3 = windows[2]; + w1.Location = new Point(0, TopLocation); + w1.Width = Desktop.Size.Width / 2; + w1.Height = DesktopHeight / 2; + w2.Left = w1.Width; + w2.Width = w1.Width; + w2.Height = w1.Height; + w2.Top = w1.Top; + w3.Top = w2.Height; + w3.Height = w1.Height; + w3.Left = 0; + w3.Width = w1.Width + w2.Width; + } + else if (windows.Count == 2) + { + var w1 = windows[0]; + var w2 = windows[1]; + + w1.Location = new Point(0, TopLocation); + w1.Width = Desktop.Size.Width / 2; + w1.Height = DesktopHeight; + w2.Left = w1.Width; + w2.Width = w1.Width; + w2.Height = w1.Height; + w2.Top = w1.Top; + + } + else if(windows.Count == 1) + { + var win = windows.FirstOrDefault(); + if(win != null) + { + win.Size = new Size(Desktop.Size.Width, DesktopHeight); + win.Location = new Point(0, this.TopLocation); + } + } + + } + } +} diff --git a/ShiftOS_TheReturn.sln b/ShiftOS_TheReturn.sln index a3eb2a0..8bb8ef4 100644 --- a/ShiftOS_TheReturn.sln +++ b/ShiftOS_TheReturn.sln @@ -1,7 +1,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +VisualStudioVersion = 14.0.23107.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShiftOS.Engine", "ShiftOS_TheReturn\ShiftOS.Engine.csproj", "{7C979B07-0585-4033-A110-E5555B9D6651}" EndProject @@ -19,12 +19,6 @@ Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ShiftOS.Modding.VB.LegacySk EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModLauncher", "ModLauncher\ModLauncher.csproj", "{AEACB7B5-E8FC-4569-BBD3-5053A694D6EC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShiftOS.Server.WebAdmin", "ShiftOS.Server.WebAdmin\ShiftOS.Server.WebAdmin.csproj", "{B29FDD06-E6FE-40A2-8258-283728CED81A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gwen", "Gwen\Gwen.csproj", "{ADDA2F43-96C0-497F-8216-29C67ABC9806}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gwen.Renderer.OpenTK", "Gwen.Renderer.OpenTK\Gwen.Renderer.OpenTK.csproj", "{41650C82-D630-4E5C-845A-F1513C8FDC99}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -63,18 +57,6 @@ Global {AEACB7B5-E8FC-4569-BBD3-5053A694D6EC}.Debug|Any CPU.Build.0 = Debug|Any CPU {AEACB7B5-E8FC-4569-BBD3-5053A694D6EC}.Release|Any CPU.ActiveCfg = Release|Any CPU {AEACB7B5-E8FC-4569-BBD3-5053A694D6EC}.Release|Any CPU.Build.0 = Release|Any CPU - {B29FDD06-E6FE-40A2-8258-283728CED81A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B29FDD06-E6FE-40A2-8258-283728CED81A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B29FDD06-E6FE-40A2-8258-283728CED81A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B29FDD06-E6FE-40A2-8258-283728CED81A}.Release|Any CPU.Build.0 = Release|Any CPU - {ADDA2F43-96C0-497F-8216-29C67ABC9806}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {ADDA2F43-96C0-497F-8216-29C67ABC9806}.Debug|Any CPU.Build.0 = Debug|Any CPU - {ADDA2F43-96C0-497F-8216-29C67ABC9806}.Release|Any CPU.ActiveCfg = Release|Any CPU - {ADDA2F43-96C0-497F-8216-29C67ABC9806}.Release|Any CPU.Build.0 = Release|Any CPU - {41650C82-D630-4E5C-845A-F1513C8FDC99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {41650C82-D630-4E5C-845A-F1513C8FDC99}.Debug|Any CPU.Build.0 = Debug|Any CPU - {41650C82-D630-4E5C-845A-F1513C8FDC99}.Release|Any CPU.ActiveCfg = Release|Any CPU - {41650C82-D630-4E5C-845A-F1513C8FDC99}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ShiftOS_TheReturn/AudioManager.cs b/ShiftOS_TheReturn/AudioManager.cs new file mode 100644 index 0000000..7466eeb --- /dev/null +++ b/ShiftOS_TheReturn/AudioManager.cs @@ -0,0 +1,126 @@ +/* + * 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. + */ + +#define NOSOUND + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using NAudio; +using NAudio.Wave; + +namespace ShiftOS.Engine +{ + public static class AudioManager + { + private static WaveOut _out = null; + private static AudioFileReader _reader = null; + private static IAudioProvider _provider = null; + private static bool _running = true; + + public static void Init(IAudioProvider _p) + { +#if !NOSOUND + _provider = _p; + AppearanceManager.OnExit += () => + { + _running = false; + _out?.Stop(); + _reader?.Dispose(); + _out?.Dispose(); + System.IO.File.Delete("temp.mp3"); + }; + var t = new Thread(() => + { + SaveSystem.GameReady += () => + { + while(_out == null) + { + + } + _out.Volume = _provider.Volume; + }; + Random rnd = new Random(); + while(_running == true) + { + int track = rnd.Next(0, _provider.Count); + byte[] mp3 = _provider.GetTrack(track); + System.IO.File.WriteAllBytes("temp.mp3", mp3); + _reader = new AudioFileReader("temp.mp3"); + _out = new WaveOut(); + _out.Init(_reader); + _out.Volume = _provider.Volume; + + _out.Play(); + while(_out.PlaybackState == PlaybackState.Playing) + { + Thread.Sleep(5000); //even when the player isn't playing, this will give a good delay between songs. + } + _reader.Dispose(); + _out.Dispose(); + } + }); + t.IsBackground = true; + t.Start(); +#endif + } + + public static void SetVolume(float volume) + { + _provider.Volume = volume; //persist between songs + _out.Volume = volume; + } + + internal static void Kill() + { + _running = false; + _out.Stop(); + _out.Dispose(); + _reader.Dispose(); + } + } + + public interface IAudioProvider + { + /// <summary> + /// Gets a byte[] array corresponding to an MP3 track given an index. + /// </summary> + /// <param name="index">A track index to use when finding the right track.</param> + /// <returns>The MP3 byte[] array.</returns> + byte[] GetTrack(int index); + + /// <summary> + /// Gets the 1-based count of all available tracks. + /// </summary> + int Count { get; } + + /// <summary> + /// Gets or sets the track player's volume. + /// </summary> + float Volume { get; set; } + } +} diff --git a/ShiftOS_TheReturn/Commands.cs b/ShiftOS_TheReturn/Commands.cs new file mode 100644 index 0000000..3cd1640 --- /dev/null +++ b/ShiftOS_TheReturn/Commands.cs @@ -0,0 +1,819 @@ +/* + * 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. + */ + +#define DEVEL + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using ShiftOS.Engine.Properties; +using System.IO; +using Newtonsoft.Json; +using System.IO.Compression; + +using ShiftOS.Objects; +using Discoursistency.Base.Models.Authentication; +using ShiftOS.Engine.Scripting; +using ShiftOS.Objects.ShiftFS; + +namespace ShiftOS.Engine +{ + [Namespace("infobox", hide = true)] + [RequiresUpgrade("desktop;wm_free_placement")] + public static class InfoboxDebugCommands + { + + [RequiresArgument("title")] + [RequiresArgument("msg")] + [Command("show")] + public static bool ShowInfo(Dictionary<string, object> args) + { + Desktop.InvokeOnWorkerThread(new Action(() => + { + Infobox.Show(args["title"].ToString(), args["msg"].ToString()); + })); + return true; + } + + [RequiresArgument("title")] + [RequiresArgument("msg")] + [Command("yesno")] + public static bool ShowYesNo(Dictionary<string, object> args) + { + bool forwarding = TerminalBackend.IsForwardingConsoleWrites; + var fGuid = TerminalBackend.ForwardGUID; + Action<bool> callback = (result) => + { + TerminalBackend.IsForwardingConsoleWrites = forwarding; + TerminalBackend.ForwardGUID = (forwarding == true) ? fGuid : null; + string resultFriendly = (result == true) ? "yes" : "no"; + Console.WriteLine($"{SaveSystem.CurrentSave.Username} says {resultFriendly}."); + TerminalBackend.IsForwardingConsoleWrites = false; + }; + Desktop.InvokeOnWorkerThread(new Action(() => + { + Infobox.PromptYesNo(args["title"].ToString(), args["msg"].ToString(), callback); + + })); + return true; + } + + [RequiresArgument("title")] + [RequiresArgument("msg")] + [Command("text")] + public static bool ShowText(Dictionary<string, object> args) + { + bool forwarding = TerminalBackend.IsForwardingConsoleWrites; + var fGuid = TerminalBackend.ForwardGUID; + Action<string> callback = (result) => + { + TerminalBackend.IsForwardingConsoleWrites = forwarding; + TerminalBackend.ForwardGUID = (forwarding == true) ? fGuid : null; + Console.WriteLine($"{SaveSystem.CurrentSave.Username} says \"{result}\"."); + TerminalBackend.IsForwardingConsoleWrites = false; + }; + Desktop.InvokeOnWorkerThread(new Action(() => + { + Infobox.PromptText(args["title"].ToString(), args["msg"].ToString(), callback); + })); + return true; + } + + } + + [Namespace("audio")] + public static class AudioCommands + { + [Command("setvol", description = "Set the volume of the system audio to anywhere between 0 and 100.")] + [RequiresArgument("value")] + [RequiresUpgrade("audio_volume")] + public static bool SetVolume(Dictionary<string,object> args) + { + int val = Convert.ToInt32(args["value"].ToString()); + float volume = (val / 100F); + AudioManager.SetVolume(volume); + return true; + } + [RequiresUpgrade("audio_volume")] + [Command("mute", description = "Sets the volume of the system audio to 0")] + public static bool MuteAudio() + { + AudioManager.SetVolume(0); + return true; + } + } + + [RequiresUpgrade("mud_fundamentals")] + [Namespace("mud")] + public static class MUDCommands + { + [MultiplayerOnly] + [Command("status")] + public static bool Status() + { + ServerManager.PrintDiagnostics(); + return true; + } + + [Command("connect")] + public static bool Connect(Dictionary<string, object> args) + { + try + { + string ip = (args.ContainsKey("addr") == true) ? args["addr"] as string : "michaeltheshifter.me"; + int port = (args.ContainsKey("port") == true) ? Convert.ToInt32(args["port"] as string) : 13370; + try + { + ServerManager.Initiate(ip, port); + } + catch (Exception ex) + { + Console.WriteLine("{ERROR}: " + ex.Message); + } + + TerminalBackend.PrefixEnabled = false; + return true; + } + catch (Exception ex) + { + Console.WriteLine("Error running script:" + ex); + return false; + } + } + + [Command("reconnect")] + [RequiresUpgrade("hacker101_deadaccts")] + public static bool Reconnect() + { + Console.WriteLine("--reconnecting to multi-user domain..."); + KernelWatchdog.MudConnected = true; + Console.WriteLine("--done."); + return true; + } + + [MultiplayerOnly] + [Command("disconnect")] + [RequiresUpgrade("hacker101_deadaccts")] + public static bool Disconnect() + { + Console.WriteLine("--connection to multi-user domain severed..."); + KernelWatchdog.MudConnected = false; + return true; + } + + [MultiplayerOnly] + [Command("sendmsg")] + [KernelMode] + [RequiresUpgrade("hacker101_deadaccts")] + [RequiresArgument("header")] + [RequiresArgument("body")] + public static bool SendMessage(Dictionary<string, object> args) + { + ServerManager.SendMessage(args["header"].ToString(), args["body"].ToString()); + return true; + } + } + + [TutorialLock] + [Namespace("trm")] + public static class TerminalCommands + { + [Command("clear")] + public static bool Clear() + { + AppearanceManager.ConsoleOut.Clear(); + return true; + } + + [Command("echo")] + [RequiresArgument("text")] + public static bool Echo(Dictionary<string, object> args) + { + Console.WriteLine(args["text"]); + return true; + } + } + +#if DEVEL + internal class Rock : Exception + { + internal Rock() : base("Someone threw a rock at the window, and the Terminal shattered.") + { + + } + } + + [MultiplayerOnly] + [Namespace("dev")] + public static class ShiftOSDevCommands + { + [Command("rock", description = "A little surprise for unstable builds...")] + public static bool ThrowASandwichingRock() + { + Infobox.Show("He who lives in a glass house shouldn't throw stones...", new Rock().Message); + return false; + } + + + [Command("unbuy")] + [RequiresArgument("upgrade")] + public static bool UnbuyUpgrade(Dictionary<string, object> args) + { + try + { + SaveSystem.CurrentSave.Upgrades[args["upgrade"] as string] = false; + } + catch + { + Console.WriteLine("Upgrade not found."); + } + return true; + } + + [Command("getallupgrades")] + public static bool GetAllUpgrades() + { + Console.WriteLine(JsonConvert.SerializeObject(SaveSystem.CurrentSave.Upgrades, Formatting.Indented)); + return true; + } + + [Command("multarg")] + [RequiresArgument("id")] + [RequiresArgument("name")] + [RequiresArgument("type")] + public static bool MultArg(Dictionary<string, object> args) + { + Console.WriteLine("Success! "+args.ToString()); + return true; + } + + + [Command("freecp")] + public static bool FreeCodepoints(Dictionary<string, object> args) + { + if (args.ContainsKey("amount")) + try + { + int codepointsToAdd = Convert.ToInt32(args["amount"].ToString()); + SaveSystem.TransferCodepointsFrom("dev", codepointsToAdd); + return true; + } + catch (Exception ex) + { + Console.WriteLine("{ERROR}: " + ex.Message); + return true; + } + + SaveSystem.TransferCodepointsFrom("dev", 1000); + return true; + } + + [Command("unlockeverything")] + public static bool UnlockAllUpgrades() + { + foreach (var upg in Shiftorium.GetDefaults()) + { + Shiftorium.Buy(upg.ID, 0); + } + return true; + } + + [Command("info")] + public static bool DevInformation() + { + Console.WriteLine("{SHIFTOS_PLUS_MOTTO}"); + Console.WriteLine("{SHIFTOS_VERSION_INFO}" + Assembly.GetExecutingAssembly().GetName().Version); + return true; + } + [Command("pullfile")] + public static bool PullFile(Dictionary<string, object> args) + { + if (args.ContainsKey("physical") && args.ContainsKey("virtual")) + { + string file = (string)args["physical"]; + string dest = (string)args["virtual"]; + if (System.IO.File.Exists(file)) + { + Console.WriteLine("Pulling physical file to virtual drive..."); + byte[] filebytes = System.IO.File.ReadAllBytes(file); + ShiftOS.Objects.ShiftFS.Utils.WriteAllBytes(dest, filebytes); + } + else + { + Console.WriteLine("The specified file does not exist on the physical drive."); + } + } + else + { + Console.WriteLine("You must supply a physical path."); + } + return true; + } + [Command("crash")] + public static bool CrashInstantly() + { + CrashHandler.Start(new Exception("ShiftOS was sent a command to forcefully crash.")); + return true; + } + } +#endif + + [Namespace("sos")] + public static class ShiftOSCommands + { + [RemoteLock] + [Command("shutdown")] + public static bool Shutdown() + { + TerminalBackend.InvokeCommand("sos.save"); + SaveSystem.ShuttingDown = true; + AppearanceManager.Exit(); + return true; + } + + [Command("lang", "{COMMAND_SOS_LANG_USAGE}", "{COMMAND_SOS_LANG_DESCRIPTION}")] + [RequiresArgument("language")] + public static bool SetLanguage(Dictionary<string, object> userArgs) + { + try + { + string lang = ""; + + if (userArgs.ContainsKey("language")) + lang = (string)userArgs["language"]; + else + throw new Exception("You must specify a valid 'language' value."); + + if (Localization.GetAllLanguages().Contains(lang)) + { + SaveSystem.CurrentSave.Language = lang; + SaveSystem.SaveGame(); + Console.WriteLine("{LANGUAGE_CHANGED}"); + return true; + } + + throw new Exception($"Couldn't find language with ID: {lang}"); + } + catch + { + return false; + } + } + + [Command("help", "{COMMAND_HELP_USAGE}", "{COMMAND_HELP_DESCRIPTION}")] + public static bool Help() + { + foreach (var exec in System.IO.Directory.GetFiles(Environment.CurrentDirectory)) + { + if (exec.EndsWith(".exe") || exec.EndsWith(".dll")) + { + try + { + 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<string, string>() { + {"%ns", ns.name}, + {"%cmd", cmd.name} + }) : ""; + + Console.WriteLine($"{{COMMAND}}{ns.name}.{cmd.name}" + usageparse + descriptionparse); + } + } + } + } + + } + } + + } + } + } + } + + } + catch { } + } + } + + return true; + } + + [MultiplayerOnly] + [Command("save")] + public static bool Save() + { + SaveSystem.SaveGame(); + return true; + } + + [MultiplayerOnly] + [Command("status")] + public static bool Status() + { + Console.WriteLine($@"ShiftOS version {Assembly.GetExecutingAssembly().GetName().Version.ToString()} + +Codepoints: {SaveSystem.CurrentSave.Codepoints} +Upgrades: {SaveSystem.CurrentSave.CountUpgrades()} installed, + {Shiftorium.GetAvailable().Length} available"); + return true; + } + } + + [MultiplayerOnly] + [Namespace("shiftorium")] + public static class ShiftoriumCommands + { + [Command("buy")] + [RequiresArgument("upgrade")] + public static bool BuyUpgrade(Dictionary<string, object> userArgs) + { + try + { + string upgrade = ""; + + if (userArgs.ContainsKey("upgrade")) + upgrade = (string)userArgs["upgrade"]; + else + throw new Exception("You must specify a valid 'upgrade' value."); + + foreach (var upg in Shiftorium.GetAvailable()) + { + if (upg.ID == upgrade) + { + Shiftorium.Buy(upgrade, upg.Cost); + return true; + } + } + + throw new Exception($"Couldn't find upgrade with ID: {upgrade}"); + } + catch + { + return false; + } + } + + [RequiresUpgrade("shiftorium_bulk_buy")] + [Command("bulkbuy")] + [RequiresArgument("upgrades")] + public static bool BuyBulk(Dictionary<string, object> args) + { + if (args.ContainsKey("upgrades")) + { + string[] upgrade_list = (args["upgrades"] as string).Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries); + foreach (var upg in upgrade_list) + { + var dict = new Dictionary<string, object>(); + dict.Add("upgrade", upg); + BuyUpgrade(dict); + } + } + else + { + throw new Exception("Please specify a list of upgrades in the 'upgrades' argument. Each upgrade is separated by a comma."); + } + return true; + } + + + [Command("info")] + public static bool ViewInfo(Dictionary<string, object> userArgs) + { + try + { + string upgrade = ""; + + if (userArgs.ContainsKey("upgrade")) + upgrade = (string)userArgs["upgrade"]; + else + throw new Exception("You must specify a valid 'upgrade' value."); + + foreach (var upg in Shiftorium.GetDefaults()) + { + if (upg.ID == upgrade) + { + Console.WriteLine($@"Information for {upgrade}: + +{upg.Category}: {upg.Name} - {upg.Cost} Codepoints +------------------------------------------------------ + +{upg.Description} + +To buy this upgrade, run: +shiftorium.buy{{upgrade:""{upg.ID}""}}"); + return true; + } + } + + throw new Exception($"Couldn't find upgrade with ID: {upgrade}"); + } + catch + { + return false; + } + } + + [Command("categories")] + public static bool ListCategories() + { + foreach(var cat in Shiftorium.GetCategories()) + { + Console.WriteLine($"{cat} - {Shiftorium.GetAvailable().Where(x=>x.Category==cat).Count()} upgrades"); + } + return true; + } + + [Command("list")] + public static bool ListAll(Dictionary<string, object> args) + { + try + { + bool showOnlyInCategory = false; + + string cat = "Other"; + + if (args.ContainsKey("cat")) + { + showOnlyInCategory = true; + cat = args["cat"].ToString(); + } + + Dictionary<string, int> upgrades = new Dictionary<string, int>(); + int maxLength = 5; + + IEnumerable<ShiftoriumUpgrade> upglist = Shiftorium.GetAvailable(); + if (showOnlyInCategory) + { + if (Shiftorium.IsCategoryEmptied(cat)) + { + ConsoleEx.Bold = true; + ConsoleEx.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Shiftorium Query Error"); + Console.WriteLine(); + ConsoleEx.Bold = false; + ConsoleEx.ForegroundColor = ConsoleColor.Gray; + Console.WriteLine("Either there are no upgrades in the category \"" + cat + "\" or the category was not found."); + return true; + } + upglist = Shiftorium.GetAvailable().Where(x => x.Category == cat); + } + + + if(upglist.Count() == 0) + { + ConsoleEx.Bold = true; + ConsoleEx.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("No upgrades available!"); + Console.WriteLine(); + ConsoleEx.Bold = false; + ConsoleEx.ForegroundColor = ConsoleColor.Gray; + Console.WriteLine("You have installed all available upgrades for your system. Please check back later for more."); + return true; + + } + foreach (var upg in upglist) + { + if (upg.ID.Length > maxLength) + { + maxLength = upg.ID.Length; + } + + upgrades.Add(upg.ID, upg.Cost); + } + + Console.WriteLine("ID".PadRight((maxLength + 5) - 2) + "Cost (Codepoints)"); + + foreach (var upg in upgrades) + { + Console.WriteLine(upg.Key.PadRight((maxLength + 5) - upg.Key.Length) + " " + upg.Value.ToString()); + } + return true; + } + catch (Exception e) + { + CrashHandler.Start(e); + return false; + } + } + } + + [Namespace("win")] + public static class WindowCommands + { + + + + [RemoteLock] + [Command("list")] + public static bool List() + { + Console.WriteLine("Window ID\tName"); + foreach (var app in AppearanceManager.OpenForms) + { + //Windows are displayed the order in which they were opened. + Console.WriteLine($"{AppearanceManager.OpenForms.IndexOf(app)}\t{app.Text}"); + } + return true; + } + + [RemoteLock] + [Command("open")] + public static bool Open(Dictionary<string, object> args) + { + try + { + if (args.ContainsKey("app")) + { + var app = args["app"] as string; + //ANNND now we start reflecting... + foreach (var asmExec in System.IO.Directory.GetFiles(Environment.CurrentDirectory)) + { + if (asmExec.EndsWith(".exe") || asmExec.EndsWith(".dll")) + { + var asm = Assembly.LoadFile(asmExec); + try + { + foreach (var type in asm.GetTypes()) + { + if (type.BaseType == typeof(UserControl)) + { + foreach (var attr in type.GetCustomAttributes(false)) + { + if (attr is WinOpenAttribute) + { + if (app == (attr as WinOpenAttribute).ID) + { + if (SaveSystem.CurrentSave.Upgrades.ContainsKey(app)) + { + if (Shiftorium.UpgradeInstalled(app)) + { + IShiftOSWindow frm = Activator.CreateInstance(type) as IShiftOSWindow; + AppearanceManager.SetupWindow(frm); + return true; + } + else + { + throw new Exception($"{app} was not found on your system! Try looking in the shiftorium..."); + } + } + else + { + IShiftOSWindow frm = Activator.CreateInstance(type) as IShiftOSWindow; + AppearanceManager.SetupWindow(frm); + return true; + } + } + } + } + } + } + } + catch { } + + } + } + + } + else + { + foreach (var asmExec in System.IO.Directory.GetFiles(Environment.CurrentDirectory)) + { + if (asmExec.EndsWith(".exe") || asmExec.EndsWith(".dll")) + { + try + { + var asm = Assembly.LoadFile(asmExec); + + foreach (var type in asm.GetTypes()) + { + if (type.GetInterfaces().Contains(typeof(IShiftOSWindow))) + { + foreach (var attr in type.GetCustomAttributes(false)) + { + if (attr is WinOpenAttribute) + { + if (Shiftorium.UpgradeAttributesUnlocked(type)) + { + Console.WriteLine("win.open{app:\"" + (attr as WinOpenAttribute).ID + "\"}"); + } + } + } + } + } + } + catch { } + } + } + + + return true; + } + Console.WriteLine("Couldn't find the specified app on your system."); + return true; + } + catch (Exception ex) + { + Console.WriteLine("Error running script:" + ex); + return false; + } + } + + [RemoteLock] + [Command("close", usage = "{win:integer32}", description ="Closes the specified window.")] + [RequiresArgument("win")] + [RequiresUpgrade("close_command")] + public static bool CloseWindow(Dictionary<string, object> args) + { + int winNum = -1; + if (args.ContainsKey("win")) + winNum = Convert.ToInt32(args["win"].ToString()); + string err = null; + + if (winNum < 0 || winNum >= AppearanceManager.OpenForms.Count) + err = "The window number must be between 0 and " + (AppearanceManager.OpenForms.Count - 1).ToString() + "."; + + if (string.IsNullOrEmpty(err)) + { + Console.WriteLine($"Closing {AppearanceManager.OpenForms[winNum].Text}..."); + AppearanceManager.Close(AppearanceManager.OpenForms[winNum].ParentWindow); + } + else + { + Console.WriteLine(err); + } + + return true; + } + + } +} diff --git a/ShiftOS_TheReturn/Localization.cs b/ShiftOS_TheReturn/Localization.cs new file mode 100644 index 0000000..c1a6bd6 --- /dev/null +++ b/ShiftOS_TheReturn/Localization.cs @@ -0,0 +1,219 @@ +/* + * 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 Newtonsoft.Json; +using ShiftOS.Objects.ShiftFS; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShiftOS.Engine +{ + public interface ILanguageProvider + { + List<string> GetJSONTranscripts(); + void WriteDefaultTranscript(); + void WriteTranscript(); + string GetCurrentTranscript(); + string[] GetAllLanguages(); + } + + public static class Localization + { + private static ILanguageProvider _provider = null; + private static string _languageid = null; + + public static string[] GetAllLanguages() + { + if(_provider == null) + { + return JsonConvert.DeserializeObject<string[]>(Properties.Resources.languages); + } + else + { + return _provider.GetAllLanguages(); + } + } + + public static void SetupTHETRUEDefaultLocals() + { + if (_provider == null) + { + var lines = Properties.Resources.strings_en; + var path = "english.local"; + Utils.WriteAllText(Paths.GetPath(path), lines); + } + else if (SaveSystem.CurrentSave == null) + { + var lines = Properties.Resources.strings_en; + var path = "english.local"; + Utils.WriteAllText(Paths.GetPath(path), lines); + } + else + { + _provider.WriteTranscript(); + } + } + + public static void SetupDefaultLocals(string lines, string path) + { + Utils.WriteAllText(Paths.GetPath(path), lines); + + } + + + /// <summary> + /// Takes in a string and parses localization blocks into text blocks in the current language. + /// </summary> + /// <example>"{CODEPOINTS}: 0" will come out as "Codepoints: 0" if the current language is english.</example> + /// <param name="original">The string to parse</param> + /// <returns>The parsed string.</returns> + /// + public static string Parse(string original) + { + return Parse(original, new Dictionary<string, string>()); + } + + + public static string Parse(string original, Dictionary<string, string> replace) + { + Dictionary<string, string> localizationStrings = new Dictionary<string, string>(); + + + + try + { + localizationStrings = JsonConvert.DeserializeObject<Dictionary<string, string>>(_provider.GetCurrentTranscript()); + } + catch + { + localizationStrings = JsonConvert.DeserializeObject<Dictionary<string, string>>(Utils.ReadAllText(Paths.GetPath("english.local"))); + } + + foreach (var kv in localizationStrings) + { + original = original.Replace(kv.Key, kv.Value); + } + + List<string> orphaned = new List<string>(); + if (Utils.FileExists("0:/dev_orphaned_lang.txt")) + { + orphaned = JsonConvert.DeserializeObject<List<string>>(Utils.ReadAllText("0:/dev_orphaned_lang.txt")); + } + + + int start_index = 0; + int length = 0; + bool indexing = false; + + foreach (var c in original) + { + if (c == '{') + { + start_index = original.IndexOf(c); + indexing = true; + } + + if (indexing == true) + { + length++; + if (c == '}') + { + indexing = false; + string o = original.Substring(start_index, length); + if (!orphaned.Contains(o)) + { + orphaned.Add(o); + } + start_index = 0; + length = 0; + } + } + } + + if (orphaned.Count > 0) + { + Utils.WriteAllText("0:/dev_orphaned_lang.txt", JsonConvert.SerializeObject(orphaned, Formatting.Indented)); + } + + //string original2 = Parse(original); + + string usernameReplace = ""; + string domainReplace = ""; + + if (SaveSystem.CurrentSave != null) + { + usernameReplace = SaveSystem.CurrentSave.Username; + domainReplace = SaveSystem.CurrentSave.SystemName; + } + + string namespaceReplace = ""; + string commandReplace = ""; + + if (TerminalBackend.latestCommmand != "" && TerminalBackend.latestCommmand.IndexOf('.') > -1) + { + namespaceReplace = TerminalBackend.latestCommmand.Split('.')[0]; + commandReplace = TerminalBackend.latestCommmand.Split('.')[1]; + } + + Dictionary<string, string> defaultReplace = new Dictionary<string, string>() { + {"%username", usernameReplace}, + {"%domain", domainReplace}, + {"%ns", namespaceReplace}, + {"%cmd", commandReplace}, + {"%cp", SaveSystem.CurrentSave?.Codepoints.ToString() }, + }; + + foreach (KeyValuePair<string, string> replacement in replace) + { + original = original.Replace(replacement.Key, Parse(replacement.Value)); + } + + foreach (KeyValuePair<string, string> replacement in defaultReplace) + { + original = original.Replace(replacement.Key, replacement.Value); + } + + return original; + } + + public static void RegisterProvider(ILanguageProvider p) + { + _provider = p; + } + + public static void SetLanguageID(string id) + { + _languageid = id; + } + + public static string GetLanguageID() + { + return _languageid; + } + } +} diff --git a/ShiftOS_TheReturn/Resources/strings_de.txt b/ShiftOS_TheReturn/Resources/strings_de.txt index 10535c8..06ef9d7 100644 --- a/ShiftOS_TheReturn/Resources/strings_de.txt +++ b/ShiftOS_TheReturn/Resources/strings_de.txt @@ -36,7 +36,7 @@ Wenn eine Systemdatei von dem Virenscanner erkannt wird, wird sie ersetzt.", "{TERMINAL}":"Terminal", "{PONG}":"Pong", "{CODEPOINTS}":"Codepoints", - "{CODEPOINTS_VALUE}":"%cp " + "{CODEPOINTS_VALUE}":"%cp ", "{SHIFTORIUM}":"Shiftorium", "{HACK}":"Hack", "{SHIFTER}":"Shifter", @@ -151,15 +151,17 @@ Wenn eine Systemdatei von dem Virenscanner erkannt wird, wird sie ersetzt.", "{ERROR_COMMAND_WRONG}": "Check your syntax and try again", "{LOGIN_EXP}": "Login as the admin of the multi user domain.", - "{USAGE}": "Usage: ", + "{USAGE}": "Verwendung: ", "{NAMESPACE_SOS_DESCRIPTION}":"The ShiftOS Namespace", "{COMMAND_HELP_USAGE}":"%ns.%cmd{[topic:]}", - "{COMMAND_HELP_DESCRIPTION}":"Lists all commands", + "{COMMAND_HELP_DESCRIPTION}":"Listet alle Befehle auf", "{COMMAND_SOS_SHUTDOWN_USAGE}":"%ns.%cmd", "{COMMAND_SOS_SHUTDOWN_DESCRIPTION}":"Saves and shuts down ShiftOS", "{COMMAND_SOS_STATUS_USAGE}":"%ns.%cmd", "{COMMAND_SOS_STATUS_DESCRIPTION}":"Displays how many codepoints you have", + "{COMMAND_SOS_LANG_USAGE}":"%ns.%cmd{[language:\"english\"]}", + "{COMMAND_SOS_LANG_DESCRIPTION}":"Sprache �ndern.", "{COMMAND_DEV_CRASH_USAGE}":"%ns.%cmd", "{COMMAND_DEV_CRASH_DESCRIPTION}":"Shuts down ShiftOS forcefully", "{COMMAND_DEV_UNLOCKEVERYTHING_USAGE}":"%ns.%cmd", @@ -177,7 +179,7 @@ Wenn eine Systemdatei von dem Virenscanner erkannt wird, wird sie ersetzt.", "{COMMAND_DEV_MULTARG_USAGE}":"%ns.%cmd{id:,name:,type:}", "{COMMAND_DEV_MULTARG_DESCRIPTION}":"A command which requiers multiple arguments", - "{ERR_COMMAND_NOT_FOUND}":"Command not found.", + "{ERR_COMMAND_NOT_FOUND}":"Befehl nicht gefunden.", "{MUD_ERROR}":"MUD error", "{PROLOGUE_NO_USER_DETECTED}":"No user detected. Please enter a username.", @@ -200,26 +202,44 @@ Wenn eine Systemdatei von dem Virenscanner erkannt wird, wird sie ersetzt.", "{SENTIENCE_POSSIBLEHUMAN}":"Sentience: Possible human - user can perform actions based on a choice.", "{SENTIENCE_POSSIBLEHUMANPLUS}":"Sentience: Possible human+ - user can infer, and can pass arguments.", "{SENTIENCE_HUMAN}":"Sentience: Human. Thanks for your patience.", - "{SENTIENCE_INVALIDPASSWORD}":"The password you entered is invalid.", + "{SENTIENCE_INVALIDPASSWORD}":"Das eingegebene Passwort ist ung�ltig.", "{ARGS_PASSWORD}":"password", "{SHIFTOS_PLUS_MOTTO}":"ShiftOS, Shift it YOUR way.", "{SHIFTOS_VERSION_INFO}":"ShiftOS Version: ", - "{USER_NAME}":"Username", + "{USER_NAME}":"Benutzername", "{DISCOURSE_INTEGRATION}":"Discourse Integration", "{SYSTEM_NAME}":"System Name", "{USER_INFO}":"User Information", "{SELECT_LANG}":"Select language", "{WELCOME_TO_SHIFTOS}":"Welcome to ShiftOS Alpha!", - "{CREATE}":"Create", - "{INSTALL}":"Install", + "{CREATE}":"Erstellen", + "{INSTALL}":"Installieren", "{ALIAS}":"Alias:", "{OBSOLETE_SYS_SHUTDOWN}":"sys.shutdown is obsolete", "{PY_EXCEPTION}":"There was an error running python code.", - "{LUA_ERROR}":"There was an error running lua code." + "{LUA_ERROR}":"There was an error running lua code.", + "{LANGUAGE_CHANGED}":"Die Sprache wurde ge�ndert. Bitte �ndern Sie ShiftOS neu, damit �nderungen voll wirksam werden.", "{TERMINAL_NAME}":"Terminal", "{ARTPAD_NAME}":"Artpad", "{PONG_NAME}":"Pong", + "{WAV_PLAYER_NAME}":"WAV Player", + "{SHIFTORIUM_NAME}":"Shiftorium", + "{TEXTPAD_NAME}":"TextPad", + "{VIRUS_SCANNER_NAME}":"Virus Scanner", + "{SKIN_LOADER_NAME}":"Skin Loader", + "{SHIFTER_NAME}":"Shifter", + "{NAME_CHANGER_NAME}":"Name Changer", + "{MUD_PASSWORD_CRACKER_NAME}":"Multi-User Domain Password Cracker v1.0", + "{MUD_CONTROL_CENTRE_NAME}":"MUD Control Centre", + "{MUD_AUTHENTICATOR_NAME}":"Multi-User Domain Admin Panel", + "{GRAPHIC_PICKER_NAME}":"Graphic Picker", + "{FILE_SKIMMER_NAME}":"File Skimmer", + "{FILE_DIALOG_NAME}":"File Dialog", + "{DIALOG_NAME}":"Dialog", + "{COLOR_PICKER_NAME}":"Color Picker", + "{CHAT_NAME}":"Chat", + "{GERMAN_SECRET}":"guten tag polen ist anschluss", }
\ No newline at end of file diff --git a/ShiftOS_TheReturn/Resources/strings_en.txt b/ShiftOS_TheReturn/Resources/strings_en.txt index c42edab..68719c0 100644 --- a/ShiftOS_TheReturn/Resources/strings_en.txt +++ b/ShiftOS_TheReturn/Resources/strings_en.txt @@ -32,7 +32,7 @@ If a system file is deleted by the virus scanner, it will be replaced.", "{TERMINAL}":"Terminal", "{PONG}":"Pong", "{CODEPOINTS}":"Codepoints", - "{CODEPOINTS_VALUE}":"%cp " + "{CODEPOINTS_VALUE}":"%cp ", "{SHIFTORIUM}":"Shiftorium", "{HACK}":"Hack", "{SHIFTER}":"Shifter", @@ -215,7 +215,7 @@ If a system file is deleted by the virus scanner, it will be replaced.", "{ALIAS}":"Alias:", "{OBSOLETE_SYS_SHUTDOWN}":"sys.shutdown is obsolete", "{PY_EXCEPTION}":"There was an error running python code.", - "{LUA_ERROR}":"There was an error running lua code." + "{LUA_ERROR}":"There was an error running lua code.", "{TERMINAL_NAME}":"Terminal", "{ARTPAD_NAME}":"Artpad", diff --git a/ShiftOS_TheReturn/SaveSystem.cs b/ShiftOS_TheReturn/SaveSystem.cs new file mode 100644 index 0000000..9ff3111 --- /dev/null +++ b/ShiftOS_TheReturn/SaveSystem.cs @@ -0,0 +1,332 @@ +/* + * 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. + */ + +//#define ONLINEMODE + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.IO; +using Newtonsoft.Json; +using ShiftOS.Objects; +using ShiftOS.Objects.ShiftFS; +using oobe = ShiftOS.Engine.OutOfBoxExperience; +using static System.Net.Mime.MediaTypeNames; + +namespace ShiftOS.Engine +{ + public class EngineConfig + { + public bool ConnectToMud = true; + public string MudDefaultIP = "dome.rol.im"; + public int MudDefaultPort = 13370; + } + + public static class SaveSystem + { + public static bool ShuttingDown = false; + + public static Save CurrentSave { get; set; } + + /// <summary> + /// Start the entire ShiftOS engine. + /// </summary> + /// <param name="useDefaultUI">Whether ShiftOS should initiate it's Windows Forms front-end.</param> + public static void Begin(bool useDefaultUI = true) + { + AppDomain.CurrentDomain.UnhandledException += (o, a) => + { + CrashHandler.Start((Exception)a.ExceptionObject); + }; + + if (!System.IO.File.Exists(Paths.SaveFile)) + { + var root = new ShiftOS.Objects.ShiftFS.Directory(); + root.Name = "System"; + root.permissions = Permissions.All; + System.IO.File.WriteAllText(Paths.SaveFile, JsonConvert.SerializeObject(root)); + } + + if (Utils.Mounts.Count == 0) + Utils.Mount(System.IO.File.ReadAllText(Paths.SaveFile)); + Paths.Init(); + + Localization.SetupTHETRUEDefaultLocals(); + SkinEngine.Init(); + + TerminalBackend.OpenTerminal(); + + TerminalBackend.InStory = true; + var thread = new Thread(new ThreadStart(() => + { + //Do not uncomment until I sort out the copyright stuff... - Michael + //AudioManager.Init(); + + var defaultConf = new EngineConfig(); + if (System.IO.File.Exists("engineconfig.json")) + defaultConf = JsonConvert.DeserializeObject<EngineConfig>(System.IO.File.ReadAllText("engineconfig.json")); + else + { + System.IO.File.WriteAllText("engineconfig.json", JsonConvert.SerializeObject(defaultConf, Formatting.Indented)); + } + + Thread.Sleep(350); + Console.WriteLine("Initiating kernel..."); + Thread.Sleep(250); + Console.WriteLine("Reading filesystem..."); + Thread.Sleep(100); + Console.WriteLine("Reading configuration..."); + + Console.WriteLine("{CONNECTING_TO_MUD}"); + + if (defaultConf.ConnectToMud == true) + { + bool guidReceived = false; + ServerManager.GUIDReceived += (str) => + { + //Connection successful! Stop waiting! + guidReceived = true; + Console.WriteLine("Connection successful."); + }; + + try + { + + ServerManager.Initiate("secondary4162.cloudapp.net", 13370); + //This haults the client until the connection is successful. + while (ServerManager.thisGuid == new Guid()) + { + + } + Console.WriteLine("GUID received - bootstrapping complete."); + FinishBootstrap(); + } + catch (Exception ex) + { + //No errors, this never gets called. + Console.WriteLine("{ERROR}: " + ex.Message); + Thread.Sleep(3000); + ServerManager.StartLANServer(); + while (ServerManager.thisGuid == new Guid()) + { + + } + Console.WriteLine("GUID received - bootstrapping complete."); + FinishBootstrap(); + } + } + else + { + ServerManager.StartLANServer(); + } + + //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() + { + KernelWatchdog.Log("mud_handshake", "handshake successful: kernel watchdog access code is \"" + ServerManager.thisGuid.ToString() + "\""); + + ServerManager.MessageReceived += (msg) => + { + if (msg.Name == "mud_savefile") + { + CurrentSave = JsonConvert.DeserializeObject<Save>(msg.Contents); + } + else if (msg.Name == "mud_login_denied") + { + oobe.PromptForLogin(); + } + }; + + ReadSave(); + + while (CurrentSave == null) + { + + } + + Localization.SetupTHETRUEDefaultLocals(); + + Shiftorium.Init(); + + while (CurrentSave.StoryPosition < 1) + { + + } + + Thread.Sleep(75); + + Thread.Sleep(50); + Console.WriteLine("{SYSTEM_INITIATED}"); + + TerminalBackend.InStory = false; + TerminalBackend.PrefixEnabled = true; + Shiftorium.LogOrphanedUpgrades = true; + Desktop.InvokeOnWorkerThread(new Action(() => + { + ShiftOS.Engine.Scripting.LuaInterpreter.RunSft(Paths.GetPath("kernel.sft")); + })); + Desktop.InvokeOnWorkerThread(new Action(() => Desktop.PopulateAppLauncher())); + if (CurrentSave.StoryPosition == 1) + { + Desktop.InvokeOnWorkerThread(new Action(() => + { + TutorialManager.StartTutorial(); + + })); + while (TutorialManager.IsInTutorial == true) { } + GameReady?.Invoke(); + } + else + { + GameReady?.Invoke(); + } + } + + public delegate void EmptyEventHandler(); + + public static List<ClientSave> Users + { + get; + private set; + } + + public static event EmptyEventHandler GameReady; + + public static void TransferCodepointsToVoid(int amount) + { + CurrentSave.Codepoints -= amount; + NotificationDaemon.AddNotification(NotificationType.CodepointsSent, amount); + } + + public static void Restart() + { + TerminalBackend.InvokeCommand("sos.shutdown"); + System.Windows.Forms.Application.Restart(); + } + + public static void ReadSave() + { + //Migrate old saves. + if(System.IO.Directory.Exists("C:\\ShiftOS2")) + { + Console.WriteLine("Old save detected. Migrating filesystem to MFS..."); + foreach (string file in System.IO.Directory.EnumerateDirectories("C:\\ShiftOS2") +.Select(d => new DirectoryInfo(d).FullName)) + { + if(!Utils.DirectoryExists(file.Replace("C:\\ShiftOS2\\", "0:/").Replace("\\", "/"))) + Utils.CreateDirectory(file.Replace("C:\\ShiftOS2\\", "0:/").Replace("\\", "/")); + } + foreach (string file in System.IO.Directory.EnumerateFiles("C:\\ShiftOS2")) + { + + string rfile = Path.GetFileName(file); + Utils.WriteAllBytes(file.Replace("C:\\ShiftOS2\\", "0:/").Replace("\\", "/"), System.IO.File.ReadAllBytes(file)); + Console.WriteLine("Exported file " + file); + } + + } + + + if (Utils.FileExists(Paths.SaveFileInner)) + { + oobe.ShowSaveTransfer(JsonConvert.DeserializeObject<Save>(Utils.ReadAllText(Paths.SaveFileInner))); + } + else + { + if (Utils.FileExists(Paths.GetPath("user.dat"))) + { + var userdat = JsonConvert.DeserializeObject<ClientSave>(Utils.ReadAllText(Paths.GetPath("user.dat"))); + + ServerManager.SendMessage("mud_login", $@"{{ + username: ""{userdat.Username}"", + password: ""{userdat.Password}"" +}}"); + } + else + { + NewSave(); + } + } + + } + + public static void NewSave() + { + AppearanceManager.Invoke(new Action(() => + { + CurrentSave = new Save(); + CurrentSave.Codepoints = 0; + CurrentSave.Upgrades = new Dictionary<string, bool>(); + Shiftorium.Init(); + oobe.Start(CurrentSave); + })); + } + + public static void SaveGame() + { + if(!Shiftorium.Silent) + Console.WriteLine(""); + if(!Shiftorium.Silent) + Console.Write("{SE_SAVING}... "); + if (SaveSystem.CurrentSave != null) + { + string username = CurrentSave.Username; + string password = CurrentSave.Password; + + Utils.WriteAllText(Paths.GetPath("user.dat"), $@"{{ + username: ""{username}"", + password: ""{password}"" +}}"); + + ServerManager.SendMessage("mud_save", JsonConvert.SerializeObject(CurrentSave, Formatting.Indented)); + } + if (!Shiftorium.Silent) + Console.WriteLine(" ...{DONE}."); + System.IO.File.WriteAllText(Paths.SaveFile, Utils.ExportMount(0)); + } + + public static void TransferCodepointsFrom(string who, long amount) + { + NotificationDaemon.AddNotification(NotificationType.CodepointsReceived, amount); + CurrentSave.Codepoints += amount; + } + } + + public delegate void TextSentEventHandler(string text); + + public class DeveloperAttribute : Attribute + { + + } +} diff --git a/ShiftOS_TheReturn/ServerManager.cs b/ShiftOS_TheReturn/ServerManager.cs new file mode 100644 index 0000000..4fce247 --- /dev/null +++ b/ShiftOS_TheReturn/ServerManager.cs @@ -0,0 +1,248 @@ +/* + * MIT License + * + * Copyright (c) 2017 Michael VanOverbeek and ShiftOS devs + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ShiftOS.Objects; +using NetSockets; +using System.Windows.Forms; +using System.Threading; +using ShiftOS; +using static ShiftOS.Engine.SaveSystem; +using Newtonsoft.Json; + +namespace ShiftOS.Engine +{ + public static class ServerManager + { + public static void PrintDiagnostics() + { + Console.WriteLine($@"{{CLIENT_DIAGNOSTICS}} + +{{GUID}}: {thisGuid} +{{CLIENT_DATA}}: + +{JsonConvert.SerializeObject(client, Formatting.Indented)}"); + } + + public static Guid thisGuid { get; private set; } + private static NetObjectClient client { get; set; } + private static bool UserDisconnect = false; + + public static void Disconnect() + { + UserDisconnect = true; + if (client != null) + { + client.Disconnect(); + } + Disconnected?.Invoke(); + + } + + public static event EmptyEventHandler Disconnected; + + public static void InitiateMUDHack() + { + MessageReceived += ServerManager_MessageReceived; + SendMessage("mudhack_init", ""); + } + + public static event Action<string> ServerPasswordGenerated; + public static event EmptyEventHandler ServerAccessGranted; + public static event EmptyEventHandler ServerAccessDenied; + public static event Action<string> GUIDReceived; + public static event Action<List<OnlineUser>> UsersReceived; + + private static void ServerManager_MessageReceived(ServerMessage msg) + { + switch(msg.Name) + { + case "mudhack_users": + UsersReceived?.Invoke(JsonConvert.DeserializeObject<List<OnlineUser>>(msg.Contents)); + break; + case "mudhack_init": + ServerPasswordGenerated?.Invoke(msg.Contents); + break; + case "mudhack_denied": + ServerAccessDenied?.Invoke(); + break; + case "mudhack_granted": + ServerAccessGranted?.Invoke(); + break; + case "getguid_fromserver": + if(SaveSystem.CurrentSave.Username == msg.Contents) + { + client.Send(new NetObject("yes_i_am", new ServerMessage + { + Name = "getguid_reply", + GUID = msg.GUID, + Contents = thisGuid.ToString(), + })); + } + break; + case "getguid_reply": + GUIDReceived?.Invoke(msg.Contents); + break; + } + } + + public static void Detach_ServerManager_MessageReceived() + { + MessageReceived -= new ServerMessageReceived(ServerManager_MessageReceived); + } + + public static void Initiate(string mud_address, int port) + { + client = new NetObjectClient(); + client.OnDisconnected += (o, a) => + { + if (!UserDisconnect) + { + TerminalBackend.PrefixEnabled = true; + ConsoleEx.ForegroundColor = ConsoleColor.Red; + ConsoleEx.Bold = true; + Console.Write($@"Disconnected from MUD: "); + ConsoleEx.Bold = false; + ConsoleEx.Italic = true; + ConsoleEx.ForegroundColor = ConsoleColor.DarkYellow; + Console.WriteLine("You have been disconnected from the multi-user domain for an unknown reason. Your save data is preserved within the kernel and you will be reconnected shortly."); + TerminalBackend.PrefixEnabled = true; + TerminalBackend.PrintPrompt(); + Initiate(mud_address, port); + } + }; + client.OnReceived += (o, a) => + { + var msg = a.Data.Object as ServerMessage; + if (msg.Name == "Welcome") + { + thisGuid = new Guid(msg.Contents); + GUIDReceived?.Invoke(msg.Contents); + TerminalBackend.PrefixEnabled = true; + TerminalBackend.PrintPrompt(); + } + else if(msg.Name == "allusers") + { + foreach(var acc in JsonConvert.DeserializeObject<string[]>(msg.Contents)) + { + Console.WriteLine(acc); + } + TerminalBackend.PrintPrompt(); + } + else if(msg.Name == "update_your_cp") + { + var args = JsonConvert.DeserializeObject<Dictionary<string, object>>(msg.Contents); + if(args["username"] as string == SaveSystem.CurrentSave.Username) + { + SaveSystem.CurrentSave.Codepoints += (long)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."); + })); + SaveSystem.SaveGame(); + } + } + else if(msg.Name =="broadcast") + { + Console.WriteLine(msg.Contents); + } + else if (msg.Name == "Error") + { + var ex = JsonConvert.DeserializeObject<Exception>(msg.Contents); + TerminalBackend.PrefixEnabled = true; + ConsoleEx.ForegroundColor = ConsoleColor.Red; + ConsoleEx.Bold = true; + Console.Write($@"{{MUD_ERROR}}: "); + ConsoleEx.Bold = false; + ConsoleEx.Italic = true; + ConsoleEx.ForegroundColor = ConsoleColor.DarkYellow; + Console.WriteLine(ex.Message); + TerminalBackend.PrefixEnabled = true; + TerminalBackend.PrintPrompt(); + } + else + { + MessageReceived?.Invoke(msg); + } + }; + + client.Connect(mud_address, port); + + } + + public static void SendMessage(string name, string contents) + { + var sMsg = new ServerMessage + { + Name = name, + Contents = contents, + GUID = thisGuid.ToString(), + }; + + client.Send(new NetObject("msg", sMsg)); + + } + + private static bool singleplayer = false; + public static bool IsSingleplayer { get { return singleplayer; } } + + public static void StartLANServer() + { + singleplayer = true; + ShiftOS.Server.Program.ServerStarted += (address) => + { + Console.WriteLine($"Connecting to {address}..."); + Initiate(address, 13370); + }; + Disconnected += () => + { + ShiftOS.Server.Program.Stop(); + }; + ShiftOS.Server.Program.Main(new[] { "" }); + + + } + + + public static event ServerMessageReceived MessageReceived; + + } + + public delegate void ServerMessageReceived(ServerMessage msg); + + public class MultiplayerOnlyAttribute : Attribute + { + /// <summary> + /// Marks this application as a multiplayer-only application. + /// </summary> + public MultiplayerOnlyAttribute() + { + + } + } +} diff --git a/ShiftOS_TheReturn/Shiftorium.cs b/ShiftOS_TheReturn/Shiftorium.cs new file mode 100644 index 0000000..43ea13a --- /dev/null +++ b/ShiftOS_TheReturn/Shiftorium.cs @@ -0,0 +1,332 @@ +/* + * 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 Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using static ShiftOS.Engine.SaveSystem; +using System.Diagnostics; + +namespace ShiftOS.Engine +{ + public static class Shiftorium + { + /// <summary> + /// Whether or not shiftorium output should be written to the console. + /// </summary> + public static bool Silent = false; + + /// <summary> + /// Gets all Shiftorium categories. + /// </summary> + /// <param name="onlyAvailable">Should we look in the "available" upgrade list (i.e, what the user can buy right now), or the full upgrade list?</param> + /// <returns>All Shiftorium categories from the list, in a <see cref="System.String[]"/>. </returns> + public static string[] GetCategories(bool onlyAvailable = true) + { + List<string> cats = new List<string>(); + IEnumerable < ShiftoriumUpgrade > upgrades = GetDefaults(); + if (onlyAvailable) + upgrades = new List<ShiftoriumUpgrade>(GetAvailable()); + + foreach(var upg in upgrades) + { + if (!cats.Contains(upg.Category)) + cats.Add(upg.Category); + } + + return cats.ToArray(); + } + + public static void InvokeUpgradeInstalled() + { + Installed?.Invoke(); + } + + public static string GetCategory(string id) + { + var upg = GetDefaults().FirstOrDefault(x => x.ID == id); + if (upg == null) + return "Other"; + return (upg.Category == null) ? "Other" : upg.Category; + } + + public static IEnumerable<ShiftoriumUpgrade> GetAllInCategory(string cat) + { + return GetDefaults().Where(x => x.Category == cat); + } + + public static bool IsCategoryEmptied(string cat) + { + return GetDefaults().Where(x => x.Category == cat).FirstOrDefault(x => x.Installed == false) == null; + } + + public static bool Buy(string id, int cost) + { + if(SaveSystem.CurrentSave.Codepoints >= cost) + { + SaveSystem.CurrentSave.Upgrades[id] = true; + TerminalBackend.InvokeCommand("sos.save"); + SaveSystem.TransferCodepointsToVoid(cost); + Installed?.Invoke(); + Desktop.ResetPanelButtons(); + Desktop.PopulateAppLauncher(); + return true; + } + else + { + if(!Silent) + Console.WriteLine($"{{SHIFTORIUM_NOTENOUGHCP}}: {cost} > {SaveSystem.CurrentSave.Codepoints}"); + return false; + } + } + + public static bool UpgradeAttributesUnlocked(Type type) + { + foreach(var attr in type.GetCustomAttributes(true)) + { + if(attr is RequiresUpgradeAttribute) + { + var rAttr = attr as RequiresUpgradeAttribute; + return rAttr.Installed; + } + } + + return true; + } + + public static bool UpgradeAttributesUnlocked(MethodInfo type) + { + foreach (var attr in type.GetCustomAttributes(true)) + { + if (attr is RequiresUpgradeAttribute) + { + var rAttr = attr as RequiresUpgradeAttribute; + return rAttr.Installed; + } + } + + return true; + } + + public static bool UpgradeAttributesUnlocked(PropertyInfo type) + { + foreach (var attr in type.GetCustomAttributes(true)) + { + if (attr is RequiresUpgradeAttribute) + { + var rAttr = attr as RequiresUpgradeAttribute; + return rAttr.Installed; + } + } + + return true; + } + + public static bool UpgradeAttributesUnlocked(FieldInfo type) + { + foreach (var attr in type.GetCustomAttributes(true)) + { + if (attr is RequiresUpgradeAttribute) + { + var rAttr = attr as RequiresUpgradeAttribute; + return rAttr.Installed; + } + } + + return true; + } + + public static bool IsInitiated { get; private set; } + + public static void Init() + { + if (IsInitiated == false) + { + IsInitiated = true; + //Let the crash handler deal with this one... + var dict = GetDefaults(); + foreach (var itm in dict) + { + if (!SaveSystem.CurrentSave.Upgrades.ContainsKey(itm.ID)) + { + try + { + SaveSystem.CurrentSave.Upgrades.Add(itm.ID, false); + } + catch + { + + } + } + } + } + + } + + public static int GetCPValue(string id) + { + foreach(var upg in GetDefaults()) + { + if (upg.ID == id) + return upg.Cost; + } + return 0; + } + + public static ShiftoriumUpgrade[] GetAvailable() + { + List<ShiftoriumUpgrade> available = new List<ShiftoriumUpgrade>(); + foreach(var defaultupg in GetDefaults()) + { + if (!UpgradeInstalled(defaultupg.ID) && DependenciesInstalled(defaultupg)) + available.Add(defaultupg); + } + return available.ToArray(); + } + + public static bool DependenciesInstalled(ShiftoriumUpgrade upg) + { + if (string.IsNullOrEmpty(upg.Dependencies)) + { + return true;//root upgrade, no parents + } + else if (upg.Dependencies.Contains(";")) + { + string[] dependencies = upg.Dependencies.Split(';'); + foreach(var dependency in dependencies) + { + if (!UpgradeInstalled(dependency)) + return false; + } + return true; + } + else + { + return UpgradeInstalled(upg.Dependencies); + } + } + + public static event EmptyEventHandler Installed; + + public static bool UpgradeInstalled(string id) + { + if (SaveSystem.CurrentSave != null) + { + if (!IsInitiated) + Init(); + } + try + { + if (SaveSystem.CurrentSave == null) + return false; + + if (SaveSystem.CurrentSave.StoriesExperienced == null) + SaveSystem.CurrentSave.StoriesExperienced = new List<string>(); + + bool upgInstalled = false; + if(SaveSystem.CurrentSave.Upgrades.ContainsKey(id)) + upgInstalled = SaveSystem.CurrentSave.Upgrades[id]; + + if(upgInstalled == false) + return SaveSystem.CurrentSave.StoriesExperienced.Contains(id); + return true; + } + catch + { + Console.WriteLine("Upgrade " + id + "DNE."); + Console.WriteLine(); + return false; + } + + } + + //LEAVE THIS AS FALSE. The game will set it when the save is loaded. + public static bool LogOrphanedUpgrades = false; + + private static IShiftoriumProvider _provider = null; + + public static void RegisterProvider(IShiftoriumProvider p) + { + _provider = p; + } + + //Bless the newer NEWER engine. + public static List<ShiftoriumUpgrade> GetDefaults() + { + try + { + return _provider.GetDefaults(); + } + catch (Exception ex) + { + Console.WriteLine("Couldn't get the upgrade definition list from the provider."); + Console.WriteLine("This might be able to help:"); + Console.WriteLine(ex); + return JsonConvert.DeserializeObject<List<ShiftoriumUpgrade>>(Properties.Resources.Shiftorium); + } + } + } + + public interface IShiftoriumProvider + { + List<ShiftoriumUpgrade> GetDefaults(); + } + + public class ShiftoriumUpgradeLookupException : Exception + { + public ShiftoriumUpgradeLookupException(string id) : base("A shiftorium upgrade of ID \"" + id + "\" was not found in the system.") + { + ID = id; + + Debug.WriteLine("UpgradeNotFound: " + id); + + } + + public string ID { get; private set; } + } + + + + public class ShiftoriumUpgrade + { + public string Name { get; set; } + public string Description { get; set; } + public int Cost { get; set; } + public string ID { get { return (this.Id != null ? this.Id : (Name.ToLower().Replace(" ", "_"))); } } + public string Id { get; set; } + public string Category { get; set; } + public bool Installed + { + get + { + return Shiftorium.UpgradeInstalled(ID); + } + } + public string Dependencies { get; set; } + } +} diff --git a/ShiftOS_TheReturn/TerminalTextWriter.cs b/ShiftOS_TheReturn/TerminalTextWriter.cs new file mode 100644 index 0000000..55e27cf --- /dev/null +++ b/ShiftOS_TheReturn/TerminalTextWriter.cs @@ -0,0 +1,131 @@ +/* + * MIT License + * + * Copyright (c) 2017 Michael VanOverbeek and ShiftOS devs + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using System.Windows.Forms; + +namespace ShiftOS.Engine +{ + public class TerminalTextWriter : TextWriter + { + [System.Runtime.InteropServices.DllImport("user32.dll")] + public static extern bool LockWindowUpdate(IntPtr hWndLock); + + + public override Encoding Encoding + { + get + { + return Encoding.Unicode; + } + } + + public ITerminalWidget UnderlyingControl + { + get + { + return AppearanceManager.ConsoleOut; + } + } + + public void select() + { + Desktop.InvokeOnWorkerThread(new Action(() => + { + UnderlyingControl?.SelectBottom(); + + })); + } + + public override void Write(char value) + { + if (TerminalBackend.IsForwardingConsoleWrites) + { + ServerManager.SendMessage("write", $@"{{ + guid: ""{TerminalBackend.ForwardGUID}"", + text: ""{value}"" +}}"); + } + else + { + Desktop.InvokeOnWorkerThread(new Action(() => + { + UnderlyingControl?.Write(value.ToString()); + select(); + })); + } + } + + public override void WriteLine(string value) + { + if (TerminalBackend.IsForwardingConsoleWrites) + { + ServerManager.SendMessage("write", $@"{{ + guid: ""{TerminalBackend.ForwardGUID}"", + text: ""{value + Environment.NewLine}"" +}}"); + } + else + { + + Desktop.InvokeOnWorkerThread(new Action(() => + { + UnderlyingControl?.WriteLine(value); + select(); + })); + } + } + + public void SetLastText() + { + } + + public override void Write(string value) + { + if (TerminalBackend.IsForwardingConsoleWrites) + { + ServerManager.SendMessage("write", $@"{{ + guid: ""{TerminalBackend.ForwardGUID}"", + text: ""{value}"" +}}"); + } + else + { + + Desktop.InvokeOnWorkerThread(new Action(() => + { + UnderlyingControl?.Write(value.ToString()); + select(); + })); + } + } + + + } +} diff --git a/Templates/IssueTemplate.md b/Templates/IssueTemplate.md deleted file mode 100644 index 9c62fdb..0000000 --- a/Templates/IssueTemplate.md +++ /dev/null @@ -1,23 +0,0 @@ -# Issue Template - -## What you expected to happen - -## What actually happened - -## Steps To Reproduce - - # What you expected to happen - - # What actually happened - - # Steps To Reproduce - -# Suggestion Template - -## What should be added to the game/api - -## Why it should be added - - # What should be added to the game/api - - # Why it should be added diff --git a/Templates/PullRequestTemplate.md b/Templates/PullRequestTemplate.md deleted file mode 100644 index 49948c0..0000000 --- a/Templates/PullRequestTemplate.md +++ /dev/null @@ -1,13 +0,0 @@ -# Pull Request Template - -## What did you change - -## Benefits - -## Drawbacks - - # What did you change - - # Benefits - - # Drawbacks |
