Hacking, barebones fskimmer, double clicking

This commit is contained in:
Michael 2017-07-17 14:34:59 -04:00
parent e929a9f510
commit a0ee79dbcd
18 changed files with 577 additions and 47 deletions

View file

@ -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 { }
}
}
}

View file

@ -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);

View file

@ -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()

View file

@ -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;

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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);
}
}
}

View file

@ -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

View file

@ -70,6 +70,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>
@ -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 {

View file

@ -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>

View file

@ -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",
}
]

View file

@ -0,0 +1,3 @@
//Loot information table
[]

View file

@ -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.

View file

@ -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();
}
}
}

View file

@ -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; }
}
}

View file

@ -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);
}

View file

@ -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; }
}
}

View file

@ -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>