mirror of
https://git.alee14.me/shiftos-archive/ShiftOS_TheReturn.git
synced 2025-01-22 09:52:15 +00:00
chat stuff and eas failure
This commit is contained in:
parent
1f131438c0
commit
6ec4837523
7 changed files with 435 additions and 105 deletions
|
@ -11,6 +11,7 @@ using ShiftOS.Frontend.GraphicsSubsystem;
|
|||
using Microsoft.Xna.Framework;
|
||||
using static ShiftOS.Engine.SkinEngine;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
|
||||
namespace ShiftOS.Frontend.Apps
|
||||
{
|
||||
|
@ -23,17 +24,12 @@ namespace ShiftOS.Frontend.Apps
|
|||
private TextInput _input = null;
|
||||
private Button _send = null;
|
||||
private List<ChatMessage> _messages = new List<ChatMessage>();
|
||||
|
||||
|
||||
const int usersListWidth = 100;
|
||||
const int topicBarHeight = 24;
|
||||
public IRCNetwork NetInfo = null;
|
||||
|
||||
public ChatClient()
|
||||
{
|
||||
_messages.Add(new ChatMessage
|
||||
{
|
||||
Timestamp = DateTime.Now,
|
||||
Author = "michael",
|
||||
Message = "Welcome to ShiftOS IRC! Type in the box below to type a message."
|
||||
});
|
||||
_send = new GUI.Button();
|
||||
_input = new GUI.TextInput();
|
||||
_sendprompt = new GUI.TextControl();
|
||||
|
@ -81,6 +77,16 @@ namespace ShiftOS.Frontend.Apps
|
|||
}
|
||||
}
|
||||
|
||||
public bool ChannelConnected
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public bool NetworkConnected
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public void SendMessage()
|
||||
{
|
||||
_messages.Add(new Apps.ChatMessage
|
||||
|
@ -150,13 +156,16 @@ namespace ShiftOS.Frontend.Apps
|
|||
|
||||
protected override void OnPaint(GraphicsContext gfx)
|
||||
{
|
||||
int messagesTop = NetworkConnected ? topicBarHeight : 0;
|
||||
int messagesFromRight = ChannelConnected ? usersListWidth : 0;
|
||||
|
||||
int _bottomseparator = _send.Y - 10;
|
||||
gfx.DrawRectangle(0, _bottomseparator, Width, 1, UIManager.SkinTextures["ControlTextColor"]);
|
||||
int nnGap = 25;
|
||||
int messagebottom = _bottomseparator - 5;
|
||||
foreach (var msg in _messages.OrderByDescending(x=>x.Timestamp))
|
||||
{
|
||||
if (Height - messagebottom <= 0)
|
||||
if (Height - messagebottom <= messagesTop)
|
||||
break;
|
||||
var tsProper = $"[{msg.Timestamp.Hour.ToString("##")}:{msg.Timestamp.Minute.ToString("##")}]";
|
||||
var nnProper = $"<{msg.Author}>";
|
||||
|
@ -166,16 +175,134 @@ namespace ShiftOS.Frontend.Apps
|
|||
vertSeparatorLeft = (int)Math.Round(Math.Max(vertSeparatorLeft, tsMeasure.X + nnGap + nnMeasure.X+2));
|
||||
if (old != vertSeparatorLeft)
|
||||
requiresRepaint = true;
|
||||
var msgMeasure = gfx.MeasureString(msg.Message, LoadedSkin.TerminalFont, Width - vertSeparatorLeft - 4);
|
||||
var msgMeasure = gfx.MeasureString(msg.Message, LoadedSkin.TerminalFont, (Width - vertSeparatorLeft - 4) - messagesFromRight);
|
||||
messagebottom -= (int)msgMeasure.Y;
|
||||
gfx.DrawString(tsProper, 0, messagebottom, LoadedSkin.ControlTextColor.ToMonoColor(), LoadedSkin.TerminalFont);
|
||||
var nnColor = (msg.Author == SaveSystem.CurrentSave.Username) ? Color.Red : Color.LightGreen;
|
||||
var nnColor = Color.LightGreen;
|
||||
|
||||
if (msg.Author == SaveSystem.CurrentSave.Username)
|
||||
nnColor = Color.Red;
|
||||
else
|
||||
{
|
||||
if (NetInfo != null)
|
||||
{
|
||||
if (NetInfo.Channel != null)
|
||||
{
|
||||
if (NetInfo.Channel.OnlineUsers != null)
|
||||
{
|
||||
var user = NetInfo.Channel.OnlineUsers.FirstOrDefault(x => x.Nickname == msg.Author);
|
||||
if(user != null)
|
||||
{
|
||||
switch(user.Permission)
|
||||
{
|
||||
case IRCPermission.ChanOp:
|
||||
nnColor = Color.Orange;
|
||||
break;
|
||||
case IRCPermission.NetOp:
|
||||
nnColor = Color.Yellow;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gfx.DrawString(nnProper, (int)tsMeasure.X + nnGap, messagebottom, nnColor, LoadedSkin.TerminalFont);
|
||||
gfx.DrawString(msg.Message, vertSeparatorLeft + 4, messagebottom, LoadedSkin.ControlTextColor.ToMonoColor(), LoadedSkin.TerminalFont, Width - vertSeparatorLeft - 4);
|
||||
var mcolor = LoadedSkin.ControlTextColor.ToMonoColor();
|
||||
if (msg.Message.Contains(SaveSystem.CurrentSave.Username))
|
||||
mcolor = Color.Orange;
|
||||
gfx.DrawString(msg.Message, vertSeparatorLeft + 4, messagebottom, mcolor, LoadedSkin.TerminalFont, (Width - vertSeparatorLeft - 4) - messagesFromRight);
|
||||
}
|
||||
gfx.DrawRectangle(vertSeparatorLeft, 0, 1, _bottomseparator, UIManager.SkinTextures["ControlTextColor"]);
|
||||
|
||||
string topic = "";
|
||||
if (NetworkConnected)
|
||||
{
|
||||
topic = $"{NetInfo.FriendlyName}: {NetInfo.MOTD}";
|
||||
if (ChannelConnected)
|
||||
{
|
||||
topic = $"#{NetInfo.Channel.Tag} | {NetInfo.Channel.Topic}";
|
||||
int usersStartY = messagesTop;
|
||||
foreach(var user in NetInfo.Channel.OnlineUsers.OrderBy(x=>x.Nickname))
|
||||
{
|
||||
var measure = gfx.MeasureString(user.Nickname, LoadedSkin.TerminalFont);
|
||||
|
||||
var nnColor = Color.LightGreen;
|
||||
if (user.Nickname == SaveSystem.CurrentSave.Username)
|
||||
nnColor = Color.Red;
|
||||
else
|
||||
{
|
||||
switch (user.Permission)
|
||||
{
|
||||
case IRCPermission.ChanOp:
|
||||
nnColor = Color.Orange;
|
||||
break;
|
||||
case IRCPermission.NetOp:
|
||||
nnColor = Color.Yellow;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gfx.DrawString(user.Nickname, Width - messagesFromRight + 2, usersStartY, nnColor, LoadedSkin.TerminalFont);
|
||||
|
||||
usersStartY += (int)measure.Y;
|
||||
}
|
||||
gfx.DrawRectangle(Width - messagesFromRight, messagesTop, 1, _bottomseparator - messagesTop, LoadedSkin.ControlTextColor.ToMonoColor());
|
||||
}
|
||||
gfx.DrawString(topic, 0, 0, LoadedSkin.ControlTextColor.ToMonoColor(), LoadedSkin.TerminalFont);
|
||||
gfx.DrawRectangle(0, messagesTop, Width, 1, LoadedSkin.ControlTextColor.ToMonoColor());
|
||||
}
|
||||
|
||||
gfx.DrawRectangle(vertSeparatorLeft, messagesTop, 1, _bottomseparator - messagesTop, UIManager.SkinTextures["ControlTextColor"]);
|
||||
}
|
||||
|
||||
public void FakeConnection(IRCNetwork net)
|
||||
{
|
||||
NetInfo = net;
|
||||
var cs = net.Channel.OnlineUsers.FirstOrDefault(x => x.Nickname == "ChanServ");
|
||||
if (cs == null)
|
||||
net.Channel.OnlineUsers.Add(new IRCUser
|
||||
{
|
||||
Nickname = "ChanServ",
|
||||
Permission = IRCPermission.ChanOp
|
||||
});
|
||||
var t = new Thread(() =>
|
||||
{
|
||||
SendClientMessage("shiftos", $"Looking up {net.SystemName}");
|
||||
Thread.Sleep(250);
|
||||
SendClientMessage("*", $"Connecting to {net.SystemName} ({net.SystemName}:6667)");
|
||||
Thread.Sleep(1500);
|
||||
SendClientMessage("*", "Connected. Now logging in.");
|
||||
Thread.Sleep(25);
|
||||
SendClientMessage("*", "*** Looking up your hostname... ");
|
||||
Thread.Sleep(2000);
|
||||
SendClientMessage("*", "***Checking Ident");
|
||||
Thread.Sleep(10);
|
||||
SendClientMessage("*", "*** Couldn't look up your hostname");
|
||||
Thread.Sleep(10);
|
||||
SendClientMessage("*", "***No Ident response");
|
||||
Thread.Sleep(750);
|
||||
SendClientMessage("*", "Capabilities supported: account-notify extended-join identify-msg multi-prefix sasl");
|
||||
Thread.Sleep(250);
|
||||
SendClientMessage("*", "Capabilities requested: account-notify extended-join identify-msg multi-prefix");
|
||||
Thread.Sleep(250);
|
||||
SendClientMessage("*", "Capabilities acknowledged: account-notify extended-join identify-msg multi-prefix");
|
||||
Thread.Sleep(500);
|
||||
SendClientMessage("*", $"Welcome to the {net.FriendlyName} {SaveSystem.CurrentSave.Username}");
|
||||
NetworkConnected = true;
|
||||
Thread.Sleep(250);
|
||||
SendClientMessage("*", $"{SaveSystem.CurrentSave.Username} sets mode +i on {SaveSystem.CurrentSave.Username}");
|
||||
Thread.Sleep(300);
|
||||
SendClientMessage("shiftos", "Joining #" + net.Channel.Tag);
|
||||
Thread.Sleep(100);
|
||||
ChannelConnected = true;
|
||||
SendClientMessage("shiftos", $"{net.Channel.Topic}: {net.Channel.OnlineUsers.Count} users online");
|
||||
Thread.Sleep(10);
|
||||
SendClientMessage("ChanServ", "ChanServ sets mode -v on " + SaveSystem.CurrentSave.Username);
|
||||
});
|
||||
t.Start();
|
||||
}
|
||||
|
||||
public void OnLoad()
|
||||
{
|
||||
if (System.IO.File.Exists("aicache.dat"))
|
||||
|
|
|
@ -44,6 +44,30 @@ using ShiftOS.Engine;
|
|||
|
||||
namespace ShiftOS.Frontend
|
||||
{
|
||||
public static class FrontendDebugCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// Debug command to drop a fatal objective/hack failure screen in the form of an emergency alert system-esque screen.
|
||||
///
|
||||
/// ...Because WE'RE CANADA.
|
||||
/// </summary>
|
||||
[Command("drop_eas")]
|
||||
[ShellConstraint("shiftos_debug> ")]
|
||||
[RequiresArgument("id")]
|
||||
public static void DropEAS(Dictionary<string, object> args)
|
||||
{
|
||||
Story.DisplayFailure(args["id"].ToString());
|
||||
}
|
||||
|
||||
[Command("loaddefaultskn")]
|
||||
[ShellConstraint("shiftos_debug> ")]
|
||||
public static void LoadDefault()
|
||||
{
|
||||
Utils.Delete(Paths.GetPath("skin.json"));
|
||||
SkinEngine.Init();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Cowsay
|
||||
{
|
||||
[Command("cowsay")]
|
||||
|
|
|
@ -19,10 +19,28 @@ namespace ShiftOS.Frontend
|
|||
internal GraphicsDeviceManager graphicsDevice;
|
||||
SpriteBatch spriteBatch;
|
||||
|
||||
private bool isFailing = false;
|
||||
private double failFadeInMS = 0;
|
||||
private const double failFadeMaxMS = 500;
|
||||
private string failMessage = "";
|
||||
private string failRealMessage = "";
|
||||
private double failFadeOutMS = 0;
|
||||
private bool failEnded = false;
|
||||
private double failCharAddMS = 0;
|
||||
|
||||
private bool DisplayDebugInfo = false;
|
||||
|
||||
public ShiftOS()
|
||||
{
|
||||
Story.FailureRequested += (message) =>
|
||||
{
|
||||
failMessage = "";
|
||||
failRealMessage = message;
|
||||
isFailing = true;
|
||||
failFadeInMS = 0;
|
||||
failFadeOutMS = 0;
|
||||
failEnded = false;
|
||||
};
|
||||
graphicsDevice = new GraphicsDeviceManager(this);
|
||||
var uconf = Objects.UserConfig.Get();
|
||||
graphicsDevice.PreferredBackBufferHeight = uconf.ScreenHeight;
|
||||
|
@ -154,115 +172,163 @@ namespace ShiftOS.Frontend
|
|||
/// <param name="gameTime">Provides a snapshot of timing values.</param>
|
||||
protected override void Update(GameTime gameTime)
|
||||
{
|
||||
if (UIManager.CrossThreadOperations.Count > 0)
|
||||
if (isFailing)
|
||||
{
|
||||
var action = UIManager.CrossThreadOperations.Dequeue();
|
||||
action?.Invoke();
|
||||
}
|
||||
|
||||
//Let's get the mouse state
|
||||
var mouseState = Mouse.GetState(this.Window);
|
||||
LastMouseState = mouseState;
|
||||
|
||||
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!
|
||||
|
||||
//Let's see how keyboard input works.
|
||||
|
||||
//Hmmm... just like the mouse...
|
||||
var keystate = Keyboard.GetState();
|
||||
|
||||
//Simple... just iterate through this list and generate some key events?
|
||||
var keys = keystate.GetPressedKeys();
|
||||
if (keys.Length > 0)
|
||||
{
|
||||
var key = keys.FirstOrDefault(x => x != Keys.LeftControl && x != Keys.RightControl && x != Keys.LeftShift && x != Keys.RightShift && x != Keys.LeftAlt && x != Keys.RightAlt);
|
||||
if(lastKey != key)
|
||||
if (failFadeInMS < failFadeMaxMS)
|
||||
failFadeInMS += gameTime.ElapsedGameTime.TotalMilliseconds;
|
||||
if(failEnded == false)
|
||||
{
|
||||
kb_elapsedms = 0;
|
||||
lastKey = key;
|
||||
}
|
||||
}
|
||||
if (keystate.IsKeyDown(lastKey))
|
||||
{
|
||||
if (kb_elapsedms == 0 || kb_elapsedms >= 500)
|
||||
{
|
||||
if (lastKey == Keys.F11)
|
||||
shroudOpacity = (float)GUI.ProgressBar.linear(failFadeInMS, 0, failFadeMaxMS, 0, 1);
|
||||
if(shroudOpacity >= 1)
|
||||
{
|
||||
UIManager.Fullscreen = !UIManager.Fullscreen;
|
||||
}
|
||||
else
|
||||
{
|
||||
var shift = keystate.IsKeyDown(Keys.LeftShift) || keystate.IsKeyDown(Keys.RightShift);
|
||||
var alt = keystate.IsKeyDown(Keys.LeftAlt) || keystate.IsKeyDown(Keys.RightAlt);
|
||||
var control = keystate.IsKeyDown(Keys.LeftControl) || keystate.IsKeyDown(Keys.RightControl);
|
||||
|
||||
if (control && lastKey == Keys.D)
|
||||
if (failMessage == failRealMessage + "|")
|
||||
{
|
||||
DisplayDebugInfo = !DisplayDebugInfo;
|
||||
var keydata = Keyboard.GetState();
|
||||
|
||||
if (keydata.GetPressedKeys().FirstOrDefault(x => x != Keys.None) != Keys.None)
|
||||
{
|
||||
failEnded = true;
|
||||
}
|
||||
}
|
||||
else if(control && lastKey == Keys.E)
|
||||
{
|
||||
UIManager.ExperimentalEffects = !UIManager.ExperimentalEffects;
|
||||
}
|
||||
else
|
||||
{
|
||||
var e = new KeyEvent(control, alt, shift, lastKey);
|
||||
UIManager.ProcessKeyEvent(e);
|
||||
failCharAddMS += gameTime.ElapsedGameTime.TotalMilliseconds;
|
||||
if (failCharAddMS >= 75)
|
||||
{
|
||||
failMessage = failRealMessage.Substring(0, failMessage.Length) + "|";
|
||||
failCharAddMS = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
kb_elapsedms += gameTime.ElapsedGameTime.TotalMilliseconds;
|
||||
}
|
||||
else
|
||||
{
|
||||
kb_elapsedms = 0;
|
||||
}
|
||||
|
||||
//Cause layout update on all elements
|
||||
UIManager.LayoutUpdate(gameTime);
|
||||
|
||||
timeSinceLastPurge += gameTime.ElapsedGameTime.TotalSeconds;
|
||||
|
||||
if(timeSinceLastPurge > 2)
|
||||
{
|
||||
GraphicsContext.StringCaches.Clear();
|
||||
timeSinceLastPurge = 0;
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
|
||||
//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)
|
||||
}
|
||||
else
|
||||
{
|
||||
Hacking.CurrentHackable.MillisecondsCountdown -= gameTime.ElapsedGameTime.TotalMilliseconds;
|
||||
shroudOpacity = (float)GUI.ProgressBar.linear(Hacking.CurrentHackable.MillisecondsCountdown, Hacking.CurrentHackable.TotalConnectionTimeMS, 0, 0, 1);
|
||||
if (Hacking.CurrentHackable.MillisecondsCountdown <= 0)
|
||||
if(failFadeOutMS < failFadeMaxMS)
|
||||
{
|
||||
Hacking.FailHack();
|
||||
failFadeOutMS += gameTime.ElapsedGameTime.TotalMilliseconds;
|
||||
}
|
||||
|
||||
shroudOpacity = 1 - (float)GUI.ProgressBar.linear(failFadeOutMS, 0, failFadeMaxMS, 0, 1);
|
||||
|
||||
if(shroudOpacity <= 0)
|
||||
{
|
||||
isFailing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shroudOpacity = 0;
|
||||
if (UIManager.CrossThreadOperations.Count > 0)
|
||||
{
|
||||
var action = UIManager.CrossThreadOperations.Dequeue();
|
||||
action?.Invoke();
|
||||
}
|
||||
|
||||
//Let's get the mouse state
|
||||
var mouseState = Mouse.GetState(this.Window);
|
||||
LastMouseState = mouseState;
|
||||
|
||||
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!
|
||||
|
||||
//Let's see how keyboard input works.
|
||||
|
||||
//Hmmm... just like the mouse...
|
||||
var keystate = Keyboard.GetState();
|
||||
|
||||
//Simple... just iterate through this list and generate some key events?
|
||||
var keys = keystate.GetPressedKeys();
|
||||
if (keys.Length > 0)
|
||||
{
|
||||
var key = keys.FirstOrDefault(x => x != Keys.LeftControl && x != Keys.RightControl && x != Keys.LeftShift && x != Keys.RightShift && x != Keys.LeftAlt && x != Keys.RightAlt);
|
||||
if (lastKey != key)
|
||||
{
|
||||
kb_elapsedms = 0;
|
||||
lastKey = key;
|
||||
}
|
||||
}
|
||||
if (keystate.IsKeyDown(lastKey))
|
||||
{
|
||||
if (kb_elapsedms == 0 || kb_elapsedms >= 500)
|
||||
{
|
||||
if (lastKey == Keys.F11)
|
||||
{
|
||||
UIManager.Fullscreen = !UIManager.Fullscreen;
|
||||
}
|
||||
else
|
||||
{
|
||||
var shift = keystate.IsKeyDown(Keys.LeftShift) || keystate.IsKeyDown(Keys.RightShift);
|
||||
var alt = keystate.IsKeyDown(Keys.LeftAlt) || keystate.IsKeyDown(Keys.RightAlt);
|
||||
var control = keystate.IsKeyDown(Keys.LeftControl) || keystate.IsKeyDown(Keys.RightControl);
|
||||
|
||||
if (control && lastKey == Keys.D)
|
||||
{
|
||||
DisplayDebugInfo = !DisplayDebugInfo;
|
||||
}
|
||||
else if (control && lastKey == Keys.E)
|
||||
{
|
||||
UIManager.ExperimentalEffects = !UIManager.ExperimentalEffects;
|
||||
}
|
||||
else
|
||||
{
|
||||
var e = new KeyEvent(control, alt, shift, lastKey);
|
||||
UIManager.ProcessKeyEvent(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
kb_elapsedms += gameTime.ElapsedGameTime.TotalMilliseconds;
|
||||
}
|
||||
else
|
||||
{
|
||||
kb_elapsedms = 0;
|
||||
}
|
||||
|
||||
//Cause layout update on all elements
|
||||
UIManager.LayoutUpdate(gameTime);
|
||||
|
||||
timeSinceLastPurge += gameTime.ElapsedGameTime.TotalSeconds;
|
||||
|
||||
if (timeSinceLastPurge > 2)
|
||||
{
|
||||
GraphicsContext.StringCaches.Clear();
|
||||
timeSinceLastPurge = 0;
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
|
||||
//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;
|
||||
shroudOpacity = (float)GUI.ProgressBar.linear(Hacking.CurrentHackable.MillisecondsCountdown, Hacking.CurrentHackable.TotalConnectionTimeMS, 0, 0, 1);
|
||||
if (Hacking.CurrentHackable.MillisecondsCountdown <= 0)
|
||||
{
|
||||
Hacking.FailHack();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shroudOpacity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
base.Update(gameTime);
|
||||
}
|
||||
|
||||
|
@ -301,6 +367,21 @@ namespace ShiftOS.Frontend
|
|||
|
||||
spriteBatch.Draw(UIManager.SkinTextures["PureWhite"], new Rectangle(0, 0, UIManager.Viewport.Width, UIManager.Viewport.Height), Color.Red * shroudOpacity);
|
||||
|
||||
if(isFailing && failFadeInMS >= failFadeMaxMS)
|
||||
{
|
||||
var gfx = new GraphicsContext(graphicsDevice.GraphicsDevice, spriteBatch, 0,0, UIManager.Viewport.Width, UIManager.Viewport.Height);
|
||||
string objectiveFailed = "- OBJECTIVE FAILURE -";
|
||||
string prompt = "[press any key to dismiss this message and return to your sentience]";
|
||||
int textMaxWidth = UIManager.Viewport.Width / 3;
|
||||
var topMeasure = gfx.MeasureString(objectiveFailed, SkinEngine.LoadedSkin.HeaderFont, textMaxWidth);
|
||||
var msgMeasure = gfx.MeasureString(failMessage, SkinEngine.LoadedSkin.Header3Font, textMaxWidth);
|
||||
var pMeasure = gfx.MeasureString(prompt, SkinEngine.LoadedSkin.MainFont, textMaxWidth);
|
||||
|
||||
gfx.DrawString(objectiveFailed, (UIManager.Viewport.Width - (int)topMeasure.X) / 2, UIManager.Viewport.Height / 3, Color.White, SkinEngine.LoadedSkin.HeaderFont, textMaxWidth);
|
||||
gfx.DrawString(failMessage, (UIManager.Viewport.Width - (int)msgMeasure.X) / 2, (UIManager.Viewport.Height - (int)msgMeasure.Y) / 2, Color.White, SkinEngine.LoadedSkin.Header3Font, textMaxWidth);
|
||||
gfx.DrawString(prompt, (UIManager.Viewport.Width - (int)pMeasure.X) / 2, UIManager.Viewport.Height - (UIManager.Viewport.Height / 3), Color.White, SkinEngine.LoadedSkin.MainFont, textMaxWidth);
|
||||
}
|
||||
|
||||
if(Hacking.CurrentHackable != null)
|
||||
{
|
||||
if (Hacking.CurrentHackable.DoConnectionTimeout)
|
||||
|
|
|
@ -257,5 +257,57 @@ namespace ShiftOS.Frontend.Stories
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
[RequiresUpgrade("tutorial_hacking_basics")]
|
||||
[Mission("the_syndicate", "The Syndicate", "You just exploited a server owned by a group known as ShiftSyndicate. They found out, and they see you as a worthy recruit.", 250, "thejackel")]
|
||||
public static void TheSyndicateEntry()
|
||||
{
|
||||
Story.Context.AutoComplete = false;
|
||||
var irc = AppearanceManager.OpenForms.FirstOrDefault(x => x.ParentWindow is Apps.ChatClient) as Apps.ChatClient;
|
||||
if (irc == null)
|
||||
{
|
||||
irc = new Apps.ChatClient();
|
||||
AppearanceManager.SetupWindow(irc);
|
||||
}
|
||||
|
||||
irc.FakeConnection(new Objects.IRCNetwork
|
||||
{
|
||||
SystemName = "shiftsyndicate_irc",
|
||||
FriendlyName = "ShiftSyndicate IRC Network",
|
||||
MOTD = "Welcome to ShiftSyndicate IRC. This network is dedicated to finding out what this Digital Society is and how to break out. Unauthorized users WILL be z-lined.",
|
||||
Channel = new Objects.IRCChannel
|
||||
{
|
||||
Tag = "recruitment",
|
||||
Topic = "Artificial intelligence do everything now. Nobody is really here.",
|
||||
OnlineUsers = new List<Objects.IRCUser>
|
||||
{
|
||||
new Objects.IRCUser
|
||||
{
|
||||
Nickname = "thejackel",
|
||||
Permission = Objects.IRCPermission.NetOp
|
||||
},
|
||||
new Objects.IRCUser
|
||||
{
|
||||
Nickname = SaveSystem.CurrentSave.Username,
|
||||
Permission = Objects.IRCPermission.User
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
while (!irc.ChannelConnected)
|
||||
Thread.Sleep(10);
|
||||
SendClientMessage(irc, "thejackel", $"Hello there, {SaveSystem.CurrentSave.Username}. Welcome to our network.");
|
||||
SendClientMessage(irc, "thejackel", $"I see you breached our File Transfer Protocol server.");
|
||||
SendClientMessage(irc, "thejackel", $"You may not realize exactly who we are...");
|
||||
SendClientMessage(irc, "thejackel", $"We know about you, and we know what you want.");
|
||||
SendClientMessage(irc, "thejackel", $"");
|
||||
|
||||
}
|
||||
|
||||
public static void SendClientMessage(Apps.ChatClient client, string nick, string message)
|
||||
{
|
||||
Thread.Sleep(message.Length * 25);
|
||||
client.SendClientMessage(nick, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
37
ShiftOS.Objects/IRCNetwork.cs
Normal file
37
ShiftOS.Objects/IRCNetwork.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ShiftOS.Objects
|
||||
{
|
||||
public class IRCNetwork
|
||||
{
|
||||
public string SystemName { get; set; }
|
||||
public string FriendlyName { get; set; }
|
||||
public string MOTD { get; set; }
|
||||
public IRCChannel Channel { get; set; }
|
||||
}
|
||||
|
||||
public class IRCChannel
|
||||
{
|
||||
public string Tag { get; set; }
|
||||
public string Topic { get; set; }
|
||||
public List<IRCUser> OnlineUsers { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class IRCUser
|
||||
{
|
||||
public string Nickname { get; set; }
|
||||
public IRCPermission Permission { get; set; }
|
||||
}
|
||||
|
||||
public enum IRCPermission
|
||||
{
|
||||
User,
|
||||
ChanOp,
|
||||
NetOp,
|
||||
}
|
||||
}
|
|
@ -52,6 +52,7 @@
|
|||
<Compile Include="Hacking\Payload.cs" />
|
||||
<Compile Include="Hacking\Exploit.cs" />
|
||||
<Compile Include="Hacking\Hackable.cs" />
|
||||
<Compile Include="IRCNetwork.cs" />
|
||||
<Compile Include="MudAttributes.cs" />
|
||||
<Compile Include="Objects.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
|
|
@ -95,6 +95,14 @@ namespace ShiftOS.Engine
|
|||
public static StoryContext Context { get; private set; }
|
||||
public static event Action<string> StoryComplete;
|
||||
public static List<Objective> CurrentObjectives { get; private set; }
|
||||
public static event Action<string> FailureRequested;
|
||||
|
||||
public static void DisplayFailure(string message)
|
||||
{
|
||||
FailureRequested?.Invoke(message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void PushObjective(string name, string desc, Func<bool> completeFunc, Action onComplete)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue