diff options
| -rw-r--r-- | ShiftOS.Frontend/Apps/FileSkimmer.cs | 151 | ||||
| -rw-r--r-- | ShiftOS.Frontend/Apps/Terminal.cs | 12 | ||||
| -rw-r--r-- | ShiftOS.Frontend/Desktop/WindowManager.cs | 2 | ||||
| -rw-r--r-- | ShiftOS.Frontend/GUI/Control.cs | 7 | ||||
| -rw-r--r-- | ShiftOS.Frontend/GUI/ListBox.cs | 27 | ||||
| -rw-r--r-- | ShiftOS.Frontend/GraphicsSubsystem/UIManager.cs | 5 | ||||
| -rw-r--r-- | ShiftOS.Frontend/HackableProvider.cs | 29 | ||||
| -rw-r--r-- | ShiftOS.Frontend/HackerTestCommands.cs | 59 | ||||
| -rw-r--r-- | ShiftOS.Frontend/Properties/Resources.Designer.cs | 60 | ||||
| -rw-r--r-- | ShiftOS.Frontend/Properties/Resources.resx | 6 | ||||
| -rw-r--r-- | ShiftOS.Frontend/Resources/Hackables.txt | 21 | ||||
| -rw-r--r-- | ShiftOS.Frontend/Resources/LootInfo.txt | 3 | ||||
| -rw-r--r-- | ShiftOS.Frontend/ShiftOS.Frontend.csproj | 9 | ||||
| -rw-r--r-- | ShiftOS.Frontend/ShiftOS.cs | 93 | ||||
| -rw-r--r-- | ShiftOS.Objects/Hackable.cs | 21 | ||||
| -rw-r--r-- | ShiftOS_TheReturn/FileSkimmerBackend.cs | 12 | ||||
| -rw-r--r-- | ShiftOS_TheReturn/Hacking.cs | 98 | ||||
| -rw-r--r-- | ShiftOS_TheReturn/Paths.cs | 9 |
18 files changed, 577 insertions, 47 deletions
diff --git a/ShiftOS.Frontend/Apps/FileSkimmer.cs b/ShiftOS.Frontend/Apps/FileSkimmer.cs new file mode 100644 index 0000000..29c5802 --- /dev/null +++ b/ShiftOS.Frontend/Apps/FileSkimmer.cs @@ -0,0 +1,151 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ShiftOS.Engine; +using static ShiftOS.Objects.ShiftFS.Utils; + +namespace ShiftOS.Frontend.Apps +{ + [WinOpen("fileskimmer")] + [Launcher("File Skimmer", false, null, "System")] + [DefaultTitle("File Skimmer")] + public class FileSkimmer : GUI.Control, IShiftOSWindow + { + private string _currentdirectory = "0:"; + private const string SD_SYSTEM = "__system"; + private GUI.ListBox _fList = null; + private GUI.TextControl _currentdirtext = null; + + public void OnLoad() + { + Width = 720; + Height = 480; + _fList = new GUI.ListBox(); + _fList.KeyEvent += (e) => + { + if(e.Key == Microsoft.Xna.Framework.Input.Keys.Enter) + { + Navigate(_fList.SelectedItem.ToString()); + } + }; + _fList.DoubleClick += () => + { + try + { + Navigate(_fList.SelectedItem.ToString()); + } + catch { } + }; + AddControl(_fList); + _currentdirtext = new GUI.TextControl(); + _currentdirtext.AutoSize = true; + AddControl(_currentdirtext); + ResetList(); + } + + public void Navigate(string relativepath) + { + if (relativepath == "Up one...") + { + if (_currentdirectory.Contains('/')) + { + int _index = _currentdirectory.LastIndexOf('/'); + int _len = _currentdirectory.Length - _index; + _currentdirectory = _currentdirectory.Remove(_index, _len); + ResetList(); + } + else + { + _currentdirectory = SD_SYSTEM; + ResetList(); + } + return; + } + + string path = ""; + if (_currentdirectory == SD_SYSTEM) + path = relativepath; + else + path = _currentdirectory + "/" + relativepath; + if (DirectoryExists(path)) + { + _currentdirectory = path; + ResetList(); + } + else if (FileExists(path)) + { + if (!FileSkimmerBackend.OpenFile(path)) + { + Engine.Infobox.Show("File Skimmer can't open this file!", "A program that can open files of this type was not found on your computer."); + } + } + } + + public void OnSkinLoad() + { + _currentdirtext.Font = SkinEngine.LoadedSkin.Header3Font; + } + + public bool OnUnload() + { + return true; + } + + public void OnUpgrade() + { + } + + public void ResetList() + { + if (_currentdirectory == SD_SYSTEM) + _currentdirtext.Text = "My storage drives"; + else + _currentdirtext.Text = _currentdirectory; + + _fList.ClearItems(); + if (_currentdirectory != SD_SYSTEM) + _fList.AddItem("Up one..."); + + if(_currentdirectory == SD_SYSTEM) + { + foreach(var mount in Mounts) + { + _fList.AddItem(Mounts.IndexOf(mount) + ":"); + } + } + else + { + foreach(var dir in GetDirectories(_currentdirectory)) + { + var dinf = GetDirectoryInfo(dir); + _fList.AddItem(dinf.Name); + } + foreach (var dir in GetFiles(_currentdirectory)) + { + var dinf = GetFileInfo(dir); + _fList.AddItem(dinf.Name); + } + + } + InvalidateTopLevel(); + } + + + protected override void OnLayout() + { + try + { + _currentdirtext.Layout(); + _fList.X = 0; + _fList.Y = 0; + _fList.Width = Width; + _fList.Height = Height - _currentdirtext.Height; + _currentdirtext.X = (Width - _currentdirtext.Width) / 2; + _currentdirtext.Y = _fList.Height; + } + catch { } + } + } +} diff --git a/ShiftOS.Frontend/Apps/Terminal.cs b/ShiftOS.Frontend/Apps/Terminal.cs index ea75f3a..6d03a0e 100644 --- a/ShiftOS.Frontend/Apps/Terminal.cs +++ b/ShiftOS.Frontend/Apps/Terminal.cs @@ -262,6 +262,16 @@ namespace ShiftOS.Frontend.Apps Debug.WriteLine("Drunky alert in terminal."); } } + else if(a.Key == Keys.Right) + { + if(Index < Text.Length) + { + Index++; + AppearanceManager.CurrentPosition++; + RecalculateLayout(); + InvalidateTopLevel(); + } + } else if (a.Key == Keys.Left) { if (SaveSystem.CurrentSave != null) @@ -274,7 +284,7 @@ namespace ShiftOS.Frontend.Apps var remstrlen = Text.Length - stringlen; var finalnum = selstart - remstrlen; - if (finalnum != headerlen) + if (finalnum > headerlen) { AppearanceManager.CurrentPosition--; base.OnKeyEvent(a); diff --git a/ShiftOS.Frontend/Desktop/WindowManager.cs b/ShiftOS.Frontend/Desktop/WindowManager.cs index 18f6728..cdbae90 100644 --- a/ShiftOS.Frontend/Desktop/WindowManager.cs +++ b/ShiftOS.Frontend/Desktop/WindowManager.cs @@ -127,10 +127,10 @@ namespace ShiftOS.Frontend.Desktop UIManager.AddTopLevel(wb); AppearanceManager.OpenForms.Add(wb); RunningBorders.Add(wb); + TileWindows(); win.OnLoad(); win.OnUpgrade(); win.OnSkinLoad(); - TileWindows(); } public void TileWindows() diff --git a/ShiftOS.Frontend/GUI/Control.cs b/ShiftOS.Frontend/GUI/Control.cs index f253903..d34a97a 100644 --- a/ShiftOS.Frontend/GUI/Control.cs +++ b/ShiftOS.Frontend/GUI/Control.cs @@ -509,7 +509,7 @@ namespace ShiftOS.Frontend.GUI } } - public virtual bool ProcessMouseState(MouseState state) + public virtual bool ProcessMouseState(MouseState state, double lastLeftClickMS) { //If we aren't rendering the control, we aren't accepting input. if (_visible == false) @@ -548,7 +548,7 @@ namespace ShiftOS.Frontend.GUI var nstate = new MouseState(coords.X, coords.Y, state.ScrollWheelValue, state.LeftButton, state.MiddleButton, state.RightButton, state.XButton1, state.XButton2); //pass that state to the process method, and set the _requiresMoreWork value to the opposite of the return value - _requiresMoreWork = !control.ProcessMouseState(nstate); + _requiresMoreWork = !control.ProcessMouseState(nstate, lastLeftClickMS); //If it's false, break the loop. if (_requiresMoreWork == false) break; @@ -575,6 +575,8 @@ namespace ShiftOS.Frontend.GUI } if (_leftState == false && ld == true) { + if (lastLeftClickMS <= 500 & lastLeftClickMS > 0) + DoubleClick?.Invoke(); var focused = UIManager.FocusedControl; UIManager.FocusedControl = this; focused?.InvalidateTopLevel(); @@ -642,6 +644,7 @@ namespace ShiftOS.Frontend.GUI KeyEvent?.Invoke(e); } + public event Action DoubleClick; public event Action<Point> MouseMove; public event Action MouseEnter; public event Action MouseLeave; diff --git a/ShiftOS.Frontend/GUI/ListBox.cs b/ShiftOS.Frontend/GUI/ListBox.cs index 29d3712..2fe5fc4 100644 --- a/ShiftOS.Frontend/GUI/ListBox.cs +++ b/ShiftOS.Frontend/GUI/ListBox.cs @@ -17,6 +17,27 @@ namespace ShiftOS.Frontend.GUI private int itemOffset = 0; private int itemsPerPage = 1; + public ListBox() + { + Click += () => + { + //loop through the list of items on the screen + for(int i = itemOffset; i < itemOffset + itemsPerPage && i < items.Count; i++) + { + int screeni = i - itemOffset; + int loc = 1+screeni * fontheight; + int height = 1+(screeni + 1) * fontheight; + if(MouseY >= loc && MouseY <= height) + { + SelectedIndex = i; + RecalculateItemsPerPage(); + return; + } + } + }; + } + + public int SelectedIndex { get @@ -73,7 +94,7 @@ namespace ShiftOS.Frontend.GUI public void RecalculateItemsPerPage() { itemsPerPage = 0; - while(itemsPerPage * fontheight < Height && itemsPerPage < items.Count - 1) + while(itemsPerPage * fontheight < Height && itemsPerPage < items.Count) { itemsPerPage++; } @@ -102,7 +123,7 @@ namespace ShiftOS.Frontend.GUI { if(e.Key== Microsoft.Xna.Framework.Input.Keys.Down) { - if(selectedIndex < items.Count - 2) + if(selectedIndex < items.Count - 1) { selectedIndex++; RecalculateItemsPerPage(); @@ -126,7 +147,7 @@ namespace ShiftOS.Frontend.GUI { gfx.Clear(LoadedSkin.ControlTextColor.ToMonoColor()); gfx.DrawRectangle(1, 1, Width - 2, Height - 2, UIManager.SkinTextures["ControlColor"]); - for(int i = itemOffset; i < items.Count - 1 && i < itemsPerPage; i++) + for(int i = itemOffset; i < items.Count && i < itemsPerPage; i++) { int x = 1; int y = fontheight * (i - itemOffset); diff --git a/ShiftOS.Frontend/GraphicsSubsystem/UIManager.cs b/ShiftOS.Frontend/GraphicsSubsystem/UIManager.cs index 165944e..a88f28e 100644 --- a/ShiftOS.Frontend/GraphicsSubsystem/UIManager.cs +++ b/ShiftOS.Frontend/GraphicsSubsystem/UIManager.cs @@ -146,11 +146,12 @@ namespace ShiftOS.Frontend.GraphicsSubsystem } } - public static void ProcessMouseState(MouseState state) + public static void ProcessMouseState(MouseState state, double lastLeftClickMS) { foreach(var ctrl in topLevels.ToArray()) { - ctrl.ProcessMouseState(state); + ctrl.ProcessMouseState(state, lastLeftClickMS); + } } diff --git a/ShiftOS.Frontend/HackableProvider.cs b/ShiftOS.Frontend/HackableProvider.cs new file mode 100644 index 0000000..1c57f37 --- /dev/null +++ b/ShiftOS.Frontend/HackableProvider.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ShiftOS.Objects; +using ShiftOS.Engine; +using Newtonsoft.Json; + +namespace ShiftOS.Frontend +{ + public class HackableProvider : IHackableProvider + { + public Hackable[] GetHackables() + { + return JsonConvert.DeserializeObject<Hackable[]>(Properties.Resources.Hackables); + } + + public byte[] GetLootFromResource(string resId) + { + return new byte[] { 0xDE, 0xAD, 0xBE, 0xEF }; //nyi + } + + public LootInfo[] GetLootInfo() + { + return JsonConvert.DeserializeObject<LootInfo[]>(Properties.Resources.LootInfo); + } + } +} diff --git a/ShiftOS.Frontend/HackerTestCommands.cs b/ShiftOS.Frontend/HackerTestCommands.cs new file mode 100644 index 0000000..675356a --- /dev/null +++ b/ShiftOS.Frontend/HackerTestCommands.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ShiftOS.Engine; + +#if DEBUG +namespace ShiftOS.Frontend +{ + public static class HackerTestCommands + { + [Command("lshackables")] + public static void ListAllHackables() + { + foreach(var hackable in Hacking.AvailableToHack) + { + Console.WriteLine(hackable.ID + ": " + hackable.FriendlyName); + } + } + + [Command("describebackable")] + [RequiresArgument("id")] + public static void DescribeHackable(Dictionary<string, object> args) + { + string id = args["id"].ToString(); + var hackable = Hacking.AvailableToHack.FirstOrDefault(x => x.ID == id); + if(hackable == null) + { + Console.WriteLine("Hackable not found."); + return; + } + Console.WriteLine(hackable.FriendlyName); + Console.WriteLine("------------------------"); + Console.WriteLine(); + Console.WriteLine("System name: " + hackable.SystemName); + Console.WriteLine("Loot rarity: " + hackable.LootRarity); + Console.WriteLine("Loot amount: " + hackable.LootAmount); + Console.WriteLine("Connection timeout level: " + hackable.ConnectionTimeoutLevel); + Console.WriteLine(); + Console.WriteLine(hackable.WelcomeMessage); + } + + [Command("inithack")] + [RequiresArgument("id")] + public static void InitHack(Dictionary<string, object> args) + { + string id = args["id"].ToString(); + var hackable = Hacking.AvailableToHack.FirstOrDefault(x => x.ID == id); + if (hackable == null) + { + Console.WriteLine("Hackable not found."); + return; + } + Hacking.InitHack(hackable); + } + } +} +#endif
\ No newline at end of file diff --git a/ShiftOS.Frontend/Properties/Resources.Designer.cs b/ShiftOS.Frontend/Properties/Resources.Designer.cs index aaca596..3d40c29 100644 --- a/ShiftOS.Frontend/Properties/Resources.Designer.cs +++ b/ShiftOS.Frontend/Properties/Resources.Designer.cs @@ -71,6 +71,35 @@ namespace ShiftOS.Frontend.Properties { } /// <summary> + /// Looks up a localized string similar to /* ShiftOS hackables data file + /// * + /// * This file contains information about all hackable systems in the game's campaign. + /// * + /// */ + /// + ///[ + /// { + /// SystemName: "shiftsyndicate_main", + /// FriendlyName: "ShiftSyndicate file server", + /// Password: "h0ldy0urc0l0ur", + /// PasswordHint: "Prepare to hold your colour...", + /// WelcomeMessage: "Don't make fun of SpamSyndicate web design.", + /// FirewallStrength: 1, + /// LootRarity: 1, + /// LootAmount: 4, + /// ConnectionTimeoutLevel: 4, + /// SystemType: "FileServer, SSHServer", + /// + /// } + ///]. + /// </summary> + internal static string Hackables { + get { + return ResourceManager.GetString("Hackables", resourceCulture); + } + } + + /// <summary> /// Looks up a localized resource of type System.Drawing.Bitmap. /// </summary> internal static System.Drawing.Bitmap justthes { @@ -81,25 +110,18 @@ namespace ShiftOS.Frontend.Properties { } /// <summary> - /// Looks up a localized string similar to [ - /////Virus Scanner Grades - /// { - /// Name: "Virus Scanner Grade 2", - /// Description: "Update the Virus Scanner database to include threatlevel 2 viruses.", - /// Dependencies: "virus_scanner", - /// Category: "Virus Scanner", - /// Cost: 75 - /// }, - /// { - /// Name: "Virus Scanner Grade 3", - /// Description: "Update the Virus Scanner database to include threatlevel 3 viruses.", - /// Dependencies: "virus_scanner_grade_2", - /// Category: "Virus Scanner", - /// Cost: 150 - /// }, - /// { - /// Name: "Virus Scanner Grade 4", - /// Description: "Update the [rest of string was truncated]";. + /// Looks up a localized string similar to //Loot information table + /// + ///[]. + /// </summary> + internal static string LootInfo { + get { + return ResourceManager.GetString("LootInfo", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to []. /// </summary> internal static string Shiftorium { get { diff --git a/ShiftOS.Frontend/Properties/Resources.resx b/ShiftOS.Frontend/Properties/Resources.resx index 1a04f46..c0a2cff 100644 --- a/ShiftOS.Frontend/Properties/Resources.resx +++ b/ShiftOS.Frontend/Properties/Resources.resx @@ -136,4 +136,10 @@ <data name="strings_fr" type="System.Resources.ResXFileRef, System.Windows.Forms"> <value>..\Resources\strings_fr.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value> </data> + <data name="Hackables" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\Resources\Hackables.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value> + </data> + <data name="LootInfo" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\Resources\LootInfo.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.Frontend/Resources/Hackables.txt b/ShiftOS.Frontend/Resources/Hackables.txt new file mode 100644 index 0000000..1c82394 --- /dev/null +++ b/ShiftOS.Frontend/Resources/Hackables.txt @@ -0,0 +1,21 @@ +/* ShiftOS hackables data file + * + * This file contains information about all hackable systems in the game's campaign. + * + */ + +[ + { + SystemName: "shiftsyndicate_main", + FriendlyName: "ShiftSyndicate file server", + Password: "h0ldy0urc0l0ur", + PasswordHint: "Prepare to hold your colour...", + WelcomeMessage: "Don't make fun of SpamSyndicate web design.", + FirewallStrength: 1, + LootRarity: 1, + LootAmount: 4, + ConnectionTimeoutLevel: 4, + SystemType: "FileServer, SSHServer", + + } +]
\ No newline at end of file diff --git a/ShiftOS.Frontend/Resources/LootInfo.txt b/ShiftOS.Frontend/Resources/LootInfo.txt new file mode 100644 index 0000000..361bab9 --- /dev/null +++ b/ShiftOS.Frontend/Resources/LootInfo.txt @@ -0,0 +1,3 @@ +//Loot information table + +[]
\ No newline at end of file diff --git a/ShiftOS.Frontend/ShiftOS.Frontend.csproj b/ShiftOS.Frontend/ShiftOS.Frontend.csproj index cdba714..c401a3c 100644 --- a/ShiftOS.Frontend/ShiftOS.Frontend.csproj +++ b/ShiftOS.Frontend/ShiftOS.Frontend.csproj @@ -43,6 +43,7 @@ </PropertyGroup> <ItemGroup> <Compile Include="Apps\CodeShop.cs" /> + <Compile Include="Apps\FileSkimmer.cs" /> <Compile Include="Apps\Pong.cs" /> <Compile Include="Apps\SystemStatus.cs" /> <Compile Include="Apps\Terminal.cs" /> @@ -59,6 +60,8 @@ <Compile Include="GUI\ProgressBar.cs" /> <Compile Include="GUI\TextControl.cs" /> <Compile Include="GUI\TextInput.cs" /> + <Compile Include="HackableProvider.cs" /> + <Compile Include="HackerTestCommands.cs" /> <Compile Include="Infobox.cs" /> <Compile Include="MonoGameLanguageProvider.cs" /> <Compile Include="Properties\Resources.Designer.cs"> @@ -174,6 +177,12 @@ <ItemGroup> <None Include="Resources\Shiftorium.txt" /> </ItemGroup> + <ItemGroup> + <None Include="Resources\Hackables.txt" /> + </ItemGroup> + <ItemGroup> + <None Include="Resources\LootInfo.txt" /> + </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath)\MonoGame\v3.0\MonoGame.Content.Builder.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. diff --git a/ShiftOS.Frontend/ShiftOS.cs b/ShiftOS.Frontend/ShiftOS.cs index e2d3c4a..9211fcd 100644 --- a/ShiftOS.Frontend/ShiftOS.cs +++ b/ShiftOS.Frontend/ShiftOS.cs @@ -92,9 +92,11 @@ namespace ShiftOS.Frontend AppearanceManager.SetupWindow(new Apps.Terminal()); }; + FileSkimmerBackend.Init(new MGFSLayer()); + + //We'll use sandbox mode SaveSystem.IsSandbox = false; - Engine.Infobox.Show("Test window", "This is a test window."); SaveSystem.Begin(true); base.Initialize(); @@ -139,6 +141,7 @@ namespace ShiftOS.Frontend } private double kb_elapsedms = 0; + private double mouseMS = 0; private MouseState LastMouseState; /// <summary> @@ -157,8 +160,17 @@ namespace ShiftOS.Frontend //Let's get the mouse state var mouseState = Mouse.GetState(this.Window); LastMouseState = mouseState; - UIManager.ProcessMouseState(LastMouseState); + UIManager.ProcessMouseState(LastMouseState, mouseMS); + if (mouseState.LeftButton == ButtonState.Pressed) + { + mouseMS = 0; + } + else + { + mouseMS += gameTime.ElapsedGameTime.TotalMilliseconds; + + } //So we have mouse input, and the UI layout system working... //But an OS isn't useful without the keyboard! @@ -227,6 +239,22 @@ namespace ShiftOS.Frontend timeSinceLastPurge = 0; } + + //Some hackables have a connection timeout applied to them. + //We must update timeout values here, and disconnect if the timeout + //hits zero. + + if(Hacking.CurrentHackable != null) + { + if (Hacking.CurrentHackable.DoConnectionTimeout) + { + Hacking.CurrentHackable.MillisecondsCountdown -= gameTime.ElapsedGameTime.TotalMilliseconds; + if(Hacking.CurrentHackable.MillisecondsCountdown <= 0) + { + Hacking.FailHack(); + } + } + } base.Update(gameTime); } @@ -261,6 +289,17 @@ namespace ShiftOS.Frontend spriteBatch.Draw(MouseTexture, new Rectangle(mousepos.X+1, mousepos.Y+1, MouseTexture.Width, MouseTexture.Height), Color.Black * 0.5f); spriteBatch.Draw(MouseTexture, new Rectangle(mousepos.X, mousepos.Y, MouseTexture.Width, MouseTexture.Height), Color.White); + if(Hacking.CurrentHackable != null) + { + if (Hacking.CurrentHackable.DoConnectionTimeout) + { + string str = $"Connection TImeout in {(Hacking.CurrentHackable.MillisecondsCountdown / 1000).ToString("#.##")} seconds."; + var gfx = new GraphicsContext(GraphicsDevice.GraphicsDevice, spriteBatch, 0, 0, UIManager.Viewport.Width, UIManager.Viewport.Height); + var measure = gfx.MeasureString(str, SkinEngine.LoadedSkin.HeaderFont); + gfx.DrawString(str, 5, (gfx.Height - ((int)measure.Y) - 5), Color.Red, SkinEngine.LoadedSkin.HeaderFont); + } + } + if (DisplayDebugInfo) { var gfxContext = new GraphicsContext(GraphicsDevice.GraphicsDevice, spriteBatch, 0, 0, GraphicsDevice.PreferredBackBufferWidth, GraphicsDevice.PreferredBackBufferHeight); @@ -292,7 +331,14 @@ Open windows (excluding dialog boxes): {AppearanceManager.OpenForms.Count} Experimental effects enabled: {UIManager.ExperimentalEffects} Fullscreen: {GraphicsDevice.IsFullScreen} -Game resolution: {GraphicsDevice.PreferredBackBufferWidth}x{GraphicsDevice.PreferredBackBufferHeight}", 0, 0, color, new System.Drawing.Font("Lucida Console", 9F, System.Drawing.FontStyle.Bold)); +Game resolution: {GraphicsDevice.PreferredBackBufferWidth}x{GraphicsDevice.PreferredBackBufferHeight} + +Mouse state: +X: {LastMouseState.X} +Y: {LastMouseState.Y} +Last left click MS: {mouseMS} + +", 0, 0, color, new System.Drawing.Font("Lucida Console", 9F, System.Drawing.FontStyle.Bold)); } spriteBatch.End(); @@ -308,4 +354,45 @@ Game resolution: {GraphicsDevice.PreferredBackBufferWidth}x{GraphicsDevice.Prefe return JsonConvert.DeserializeObject<List<ShiftoriumUpgrade>>(Properties.Resources.Shiftorium); } } + + public class MGFSLayer : IFileSkimmer + { + public string GetFileExtension(FileType fileType) + { + switch (fileType) + { + case FileType.CommandFormat: + return ".cf"; + case FileType.Executable: + return ".saa"; + case FileType.Filesystem: + return ".mfs"; + case FileType.Image: + return ".png"; + case FileType.JSON: + return ".json"; + case FileType.Lua: + return ".lua"; + case FileType.Python: + return ".py"; + case FileType.Skin: + return ".skn"; + case FileType.TextFile: + return ".txt"; + default: + return ".scrtm"; + } + } + + public void GetPath(string[] filetypes, FileOpenerStyle style, Action<string> callback) + { + throw new NotImplementedException(); + } + + public void OpenDirectory(string path) + { + throw new NotImplementedException(); + } + } + } diff --git a/ShiftOS.Objects/Hackable.cs b/ShiftOS.Objects/Hackable.cs index cb05b0c..309ce87 100644 --- a/ShiftOS.Objects/Hackable.cs +++ b/ShiftOS.Objects/Hackable.cs @@ -22,8 +22,8 @@ namespace ShiftOS.Objects public SystemType SystemType { get; set; } public string OnHackCompleteStoryEvent { get; set; } + public string OnHackFailedStoryEvent { get; set; } - public string Dependencies { get; set; } @@ -52,4 +52,23 @@ namespace ShiftOS.Objects public string GUID { get; set; } public string Contents { get; set; } } + + public class LootInfo + { + public string Filename { get; set; } + public string ResourceId { get; set; } + public int Rarity { get; set; } + } + + public class Loot + { + public Loot(LootInfo info, byte[] data) + { + Data = data; + Info = info; + } + + public LootInfo Info { get; private set; } + public byte[] Data { get; private set; } + } } diff --git a/ShiftOS_TheReturn/FileSkimmerBackend.cs b/ShiftOS_TheReturn/FileSkimmerBackend.cs index ac20d34..b14733f 100644 --- a/ShiftOS_TheReturn/FileSkimmerBackend.cs +++ b/ShiftOS_TheReturn/FileSkimmerBackend.cs @@ -44,7 +44,8 @@ namespace ShiftOS.Engine /// Opens a file from the specified ShiftFS path. /// </summary> /// <param name="path">The path to open.</param> - public static void OpenFile(string path) + /// <returns>Whether or not the file could be opened.</returns> + public static bool OpenFile(string path) { if (!Objects.ShiftFS.Utils.FileExists(path)) throw new System.IO.FileNotFoundException("ShiftFS could not find the file specified.", path); @@ -56,9 +57,11 @@ namespace ShiftOS.Engine { var obj = (IFileHandler)Activator.CreateInstance(type); obj.OpenFile(path); + return true; } } } + return false; } public static FileType GetFileType(string path) { @@ -137,11 +140,6 @@ namespace ShiftOS.Engine _fs = fs; } - public static System.Drawing.Image GetImage(string filepath) - { - return _fs.GetImage(filepath); - } - public static string GetFileExtension(FileType fileType) { return _fs.GetFileExtension(fileType); @@ -153,10 +151,8 @@ namespace ShiftOS.Engine /// </summary> public interface IFileSkimmer { - void OpenFile(string filepath); void GetPath(string[] filetypes, FileOpenerStyle style, Action<string> callback); void OpenDirectory(string path); - Image GetImage(string path); string GetFileExtension(FileType fileType); } diff --git a/ShiftOS_TheReturn/Hacking.cs b/ShiftOS_TheReturn/Hacking.cs index db47f66..ea2d89b 100644 --- a/ShiftOS_TheReturn/Hacking.cs +++ b/ShiftOS_TheReturn/Hacking.cs @@ -10,6 +10,9 @@ namespace ShiftOS.Engine { private static List<HackableSystem> _activeConnections = new List<HackableSystem>(); private static List<Objects.Hackable> Hackables = new List<Objects.Hackable>(); + private static List<Objects.Loot> Loot = new List<Objects.Loot>(); + + public static HackableSystem CurrentHackable { get; private set; } public static Objects.Hackable[] AvailableToHack { @@ -44,13 +47,84 @@ namespace ShiftOS.Engine } } + public static void InitHack(Objects.Hackable data) + { + var hsys = new HackableSystem(); + hsys.Data = data; + hsys.IsPwn3d = false; + var fs = new Objects.ShiftFS.Directory(); + fs.Name = data.FriendlyName; + Objects.ShiftFS.Utils.Mounts.Add(fs); + var mountid = Objects.ShiftFS.Utils.Mounts.IndexOf(fs); + Objects.ShiftFS.Utils.Mounts.Remove(fs); + hsys.Filesystem = fs; + hsys.FirewallCracked = (data.FirewallStrength == 0); + hsys.DoConnectionTimeout = (data.ConnectionTimeoutLevel > 0); + if (hsys.DoConnectionTimeout) + { + hsys.MillisecondsCountdown = 1000 * (240 / data.ConnectionTimeoutLevel); + } + else + { + hsys.MillisecondsCountdown = 0; + } + hsys.PortsToUnlock = new List<Port>(); + if (data.SystemType.HasFlag(Objects.SystemType.EmailServer)) + hsys.PortsToUnlock.Add(new Port + { + Value = 25, + Name = "SMTP mailserver (unencrypted)", + }); + if (data.SystemType.HasFlag(Objects.SystemType.FileServer)) + hsys.PortsToUnlock.Add(new Port + { + Value = 22, + Name = "File Transfer Protocol", + }); + if (data.SystemType.HasFlag(Objects.SystemType.SSHServer)) + hsys.PortsToUnlock.Add(new Port + { + Value = 21, + Name = "ShiftSSH server", + }); + if (data.SystemType.HasFlag(Objects.SystemType.Database)) + hsys.PortsToUnlock.Add(new Port + { + Value = 3306, + Name = "MySQL database", + }); + + CurrentHackable = hsys; + } + + public static void FailHack() + { + if (CurrentHackable == null) + throw new NaughtyDeveloperException("Someone tried to fail a non-existent hack."); + if (CurrentHackable.IsPwn3d) + throw new NaughtyDeveloperException("A developer tried to un-pwn a pwn3d hackable."); + if (!string.IsNullOrWhiteSpace(CurrentHackable.Data.OnHackFailedStoryEvent)) + Story.Start(CurrentHackable.Data.OnHackFailedStoryEvent); + if (Objects.ShiftFS.Utils.Mounts.Contains(CurrentHackable.Filesystem)) + Objects.ShiftFS.Utils.Mounts.Remove(CurrentHackable.Filesystem); + CurrentHackable = null; + } + public static void Initiate() { foreach(var type in ReflectMan.Types.Where(x => x.GetInterfaces().Contains(typeof(IHackableProvider)))) { var @interface = (IHackableProvider)Activator.CreateInstance(type, null); Hackables.AddRange(@interface.GetHackables()); - + var lootinfo = @interface.GetLootInfo(); + foreach(var loot in lootinfo) + { + var existing = Loot.FirstOrDefault(x => x.Info.Filename == loot.Filename); + if (existing != null) + throw new DataConflictException("Data conflict encountered while reading loot data. Two or more loot resources with the filename \"" + loot.Filename + "\" were found. This can cause major bugs and confusion in the game."); + var @new = new Objects.Loot(loot, @interface.GetLootFromResource(loot.ResourceId)); + Loot.Add(@new); + } } var hackable = Hackables.FirstOrDefault(x => Hackables.Where(y => x.SystemName == y.SystemName).Count() > 1); @@ -61,6 +135,21 @@ namespace ShiftOS.Engine } } + /// <summary> + /// An exception which is thrown when a developer deliberately tries to cause a bug. + /// </summary> + public class NaughtyDeveloperException : Exception + { + /// <summary> + /// Create a new instance of the <see cref="NaughtyDeveloperException"/>, with the specified message, which will cause Visual Studio to call the person who caused the exception a scrotem. + /// </summary> + /// <param name="message">The message you want to yell at the user.</param> + public NaughtyDeveloperException(string message) : base(message + " - FIX IT, YOU SCROTEM") + { + + } + } + public class DataConflictException : Exception { public DataConflictException(string message) : base(message) @@ -72,6 +161,8 @@ namespace ShiftOS.Engine public interface IHackableProvider { Objects.Hackable[] GetHackables(); + Objects.LootInfo[] GetLootInfo(); + byte[] GetLootFromResource(string resId); } public class HackableSystem @@ -80,7 +171,8 @@ namespace ShiftOS.Engine public List<Port> PortsToUnlock { get; set; } public bool FirewallCracked { get; set; } public Objects.ShiftFS.Directory Filesystem { get; set; } - public int MillisecondsCountdown { get; set; } + public double MillisecondsCountdown { get; set; } + public bool DoConnectionTimeout { get; set; } public bool IsPwn3d { get; set; } } @@ -88,7 +180,5 @@ namespace ShiftOS.Engine { public string Name { get; set; } public int Value { get; set; } - public int Difficulty { get; set; } - public bool Cracked { get; set; } } } diff --git a/ShiftOS_TheReturn/Paths.cs b/ShiftOS_TheReturn/Paths.cs index 5827af2..0b00915 100644 --- a/ShiftOS_TheReturn/Paths.cs +++ b/ShiftOS_TheReturn/Paths.cs @@ -45,8 +45,8 @@ namespace ShiftOS.Engine /// </summary> public static void Init() { - Locations = new Dictionary<string, string>(); - Locations.Add("root", "0:"); + Locations = new Dictionary<string, string>(); + Locations.Add("root", "0:"); AddPath("root", "system"); @@ -76,7 +76,10 @@ namespace ShiftOS.Engine CheckPathExistence(); - CreateAndMountSharedFolder(); + if (Mounts.Count < 2) + { + CreateAndMountSharedFolder(); + } } /// <summary> |
