aboutsummaryrefslogtreecommitdiff
path: root/ShiftOS_TheReturn
diff options
context:
space:
mode:
Diffstat (limited to 'ShiftOS_TheReturn')
-rw-r--r--ShiftOS_TheReturn/CommandParser.cs2
-rw-r--r--ShiftOS_TheReturn/FileSkimmerBackend.cs20
-rw-r--r--ShiftOS_TheReturn/IFileHandler.cs30
-rw-r--r--ShiftOS_TheReturn/IVirus.cs29
-rw-r--r--ShiftOS_TheReturn/SaveSystem.cs2
-rw-r--r--ShiftOS_TheReturn/ShiftOS.Engine.csproj3
-rw-r--r--ShiftOS_TheReturn/Skinning.cs292
-rw-r--r--ShiftOS_TheReturn/VirusManager.cs125
8 files changed, 408 insertions, 95 deletions
diff --git a/ShiftOS_TheReturn/CommandParser.cs b/ShiftOS_TheReturn/CommandParser.cs
index 2f0d249..d56e7bd 100644
--- a/ShiftOS_TheReturn/CommandParser.cs
+++ b/ShiftOS_TheReturn/CommandParser.cs
@@ -208,7 +208,7 @@ namespace ShiftOS.Engine
}
}
- internal static CommandParser GenerateSample()
+ public static CommandParser GenerateSample()
{
var parser = new CommandParser();
parser.AddPart(new CommandFormatCommand());
diff --git a/ShiftOS_TheReturn/FileSkimmerBackend.cs b/ShiftOS_TheReturn/FileSkimmerBackend.cs
index 090dc8e..ac20d34 100644
--- a/ShiftOS_TheReturn/FileSkimmerBackend.cs
+++ b/ShiftOS_TheReturn/FileSkimmerBackend.cs
@@ -46,14 +46,20 @@ namespace ShiftOS.Engine
/// <param name="path">The path to open.</param>
public static void OpenFile(string path)
{
- _fs.OpenFile(path);
+ if (!Objects.ShiftFS.Utils.FileExists(path))
+ throw new System.IO.FileNotFoundException("ShiftFS could not find the file specified.", path);
+ foreach (var type in ReflectMan.Types.Where(x => x.GetInterfaces().Contains(typeof(IFileHandler)) && Shiftorium.UpgradeAttributesUnlocked(x)))
+ {
+ foreach(FileHandlerAttribute attrib in type.GetCustomAttributes(false).Where(x => x is FileHandlerAttribute))
+ {
+ if (path.ToLower().EndsWith(attrib.Extension))
+ {
+ var obj = (IFileHandler)Activator.CreateInstance(type);
+ obj.OpenFile(path);
+ }
+ }
+ }
}
-
- /// <summary>
- /// Gets the file type of a given path.
- /// </summary>
- /// <param name="path">The path to check</param>
- /// <returns>The FileType of the path</returns>
public static FileType GetFileType(string path)
{
diff --git a/ShiftOS_TheReturn/IFileHandler.cs b/ShiftOS_TheReturn/IFileHandler.cs
new file mode 100644
index 0000000..3187c9a
--- /dev/null
+++ b/ShiftOS_TheReturn/IFileHandler.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ShiftOS.Engine
+{
+ public interface IFileHandler
+ {
+ void OpenFile(string file);
+ }
+
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
+ public class FileHandlerAttribute : Attribute
+ {
+ public FileHandlerAttribute(string name, string extension, string iconid)
+ {
+ Name = name;
+ Extension = extension;
+ IconID = iconid;
+ }
+
+ public string Name { get; set; }
+ public string Extension { get; set; }
+ public string IconID { get; set; }
+ }
+}
+
+
diff --git a/ShiftOS_TheReturn/IVirus.cs b/ShiftOS_TheReturn/IVirus.cs
new file mode 100644
index 0000000..0c06aea
--- /dev/null
+++ b/ShiftOS_TheReturn/IVirus.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ShiftOS.Engine
+{
+ public interface IVirus
+ {
+ void Infect(int threatlevel);
+ void Disinfect();
+ }
+
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
+ public class VirusAttribute : Attribute
+ {
+ public VirusAttribute(string id, string name, string desc)
+ {
+ Name = name;
+ ID = id;
+ Description = desc;
+ }
+
+ public string Name { get; set; }
+ public string Description { get; set; }
+ public string ID { get; set; }
+ }
+}
diff --git a/ShiftOS_TheReturn/SaveSystem.cs b/ShiftOS_TheReturn/SaveSystem.cs
index b767605..e20bc08 100644
--- a/ShiftOS_TheReturn/SaveSystem.cs
+++ b/ShiftOS_TheReturn/SaveSystem.cs
@@ -191,7 +191,7 @@ namespace ShiftOS.Engine
{
// "No errors, this never gets called."
Console.WriteLine("[inetd] SEVERE: " + ex.Message);
- string dest = "Startup Exception " + DateTime.Now.ToString() + ".txt";
+ string dest = "Startup Exception " + DateTime.Now.ToString().Replace("/", "-").Replace(":", "-") + ".txt";
System.IO.File.WriteAllText(dest, ex.ToString());
Console.WriteLine("[inetd] Full exception details have been saved to: " + dest);
Thread.Sleep(3000);
diff --git a/ShiftOS_TheReturn/ShiftOS.Engine.csproj b/ShiftOS_TheReturn/ShiftOS.Engine.csproj
index 4bb930e..f1946ad 100644
--- a/ShiftOS_TheReturn/ShiftOS.Engine.csproj
+++ b/ShiftOS_TheReturn/ShiftOS.Engine.csproj
@@ -132,9 +132,11 @@
</Compile>
<Compile Include="Desktop.cs" />
<Compile Include="FileSkimmerBackend.cs" />
+ <Compile Include="IFileHandler.cs" />
<Compile Include="Infobox.cs" />
<Compile Include="IShiftOSWindow.cs" />
<Compile Include="IStatusIcon.cs" />
+ <Compile Include="IVirus.cs" />
<Compile Include="KernelWatchdog.cs" />
<Compile Include="Localization.cs" />
<Compile Include="LoginManager.cs" />
@@ -164,6 +166,7 @@
<Compile Include="TerminalTextWriter.cs" />
<Compile Include="TutorialManager.cs" />
<Compile Include="UserManagementCommands.cs" />
+ <Compile Include="VirusManager.cs" />
<Compile Include="WinOpenAttribute.cs" />
<EmbeddedResource Include="Infobox.resx">
<DependentUpon>Infobox.cs</DependentUpon>
diff --git a/ShiftOS_TheReturn/Skinning.cs b/ShiftOS_TheReturn/Skinning.cs
index e7ebbc7..59c7132 100644
--- a/ShiftOS_TheReturn/Skinning.cs
+++ b/ShiftOS_TheReturn/Skinning.cs
@@ -679,7 +679,7 @@ namespace ShiftOS.Engine
[ShifterDescription("The background color for the bottom right border when the window is inactive.")]
public Color BorderInactiveBottomRightBackground = DefaultBackground;
-
+ #region Windows -> Title Buttons -> Idle -> Colors
[ShifterMeta("Windows")]
[ShifterCategory("Title Buttons")]
[ShifterName("Close Button Color")]
@@ -694,15 +694,64 @@ namespace ShiftOS.Engine
[ShifterDescription("The maximize button color")]
public Color MaximizeButtonColor = Accent1;
- [ShifterHidden]
- public CommandParser CurrentParser = CommandParser.GenerateSample();
-
[ShifterMeta("Windows")]
[ShifterCategory("Title Buttons")]
[ShifterName("Minimize Button Color")]
[RequiresUpgrade("shift_title_buttons")]
[ShifterDescription("The minimize button color")]
public Color MinimizeButtonColor = Accent1;
+ #endregion
+
+ #region Windows -> Title Buttons -> Over -> Colors
+ [ShifterMeta("Windows")]
+ [ShifterCategory("Title Buttons")]
+ [ShifterName("Close Button Mouse Over Color")]
+ [RequiresUpgrade("shift_title_buttons;shift_states")]
+ [ShifterDescription("The close button color when the mouse hovers over it.")]
+ public Color CloseButtonOverColor = Color.FromArgb(0x80, 0, 0);
+
+ [ShifterMeta("Windows")]
+ [ShifterCategory("Title Buttons")]
+ [ShifterName("Maximize Button Mouse Over Color")]
+ [RequiresUpgrade("shift_title_buttons;shift_states")]
+ [ShifterDescription("The maximize button color when the mouse hovers over it.")]
+ public Color MaximizeButtonOverColor = Accent1;
+
+ [ShifterMeta("Windows")]
+ [ShifterCategory("Title Buttons")]
+ [ShifterName("Minimize Button Mouse Over Color")]
+ [RequiresUpgrade("shift_title_buttons;shift_states")]
+ [ShifterDescription("The minimize button color when the mouse hovers over it")]
+ public Color MinimizeButtonOverColor = Accent1;
+ #endregion
+
+ #region Windows -> Title Buttons -> Down -> Colors
+ [ShifterMeta("Windows")]
+ [ShifterCategory("Title Buttons")]
+ [ShifterName("Close Button Mouse Down Color")]
+ [RequiresUpgrade("shift_title_buttons;shift_states")]
+ [ShifterDescription("The close button color when the mouse clicks it.")]
+ public Color CloseButtonDownColor = Color.FromArgb(0x80, 0, 0);
+
+ [ShifterMeta("Windows")]
+ [ShifterCategory("Title Buttons")]
+ [ShifterName("Maximize Button Mouse Down Color")]
+ [RequiresUpgrade("shift_title_buttons;shift_states")]
+ [ShifterDescription("The maximize button color when the mouse clicks it.")]
+ public Color MaximizeButtonDownColor = Accent1;
+
+ [ShifterMeta("Windows")]
+ [ShifterCategory("Title Buttons")]
+ [ShifterName("Minimize Button Mouse Down Color")]
+ [RequiresUpgrade("shift_title_buttons;shift_states")]
+ [ShifterDescription("The minimize button color when the mouse clicks it")]
+ public Color MinimizeButtonDownColor = Accent1;
+ #endregion
+
+
+ [ShifterHidden]
+ public CommandParser CurrentParser = CommandParser.GenerateSample();
+
[ShifterMeta("Desktop")]
[ShifterCategory("Desktop Panel")]
@@ -825,6 +874,32 @@ namespace ShiftOS.Engine
[ShifterDescription("The background color of the desktop.")]
public Color DesktopColor = DesktopBG;
+ #region Menus -> Toolbars
+ [ShifterMeta("Menus")]
+ [ShifterCategory("Toolbars")]
+ [ShifterName("Toolbar Border")]
+ public Color Menu_ToolStripBorder = TitleBG;
+
+ [ShifterMeta("Menus")]
+ [ShifterCategory("Toolbars")]
+ [ShifterName("Dropdown background")]
+ public Color Menu_ToolStripDropDownBackground = DefaultBackground;
+
+ [ShifterMeta("Menus")]
+ [ShifterCategory("Toolbars")]
+ [ShifterName("Toolbar gradient start")]
+ public Color Menu_ToolStripGradientBegin = TitleBG;
+
+ [ShifterMeta("Menus")]
+ [ShifterCategory("Toolbars")]
+ [ShifterName("Toolbar gradient middle")]
+ public Color Menu_ToolStripGradientMiddle = TitleBG;
+
+ [ShifterMeta("Menus")]
+ [ShifterCategory("Toolbars")]
+ [ShifterName("Toolbar gradient end")]
+ public Color Menu_ToolStripGradientEnd = TitleBG;
+
[ShifterMeta("Menus")]
[ShifterCategory("Toolbars")]
[ShifterName("Button select highlight")]
@@ -909,6 +984,38 @@ namespace ShiftOS.Engine
[ShifterCategory("Toolbars")]
[ShifterName("Button pressed gradient end")]
public Color Menu_ButtonPressedGradientEnd = Accent1;
+ #endregion
+
+ #region Menus -> General
+ [ShifterMeta("Menus")]
+ [ShifterCategory("General")]
+ [ShifterName("Menu text color")]
+ public Color Menu_TextColor = DefaultForeground;
+
+ [ShifterMeta("Menus")]
+ [ShifterCategory("General")]
+ [ShifterName("Menu selected text color")]
+ public Color Menu_SelectedTextColor = TitleFG;
+
+ [ShifterMeta("Menus")]
+ [ShifterCategory("General")]
+ [ShifterName("Rafter gradient start")]
+ public Color Menu_RaftingContainerGradientBegin = TitleBG;
+
+ [ShifterMeta("Menus")]
+ [ShifterCategory("General")]
+ [ShifterName("Rafter gradient end")]
+ public Color Menu_RaftingContainerGradientEnd = TitleBG;
+
+ [ShifterMeta("Menus")]
+ [ShifterCategory("General")]
+ [ShifterName("Separator Color 1")]
+ public Color Menu_SeparatorDark = DefaultForeground;
+
+ [ShifterMeta("Menus")]
+ [ShifterCategory("General")]
+ [ShifterName("Separator Color 2")]
+ public Color Menu_SeparatorLight = TitleFG;
[ShifterMeta("Menus")]
[ShifterCategory("General")]
@@ -924,6 +1031,34 @@ namespace ShiftOS.Engine
[ShifterCategory("General")]
[ShifterName("Check BG (Pressed)")]
public Color Menu_CheckPressedBackground = Accent1;
+ #endregion
+
+ #region Menus -> Menu Bars
+ [ShifterMeta("Menus")]
+ [ShifterCategory("Toolbars")]
+ [ShifterName("Menu item pressed gradient start")]
+ public Color Menu_MenuItemPressedGradientBegin = Accent1;
+
+ [ShifterMeta("Menus")]
+ [ShifterCategory("Toolbars")]
+ [ShifterName("Menu item pressed gradient middle")]
+ public Color Menu_MenuItemPressedGradientMiddle = Accent1;
+
+ [ShifterMeta("Menus")]
+ [ShifterCategory("Toolbars")]
+ [ShifterName("Menu item pressed gradient end")]
+ public Color Menu_MenuItemPressedGradientEnd = Accent1;
+
+ [ShifterMeta("Menus")]
+ [ShifterCategory("Toolbars")]
+ [ShifterName("Menu item selected gradient start")]
+ public Color Menu_MenuItemSelectedGradientBegin = Accent2;
+
+ [ShifterMeta("Menus")]
+ [ShifterCategory("Toolbars")]
+ [ShifterName("Menu item selected gradient end")]
+ public Color Menu_MenuItemSelectedGradientEnd = Accent2;
+
[ShifterMeta("Menus")]
[ShifterCategory("Menu bars")]
@@ -964,52 +1099,9 @@ namespace ShiftOS.Engine
[ShifterCategory("Menu bars")]
[ShifterName("Menu border")]
public Color Menu_MenuBorder = DefaultBackground;
+ #endregion
- [ShifterMeta("Menus")]
- [ShifterCategory("Toolbars")]
- [ShifterName("Menu item selected gradient start")]
- public Color Menu_MenuItemSelectedGradientBegin = Accent2;
-
- [ShifterMeta("Menus")]
- [ShifterCategory("Toolbars")]
- [ShifterName("Menu item selected gradient end")]
- public Color Menu_MenuItemSelectedGradientEnd = Accent2;
-
- [ShifterMeta("Menus")]
- [ShifterCategory("Toolbars")]
- [ShifterName("Menu item pressed gradient start")]
- public Color Menu_MenuItemPressedGradientBegin = Accent1;
-
- [ShifterMeta("Menus")]
- [ShifterCategory("Toolbars")]
- [ShifterName("Menu item pressed gradient middle")]
- public Color Menu_MenuItemPressedGradientMiddle = Accent1;
-
- [ShifterMeta("Menus")]
- [ShifterCategory("Toolbars")]
- [ShifterName("Menu item pressed gradient end")]
- public Color Menu_MenuItemPressedGradientEnd = Accent1;
-
- [ShifterMeta("Menus")]
- [ShifterCategory("General")]
- [ShifterName("Rafter gradient start")]
- public Color Menu_RaftingContainerGradientBegin = TitleBG;
-
- [ShifterMeta("Menus")]
- [ShifterCategory("General")]
- [ShifterName("Rafter gradient end")]
- public Color Menu_RaftingContainerGradientEnd = TitleBG;
-
- [ShifterMeta("Menus")]
- [ShifterCategory("General")]
- [ShifterName("Separator Color 1")]
- public Color Menu_SeparatorDark = DefaultForeground;
-
- [ShifterMeta("Menus")]
- [ShifterCategory("General")]
- [ShifterName("Separator Color 2")]
- public Color Menu_SeparatorLight = TitleFG;
-
+ #region Menus -> Status bars
[ShifterMeta("Menus")]
[ShifterCategory("Status bars")]
[ShifterName("Status bar gradient start")]
@@ -1019,32 +1111,9 @@ namespace ShiftOS.Engine
[ShifterCategory("Status bars")]
[ShifterName("Status bar gradient end")]
public Color Menu_StatusStripGradientEnd = TitleBG;
+ #endregion
- [ShifterMeta("Menus")]
- [ShifterCategory("Toolbars")]
- [ShifterName("Toolbar Border")]
- public Color Menu_ToolStripBorder = TitleBG;
-
- [ShifterMeta("Menus")]
- [ShifterCategory("Toolbars")]
- [ShifterName("Dropdown background")]
- public Color Menu_ToolStripDropDownBackground = DefaultBackground;
-
- [ShifterMeta("Menus")]
- [ShifterCategory("Toolbars")]
- [ShifterName("Toolbar gradient start")]
- public Color Menu_ToolStripGradientBegin = TitleBG;
-
- [ShifterMeta("Menus")]
- [ShifterCategory("Toolbars")]
- [ShifterName("Toolbar gradient middle")]
- public Color Menu_ToolStripGradientMiddle = TitleBG;
-
- [ShifterMeta("Menus")]
- [ShifterCategory("Toolbars")]
- [ShifterName("Toolbar gradient end")]
- public Color Menu_ToolStripGradientEnd = TitleBG;
-
+ #region Menus -> Menu holders
[ShifterMeta("Menus")]
[ShifterCategory("Menu holders")]
[ShifterName("Content panel gradient start")]
@@ -1064,19 +1133,9 @@ namespace ShiftOS.Engine
[ShifterCategory("Menu holders")]
[ShifterName("Panel gradient end")]
public Color Menu_ToolStripPanelGradientEnd = TitleBG;
+ #endregion
- [ShifterMeta("Menus")]
- [ShifterCategory("General")]
- [ShifterName("Menu text color")]
- public Color Menu_TextColor = DefaultForeground;
-
- [ShifterMeta("Menus")]
- [ShifterCategory("General")]
- [ShifterName("Menu selected text color")]
- public Color Menu_SelectedTextColor = TitleFG;
-
-
-
+ #region Windows -> Title Buttons -> Idle -> Images
//Images
[Image("closebutton")]
[ShifterMeta("Windows")]
@@ -1101,7 +1160,64 @@ namespace ShiftOS.Engine
[RequiresUpgrade("shift_title_buttons;skinning")]
[ShifterDescription("Show an image on the Maximize Button using this setting.")]
public byte[] MaximizeButtonImage = null;
+ #endregion
+
+ #region Windows -> Title Buttons -> Mouse Over -> Images
+ //Images
+ [Image("closebuttonover")]
+ [ShifterMeta("Windows")]
+ [ShifterCategory("Title Buttons")]
+ [ShifterName("Close Button Mouse Over Image")]
+ [RequiresUpgrade("shift_title_buttons;skinning;shift_states")]
+ [ShifterDescription("Show an image on the Close Button when the mouse hovers over it using this setting.")]
+ public byte[] CloseButtonOverImage = null;
+
+ [Image("minimizebuttonover")]
+ [ShifterMeta("Windows")]
+ [ShifterCategory("Title Buttons")]
+ [ShifterName("Minimize Button Mouse Over Image")]
+ [RequiresUpgrade("shift_title_buttons;skinning;shift_states")]
+ [ShifterDescription("Show an image on the Minimize Button when the mouse hovers over it using this setting.")]
+ public byte[] MinimizeButtonOverImage = null;
+
+ [Image("maximizebuttonover")]
+ [ShifterMeta("Windows")]
+ [ShifterCategory("Title Buttons")]
+ [ShifterName("Maximize Button Mouse Over Image")]
+ [RequiresUpgrade("shift_title_buttons;skinning;shift_states")]
+ [ShifterDescription("Show an image on the Maximize Button when the mouse hovers over it using this setting.")]
+ public byte[] MaximizeButtonOverImage = null;
+ #endregion
+ #region Windows -> Title Buttons -> Mouse Down -> Images
+ //Images
+ [Image("closebuttondown")]
+ [ShifterMeta("Windows")]
+ [ShifterCategory("Title Buttons")]
+ [ShifterName("Close Button Mouse Down Image")]
+ [RequiresUpgrade("shift_title_buttons;skinning;shift_states")]
+ [ShifterDescription("Show an image on the Close Button when the mouse clicks it using this setting.")]
+ public byte[] CloseButtonDownImage = null;
+
+ [Image("minimizebuttondown")]
+ [ShifterMeta("Windows")]
+ [ShifterCategory("Title Buttons")]
+ [ShifterName("Minimize Button Mouse Down Image")]
+ [RequiresUpgrade("shift_title_buttons;skinning;shift_states")]
+ [ShifterDescription("Show an image on the Minimize Button when the mouse clicks it using this setting.")]
+ public byte[] MinimizeButtonDownImage = null;
+
+ [Image("maximizebuttondown")]
+ [ShifterMeta("Windows")]
+ [ShifterCategory("Title Buttons")]
+ [ShifterName("Maximize Button Mouse Down Image")]
+ [RequiresUpgrade("shift_title_buttons;skinning;shift_states")]
+ [ShifterDescription("Show an image on the Maximize Button when the mouse clicks it using this setting.")]
+ public byte[] MaximizeButtonDownImage = null;
+ #endregion
+
+
+ #region Desktop -> Images
[Image("desktopbackground")]
[ShifterMeta("Desktop")]
[ShifterCategory("General")]
@@ -1160,7 +1276,10 @@ namespace ShiftOS.Engine
[Image("applauncher")]
[RequiresUpgrade("skinning;shift_app_launcher")]
public byte[] AppLauncherImage = null;
+ #endregion
+
+ #region System -> General
[ShifterMeta("System")]
[ShifterCategory("General")]
[ShifterName("Terminal font")]
@@ -1175,6 +1294,7 @@ namespace ShiftOS.Engine
[ShifterCategory("General")]
[ShifterName("Terminal background color")]
public ConsoleColor TerminalBackColorCC = ConsoleColor.Black;
+ #endregion
[ShifterMeta("Desktop")]
[ShifterCategory("Desktop Panel")]
diff --git a/ShiftOS_TheReturn/VirusManager.cs b/ShiftOS_TheReturn/VirusManager.cs
new file mode 100644
index 0000000..31152cc
--- /dev/null
+++ b/ShiftOS_TheReturn/VirusManager.cs
@@ -0,0 +1,125 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ShiftOS.Objects;
+
+namespace ShiftOS.Engine
+{
+ public static class VirusManager
+ {
+ public static List<IVirus> ActiveInfections = new List<IVirus>();
+
+ public static void Init()
+ {
+ Desktop.InvokeOnWorkerThread(() =>
+ {
+ ActiveInfections = new List<IVirus>();
+ if (SaveSystem.CurrentSave.ViralInfections == null)
+ SaveSystem.CurrentSave.ViralInfections = new List<ViralInfection>();
+ foreach (var virusdata in SaveSystem.CurrentSave.ViralInfections)
+ {
+ var virus = CreateVirus(virusdata.ID, virusdata.ThreatLevel);
+ var existing = ActiveInfections.FirstOrDefault(x => x.GetType() == virus.GetType());
+ if (existing != null)
+ {
+ var eIndex = ActiveInfections.IndexOf(existing);
+ ActiveInfections[eIndex] = virus;
+ existing.Disinfect();
+ }
+ else
+ {
+ ActiveInfections.Add(virus);
+ }
+ }
+ });
+ }
+
+ public static void Infect(string id, int threatlevel)
+ {
+ if (threatlevel < 1)
+ throw new Exception("Threat level can't be below 1.");
+ if (threatlevel > 4)
+ throw new Exception("Threat level can't be above 4.");
+
+ var infection = SaveSystem.CurrentSave.ViralInfections.FirstOrDefault(x => x.ID == id);
+ if (infection != null)
+ {
+ if(infection.ThreatLevel < threatlevel)
+ {
+ infection.ThreatLevel = threatlevel;
+ }
+ else
+ {
+ return;
+ //no need to reinfect with a lower threatlevel
+ }
+ }
+ else
+ {
+ SaveSystem.CurrentSave.ViralInfections.Add(new ViralInfection
+ {
+ ID = id,
+ ThreatLevel = threatlevel
+ });
+ }
+ var virus = CreateVirus(id, threatlevel);
+ var existing = ActiveInfections.FirstOrDefault(x => x.GetType() == virus.GetType());
+ if(existing != null)
+ {
+ var eIndex = ActiveInfections.IndexOf(existing);
+ ActiveInfections[eIndex] = virus;
+ existing.Disinfect();
+ }
+ else
+ {
+ ActiveInfections.Add(virus);
+ }
+ }
+
+ internal static IVirus CreateVirus(string id, int threatlevel)
+ {
+ if (threatlevel < 1)
+ throw new Exception("Threat level can't be below 1.");
+ if (threatlevel > 4)
+ throw new Exception("Threat level can't be above 4.");
+
+ foreach(var type in ReflectMan.Types.Where(x => x.GetInterfaces().Contains(typeof(IVirus)) && Shiftorium.UpgradeAttributesUnlocked(x)))
+ {
+ var attrib = type.GetCustomAttributes(false).FirstOrDefault(x => x is VirusAttribute) as VirusAttribute;
+ if(attrib != null)
+ {
+ if(attrib.ID == id)
+ {
+ IVirus virus = (IVirus)Activator.CreateInstance(type);
+ virus.Infect(threatlevel);
+ return virus;
+ }
+ }
+ }
+
+ throw new Exception("Cannot create virus.");
+ }
+
+ public static void Disinfect(string id)
+ {
+ foreach(var virus in ActiveInfections.ToArray())
+ {
+ var type = virus.GetType();
+ var attrib = type.GetCustomAttributes(false).FirstOrDefault(x => x is VirusAttribute) as VirusAttribute;
+ if(attrib != null)
+ {
+ if (attrib.ID == id)
+ {
+ ActiveInfections.Remove(virus);
+ var inf = SaveSystem.CurrentSave.ViralInfections.FirstOrDefault(x => x.ID == id);
+ if (inf != null)
+ SaveSystem.CurrentSave.ViralInfections.Remove(inf);
+ virus.Disinfect();
+ }
+ }
+ }
+ }
+ }
+}