aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ShiftOS.Frontend/Apps/FileSkimmer.cs151
-rw-r--r--ShiftOS.Frontend/Apps/Terminal.cs12
-rw-r--r--ShiftOS.Frontend/Desktop/WindowManager.cs2
-rw-r--r--ShiftOS.Frontend/GUI/Control.cs7
-rw-r--r--ShiftOS.Frontend/GUI/ListBox.cs27
-rw-r--r--ShiftOS.Frontend/GraphicsSubsystem/UIManager.cs5
-rw-r--r--ShiftOS.Frontend/HackableProvider.cs29
-rw-r--r--ShiftOS.Frontend/HackerTestCommands.cs59
-rw-r--r--ShiftOS.Frontend/Properties/Resources.Designer.cs60
-rw-r--r--ShiftOS.Frontend/Properties/Resources.resx6
-rw-r--r--ShiftOS.Frontend/Resources/Hackables.txt21
-rw-r--r--ShiftOS.Frontend/Resources/LootInfo.txt3
-rw-r--r--ShiftOS.Frontend/ShiftOS.Frontend.csproj9
-rw-r--r--ShiftOS.Frontend/ShiftOS.cs93
-rw-r--r--ShiftOS.Objects/Hackable.cs21
-rw-r--r--ShiftOS_TheReturn/FileSkimmerBackend.cs12
-rw-r--r--ShiftOS_TheReturn/Hacking.cs98
-rw-r--r--ShiftOS_TheReturn/Paths.cs9
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&apos;s campaign.
+ /// *
+ /// */
+ ///
+ ///[
+ /// {
+ /// SystemName: &quot;shiftsyndicate_main&quot;,
+ /// FriendlyName: &quot;ShiftSyndicate file server&quot;,
+ /// Password: &quot;h0ldy0urc0l0ur&quot;,
+ /// PasswordHint: &quot;Prepare to hold your colour...&quot;,
+ /// WelcomeMessage: &quot;Don&apos;t make fun of SpamSyndicate web design.&quot;,
+ /// FirewallStrength: 1,
+ /// LootRarity: 1,
+ /// LootAmount: 4,
+ /// ConnectionTimeoutLevel: 4,
+ /// SystemType: &quot;FileServer, SSHServer&quot;,
+ ///
+ /// }
+ ///].
+ /// </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: &quot;Virus Scanner Grade 2&quot;,
- /// Description: &quot;Update the Virus Scanner database to include threatlevel 2 viruses.&quot;,
- /// Dependencies: &quot;virus_scanner&quot;,
- /// Category: &quot;Virus Scanner&quot;,
- /// Cost: 75
- /// },
- /// {
- /// Name: &quot;Virus Scanner Grade 3&quot;,
- /// Description: &quot;Update the Virus Scanner database to include threatlevel 3 viruses.&quot;,
- /// Dependencies: &quot;virus_scanner_grade_2&quot;,
- /// Category: &quot;Virus Scanner&quot;,
- /// Cost: 150
- /// },
- /// {
- /// Name: &quot;Virus Scanner Grade 4&quot;,
- /// Description: &quot;Update the [rest of string was truncated]&quot;;.
+ /// 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>