예제 #1
0
        public static SerializableAction DeserializeFromReader(XmlReader rdr)
        {
            SAAddIRCMessage saAddIrcMessage = new SAAddIRCMessage();

            if (rdr.MoveToAttribute("Author"))
            {
                saAddIrcMessage.Author = ComputerLoader.filter(rdr.ReadContentAsString());
            }
            if (rdr.MoveToAttribute("Delay"))
            {
                saAddIrcMessage.Delay = rdr.ReadContentAsFloat();
            }
            if (rdr.MoveToAttribute("TargetComp"))
            {
                saAddIrcMessage.TargetComp = rdr.ReadContentAsString();
            }
            int content = (int)rdr.MoveToContent();

            saAddIrcMessage.Message = ComputerLoader.filter(rdr.ReadElementContentAsString());
            if (string.IsNullOrWhiteSpace(saAddIrcMessage.TargetComp))
            {
                throw new FormatException("Invalid Target Comp");
            }
            if (string.IsNullOrWhiteSpace(saAddIrcMessage.Message))
            {
                throw new FormatException("Invalid or Empty Message!");
            }
            return((SerializableAction)saAddIrcMessage);
        }
예제 #2
0
        public static SerializableAction DeserializeFromReader(XmlReader rdr)
        {
            SAStartScreenBleedEffect screenBleedEffect = new SAStartScreenBleedEffect();

            if (rdr.MoveToAttribute("Delay"))
            {
                screenBleedEffect.Delay = rdr.ReadContentAsFloat();
            }
            if (rdr.MoveToAttribute("DelayHost"))
            {
                screenBleedEffect.DelayHost = rdr.ReadContentAsString();
            }
            if (rdr.MoveToAttribute("AlertTitle"))
            {
                screenBleedEffect.AlertTitle = ComputerLoader.filter(rdr.ReadContentAsString());
            }
            if (rdr.MoveToAttribute("CompleteAction"))
            {
                screenBleedEffect.CompleteAction = rdr.ReadContentAsString();
            }
            if (rdr.MoveToAttribute("TotalDurationSeconds"))
            {
                screenBleedEffect.TotalDurationSeconds = (float)rdr.ReadContentAsDouble();
            }
            int content = (int)rdr.MoveToContent();

            screenBleedEffect.ContentLines = ComputerLoader.filter(rdr.ReadElementContentAsString());
            return((SerializableAction)screenBleedEffect);
        }
예제 #3
0
        public static SerializableAction DeserializeFromReader(XmlReader rdr)
        {
            SAAppendToFile saAppendToFile = new SAAppendToFile();

            if (rdr.MoveToAttribute("Delay"))
            {
                saAppendToFile.Delay = rdr.ReadContentAsFloat();
            }
            if (rdr.MoveToAttribute("DelayHost"))
            {
                saAppendToFile.DelayHost = rdr.ReadContentAsString();
            }
            if (rdr.MoveToAttribute("TargetComp"))
            {
                saAppendToFile.TargetComp = rdr.ReadContentAsString();
            }
            if (rdr.MoveToAttribute("TargetFolderpath"))
            {
                saAppendToFile.TargetFolderpath = rdr.ReadContentAsString();
            }
            if (rdr.MoveToAttribute("TargetFilename"))
            {
                saAppendToFile.TargetFilename = rdr.ReadContentAsString();
            }
            int content = (int)rdr.MoveToContent();

            saAppendToFile.DataToAdd = ComputerLoader.filter(rdr.ReadElementContentAsString());
            return((SerializableAction)saAppendToFile);
        }
예제 #4
0
 public static void AddEmailToServer(this Hacknet.MailServer server,
                                     string sender   = null,
                                     string recip    = null,
                                     string subject  = null,
                                     string body     = null,
                                     bool dontFilter = false)
 {
     sender  = dontFilter ? sender ?? "UNKNOWN" : ComputerLoader.filter(sender ?? "UNKNOWN");
     recip   = dontFilter || recip == null ? recip : ComputerLoader.filter(recip);
     subject = dontFilter ? subject ?? "UNKNOWN" : ComputerLoader.filter(subject ?? "UNKNOWN");
     body    = dontFilter ? body ?? "UNKNOWN" : ComputerLoader.filter(body ?? "UNKNOWN");
     if (recip != null)
     {
         server.AddMailToServer(recip, Hacknet.MailServer.generateEmail(subject, body, sender));
     }
 }
예제 #5
0
        public override void Trigger(object os_obj)
        {
            OS       os       = (OS)os_obj;
            Computer computer = Programs.getComputer(os, this.TargetComp);

            if (computer == null)
            {
                throw new NullReferenceException("Computer " + this.TargetComp + " could not be found for AddAssetFunction, adding file: " + this.FileName);
            }
            Folder folderAtPath = Programs.getFolderAtPath(this.TargetFolderpath, os, computer.files.root, true);

            if (folderAtPath == null)
            {
                throw new NullReferenceException("Folder " + this.TargetFolderpath + " could not be found for AddAssetFunction, adding file: " + this.FileName);
            }
            FileEntry fileEntry = new FileEntry(ComputerLoader.filter(this.FileContents), this.FileName);

            folderAtPath.files.Add(fileEntry);
        }
예제 #6
0
 public void AddThread(string threadData)
 {
     if (this.threadsFolder == null)
     {
         this.ThreadsToAdd.Add(threadData);
     }
     else
     {
         threadData = ComputerLoader.filter(threadData);
         string str;
         do
         {
             str = Utils.getRandomByte().ToString("000") + Utils.getRandomByte().ToString("000") + Utils.getRandomByte().ToString("000") + ".tm";
         }while (this.threadsFolder.searchForFile(str) != null);
         if (this.MessageAdded != null)
         {
             this.MessageAdded("anon", threadData);
         }
         this.threadsFolder.files.Add(new FileEntry(threadData, str));
     }
 }
예제 #7
0
 public static string Filter(this string s) => s == null ? null : ComputerLoader.filter(s);
예제 #8
0
        public static void AddEOSComp(XmlReader rdr, Computer compAttatchedTo, object osObj)
        {
            OS     os       = (OS)osObj;
            string compName = "Unregistered eOS Device";
            string str1     = compAttatchedTo.idName + "_eos";
            bool   flag     = false;

            if (rdr.MoveToAttribute("name"))
            {
                compName = ComputerLoader.filter(rdr.ReadContentAsString());
            }
            if (rdr.MoveToAttribute("id"))
            {
                str1 = rdr.ReadContentAsString();
            }
            if (rdr.MoveToAttribute("empty"))
            {
                flag = rdr.ReadContentAsString().ToLower() == "true";
            }
            string newPass = "******";

            if (rdr.MoveToAttribute("passOverride"))
            {
                newPass = rdr.ReadContentAsString();
            }
            Computer device = new Computer(compName, NetworkMap.generateRandomIP(), os.netMap.getRandomPosition(), 0, (byte)5, os);

            device.idName = str1;
            string str2 = "ePhone";

            if (rdr.MoveToAttribute("icon"))
            {
                str2 = rdr.ReadContentAsString();
            }
            device.icon     = str2;
            device.location = compAttatchedTo.location + Corporation.getNearbyNodeOffset(compAttatchedTo.location, Utils.random.Next(12), 12, os.netMap, 0.0f, false);
            device.setAdminPassword(newPass);
            ComputerLoader.loadPortsIntoComputer("22,3659", (object)device);
            device.portsNeededForCrack = 2;
            EOSComp.GenerateEOSFilesystem(device);
            rdr.Read();
            Folder folder1 = device.files.root.searchForFolder("eos");
            Folder folder2 = folder1.searchForFolder("notes");
            Folder folder3 = folder1.searchForFolder("mail");

            while (!(rdr.Name == "eosDevice") || rdr.IsStartElement())
            {
                if (rdr.Name.ToLower() == "note" && rdr.IsStartElement())
                {
                    string nameEntry = (string)null;
                    if (rdr.MoveToAttribute("filename"))
                    {
                        nameEntry = ComputerLoader.filter(rdr.ReadContentAsString());
                    }
                    int    content   = (int)rdr.MoveToContent();
                    string dataEntry = ComputerLoader.filter(rdr.ReadElementContentAsString().TrimStart());
                    if (nameEntry == null)
                    {
                        int length = dataEntry.IndexOf("\n");
                        if (length == -1)
                        {
                            length = dataEntry.IndexOf("\n");
                        }
                        if (length == -1)
                        {
                            length = dataEntry.Length;
                        }
                        string str3 = dataEntry.Substring(0, length);
                        if (str3.Length > 50)
                        {
                            str3 = str3.Substring(0, 47) + "...";
                        }
                        nameEntry = str3.Replace(" ", "_").Replace(":", "").ToLower().Trim() + ".txt";
                    }
                    FileEntry fileEntry = new FileEntry(dataEntry, nameEntry);
                    folder2.files.Add(fileEntry);
                }
                if (rdr.Name.ToLower() == "mail" && rdr.IsStartElement())
                {
                    string str3 = (string)null;
                    string str4 = (string)null;
                    if (rdr.MoveToAttribute("username"))
                    {
                        str3 = ComputerLoader.filter(rdr.ReadContentAsString());
                    }
                    if (rdr.MoveToAttribute("pass"))
                    {
                        str4 = ComputerLoader.filter(rdr.ReadContentAsString());
                    }
                    string dataEntry = "MAIL ACCOUNT : " + str3 + "\nAccount   :" + str3 + "\nPassword :"******"\nLast Sync :" + DateTime.Now.ToString() + "\n\n" + Computer.generateBinaryString(512);
                    string nameEntry = str3 + ".act";
                    folder3.files.Add(new FileEntry(dataEntry, nameEntry));
                }
                if (rdr.Name.ToLower() == "file" && rdr.IsStartElement())
                {
                    string nameEntry = (string)null;
                    if (rdr.MoveToAttribute("name"))
                    {
                        nameEntry = rdr.ReadContentAsString();
                    }
                    string path = "home";
                    if (rdr.MoveToAttribute("path"))
                    {
                        path = rdr.ReadContentAsString();
                    }
                    int    content   = (int)rdr.MoveToContent();
                    string dataEntry = ComputerLoader.filter(rdr.ReadElementContentAsString()).TrimStart();
                    device.getFolderFromPath(path, true).files.Add(new FileEntry(dataEntry, nameEntry));
                }
                rdr.Read();
                if (rdr.EOF)
                {
                    break;
                }
            }
            if (flag)
            {
                Folder folder4 = folder1.searchForFolder("apps");
                if (folder4 != null)
                {
                    folder4.files.Clear();
                    folder4.folders.Clear();
                }
            }
            os.netMap.nodes.Add(device);
            ComputerLoader.postAllLoadedActions += (Action)(() => device.links.Add(os.netMap.nodes.IndexOf(compAttatchedTo)));
            if (compAttatchedTo.attatchedDeviceIDs != null)
            {
                compAttatchedTo.attatchedDeviceIDs += ",";
            }
            compAttatchedTo.attatchedDeviceIDs += device.idName;
        }
예제 #9
0
        private static void executeThreadedScript(string[] script, OS os)
        {
            KeyValuePair <string, string>?nullable = new KeyValuePair <string, string>?();
            bool     flag1   = false;
            Computer target  = os.thisComputer;
            Computer source  = (Computer)null;
            TimeSpan timeout = TimeSpan.FromSeconds(0.5);

            for (int index1 = 0; index1 < script.Length; ++index1)
            {
                if (source != null && source.disabled)
                {
                    Multiplayer.parseInputMessage(HackerScriptExecuter.getBasicNetworkCommand("cDisconnect", target, source), os);
                    Console.WriteLine("Early Script Exit on Source Disable");
                    return;
                }
                if (!string.IsNullOrWhiteSpace(script[index1]))
                {
                    string[]    strArray    = script[index1].Trim().Split(Utils.spaceDelim, StringSplitOptions.RemoveEmptyEntries);
                    CultureInfo cultureInfo = new CultureInfo("en-au");
                    bool        flag2       = target == os.thisComputer;
                    try
                    {
                        switch (strArray[0])
                        {
                        case "config":
                            target = Programs.getComputer(os, strArray[1]);
                            if (target == null)
                            {
                                if (!OS.DEBUG_COMMANDS)
                                {
                                    return;
                                }
                                os.write(" ");
                                os.write("Error: ");
                                os.write("Hack Script target " + strArray[1] + " not found! Aborting.");
                                os.write("This error will not show up if debug commands are disabled.");
                                os.write(" ");
                                return;
                            }
                            source = Programs.getComputer(os, strArray[2]);
                            if (source == null)
                            {
                                if (!OS.DEBUG_COMMANDS)
                                {
                                    return;
                                }
                                os.write(" ");
                                os.write("Error: ");
                                os.write("Hack Script source " + strArray[2] + " not found! Aborting.");
                                os.write("This error will not show up if debug commands are disabled.");
                                os.write(" ");
                                return;
                            }
                            timeout  = TimeSpan.FromSeconds(Convert.ToDouble(strArray[3], (IFormatProvider)cultureInfo));
                            flag2    = false;
                            nullable = new KeyValuePair <string, string>?(new KeyValuePair <string, string>(source.ip, target.ip));
                            os.ActiveHackers.Add(nullable.Value);
                            break;

                        case "delay":
                            if (!OS.TestingPassOnly)
                            {
                                Thread.Sleep(TimeSpan.FromSeconds(Convert.ToDouble(strArray[1], (IFormatProvider)cultureInfo)));
                            }
                            flag2 = false;
                            break;

                        case "connect":
                            Multiplayer.parseInputMessage(HackerScriptExecuter.getBasicNetworkCommand("cConnection", target, source), os);
                            if (!flag1 && target.ip == os.thisComputer.ip)
                            {
                                os.IncConnectionOverlay.Activate();
                                flag1 = true;
                                break;
                            }
                            break;

                        case "openPort":
                            Multiplayer.parseInputMessage(HackerScriptExecuter.getBasicNetworkCommand("cPortOpen", target, source) + " " + strArray[1], os);
                            break;

                        case "delete":
                            string pathString = HackerScriptExecuter.getPathString(strArray[1], os, target.files.root);
                            Multiplayer.parseInputMessage("cDelete #" + target.ip + "#" + source.ip + "#" + strArray[2] + pathString, os);
                            break;

                        case "reboot":
                            if (target == os.thisComputer)
                            {
                                if (os.connectedComp == null || os.connectedComp == os.thisComputer)
                                {
                                    os.runCommand("reboot");
                                    break;
                                }
                                os.rebootThisComputer();
                                break;
                            }
                            target.reboot(source.ip);
                            break;

                        case "forkbomb":
                            Multiplayer.parseInputMessage(HackerScriptExecuter.getBasicNetworkCommand("eForkBomb", target, source), os);
                            break;

                        case "disconnect":
                            target.disconnecting(source.ip, true);
                            break;

                        case "systakeover":
                            HostileHackerBreakinSequence.Execute((object)os, source, target);
                            break;

                        case "clearTerminal":
                            if (target == os.thisComputer)
                            {
                                os.terminal.reset();
                                break;
                            }
                            break;

                        case "write":
                            string str1 = "";
                            for (int index2 = 1; index2 < strArray.Length; ++index2)
                            {
                                str1 = str1 + strArray[index2] + " ";
                            }
                            string str2 = ComputerLoader.filter(str1.Trim());
                            if (target == os.thisComputer)
                            {
                                os.terminal.write(" " + str2);
                                os.warningFlash();
                                break;
                            }
                            break;

                        case "write_silent":
                            string str3 = "";
                            for (int index2 = 1; index2 < strArray.Length; ++index2)
                            {
                                str3 = str3 + strArray[index2] + " ";
                            }
                            string str4 = ComputerLoader.filter(str3.Trim());
                            if (target == os.thisComputer)
                            {
                                os.terminal.write(" " + str4);
                            }
                            flag2 = false;
                            break;

                        case "writel":
                            string str5 = "";
                            for (int index2 = 1; index2 < strArray.Length; ++index2)
                            {
                                str5 = str5 + strArray[index2] + " ";
                            }
                            string text1 = ComputerLoader.filter(str5.Trim());
                            if (string.IsNullOrWhiteSpace(text1))
                            {
                                flag2 = false;
                            }
                            if (target == os.thisComputer)
                            {
                                os.terminal.writeLine(text1);
                                os.warningFlash();
                                break;
                            }
                            break;

                        case "writel_silent":
                            string str6 = "";
                            for (int index2 = 1; index2 < strArray.Length; ++index2)
                            {
                                str6 = str6 + strArray[index2] + " ";
                            }
                            string text2 = ComputerLoader.filter(str6.Trim());
                            if (string.IsNullOrWhiteSpace(text2))
                            {
                                flag2 = false;
                            }
                            if (target == os.thisComputer)
                            {
                                os.terminal.writeLine(text2);
                            }
                            flag2 = false;
                            break;

                        case "hideNetMap":
                            if (target == os.thisComputer)
                            {
                                os.netMap.visible = false;
                                break;
                            }
                            break;

                        case "hideRam":
                            if (target == os.thisComputer)
                            {
                                os.ram.visible = false;
                                break;
                            }
                            break;

                        case "hideDisplay":
                            if (target == os.thisComputer)
                            {
                                os.display.visible = false;
                                break;
                            }
                            break;

                        case "hideTerminal":
                            if (target == os.thisComputer)
                            {
                                os.terminal.visible = false;
                                break;
                            }
                            break;

                        case "showNetMap":
                            if (target == os.thisComputer)
                            {
                                os.netMap.visible = true;
                                break;
                            }
                            break;

                        case "showRam":
                            if (target == os.thisComputer)
                            {
                                os.ram.visible = true;
                                break;
                            }
                            break;

                        case "showTerminal":
                            if (target == os.thisComputer)
                            {
                                os.terminal.visible = true;
                                break;
                            }
                            break;

                        case "showDisplay":
                            if (target == os.thisComputer)
                            {
                                os.display.visible = true;
                                break;
                            }
                            break;

                        case "stopMusic":
                            flag2 = false;
                            if (target == os.thisComputer)
                            {
                                if (HackerScriptExecuter.MusicStopSFX == null)
                                {
                                    HackerScriptExecuter.MusicStopSFX = !DLC1SessionUpgrader.HasDLC1Installed ? os.content.Load <SoundEffect>("SFX/MeltImpact") : os.content.Load <SoundEffect>("DLC/SFX/GlassBreak");
                                }
                                MusicManager.stop();
                                if (HackerScriptExecuter.MusicStopSFX != null)
                                {
                                    HackerScriptExecuter.MusicStopSFX.Play();
                                }
                                break;
                            }
                            break;

                        case "startMusic":
                            flag2 = false;
                            if (!OS.TestingPassOnly)
                            {
                                if (target == os.thisComputer)
                                {
                                    MusicManager.playSong();
                                }
                                break;
                            }
                            break;

                        case "trackseq":
                            try
                            {
                                if (target == os.thisComputer)
                                {
                                    TrackerCompleteSequence.FlagNextForkbombCompletionToTrace(source != null ? source.ip : (string)null);
                                    break;
                                }
                                break;
                            }
                            catch (Exception ex)
                            {
                                os.write(Utils.GenerateReportFromExceptionCompact(ex));
                                break;
                            }

                        case "instanttrace":
                            if (target == os.thisComputer)
                            {
                                TrackerCompleteSequence.TriggerETAS((object)os);
                                break;
                            }
                            break;

                        case "flash":
                            if (!OS.TestingPassOnly)
                            {
                                if (target == os.thisComputer)
                                {
                                    os.warningFlash();
                                }
                                break;
                            }
                            break;

                        case "openCDTray":
                            if (!OS.TestingPassOnly)
                            {
                                if (target == os.thisComputer)
                                {
                                    target.openCDTray(source.ip);
                                }
                                break;
                            }
                            break;

                        case "closeCDTray":
                            if (!OS.TestingPassOnly)
                            {
                                if (target == os.thisComputer)
                                {
                                    target.closeCDTray(source.ip);
                                }
                                break;
                            }
                            break;

                        case "setAdminPass":
                            target.setAdminPassword(strArray[1]);
                            break;

                        case "makeFile":
                            string        folderName    = strArray[1];
                            StringBuilder stringBuilder = new StringBuilder();
                            for (int index2 = 3; index2 < strArray.Length; ++index2)
                            {
                                stringBuilder.Append(strArray[index2]);
                                if (index2 + 1 < strArray.Length)
                                {
                                    stringBuilder.Append(" ");
                                }
                            }
                            Folder     folder     = target.files.root.searchForFolder(folderName);
                            List <int> folderPath = new List <int>();
                            if (folder == null)
                            {
                                folderPath.Add(0);
                            }
                            else
                            {
                                folderPath.Add(target.files.root.folders.IndexOf(folder));
                            }
                            target.makeFile(source.ip, strArray[2], ComputerLoader.filter(stringBuilder.ToString()), folderPath, true);
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        if (OS.TestingPassOnly)
                        {
                            throw new FormatException("Error Parsing command " + strArray[0] + " in HackerScript:", ex);
                        }
                        if (OS.DEBUG_COMMANDS)
                        {
                            os.terminal.write(Utils.GenerateReportFromException(ex));
                            os.write("HackScript error: " + strArray[0]);
                            os.write("Report written to Warnings file");
                            Utils.AppendToWarningsFile(Utils.GenerateReportFromException(ex));
                        }
                    }
                    try
                    {
                        if (flag2 && !os.thisComputer.disabled)
                        {
                            if (!OS.TestingPassOnly)
                            {
                                os.beepSound.Play();
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        os.terminal.write(Utils.GenerateReportFromException(ex));
                        Utils.AppendToErrorFile(Utils.GenerateReportFromException(ex));
                        return;
                    }
                    if (!OS.TestingPassOnly)
                    {
                        Thread.Sleep(timeout);
                    }
                }
            }
            if (!nullable.HasValue)
            {
                return;
            }
            os.ActiveHackers.Remove(nullable.Value);
        }
예제 #10
0
        public static MemoryContents Deserialize(XmlReader rdr)
        {
            MemoryContents ret = new MemoryContents();

            while (rdr.Name != "Memory")
            {
                rdr.Read();
                if (rdr.EOF)
                {
                    throw new FormatException("Unexpected end of file looking for start of Memory tag");
                }
            }
            do
            {
                rdr.Read();
                if (rdr.Name == "Memory" && !rdr.IsStartElement())
                {
                    return(ret);
                }
                Utils.ProcessXmlElementInParent(rdr, "Commands", "Command", (Action)(() =>
                {
                    int content = (int)rdr.MoveToContent();
                    string s = rdr.ReadElementContentAsString();
                    if (s.Contains("\n"))
                    {
                        string[] strArray = s.Split(Utils.robustNewlineDelim, StringSplitOptions.None);
                        for (int index = 0; index < strArray.Length; ++index)
                        {
                            if (string.IsNullOrEmpty(strArray[index]))
                            {
                                strArray[index] = " ";
                            }
                            ret.CommandsRun.Add(ComputerLoader.filter(Folder.deFilter(strArray[index])));
                        }
                    }
                    else
                    {
                        ret.CommandsRun.Add(ComputerLoader.filter(Folder.deFilter(s)));
                    }
                }));
                Utils.ProcessXmlElementInParent(rdr, "Data", "Block", (Action)(() =>
                {
                    int content = (int)rdr.MoveToContent();
                    ret.DataBlocks.Add(ComputerLoader.filter(Folder.deFilter(rdr.ReadElementContentAsString())));
                }));
                Utils.ProcessXmlElementInParent(rdr, "FileFragments", "File", (Action)(() =>
                {
                    string s1 = "UNKNOWN";
                    if (rdr.MoveToAttribute("name"))
                    {
                        s1 = rdr.ReadContentAsString();
                    }
                    int content = (int)rdr.MoveToContent();
                    string s2 = rdr.ReadElementContentAsString();
                    ret.FileFragments.Add(new KeyValuePair <string, string>(Folder.deFilter(s1), Folder.deFilter(s2)));
                }));
                Utils.ProcessXmlElementInParent(rdr, "Images", "Image", (Action)(() =>
                {
                    int content = (int)rdr.MoveToContent();
                    ret.Images.Add(Folder.deFilter(rdr.ReadElementContentAsString()));
                }));
            }while (!rdr.EOF);
            throw new FormatException("Unexpected end of file trying to deserialize memory contents!");
        }
예제 #11
0
        public static SerializableAction ReadAction(ElementInfo actionInfo)
        {
            if (ActionManager.TryLoadCustomAction(actionInfo, out var customAction))
            {
                return(customAction);
            }

            switch (actionInfo.Name)
            {
            case "LoadMission":
                return(ActionDelayDecorator.Create(actionInfo, new SALoadMission()
                {
                    MissionName = actionInfo.Attributes.GetOrThrow("MissionName", "Invalid mission for LoadMission action", StringExtensions.ContentFileExists)
                }));

            case "RunFunction":
                return(new SARunFunction()
                {
                    FunctionName = actionInfo.Attributes.GetOrThrow("FunctionName", "No function given for RunFunction action"),
                    FunctionValue = actionInfo.Attributes.GetInt("FunctionValue"),
                    Delay = actionInfo.Attributes.GetFloat("Delay"),
                    DelayHost = actionInfo.Attributes.GetString("DelayHost", null)
                });

            case "AddAsset":
                return(ActionDelayDecorator.Create(actionInfo, new SAAddAsset()
                {
                    TargetComp = actionInfo.Attributes.GetString("TargetComp", null),
                    TargetFolderpath = actionInfo.Attributes.GetString("TargetFolderpath", null),
                    FileName = actionInfo.Attributes.GetString("FileName", null),
                    FileContents = actionInfo.Attributes.GetString("FileContents", null)
                }));

            case "AddMissionToHubServer":
                var tag = actionInfo.Attributes.GetString("AssignmentTag");
                if (string.IsNullOrWhiteSpace(tag))
                {
                    tag = null;
                }
                return(ActionDelayDecorator.Create(actionInfo, new SAAddMissionToHubServer()
                {
                    MissionFilepath = actionInfo.Attributes.GetOrWarn("MissionFilepath", "Invalid mission file path for AddMissionToHubServer", StringExtensions.ContentFileExists),
                    TargetComp = actionInfo.Attributes.GetOrThrow("TargetComp", "Invalid target computer for AddMissionToHubServer", StringExtensions.HasContent),
                    AssignmentTag = tag,
                    StartsComplete = actionInfo.Attributes.GetBool("StartsComplete")
                }));

            case "RemoveMissionFromHubServer":
                return(ActionDelayDecorator.Create(actionInfo, new SARemoveMissionFromHubServer()
                {
                    MissionFilepath = actionInfo.Attributes.GetOrWarn("MissionFilepath", "Invalid mission file path for RemoveMissionFromHubServer", StringExtensions.ContentFileExists),
                    TargetComp = actionInfo.Attributes.GetOrThrow("TargetComp", "Invalid target computer for RemoveMissionFromHubServer", StringExtensions.HasContent)
                }));

            case "AddThreadToMissionBoard":
                return(ActionDelayDecorator.Create(actionInfo, new SAAddThreadToMissionBoard()
                {
                    ThreadFilepath = actionInfo.Attributes.GetOrWarn("ThreadFilepath", "Invalid thread path for AddThreadToMissionBoard", StringExtensions.ContentFileExists),
                    TargetComp = actionInfo.Attributes.GetOrThrow("TargetComp", "Invalid target computer for AddThreadToMissionBoard", StringExtensions.HasContent)
                }));

            case "AddIRCMessage":
                return(new SAAddIRCMessage()
                {
                    Author = ComputerLoader.filter(actionInfo.Attributes.GetOrThrow("Author", "Invalid author for AddIRCMessage", StringExtensions.HasContent)),
                    Message = ComputerLoader.filter(string.IsNullOrEmpty(actionInfo.Content) ? throw new FormatException("Invalid message for AddIRCMessage") : actionInfo.Content),
                    Delay = actionInfo.Attributes.GetFloat("Delay"),
                    TargetComp = actionInfo.Attributes.GetOrThrow("TargetComp", "Invalid target computer for AddIRCMessage", StringExtensions.HasContent)
                });