aboutsummaryrefslogtreecommitdiff
path: root/ShiftOS.Objects
diff options
context:
space:
mode:
Diffstat (limited to 'ShiftOS.Objects')
-rw-r--r--ShiftOS.Objects/DiscourseUser.cs18
-rw-r--r--ShiftOS.Objects/Hack.cs76
-rw-r--r--ShiftOS.Objects/Objects.cs141
-rw-r--r--ShiftOS.Objects/Properties/AssemblyInfo.cs36
-rw-r--r--ShiftOS.Objects/ShiftFS.cs374
-rw-r--r--ShiftOS.Objects/ShiftOS.Objects.csproj75
-rw-r--r--ShiftOS.Objects/ShiftOSMenuRenderer.cs27
-rw-r--r--ShiftOS.Objects/packages.config4
8 files changed, 751 insertions, 0 deletions
diff --git a/ShiftOS.Objects/DiscourseUser.cs b/ShiftOS.Objects/DiscourseUser.cs
new file mode 100644
index 0000000..d91b2e3
--- /dev/null
+++ b/ShiftOS.Objects/DiscourseUser.cs
@@ -0,0 +1,18 @@
+using Discoursistency.HTTP.Client;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Discoursistency.HTTP.Client.Models;
+
+namespace ShiftOS.Objects
+{
+ public class ShiftOSAuthAgent : Discoursistency.Base.Authentication.DiscourseAuthenticationService
+ {
+ public ShiftOSAuthAgent(IClient client) : base(client)
+ {
+ }
+ }
+
+}
diff --git a/ShiftOS.Objects/Hack.cs b/ShiftOS.Objects/Hack.cs
new file mode 100644
index 0000000..8967715
--- /dev/null
+++ b/ShiftOS.Objects/Hack.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ShiftOS.Objects
+{
+ public abstract class Exploit
+ {
+ public void BeginExploit(string remote_user, bool isMud)
+ {
+ var ctx = new ExploitContext();
+ SendToMUD(remote_user, "hack_getcontext");
+ MessageReceived += (u, c, j) =>
+ {
+
+ };
+ ThisContext = ctx;
+ }
+
+ public ExploitContext ThisContext { get; internal set; }
+
+ public virtual void SendToMUD(string target_user, string command, string json = "")
+ {
+ ThisContext.IsMUDHack = false;
+ if (command == "hack_getcontext")
+ {
+ MessageReceived?.Invoke(target_user, "context_info", ExploitContext.CreateRandom());
+ }
+ }
+
+ public event MUDMessageEventHandler MessageReceived;
+
+
+ public abstract void OnRun(ExploitContext ctx);
+ }
+
+ public delegate void MUDMessageEventHandler(string target_user, string command, string json);
+
+ public class ExploitContext
+ {
+ public static string CreateRandom()
+ {
+ //We can't use JSON.NET. We must construct the JSON ourselves.
+ StringBuilder jBuilder = new StringBuilder();
+ jBuilder.AppendLine("{");
+ jBuilder.Append("\tIsMUDHack: \"false\",");
+
+ jBuilder.AppendLine("}");
+ return jBuilder.ToString();
+ }
+
+ /// <summary>
+ /// Gets or sets whether or not this exploit context belongs to a MUD hack session.
+ /// </summary>
+ public bool IsMUDHack { get; set; }
+
+ /// <summary>
+ /// Gets or sets the target username for this exploit context. Used for talking with the MUD about it.
+ /// </summary>
+ public string TargetUsername { get; set; }
+
+ /// <summary>
+ /// Gets or sets the target's locks.
+ /// </summary>
+ public List<Lock> TargetLocks { get; set; }
+
+ }
+
+ public abstract class Lock
+ {
+ public abstract bool Unlocked { get; }
+ public abstract void Unlock();
+ }
+}
diff --git a/ShiftOS.Objects/Objects.cs b/ShiftOS.Objects/Objects.cs
new file mode 100644
index 0000000..bb5838e
--- /dev/null
+++ b/ShiftOS.Objects/Objects.cs
@@ -0,0 +1,141 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ShiftOS.Objects
+{
+ public enum LegionRole
+ {
+ Admin,
+ Manager,
+ Committed,
+ Trainee,
+ AwaitingInvite
+ }
+
+ public enum LegionPublicity
+ {
+ Public, //Will display on the 'Join Legion' page, anyone can join
+ PublicInviteOnly, //Will display on the 'Join Legion' page but you must be invited
+ Unlisted, //Won't display on 'Join Legion', but anyone can join
+ UnlistedInviteOnly //Won't display in 'Join Legion', and admin/manager invitation is required.
+ }
+
+ public class Legion
+ {
+ public string Name { get; set; }
+ public LegionPublicity Publicity { get; set; }
+ public ConsoleColor BannerColor { get; set; }
+ public string Description { get; set; }
+ public string ShortName { get; set; }
+
+ public Dictionary<string, LegionRole> Roles { get; set; }
+ public Dictionary<LegionRole, string> RoleNames { get; set; }
+
+
+ }
+
+ public class MUDMemo
+ {
+ public string UserFrom { get; set; }
+ public string UserTo { get; set; }
+ public MemoType Type { get; set; }
+ public string Body { get; set; }
+ public string Subject { get; set; }
+ }
+
+ public class ClientSave
+ {
+ public string Username { get; set; }
+ public string Password { get; set; }
+ }
+
+ public enum MemoType
+ {
+ Regular,
+ Job,
+ LegionInvite,
+ }
+
+
+ public class PongHighscore
+ {
+ public string UserName { get; set; }
+ public int HighestLevel { get; set; }
+ public int HighestCodepoints { get; set; }
+ }
+
+ public class GUIDRequest
+ {
+ public string name { get; set; }
+ public string guid { get; set; }
+ }
+
+ public class OnlineUser
+ {
+ public string Guid { get; set; }
+ public string Username { get; set; }
+ public string OnlineChat { get; set; }
+ }
+
+ public class Channel
+ {
+ public string Name { get; set; }
+ public string ID { get; set; }
+ public string Topic { get; set; }
+ public int MaxUsers { get; set; } //0 for unlimited users (or the MUD maximum)
+ public List<Save> Users = new List<Save>();
+ }
+
+
+ [Serializable]
+ public class ServerMessage
+ {
+ public string Name { get; set; }
+ public string Contents { get; set; }
+ public string GUID { get; set; }
+ }
+
+ //Better to store this stuff server-side so we can do some neat stuff with hacking...
+ public class Save
+ {
+ public string Username { get; set; }
+ public int Codepoints { get; set; }
+ public Dictionary<string, bool> Upgrades { get; set; }
+ public int StoryPosition { get; set; }
+ public string Language { get; set; }
+
+ public List<string> CurrentLegions { get; set; }
+
+ public int MajorVersion { get; set; }
+ public int MinorVersion { get; set; }
+ public int Revision { get; set; }
+
+ public string Password { get; set; }
+ public string SystemName { get; set; }
+
+ public string DiscourseName { get; set; }
+
+ /// <summary>
+ /// If the user has entered their Discourse account into ShiftOS, this is the password they gave.
+ ///
+ /// ANY developer caught abusing this property will have their dev status revoked and their account PERMANENTLY SUSPENDED. - Michael
+ /// </summary>
+ public string DiscoursePass { get; set; }
+
+
+ public int CountUpgrades()
+ {
+ int count = 0;
+ foreach (var upg in Upgrades)
+ {
+ if (upg.Value == true)
+ count++;
+ }
+ return count;
+ }
+ }
+
+}
diff --git a/ShiftOS.Objects/Properties/AssemblyInfo.cs b/ShiftOS.Objects/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..6004a95
--- /dev/null
+++ b/ShiftOS.Objects/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ShiftOS.Objects")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ShiftOS.Objects")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("a069089a-8962-4607-b2b2-4cf4a371066e")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/ShiftOS.Objects/ShiftFS.cs b/ShiftOS.Objects/ShiftFS.cs
new file mode 100644
index 0000000..c9d87e3
--- /dev/null
+++ b/ShiftOS.Objects/ShiftFS.cs
@@ -0,0 +1,374 @@
+using System;
+using Newtonsoft.Json;
+using System.Collections.Generic;
+using static ShiftOS.Objects.ShiftFS.Utils;
+using System.Text;
+using System.Threading;
+
+namespace ShiftOS.Objects.ShiftFS
+{
+
+ public enum Permissions
+ {
+ User,
+ Administrator,
+ Superuser,
+ All
+ }
+ public class File
+ {
+ public string Name;
+ public byte[] Data;
+ public bool ReadAccessToLowUsers;
+ public Permissions permissions;
+ public System.IO.Stream GetStream()
+ {
+ if ((int)CurrentUser >= (int)permissions || permissions == Permissions.All)
+ {
+ return new System.IO.MemoryStream(Data);
+ }
+ else if (ReadAccessToLowUsers == true)
+ {
+ return new System.IO.MemoryStream(Data, false);
+ }
+ return null;
+ }
+
+ public File(string name, byte[] data, bool ReadAccess_to_low_users, Permissions perm)
+ {
+ Name = name;
+ Data = data;
+ permissions = perm;
+ ReadAccessToLowUsers = ReadAccess_to_low_users;
+ }
+ }
+ public class Directory
+ {
+ public string Name;
+ public List<File> Files = new List<File>();
+ public List<Directory> Subdirectories = new List<Directory>();
+ public bool ReadAccessToLowUsers;
+ public Permissions permissions;
+ public void AddFile(File file)
+ {
+ if ((int)CurrentUser >= (int)permissions || permissions == Permissions.All)
+ {
+ Files.Add(file);
+ }
+ }
+ public void RemoveFile(string name)
+ {
+ if ((int)CurrentUser >= (int)permissions || permissions == Permissions.All)
+ {
+ Files.Remove(Files.Find(x => x.Name == name));
+ }
+ }
+ public void RemoveFile(File file)
+ {
+ if ((int)CurrentUser >= (int)permissions || permissions == Permissions.All)
+ {
+ Files.Remove(file);
+ }
+ }
+ public File FindFileByName(string name)
+ {
+ if ((int)CurrentUser >= (int)permissions || permissions == Permissions.All)
+ {
+ return Files.Find(x => x.Name == name);
+ }
+ return null;
+ }
+ public void AddDirectory(Directory dir)
+ {
+ if ((int)CurrentUser >= (int)permissions || permissions == Permissions.All)
+ {
+ Subdirectories.Add(dir);
+ }
+ }
+ public void RemoveDirectory(string name)
+ {
+ if ((int)CurrentUser >= (int)permissions || permissions == Permissions.All)
+ {
+ Subdirectories.Remove(Subdirectories.Find(x => x.Name == name));
+ }
+ }
+ public void RemoveDirectory(Directory dir)
+ {
+ if ((int)CurrentUser >= (int)permissions || permissions == Permissions.All)
+ {
+ Subdirectories.Remove(dir);
+ }
+ }
+ public Directory FindDirectoryByName(string name)
+ {
+ if ((int)CurrentUser >= (int)permissions || permissions == Permissions.All)
+ {
+ return Subdirectories.Find(x => x.Name == name);
+ }
+ return null;
+ }
+ }
+
+ public static class Utils
+ {
+ public static Permissions CurrentUser { get; set; }
+
+ public static List<Directory> Mounts { get; set; }
+
+ static Utils()
+ {
+ if (Mounts == null)
+ Mounts = new List<Directory>();
+
+ }
+
+ public static void Mount(string json)
+ {
+ var dir = JsonConvert.DeserializeObject<Directory>(json);
+ Mounts.Add(dir);
+ }
+
+ public static void MountPersistent(string mfsFile)
+ {
+ var dir = JsonConvert.DeserializeObject<Directory>(ReadAllText(mfsFile));
+ Mounts.Add(dir);
+ string oldJson = JsonConvert.SerializeObject(dir);
+ var t = new Thread(new ThreadStart(() =>
+ {
+ while (Mounts != null)
+ {
+ if (oldJson != JsonConvert.SerializeObject(dir))
+ {
+ oldJson = JsonConvert.SerializeObject(dir);
+ WriteAllText(mfsFile, oldJson);
+ }
+ }
+ }));
+ t.IsBackground = true;
+ t.Start();
+ }
+
+
+ public static void CreateDirectory(string path)
+ {
+ if (!DirectoryExists(path))
+ {
+ string[] pathlist = path.Split('/');
+ int vol = Convert.ToInt32(pathlist[0].Replace(":", ""));
+ var dir = Mounts[vol];
+ for (int i = 1; i <= pathlist.Length - 2; i++)
+ {
+ dir = dir.FindDirectoryByName(pathlist[i]);
+ }
+ dir.AddDirectory(new Directory
+ {
+ Name = pathlist[pathlist.Length - 1],
+ permissions = CurrentUser,
+ });
+ }
+ else
+ {
+ throw new Exception("The directory \"" + path + "\" already exists.");
+ }
+ }
+
+ public static byte[] ReadAllBytes(string path)
+ {
+ string[] pathlist = path.Split('/');
+ int vol = Convert.ToInt32(pathlist[0].Replace(":", ""));
+ var dir = Mounts[vol];
+ for (int i = 1; i <= pathlist.Length - 2; i++)
+ {
+ dir = dir.FindDirectoryByName(pathlist[i]);
+ }
+ var file = dir.FindFileByName(pathlist[pathlist.Length - 1]);
+
+ return file.Data;
+
+ }
+
+ public static void WriteAllText(string path, string contents)
+ {
+ string[] pathlist = path.Split('/');
+ int vol = Convert.ToInt32(pathlist[0].Replace(":", ""));
+ var dir = Mounts[vol];
+ for (int i = 1; i <= pathlist.Length - 2; i++)
+ {
+ dir = dir.FindDirectoryByName(pathlist[i]);
+ }
+
+ if (!FileExists(path))
+ {
+ dir.AddFile(new File(pathlist[pathlist.Length - 1], Encoding.UTF8.GetBytes(contents), false, Permissions.All));
+ }
+ else
+ {
+ var f = dir.FindFileByName(pathlist[pathlist.Length - 1]);
+ f.Data = Encoding.UTF8.GetBytes(contents);
+ }
+
+ }
+
+
+ public static void Delete(string path)
+ {
+ string[] pathlist = path.Split('/');
+ int vol = Convert.ToInt32(pathlist[0].Replace(":", ""));
+ var dir = Mounts[vol];
+ for (int i = 1; i <= pathlist.Length - 2; i++)
+ {
+ dir = dir.FindDirectoryByName(pathlist[i]);
+ }
+
+ if (FileExists(path))
+ {
+ dir.RemoveFile(pathlist[pathlist.Length - 1]);
+ }
+ else
+ {
+ dir.RemoveDirectory(pathlist[pathlist.Length - 1]);
+ }
+
+ }
+
+
+ public static void WriteAllBytes(string path, byte[] contents)
+ {
+ string[] pathlist = path.Split('/');
+ int vol = Convert.ToInt32(pathlist[0].Replace(":", ""));
+ var dir = Mounts[vol];
+ for (int i = 1; i <= pathlist.Length - 2; i++)
+ {
+ dir = dir.FindDirectoryByName(pathlist[i]);
+ }
+
+ if (!FileExists(path))
+ {
+ dir.AddFile(new File(pathlist[pathlist.Length - 1], contents, false, Permissions.All));
+ }
+ else
+ {
+ var f = dir.FindFileByName(pathlist[pathlist.Length - 1]);
+ f.Data = contents;
+ }
+
+ }
+
+
+
+ public static string ExportMount(int index)
+ {
+ var dir = Mounts[index];
+ return JsonConvert.SerializeObject(dir, Formatting.Indented);
+ }
+
+ public static bool DirectoryExists(string path)
+ {
+ string[] pathlist = path.Split('/');
+ int vol = Convert.ToInt32(pathlist[0].Replace(":", ""));
+ var dir = Mounts[vol];
+ for (int i = 1; i <= pathlist.Length - 1; i++)
+ {
+ dir = dir.FindDirectoryByName(pathlist[i]);
+ }
+ return dir != null;
+
+ }
+
+ public static bool FileExists(string path)
+ {
+ string[] pathlist = path.Split('/');
+ int vol = Convert.ToInt32(pathlist[0].Replace(":", ""));
+ var dir = Mounts[vol];
+ for (int i = 1; i <= pathlist.Length - 2; i++)
+ {
+ dir = dir.FindDirectoryByName(pathlist[i]);
+ }
+ return dir.FindFileByName(pathlist[pathlist.Length - 1]) != null;
+
+ }
+
+ public static Directory GetDirectoryInfo(string path)
+ {
+ string[] pathlist = path.Split('/');
+ int vol = Convert.ToInt32(pathlist[0].Replace(":", ""));
+ var dir = Mounts[vol];
+ for (int i = 1; i <= pathlist.Length - 1; i++)
+ {
+ dir = dir.FindDirectoryByName(pathlist[i]);
+ }
+ if (path.EndsWith("/"))
+ path = path.Remove(path.Length - 1, 1);
+ return dir;
+ }
+
+ public static string ReadAllText(string path)
+ {
+ return Encoding.UTF8.GetString(ReadAllBytes(path));
+ }
+
+
+
+ public static File GetFileInfo(string path)
+ {
+ string[] pathlist = path.Split('/');
+ int vol = Convert.ToInt32(pathlist[0].Replace(":", ""));
+ var dir = Mounts[vol];
+ for (int i = 1; i <= pathlist.Length - 2; i++)
+ {
+ dir = dir.FindDirectoryByName(pathlist[i]);
+ }
+ return dir.FindFileByName(pathlist[pathlist.Length - 1]);
+
+ }
+
+ public static string[] GetDirectories(string path)
+ {
+ string[] pathlist = path.Split('/');
+ int vol = Convert.ToInt32(pathlist[0].Replace(":", ""));
+ var dir = Mounts[vol];
+ for(int i = 1; i <= pathlist.Length - 1; i++)
+ {
+ dir = dir.FindDirectoryByName(pathlist[i]);
+ }
+ if (path.EndsWith("/"))
+ path = path.Remove(path.Length - 1, 1);
+
+ List<string> paths = new List<string>();
+
+ foreach(var subdir in dir.Subdirectories)
+ {
+ paths.Add(path + "/" + subdir.Name);
+ }
+ paths.Sort();
+ return paths.ToArray();
+ }
+
+ public static string[] GetFiles(string path)
+ {
+ string[] pathlist = path.Split('/');
+ int vol = Convert.ToInt32(pathlist[0].Replace(":", ""));
+ var dir = Mounts[vol];
+ for (int i = 1; i <= pathlist.Length - 1; i++)
+ {
+ dir = dir.FindDirectoryByName(pathlist[i]);
+ }
+ if (path.EndsWith("/"))
+ path = path.Remove(path.Length - 1, 1);
+
+ List<string> paths = new List<string>();
+
+ foreach (var subdir in dir.Files)
+ {
+ paths.Add(path + "/" + subdir.Name);
+ }
+ paths.Sort();
+ return paths.ToArray();
+ }
+
+ public static void WriteAllText(string v, object p)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/ShiftOS.Objects/ShiftOS.Objects.csproj b/ShiftOS.Objects/ShiftOS.Objects.csproj
new file mode 100644
index 0000000..84d7ea8
--- /dev/null
+++ b/ShiftOS.Objects/ShiftOS.Objects.csproj
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{A069089A-8962-4607-B2B2-4CF4A371066E}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>ShiftOS.Objects</RootNamespace>
+ <AssemblyName>ShiftOS.Objects</AssemblyName>
+ <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Discoursistency.Base">
+ <HintPath>..\Libraries\Discoursistency.Base.dll</HintPath>
+ </Reference>
+ <Reference Include="Discoursistency.HTTP">
+ <HintPath>..\Libraries\Discoursistency.HTTP.dll</HintPath>
+ </Reference>
+ <Reference Include="Discoursistency.Util">
+ <HintPath>..\Libraries\Discoursistency.Util.dll</HintPath>
+ </Reference>
+ <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="DiscourseUser.cs" />
+ <Compile Include="Hack.cs" />
+ <Compile Include="Objects.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="ShiftFS.cs" />
+ <Compile Include="ShiftOSMenuRenderer.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/ShiftOS.Objects/ShiftOSMenuRenderer.cs b/ShiftOS.Objects/ShiftOSMenuRenderer.cs
new file mode 100644
index 0000000..0e8fa05
--- /dev/null
+++ b/ShiftOS.Objects/ShiftOSMenuRenderer.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace ShiftOS.Objects
+{
+ class ShiftOSMenuRenderer : ToolStripProfessionalRenderer
+ {
+ public ShiftOSMenuRenderer() : base(new ShiftOSColorTable())
+ {
+
+ }
+
+ protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
+ {
+
+ }
+ }
+
+ public class ShiftOSColorTable : ProfessionalColorTable
+ {
+
+ }
+}
diff --git a/ShiftOS.Objects/packages.config b/ShiftOS.Objects/packages.config
new file mode 100644
index 0000000..9d64bf3
--- /dev/null
+++ b/ShiftOS.Objects/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
+</packages> \ No newline at end of file