diff --git a/contrib/Connection Patcher/App.config b/contrib/Connection Patcher/App.config
new file mode 100644
index 00000000000..87b8cafdd3d
--- /dev/null
+++ b/contrib/Connection Patcher/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/contrib/Connection Patcher/Connection Patcher.csproj b/contrib/Connection Patcher/Connection Patcher.csproj
new file mode 100644
index 00000000000..8ad5a631aed
--- /dev/null
+++ b/contrib/Connection Patcher/Connection Patcher.csproj
@@ -0,0 +1,69 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {137B1355-6A81-4A3A-A01E-93ABAA4FFFDB}
+ Exe
+ Properties
+ Connection_Patcher
+ Connection Patcher
+ v4.0
+ 512
+ Client
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ TRACE;DEBUG
+ prompt
+ 4
+ Off
+ false
+
+
+ AnyCPU
+ none
+ true
+ bin\Release\
+
+
+ prompt
+ 4
+ Off
+ false
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/contrib/Connection Patcher/Connection Patcher.sln b/contrib/Connection Patcher/Connection Patcher.sln
new file mode 100644
index 00000000000..7ba4e8c6137
--- /dev/null
+++ b/contrib/Connection Patcher/Connection Patcher.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.30110.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Connection Patcher", "Connection Patcher.csproj", "{137B1355-6A81-4A3A-A01E-93ABAA4FFFDB}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {137B1355-6A81-4A3A-A01E-93ABAA4FFFDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {137B1355-6A81-4A3A-A01E-93ABAA4FFFDB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {137B1355-6A81-4A3A-A01E-93ABAA4FFFDB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {137B1355-6A81-4A3A-A01E-93ABAA4FFFDB}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/contrib/Connection Patcher/Constants/BinaryTypes.cs b/contrib/Connection Patcher/Constants/BinaryTypes.cs
new file mode 100644
index 00000000000..b98a7ea73c0
--- /dev/null
+++ b/contrib/Connection Patcher/Constants/BinaryTypes.cs
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2012-2014 Arctium Emulation
+ * Copyright (C) 2008-2014 TrinityCore
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+namespace Connection_Patcher.Constants
+{
+ enum BinaryTypes : uint
+ {
+ None = 0000000000,
+ Pe32 = 0x0000014C,
+ Pe64 = 0x00008664,
+ Mach32 = 0xFEEDFACE,
+ Mach64 = 0xFEEDFACF
+ }
+}
diff --git a/contrib/Connection Patcher/Helper.cs b/contrib/Connection Patcher/Helper.cs
new file mode 100644
index 00000000000..d0e8f6655e7
--- /dev/null
+++ b/contrib/Connection Patcher/Helper.cs
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2012-2014 Arctium Emulation
+ * Copyright (C) 2008-2014 TrinityCore
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+using Connection_Patcher.Constants;
+using System;
+using System.IO;
+using System.Security.Cryptography;
+
+namespace Connection_Patcher
+{
+ class Helper
+ {
+ public static BinaryTypes GetBinaryType(byte[] data)
+ {
+ BinaryTypes type = 0u;
+
+ using (var reader = new BinaryReader(new MemoryStream(data)))
+ {
+ var magic = (uint)reader.ReadUInt16();
+
+ // Check MS-DOS magic
+ if (magic == 0x5A4D)
+ {
+ reader.BaseStream.Seek(0x3C, SeekOrigin.Begin);
+
+ // Read PE start offset
+ var peOffset = reader.ReadUInt32();
+
+ reader.BaseStream.Seek(peOffset, SeekOrigin.Begin);
+
+ var peMagic = reader.ReadUInt32();
+
+ // Check PE magic
+ if (peMagic != 0x4550)
+ throw new NotSupportedException("Not a PE file!");
+
+ type = (BinaryTypes)reader.ReadUInt16();
+ }
+ else
+ {
+ reader.BaseStream.Seek(0, SeekOrigin.Begin);
+
+ type = (BinaryTypes)reader.ReadUInt32();
+ }
+ }
+
+ return type;
+ }
+
+ public static string GetFileChecksum(byte[] data)
+ {
+ using (var stream = new BufferedStream(new MemoryStream(data), 1200000))
+ {
+ var sha256 = new SHA256Managed();
+ var checksum = sha256.ComputeHash(stream);
+
+ return BitConverter.ToString(checksum).Replace("-", "").ToLower();
+ }
+ }
+ }
+}
diff --git a/contrib/Connection Patcher/Offsets/Windows.cs b/contrib/Connection Patcher/Offsets/Windows.cs
new file mode 100644
index 00000000000..4f2f32708cc
--- /dev/null
+++ b/contrib/Connection Patcher/Offsets/Windows.cs
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+namespace Connection_Patcher.Offsets
+{
+ static class Windows
+ {
+ public static class x86
+ {
+ public static readonly long BNet = 0xD3259;
+ public static readonly long Send = 0x889CA;
+ public static readonly long Recv = 0x86EEE;
+ public static readonly long Signature = 0x20B79;
+ public static readonly long RealmList = 0x228D6C;
+ }
+
+ public static class x64
+ {
+ public static readonly long BNet = 0;
+ public static readonly long Send = 0xAAB6B;
+ public static readonly long Recv = 0xA9FA3;
+ public static readonly long Signature = 0;
+ public static readonly long RealmList = 0x2BB33C;
+ }
+ }
+}
diff --git a/contrib/Connection Patcher/Patcher.cs b/contrib/Connection Patcher/Patcher.cs
new file mode 100644
index 00000000000..8e73997365c
--- /dev/null
+++ b/contrib/Connection Patcher/Patcher.cs
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2012-2014 Arctium Emulation
+ * Copyright (C) 2008-2014 TrinityCore
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+using Connection_Patcher.Constants;
+using System;
+using System.IO;
+
+namespace Connection_Patcher
+{
+ class Patcher : IDisposable
+ {
+ public string Binary { get; set; }
+ public bool Initialized { get; private set; }
+ public BinaryTypes Type { get; private set; }
+
+ public byte[] binary;
+ bool success;
+
+ public Patcher(string file)
+ {
+ Initialized = false;
+ success = false;
+
+ using (var stream = new MemoryStream(File.ReadAllBytes(file)))
+ {
+ Binary = file;
+ binary = stream.ToArray();
+
+ if (binary != null)
+ {
+ Type = Helper.GetBinaryType(binary);
+
+ Initialized = true;
+ }
+ }
+ }
+
+ public void Patch(byte[] bytes, byte[] pattern, long address = 0)
+ {
+ if (Initialized && (address != 0 || binary.Length >= pattern.Length))
+ {
+ var offset = pattern == null ? address : SearchOffset(pattern);
+ Console.WriteLine("Found offset {0}", offset);
+
+ if (offset != 0 && binary.Length >= bytes.Length)
+ {
+ try
+ {
+ for (int i = 0; i < bytes.Length; i++)
+ binary[offset + i] = bytes[i];
+ }
+ catch (Exception ex)
+ {
+ throw new NotSupportedException(ex.Message);
+ }
+ }
+ }
+ }
+
+ long SearchOffset(byte[] pattern)
+ {
+ var matches = 0;
+
+ for (long i = 0; i < binary.Length; i++)
+ {
+ matches = 0;
+
+ for (int j = 0; j < pattern.Length; j++)
+ {
+ if (pattern.Length > (binary.Length - i))
+ return 0;
+
+ if (pattern[j] == 0)
+ {
+ matches++;
+ continue;
+ }
+
+ if (binary[i + j] != pattern[j])
+ break;
+
+ matches++;
+ }
+
+ if (matches == pattern.Length)
+ return i;
+ }
+
+ return 0;
+ }
+
+ public void Finish()
+ {
+ success = true;
+ }
+
+ public void Dispose()
+ {
+ try
+ {
+ if (File.Exists(Binary))
+ File.Delete(Binary);
+
+ if (success)
+ File.WriteAllBytes(Binary, binary);
+ }
+ catch (UnauthorizedAccessException)
+ {
+
+ }
+
+ binary = null;
+ }
+ }
+}
diff --git a/contrib/Connection Patcher/Patches/Mac.cs b/contrib/Connection Patcher/Patches/Mac.cs
new file mode 100644
index 00000000000..583d1398354
--- /dev/null
+++ b/contrib/Connection Patcher/Patches/Mac.cs
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2012-2014 Arctium Emulation
+ * Copyright (C) 2008-2014 TrinityCore
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+namespace Connection_Patcher.Patches
+{
+ class Mac
+ {
+ public static class x86
+ {
+ public static byte[] BNet = { };
+ public static byte[] Send = { };
+ public static byte[] Recv = { };
+ public static byte[] Password = { 0x0F, 0x85 };
+ public static byte[] Signature = { };
+ }
+
+ public static class x64
+ {
+ //public static byte[] BNet = { 0xB8, 0xD5, 0xF8, 0x7F, 0x82, 0x89, 0x47, 0x0C, 0x5D, 0xC3, 0x90, 0x90, 0x90 };
+ public static byte[] BNet = { };
+ //public static byte[] Send = { 0x90, 0x31, 0xDB };
+ public static byte[] Send = { };
+ public static byte[] Recv = { };
+ public static byte[] Password = { 0x0F, 0x85 };
+ //public static byte[] Signature = { 0x45, 0x31, 0xED, 0x4D, 0x89, 0xFC, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xEB };
+ public static byte[] Signature = { };
+ }
+ }
+}
diff --git a/contrib/Connection Patcher/Patches/Windows.cs b/contrib/Connection Patcher/Patches/Windows.cs
new file mode 100644
index 00000000000..feb10507084
--- /dev/null
+++ b/contrib/Connection Patcher/Patches/Windows.cs
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012-2014 Arctium Emulation
+ * Copyright (C) 2008-2014 TrinityCore
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+namespace Connection_Patcher.Patches
+{
+ class Windows
+ {
+ public static class x86
+ {
+ public static byte[] BNet = { 0x89, 0x48, 0x08, 0xC7, 0x40, 0x0C, 0xD5, 0xF8, 0x7F, 0x82, 0x90 };
+ public static byte[] Send = { 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90, 0xEB };
+ public static byte[] Recv = { 0xB8, 0x00, 0x00, 0x00, 0x00 };
+ public static byte[] Password = { 0x75 };
+ public static byte[] Signature = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xE9 };
+ public static byte[] RealmList = { 0x08 };
+ public static byte[] RealmListBn = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ }
+
+ public static class x64
+ {
+ //public static byte[] BNet = { 0xB8, 0xD5, 0xF8, 0x7F, 0x82, 0x89, 0x41, 0x0C, 0x48, 0x8B, 0xC1, 0xC3 };
+ public static byte[] BNet = { };
+ public static byte[] Send = { 0x45, 0x33, 0xED, 0x90, 0x90, 0x90 };
+ public static byte[] Recv = { 0xB8, 0x00, 0x00, 0x00, 0x00, 0x90 };
+ public static byte[] Password = { 0x75 };
+ public static byte[] RealmList = { 0x4C, 0x8B, 0xEA };
+ //public static byte[] Signature = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xE9 };
+ public static byte[] Signature = { };
+ }
+ }
+}
diff --git a/contrib/Connection Patcher/Patterns/Mac.cs b/contrib/Connection Patcher/Patterns/Mac.cs
new file mode 100644
index 00000000000..d518aa3c78f
--- /dev/null
+++ b/contrib/Connection Patcher/Patterns/Mac.cs
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2012-2014 Arctium Emulation
+ * Copyright (C) 2008-2014 TrinityCore
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+namespace Connection_Patcher.Patterns
+{
+ class Mac
+ {
+ public static class x86
+ {
+ public static byte[] Password = { 0x0F, 0x84, 0xE3, 0x00, 0x00, 0x00, 0x8B, 0x03, 0x8B, 0x40, 0x04 };
+ }
+
+ public static class x64
+ {
+ public static byte[] Password = { 0x0F, 0x84, 0x00, 0xFF, 0xFF, 0xFF, 0x49, 0x8B, 0x45, 0x00, 0xB9, 0x40 };
+ }
+ }
+}
diff --git a/contrib/Connection Patcher/Patterns/Windows.cs b/contrib/Connection Patcher/Patterns/Windows.cs
new file mode 100644
index 00000000000..f8bde67dddb
--- /dev/null
+++ b/contrib/Connection Patcher/Patterns/Windows.cs
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012-2014 Arctium Emulation
+ * Copyright (C) 2008-2014 TrinityCore
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+namespace Connection_Patcher.Patterns
+{
+ class Windows
+ {
+ public static class x86
+ {
+ public static byte[] Password = { 0x74, 0x89, 0x8B, 0x16, 0x8B, 0x42, 0x04 };
+ public static byte[] RealmListBn = { 0x2E, 0x6C, 0x6F, 0x67, 0x6F, 0x6E, 0x2E, 0x62, 0x61, 0x74, 0x74, 0x6C, 0x65, 0x2E, 0x6E, 0x65, 0x74 };
+ }
+
+ public static class x64
+ {
+ public static byte[] Password = { 0x74, 0x84, 0x48, 0x8B, 0x03 };
+ }
+ }
+}
diff --git a/contrib/Connection Patcher/Program.cs b/contrib/Connection Patcher/Program.cs
new file mode 100644
index 00000000000..956741b625b
--- /dev/null
+++ b/contrib/Connection Patcher/Program.cs
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2012-2014 Arctium Emulation
+ * Copyright (C) 2008-2014 TrinityCore
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+using Connection_Patcher.Constants;
+using System;
+using System.IO;
+using System.Net;
+using System.Text;
+using System.Threading;
+
+namespace Connection_Patcher
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ if (args.Length >= 1)
+ {
+ Console.ForegroundColor = ConsoleColor.Cyan;
+
+ Console.WriteLine("Client Connection Patcher");
+ Console.WriteLine("Press Enter to patch...");
+
+ Console.ReadKey(true);
+
+ var commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
+ var modulePath = "";
+ var moduleFile = "";
+
+ // Let's use Win32 as default module
+ var patchSend = Patches.Windows.x86.Send;
+ var offsetSend = Offsets.Windows.x86.Send;
+ var patchRecv = Patches.Windows.x86.Recv;
+ var offsetRecv = Offsets.Windows.x86.Recv;
+ var patchBNet = Patches.Windows.x86.BNet;
+ var offsetBNet = Offsets.Windows.x86.BNet;
+ var patchSignature = Patches.Windows.x86.Signature;
+ var offsetSignature = Offsets.Windows.x86.Signature;
+ var fileName = args[0].Replace(".exe", "_Patched.exe");
+ var battleNetFileName = args[0].Replace("Wow.exe", "Battle.net.dll");
+ var modulePatch = Patches.Windows.x86.Password;
+ var modulePattern = Patterns.Windows.x86.Password;
+ var realmListPatch = Patches.Windows.x86.RealmList;
+ var realmListoffset = Offsets.Windows.x86.RealmList;
+ var realmListBnPatch = Patches.Windows.x86.RealmListBn;
+ var realmListBnPattern = Patterns.Windows.x86.RealmListBn;
+
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.Write("Creating patched binaries for ");
+
+ using (var patcher = new Patcher(args[0]))
+ {
+ switch (patcher.Type)
+ {
+ case BinaryTypes.Pe32:
+ Console.WriteLine("Win32 client...");
+ modulePath = commonAppData + "/Blizzard Entertainment/Battle.net/Cache/";
+ moduleFile = "8f52906a2c85b416a595702251570f96d3522f39237603115f2f1ab24962043c.auth";
+ break;
+ //case BinaryTypes.Pe64:
+ // Console.WriteLine("Win64 client...");
+ // fileName = patcher.Binary.Replace(".exe", "") + "_Patched.exe";
+
+ // modulePath = commonAppData + "/Blizzard Entertainment/Battle.net/Cache/";
+ // moduleFile = "0a3afee2cade3a0e8b458c4b4660104cac7fc50e2ca9bef0d708942e77f15c1d.auth";
+ // break;
+ //case BinaryTypes.Mach32:
+ // break;
+ //case BinaryTypes.Mach64:
+ // Console.WriteLine("Mc64 client...");
+ // patchBNet = Patches.Mac.x64.BNet;
+ // patternBNet = Patterns.Mac.x64.BNet;
+ // patchSend = Patches.Mac.x64.Send;
+ // patternSend = Patterns.Mac.x64.Send;
+ // patchSignature = Patches.Mac.x64.Signature;
+ // patternSignature = Patterns.Mac.x64.Signature;
+ // fileName = patcher.Binary + " Patched";
+
+ // modulePath = "/Users/Shared/Blizzard/Battle.net/Cache/";
+ // moduleFile = "97eeb2e28e9e56ed6a22d09f44e2ff43c93315e006bbad43bafc0defaa6f50ae.auth";
+ // modulePatch = Patches.Mac.x64.Password;
+ // modulePattern = Patterns.Mac.x64.Password;
+ // break;
+ default:
+ throw new NotSupportedException("Type: " + patcher.Type + " not supported!");
+ }
+
+ if (!File.Exists(battleNetFileName + "_backup"))
+ {
+ File.Copy(battleNetFileName, battleNetFileName + "_backup");
+ File.SetAttributes(battleNetFileName + "_backup", File.GetAttributes(battleNetFileName + "_backup") | FileAttributes.ReadOnly);
+ }
+
+ using (var bnpatcher = new Patcher(battleNetFileName))
+ {
+ bnpatcher.Patch(patchBNet, null, offsetBNet);
+ bnpatcher.Patch(patchSignature, null, offsetSignature);
+ bnpatcher.Patch(realmListBnPatch, realmListBnPattern);
+ bnpatcher.Finish();
+ }
+
+ patcher.Patch(patchSend, null, offsetSend);
+ patcher.Patch(patchRecv, null, offsetRecv);
+ patcher.Patch(realmListPatch, null, realmListoffset);
+
+ patcher.Binary = fileName;
+
+ patcher.Finish();
+
+ Console.ForegroundColor = ConsoleColor.Green;
+ Console.WriteLine("Patching done.");
+
+ CreateModule(moduleFile, modulePath, modulePatch, modulePattern);
+
+ Console.ForegroundColor = ConsoleColor.Green;
+ Console.WriteLine("Successfully created your patched binaries.");
+ }
+ }
+ else
+ {
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.WriteLine("Wrong number of arguments: Missing client file.");
+ }
+
+ Console.ForegroundColor = ConsoleColor.Gray;
+ Thread.Sleep(5000);
+ Environment.Exit(0);
+ }
+
+ static void CreateModule(string moduleName, string path, byte[] patches, byte[] patterns)
+ {
+ var modulePath = path + moduleName[0] + moduleName[1] + "/" + moduleName[2] + moduleName[3];
+ var module = modulePath + "/" + moduleName;
+
+ if (!File.Exists(module))
+ {
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.WriteLine("Base module doesn't exist, downloading it...");
+
+ if (!Directory.Exists(modulePath))
+ Directory.CreateDirectory(modulePath);
+
+ var webClient = new WebClient();
+
+ webClient.DownloadFileCompleted += (o, e) => PatchModule(module, path, patches, patterns);
+ webClient.DownloadFileAsync(new Uri("http://xx.depot.battle.net:1119/" + moduleName), module);
+
+ Console.ForegroundColor = ConsoleColor.Green;
+ Console.WriteLine("Done.");
+ }
+ else
+ PatchModule(module, path, patches, patterns);
+ }
+
+ static void PatchModule(string file, string path, byte[] patches, byte[] pattern)
+ {
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.WriteLine("Patching module...");
+
+ using (var patcher2 = new Patcher(file))
+ {
+ patcher2.Patch(patches, pattern);
+
+ var moduleName = Helper.GetFileChecksum(patcher2.binary) + ".auth";
+ var modulePath = path + moduleName[0] + moduleName[1] + "/" + moduleName[2] + moduleName[3];
+
+ if (!Directory.Exists(modulePath))
+ Directory.CreateDirectory(modulePath);
+
+ patcher2.Binary = modulePath + "/" + moduleName;
+
+ patcher2.Finish();
+ }
+
+ Console.ForegroundColor = ConsoleColor.Green;
+ Console.WriteLine("Patching module finished.");
+
+ Console.ForegroundColor = ConsoleColor.Gray;
+ }
+ }
+}
diff --git a/contrib/Connection Patcher/Properties/AssemblyInfo.cs b/contrib/Connection Patcher/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000000..b1d174575c5
--- /dev/null
+++ b/contrib/Connection Patcher/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("Connection Patcher")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Connection Patcher")]
+[assembly: AssemblyCopyright("Copyright © 2014")]
+[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("07c6905b-5b42-4804-81fe-73d0f74ebfb1")]
+
+// 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/sql/base/auth_database.sql b/sql/base/auth_database.sql
index 0a989cdcb92..3ccbadbbda0 100644
--- a/sql/base/auth_database.sql
+++ b/sql/base/auth_database.sql
@@ -46,8 +46,12 @@ CREATE TABLE `account` (
`locale` tinyint(3) unsigned NOT NULL DEFAULT '0',
`os` varchar(3) NOT NULL DEFAULT '',
`recruiter` int(10) unsigned NOT NULL DEFAULT '0',
+ `battlenet_account` int(10) unsigned DEFAULT NULL,
+ `battlenet_index` tinyint(3) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
- UNIQUE KEY `idx_username` (`username`)
+ UNIQUE KEY `idx_username` (`username`),
+ UNIQUE KEY `uk_bnet_acc` (`battlenet_account`, `battlenet_index`),
+ CONSTRAINT `fk_bnet_acc` FOREIGN KEY (`battlenet_account`) REFERENCES `battlenet_accounts` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Account System';
/*!40101 SET character_set_client = @saved_cs_client */;
@@ -136,6 +140,145 @@ LOCK TABLES `autobroadcast` WRITE;
/*!40000 ALTER TABLE `autobroadcast` ENABLE KEYS */;
UNLOCK TABLES;
+--
+-- Table structure for table `battlenet_account_bans`
+--
+
+DROP TABLE IF EXISTS `battlenet_account_bans`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `battlenet_account_bans` (
+ `id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Account id',
+ `bandate` int(10) unsigned NOT NULL DEFAULT '0',
+ `unbandate` int(10) unsigned NOT NULL DEFAULT '0',
+ `bannedby` varchar(50) NOT NULL,
+ `banreason` varchar(255) NOT NULL,
+ `active` tinyint(3) unsigned NOT NULL DEFAULT '1',
+ PRIMARY KEY (`id`,`bandate`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Ban List';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `battlenet_account_bans`
+--
+
+LOCK TABLES `battlenet_account_bans` WRITE;
+/*!40000 ALTER TABLE `battlenet_account_bans` DISABLE KEYS */;
+/*!40000 ALTER TABLE `battlenet_account_bans` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `battlenet_accounts`
+--
+
+DROP TABLE IF EXISTS `battlenet_accounts`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `battlenet_accounts` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Identifier',
+ `email` varchar(320) NOT NULL,
+ `sha_pass_hash` varchar(64) NOT NULL DEFAULT '',
+ `v` varchar(256) NOT NULL DEFAULT '',
+ `s` varchar(64) NOT NULL DEFAULT '',
+ `sessionKey` varchar(128) NOT NULL DEFAULT '',
+ `joindate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `last_ip` varchar(15) NOT NULL DEFAULT '127.0.0.1',
+ `failed_logins` int(10) unsigned NOT NULL DEFAULT '0',
+ `locked` tinyint(3) unsigned NOT NULL DEFAULT '0',
+ `lock_country` varchar(2) NOT NULL DEFAULT '00',
+ `last_login` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `online` tinyint(3) unsigned NOT NULL DEFAULT '0',
+ `locale` tinyint(3) unsigned NOT NULL DEFAULT '0',
+ `os` varchar(3) NOT NULL DEFAULT '',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='Account System';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+-- Table structure for table `battlenet_components`
+--
+
+DROP TABLE IF EXISTS `battlenet_components`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `battlenet_components` (
+ `Program` varchar(4) NOT NULL,
+ `Platform` varchar(4) NOT NULL,
+ `Build` int(11) unsigned NOT NULL,
+ PRIMARY KEY (`Program`,`Platform`,`Build`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `battlenet_components`
+--
+
+LOCK TABLES `battlenet_components` WRITE;
+/*!40000 ALTER TABLE `battlenet_components` DISABLE KEYS */;
+INSERT INTO `battlenet_components` VALUES
+('Bnet','Cmp1',3),
+('Bnet','Win',26487),
+('Bnet','Wn64',26487),
+('Tool','Win',2736),
+('WoW','base',15595),
+('WoW','enGB',15595),
+('WoW','enUS',15595),
+('WoW','Win',15595),
+('WoW','Wn64',15595);
+/*!40000 ALTER TABLE `battlenet_components` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `battlenet_modules`
+--
+
+DROP TABLE IF EXISTS `battlenet_modules`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `battlenet_modules` (
+ `Hash` varchar(64) NOT NULL,
+ `Name` varchar(64) NOT NULL DEFAULT '',
+ `Type` varchar(8) NOT NULL,
+ `System` varchar(8) NOT NULL,
+ `Data` text,
+ PRIMARY KEY (`Hash`),
+ UNIQUE KEY `uk_name_type_system` (`Name`,`Type`,`System`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `battlenet_modules`
+--
+
+LOCK TABLES `battlenet_modules` WRITE;
+/*!40000 ALTER TABLE `battlenet_modules` DISABLE KEYS */;
+INSERT INTO `battlenet_modules` VALUES
+('19c91b68752b7826df498bf73aca1103c86962a9a55a0a7033e5ad895f4d927c','Password','auth','Mc64',NULL),
+('1af5418a448f8ad05451e3f7dbb2d9af9cb13458eea2368ebfc539476b954f1c','RiskFingerprint','auth','Mc64',NULL),
+('207640724f4531d3b2a21532224d1486e8c4d2d805170381cbc3093264157960','SelectGameAccount','auth','Mac',NULL),
+('2e6d53adab37a41542b38e01f62cd365eab8805ed0de73c307cc6d9d1dfe478c','Password','auth','Win',NULL),
+('36b27cd911b33c61730a8b82c8b2495fd16e8024fc3b2dde08861c77a852941c','Thumbprint','auth','Win','E716F4F0A01EB9C032A6C1393356A4F766F067949D71023C0CFC0613718966EF814E65CC6EE70C432A7F8AFD8A062B52603A2697E851D231D72C0277614181D713369B1E8E4BEEAB72045A9AAD45F319DB918ECDDB83C8EF8B7510600D391D45E7FEC0BEEAE904A5F9FA620F1CCDAD699D84A4739CE669B5A551831E396214E13B4C88F573F5CDC784CD01530C086B674C03BEB66403A0F87ED17ABBB403DE54CF31BE828A20C566C22E4D4263AA77220B0644D99245345BCAC276EA06925EB984D664725C3CB757140AFE12E27CB996F17159B1057E9B58B78BBB5A139C9FF6215A0D250B75FC9DD435655DDEADCD6CFD84800792C146B3633188ECEB53D2038C185E0BD51A9E6C70FD38ADF530F8DF50FB62053C5E894897AB7DD65C7AC80665F18E7989BE6E30F15E939751123D6D8A44F033175301D15AAAD2AEA06FAC60BA4065846AE938F32B1CB15F16DC0E76792A7332346896048065D17C059899E1D2300E402BD0EA74265DA6A42B1C854E2470D7B21AE4A2DAE90E602A759B2CA0EE610B50D5389DB89335D5451FE76DD85B09FD5297D6F9EFB6C34CE885007F7DF20D6A524E0C3E772FA04B3DD2E014D3A337A790943DAD523CBB5453F4FDF8E74DFE361BD5F25AB31952B478148B570DF5762643F32B994FEC99A747E4A265A66EE84A53509EC285C84679606049314FC526C61B537AC8061C788F8B86F52208'),
+('393ca8d75aff6f04f79532cf95a88b91e5743bc59121520ac31fc4508019fe60','Token','auth','Mac',NULL),
+('3c2f63e5949aa6fd6cf330b109ca5b9adcd215beac846b7462ed3aa01d5ad6bb','Password','auth','Mac',NULL),
+('52e2978db6468dfade7c61da89513f443c9225692b5085fbe956749870993703','SelectGameAccount','auth','Mc64',NULL),
+('548b5ef9e0dd5c2f89f59c3e0979249b27505c51f0c77d2b27133726eaee0ad0','Thumbprint','auth','Mac','E716F4F0A01EB9C032A6C1393356A4F766F067949D71023C0CFC0613718966EF814E65CC6EE70C432A7F8AFD8A062B52603A2697E851D231D72C0277614181D713369B1E8E4BEEAB72045A9AAD45F319DB918ECDDB83C8EF8B7510600D391D45E7FEC0BEEAE904A5F9FA620F1CCDAD699D84A4739CE669B5A551831E396214E13B4C88F573F5CDC784CD01530C086B674C03BEB66403A0F87ED17ABBB403DE54CF31BE828A20C566C22E4D4263AA77220B0644D99245345BCAC276EA06925EB984D664725C3CB757140AFE12E27CB996F17159B1057E9B58B78BBB5A139C9FF6215A0D250B75FC9DD435655DDEADCD6CFD84800792C146B3633188ECEB53D2038C185E0BD51A9E6C70FD38ADF530F8DF50FB62053C5E894897AB7DD65C7AC80665F18E7989BE6E30F15E939751123D6D8A44F033175301D15AAAD2AEA06FAC60BA4065846AE938F32B1CB15F16DC0E76792A7332346896048065D17C059899E1D2300E402BD0EA74265DA6A42B1C854E2470D7B21AE4A2DAE90E602A759B2CA0EE610B50D5389DB89335D5451FE76DD85B09FD5297D6F9EFB6C34CE885007F7DF20D6A524E0C3E772FA04B3DD2E014D3A337A790943DAD523CBB5453F4FDF8E74DFE361BD5F25AB31952B478148B570DF5762643F32B994FEC99A747E4A265A66EE84A53509EC285C84679606049314FC526C61B537AC8061C788F8B86F52208'),
+('5e298e530698af905e1247e51ef0b109b352ac310ce7802a1f63613db980ed17','RiskFingerprint','auth','Win',NULL),
+('851c1d2ef926e9b9a345a460874e65517195129b9e3bdec7cc77710fa0b1fad6','Password','auth','Wn64',NULL),
+('894d25d3219d97d085ea5a8b98e66df5bd9f460ec6f104455246a12b8921409d','SelectGameAccount','auth','Wn64',NULL),
+('8c43bda10be33a32abbc09fb2279126c7f5953336391276cff588565332fcd40','RiskFingerprint','auth','Wn64',NULL),
+('a1edab845d9e13e9c84531369be2f61b930a37c8e7a9c66d11ef8963380e178a','Token','auth','Mc64',NULL),
+('a330f388b6687f8a42fe8fbb592a3df724b20b65fb0989342bb8261f2f452318','Token','auth','Wn64',NULL),
+('abc6bb719a73ec1055296001910e26afa561f701ad9995b1ecd7f55f9d3ca37c','SelectGameAccount','auth','Win',NULL),
+('b37136b39add83cfdbafa81857de3dd8f15b34e0135ec6cd9c3131d3a578d8c2','Thumbprint','auth','Mc64','E716F4F0A01EB9C032A6C1393356A4F766F067949D71023C0CFC0613718966EF814E65CC6EE70C432A7F8AFD8A062B52603A2697E851D231D72C0277614181D713369B1E8E4BEEAB72045A9AAD45F319DB918ECDDB83C8EF8B7510600D391D45E7FEC0BEEAE904A5F9FA620F1CCDAD699D84A4739CE669B5A551831E396214E13B4C88F573F5CDC784CD01530C086B674C03BEB66403A0F87ED17ABBB403DE54CF31BE828A20C566C22E4D4263AA77220B0644D99245345BCAC276EA06925EB984D664725C3CB757140AFE12E27CB996F17159B1057E9B58B78BBB5A139C9FF6215A0D250B75FC9DD435655DDEADCD6CFD84800792C146B3633188ECEB53D2038C185E0BD51A9E6C70FD38ADF530F8DF50FB62053C5E894897AB7DD65C7AC80665F18E7989BE6E30F15E939751123D6D8A44F033175301D15AAAD2AEA06FAC60BA4065846AE938F32B1CB15F16DC0E76792A7332346896048065D17C059899E1D2300E402BD0EA74265DA6A42B1C854E2470D7B21AE4A2DAE90E602A759B2CA0EE610B50D5389DB89335D5451FE76DD85B09FD5297D6F9EFB6C34CE885007F7DF20D6A524E0C3E772FA04B3DD2E014D3A337A790943DAD523CBB5453F4FDF8E74DFE361BD5F25AB31952B478148B570DF5762643F32B994FEC99A747E4A265A66EE84A53509EC285C84679606049314FC526C61B537AC8061C788F8B86F52208'),
+('c0f38d05aa1b83065e839c9bd96c831e9f7e42477085138752657a6a9bb9c520','RiskFingerprint','auth','Mac',NULL),
+('c3a1ac0694979e709c3b5486927e558af1e2be02ca96e5615c5a65aacc829226','Thumbprint','auth','Wn64','E716F4F0A01EB9C032A6C1393356A4F766F067949D71023C0CFC0613718966EF814E65CC6EE70C432A7F8AFD8A062B52603A2697E851D231D72C0277614181D713369B1E8E4BEEAB72045A9AAD45F319DB918ECDDB83C8EF8B7510600D391D45E7FEC0BEEAE904A5F9FA620F1CCDAD699D84A4739CE669B5A551831E396214E13B4C88F573F5CDC784CD01530C086B674C03BEB66403A0F87ED17ABBB403DE54CF31BE828A20C566C22E4D4263AA77220B0644D99245345BCAC276EA06925EB984D664725C3CB757140AFE12E27CB996F17159B1057E9B58B78BBB5A139C9FF6215A0D250B75FC9DD435655DDEADCD6CFD84800792C146B3633188ECEB53D2038C185E0BD51A9E6C70FD38ADF530F8DF50FB62053C5E894897AB7DD65C7AC80665F18E7989BE6E30F15E939751123D6D8A44F033175301D15AAAD2AEA06FAC60BA4065846AE938F32B1CB15F16DC0E76792A7332346896048065D17C059899E1D2300E402BD0EA74265DA6A42B1C854E2470D7B21AE4A2DAE90E602A759B2CA0EE610B50D5389DB89335D5451FE76DD85B09FD5297D6F9EFB6C34CE885007F7DF20D6A524E0C3E772FA04B3DD2E014D3A337A790943DAD523CBB5453F4FDF8E74DFE361BD5F25AB31952B478148B570DF5762643F32B994FEC99A747E4A265A66EE84A53509EC285C84679606049314FC526C61B537AC8061C788F8B86F52208'),
+('fbe675a99fb5f4b7fb3eb5e5a22add91a4cabf83e3c5930c6659ad13c457ba18','Token','auth','Win',NULL),
+('bfe4ceb47700aa872e815e007e27df955d4cd4bc1fe731039ee6498ce209f368','Resume','auth','Win',NULL),
+('00ffd88a437afbb88d7d4b74be2e3b43601605ee229151aa9f4bebb29ef66280','Resume','auth','Mac',NULL),
+('898166926805f897804bdbbf40662c9d768590a51a0b26c40dbcdf332ba11974','Resume','auth','Wn64',NULL),
+('304627d437c38500c0b5ca0c6220eeade91390e52a2b005ff3f7754afa1f93cd','Resume','auth','Mc64',NULL);
+/*!40000 ALTER TABLE `battlenet_modules` ENABLE KEYS */;
+UNLOCK TABLES;
+
--
-- Table structure for table `ip2nation`
--
@@ -390,6 +533,8 @@ CREATE TABLE `realmlist` (
`allowedSecurityLevel` tinyint(3) unsigned NOT NULL DEFAULT '0',
`population` float unsigned NOT NULL DEFAULT '0',
`gamebuild` int(10) unsigned NOT NULL DEFAULT '15595',
+ `Region` tinyint(3) unsigned NOT NULL DEFAULT '2',
+ `Battlegroup` tinyint(3) unsigned NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='Realm System';
@@ -401,7 +546,7 @@ CREATE TABLE `realmlist` (
LOCK TABLES `realmlist` WRITE;
/*!40000 ALTER TABLE `realmlist` DISABLE KEYS */;
-INSERT INTO `realmlist` VALUES (1,'Trinity','127.0.0.1','127.0.0.1','255.255.255.0',8085,1,0,1,0,0,15595);
+INSERT INTO `realmlist` VALUES (1,'Trinity','127.0.0.1','127.0.0.1','255.255.255.0',8085,1,0,1,0,0,15595,2,1);
/*!40000 ALTER TABLE `realmlist` ENABLE KEYS */;
UNLOCK TABLES;
diff --git a/sql/updates/auth/2014_05_06_00_auth_battlenet_434.sql b/sql/updates/auth/2014_05_06_00_auth_battlenet_434.sql
new file mode 100644
index 00000000000..f4410c58976
--- /dev/null
+++ b/sql/updates/auth/2014_05_06_00_auth_battlenet_434.sql
@@ -0,0 +1,148 @@
+ALTER TABLE `account`
+ ADD `battlenet_account` int(10) unsigned DEFAULT NULL AFTER `recruiter`,
+ ADD CONSTRAINT `fk_bnet_acc` FOREIGN KEY (`battlenet_account`) REFERENCES `battlenet_accounts` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
+
+ALTER TABLE `realmlist`
+ ADD `Region` tinyint(3) UNSIGNED NOT NULL DEFAULT 2 AFTER `gamebuild`,
+ ADD `Battlegroup` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `Region`;
+
+--
+-- Table structure for table `battlenet_account_bans`
+--
+
+DROP TABLE IF EXISTS `battlenet_account_bans`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `battlenet_account_bans` (
+ `id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Account id',
+ `bandate` int(10) unsigned NOT NULL DEFAULT '0',
+ `unbandate` int(10) unsigned NOT NULL DEFAULT '0',
+ `bannedby` varchar(50) NOT NULL,
+ `banreason` varchar(255) NOT NULL,
+ `active` tinyint(3) unsigned NOT NULL DEFAULT '1',
+ PRIMARY KEY (`id`,`bandate`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Ban List';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `battlenet_account_bans`
+--
+
+LOCK TABLES `battlenet_account_bans` WRITE;
+/*!40000 ALTER TABLE `battlenet_account_bans` DISABLE KEYS */;
+/*!40000 ALTER TABLE `battlenet_account_bans` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `battlenet_accounts`
+--
+
+DROP TABLE IF EXISTS `battlenet_accounts`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `battlenet_accounts` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Identifier',
+ `email` varchar(320) NOT NULL,
+ `sha_pass_hash` varchar(64) NOT NULL DEFAULT '',
+ `v` varchar(256) NOT NULL DEFAULT '',
+ `s` varchar(64) NOT NULL DEFAULT '',
+ `joindate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `last_ip` varchar(15) NOT NULL DEFAULT '127.0.0.1',
+ `failed_logins` int(10) unsigned NOT NULL DEFAULT '0',
+ `locked` tinyint(3) unsigned NOT NULL DEFAULT '0',
+ `lock_country` varchar(2) NOT NULL DEFAULT '00',
+ `last_login` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `online` tinyint(3) unsigned NOT NULL DEFAULT '0',
+ `locale` tinyint(3) unsigned NOT NULL DEFAULT '0',
+ `os` varchar(3) NOT NULL DEFAULT '',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='Account System';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+-- Table structure for table `battlenet_components`
+--
+
+DROP TABLE IF EXISTS `battlenet_components`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `battlenet_components` (
+ `Program` varchar(4) NOT NULL,
+ `Platform` varchar(4) NOT NULL,
+ `Build` int(11) unsigned NOT NULL,
+ PRIMARY KEY (`Program`,`Platform`,`Build`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `battlenet_components`
+--
+
+LOCK TABLES `battlenet_components` WRITE;
+/*!40000 ALTER TABLE `battlenet_components` DISABLE KEYS */;
+INSERT INTO `battlenet_components` VALUES
+('Bnet','Cmp1',3),
+('Bnet','Win',21719),
+('Bnet','Win',26487),
+('Bnet','Wn64',26487),
+('Tool','Win',1569),
+('Tool','Win',2736),
+('WoW','base',12340),
+('WoW','base',15595),
+('WoW','enGB',12340),
+('WoW','enGB',15595),
+('WoW','enUS',12340),
+('WoW','enUS',15595),
+('WoW','Win',12340),
+('WoW','Win',15595),
+('WoW','Wn64',15595);
+/*!40000 ALTER TABLE `battlenet_components` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `battlenet_modules`
+--
+
+DROP TABLE IF EXISTS `battlenet_modules`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `battlenet_modules` (
+ `Hash` varchar(64) NOT NULL,
+ `Name` varchar(64) NOT NULL DEFAULT '',
+ `Type` varchar(8) NOT NULL,
+ `System` varchar(8) NOT NULL,
+ `Data` text,
+ PRIMARY KEY (`Hash`),
+ UNIQUE KEY `uk_name_type_system` (`Name`,`Type`,`System`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `battlenet_modules`
+--
+
+LOCK TABLES `battlenet_modules` WRITE;
+/*!40000 ALTER TABLE `battlenet_modules` DISABLE KEYS */;
+INSERT INTO `battlenet_modules` VALUES
+('19c91b68752b7826df498bf73aca1103c86962a9a55a0a7033e5ad895f4d927c','Password','auth','Mc64',NULL),
+('1af5418a448f8ad05451e3f7dbb2d9af9cb13458eea2368ebfc539476b954f1c','RiskFingerprint','auth','Mc64',NULL),
+('207640724f4531d3b2a21532224d1486e8c4d2d805170381cbc3093264157960','SelectGameAccount','auth','Mac',NULL),
+('2e6d53adab37a41542b38e01f62cd365eab8805ed0de73c307cc6d9d1dfe478c','Password','auth','Win',NULL),
+('36b27cd911b33c61730a8b82c8b2495fd16e8024fc3b2dde08861c77a852941c','Thumbprint','auth','Win','E716F4F0A01EB9C032A6C1393356A4F766F067949D71023C0CFC0613718966EF814E65CC6EE70C432A7F8AFD8A062B52603A2697E851D231D72C0277614181D713369B1E8E4BEEAB72045A9AAD45F319DB918ECDDB83C8EF8B7510600D391D45E7FEC0BEEAE904A5F9FA620F1CCDAD699D84A4739CE669B5A551831E396214E13B4C88F573F5CDC784CD01530C086B674C03BEB66403A0F87ED17ABBB403DE54CF31BE828A20C566C22E4D4263AA77220B0644D99245345BCAC276EA06925EB984D664725C3CB757140AFE12E27CB996F17159B1057E9B58B78BBB5A139C9FF6215A0D250B75FC9DD435655DDEADCD6CFD84800792C146B3633188ECEB53D2038C185E0BD51A9E6C70FD38ADF530F8DF50FB62053C5E894897AB7DD65C7AC80665F18E7989BE6E30F15E939751123D6D8A44F033175301D15AAAD2AEA06FAC60BA4065846AE938F32B1CB15F16DC0E76792A7332346896048065D17C059899E1D2300E402BD0EA74265DA6A42B1C854E2470D7B21AE4A2DAE90E602A759B2CA0EE610B50D5389DB89335D5451FE76DD85B09FD5297D6F9EFB6C34CE885007F7DF20D6A524E0C3E772FA04B3DD2E014D3A337A790943DAD523CBB5453F4FDF8E74DFE361BD5F25AB31952B478148B570DF5762643F32B994FEC99A747E4A265A66EE84A53509EC285C84679606049314FC526C61B537AC8061C788F8B86F52208'),
+('393ca8d75aff6f04f79532cf95a88b91e5743bc59121520ac31fc4508019fe60','Token','auth','Mac',NULL),
+('3c2f63e5949aa6fd6cf330b109ca5b9adcd215beac846b7462ed3aa01d5ad6bb','Password','auth','Mac',NULL),
+('52e2978db6468dfade7c61da89513f443c9225692b5085fbe956749870993703','SelectGameAccount','auth','Mc64',NULL),
+('548b5ef9e0dd5c2f89f59c3e0979249b27505c51f0c77d2b27133726eaee0ad0','Thumbprint','auth','Mac','E716F4F0A01EB9C032A6C1393356A4F766F067949D71023C0CFC0613718966EF814E65CC6EE70C432A7F8AFD8A062B52603A2697E851D231D72C0277614181D713369B1E8E4BEEAB72045A9AAD45F319DB918ECDDB83C8EF8B7510600D391D45E7FEC0BEEAE904A5F9FA620F1CCDAD699D84A4739CE669B5A551831E396214E13B4C88F573F5CDC784CD01530C086B674C03BEB66403A0F87ED17ABBB403DE54CF31BE828A20C566C22E4D4263AA77220B0644D99245345BCAC276EA06925EB984D664725C3CB757140AFE12E27CB996F17159B1057E9B58B78BBB5A139C9FF6215A0D250B75FC9DD435655DDEADCD6CFD84800792C146B3633188ECEB53D2038C185E0BD51A9E6C70FD38ADF530F8DF50FB62053C5E894897AB7DD65C7AC80665F18E7989BE6E30F15E939751123D6D8A44F033175301D15AAAD2AEA06FAC60BA4065846AE938F32B1CB15F16DC0E76792A7332346896048065D17C059899E1D2300E402BD0EA74265DA6A42B1C854E2470D7B21AE4A2DAE90E602A759B2CA0EE610B50D5389DB89335D5451FE76DD85B09FD5297D6F9EFB6C34CE885007F7DF20D6A524E0C3E772FA04B3DD2E014D3A337A790943DAD523CBB5453F4FDF8E74DFE361BD5F25AB31952B478148B570DF5762643F32B994FEC99A747E4A265A66EE84A53509EC285C84679606049314FC526C61B537AC8061C788F8B86F52208'),
+('5e298e530698af905e1247e51ef0b109b352ac310ce7802a1f63613db980ed17','RiskFingerprint','auth','Win',NULL),
+('851c1d2ef926e9b9a345a460874e65517195129b9e3bdec7cc77710fa0b1fad6','Password','auth','Wn64',NULL),
+('894d25d3219d97d085ea5a8b98e66df5bd9f460ec6f104455246a12b8921409d','SelectGameAccount','auth','Wn64',NULL),
+('8c43bda10be33a32abbc09fb2279126c7f5953336391276cff588565332fcd40','RiskFingerprint','auth','Wn64',NULL),
+('a1edab845d9e13e9c84531369be2f61b930a37c8e7a9c66d11ef8963380e178a','Token','auth','Mc64',NULL),
+('a330f388b6687f8a42fe8fbb592a3df724b20b65fb0989342bb8261f2f452318','Token','auth','Wn64',NULL),
+('abc6bb719a73ec1055296001910e26afa561f701ad9995b1ecd7f55f9d3ca37c','SelectGameAccount','auth','Win',NULL),
+('b37136b39add83cfdbafa81857de3dd8f15b34e0135ec6cd9c3131d3a578d8c2','Thumbprint','auth','Mc64','E716F4F0A01EB9C032A6C1393356A4F766F067949D71023C0CFC0613718966EF814E65CC6EE70C432A7F8AFD8A062B52603A2697E851D231D72C0277614181D713369B1E8E4BEEAB72045A9AAD45F319DB918ECDDB83C8EF8B7510600D391D45E7FEC0BEEAE904A5F9FA620F1CCDAD699D84A4739CE669B5A551831E396214E13B4C88F573F5CDC784CD01530C086B674C03BEB66403A0F87ED17ABBB403DE54CF31BE828A20C566C22E4D4263AA77220B0644D99245345BCAC276EA06925EB984D664725C3CB757140AFE12E27CB996F17159B1057E9B58B78BBB5A139C9FF6215A0D250B75FC9DD435655DDEADCD6CFD84800792C146B3633188ECEB53D2038C185E0BD51A9E6C70FD38ADF530F8DF50FB62053C5E894897AB7DD65C7AC80665F18E7989BE6E30F15E939751123D6D8A44F033175301D15AAAD2AEA06FAC60BA4065846AE938F32B1CB15F16DC0E76792A7332346896048065D17C059899E1D2300E402BD0EA74265DA6A42B1C854E2470D7B21AE4A2DAE90E602A759B2CA0EE610B50D5389DB89335D5451FE76DD85B09FD5297D6F9EFB6C34CE885007F7DF20D6A524E0C3E772FA04B3DD2E014D3A337A790943DAD523CBB5453F4FDF8E74DFE361BD5F25AB31952B478148B570DF5762643F32B994FEC99A747E4A265A66EE84A53509EC285C84679606049314FC526C61B537AC8061C788F8B86F52208'),
+('c0f38d05aa1b83065e839c9bd96c831e9f7e42477085138752657a6a9bb9c520','RiskFingerprint','auth','Mac',NULL),
+('c3a1ac0694979e709c3b5486927e558af1e2be02ca96e5615c5a65aacc829226','Thumbprint','auth','Wn64','E716F4F0A01EB9C032A6C1393356A4F766F067949D71023C0CFC0613718966EF814E65CC6EE70C432A7F8AFD8A062B52603A2697E851D231D72C0277614181D713369B1E8E4BEEAB72045A9AAD45F319DB918ECDDB83C8EF8B7510600D391D45E7FEC0BEEAE904A5F9FA620F1CCDAD699D84A4739CE669B5A551831E396214E13B4C88F573F5CDC784CD01530C086B674C03BEB66403A0F87ED17ABBB403DE54CF31BE828A20C566C22E4D4263AA77220B0644D99245345BCAC276EA06925EB984D664725C3CB757140AFE12E27CB996F17159B1057E9B58B78BBB5A139C9FF6215A0D250B75FC9DD435655DDEADCD6CFD84800792C146B3633188ECEB53D2038C185E0BD51A9E6C70FD38ADF530F8DF50FB62053C5E894897AB7DD65C7AC80665F18E7989BE6E30F15E939751123D6D8A44F033175301D15AAAD2AEA06FAC60BA4065846AE938F32B1CB15F16DC0E76792A7332346896048065D17C059899E1D2300E402BD0EA74265DA6A42B1C854E2470D7B21AE4A2DAE90E602A759B2CA0EE610B50D5389DB89335D5451FE76DD85B09FD5297D6F9EFB6C34CE885007F7DF20D6A524E0C3E772FA04B3DD2E014D3A337A790943DAD523CBB5453F4FDF8E74DFE361BD5F25AB31952B478148B570DF5762643F32B994FEC99A747E4A265A66EE84A53509EC285C84679606049314FC526C61B537AC8061C788F8B86F52208'),
+('fbe675a99fb5f4b7fb3eb5e5a22add91a4cabf83e3c5930c6659ad13c457ba18','Token','auth','Win',NULL);
+/*!40000 ALTER TABLE `battlenet_modules` ENABLE KEYS */;
+UNLOCK TABLES;
+
diff --git a/sql/updates/auth/2014_06_01_00_auth_battlenet_434.sql b/sql/updates/auth/2014_06_01_00_auth_battlenet_434.sql
new file mode 100644
index 00000000000..ee88c91b323
--- /dev/null
+++ b/sql/updates/auth/2014_06_01_00_auth_battlenet_434.sql
@@ -0,0 +1,8 @@
+ALTER TABLE `battlenet_accounts` ADD `sessionKey` VARCHAR(128) NOT NULL DEFAULT '' AFTER `s`;
+
+DELETE FROM `battlenet_modules` WHERE `Name`='Resume';
+INSERT INTO `battlenet_modules` VALUES
+('bfe4ceb47700aa872e815e007e27df955d4cd4bc1fe731039ee6498ce209f368','Resume','auth','Win',NULL),
+('00ffd88a437afbb88d7d4b74be2e3b43601605ee229151aa9f4bebb29ef66280','Resume','auth','Mac',NULL),
+('898166926805f897804bdbbf40662c9d768590a51a0b26c40dbcdf332ba11974','Resume','auth','Wn64',NULL),
+('304627d437c38500c0b5ca0c6220eeade91390e52a2b005ff3f7754afa1f93cd','Resume','auth','Mc64',NULL);
diff --git a/sql/updates/auth/2014_06_08_00_auth_account_434.sql b/sql/updates/auth/2014_06_08_00_auth_account_434.sql
new file mode 100644
index 00000000000..bc57136dc07
--- /dev/null
+++ b/sql/updates/auth/2014_06_08_00_auth_account_434.sql
@@ -0,0 +1,3 @@
+ALTER TABLE `account`
+ ADD `battlenet_index` tinyint(3) unsigned DEFAULT NULL AFTER `battlenet_account`,
+ ADD UNIQUE KEY `uk_bnet_acc` (`battlenet_account`, `battlenet_index`);
diff --git a/sql/updates/auth/2014_06_08_01_auth_account_434.sql b/sql/updates/auth/2014_06_08_01_auth_account_434.sql
new file mode 100644
index 00000000000..dc05a98d17b
--- /dev/null
+++ b/sql/updates/auth/2014_06_08_01_auth_account_434.sql
@@ -0,0 +1,3 @@
+DELETE FROM `battlenet_components` WHERE `Program`='WoW' AND `Build`=12340;
+DELETE FROM `battlenet_components` WHERE `Program`='Tool' AND `Build`=1569;
+DELETE FROM `battlenet_components` WHERE `Program`='Bnet' AND `Build`=21719;
diff --git a/src/server/authserver/Authentication/AuthCodes.cpp b/src/server/authserver/Authentication/AuthCodes.cpp
index 55517884b8e..44921f6a1cd 100644
--- a/src/server/authserver/Authentication/AuthCodes.cpp
+++ b/src/server/authserver/Authentication/AuthCodes.cpp
@@ -79,4 +79,9 @@ namespace AuthHelper
return NULL;
}
+
+ bool IsBuildSupportingBattlenet(int build)
+ {
+ return build >= 15595;
+ }
}
diff --git a/src/server/authserver/Authentication/AuthCodes.h b/src/server/authserver/Authentication/AuthCodes.h
index 97b4779da0e..eb9f443f624 100644
--- a/src/server/authserver/Authentication/AuthCodes.h
+++ b/src/server/authserver/Authentication/AuthCodes.h
@@ -70,6 +70,96 @@ enum LoginResult
LOGIN_LOCKED_ENFORCED = 0x10
};
+enum GameAccountFlags
+{
+ GAMEACCOUNT_FLAG_GM = 0x00000001,
+ GAMEACCOUNT_FLAG_NOKICK = 0x00000002,
+ GAMEACCOUNT_FLAG_COLLECTOR = 0x00000004,
+ GAMEACCOUNT_FLAG_WOW_TRIAL = 0x00000008,
+ GAMEACCOUNT_FLAG_CANCELLED = 0x00000010,
+ GAMEACCOUNT_FLAG_IGR = 0x00000020,
+ GAMEACCOUNT_FLAG_WHOLESALER = 0x00000040,
+ GAMEACCOUNT_FLAG_PRIVILEGED = 0x00000080,
+ GAMEACCOUNT_FLAG_EU_FORBID_ELV = 0x00000100,
+ GAMEACCOUNT_FLAG_EU_FORBID_BILLING = 0x00000200,
+ GAMEACCOUNT_FLAG_WOW_RESTRICTED = 0x00000400,
+ GAMEACCOUNT_FLAG_REFERRAL = 0x00000800,
+ GAMEACCOUNT_FLAG_BLIZZARD = 0x00001000,
+ GAMEACCOUNT_FLAG_RECURRING_BILLING = 0x00002000,
+ GAMEACCOUNT_FLAG_NOELECTUP = 0x00004000,
+ GAMEACCOUNT_FLAG_KR_CERTIFICATE = 0x00008000,
+ GAMEACCOUNT_FLAG_EXPANSION_COLLECTOR = 0x00010000,
+ GAMEACCOUNT_FLAG_DISABLE_VOICE = 0x00020000,
+ GAMEACCOUNT_FLAG_DISABLE_VOICE_SPEAK = 0x00040000,
+ GAMEACCOUNT_FLAG_REFERRAL_RESURRECT = 0x00080000,
+ GAMEACCOUNT_FLAG_EU_FORBID_CC = 0x00100000,
+ GAMEACCOUNT_FLAG_OPENBETA_DELL = 0x00200000,
+ GAMEACCOUNT_FLAG_PROPASS = 0x00400000,
+ GAMEACCOUNT_FLAG_PROPASS_LOCK = 0x00800000,
+ GAMEACCOUNT_FLAG_PENDING_UPGRADE = 0x01000000,
+ GAMEACCOUNT_FLAG_RETAIL_FROM_TRIAL = 0x02000000,
+ GAMEACCOUNT_FLAG_EXPANSION2_COLLECTOR = 0x04000000,
+ GAMEACCOUNT_FLAG_OVERMIND_LINKED = 0x08000000,
+ GAMEACCOUNT_FLAG_DEMOS = 0x10000000,
+ GAMEACCOUNT_FLAG_DEATH_KNIGHT_OK = 0x20000000,
+};
+
+namespace Battlenet
+{
+ enum AuthResult
+ {
+ AUTH_OK = 0,
+ AUTH_INTERNAL_ERROR = 100,
+ AUTH_CORRUPTED_MODULE = 102,
+ AUTH_BAD_SERVER_PROOF = 103,
+ AUTH_UNKNOWN_ACCOUNT = 104,
+ AUTH_CLOSED = 105,
+ AUTH_LOGIN_TIMEOUT = 106,
+ AUTH_NO_GAME_ACCOUNTS = 107,
+ AUTH_INVALID_TOKEN = 108,
+ AUTH_INVALID_PROGRAM = 109,
+ AUTH_INVALID_OS = 110,
+ AUTH_UNSUPPORTED_LANGUAGE = 111,
+ AUTH_REGION_BAD_VERSION = 112,
+ AUTH_TEMP_OUTAGE = 113,
+ AUTH_CANT_DOWNLOAD_MODULE = 114,
+ AUTH_DUPLICATE_LOGON = 115,
+ AUTH_BAD_CREDENTIALS_2 = 116,
+ AUTH_VERSION_CHECK_SUCCEEDED = 117,
+ AUTH_BAD_VERSION_HASH = 118,
+ AUTH_CANT_RETRIEVE_PORTAL_LIST = 119,
+ AUTH_DARK_PORTAL_DOES_NOT_EXIST = 120,
+ AUTH_DARK_PORTAL_FILE_CORRUPTED = 121,
+ AUTH_BATTLENET_MAINTENANCE = 122,
+ AUTH_LOGON_TOO_FAST = 123,
+ AUTH_USE_GRUNT_LOGON = 124,
+ AUTH_NO_GAME_ACCOUNTS_IN_REGION = 140,
+ AUTH_ACCOUNT_LOCKED = 141,
+
+ LOGIN_SERVER_BUSY = 200,
+ LOGIN_NO_GAME_ACCOUNT = 201,
+ LOGIN_BANNED = 202,
+ LOGIN_SUSPENDED = 203,
+ LOGIN_GAME_ACCOUNT_LOCKED = 204,
+ LOGIN_ALREADY_ONLINE = 205,
+ LOGIN_NOTIME = 206,
+ LOGIN_EXPIRED = 207,
+ LOGIN_EXPIRED_2 = 208,
+ LOGIN_PARENTALCONTROL = 209,
+ LOGIN_TRIAL_EXPIRED = 210,
+ LOGIN_ANTI_INDULGENCE = 211,
+ LOGIN_INCORRECT_REGION = 212,
+ LOGIN_LOCKED_ENFORCED = 213,
+ LOGIN_CHARGEBACK = 214,
+ LOGIN_IGR_WITHOUT_BNET = 215,
+ LOGIN_UNLOCKABLE_LOCK = 216,
+ LOGIN_IGR_REQUIRED = 217,
+ LOGIN_PAYMENT_CHANGED = 218,
+ LOGIN_INVALID_PAYMENT = 219,
+ LOGIN_INVALID_ACCOUNT_STATE = 220
+ };
+}
+
enum ExpansionFlags
{
POST_BC_EXP_FLAG = 0x2,
@@ -92,6 +182,7 @@ namespace AuthHelper
bool IsAcceptedClientBuild(int build);
bool IsPostBCAcceptedClientBuild(int build);
bool IsPreBCAcceptedClientBuild(int build);
+ bool IsBuildSupportingBattlenet(int build);
}
#endif
diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp
index be6623c7fa3..be2e6a11d4f 100644
--- a/src/server/authserver/Main.cpp
+++ b/src/server/authserver/Main.cpp
@@ -151,7 +151,8 @@ extern int main(int argc, char** argv)
}
// Launch the listening network socket
- RealmAcceptor acceptor;
+ RealmAcceptor acceptor;
+ RealmAcceptor bnetacceptor;
int32 rmport = sConfigMgr->GetIntDefault("RealmServerPort", 3724);
if (rmport < 0 || rmport > 0xFFFF)
@@ -170,6 +171,13 @@ extern int main(int argc, char** argv)
return 1;
}
+ bind_addr.set_port_number(1119);
+ if (bnetacceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1)
+ {
+ TC_LOG_ERROR("server.authserver", "Auth server can not bind to %s:%d", bind_ip.c_str(), 1119);
+ return 1;
+ }
+
// Initialize the signal handlers
AuthServerSignalHandler SignalINT, SignalTERM;
@@ -246,6 +254,8 @@ extern int main(int argc, char** argv)
#endif
#endif
+ sBattlenetMgr->Load();
+
// maximum counter for next ping
uint32 numLoops = (sConfigMgr->GetIntDefault("MaxPingTime", 30) * (MINUTE * 1000000 / 100000));
uint32 loopCounter = 0;
diff --git a/src/server/authserver/Realms/RealmList.cpp b/src/server/authserver/Realms/RealmList.cpp
index 4aeecfc0aaa..48b7a178c2d 100644
--- a/src/server/authserver/Realms/RealmList.cpp
+++ b/src/server/authserver/Realms/RealmList.cpp
@@ -18,9 +18,29 @@
#include "Common.h"
#include "RealmList.h"
+#include "BattlenetManager.h"
#include "Database/DatabaseEnv.h"
+#include "Util.h"
-RealmList::RealmList() : m_UpdateInterval(0), m_NextUpdateTime(time(NULL)) { }
+ACE_INET_Addr const& Realm::GetAddressForClient(ACE_INET_Addr const& clientAddr) const
+{
+ // Attempt to send best address for client
+ if (clientAddr.is_loopback())
+ // Assume that user connecting from the machine that authserver is located on
+ // has all realms available in his local network
+ return LocalAddress;
+
+ // Check if connecting client is in the same network
+ if (IsIPAddrInNetwork(LocalAddress, clientAddr, LocalSubnetMask))
+ return LocalAddress;
+
+ // Return external IP
+ return ExternalAddress;
+}
+
+RealmList::RealmList() : m_UpdateInterval(0), m_NextUpdateTime(time(NULL))
+{
+}
// Load the realm list from the database
void RealmList::Initialize(uint32 updateInterval)
@@ -31,7 +51,7 @@ void RealmList::Initialize(uint32 updateInterval)
UpdateRealms(true);
}
-void RealmList::UpdateRealm(uint32 id, const std::string& name, ACE_INET_Addr const& address, ACE_INET_Addr const& localAddr, ACE_INET_Addr const& localSubmask, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build)
+void RealmList::UpdateRealm(uint32 id, const std::string& name, ACE_INET_Addr const& address, ACE_INET_Addr const& localAddr, ACE_INET_Addr const& localSubmask, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build, uint8 region, uint8 battlegroup)
{
// Create new if not exist or update existed
Realm& realm = m_realms[name];
@@ -49,6 +69,8 @@ void RealmList::UpdateRealm(uint32 id, const std::string& name, ACE_INET_Addr co
realm.LocalAddress = localAddr;
realm.LocalSubnetMask = localSubmask;
realm.gamebuild = build;
+ realm.Region = region;
+ realm.Battlegroup = battlegroup;
}
void RealmList::UpdateIfNeed()
@@ -91,12 +113,14 @@ void RealmList::UpdateRealms(bool init)
uint8 allowedSecurityLevel = fields[9].GetUInt8();
float pop = fields[10].GetFloat();
uint32 build = fields[11].GetUInt32();
+ uint8 region = fields[12].GetUInt8();
+ uint8 battlegroup = fields[13].GetUInt8();
ACE_INET_Addr externalAddr(port, externalAddress.c_str(), AF_INET);
ACE_INET_Addr localAddr(port, localAddress.c_str(), AF_INET);
ACE_INET_Addr submask(0, localSubmask.c_str(), AF_INET);
- UpdateRealm(realmId, name, externalAddr, localAddr, submask, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build);
+ UpdateRealm(realmId, name, externalAddr, localAddr, submask, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build, region, battlegroup);
if (init)
TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), m_realms[name].ExternalAddress.get_host_addr(), port);
@@ -104,3 +128,16 @@ void RealmList::UpdateRealms(bool init)
while (result->NextRow());
}
}
+
+Realm const* RealmList::GetRealm(Battlenet::RealmId const& id) const
+{
+ auto itr = std::find_if(m_realms.begin(), m_realms.end(), [id](RealmMap::value_type const& pair)
+ {
+ return pair.second.Region == id.Region && pair.second.Battlegroup == id.Battlegroup && pair.second.m_ID == id.Index;
+ });
+
+ if (itr != m_realms.end())
+ return &itr->second;
+
+ return NULL;
+}
diff --git a/src/server/authserver/Realms/RealmList.h b/src/server/authserver/Realms/RealmList.h
index 1d76c39e4f0..c4a6b4eaa0b 100644
--- a/src/server/authserver/Realms/RealmList.h
+++ b/src/server/authserver/Realms/RealmList.h
@@ -51,8 +51,17 @@ struct Realm
AccountTypes allowedSecurityLevel;
float populationLevel;
uint32 gamebuild;
+ uint8 Region;
+ uint8 Battlegroup;
+
+ ACE_INET_Addr const& GetAddressForClient(ACE_INET_Addr const& clientAddr) const;
};
+namespace Battlenet
+{
+ struct RealmId;
+}
+
/// Storage object for the list of realms on the server
class RealmList
{
@@ -71,10 +80,11 @@ public:
RealmMap::const_iterator begin() const { return m_realms.begin(); }
RealmMap::const_iterator end() const { return m_realms.end(); }
uint32 size() const { return m_realms.size(); }
+ Realm const* GetRealm(Battlenet::RealmId const& id) const;
private:
void UpdateRealms(bool init=false);
- void UpdateRealm(uint32 id, const std::string& name, ACE_INET_Addr const& address, ACE_INET_Addr const& localAddr, ACE_INET_Addr const& localSubmask, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build);
+ void UpdateRealm(uint32 id, const std::string& name, ACE_INET_Addr const& address, ACE_INET_Addr const& localAddr, ACE_INET_Addr const& localSubmask, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build, uint8 region, uint8 battlegroup);
RealmMap m_realms;
uint32 m_UpdateInterval;
diff --git a/src/server/authserver/Server/AuthSocket.cpp b/src/server/authserver/Server/AuthSocket.cpp
index c7bb600024a..7ca49b03b56 100644
--- a/src/server/authserver/Server/AuthSocket.cpp
+++ b/src/server/authserver/Server/AuthSocket.cpp
@@ -293,19 +293,11 @@ void AuthSocket::_SetVSFields(const std::string& rI)
x.SetBinary(sha.GetDigest(), sha.GetLength());
v = g.ModExp(x, N);
- // No SQL injection (username escaped)
- char *v_hex, *s_hex;
- v_hex = v.AsHexStr();
- s_hex = s.AsHexStr();
-
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_VS);
- stmt->setString(0, v_hex);
- stmt->setString(1, s_hex);
+ stmt->setString(0, v.AsHexStr());
+ stmt->setString(1, s.AsHexStr());
stmt->setString(2, _login);
LoginDatabase.Execute(stmt);
-
- OPENSSL_free(v_hex);
- OPENSSL_free(s_hex);
}
// Logon Challenge command handler
@@ -488,7 +480,9 @@ bool AuthSocket::_HandleLogonChallenge()
unk3.SetRand(16 * 8);
// Fill the response packet with the result
- if (AuthHelper::IsAcceptedClientBuild(_build))
+ if (fields[9].GetUInt32() && AuthHelper::IsBuildSupportingBattlenet(_build))
+ pkt << uint8(WOW_FAIL_USE_BATTLENET);
+ else if (AuthHelper::IsAcceptedClientBuild(_build))
pkt << uint8(WOW_SUCCESS);
else
pkt << uint8(WOW_FAIL_VERSION_INVALID);
@@ -650,19 +644,14 @@ bool AuthSocket::_HandleLogonProof()
TC_LOG_DEBUG("server.authserver", "'%s:%d' User '%s' successfully authenticated", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str());
// Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account
- // No SQL injection (escaped user name) and IP address as received by socket
- const char *K_hex = K.AsHexStr();
-
PreparedStatement *stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LOGONPROOF);
- stmt->setString(0, K_hex);
+ stmt->setString(0, K.AsHexStr());
stmt->setString(1, socket().getRemoteAddress().c_str());
stmt->setUInt32(2, GetLocaleByName(_localizationName));
stmt->setString(3, _os);
stmt->setString(4, _login);
LoginDatabase.DirectExecute(stmt);
- OPENSSL_free((void*)K_hex);
-
// Finish SRP6 and send the final result to the client
sha.Initialize();
sha.UpdateBigNumbers(&A, &M, &K, NULL);
@@ -693,7 +682,7 @@ bool AuthSocket::_HandleLogonProof()
memcpy(proof.M2, sha.GetDigest(), 20);
proof.cmd = AUTH_LOGON_PROOF;
proof.error = 0;
- proof.unk1 = 0x00800000; // Accountflags. 0x01 = GM, 0x08 = Trial, 0x00800000 = Pro pass (arena tournament)
+ proof.unk1 = GAMEACCOUNT_FLAG_PROPASS_LOCK;
proof.unk2 = 0x00; // SurveyId
proof.unk3 = 0x00;
socket().send((char *)&proof, sizeof(proof));
@@ -879,28 +868,6 @@ bool AuthSocket::_HandleReconnectProof()
}
}
-ACE_INET_Addr const& AuthSocket::GetAddressForClient(Realm const& realm, ACE_INET_Addr const& clientAddr)
-{
- // Attempt to send best address for client
- if (clientAddr.is_loopback())
- {
- // Try guessing if realm is also connected locally
- if (realm.LocalAddress.is_loopback() || realm.ExternalAddress.is_loopback())
- return clientAddr;
-
- // Assume that user connecting from the machine that authserver is located on
- // has all realms available in his local network
- return realm.LocalAddress;
- }
-
- // Check if connecting client is in the same network
- if (IsIPAddrInNetwork(realm.LocalAddress, clientAddr, realm.LocalSubnetMask))
- return realm.LocalAddress;
-
- // Return external IP
- return realm.ExternalAddress;
-}
-
// Realm List command handler
bool AuthSocket::_HandleRealmList()
{
@@ -981,12 +948,12 @@ bool AuthSocket::_HandleRealmList()
pkt << lock; // if 1, then realm locked
pkt << uint8(flag); // RealmFlags
pkt << name;
- pkt << GetAddressString(GetAddressForClient(realm, clientAddr));
+ pkt << GetAddressString(realm.GetAddressForClient(clientAddr));
pkt << realm.populationLevel;
pkt << AmountOfCharacters;
pkt << realm.timezone; // realm category
if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients
- pkt << uint8(0x2C); // unk, may be realm number/id?
+ pkt << uint8(realm.m_ID);
else
pkt << uint8(0x0); // 1.12.1 and 1.12.2 clients
diff --git a/src/server/authserver/Server/AuthSocket.h b/src/server/authserver/Server/AuthSocket.h
index 5e04d459ba1..e81944389ef 100644
--- a/src/server/authserver/Server/AuthSocket.h
+++ b/src/server/authserver/Server/AuthSocket.h
@@ -39,8 +39,6 @@ public:
virtual void OnAccept(void);
virtual void OnClose(void);
- static ACE_INET_Addr const& GetAddressForClient(Realm const& realm, ACE_INET_Addr const& clientAddr);
-
bool _HandleLogonChallenge();
bool _HandleLogonProof();
bool _HandleReconnectChallenge();
diff --git a/src/server/authserver/Server/BattlenetBitStream.h b/src/server/authserver/Server/BattlenetBitStream.h
new file mode 100644
index 00000000000..a59150f5327
--- /dev/null
+++ b/src/server/authserver/Server/BattlenetBitStream.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+
+#ifndef __BATTLENETBITSTREAM_H__
+#define __BATTLENETBITSTREAM_H__
+
+#include "ByteConverter.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace Battlenet
+{
+ class BitStreamPositionException : public std::exception
+ {
+ public:
+ BitStreamPositionException() : st(1) { }
+
+ char const* what() const
+ {
+ return st.c_str();
+ }
+
+ ACE_Stack_Trace st;
+ };
+
+ class BitStream
+ {
+ public:
+ static uint32 const MaxSize = 0x1000;
+
+ // length : The maximum number of bytes to read
+ BitStream(uint32 length) : _numBits(length * 8), _readPos(0), _writePos(0)
+ {
+ _buffer.resize(length, 0);
+ }
+
+ BitStream() : _numBits(0), _readPos(0), _writePos(0)
+ {
+ _buffer.reserve(0x1000);
+ }
+
+ void AlignToNextByte()
+ {
+ _readPos = (_readPos + 7) & ~7;
+ _writePos = (_writePos + 7) & ~7;
+ }
+
+ std::string ReadString(uint32 bitCount, int32 baseLength = 0)
+ {
+ uint32 len = Read(bitCount) + baseLength;
+ AlignToNextByte();
+ std::string str(reinterpret_cast(&_buffer[_readPos >> 3]), len);
+ _readPos += len * 8;
+ return str;
+ }
+
+ ACE_Auto_Array_Ptr ReadBytes(uint32 count)
+ {
+ AlignToNextByte();
+ if (_readPos + count * 8 > _numBits)
+ throw BitStreamPositionException();
+
+ ACE_Auto_Array_Ptr buf(new uint8[count]);
+ memcpy(buf.get(), &_buffer[_readPos >> 3], count);
+ _readPos += count * 8;
+ return buf;
+ }
+
+ float ReadFloat()
+ {
+ uint32 val = Read(32);
+ return *reinterpret_cast(&val);
+ }
+
+ std::string ReadFourCC()
+ {
+ uint32 fcc = Read(32);
+ EndianConvertReverse(fcc);
+ size_t len = 4;
+ while (!(fcc & 0xFF))
+ {
+ fcc >>= 8;
+ --len;
+ }
+
+ return std::string(reinterpret_cast(&fcc), len);
+ }
+
+ template
+ T Read(uint32 bitCount)
+ {
+ static_assert(std::is_integral::value || std::is_enum::value, "T must be an integer type");
+
+ uint64 ret = 0;
+ while (bitCount != 0)
+ {
+ uint32 bitPos = (_readPos & 7);
+ uint32 bitsLeftInByte = 8 - bitPos;
+ if (bitsLeftInByte >= bitCount)
+ bitsLeftInByte = bitCount;
+
+ bitCount -= bitsLeftInByte;
+ ret |= (uint64)(_buffer[_readPos >> 3] >> bitPos & (uint32)((uint8)(1 << bitsLeftInByte) - 1)) << bitCount;
+ _readPos += bitsLeftInByte;
+ }
+
+ return static_cast(ret);
+ }
+
+ void WriteString(std::string const& str, uint32 bitCount, int32 baseLength = 0)
+ {
+ Write(str.length() + baseLength, bitCount);
+ WriteBytes(str.c_str(), str.length());
+ }
+
+ template
+ void WriteBytes(T* data, uint32 count)
+ {
+ AlignToNextByte();
+ if (!count || !data)
+ return;
+
+ if ((_writePos >> 3) + count > MaxSize)
+ throw BitStreamPositionException();
+
+ _buffer.resize(_buffer.size() + count);
+ memcpy(&_buffer[_writePos >> 3], data, count);
+ _writePos += count * 8;
+ }
+
+ void WriteFloat(float value)
+ {
+ uint32 intVal = *reinterpret_cast(&value);
+ Write(intVal, 32);
+ }
+
+ void WriteFourCC(std::string const& fcc)
+ {
+ uint32 intVal = *(uint32*)fcc.c_str();
+ size_t len = fcc.length();
+ EndianConvertReverse(intVal);
+ // Add padding
+ while (len++ < 4)
+ intVal >>= 8;
+
+ Write(intVal, 32);
+ }
+
+ template
+ void Write(T value, uint32 bitCount)
+ {
+ static_assert(std::is_integral::value || std::is_enum::value, "T must be an integer type");
+
+ if (_writePos + bitCount >= 8 * MaxSize)
+ throw BitStreamPositionException();
+
+ while (bitCount != 0)
+ {
+ uint32 bitPos = (_writePos & 7);
+ uint32 bitsLeftInByte = 8 - bitPos;
+ if (bitsLeftInByte >= bitCount)
+ bitsLeftInByte = bitCount;
+
+ bitCount -= bitsLeftInByte;
+
+ uint8 firstHalf = (uint8)(~(((uint8)(1 << bitsLeftInByte) - 1) << bitPos));
+ uint8 secondHalf = (uint8)((((uint8)(1 << bitsLeftInByte) - 1) & (uint8)(value >> bitCount)) << bitPos);
+
+ if (_buffer.size() > (_writePos >> 3))
+ _buffer[_writePos >> 3] = (uint8)(_buffer[_writePos >> 3] & firstHalf | secondHalf);
+ else
+ _buffer.push_back(secondHalf);
+
+ _writePos += bitsLeftInByte;
+ }
+ }
+
+ void SetReadPos(uint32 bits)
+ {
+ if (bits >= _numBits)
+ throw BitStreamPositionException();
+
+ _readPos = bits;
+ }
+
+ bool IsRead() const { return _readPos >= _numBits; }
+
+ uint8* GetBuffer() { return _buffer.data(); }
+
+ size_t GetSize() const { return _buffer.size(); }
+
+ void FinishReading() { _readPos = _numBits; }
+
+ private:
+ std::vector _buffer;
+ uint32 _numBits;
+ uint32 _readPos;
+ uint32 _writePos;
+ };
+}
+
+#endif // __BATTLENETBITSTREAM_H__
diff --git a/src/server/authserver/Server/BattlenetManager.cpp b/src/server/authserver/Server/BattlenetManager.cpp
new file mode 100644
index 00000000000..f470c365b56
--- /dev/null
+++ b/src/server/authserver/Server/BattlenetManager.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+
+#include "BattlenetManager.h"
+#include "DatabaseEnv.h"
+
+BattlenetMgr::~BattlenetMgr()
+{
+ for (Battlenet::Component* component : _components)
+ delete component;
+
+ for (auto const& m : _modules)
+ delete m.second;
+}
+
+void BattlenetMgr::Load()
+{
+ LoadComponents();
+ LoadModules();
+}
+
+void BattlenetMgr::LoadComponents()
+{
+ QueryResult result = LoginDatabase.Query("SELECT Program, Platform, Build FROM battlenet_components");
+ if (result)
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ Battlenet::Component* component = new Battlenet::Component();
+ component->Program = fields[0].GetString();
+ component->Platform = fields[1].GetString();
+ component->Build = fields[2].GetUInt32();
+
+ _components.insert(component);
+ _programs.insert(component->Program);
+ _platforms.insert(component->Platform);
+
+ } while (result->NextRow());
+ }
+}
+
+void BattlenetMgr::LoadModules()
+{
+ QueryResult result = LoginDatabase.Query("SELECT `Hash`, `Name`, `Type`, `System`, `Data` FROM battlenet_modules");
+ if (result)
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ Battlenet::ModuleInfo* module = new Battlenet::ModuleInfo();
+ module->Type = fields[2].GetString();
+ HexStrToByteArray(fields[0].GetString(), module->ModuleId);
+ std::string data = fields[4].GetString();
+ module->DataSize = data.length() / 2;
+ if (module->DataSize)
+ {
+ module->Data = new uint8[data.length() / 2];
+ HexStrToByteArray(data, module->Data);
+ }
+
+ _modules[{ fields[3].GetString(), fields[1].GetString() }] = module;
+ } while (result->NextRow());
+ }
+}
+
+bool BattlenetMgr::HasComponent(Battlenet::Component const* component) const
+{
+ for (Battlenet::Component const* c : _components)
+ if (component->Program == c->Program && component->Platform == c->Platform && component->Build == c->Build)
+ return true;
+
+ return false;
+}
+
+Battlenet::ModuleInfo* BattlenetMgr::CreateModule(std::string const& os, std::string const& name) const
+{
+ Battlenet::ModuleKey key { os, name };
+ ASSERT(_modules.count(key));
+
+ return new Battlenet::ModuleInfo(*_modules.at(key));
+}
diff --git a/src/server/authserver/Server/BattlenetManager.h b/src/server/authserver/Server/BattlenetManager.h
new file mode 100644
index 00000000000..3b8a145f4e9
--- /dev/null
+++ b/src/server/authserver/Server/BattlenetManager.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+
+#ifndef __BATTLENETMANAGER_H__
+#define __BATTLENETMANAGER_H__
+
+#include "Define.h"
+#include
+#include
+#include
+#include