Hacking UI is coming in.

This commit is contained in:
Michael 2017-07-27 12:03:55 -04:00
parent cac4e1f9a7
commit 89dfed83af
8 changed files with 327 additions and 10 deletions

View file

@ -0,0 +1,228 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using ShiftOS.Engine;
using ShiftOS.Frontend.GraphicsSubsystem;
using ShiftOS.Frontend.GUI;
using ShiftOS.Objects;
using static ShiftOS.Engine.SkinEngine;
namespace ShiftOS.Frontend.Apps
{
[WinOpen("network")]
[Launcher("Network", false, null, "Networking")]
[DefaultTitle("Network")]
public class Network : Control, IShiftOSWindow
{
private NetworkGUIState _state = NetworkGUIState.Listing;
private TextControl _title = new TextControl();
private TextControl _subtitle = new TextControl();
private TextControl _description = new TextControl();
private ListBox _sysList = new ListBox();
private Button _connect = new Button();
private Button _disconnect = new Button();
private HackableSystem _current = null;
public Network()
{
Width = 720;
Height = 480;
AddControl(_title);
AddControl(_subtitle);
AddControl(_description);
AddControl(_sysList);
AddControl(_connect);
AddControl(_disconnect);
_connect.Text = "Connect";
_connect.AutoSize = true;
_title.Font = LoadedSkin.HeaderFont;
_title.AutoSize = true;
_title.Text = "Network";
_subtitle.AutoSize = true;
_subtitle.Text = "Select a Digital Society system below to view information about it.";
_subtitle.Font = LoadedSkin.Header3Font;
_sysList.DoubleClick += () =>
{
if(_sysList.SelectedItem != null)
{
ProcedurallyGenerateWhatWillBringShiftOSBack(_sysList.SelectedItem as Hackable);
}
};
_sysList.KeyEvent += (k) =>
{
if (k.Key == Microsoft.Xna.Framework.Input.Keys.Enter)
{
if (_sysList.SelectedItem != null)
{
ProcedurallyGenerateWhatWillBringShiftOSBack(_sysList.SelectedItem as Hackable);
}
}
};
_connect.Click += () =>
{
ListPorts();
};
}
public void ListPorts()
{
_state = NetworkGUIState.PortsList;
int portListStart = _sysList.Y;
int portHeight = 100;
for(int i = 0; i < _current.PortsToUnlock.Count; i++)
{
var portview = new PortView(_current.PortsToUnlock[i]);
portview.Width = _sysList.Width;
portview.X = _sysList.X;
portview.Y = portListStart + (portHeight * i);
portview.Height = portHeight;
AddControl(portview);
}
}
public void OnLoad()
{
ListHackables();
}
bool doCountdown = false;
public void ProcedurallyGenerateWhatWillBringShiftOSBack(Hackable hackable)
{
_state = NetworkGUIState.Information;
Hacking.InitHack(hackable);
doCountdown = Hacking.CurrentHackable.DoConnectionTimeout;
Hacking.CurrentHackable.DoConnectionTimeout = false;
_current = Hacking.CurrentHackable;
}
public void ListHackables()
{
_state = NetworkGUIState.Listing;
_sysList.ClearItems();
foreach(var hackable in Hacking.AvailableToHack.OrderBy(x=>x.FriendlyName))
{
_sysList.AddItem(hackable);
}
}
public void OnSkinLoad()
{
}
public bool OnUnload()
{
return true;
}
public void OnUpgrade()
{
}
protected override void OnLayout(GameTime gameTime)
{
_title.X = 15;
_title.Y = 15;
_subtitle.X = 15;
_subtitle.Y = _title.Y + _title.Height + 7;
_description.Visible = (_current != null) && _state != NetworkGUIState.Listing;
_connect.Visible = (_current != null) && _state == NetworkGUIState.Information;
_disconnect.Visible = (_current != null) && _state == NetworkGUIState.Information;
_sysList.Visible = _state == NetworkGUIState.Listing;
if (_sysList.Visible)
{
_sysList.X = 15;
_sysList.Y = _subtitle.Y + _subtitle.Height + 10;
_sysList.Width = this.Width - 30;
_sysList.Height = (Height - _sysList.Y - 15);
_title.Text = "Network";
_subtitle.Text = "Select a Digital Society system below to view information about it.";
}
if (_current != null)
{
_title.Text = _current.Data.SystemName;
_subtitle.Text = _current.Data.FriendlyName;
if(_state == NetworkGUIState.Information)
{
_description.Visible = true;
_description.AutoSize = false;
_description.X = _sysList.X;
_description.Y = _sysList.Y;
_description.Width = _sysList.Width;
_description.Height = _sysList.Height - 50;
_description.Text = $@"System type: {_current.Data.SystemType}
Loot rarity: {_current.Data.LootRarity}
{_current.Data.Description}";
_connect.Visible = true;
_connect.X = Width - _connect.Width - 15;
_connect.Y = _description.Y + _description.Height + 15;
}
}
base.OnLayout(gameTime);
}
public class PortView : Control
{
private Port _port = null;
private Button _start = new Button();
public PortView(Port port)
{
_port = port;
_start.AutoSize = true;
_start.Text = "Connect";
_start.Click += () =>
{
ConnectionStarted?.Invoke(port);
};
AddControl(_start);
}
private bool unlocked = false;
protected override void OnLayout(GameTime gameTime)
{
_start.Y = (Height - _start.Height) / 2;
_start.X = (Width - _start.Width) - 15;
unlocked = _port.Locks.Count > 0;
base.OnLayout(gameTime);
}
protected override void OnPaint(GraphicsContext gfx)
{
gfx.Clear(LoadedSkin.ControlTextColor.ToMonoColor());
gfx.DrawRectangle(1, 1, Width - 2, Height - 2, LoadedSkin.ControlColor.ToMonoColor());
gfx.DrawString(_port.Name + " (" + _port.Value + ")", 15, 15, LoadedSkin.ControlTextColor.ToMonoColor(), LoadedSkin.Header3Font);
string _status = "Tier: " + _port.Tier.ToString();
string lockstatus = (unlocked == true) ? "Unlocked" : $"{_port.Locks.Count} locks";
_status += " - " + lockstatus;
gfx.DrawString(_status, 15, 15 + LoadedSkin.Header3Font.Height + 5, LoadedSkin.ControlTextColor.ToMonoColor(), LoadedSkin.MainFont);
}
public event Action<Port> ConnectionStarted;
}
public enum NetworkGUIState
{
Listing,
Information,
PortsList,
}
}
}

View file

@ -120,7 +120,8 @@ namespace ShiftOS.Frontend
[Command("shutdown", description = "{DESC_SHUTDOWN}")]
public static bool Shutdown()
{
SaveSystem.SaveGame();
if(Objects.ShiftFS.Utils.Mounts.Count > 0)
SaveSystem.SaveGame();
AppearanceManager.Exit();
return true;
}

View file

@ -105,22 +105,16 @@ namespace ShiftOS.Frontend.GraphicsSubsystem
{
x += _startx;
y += _starty;
var tex2 = new Texture2D(_graphicsDevice, 1, 1, false, SurfaceFormat.Color);
byte[] colordata = new byte[] { color.B, color.G, color.R, color.A };
tex2.SetData<byte>(colordata);
int distance = (int)Vector2.Distance(new Vector2(x, y), new Vector2(x1, y1));
float rotation = getRotation(x, y, x1, y1);
_spritebatch.Draw(tex2, new Rectangle(x, y, distance, thickness), null, color, rotation, Vector2.Zero, SpriteEffects.None, 0);
_spritebatch.Draw(UIManager.SkinTextures["PureWhite"], new Rectangle(x, y, distance, thickness), null, color, rotation, Vector2.Zero, SpriteEffects.None, 0);
}
public void DrawRectangle(int x, int y, int width, int height, Color color)
{
x += _startx;
y += _starty;
var tex2 = new Texture2D(_graphicsDevice, 1, 1, false, SurfaceFormat.Color);
byte[] colordata = new byte[] { 255, 255, 255, 255 };
tex2.SetData<byte>(colordata);
_spritebatch.Draw(tex2, new Rectangle(x, y, width, height), color);
_spritebatch.Draw(UIManager.SkinTextures["PureWhite"], new Rectangle(x, y, width, height), color);
}
public void DrawRectangle(int x, int y, int width, int height, Texture2D tex2)

View file

@ -233,7 +233,9 @@ namespace ShiftOS.Frontend.GraphicsSubsystem
SkinTextures.Add(colorfield.Name, tex2);
}
var pureWhite = new Texture2D(graphics, 1, 1);
pureWhite.SetData<byte>(new byte[] { 255, 255, 255, 255 });
SkinTextures.Add("PureWhite", pureWhite);
}

View file

@ -23,6 +23,8 @@ namespace ShiftOS.Frontend
private TextControl _resDisplay = new TextControl();
private Button _optionsSave = new Button();
private CheckBox _fullscreen = new CheckBox();
private Button _close = new Button();
public MainMenu()
{
@ -170,6 +172,7 @@ namespace ShiftOS.Frontend
SaveOptions();
_menuTitle.Text = "Main Menu";
_campaign.Visible = true;
_close.Visible = true;
_sandbox.Visible = true;
_options.Visible = true;
}
@ -182,6 +185,19 @@ namespace ShiftOS.Frontend
_resIndex = _screenResolutions.Count - 1;
}
_fullscreen.Y = _sandbox.Y;
_close.X = 30;
_close.Font = _campaign.Font;
_close.Y = _options.Y + _options.Font.Height + 15;
_close.Text = "Close";
_close.Height = _campaign.Height;
_close.Width = _campaign.Width;
AddControl(_close);
_close.Click += () =>
{
SaveSystem.IsSandbox = true;
ShiftOSCommands.Shutdown();
};
}
public void SaveOptions()
@ -199,6 +215,7 @@ namespace ShiftOS.Frontend
_campaign.Visible = false;
_sandbox.Visible = false;
_options.Visible = false;
_close.Visible = false;
var res = _screenResolutions[_resIndex];
_resDisplay.Text = $"{res.Width}x{res.Height}";

View file

@ -44,6 +44,7 @@
<ItemGroup>
<Compile Include="Apps\CodeShop.cs" />
<Compile Include="Apps\FileSkimmer.cs" />
<Compile Include="Apps\Network.cs" />
<Compile Include="Apps\Pong.cs" />
<Compile Include="Apps\SkinLoader.cs" />
<Compile Include="Apps\SystemStatus.cs" />

View file

@ -14,10 +14,13 @@ namespace ShiftOS.Objects
public string PasswordHint { get; set; }
public string WelcomeMessage { get; set; }
public string Description { get; set; }
public int FirewallStrength { get; set; }
public int LootRarity { get; set; }
public int LootAmount { get; set; }
public int ConnectionTimeoutLevel { get; set; }
public int LockTier { get; set; }
public SystemType SystemType { get; set; }
@ -34,6 +37,11 @@ namespace ShiftOS.Objects
return SystemName.ToLower().Replace(" ", "_");
}
}
public override string ToString()
{
return $"{FriendlyName} ({SystemName})";
}
}
[Flags]

View file

@ -74,29 +74,66 @@ namespace ShiftOS.Engine
{
Value = 25,
Name = "SMTP mailserver (unencrypted)",
Tier = hsys.Data.LockTier,
Locks = GetLocks(hsys.Data.LockTier, hsys.Data.FirewallStrength),
});
if (data.SystemType.HasFlag(Objects.SystemType.FileServer))
hsys.PortsToUnlock.Add(new Port
{
Value = 22,
Name = "File Transfer Protocol",
Tier = hsys.Data.LockTier,
Locks = GetLocks(hsys.Data.LockTier, hsys.Data.FirewallStrength),
});
if (data.SystemType.HasFlag(Objects.SystemType.SSHServer))
hsys.PortsToUnlock.Add(new Port
{
Value = 21,
Name = "ShiftSSH server",
Tier = hsys.Data.LockTier,
Locks = GetLocks(hsys.Data.LockTier, hsys.Data.FirewallStrength),
});
if (data.SystemType.HasFlag(Objects.SystemType.Database))
hsys.PortsToUnlock.Add(new Port
{
Value = 3306,
Name = "MySQL database",
Tier = hsys.Data.LockTier,
Locks = GetLocks(hsys.Data.LockTier, hsys.Data.FirewallStrength),
});
CurrentHackable = hsys;
}
public static List<PortLock> GetLocks(int tier, int fwallstrength)
{
var locks = new List<PortLock>();
var lckTypes = new List<Type>();
foreach(var lck in ReflectMan.Types.Where(x=>x.BaseType == typeof(PortLock)))
{
var lckAttrib = lck.GetCustomAttributes(false).FirstOrDefault(x => x is LockAttribute) as LockAttribute;
if(lckAttrib != null)
{
if(lckAttrib.Tier == tier)
{
lckTypes.Add(lck);
}
}
}
if (lckTypes.Count > 0)
{
var rnd = new Random();
for (int i = 0; i < fwallstrength; i++)
{
int _typeindex = rnd.Next(lckTypes.Count);
var type = (PortLock)Activator.CreateInstance(lckTypes[_typeindex], lckTypes[_typeindex].GetCustomAttributes(false).FirstOrDefault(x => x is LockAttribute));
lckTypes.RemoveAt(_typeindex);
locks.Add(type);
}
}
return locks;
}
public static void FailHack()
{
if (CurrentHackable == null)
@ -180,5 +217,34 @@ namespace ShiftOS.Engine
{
public string Name { get; set; }
public int Value { get; set; }
public int Tier { get; set; }
public List<PortLock> Locks { get; set; } //not a hackmud thing i promise
}
public abstract class PortLock
{
public PortLock(LockAttribute attrib)
{
Attribute = attrib;
}
public LockAttribute Attribute { get; private set; }
public abstract bool Evaluate(Dictionary<string, object> args);
}
[AttributeUsage(AttributeTargets.Class, AllowMultiple =false)]
public class LockAttribute : Attribute
{
public LockAttribute(string name, string company, int tier)
{
Name = name;
Company = company;
Tier = tier;
}
public int Tier { get; private set; }
public string Name { get; private set; }
public string Company { get; private set; }
}
}