diff --git a/FFXIVClassic.sln b/FFXIVClassic.sln
index b79d9e72..4a0fe45b 100644
--- a/FFXIVClassic.sln
+++ b/FFXIVClassic.sln
@@ -20,6 +20,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FFXIVClassic World Server",
{3A3D6626-C820-4C18-8C81-64811424F20E} = {3A3D6626-C820-4C18-8C81-64811424F20E}
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Launcher Editor", "Launcher Editor\Launcher Editor.csproj", "{0FFA9D2F-41C6-443C-99B7-665702CF548F}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -42,6 +44,10 @@ Global
{3067889D-8A50-40D6-9CD5-23AA8EA96F26}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3067889D-8A50-40D6-9CD5-23AA8EA96F26}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3067889D-8A50-40D6-9CD5-23AA8EA96F26}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0FFA9D2F-41C6-443C-99B7-665702CF548F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0FFA9D2F-41C6-443C-99B7-665702CF548F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0FFA9D2F-41C6-443C-99B7-665702CF548F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0FFA9D2F-41C6-443C-99B7-665702CF548F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Launcher Editor/App.config b/Launcher Editor/App.config
new file mode 100644
index 00000000..88fa4027
--- /dev/null
+++ b/Launcher Editor/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Launcher Editor/Launcher Editor.csproj b/Launcher Editor/Launcher Editor.csproj
new file mode 100644
index 00000000..c1a98e86
--- /dev/null
+++ b/Launcher Editor/Launcher Editor.csproj
@@ -0,0 +1,60 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {0FFA9D2F-41C6-443C-99B7-665702CF548F}
+ Exe
+ Properties
+ Launcher_Editor
+ Launcher Editor
+ v4.5.2
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Launcher Editor/Program.cs b/Launcher Editor/Program.cs
new file mode 100644
index 00000000..45a89bb5
--- /dev/null
+++ b/Launcher Editor/Program.cs
@@ -0,0 +1,137 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Launcher_Editor
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine(FFXIVLoginStringDecodeBinary("C:\\Program Files (x86)\\SquareEnix\\FINAL FANTASY XIV\\ffxivlogin.exe"));
+ }
+
+ public static string FFXIVLoginStringDecodeBinary(string path)
+ {
+ Console.OutputEncoding = System.Text.Encoding.UTF8;
+ byte[] data = File.ReadAllBytes(path);
+ //int offset = 0x5405a;
+ //int offset = 0x5425d;
+ int offset = 0x53ea0;
+ while (true)
+ {
+ string result = "";
+ uint key = (uint)data[offset + 0] << 8 | data[offset + 1];
+ uint key2 = data[offset + 2];
+ key = RotateRight(key, 1) & 0xFFFF;
+ key -= 0x22AF;
+ key &= 0xFFFF;
+ key2 = key2 ^ key;
+ key = RotateRight(key, 1) & 0xFFFF;
+ key -= 0x22AF;
+ key &= 0xFFFF;
+ uint finalKey = key;
+ key = data[offset + 3];
+ uint count = (key2 & 0xFF) << 8;
+ key = key ^ finalKey;
+ key &= 0xFF;
+ count |= key;
+
+ int count2 = 0;
+ while (count != 0)
+ {
+ uint encrypted = data[offset + 4 + count2];
+ finalKey = RotateRight(finalKey, 1) & 0xFFFF;
+ finalKey -= 0x22AF;
+ finalKey &= 0xFFFF;
+ encrypted = encrypted ^ (finalKey & 0xFF);
+
+ result += (char)encrypted;
+ count--;
+ count2++;
+ }
+
+ offset += 4 + count2;
+ }
+ }
+
+ public static string FFXIVLoginStringDecode(byte[] data)
+ {
+ string result = "";
+ uint key = (uint)data[0] << 8 | data[1];
+ uint key2 = data[2];
+ key = RotateRight(key, 1) & 0xFFFF;
+ key -= 0x22AF;
+ key2 = key2 ^ key;
+ key = RotateRight(key, 1) & 0xFFFF;
+ key -= 0x22AF;
+ uint finalKey = key;
+ key = data[3];
+ uint count = (key2 & 0xFF) << 8;
+ key = key ^ finalKey;
+ key &= 0xFF;
+ count |= key;
+
+ int count2 = 0;
+ while (count != 0)
+ {
+ uint encrypted = data[4 + count2];
+ finalKey = RotateRight(finalKey, 1) & 0xFFFF;
+ finalKey -= 0x22AF;
+ encrypted = encrypted ^ (finalKey & 0xFF);
+ result += (char)encrypted;
+ count--;
+ count2++;
+ }
+
+ return result;
+ }
+
+ public static byte[] FFXIVLoginStringEncode(uint key, string text)
+ {
+ key = key & 0xFFFF;
+
+ uint count = 0;
+ byte[] asciiBytes = Encoding.ASCII.GetBytes(text);
+ byte[] result = new byte[4 + text.Length];
+ for (count = 0; count < text.Length; count++)
+ {
+ result[result.Length - count - 1] = (byte)(asciiBytes[asciiBytes.Length - count - 1] ^ (key & 0xFF));
+ key += 0x22AF;
+ key &= 0xFFFF;
+ key = RotateLeft(key, 1) & 0xFFFF;
+ }
+
+ count = count ^ key;
+ result[3] = (byte)(count & 0xFF);
+
+ key += 0x22AF & 0xFFFF;
+ key = RotateLeft(key, 1) & 0xFFFF;
+
+ result[2] = (byte)(key & 0xFF);
+
+ key += 0x22AF & 0xFFFF;
+ key = RotateLeft(key, 1) & 0xFFFF;
+
+
+ result[1] = (byte)(key & 0xFF);
+ result[0] = (byte)((key >> 8) & 0xFF);
+
+ return result;
+ }
+
+ public static uint RotateLeft(uint value, int bits)
+ {
+ return (value << bits) | (value >> (16 - bits));
+ }
+
+ public static uint RotateRight(uint value, int bits)
+ {
+ return (value >> bits) | (value << (16 - bits));
+ }
+
+ }
+}
diff --git a/Launcher Editor/Properties/AssemblyInfo.cs b/Launcher Editor/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..bed36e48
--- /dev/null
+++ b/Launcher Editor/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("Launcher Editor")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Launcher Editor")]
+[assembly: AssemblyCopyright("Copyright © 2017")]
+[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("0ffa9d2f-41c6-443c-99b7-665702cf548f")]
+
+// 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")]