From 1661f9a5bd46dbd7d2586787c55bfc407c027629 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 23 Jun 2017 20:20:38 -0400 Subject: hacking work Me: [squeaky] IT'S WORKING!! Phil: Michael... You just creeped me out... --- ShiftOS.WinForms/Stories/LegionStory.cs | 186 +++++++++++++++++++++++++++++++- 1 file changed, 184 insertions(+), 2 deletions(-) (limited to 'ShiftOS.WinForms/Stories') diff --git a/ShiftOS.WinForms/Stories/LegionStory.cs b/ShiftOS.WinForms/Stories/LegionStory.cs index 168d55c..0723a37 100644 --- a/ShiftOS.WinForms/Stories/LegionStory.cs +++ b/ShiftOS.WinForms/Stories/LegionStory.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using Newtonsoft.Json; using ShiftOS.Engine; namespace ShiftOS.WinForms.Stories @@ -80,6 +81,188 @@ namespace ShiftOS.WinForms.Stories Story.Start("aiden_shiftnet2"); } + [Story("hacker101_breakingbonds_3")] + public static void BreakingTheBonds_Outro() + { + Story.Context.AutoComplete = false; + CharacterName = "hacker101"; + SysName = "pebcak"; + + if (!terminalOpen()) + { + var term = new Applications.Terminal(); + AppearanceManager.SetupWindow(term); + } + + WriteLine("Now let's teach you how to hack others' systems."); + WriteLine("I'll start up a safe virtual environment for you to mess with."); + VirtualEnvironments.Create("pebcak_devel", new List + { + new Objects.ClientSave + { + Username = "root", + Password = GenRandomPassword(), + Permissions = Objects.UserPermissions.Root + }, + new Objects.ClientSave + { + Username = "user", + Password = "", + Permissions = Objects.UserPermissions.Admin, + } + }, 6500l, JsonConvert.DeserializeObject(Properties.Resources.PebcakDevelFS)); + Thread.Sleep(2000); + WriteLine("It's all set up now. The system name for this environment is \"pebcak_devel\"."); + WriteLine("This server allows FTP connections through your File Skimmer."); + WriteLine("Other systems can allow RTS connections (which allows you to control their terminals remotely), SMTP (mail transfer), etc. It depends on the system's role."); + + bool isFsCopyInstalled = Shiftorium.UpgradeInstalled("fs_copy"); + if (isFsCopyInstalled == false) + { + WriteLine("Before we can begin, one last thing. You need the FS Copy Shiftorium upgrade."); + Story.PushObjective("Breaking The Bonds: Preparations", "You need to buy the FS Copy upgrade from the Shiftorium.", () => { return Shiftorium.UpgradeInstalled("fs_copy"); }, () => + { + isFsCopyInstalled = true; + }); + } + while (isFsCopyInstalled == false) + Thread.Sleep(10); + + WriteLine("Alright, open your File Skimmer, click \"Start Remote Session\", and connect to the system name \"pebcak_devel\" with user name \"user\" and no password."); + + Story.PushObjective("Breaking The Bonds: A little practice...", "hacker101 has set up a virtual environment for you to connect to. Its system name is \"pebcak_local\", and has an unsecured user account with the name \"user\". Log into that user using your File Skimmer.", + () => { return Applications.FileSkimmer.OpenConnection.SystemName == "pebcak_devel"; }, + () => + { + WriteLine("Good work. You're in. This user only has Admin privileges, and doesn't have anything useful on it. This is where hacking comes in."); + WriteLine("See that \"super private personal stuff\" folder? It can only be accessed as a root user. You'll need the root password for pebcak_devel to get in there."); + WriteLine("I'll send you a password cracking utility that can use open ShiftOS connections to sniff out all the users on the system and allow you to brute-force into an account."); + Console.WriteLine("New program unlocked: brute"); + SaveSystem.CurrentSave.StoriesExperienced.Add("brute"); + WriteLine("Go ahead and open it! Use it to breach the root user on pebcak_devel."); + WriteLine("Once you've got the root password, click the Reauthenticate button in File Skimmer and it will ask you to log in as a new user."); + WriteLine("Use the new credentials to log in."); + Story.PushObjective("Breaking The Bonds: The Brute", "Use your new \"brute\" application to breach the root account on pebcak_local so you can access the super secret folder and download its contents.", () => + { + return Applications.FileSkimmer.CurrentRemoteUser == Applications.FileSkimmer.OpenConnection.Users.FirstOrDefault(x => x.Username == "root"); + }, + () => + { + WriteLine("Now, open the folder and you can copy files and folders from it to your system."); + WriteLine("You've got 60 seconds before ShiftOS's internet daemon terminates this connection."); + int counter = 60; + while(counter > 0 && Applications.FileSkimmer.OpenConnection.SystemName == "pebcak_devel") + { + Thread.Sleep(1000); + Console.WriteLine("Connection termination in " + counter + " seconds..."); + if (counter == 30 || counter == 15) + Engine.AudioManager.PlayStream(Properties.Resources._3beepvirus); + if (counter <= 10) + Engine.AudioManager.PlayStream(Properties.Resources.writesound); + counter--; + } + VirtualEnvironments.Clear(); + Applications.FileSkimmer.DisconnectRemote(); + }); + }); + } + + [Story("brute")] + public static void BreakingBondsStubStory() + { + //just to annoy victor tran + } + + public static string GenRandomPassword() + { + var rnd = new Random(); + int len = rnd.Next(5, 15); + string pass = ""; + for(int i = 0; i < len; i++) + { + pass += (char)rnd.Next(255); + } + return pass; + } + + [Story("hacker101_breakingbonds_2")] + public static void BreakingTheBonds_Patchwork() + { + CharacterName = "hacker101"; + SysName = "pebcak"; + + if (!terminalOpen()) + { + var term = new Applications.Terminal(); + AppearanceManager.SetupWindow(term); + } + + WriteLine("hacker101@pebcak - user connecting to your system.", false); + Thread.Sleep(2000); + WriteLine("Alright, you've gotten the applications you need."); + WriteLine("Now, I know you're wondering, why do you need these three applications on your system?"); + WriteLine("Well, you're going to be doing some shady things and we need secure ways of storing the things you learn."); + WriteLine("TriWrite is also needed so you can view rich-formatted text documents without them being garbled in TextPad."); + WriteLine("Address Book is a secure way of storing information about the people you meet and learn about in the Digital Society."); + WriteLine("And SimpleSRC is a chat system, much more advanced and secure than this remote terminal stuff you may have seen people doing to you."); + WriteLine("ALL further operations with me will be done on SimpleSRC. But, for now, let's get you set up with your task."); + WriteLine("You're going to be learning how to hack and crack systems in the Digital Society."); + WriteLine("And this ain't no hippy DDoS stuff. Pfft, that crap is boring as hell."); + WriteLine("I'm talking the ability to steal people's files remotely, read them on your system, and also, gain desktop-level and even root-level access to their ShiftOS installations, without them even knowing."); + WriteLine("You'll be able to steal documents, programs, Codepoints and even more."); + WriteLine("Of course, there's going to be defenses in place on other people's systems, such as secure passwords, advanced firewalls, network monitors, virus scanners, etc. You should get those kinds of things going on your system before we continue."); + Story.Context.AutoComplete = false; + WriteLine("I'll push out a sequence of objectives for you to follow to get your system secure."); + Story.PushObjective("Breaking The Bonds: Patchwork - Get a virus scanner.", "Viruses are programs with the intent to harm users. They spread across the Digital Society infecting whoever they can find. A virus scanner can help you fight them off. There's a minimal one in the Shiftorium. Go get it!", + + () => { return Shiftorium.UpgradeInstalled("virus_scanner"); }, + () => + { + WriteLine("Alright, you've got a virus scanning program."); + WriteLine("Now, let's take care of your system's biggest vulnerability, your root account."); + bool isRootVulnerable = false; + if (string.IsNullOrWhiteSpace(SaveSystem.Users.FirstOrDefault(x => x.Username == "root").Password)) + { + isRootVulnerable = true; + WriteLine("I was able to authenticate as root on your system without a password. Use the passwd command when logged in as root to change that."); + Story.PushObjective("Breaking The Bonds: Patchwork - Set a root password.", "If you aren't already, login as root using the su command. Then, Jesus Christ, set a root password!", + () => { return string.IsNullOrWhiteSpace(SaveSystem.Users.FirstOrDefault(x => x.Username == "root").Password); }, + () => { + WriteLine("Man, oh man. My connection got terminated. That means you did it."); + WriteLine("Be lucky that was me and not someone who wanted to harm you."); + WriteLine("In ShiftOS, as well as most other Unix-likes, the root account has full permissions to everything on your system, no matter what."); + WriteLine("If someone gains access to your root system remotely, you must change its password immediately or you can call that system toast."); + + isRootVulnerable = false; }); + } + while (isRootVulnerable) + Thread.Sleep(10); + + WriteLine("Alright, now let's make you another user account."); + WriteLine("This user account will have administrative permissions, but in order for you to use them, you'll need to type your root password to confirm any administrative task."); + WriteLine("Use the adduser command to add a new user. Give it a name, log into it, set a password if you'd like, then log back into root using su..."); + WriteLine("Then, in root, run \"setuserpermissions --user \"yourusername\" --val 2\". This will give the specified user \"admin\" permissions."); + Story.PushObjective("Breaking The Bonds: Patchwork - Create an admin user", "Your root account looks nice and safe, but it's good practice on any Unix-like operating system, including ShiftOS, to have a user with slightly lower permissions called an Admin user. This user can do all the things that root can, but it requires you to enter your root password to verify administrative tasks.", + + () => + { + bool success = false; + if(SaveSystem.Users.Count() > 1) + { + success = SaveSystem.Users.FirstOrDefault(x => x.Username != "root" && x.Permissions == Objects.UserPermissions.Admin) != null; + } + return success; + }, + () => + { + WriteLine("It's as secure as you need now. There are a few other things you'll want to do, like setting up a firewall and a network monitor, but we'll save that for later."); + Story.Context.MarkComplete(); + Story.Start("hacker101_breakingbonds_3"); + }); + }); + + } + [Story("hacker101_breakingbonds_1")] public static void BreakingTheBondsIntro() { @@ -99,7 +282,6 @@ namespace ShiftOS.WinForms.Stories WriteLine("Before I can do that, however, I need you to do a few things."); WriteLine("I'll assign what I need you to do as an objective. When you're done, I'll tell you what you need to know."); - Story.Context.MarkComplete(); TerminalBackend.PrefixEnabled = true; Story.PushObjective("Breaking the Bonds: Errand Boy", @"hacker101 has something he needs to show you, however before he can, you need to do the following: @@ -110,7 +292,7 @@ namespace ShiftOS.WinForms.Stories { bool flag1 = Shiftorium.UpgradeInstalled("address_book"); bool flag2 = Shiftorium.UpgradeInstalled("triwrite"); - bool flag3 = Shiftorium.UpgradeInstalled("simplesrc"); + bool flag3 = Shiftorium.UpgradeInstalled("simplesrc_client"); return flag1 && flag2 && flag3; }, () => { -- cgit v1.2.3 From 8621b3ddffdd8211604f01d90ff40c9b2991f27a Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 24 Jun 2017 14:41:45 -0400 Subject: breaking the bonds storyline --- ShiftOS.WinForms/Applications/FileSkimmer.cs | 13 ++- ShiftOS.WinForms/Commands.cs | 5 +- ShiftOS.WinForms/Properties/Resources.Designer.cs | 10 ++ ShiftOS.WinForms/Properties/Resources.resx | 3 + ShiftOS.WinForms/Resources/brute.mp3 | Bin 0 -> 1206934 bytes ShiftOS.WinForms/ShiftOS.WinForms.csproj | 1 + ShiftOS.WinForms/Stories/LegionStory.cs | 19 +++- ShiftOS.WinForms/VirtualEnvironments.cs | 109 ++++++++++++++++++++++ ShiftOS_TheReturn/AudioManager.cs | 58 +++--------- 9 files changed, 165 insertions(+), 53 deletions(-) create mode 100644 ShiftOS.WinForms/Resources/brute.mp3 (limited to 'ShiftOS.WinForms/Stories') diff --git a/ShiftOS.WinForms/Applications/FileSkimmer.cs b/ShiftOS.WinForms/Applications/FileSkimmer.cs index 34f9e9c..dee751b 100644 --- a/ShiftOS.WinForms/Applications/FileSkimmer.cs +++ b/ShiftOS.WinForms/Applications/FileSkimmer.cs @@ -55,11 +55,14 @@ namespace ShiftOS.WinForms.Applications public static void DisconnectRemote() { - OnDisconnect?.Invoke(); - CurrentRemoteUser = new Objects.ClientSave(); - if (!string.IsNullOrWhiteSpace(OpenConnection.SystemName)) - Infobox.Show("Connections terminated.", "All outbound File Skimmer connections have been terminated."); - OpenConnection = new ShiftOSEnvironment(); + Desktop.InvokeOnWorkerThread(() => + { + OnDisconnect?.Invoke(); + CurrentRemoteUser = new Objects.ClientSave(); + if (!string.IsNullOrWhiteSpace(OpenConnection.SystemName)) + Infobox.Show("Connections terminated.", "All outbound File Skimmer connections have been terminated."); + OpenConnection = new ShiftOSEnvironment(); + }); } public FileSkimmer() diff --git a/ShiftOS.WinForms/Commands.cs b/ShiftOS.WinForms/Commands.cs index c7d8f5b..c9e9376 100644 --- a/ShiftOS.WinForms/Commands.cs +++ b/ShiftOS.WinForms/Commands.cs @@ -49,7 +49,10 @@ namespace ShiftOS.Engine [Command("clear", description = "{DESC_CLEAR}")] public static bool Clear() { - AppearanceManager.ConsoleOut.Clear(); + Desktop.InvokeOnWorkerThread(() => + { + AppearanceManager.ConsoleOut.Clear(); + }); return true; } } diff --git a/ShiftOS.WinForms/Properties/Resources.Designer.cs b/ShiftOS.WinForms/Properties/Resources.Designer.cs index 83515c4..dd84e94 100644 --- a/ShiftOS.WinForms/Properties/Resources.Designer.cs +++ b/ShiftOS.WinForms/Properties/Resources.Designer.cs @@ -359,6 +359,16 @@ namespace ShiftOS.WinForms.Properties { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] brute { + get { + object obj = ResourceManager.GetObject("brute", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/ShiftOS.WinForms/Properties/Resources.resx b/ShiftOS.WinForms/Properties/Resources.resx index 8390f39..07cf941 100644 --- a/ShiftOS.WinForms/Properties/Resources.resx +++ b/ShiftOS.WinForms/Properties/Resources.resx @@ -34618,6 +34618,9 @@ ..\Resources\strings_fr.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + ..\Resources\brute.mp3;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ..\Resources\PebcakDevelFS.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 diff --git a/ShiftOS.WinForms/Resources/brute.mp3 b/ShiftOS.WinForms/Resources/brute.mp3 new file mode 100644 index 0000000..ae20cc2 Binary files /dev/null and b/ShiftOS.WinForms/Resources/brute.mp3 differ diff --git a/ShiftOS.WinForms/ShiftOS.WinForms.csproj b/ShiftOS.WinForms/ShiftOS.WinForms.csproj index f287540..d79a7e3 100644 --- a/ShiftOS.WinForms/ShiftOS.WinForms.csproj +++ b/ShiftOS.WinForms/ShiftOS.WinForms.csproj @@ -873,6 +873,7 @@ + diff --git a/ShiftOS.WinForms/Stories/LegionStory.cs b/ShiftOS.WinForms/Stories/LegionStory.cs index 0723a37..74e6ea6 100644 --- a/ShiftOS.WinForms/Stories/LegionStory.cs +++ b/ShiftOS.WinForms/Stories/LegionStory.cs @@ -163,6 +163,20 @@ namespace ShiftOS.WinForms.Stories } VirtualEnvironments.Clear(); Applications.FileSkimmer.DisconnectRemote(); + WriteLine("Connections terminated I see.. Alright. Have fun with those dummy documents - you can keep them if you'd like. There's nothing important in them."); + WriteLine("That's one thing you can do with brute and other hacking utilities. I'd recommend buying some of brute's Shiftorium upgrades to make it faster and more efficient."); + WriteLine("Also, along the way, you're going to find a lot of new tricks. Some of them will require more than just brute to get into."); + WriteLine("So be on the lookout on the Shiftnet for other hacking-related tools. You won't find any on Appscape, however..."); + WriteLine("That darn Aiden Nirh guy can't stand hackers."); + WriteLine("Looking at your logs, I see he's contacted you before... Seriously... don't let him find out about brute. He'll report it directly to DevX."); + WriteLine("Oh yeah, one more thing... that virus scanner... you may want to scan any files that you transfer from other systems with it."); + WriteLine("You never know what sorts of digital filth is hidden within such innocent-looking files."); + WriteLine("ALWAYS scan before opening - because if you open a file containing malicious code, it'll get run. It's just how ShiftOS's kernel works."); + Console.WriteLine("User has disconnected."); + Story.Context.MarkComplete(); + TerminalBackend.PrefixEnabled = true; + SaveSystem.SaveGame(); + TerminalBackend.PrintPrompt(); }); }); } @@ -173,6 +187,8 @@ namespace ShiftOS.WinForms.Stories //just to annoy victor tran } + const string VALID_PASSWORD_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_"; + public static string GenRandomPassword() { var rnd = new Random(); @@ -180,7 +196,8 @@ namespace ShiftOS.WinForms.Stories string pass = ""; for(int i = 0; i < len; i++) { - pass += (char)rnd.Next(255); + char c = VALID_PASSWORD_CHARS[rnd.Next(VALID_PASSWORD_CHARS.Length)]; + pass += c; } return pass; } diff --git a/ShiftOS.WinForms/VirtualEnvironments.cs b/ShiftOS.WinForms/VirtualEnvironments.cs index 5faa6ff..fb39569 100644 --- a/ShiftOS.WinForms/VirtualEnvironments.cs +++ b/ShiftOS.WinForms/VirtualEnvironments.cs @@ -2,7 +2,9 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; +using ShiftOS.Engine; namespace ShiftOS.WinForms { @@ -27,6 +29,113 @@ namespace ShiftOS.WinForms _environments.Clear(); } + const string VALID_PASSWORD_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_"; + + + [RequiresUpgrade("brute")] + [Command("brute")] + public static void Brute() + { + TerminalBackend.PrefixEnabled = false; + bool cracked = false; + var brute = Properties.Resources.brute; + var str = new System.IO.MemoryStream(brute); + var reader = new NAudio.Wave.Mp3FileReader(str); + var _out = new NAudio.Wave.WaveOut(); + _out.Init(reader); + _out.PlaybackStopped += (o, a) => + { + if (cracked == false) + { + cracked = true; + TerminalCommands.Clear(); + ConsoleEx.Bold = true; + ConsoleEx.ForegroundColor = ConsoleColor.Red; + Console.WriteLine(" - access denied - "); + ConsoleEx.ForegroundColor = ConsoleColor.Gray; + ConsoleEx.Bold = false; + ConsoleEx.Italic = true; + Console.WriteLine("password could not be cracked before connection termination."); + } + TerminalBackend.PrefixEnabled = true; + TerminalBackend.PrintPrompt(); + _out.Dispose(); + reader.Dispose(); + str.Dispose(); + }; + _out.Play(); + + var t = new Thread(() => + { + + + Console.WriteLine("brute - version 1.0"); + Console.WriteLine("Copyright (c) 2018 hacker101. All rights reserved."); + Console.WriteLine(); + Thread.Sleep(4000); + Console.WriteLine("Scanning outbound connections..."); + if (string.IsNullOrWhiteSpace(Applications.FileSkimmer.OpenConnection.SystemName)) + { + Thread.Sleep(2000); + Console.WriteLine(" - no outbound connections to scan, aborting - "); + _out.Stop(); + _out.Dispose(); + reader.Dispose(); + str.Dispose(); + } + else + { + Thread.Sleep(2000); + var con = Applications.FileSkimmer.OpenConnection; + Console.WriteLine($@"{con.SystemName} +------------------ + +Active connection: ftp, rts +System name: {con.SystemName} +Users: {con.Users.Count}"); + Thread.Sleep(500); + var user = con.Users.FirstOrDefault(x => x.Permissions == Objects.UserPermissions.Root); + if (user == null) + Console.WriteLine(" - no users found with root access - this is a shiftos bug - "); + else + { + Console.WriteLine(" - starting bruteforce attack on user: " + user.Username + " - "); + var rnd = new Random(); + + char[] pass = new char[user.Password.Length]; + for (int i = 0; i < pass.Length; i++) + { + if (cracked == true) + break; + while (pass[i] != user.Password[i]) + { + if (cracked == true) + break; + char c = VALID_PASSWORD_CHARS[rnd.Next(VALID_PASSWORD_CHARS.Length)]; + if (char.IsLetterOrDigit(c)) + { + pass[i] = c; + Console.WriteLine(new string(pass)); + Console.WriteLine(); + Thread.Sleep(1); + } + } + } + if (cracked == false) + { + cracked = true; + TerminalCommands.Clear(); + Console.WriteLine(" - credentials cracked. -"); + Console.WriteLine($@"sysname: {con.SystemName} +user: {user.Username} +password: {user.Password}"); + } + } + } + }); + t.Start(); + } + public static ShiftOSEnvironment Get(string sysname) { return _environments.FirstOrDefault(x => x.SystemName == sysname); diff --git a/ShiftOS_TheReturn/AudioManager.cs b/ShiftOS_TheReturn/AudioManager.cs index 85e1371..a9101b7 100644 --- a/ShiftOS_TheReturn/AudioManager.cs +++ b/ShiftOS_TheReturn/AudioManager.cs @@ -83,28 +83,15 @@ namespace ShiftOS.Engine /// The file to play. public static void Play(string file) { - bool play = true; - float volume = 1f; - if (SaveSystem.CurrentSave != null) + try { - play = (SaveSystem.CurrentSave.SoundEnabled); - volume = (float)SaveSystem.CurrentSave.MusicVolume / 100f; + var bytes = File.ReadAllBytes(file); + var str = new MemoryStream(bytes); + PlayStream(str); } - if (play) + catch { - try - { - _reader = new AudioFileReader(file); - _out = new WaveOut(); - _out.Init(_reader); - _out.Volume = volume; - _out.Play(); - _out.PlaybackStopped += (o, a) => { PlayCompleted?.Invoke(); }; - } - catch (Exception ex) - { - Console.WriteLine("Audio error: " + ex.Message); - } + } } @@ -114,35 +101,14 @@ namespace ShiftOS.Engine /// The stream to read from. public static void PlayStream(Stream str) { - try + bool play = true; + if (SaveSystem.CurrentSave != null) + play = SaveSystem.CurrentSave.SoundEnabled; + if (play) { - bool play = true; - float volume = 1f; - if (SaveSystem.CurrentSave != null) - { - play = (SaveSystem.CurrentSave.SoundEnabled); - volume = (float)SaveSystem.CurrentSave.MusicVolume / 100f; - } - if (play) - { - try - { - while (_out.PlaybackState == PlaybackState.Playing) - { - Thread.Sleep(10); - } - } - catch { } - ShiftOS.Engine.AudioManager.Stop(); - _out = new WaveOut(); - var mp3 = new WaveFileReader(str); - _out.Init(mp3); - _out.Volume = volume; - _out.Play(); - _out.PlaybackStopped += (o, a) => { PlayCompleted?.Invoke(); }; - } + var splayer = new System.Media.SoundPlayer(str); + splayer.Play(); } - catch { } } public static event Action PlayCompleted; -- cgit v1.2.3 From 4c63e5e41c55d41c0bcaa09f125299d4b1892ef6 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 24 Jun 2017 20:26:14 -0400 Subject: mission commands --- ShiftOS.WinForms/MissionCommands.cs | 83 ++++++++++++++++++++++++++++++++ ShiftOS.WinForms/ShiftOS.WinForms.csproj | 2 +- ShiftOS.WinForms/Stories/LegionStory.cs | 11 ++++- 3 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 ShiftOS.WinForms/MissionCommands.cs (limited to 'ShiftOS.WinForms/Stories') diff --git a/ShiftOS.WinForms/MissionCommands.cs b/ShiftOS.WinForms/MissionCommands.cs new file mode 100644 index 0000000..375c490 --- /dev/null +++ b/ShiftOS.WinForms/MissionCommands.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ShiftOS.Engine; + +namespace ShiftOS.WinForms +{ + [RequiresUpgrade("hacker101_breakingbonds_3")] + public static class MissionCommands + { + public static List GetMissionsList() + { + var missions = new List(); + foreach (var type in ReflectMan.Types) + { + foreach (var method in type.GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static)) + { + var attrib = method.GetCustomAttributes(false).FirstOrDefault(x => x is MissionAttribute) as MissionAttribute; + if (attrib != null) + { + if (!Shiftorium.UpgradeInstalled(attrib.StoryID)) + { + missions.Add(attrib); + } + } + } + } + return missions; + } + + [Command("missions", description = "Lists all available missions.")] + public static void ShowAll() + { + ConsoleEx.ForegroundColor = ConsoleColor.Yellow; + ConsoleEx.Bold = true; + Console.WriteLine(" - Missions - "); + + var missions = GetMissionsList(); + + ConsoleEx.ForegroundColor = ConsoleColor.White; + ConsoleEx.Bold = false; + if(missions.Count == 0) + { + Console.WriteLine("No missions available. Check back later!"); + } + else + { + foreach(var mission in missions) + { + Console.WriteLine(); + Console.WriteLine(mission.Name); + Console.WriteLine("--------------------------"); + Console.WriteLine(); + Console.WriteLine(mission.Description); + Console.WriteLine(); + Console.WriteLine("assigner: " + mission.Assigner); + Console.WriteLine("reward: " + mission.CodepointAward + " Codepoints"); + Console.WriteLine("To start this mission, run:"); + ConsoleEx.Bold = true; + Console.WriteLine("startmission --id " + missions.IndexOf(mission)); + } + } + } + + [Command("startmission", description = "Starts the specified mission.")] + [RequiresArgument("id")] + public static void StartMission(Dictionary args) + { + var id = Convert.ToInt32(args["id"].ToString()); + var missions = GetMissionsList(); + if (id < 0 || id >= missions.Count) + Console.WriteLine("Error: Mission ID not found."); + else + { + var mission = missions[id]; + Story.Start(mission.StoryID); + } + } + + } +} diff --git a/ShiftOS.WinForms/ShiftOS.WinForms.csproj b/ShiftOS.WinForms/ShiftOS.WinForms.csproj index a83bed1..570d049 100644 --- a/ShiftOS.WinForms/ShiftOS.WinForms.csproj +++ b/ShiftOS.WinForms/ShiftOS.WinForms.csproj @@ -357,7 +357,7 @@ MainMenu.cs - + Form diff --git a/ShiftOS.WinForms/Stories/LegionStory.cs b/ShiftOS.WinForms/Stories/LegionStory.cs index 74e6ea6..a91b0b1 100644 --- a/ShiftOS.WinForms/Stories/LegionStory.cs +++ b/ShiftOS.WinForms/Stories/LegionStory.cs @@ -81,7 +81,7 @@ namespace ShiftOS.WinForms.Stories Story.Start("aiden_shiftnet2"); } - [Story("hacker101_breakingbonds_3")] + [Mission("hacker101_breakingbonds_3", "Breaking the Bonds", "It's time you've learned how to hack.", 500l, "hacker101")] public static void BreakingTheBonds_Outro() { Story.Context.AutoComplete = false; @@ -172,7 +172,16 @@ namespace ShiftOS.WinForms.Stories WriteLine("Oh yeah, one more thing... that virus scanner... you may want to scan any files that you transfer from other systems with it."); WriteLine("You never know what sorts of digital filth is hidden within such innocent-looking files."); WriteLine("ALWAYS scan before opening - because if you open a file containing malicious code, it'll get run. It's just how ShiftOS's kernel works."); + WriteLine("Oh yeah, one last thing. Things are going to start getting pretty open in the Digital Society.."); + WriteLine("Multiple people are going to want you to help them out with multiple things."); + WriteLine("I've written a little command-line utility that'll help you keep track of these missions and see how far you've gotten."); + WriteLine("Use the missions command to list out all the available missions, then use the startmission command to start one."); + WriteLine("When you complete a mission, you'll earn Codepoints depending on the mission."); + WriteLine("Allow me to demonstrate..."); Console.WriteLine("User has disconnected."); + + + Story.Context.MarkComplete(); TerminalBackend.PrefixEnabled = true; SaveSystem.SaveGame(); -- cgit v1.2.3 From 8e19c8599975685410d7508b150f811dc3991f4a Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 25 Jun 2017 13:43:14 -0400 Subject: another mission --- ShiftOS.WinForms/Applications/Chat.Designer.cs | 32 ++++- ShiftOS.WinForms/Applications/Chat.cs | 97 ++++++------- ShiftOS.WinForms/Applications/Chat.resx | 23 +++- ShiftOS.WinForms/MissionCommands.cs | 37 ++++- ShiftOS.WinForms/Properties/Resources.Designer.cs | 29 ++++ ShiftOS.WinForms/Properties/Resources.resx | 7 + ShiftOS.WinForms/Resources/AppscapeServerFS.txt | 52 +++++++ ShiftOS.WinForms/ShiftOS.WinForms.csproj | 1 + ShiftOS.WinForms/Stories/LegionStory.cs | 161 ++++++++++++++++++++++ ShiftOS_TheReturn/Story.cs | 2 + 10 files changed, 376 insertions(+), 65 deletions(-) create mode 100644 ShiftOS.WinForms/Resources/AppscapeServerFS.txt (limited to 'ShiftOS.WinForms/Stories') diff --git a/ShiftOS.WinForms/Applications/Chat.Designer.cs b/ShiftOS.WinForms/Applications/Chat.Designer.cs index 7bfa4dd..622bf1a 100644 --- a/ShiftOS.WinForms/Applications/Chat.Designer.cs +++ b/ShiftOS.WinForms/Applications/Chat.Designer.cs @@ -65,9 +65,12 @@ namespace ShiftOS.WinForms.Applications this.toolStrip1 = new System.Windows.Forms.ToolStrip(); this.tschatid = new System.Windows.Forms.ToolStripLabel(); this.tsuserdata = new System.Windows.Forms.ToolStripLabel(); + this.lbtyping = new System.Windows.Forms.ToolStripLabel(); this.tsbottombar = new System.Windows.Forms.ToolStrip(); this.txtuserinput = new System.Windows.Forms.ToolStripTextBox(); this.btnsend = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.btnsendfile = new System.Windows.Forms.ToolStripButton(); this.panel1.SuspendLayout(); this.pnlstart.SuspendLayout(); this.flowLayoutPanel1.SuspendLayout(); @@ -179,7 +182,10 @@ namespace ShiftOS.WinForms.Applications // this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.tschatid, - this.tsuserdata}); + this.tsuserdata, + this.lbtyping, + this.toolStripSeparator1, + this.btnsendfile}); this.toolStrip1.Location = new System.Drawing.Point(0, 0); this.toolStrip1.Name = "toolStrip1"; this.toolStrip1.Size = new System.Drawing.Size(633, 25); @@ -198,6 +204,12 @@ namespace ShiftOS.WinForms.Applications this.tsuserdata.Size = new System.Drawing.Size(86, 22); this.tsuserdata.Text = "toolStripLabel1"; // + // lbtyping + // + this.lbtyping.Name = "lbtyping"; + this.lbtyping.Size = new System.Drawing.Size(86, 22); + this.lbtyping.Text = "toolStripLabel1"; + // // tsbottombar // this.tsbottombar.Dock = System.Windows.Forms.DockStyle.Bottom; @@ -227,6 +239,21 @@ namespace ShiftOS.WinForms.Applications this.btnsend.Text = "Send"; this.btnsend.Click += new System.EventHandler(this.btnsend_Click); // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); + // + // btnsendfile + // + this.btnsendfile.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.btnsendfile.Image = ((System.Drawing.Image)(resources.GetObject("btnsendfile.Image"))); + this.btnsendfile.ImageTransparentColor = System.Drawing.Color.Magenta; + this.btnsendfile.Name = "btnsendfile"; + this.btnsendfile.Size = new System.Drawing.Size(65, 22); + this.btnsendfile.Text = "Send a file"; + this.btnsendfile.Click += new System.EventHandler(this.btnsendfile_Click); + // // Chat // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -265,5 +292,8 @@ namespace ShiftOS.WinForms.Applications private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; private System.Windows.Forms.TextBox txtchatid; private System.Windows.Forms.Button btnjoin; + private System.Windows.Forms.ToolStripLabel lbtyping; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripButton btnsendfile; } } diff --git a/ShiftOS.WinForms/Applications/Chat.cs b/ShiftOS.WinForms/Applications/Chat.cs index 2abf5eb..5be7b0c 100644 --- a/ShiftOS.WinForms/Applications/Chat.cs +++ b/ShiftOS.WinForms/Applications/Chat.cs @@ -49,6 +49,41 @@ namespace ShiftOS.WinForms.Applications InitializeComponent(); } + public event Action FileSent; + + public string Typing + { + get + { + return lbtyping.Text; + } + set + { + this.Invoke(new Action(() => + { + if (string.IsNullOrWhiteSpace(value)) + { + lbtyping.Visible = false; + } + else + { + lbtyping.Text = value + " is typing..."; + lbtyping.Visible = true; + } + })); + } + } + + public void ShowChat() + { + this.Invoke(new Action(() => + { + pnlstart.Hide(); + rtbchat.Show(); + rtbchat.BringToFront(); + })); + } + public void OnLoad() { AllInstances.Add(this); @@ -86,7 +121,7 @@ namespace ShiftOS.WinForms.Applications private void txtuserinput_KeyDown(object sender, KeyEventArgs e) { - if(e.KeyCode == Keys.Enter) + if (e.KeyCode == Keys.Enter) { e.SuppressKeyPress = true; @@ -108,7 +143,7 @@ namespace ShiftOS.WinForms.Applications public static void SendMessage(string user, string destination, string msg) { - foreach(var chat in AllInstances) + foreach (var chat in AllInstances) { chat.PostMessage(user, destination, msg); } @@ -138,62 +173,14 @@ namespace ShiftOS.WinForms.Applications txtuserinput.Text = ""; } - [Story("story_thefennfamily")] - public static void Story_TheFennFamily() + private void btnsendfile_Click(object sender, EventArgs e) { - bool complete = false; - Infobox.Show("SimpleSRC", "A direct message has been sent to you on SimpleSRC from user \"maureenfenn@trisys\".", () => + FileSkimmerBackend.GetFile(new[] { "" }, FileOpenerStyle.Open, (file) => { - string ch = "maureenfenn@trisys"; - var c = new Chat(); - c.ChatID = ch; - AppearanceManager.SetupWindow(c); - string you = $"{SaveSystem.CurrentUser.Username}@{SaveSystem.CurrentSave.SystemName}"; - - var t = new Thread(() => - { - SendMessage(you, ch, "User has joined the chat."); - Thread.Sleep(2000); - SendMessage(ch, ch, "Hello, " + you + ". My name is Maureen. Maureen Fenn."); - Thread.Sleep(2500); - SendMessage(ch, ch, "I am the author of the various Tri applications you may see on Appscape."); - Thread.Sleep(2000); - SendMessage(ch, ch, "I need your help with something..."); - Thread.Sleep(2500); - SendMessage(ch, ch, "Firstly, a little backstory. There was a time in ShiftOS when none of us were connected."); - Thread.Sleep(2500); - SendMessage(ch, ch, "There wasn't a Digital Society, we didn't have chat applications or anything..."); - Thread.Sleep(2000); - SendMessage(ch, ch, "All we had was the Shiftnet."); - Thread.Sleep(2500); - SendMessage(ch, ch, "However, in 2016, something happened called the \"connected revolution\". It was like, the invention of the Internet - it was huge for the world of ShiftOS."); - Thread.Sleep(2500); - SendMessage(ch, ch, "Before this, the only way you could earn Codepoints was through playing games in ShiftOS."); - Thread.Sleep(2500); - SendMessage(ch, ch, "I was the one who coded those games, and I would put them on a Shiftnet website that you can still access today, shiftnet/main/shiftgames."); - Thread.Sleep(2500); - SendMessage(ch, ch, "But when the Connected Revolution took place, things got difficult. My son, Nalyr Fenn, was born, and people stopped using my software and instead moved on to hacking eachother and stealing peoples' Codepoints."); - Thread.Sleep(2500); - SendMessage(ch, ch, "When Nalyr's sentience levels reached near human - i.e, he grew up, we decided to start TriOffice. It was a huge success, thanks to Aiden Nirh, the guy who runs Appscape."); - Thread.Sleep(2500); - SendMessage(ch, ch, "However... a few months ago he cut contact with us and we stopped receiving Codepoints from TriOffice."); - Thread.Sleep(2500); - SendMessage(ch, ch, "I'm running low - I can't afford to keep my system running much longer. You have to help!"); - Thread.Sleep(2500); - SendMessage(ch, ch, "Perhaps, you could breach Aiden's server and look for clues as to why he's against us? I'll reward you with the last Codepoints I have."); - Thread.Sleep(2500); - SendMessage(you, ch, "Alright, I'm in - but I don't know where to begin..."); - Thread.Sleep(2500); - SendMessage(ch, ch, "A little birdie tells me you know about the RTS exploits going around... Try using that on Aiden's server. You can find his systemname on Appscape under \"Contact Us.\" He has a mailserver on Appscape - and also has RTS on the same server."); - Thread.Sleep(2500); - SendMessage(ch, ch, "Good luck... My life depends on you!"); - complete = true; - }); - t.IsBackground = true; - t.Start(); + var finf = ShiftOS.Objects.ShiftFS.Utils.GetFileInfo(file); + PostMessage($"{SaveSystem.CurrentUser.Username}@{SaveSystem.CurrentSave.SystemName}", ChatID, ""); + FileSent?.Invoke(finf); }); - while (!complete) - Thread.Sleep(10); } } } diff --git a/ShiftOS.WinForms/Applications/Chat.resx b/ShiftOS.WinForms/Applications/Chat.resx index e4a35ad..1787168 100644 --- a/ShiftOS.WinForms/Applications/Chat.resx +++ b/ShiftOS.WinForms/Applications/Chat.resx @@ -120,16 +120,25 @@ 17, 17 + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + 122, 17 - - 17, 17 - - - 122, 17 - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 diff --git a/ShiftOS.WinForms/MissionCommands.cs b/ShiftOS.WinForms/MissionCommands.cs index 375c490..d295392 100644 --- a/ShiftOS.WinForms/MissionCommands.cs +++ b/ShiftOS.WinForms/MissionCommands.cs @@ -20,9 +20,12 @@ namespace ShiftOS.WinForms var attrib = method.GetCustomAttributes(false).FirstOrDefault(x => x is MissionAttribute) as MissionAttribute; if (attrib != null) { - if (!Shiftorium.UpgradeInstalled(attrib.StoryID)) + if (Shiftorium.UpgradeAttributesUnlocked(method)) { - missions.Add(attrib); + if (!Shiftorium.UpgradeInstalled(attrib.StoryID)) + { + missions.Add(attrib); + } } } } @@ -62,6 +65,36 @@ namespace ShiftOS.WinForms Console.WriteLine("startmission --id " + missions.IndexOf(mission)); } } + + Console.WriteLine(); + + Console.WriteLine("Story progress:"); + ConsoleEx.Bold = true; + ConsoleEx.ForegroundColor = ConsoleColor.Cyan; + double percentage = GetMissionPercentage() * 100; + Console.WriteLine(percentage.ToString("#.##") + "%"); + } + + public static double GetMissionPercentage() + { + int missionsFound = 0; + int missionsComplete = 0; + foreach(var type in ReflectMan.Types) + { + foreach (var mth in type.GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static)) + { + var missionAttrib = mth.GetCustomAttributes(false).FirstOrDefault(x => x is MissionAttribute) as MissionAttribute; + if (missionAttrib != null) + { + missionsFound++; + if (Shiftorium.UpgradeInstalled(missionAttrib.StoryID)) + missionsComplete++; + } + + } + } + double percentage = (double)missionsComplete / (double)missionsFound; + return percentage; } [Command("startmission", description = "Starts the specified mission.")] diff --git a/ShiftOS.WinForms/Properties/Resources.Designer.cs b/ShiftOS.WinForms/Properties/Resources.Designer.cs index dd84e94..9d233ff 100644 --- a/ShiftOS.WinForms/Properties/Resources.Designer.cs +++ b/ShiftOS.WinForms/Properties/Resources.Designer.cs @@ -159,6 +159,35 @@ namespace ShiftOS.WinForms.Properties { } } + /// + /// Looks up a localized string similar to { + /// "Name": "appscape_main", + /// "Files": [], + /// "Subdirectories": [ + /// { + /// "Name": "bans", + /// "Files": [ + /// { + /// "Name": "hacker101.txt", + /// "Data": "RGF0ZTogMTAvMy8yMDE4DQpVc2VyOiBoYWNrZXIxMDENCg0KQmFuIHR5cGU6IEF1dG9tYXRlZA0KDQpEZXNjcmlwdGlvbjoNCg0KVGhpcyB1c2VyIGhhcyBiZWVuIGJhbm5lZCBieSB0aGUgYXV0b21hdGVkIGFudGktaGFja2luZyBzeXN0ZW0gZm9yIGNyZWF0aW9uIG9mIG1hbGljaW91cyBzb2Z0d2FyZSBhbmQgZXhwbG9pdGF0aW9uIHV0aWxpdGllcy4=", + /// "HeaderData": null, + /// "ReadAccessToLo [rest of string was truncated]";. + /// + internal static string AppscapeServerFS { + get { + return ResourceManager.GetString("AppscapeServerFS", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to RGF0ZTogMDQvMS8yMDE4DQpVc2VyOiBtYXVyZWVuX2Zlbm4NCg0KQmFuIHR5cGU6IENlYXNlIGFuZCBkZXNpc3QgKERldlgpDQoNCkRlc2NyaXB0aW9uOg0KDQpEZXZYIGhhcyBzZW50IGEgY2Vhc2UgYW5kIGRlc2lzdCByZXF1ZXN0IHRvIEFwcHNjYXBlIGZvciBob3N0aW5nIHRoaXMgdXNlcidzIGFwcGxpY2F0aW9ucyBhbmQgc2VuZGluZyBwcm9maXRzIG92ZXIuIFRoaXMgdXNlcidzIHNvZnR3YXJlIHdpbGwgbm90IGJlIHB1bGxlZCwgYnV0IGFsbCBDb2RlcG9pbnRzIGVhcm5lZCBmcm9tIGl0IHdpbGwgbm90IGJlIHJlZGlyZWN0ZWQgYW5kIHRoZSB1c2VyIHdpbGwgbm90IGJlIGFibGUgdG8gYWNjZXNzIHRoZWlyIGRldmVsb3BtZW50IHBhbmVsLg==. + /// + internal static string AppscapeWantedFile { + get { + return ResourceManager.GetString("AppscapeWantedFile", resourceCulture); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/ShiftOS.WinForms/Properties/Resources.resx b/ShiftOS.WinForms/Properties/Resources.resx index 07cf941..d1264e8 100644 --- a/ShiftOS.WinForms/Properties/Resources.resx +++ b/ShiftOS.WinForms/Properties/Resources.resx @@ -34618,6 +34618,13 @@ ..\Resources\strings_fr.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + ..\Resources\AppscapeServerFS.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + + RGF0ZTogMDQvMS8yMDE4DQpVc2VyOiBtYXVyZWVuX2Zlbm4NCg0KQmFuIHR5cGU6IENlYXNlIGFuZCBkZXNpc3QgKERldlgpDQoNCkRlc2NyaXB0aW9uOg0KDQpEZXZYIGhhcyBzZW50IGEgY2Vhc2UgYW5kIGRlc2lzdCByZXF1ZXN0IHRvIEFwcHNjYXBlIGZvciBob3N0aW5nIHRoaXMgdXNlcidzIGFwcGxpY2F0aW9ucyBhbmQgc2VuZGluZyBwcm9maXRzIG92ZXIuIFRoaXMgdXNlcidzIHNvZnR3YXJlIHdpbGwgbm90IGJlIHB1bGxlZCwgYnV0IGFsbCBDb2RlcG9pbnRzIGVhcm5lZCBmcm9tIGl0IHdpbGwgbm90IGJlIHJlZGlyZWN0ZWQgYW5kIHRoZSB1c2VyIHdpbGwgbm90IGJlIGFibGUgdG8gYWNjZXNzIHRoZWlyIGRldmVsb3BtZW50IHBhbmVsLg== + The file that Maureen Fenn wants to see in the Appscape Troubles storyline. + ..\Resources\brute.mp3;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 diff --git a/ShiftOS.WinForms/Resources/AppscapeServerFS.txt b/ShiftOS.WinForms/Resources/AppscapeServerFS.txt new file mode 100644 index 0000000..214581d --- /dev/null +++ b/ShiftOS.WinForms/Resources/AppscapeServerFS.txt @@ -0,0 +1,52 @@ +{ + "Name": "appscape_main", + "Files": [], + "Subdirectories": [ + { + "Name": "bans", + "Files": [ + { + "Name": "hacker101.txt", + "Data": "RGF0ZTogMTAvMy8yMDE4DQpVc2VyOiBoYWNrZXIxMDENCg0KQmFuIHR5cGU6IEF1dG9tYXRlZA0KDQpEZXNjcmlwdGlvbjoNCg0KVGhpcyB1c2VyIGhhcyBiZWVuIGJhbm5lZCBieSB0aGUgYXV0b21hdGVkIGFudGktaGFja2luZyBzeXN0ZW0gZm9yIGNyZWF0aW9uIG9mIG1hbGljaW91cyBzb2Z0d2FyZSBhbmQgZXhwbG9pdGF0aW9uIHV0aWxpdGllcy4=", + "HeaderData": null, + "ReadAccessToLowUsers": false, + "permissions": 0 + }, + { + "Name": "maureen_fenn.txt", + "Data": "RGF0ZTogMDQvMS8yMDE4DQpVc2VyOiBtYXVyZWVuX2Zlbm4NCg0KQmFuIHR5cGU6IENlYXNlIGFuZCBkZXNpc3QgKERldlgpDQoNCkRlc2NyaXB0aW9uOg0KDQpEZXZYIGhhcyBzZW50IGEgY2Vhc2UgYW5kIGRlc2lzdCByZXF1ZXN0IHRvIEFwcHNjYXBlIGZvciBob3N0aW5nIHRoaXMgdXNlcidzIGFwcGxpY2F0aW9ucyBhbmQgc2VuZGluZyBwcm9maXRzIG92ZXIuIFRoaXMgdXNlcidzIHNvZnR3YXJlIHdpbGwgbm90IGJlIHB1bGxlZCwgYnV0IGFsbCBDb2RlcG9pbnRzIGVhcm5lZCBmcm9tIGl0IHdpbGwgbm90IGJlIHJlZGlyZWN0ZWQgYW5kIHRoZSB1c2VyIHdpbGwgbm90IGJlIGFibGUgdG8gYWNjZXNzIHRoZWlyIGRldmVsb3BtZW50IHBhbmVsLg==", + "HeaderData": null, + "ReadAccessToLowUsers": false, + "permissions": 0 + } + ], + "Subdirectories": [], + "ReadAccessToLowUsers": false, + "permissions": 3 + }, + { + "Name": "feedback", + "Files": [ + { + "Name": "better_feedback_system.txt", + "Data": "VXNlcjogYW5vbnltb3VzDQpEYXRlOiAyNS8xMi8yMDE3DQpUaXRsZTogQmV0dGVyIGZlZWRiYWNrIHN5c3RlbS4NCg0KRGVzY3JpcHRpb246DQoNCldoeSBtdXN0IHdlIEZUUCBpbnRvIHlvdXIgc3lzdGVtIHRvIGxlYXZlIGZlZWRiYWNrIGZvciBBcHBzY2FwZT8gSSBrbm93IHRoYXQgeW91J3ZlIGdvdCB0aGlzIGFjY291bnQgdGlnaHRseSBsb2NrZWQgYW5kIGl0IGNhbiBvbmx5IGFjY2VzcyB0aGlzIHBhcnQgb2YgeW91ciBjb21wdXRlciwgYnV0IGl0J3MgdGhlIERpZ2l0YWwgU29jaWV0eS4gU29tZW9uZSdzIGdvbm5hIGJyZWFrIHRoaXMuIENhbid0IHdlIGF0IGxlYXN0IGhhdmUgYSBtb3JlIHNlY3VyZSBTTVRQLWJhc2VkIGZlZWRiYWNrIHN5c3RlbT8gT3IgZXZlbiBhIGZvcm0gb24gQXBwc2NhcGUncyB3ZWJzaXRlPw0KDQpSZXBseToNCg0KQ29tZSBvbiBtYW4hIEl0J3MgQ2hyaXN0bWFzLCB5b3UncmUgZ29ubmEgbWFrZSBtZSBjb2RlPyBJJ20gdHJ5aW5nIHRvIHNwZW5kIHRpbWUgd2l0aCB0aGUgZmFtaWx5IGhlcmUuLi4gd2FpdCBhIG1pbnV0ZS4uLiB1aGhoLi4uIG5ldmVybWluZC4gSSdtIGFjdHVhbGx5IHdvcmtpbmcgb24gdGhhdCBhcyB3ZSBzcGVhay4=", + "HeaderData": null, + "ReadAccessToLowUsers": false, + "permissions": 0 + }, + { + "Name": "screenshots.txt", + "Data": "VXNlcjogYW5vbnltb3VzDQpEYXRlOiAwNC8xMi8yMDE3DQpUaXRsZTogQnJpbmcgYmFjayBzY3JlZW5zaG90cy4NCg0KRGVzY3JpcHRpb246DQoNCkJhY2sgaW4gdGhlIG9sZGVuIGRheXMsIGJlZm9yZSB0aGUgRGlnaXRhbCBTb2NpZXR5LCBBcHBzY2FwZSBoYWQgZGVjZW50IHNjcmVlbnNob3RzIGZvciBpdHMgYXBwcy4gV2h5IGNhbid0IHdlIGhhdmUgdGhlbSBpbiBtb2Rlcm4gQXBwc2NhcGU/DQoNClJlcGx5Og0KDQpUaGUgU2hpZnRuZXQgaXMgaW4gaXRzIGVuZmFuY3kgYXQgdGhpcyB0aW1lLi4uIGV2ZXIgc2luY2UgRGV2WCBtYWRlIGl0IGFuIG9mZmljaWFsIHBhcnQgb2YgU2hpZnRPUyBhbmQgcmV3cm90ZSB0aGUgcGFnZSB0ZW1wbGF0aW5nIHN5c3RlbSwgSSBoYXZlbid0IGxlYXJuZWQgeWV0IGhvdyB0byBkZWFsIHdpdGggcGljdHVyZXMuIEknbGwgbG9vayBpbnRvIGl0IHRob3VnaC4gSSBzdXJlIGRvIG1pc3MgdGhlIG9sZGVyIFNoaWZ0bmV0Li4u", + "HeaderData": null, + "ReadAccessToLowUsers": false, + "permissions": 0 + } + ], + "Subdirectories": [], + "ReadAccessToLowUsers": false, + "permissions": 0 + } + ], + "ReadAccessToLowUsers": false, + "permissions": 3 +} \ No newline at end of file diff --git a/ShiftOS.WinForms/ShiftOS.WinForms.csproj b/ShiftOS.WinForms/ShiftOS.WinForms.csproj index 570d049..5fcf349 100644 --- a/ShiftOS.WinForms/ShiftOS.WinForms.csproj +++ b/ShiftOS.WinForms/ShiftOS.WinForms.csproj @@ -875,6 +875,7 @@ + diff --git a/ShiftOS.WinForms/Stories/LegionStory.cs b/ShiftOS.WinForms/Stories/LegionStory.cs index a91b0b1..1eff0e9 100644 --- a/ShiftOS.WinForms/Stories/LegionStory.cs +++ b/ShiftOS.WinForms/Stories/LegionStory.cs @@ -6,6 +6,7 @@ using System.Threading; using System.Threading.Tasks; using Newtonsoft.Json; using ShiftOS.Engine; +using ShiftOS.Objects; namespace ShiftOS.WinForms.Stories { @@ -80,6 +81,166 @@ namespace ShiftOS.WinForms.Stories Story.Context.MarkComplete(); Story.Start("aiden_shiftnet2"); } + + [RequiresUpgrade("appscape_troubles")] + [Mission("appscape_troubles_end", "Appscape Troubles: Lifting The Ban", "Maureen's been banned from Appscape. Let's see if we can get Aiden to reverse that.", 1200l, "maureen_fenn")] + public static void AppscapeTroublesEnd() + { + Applications.Chat chat = null; + Desktop.InvokeOnWorkerThread(() => + { + chat = OpenChat(); + }); + while (chat == null) + Thread.Sleep(10); + chat.ShowChat(); + chat.ChatID = "maureen_fenn@trisys"; + CurrentChat = chat; + SendChatMessage("maureen_fenn", "I just talked to hacker101 about our little issue here..."); + SendChatMessage("maureen_fenn", "He tried to get Aiden to lighten up, but he's too hell-bent on making DevX happy."); + SendChatMessage("maureen_fenn", "But, I think we've gotten a plan."); + SendChatMessage("hacker101", ""); + chat.ChatID = "maureen_fenn@trisys, hacker101@pebcak"; + SendChatMessage("hacker101", "We meet again, " + SaveSystem.CurrentUser.Username + "..."); + SendChatMessage("hacker101", "Maureen tells me you've used your hacking skills to steal a document from Aiden Nirh."); + SendChatMessage("hacker101", "I hope he didn't find out about brute..."); + SendChatMessage("maureen_fenn", "Ugh... brute? That thing? That's not hacking."); + SendChatMessage("maureen_fenn", "You're just turning " + SaveSystem.CurrentUser.Username + " into a script-kiddie."); + SendChatMessage("maureen_fenn", SaveSystem.CurrentUser.Username + ", you want REAL hacking? Why don't you come to me after we're done here. I'll show you how REAL sentiences get their way."); + SendChatMessage("hacker101", "HEY. You gotta give Brute some credit. It's good at cracking passwords."); + SendChatMessage("maureen_fenn", "Well, what happens if the user runs into a firewall block? Brute ain't going to help with that."); + SendChatMessage("hacker101", "....whatever. Let's just get on with this."); + SendChatMessage("hacker101", "We need to get rid of that cease and desist ban."); + SendChatMessage("hacker101", "Firstly, let's review the document."); + SendChatMessage("hacker101", ""); + var bytes = Convert.FromBase64String(Properties.Resources.AppscapeWantedFile); + chat.PostMessage("maureen_fenn.txt", chat.ChatID, Encoding.UTF8.GetString(bytes)); + SendChatMessage("hacker101", "I ain't no lawyer but I can tell you right now that C&D is bull."); + SendChatMessage("hacker101", "Guess this is just DevX's way of saying he can't stand you, Maureen."); + SendChatMessage("hacker101", "I want you to know that unlike him, I can. I... I..."); + SendChatMessage("maureen_fenn", "..Nope, nope. Let's not go there. You're getting a bit creepy, hacker."); + SendChatMessage("hacker101", "Whoops. Oh well... We need to show DevX who's boss."); + SendChatMessage("hacker101", "Maybe, " + SaveSystem.CurrentUser.Username + " can help us."); + SendChatMessage("maureen_fenn", "Maybe they can... and meybe Aiden can as well."); + SendChatMessage("hacker101", "No, he's convinced that we're the bad guys."); + SendChatMessage("hacker101", "He's got me banned because of brute."); + SendChatMessage("maureen_fenn", "Lol, banned... for BRUTE? That little harmless tool? Bahahahaha."); + SendChatMessage(SaveSystem.CurrentUser.Username, "Will you two stop bickering at eachother about Brute and hacker101's love for Maureen and let us get on with this? I could be playing Pong right now."); + SendChatMessage("maureen_fenn", "Right. We need to gather as much evidence against DevX as possible."); + SendChatMessage("hacker101", "Then, we need to send it all to Aiden, right? We'll need " + SaveSystem.CurrentUser.Username + " to do that."); + SendChatMessage("maureen_fenn", "Alrighty, " + SaveSystem.CurrentUser.Username + ". You're on our team. We'll have any tasks we need you to do in your missions list."); + SendChatMessage("maureen_fenn", "Oh yeah, and here's a couple Codepoints as compensation for helping us out."); + Story.Context.MarkComplete(); + Thread.Sleep(5000); + Desktop.InvokeOnWorkerThread(() => + { + AppearanceManager.Close(chat); + }); + } + + [RequiresUpgrade("hacker101_breakingbonds_3")] + [Mission("appscape_troubles", "Appscape Troubles", "You know how to do some basic hacking, now you've got a chance to exercise it.", 750l, "maureen_fenn")] + public static void AppscapeTroubles() + { + Applications.Chat chat = null; + Desktop.InvokeOnWorkerThread(() => + { + chat = OpenChat(); + }); + while (chat == null) + Thread.Sleep(10); + chat.ShowChat(); + chat.ChatID = "maureen_fenn@trisys"; + CurrentChat = chat; + SendChatMessage("maureen_fenn", "Hello there, " + SaveSystem.CurrentUser.Username + ". My name is Maureen."); + SendChatMessage("maureen_fenn", "I'm the developer of the various Tri apps you may've seen around the Shiftnet."); + Story.Context.AutoComplete = false; + SendChatMessage("maureen_fenn", "I have a bit of a problem that may need your assistance.."); + SendChatMessage("maureen_fenn", "I struck a deal with Aiden Nirh to put my software on his site and split the profits in half with me and him."); + SendChatMessage("maureen_fenn", "But lately, even though many people have been buying my software, I've been getting nothing for it."); + SendChatMessage("maureen_fenn", "Now I have barely enough Codepoints to keep my development environment online..."); + SendChatMessage("maureen_fenn", "My friend, you know him as hacker101, he's told me that you know how to hack."); + SendChatMessage("maureen_fenn", "Can you bust into Aiden's server and see if he's gotten any documents or anything indicating why he's not paying me?"); + SendChatMessage("maureen_fenn", "He likes to document a lot of things about what he does and he likes to store those docs on his central Appscape server. Maybe there's something on there about me..."); + SendChatMessage("maureen_fenn", "You can find connection details for his server on Appscape's Contact page."); + SendChatMessage("maureen_fenn", "The guy has pretty good security though... so be careful."); + SendChatMessage("maureen_fenn", "When you find the right file, I'd download it to your system and just send it through SimpleSRC."); + + + VirtualEnvironments.Create("appscape_main", new List + { + new ClientSave + { + Username = "aiden", + Password = GenRandomPassword(), + Permissions = UserPermissions.Root, + }, + new ClientSave + { + Username = "feedback", + Password = "", + Permissions = UserPermissions.Guest + } + }, 15000l, JsonConvert.DeserializeObject(Properties.Resources.AppscapeServerFS)); + + bool validFileSent = false; + chat.FileSent += (file) => + { + if (Convert.ToBase64String(file.Data) == Properties.Resources.AppscapeWantedFile) + validFileSent = true; + }; + + Story.Context.AutoComplete = false; + + Story.PushObjective("Appscape Troubles: The Secret", "Maureen has asked you to find out why Aiden Nirh, the maintainer of Appscape, isn't paying her half the profits for her TriOffice suite. Time to use your hacking skills... just like before.", + () => { return validFileSent; }, + () => + { + SendChatMessage("maureen_fenn", "File received."); + SendChatMessage("maureen_fenn", "Awwww, come on, man! You can't tell me I got banned due to a cease and desist from DevX... That bastard... DevX, I mean."); + SendChatMessage("maureen_fenn", "Anyways, I'll talk to Aiden about that... if I can... or maybe you can? Either way, here's your Codepoints."); + Story.Context.MarkComplete(); + Thread.Sleep(5000); + Desktop.InvokeOnWorkerThread(() => + { + AppearanceManager.Close(chat); + }); + + }); + + + } + + private static Applications.Chat CurrentChat; + + public static void SendChatMessage(string who, string msg) + { + CurrentChat.Typing = who; + foreach(var c in msg) + { + Thread.Sleep(75); + } + CurrentChat?.PostMessage(who, CurrentChat?.ChatID, msg); + CurrentChat.Typing = ""; + Thread.Sleep(500); + } + + public static Applications.Chat OpenChat() + { + var chatbrd = AppearanceManager.OpenForms.FirstOrDefault(x => x.ParentWindow is Applications.Chat); + Applications.Chat chat = null; + if(chatbrd == null) + { + chat = new Applications.Chat(); + AppearanceManager.SetupWindow(chat); + } + else + { + chat = chatbrd.ParentWindow as Applications.Chat; + } + return chat; + } + [Mission("hacker101_breakingbonds_3", "Breaking the Bonds", "It's time you've learned how to hack.", 500l, "hacker101")] public static void BreakingTheBonds_Outro() diff --git a/ShiftOS_TheReturn/Story.cs b/ShiftOS_TheReturn/Story.cs index 02fe6e3..bf727d8 100644 --- a/ShiftOS_TheReturn/Story.cs +++ b/ShiftOS_TheReturn/Story.cs @@ -167,6 +167,8 @@ namespace ShiftOS.Engine ConsoleEx.ForegroundColor = ConsoleColor.White; Console.WriteLine($"{mission.Name} successfully finished. You have earned {mission.CodepointAward} Codepoints for your efforts."); SaveSystem.CurrentSave.Codepoints += mission.CodepointAward; + TerminalBackend.PrintPrompt(); + TerminalBackend.PrefixEnabled = true; } StoryComplete?.Invoke(stid); SaveSystem.CurrentSave.PickupPoint = null; -- cgit v1.2.3