diff --git a/FFXIVClassic Common Class Lib/FFXIVClassic Common Class Lib.csproj b/FFXIVClassic Common Class Lib/FFXIVClassic Common Class Lib.csproj index 1adbda3e..8c708e5f 100644 --- a/FFXIVClassic Common Class Lib/FFXIVClassic Common Class Lib.csproj +++ b/FFXIVClassic Common Class Lib/FFXIVClassic Common Class Lib.csproj @@ -24,6 +24,7 @@ 4 false false + true pdbonly @@ -35,6 +36,14 @@ false + + ..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll + True + + + ..\packages\NLog.4.3.5\lib\net45\NLog.dll + True + @@ -49,10 +58,12 @@ + + diff --git a/FFXIVClassic Common Class Lib/Sql.cs b/FFXIVClassic Common Class Lib/Sql.cs new file mode 100644 index 00000000..2de92bc0 --- /dev/null +++ b/FFXIVClassic Common Class Lib/Sql.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MySql.Data.MySqlClient; +using NLog; +using System.Data; +using System.Data.Common; + +namespace FFXIVClassic.Common +{ + // todo: + // havent decided whether it's worth wrapping every sql class + // so i'll just leave it with logger for now + public class Sql + { + public static Logger Log = LogManager.GetCurrentClassLogger(); + } +} diff --git a/FFXIVClassic Common Class Lib/Utils.cs b/FFXIVClassic Common Class Lib/Utils.cs index a97f2ee2..12f5f88f 100644 --- a/FFXIVClassic Common Class Lib/Utils.cs +++ b/FFXIVClassic Common Class Lib/Utils.cs @@ -1,233 +1,234 @@ -using System; -using System.Text; - -namespace FFXIVClassic.Common -{ - public static class Utils - { - private static readonly uint[] _lookup32 = CreateLookup32(); - - private static uint[] CreateLookup32() - { - var result = new uint[256]; - for (int i = 0; i < 256; i++) - { - string s = i.ToString("X2"); - result[i] = ((uint)s[0]) + ((uint)s[1] << 16); - } - return result; - } - - public static string ByteArrayToHex(byte[] bytes, int offset = 0, int bytesPerLine = 16) - { - if (bytes == null) - { - return String.Empty; - } - - char[] hexChars = "0123456789ABCDEF".ToCharArray(); - - // 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ - // 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ - int offsetBlock = 8 + 3; - int byteBlock = offsetBlock + (bytesPerLine * 3) + ((bytesPerLine - 1) / 8) + 2; - int lineLength = byteBlock + bytesPerLine + Environment.NewLine.Length; - - char[] line = (new String(' ', lineLength - Environment.NewLine.Length) + Environment.NewLine).ToCharArray(); - int numLines = (bytes.Length + bytesPerLine - 1) / bytesPerLine; - - StringBuilder sb = new StringBuilder(numLines * lineLength); - - for (int i = 0; i < bytes.Length; i += bytesPerLine) - { - int h = i + offset; - - line[0] = hexChars[(h >> 28) & 0xF]; - line[1] = hexChars[(h >> 24) & 0xF]; - line[2] = hexChars[(h >> 20) & 0xF]; - line[3] = hexChars[(h >> 16) & 0xF]; - line[4] = hexChars[(h >> 12) & 0xF]; - line[5] = hexChars[(h >> 8) & 0xF]; - line[6] = hexChars[(h >> 4) & 0xF]; - line[7] = hexChars[(h >> 0) & 0xF]; - - int hexColumn = offsetBlock; - int charColumn = byteBlock; - - for (int j = 0; j < bytesPerLine; j++) - { - if (j > 0 && (j & 7) == 0) - { - hexColumn++; - } - - if (i + j >= bytes.Length) - { - line[hexColumn] = ' '; - line[hexColumn + 1] = ' '; - line[charColumn] = ' '; - } - else - { - byte by = bytes[i + j]; - line[hexColumn] = hexChars[(by >> 4) & 0xF]; - line[hexColumn + 1] = hexChars[by & 0xF]; - line[charColumn] = (by < 32 ? '.' : (char)by); - } - - hexColumn += 3; - charColumn++; - } - - sb.Append(line); - } - - return sb.ToString(); - } - - public static UInt32 UnixTimeStampUTC() - { - UInt32 unixTimeStamp; - DateTime currentTime = DateTime.Now; - DateTime zuluTime = currentTime.ToUniversalTime(); - DateTime unixEpoch = new DateTime(1970, 1, 1); - unixTimeStamp = (UInt32)(zuluTime.Subtract(unixEpoch)).TotalSeconds; - - return unixTimeStamp; - } - - public static UInt64 MilisUnixTimeStampUTC() - { - UInt64 unixTimeStamp; - DateTime currentTime = DateTime.Now; - DateTime zuluTime = currentTime.ToUniversalTime(); - DateTime unixEpoch = new DateTime(1970, 1, 1); - unixTimeStamp = (UInt64)(zuluTime.Subtract(unixEpoch)).TotalMilliseconds; - - return unixTimeStamp; - } - - public static ulong SwapEndian(ulong input) - { - return ((0x00000000000000FF) & (input >> 56) | - (0x000000000000FF00) & (input >> 40) | - (0x0000000000FF0000) & (input >> 24) | - (0x00000000FF000000) & (input >> 8) | - (0x000000FF00000000) & (input << 8) | - (0x0000FF0000000000) & (input << 24) | - (0x00FF000000000000) & (input << 40) | - (0xFF00000000000000) & (input << 56)); - } - - public static uint SwapEndian(uint input) - { - return ((input >> 24) & 0xff) | - ((input << 8) & 0xff0000) | - ((input >> 8) & 0xff00) | - ((input << 24) & 0xff000000); - } - - public static int SwapEndian(int input) - { - uint inputAsUint = (uint)input; - - input = (int) - (((inputAsUint >> 24) & 0xff) | - ((inputAsUint << 8) & 0xff0000) | - ((inputAsUint >> 8) & 0xff00) | - ((inputAsUint << 24) & 0xff000000)); - - return input; - } - - public static uint MurmurHash2(string key, uint seed) - { - // 'm' and 'r' are mixing constants generated offline. - // They're not really 'magic', they just happen to work well. - - byte[] data = Encoding.ASCII.GetBytes(key); - const uint m = 0x5bd1e995; - const int r = 24; - int len = key.Length; - int dataIndex = len - 4; - - // Initialize the hash to a 'random' value - - uint h = seed ^ (uint)len; - - // Mix 4 bytes at a time into the hash - - - while (len >= 4) - { - h *= m; - - uint k = (uint)BitConverter.ToInt32(data, dataIndex); - k = ((k >> 24) & 0xff) | // move byte 3 to byte 0 - ((k << 8) & 0xff0000) | // move byte 1 to byte 2 - ((k >> 8) & 0xff00) | // move byte 2 to byte 1 - ((k << 24) & 0xff000000); // byte 0 to byte 3 - - k *= m; - k ^= k >> r; - k *= m; - - h ^= k; - - dataIndex -= 4; - len -= 4; - } - - // Handle the last few bytes of the input array - switch (len) - { - case 3: - h ^= (uint)data[0] << 16; goto case 2; - case 2: - h ^= (uint)data[len - 2] << 8; goto case 1; - case 1: - h ^= data[len - 1]; - h *= m; - break; - }; - - // Do a few final mixes of the hash to ensure the last few - // bytes are well-incorporated. - - h ^= h >> 13; - h *= m; - h ^= h >> 15; - - return h; - } - - public static byte[] ConvertBoolArrayToBinaryStream(bool[] array) - { - byte[] data = new byte[(array.Length / 8) + (array.Length % 8 != 0 ? 1 : 0)]; - - int dataCounter = 0; - for (int i = 0; i < array.Length; i += 8) - { - for (int bitCount = 0; bitCount < 8; bitCount++) - { - if (i + bitCount >= array.Length) - break; - data[dataCounter] = (byte)(((array[i + bitCount] ? 1 : 0) << 7 - bitCount) | data[dataCounter]); - } - dataCounter++; - } - - return data; +using System; +using System.Text; + +namespace FFXIVClassic.Common +{ + public static class Utils + { + private static readonly uint[] _lookup32 = CreateLookup32(); + + private static uint[] CreateLookup32() + { + var result = new uint[256]; + for (var i = 0; i < 256; i++) + { + var s = i.ToString("X2"); + result[i] = s[0] + ((uint) s[1] << 16); + } + return result; + } + + public static string ByteArrayToHex(byte[] bytes, int offset = 0, int bytesPerLine = 16) + { + if (bytes == null) + { + return string.Empty; + } + + var hexChars = "0123456789ABCDEF".ToCharArray(); + + var offsetBlock = 8 + 3; + var byteBlock = offsetBlock + bytesPerLine*3 + (bytesPerLine - 1)/8 + 2; + var lineLength = byteBlock + bytesPerLine + Environment.NewLine.Length; + + var line = (new string(' ', lineLength - Environment.NewLine.Length) + Environment.NewLine).ToCharArray(); + var numLines = (bytes.Length + bytesPerLine - 1)/bytesPerLine; + + var sb = new StringBuilder(numLines*lineLength); + + for (var i = 0; i < bytes.Length; i += bytesPerLine) + { + var h = i + offset; + + line[0] = hexChars[(h >> 28) & 0xF]; + line[1] = hexChars[(h >> 24) & 0xF]; + line[2] = hexChars[(h >> 20) & 0xF]; + line[3] = hexChars[(h >> 16) & 0xF]; + line[4] = hexChars[(h >> 12) & 0xF]; + line[5] = hexChars[(h >> 8) & 0xF]; + line[6] = hexChars[(h >> 4) & 0xF]; + line[7] = hexChars[(h >> 0) & 0xF]; + + var hexColumn = offsetBlock; + var charColumn = byteBlock; + + for (var j = 0; j < bytesPerLine; j++) + { + if (j > 0 && (j & 7) == 0) + { + hexColumn++; + } + + if (i + j >= bytes.Length) + { + line[hexColumn] = ' '; + line[hexColumn + 1] = ' '; + line[charColumn] = ' '; + } + else + { + var by = bytes[i + j]; + line[hexColumn] = hexChars[(by >> 4) & 0xF]; + line[hexColumn + 1] = hexChars[by & 0xF]; + line[charColumn] = by < 32 ? '.' : (char) by; + } + + hexColumn += 3; + charColumn++; + } + + sb.Append(line); + } + + return sb.ToString().TrimEnd(Environment.NewLine.ToCharArray()); + } + + public static uint UnixTimeStampUTC() + { + uint unixTimeStamp; + var currentTime = DateTime.Now; + var zuluTime = currentTime.ToUniversalTime(); + var unixEpoch = new DateTime(1970, 1, 1); + unixTimeStamp = (uint) zuluTime.Subtract(unixEpoch).TotalSeconds; + + return unixTimeStamp; + } + + public static ulong MilisUnixTimeStampUTC() + { + ulong unixTimeStamp; + var currentTime = DateTime.Now; + var zuluTime = currentTime.ToUniversalTime(); + var unixEpoch = new DateTime(1970, 1, 1); + unixTimeStamp = (ulong) zuluTime.Subtract(unixEpoch).TotalMilliseconds; + + return unixTimeStamp; + } + + public static ulong SwapEndian(ulong input) + { + return 0x00000000000000FF & (input >> 56) | + 0x000000000000FF00 & (input >> 40) | + 0x0000000000FF0000 & (input >> 24) | + 0x00000000FF000000 & (input >> 8) | + 0x000000FF00000000 & (input << 8) | + 0x0000FF0000000000 & (input << 24) | + 0x00FF000000000000 & (input << 40) | + 0xFF00000000000000 & (input << 56); + } + + public static uint SwapEndian(uint input) + { + return ((input >> 24) & 0xff) | + ((input << 8) & 0xff0000) | + ((input >> 8) & 0xff00) | + ((input << 24) & 0xff000000); + } + + public static int SwapEndian(int input) + { + var inputAsUint = (uint) input; + + input = (int) + (((inputAsUint >> 24) & 0xff) | + ((inputAsUint << 8) & 0xff0000) | + ((inputAsUint >> 8) & 0xff00) | + ((inputAsUint << 24) & 0xff000000)); + + return input; + } + + public static uint MurmurHash2(string key, uint seed) + { + // 'm' and 'r' are mixing constants generated offline. + // They're not really 'magic', they just happen to work well. + + var data = Encoding.ASCII.GetBytes(key); + const uint m = 0x5bd1e995; + const int r = 24; + var len = key.Length; + var dataIndex = len - 4; + + // Initialize the hash to a 'random' value + + var h = seed ^ (uint) len; + + // Mix 4 bytes at a time into the hash + + + while (len >= 4) + { + h *= m; + + var k = (uint) BitConverter.ToInt32(data, dataIndex); + k = ((k >> 24) & 0xff) | // move byte 3 to byte 0 + ((k << 8) & 0xff0000) | // move byte 1 to byte 2 + ((k >> 8) & 0xff00) | // move byte 2 to byte 1 + ((k << 24) & 0xff000000); // byte 0 to byte 3 + + k *= m; + k ^= k >> r; + k *= m; + + h ^= k; + + dataIndex -= 4; + len -= 4; + } + + // Handle the last few bytes of the input array + switch (len) + { + case 3: + h ^= (uint) data[0] << 16; + goto case 2; + case 2: + h ^= (uint) data[len - 2] << 8; + goto case 1; + case 1: + h ^= data[len - 1]; + h *= m; + break; + } + ; + + // Do a few final mixes of the hash to ensure the last few + // bytes are well-incorporated. + + h ^= h >> 13; + h *= m; + h ^= h >> 15; + + return h; + } + + public static byte[] ConvertBoolArrayToBinaryStream(bool[] array) + { + var data = new byte[array.Length/8 + (array.Length%8 != 0 ? 1 : 0)]; + + var dataCounter = 0; + for (var i = 0; i < array.Length; i += 8) + { + for (var bitCount = 0; bitCount < 8; bitCount++) + { + if (i + bitCount >= array.Length) + break; + data[dataCounter] = (byte) (((array[i + bitCount] ? 1 : 0) << 7 - bitCount) | data[dataCounter]); + } + dataCounter++; + } + + return data; } public static string ToStringBase63(int number) { - string lookup = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + var lookup = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - string secondDigit = lookup.Substring((int)Math.Floor((double)number / (double)lookup.Length), 1); - string firstDigit = lookup.Substring(number % lookup.Length, 1); + var secondDigit = lookup.Substring((int) Math.Floor(number/(double) lookup.Length), 1); + var firstDigit = lookup.Substring(number%lookup.Length, 1); return secondDigit + firstDigit; - } - } -} + } + } +} \ No newline at end of file diff --git a/FFXIVClassic Common Class Lib/app.config b/FFXIVClassic Common Class Lib/app.config new file mode 100644 index 00000000..143834c2 --- /dev/null +++ b/FFXIVClassic Common Class Lib/app.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/FFXIVClassic Common Class Lib/packages.config b/FFXIVClassic Common Class Lib/packages.config index dac938f3..8b2d1420 100644 --- a/FFXIVClassic Common Class Lib/packages.config +++ b/FFXIVClassic Common Class Lib/packages.config @@ -1,4 +1,5 @@  + \ No newline at end of file diff --git a/FFXIVClassic Lobby Server/FFXIVClassic Lobby Server.csproj b/FFXIVClassic Lobby Server/FFXIVClassic Lobby Server.csproj index 550b75a0..8f83df96 100644 --- a/FFXIVClassic Lobby Server/FFXIVClassic Lobby Server.csproj +++ b/FFXIVClassic Lobby Server/FFXIVClassic Lobby Server.csproj @@ -58,8 +58,9 @@ ..\FFXIVClassic Common Class Lib\bin\Debug\FFXIVClassic.Common.dll - - ..\packages\MySql.Data.6.9.7\lib\net45\MySql.Data.dll + + ..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll + True ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll @@ -112,6 +113,7 @@ Always + Designer diff --git a/FFXIVClassic Lobby Server/NLog.config b/FFXIVClassic Lobby Server/NLog.config index c152c074..43645610 100644 --- a/FFXIVClassic Lobby Server/NLog.config +++ b/FFXIVClassic Lobby Server/NLog.config @@ -1,45 +1,62 @@ - + + + internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log"> - - + - - + - - - - - + + + + + + + + + - - - - - + + + + - + \ No newline at end of file diff --git a/FFXIVClassic Lobby Server/Program.cs b/FFXIVClassic Lobby Server/Program.cs index 0bfb56ee..598397b5 100644 --- a/FFXIVClassic Lobby Server/Program.cs +++ b/FFXIVClassic Lobby Server/Program.cs @@ -1,65 +1,63 @@ -using System; -using System.Diagnostics; -using System.Threading; -using MySql.Data.MySqlClient; -using System.Reflection; -using FFXIVClassic.Common; -using NLog; -namespace FFXIVClassic_Lobby_Server -{ - class Program - { - public static Logger Log; - - static void Main(string[] args) - { - - // set up logging - Log = LogManager.GetCurrentClassLogger(); -#if DEBUG - TextWriterTraceListener myWriter = new TextWriterTraceListener(System.Console.Out); - Debug.Listeners.Add(myWriter); -#endif - Console.ForegroundColor = ConsoleColor.Yellow; - Console.WriteLine("--------FFXIV 1.0 Lobby Server--------"); - Console.ForegroundColor = ConsoleColor.Gray; - - bool startServer = true; - - //Load Config - if (!ConfigConstants.Load()) - startServer = false; - - //Test DB Connection - Program.Log.Info("Testing DB connection to \"{0}\"", ConfigConstants.DATABASE_HOST); - using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD))) - { - try - { - conn.Open(); - conn.Close(); - - Program.Log.Info("Connection ok."); - } - catch (MySqlException e) - { - Program.Log.Error(e.ToString()); - startServer = false; - } - } - - //Start Server if A-OK - if (startServer) - { - Server server = new Server(); - server.StartServer(); +using System; +using System.Diagnostics; +using System.Threading; +using MySql.Data.MySqlClient; +using System.Reflection; +using FFXIVClassic.Common; +using NLog; +namespace FFXIVClassic_Lobby_Server +{ + class Program + { + public static Logger Log; + + static void Main(string[] args) + { + + // set up logging + Log = LogManager.GetCurrentClassLogger(); +#if DEBUG + TextWriterTraceListener myWriter = new TextWriterTraceListener(System.Console.Out); + Debug.Listeners.Add(myWriter); +#endif + Program.Log.Info("--------FFXIV 1.0 Lobby Server--------"); + + bool startServer = true; + + //Load Config + if (!ConfigConstants.Load()) + startServer = false; + + //Test DB Connection + Program.Log.Info("Testing DB connection to \"{0}\"... ", ConfigConstants.DATABASE_HOST); + using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD))) + { + try + { + conn.Open(); + conn.Close(); + + Program.Log.Info("Connection ok."); + } + catch (MySqlException e) + { + Program.Log.Error(e.ToString()); + startServer = false; + } + } + + //Start Server if A-OK + if (startServer) + { + Server server = new Server(); + server.StartServer(); while (true) Thread.Sleep(10000); - } - - Program.Log.Info("Press any key to continue..."); - Console.ReadKey(); - } - - - } -} + } + + Program.Log.Info("Press any key to continue..."); + Console.ReadKey(); + } + + + } +} diff --git a/FFXIVClassic Lobby Server/app.config b/FFXIVClassic Lobby Server/app.config index d0ac62a0..143834c2 100644 --- a/FFXIVClassic Lobby Server/app.config +++ b/FFXIVClassic Lobby Server/app.config @@ -1,9 +1,9 @@ - - - - - - - - + + + + + + + + \ No newline at end of file diff --git a/FFXIVClassic Lobby Server/packages.config b/FFXIVClassic Lobby Server/packages.config index 5a3427bf..dd879142 100644 --- a/FFXIVClassic Lobby Server/packages.config +++ b/FFXIVClassic Lobby Server/packages.config @@ -2,7 +2,7 @@ - + diff --git a/FFXIVClassic Lobby Server/packets/BasePacket.cs b/FFXIVClassic Lobby Server/packets/BasePacket.cs index f37d6721..075ec2b6 100644 --- a/FFXIVClassic Lobby Server/packets/BasePacket.cs +++ b/FFXIVClassic Lobby Server/packets/BasePacket.cs @@ -1,13 +1,14 @@ using System; using System.Collections.Generic; -using System.Runtime.InteropServices; using System.Diagnostics; -using FFXIVClassic.Common; using System.IO; +using System.Runtime.InteropServices; +using FFXIVClassic.Common; +using NLog; +using NLog.Targets; namespace FFXIVClassic_Lobby_Server.packets { - [StructLayout(LayoutKind.Sequential)] public struct BasePacketHeader { @@ -21,25 +22,25 @@ namespace FFXIVClassic_Lobby_Server.packets public class BasePacket { - public const int TYPE_ZONE = 1; public const int TYPE_CHAT = 2; public const int BASEPACKET_SIZE = 0x10; - - public BasePacketHeader header; + private static readonly Logger logger = LogManager.GetCurrentClassLogger(); public byte[] data; + public BasePacketHeader header; + //Loads a sniffed packet from a file - public unsafe BasePacket(String path) + public unsafe BasePacket(string path) { - byte[] bytes = File.ReadAllBytes(path); + var bytes = File.ReadAllBytes(path); if (bytes.Length < BASEPACKET_SIZE) throw new OverflowException("Packet Error: Packet was too small"); fixed (byte* pdata = &bytes[0]) { - header = (BasePacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader)); + header = (BasePacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader)); } if (bytes.Length < header.packetSize) @@ -64,7 +65,7 @@ namespace FFXIVClassic_Lobby_Server.packets fixed (byte* pdata = &bytes[0]) { - header = (BasePacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader)); + header = (BasePacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader)); } if (bytes.Length < header.packetSize) @@ -83,7 +84,7 @@ namespace FFXIVClassic_Lobby_Server.packets fixed (byte* pdata = &bytes[offset]) { - header = (BasePacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader)); + header = (BasePacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader)); } int packetSize = header.packetSize; @@ -105,9 +106,9 @@ namespace FFXIVClassic_Lobby_Server.packets public List GetSubpackets() { - List subpackets = new List(header.numSubpackets); + var subpackets = new List(header.numSubpackets); - int offset = 0; + var offset = 0; while (offset < data.Length) subpackets.Add(new SubPacket(data, ref offset)); @@ -115,7 +116,7 @@ namespace FFXIVClassic_Lobby_Server.packets return subpackets; } - public unsafe static BasePacketHeader GetHeader(byte[] bytes) + public static unsafe BasePacketHeader GetHeader(byte[] bytes) { BasePacketHeader header; if (bytes.Length < BASEPACKET_SIZE) @@ -123,7 +124,7 @@ namespace FFXIVClassic_Lobby_Server.packets fixed (byte* pdata = &bytes[0]) { - header = (BasePacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader)); + header = (BasePacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader)); } return header; @@ -131,10 +132,10 @@ namespace FFXIVClassic_Lobby_Server.packets public byte[] GetHeaderBytes() { - int size = Marshal.SizeOf(header); - byte[] arr = new byte[size]; + var size = Marshal.SizeOf(header); + var arr = new byte[size]; - IntPtr ptr = Marshal.AllocHGlobal(size); + var ptr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(header, ptr, true); Marshal.Copy(ptr, arr, 0, size); Marshal.FreeHGlobal(ptr); @@ -143,7 +144,7 @@ namespace FFXIVClassic_Lobby_Server.packets public byte[] GetPacketBytes() { - byte[] outBytes = new byte[header.packetSize]; + var outBytes = new byte[header.packetSize]; Array.Copy(GetHeaderBytes(), 0, outBytes, 0, BASEPACKET_SIZE); Array.Copy(data, 0, outBytes, BASEPACKET_SIZE, data.Length); return outBytes; @@ -152,16 +153,17 @@ namespace FFXIVClassic_Lobby_Server.packets //Replaces all instances of the sniffed actorID with the given one public void ReplaceActorID(uint actorID) { - using (MemoryStream mem = new MemoryStream(data)) + using (var mem = new MemoryStream(data)) { - using (BinaryWriter binWriter = new BinaryWriter(mem)) + using (var binWriter = new BinaryWriter(mem)) { - using (BinaryReader binreader = new BinaryReader(mem)) + using (var binreader = new BinaryReader(mem)) { while (binreader.BaseStream.Position + 4 < data.Length) { - uint read = binreader.ReadUInt32(); - if (read == 0x029B2941 || read == 0x02977DC7 || read == 0x0297D2C8 || read == 0x0230d573 || read == 0x23317df || read == 0x23344a3 || read == 0x1730bdb) //Original ID + var read = binreader.ReadUInt32(); + if (read == 0x029B2941 || read == 0x02977DC7 || read == 0x0297D2C8 || read == 0x0230d573 || + read == 0x23317df || read == 0x23344a3 || read == 0x1730bdb) //Original ID { binWriter.BaseStream.Seek(binreader.BaseStream.Position - 0x4, SeekOrigin.Begin); binWriter.Write(actorID); @@ -175,15 +177,15 @@ namespace FFXIVClassic_Lobby_Server.packets //Replaces all instances of the sniffed actorID with the given one public void ReplaceActorID(uint fromActorID, uint actorID) { - using (MemoryStream mem = new MemoryStream(data)) + using (var mem = new MemoryStream(data)) { - using (BinaryWriter binWriter = new BinaryWriter(mem)) + using (var binWriter = new BinaryWriter(mem)) { - using (BinaryReader binreader = new BinaryReader(mem)) + using (var binreader = new BinaryReader(mem)) { while (binreader.BaseStream.Position + 4 < data.Length) { - uint read = binreader.ReadUInt32(); + var read = binreader.ReadUInt32(); if (read == fromActorID) //Original ID { binWriter.BaseStream.Seek(binreader.BaseStream.Position - 0x4, SeekOrigin.Begin); @@ -195,49 +197,65 @@ namespace FFXIVClassic_Lobby_Server.packets } } + public void DebugPrintPacket() + { +#if DEBUG + logger.ColorDebug( + string.Format("IsAuth:{0} Size:0x{1:X}, NumSubpackets:{2}{3}{4}", + header.isAuthenticated, header.packetSize, header.numSubpackets, + Environment.NewLine, Utils.ByteArrayToHex(GetHeaderBytes())), ConsoleOutputColor.DarkYellow); + + foreach (var sub in GetSubpackets()) + { + sub.DebugPrintSubPacket(); + } +#endif + } + #region Utility Functions + public static BasePacket CreatePacket(List subpackets, bool isAuthed, bool isEncrypted) { //Create Header - BasePacketHeader header = new BasePacketHeader(); + var header = new BasePacketHeader(); byte[] data = null; - header.isAuthenticated = isAuthed ? (byte)1 : (byte)0; - header.isEncrypted = isEncrypted ? (byte)1 : (byte)0; - header.numSubpackets = (ushort)subpackets.Count; + header.isAuthenticated = isAuthed ? (byte) 1 : (byte) 0; + header.isEncrypted = isEncrypted ? (byte) 1 : (byte) 0; + header.numSubpackets = (ushort) subpackets.Count; header.packetSize = BASEPACKET_SIZE; header.timestamp = Utils.MilisUnixTimeStampUTC(); //Get packet size - foreach (SubPacket subpacket in subpackets) + foreach (var subpacket in subpackets) header.packetSize += subpacket.header.subpacketSize; data = new byte[header.packetSize - 0x10]; //Add Subpackets - int offset = 0; - foreach (SubPacket subpacket in subpackets) + var offset = 0; + foreach (var subpacket in subpackets) { - byte[] subpacketData = subpacket.GetBytes(); + var subpacketData = subpacket.GetBytes(); Array.Copy(subpacketData, 0, data, offset, subpacketData.Length); - offset += (ushort)subpacketData.Length; + offset += (ushort) subpacketData.Length; } Debug.Assert(data != null && offset == data.Length && header.packetSize == 0x10 + offset); - BasePacket packet = new BasePacket(header, data); + var packet = new BasePacket(header, data); return packet; } public static BasePacket CreatePacket(SubPacket subpacket, bool isAuthed, bool isEncrypted) { //Create Header - BasePacketHeader header = new BasePacketHeader(); + var header = new BasePacketHeader(); byte[] data = null; - header.isAuthenticated = isAuthed ? (byte)1 : (byte)0; - header.isEncrypted = isEncrypted ? (byte)1 : (byte)0; - header.numSubpackets = (ushort)1; + header.isAuthenticated = isAuthed ? (byte) 1 : (byte) 0; + header.isEncrypted = isEncrypted ? (byte) 1 : (byte) 0; + header.numSubpackets = 1; header.packetSize = BASEPACKET_SIZE; header.timestamp = Utils.MilisUnixTimeStampUTC(); @@ -247,42 +265,41 @@ namespace FFXIVClassic_Lobby_Server.packets data = new byte[header.packetSize - 0x10]; //Add Subpackets - byte[] subpacketData = subpacket.GetBytes(); + var subpacketData = subpacket.GetBytes(); Array.Copy(subpacketData, 0, data, 0, subpacketData.Length); Debug.Assert(data != null); - BasePacket packet = new BasePacket(header, data); + var packet = new BasePacket(header, data); return packet; } public static BasePacket CreatePacket(byte[] data, bool isAuthed, bool isEncrypted) { - Debug.Assert(data != null); //Create Header - BasePacketHeader header = new BasePacketHeader(); + var header = new BasePacketHeader(); - header.isAuthenticated = isAuthed ? (byte)1 : (byte)0; - header.isEncrypted = isEncrypted ? (byte)1 : (byte)0; - header.numSubpackets = (ushort)1; + header.isAuthenticated = isAuthed ? (byte) 1 : (byte) 0; + header.isEncrypted = isEncrypted ? (byte) 1 : (byte) 0; + header.numSubpackets = 1; header.packetSize = BASEPACKET_SIZE; header.timestamp = Utils.MilisUnixTimeStampUTC(); //Get packet size - header.packetSize += (ushort)data.Length; + header.packetSize += (ushort) data.Length; - BasePacket packet = new BasePacket(header, data); + var packet = new BasePacket(header, data); return packet; } public static unsafe void EncryptPacket(Blowfish blowfish, BasePacket packet) { - byte[] data = packet.data; + var data = packet.data; int size = packet.header.packetSize; - int offset = 0; + var offset = 0; while (offset < data.Length) { if (data.Length < offset + SubPacket.SUBPACKET_SIZE) @@ -291,7 +308,7 @@ namespace FFXIVClassic_Lobby_Server.packets SubPacketHeader header; fixed (byte* pdata = &data[offset]) { - header = (SubPacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader)); + header = (SubPacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader)); } if (data.Length < offset + header.subpacketSize) @@ -301,15 +318,14 @@ namespace FFXIVClassic_Lobby_Server.packets offset += header.subpacketSize; } - } public static unsafe void DecryptPacket(Blowfish blowfish, ref BasePacket packet) { - byte[] data = packet.data; + var data = packet.data; int size = packet.header.packetSize; - int offset = 0; + var offset = 0; while (offset < data.Length) { if (data.Length < offset + SubPacket.SUBPACKET_SIZE) @@ -318,7 +334,7 @@ namespace FFXIVClassic_Lobby_Server.packets SubPacketHeader header; fixed (byte* pdata = &data[offset]) { - header = (SubPacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader)); + header = (SubPacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader)); } if (data.Length < offset + header.subpacketSize) @@ -329,24 +345,17 @@ namespace FFXIVClassic_Lobby_Server.packets offset += header.subpacketSize; } } + #endregion - - public void DebugPrintPacket() - { -#if DEBUG - // todo: create new target for colourful packet logging - //Console.BackgroundColor = ConsoleColor.DarkYellow; - - Program.Log.Debug("IsAuth: {0} Size: 0x{1:X}, NumSubpackets: {2}{3}{4}", header.isAuthenticated, header.packetSize, header.numSubpackets, Environment.NewLine, Utils.ByteArrayToHex(GetHeaderBytes())); - - foreach (SubPacket sub in GetSubpackets()) - { - sub.DebugPrintSubPacket(); - } - - //Console.BackgroundColor = ConsoleColor.Black; -#endif - } - } -} + + public static class LoggerExtensions + { + public static void ColorDebug(this Logger logger, string message, ConsoleOutputColor color) + { + var logEvent = new LogEventInfo(LogLevel.Debug, logger.Name, message); + logEvent.Properties["color"] = (int) color; + logger.Log(logEvent); + } + } +} \ No newline at end of file diff --git a/FFXIVClassic Lobby Server/packets/SubPacket.cs b/FFXIVClassic Lobby Server/packets/SubPacket.cs index 1711dc65..d684a087 100644 --- a/FFXIVClassic Lobby Server/packets/SubPacket.cs +++ b/FFXIVClassic Lobby Server/packets/SubPacket.cs @@ -1,6 +1,8 @@ using System; using System.Runtime.InteropServices; using FFXIVClassic.Common; +using NLog; +using NLog.Targets; namespace FFXIVClassic_Lobby_Server.packets { @@ -28,10 +30,11 @@ namespace FFXIVClassic_Lobby_Server.packets { public const int SUBPACKET_SIZE = 0x10; public const int GAMEMESSAGE_SIZE = 0x10; + private static readonly Logger logger = LogManager.GetCurrentClassLogger(); + public byte[] data; + public GameMessageHeader gameMessage; public SubPacketHeader header; - public GameMessageHeader gameMessage; - public byte[] data; public unsafe SubPacket(byte[] bytes, ref int offset) { @@ -40,14 +43,15 @@ namespace FFXIVClassic_Lobby_Server.packets fixed (byte* pdata = &bytes[offset]) { - header = (SubPacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader)); + header = (SubPacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader)); } if (header.type == 0x3) { fixed (byte* pdata = &bytes[offset + SUBPACKET_SIZE]) { - gameMessage = (GameMessageHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(GameMessageHeader)); + gameMessage = + (GameMessageHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(GameMessageHeader)); } } @@ -70,8 +74,8 @@ namespace FFXIVClassic_Lobby_Server.packets public SubPacket(ushort opcode, uint sourceId, uint targetId, byte[] data) { - this.header = new SubPacketHeader(); - this.gameMessage = new GameMessageHeader(); + header = new SubPacketHeader(); + gameMessage = new GameMessageHeader(); gameMessage.opcode = opcode; header.sourceId = sourceId; @@ -87,13 +91,13 @@ namespace FFXIVClassic_Lobby_Server.packets this.data = data; - header.subpacketSize = (ushort)(SUBPACKET_SIZE + GAMEMESSAGE_SIZE + data.Length); + header.subpacketSize = (ushort) (SUBPACKET_SIZE + GAMEMESSAGE_SIZE + data.Length); } public SubPacket(SubPacket original, uint newTargetId) { - this.header = new SubPacketHeader(); - this.gameMessage = original.gameMessage; + header = new SubPacketHeader(); + gameMessage = original.gameMessage; header.subpacketSize = original.header.subpacketSize; header.type = original.header.type; header.sourceId = original.header.sourceId; @@ -103,10 +107,10 @@ namespace FFXIVClassic_Lobby_Server.packets public byte[] GetHeaderBytes() { - int size = Marshal.SizeOf(header); - byte[] arr = new byte[size]; + var size = Marshal.SizeOf(header); + var arr = new byte[size]; - IntPtr ptr = Marshal.AllocHGlobal(size); + var ptr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(header, ptr, true); Marshal.Copy(ptr, arr, 0, size); Marshal.FreeHGlobal(ptr); @@ -115,10 +119,10 @@ namespace FFXIVClassic_Lobby_Server.packets public byte[] GetGameMessageBytes() { - int size = Marshal.SizeOf(gameMessage); - byte[] arr = new byte[size]; + var size = Marshal.SizeOf(gameMessage); + var arr = new byte[size]; - IntPtr ptr = Marshal.AllocHGlobal(size); + var ptr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(gameMessage, ptr, true); Marshal.Copy(ptr, arr, 0, size); Marshal.FreeHGlobal(ptr); @@ -127,7 +131,7 @@ namespace FFXIVClassic_Lobby_Server.packets public byte[] GetBytes() { - byte[] outBytes = new byte[header.subpacketSize]; + var outBytes = new byte[header.subpacketSize]; Array.Copy(GetHeaderBytes(), 0, outBytes, 0, SUBPACKET_SIZE); if (header.type == 0x3) @@ -140,17 +144,20 @@ namespace FFXIVClassic_Lobby_Server.packets public void DebugPrintSubPacket() { #if DEBUG - // todo: create new target for colourful packet logging - Program.Log.Debug("Size: 0x{0:X}{1}{2}", header.subpacketSize, Environment.NewLine, Utils.ByteArrayToHex(GetHeaderBytes())); - + logger.ColorDebug( + string.Format("Size:0x{0:X} Opcode:0x{1:X}{2}{3}", header.subpacketSize, gameMessage.opcode, + Environment.NewLine, + Utils.ByteArrayToHex(GetHeaderBytes())), ConsoleOutputColor.DarkRed); + if (header.type == 0x03) { - Program.Log.Debug("Opcode: 0x{0:X}{1}{2}", gameMessage.opcode, Environment.NewLine, Utils.ByteArrayToHex(GetGameMessageBytes(), SUBPACKET_SIZE)); - } + logger.ColorDebug(Utils.ByteArrayToHex(GetGameMessageBytes(), SUBPACKET_SIZE), + ConsoleOutputColor.DarkRed); - Program.Log.Debug("Data: {0}{1}", Environment.NewLine, Utils.ByteArrayToHex(data, SUBPACKET_SIZE + GAMEMESSAGE_SIZE)); + logger.ColorDebug(Utils.ByteArrayToHex(data, SUBPACKET_SIZE + GAMEMESSAGE_SIZE), + ConsoleOutputColor.DarkMagenta); + } #endif } - } -} +} \ No newline at end of file diff --git a/FFXIVClassic Map Server/App.config b/FFXIVClassic Map Server/App.config index c45a8c71..63198b4c 100644 --- a/FFXIVClassic Map Server/App.config +++ b/FFXIVClassic Map Server/App.config @@ -1,11 +1,11 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/FFXIVClassic Map Server/CommandProcessor.cs b/FFXIVClassic Map Server/CommandProcessor.cs index 5b0ccc73..50985884 100644 --- a/FFXIVClassic Map Server/CommandProcessor.cs +++ b/FFXIVClassic Map Server/CommandProcessor.cs @@ -35,25 +35,6 @@ namespace FFXIVClassic_Map_Server mConnectedPlayerList = playerList; } - public void SendPacket(ConnectedPlayer client, string path) - { - BasePacket packet = new BasePacket(path); - - if (client != null) - { - packet.ReplaceActorID(client.actorID); - client.QueuePacket(packet); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - packet.ReplaceActorID(entry.Value.actorID); - entry.Value.QueuePacket(packet); - } - } - } - public void ChangeProperty(uint id, uint value, string target) { SetActorPropetyPacket ChangeProperty = new SetActorPropetyPacket(target); @@ -73,418 +54,6 @@ namespace FFXIVClassic_Map_Server } } - public void DoMusic(ConnectedPlayer client, string music) - { - ushort musicId; - - if (music.ToLower().StartsWith("0x")) - musicId = Convert.ToUInt16(music, 16); - else - musicId = Convert.ToUInt16(music); - - if (client != null) - client.QueuePacket(BasePacket.CreatePacket(SetMusicPacket.BuildPacket(client.actorID, musicId, 1), true, false)); - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - BasePacket musicPacket = BasePacket.CreatePacket(SetMusicPacket.BuildPacket(entry.Value.actorID, musicId, 1), true, false); - entry.Value.QueuePacket(musicPacket); - } - } - } - - /// - /// Teleports player to a location on a predefined list - /// - /// The current player - /// Predefined list: <ffxiv_database>\server_zones_spawnlocations - public void DoWarp(ConnectedPlayer client, uint id) - { - WorldManager worldManager = Server.GetWorldManager(); - FFXIVClassic_Map_Server.WorldManager.ZoneEntrance ze = worldManager.GetZoneEntrance(id); - - if (ze == null) - return; - - if (client != null) - worldManager.DoZoneChange(client.GetActor(), ze.zoneId, ze.privateAreaName, ze.spawnType, ze.spawnX, ze.spawnY, ze.spawnZ, ze.spawnRotation); - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - worldManager.DoZoneChange(entry.Value.GetActor(), ze.zoneId, ze.privateAreaName, ze.spawnType, ze.spawnX, ze.spawnY, ze.spawnZ, ze.spawnRotation); - } - } - } - - public void DoWarp(ConnectedPlayer client, uint zoneId, string privateArea, byte spawnType, float x, float y, float z, float r) - { - WorldManager worldManager = Server.GetWorldManager(); - if (worldManager.GetZone(zoneId) == null) - { - if (client != null) - client.QueuePacket(BasePacket.CreatePacket(SendMessagePacket.BuildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", "Zone does not exist or setting isn't valid."), true, false)); - Program.Log.Error("Zone does not exist or setting isn't valid."); - } - - if (client != null) - worldManager.DoZoneChange(client.GetActor(), zoneId, privateArea, spawnType, x, y, z, r); - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - worldManager.DoZoneChange(entry.Value.GetActor(), zoneId, privateArea, spawnType, x, y, z, r); - } - } - } - - public void PrintPos(ConnectedPlayer client) - { - if (client != null) - { - Player p = client.GetActor(); - client.QueuePacket(BasePacket.CreatePacket(SendMessagePacket.BuildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", String.Format("{0}\'s position: ZoneID: {1}, X: {2}, Y: {3}, Z: {4}, Rotation: {5}", p.customDisplayName, p.zoneId, p.positionX, p.positionY, p.positionZ, p.rotation)), true, false)); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - Program.Log.Info(String.Format("{0}\'s position: ZoneID: {1}, X: {2}, Y: {3}, Z: {4}, Rotation: {5}", p.customDisplayName, p.zoneId, p.positionX, p.positionY, p.positionZ, p.rotation)); - } - } - } - - private void SetGraphic(ConnectedPlayer client, uint slot, uint wId, uint eId, uint vId, uint cId) - { - if (client != null) - { - Player p = client.GetActor(); - p.GraphicChange(slot, wId, eId, vId, cId); - p.SendAppearance(); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - p.GraphicChange(slot, wId, eId, vId, cId); - p.SendAppearance(); - } - } - } - - private void GiveItem(ConnectedPlayer client, uint itemId, int quantity) - { - if (client != null) - { - Player p = client.GetActor(); - p.GetInventory(Inventory.NORMAL).AddItem(itemId, quantity); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - p.GetInventory(Inventory.NORMAL).AddItem(itemId, quantity); - } - } - } - - private void GiveItem(ConnectedPlayer client, uint itemId, int quantity, ushort type) - { - if (client != null) - { - Player p = client.GetActor(); - - if (p.GetInventory(type) != null) - p.GetInventory(type).AddItem(itemId, quantity); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - - if (p.GetInventory(type) != null) - p.GetInventory(type).AddItem(itemId, quantity); - } - } - } - - private void RemoveItem(ConnectedPlayer client, uint itemId, int quantity) - { - if (client != null) - { - Player p = client.GetActor(); - p.GetInventory(Inventory.NORMAL).RemoveItem(itemId, quantity); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - p.GetInventory(Inventory.NORMAL).RemoveItem(itemId, quantity); - } - } - } - - private void RemoveItem(ConnectedPlayer client, uint itemId, int quantity, ushort type) - { - if (client != null) - { - Player p = client.GetActor(); - - if (p.GetInventory(type) != null) - p.GetInventory(type).RemoveItem(itemId, quantity); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - - if (p.GetInventory(type) != null) - p.GetInventory(type).RemoveItem(itemId, quantity); - } - } - } - - private void GiveCurrency(ConnectedPlayer client, uint itemId, int quantity) - { - if (client != null) - { - Player p = client.GetActor(); - p.GetInventory(Inventory.CURRENCY).AddItem(itemId, quantity); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - p.GetInventory(Inventory.CURRENCY).AddItem(itemId, quantity); - } - } - } - - // TODO: make RemoveCurrency() Remove all quantity of a currency if quantity_to_Remove > quantity_in_inventory instead of silently failing - private void RemoveCurrency(ConnectedPlayer client, uint itemId, int quantity) - { - if (client != null) - { - Player p = client.GetActor(); - p.GetInventory(Inventory.CURRENCY).RemoveItem(itemId, quantity); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - p.GetInventory(Inventory.CURRENCY).RemoveItem(itemId, quantity); - } - } - } - - private void GiveKeyItem(ConnectedPlayer client, uint itemId) - { - if (client != null) - { - Player p = client.GetActor(); - p.GetInventory(Inventory.KEYITEMS).AddItem(itemId, 1); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - p.GetInventory(Inventory.KEYITEMS).AddItem(itemId, 1); - } - } - } - - private void RemoveKeyItem(ConnectedPlayer client, uint itemId) - { - if (client != null) - { - Player p = client.GetActor(); - p.GetInventory(Inventory.KEYITEMS).RemoveItem(itemId, 1); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - p.GetInventory(Inventory.KEYITEMS).RemoveItem(itemId, 1); - } - } - } - - private void ParseWarp(ConnectedPlayer client, string[] split) - { - float x = 0, y = 0, z = 0, r = 0.0f; - uint zoneId = 0; - string privatearea = null; - - if (split.Length == 2) // Predefined list - { - // TODO: Handle !warp Playername - #region !warp (predefined list) - try - { - if (split[1].ToLower().StartsWith("0x")) - zoneId = Convert.ToUInt32(split[1], 16); - else - zoneId = Convert.ToUInt32(split[1]); - } - catch{return;} - #endregion - - DoWarp(client, zoneId); - } - else if (split.Length == 4) - { - #region !warp X Y Z - if (split[1].StartsWith("@")) - { - split[1] = split[1].Replace("@", string.Empty); - - if (String.IsNullOrEmpty(split[1])) - split[1] = "0"; - - try { x = Single.Parse(split[1]) + client.GetActor().positionX; } - catch{return;} - - split[1] = x.ToString(); - } - if (split[2].StartsWith("@")) - { - split[2] = split[2].Replace("@", string.Empty); - - if (String.IsNullOrEmpty(split[2])) - split[2] = "0"; - - try { y = Single.Parse(split[2]) + client.GetActor().positionY; } - catch{return;} - - split[2] = y.ToString(); - } - if (split[3].StartsWith("@")) - { - split[3] = split[3].Replace("@", string.Empty); - - if (String.IsNullOrEmpty(split[3])) - split[3] = "0"; - - try { z = Single.Parse(split[3]) + client.GetActor().positionZ; } - catch{return;} - - split[3] = z.ToString(); - } - - try - { - x = Single.Parse(split[1]); - y = Single.Parse(split[2]); - z = Single.Parse(split[3]); - } - catch{return;} - - zoneId = client.GetActor().zoneId; - r = client.GetActor().rotation; - #endregion - - SendMessage(client, String.Format("Warping to: ZoneID: {0} X: {1}, Y: {2}, Z: {3}", zoneId, x, y, z)); - DoWarp(client, zoneId, privatearea, 0x00, x, y, z, r); - } - else if (split.Length == 5) - { - #region !warp Zone X Y Z - try - { - x = Single.Parse(split[2]); - y = Single.Parse(split[3]); - z = Single.Parse(split[4]); - } - catch{return;} - - if (split[1].ToLower().StartsWith("0x")) - { - try { zoneId = Convert.ToUInt32(split[1], 16); } - catch{return;} - } - else - { - try { zoneId = Convert.ToUInt32(split[1]); } - catch{return;} - } - #endregion - - SendMessage(client, String.Format("Warping to: ZoneID: {0} X: {1}, Y: {2}, Z: {3}", zoneId, x, y, z)); - DoWarp(client, zoneId, privatearea, 0x2, x, y, z, r); - } - else if (split.Length == 6) - { - #region !warp Zone Instance X Y Z - try - { - x = Single.Parse(split[3]); - y = Single.Parse(split[4]); - z = Single.Parse(split[5]); - } - catch{return;} - - if (split[1].ToLower().StartsWith("0x")) - { - try { zoneId = Convert.ToUInt32(split[1], 16); } - catch{return;} - } - else - { - try { zoneId = Convert.ToUInt32(split[1]); } - catch{return;} - } - - privatearea = split[2]; - #endregion - - SendMessage(client, String.Format("Warping to: ZoneID: {0} X: {1}, Y: {2}, Z: {3}", zoneId, x, y, z)); - DoWarp(client, zoneId, privatearea, 0x2, x, y, z, r); - } - else - return; // catch any invalid warps here - } - - private void doWeather(ConnectedPlayer client, string weatherID, string value) - { - ushort weather = Convert.ToUInt16(weatherID); - - if (client != null) - { - client.QueuePacket(BasePacket.CreatePacket(SetWeatherPacket.BuildPacket(client.actorID, weather, Convert.ToUInt16(value)), true, false)); - } - - /* - * WIP: Change weather serverside, currently only clientside - * - uint currentZoneID; - if (client != null) - { - currentZoneID = client.GetActor().zoneId; - - foreach (KeyValuePair entry in mConnectedPlayerList) - { - // Change the weather for everyone in the same zone - if (currentZoneID == entry.Value.GetActor().zoneId) - { - BasePacket weatherPacket = BasePacket.CreatePacket(SetWeatherPacket.BuildPacket(entry.Value.actorID, weather), true, false); - entry.Value.QueuePacket(weatherPacket); - } - } - } - */ - } - /// /// We only use the default options for SendMessagePacket. /// May as well make it less unwieldly to view @@ -499,136 +68,61 @@ namespace FFXIVClassic_Map_Server internal bool DoCommand(string input, ConnectedPlayer client) { + if (!input.Any() || input.Equals("")) + return false; + input.Trim(); - if (input.StartsWith("!")) - input = input.Substring(1); + input = input.StartsWith("!") ? input.Substring(1) : input; + + var split = input.Split('"') + .Select((str, index) => index % 2 == 0 + ? str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) + : new String[] { str } + ) + .SelectMany(str => str).ToArray(); - String[] split = input.Split(' '); split = split.Select(temp => temp.ToLower()).ToArray(); // Ignore case on commands - split = split.Where(temp => temp != "").ToArray(); // strips extra whitespace from commands - // Debug - //SendMessage(client, string.Join(",", split)); - - if (split.Length >= 1) + var cmd = split[0]; + + if (cmd.Any()) { - #region !help - if (split[0].Equals("help")) + // if client isnt null, take player to be the player actor + var player = client?.GetActor(); + + if (cmd.Equals("help")) { - if (split.Length == 1) + // if there's another string after this, take it as the command we want the description for + if (split.Length > 1) { - SendMessage(client, Resources.CPhelp); - } - if (split.Length == 2) - { - if (split[1].Equals("mypos")) - SendMessage(client, Resources.CPmypos); - else if (split[1].Equals("music")) - SendMessage(client, Resources.CPmusic); - else if (split[1].Equals("warp")) - SendMessage(client, Resources.CPwarp); - else if (split[1].Equals("givecurrency")) - SendMessage(client, Resources.CPgivecurrency); - else if (split[1].Equals("giveitem")) - SendMessage(client, Resources.CPgiveitem); - else if (split[1].Equals("givekeyitem")) - SendMessage(client, Resources.CPgivekeyitem); - else if (split[1].Equals("Removecurrency")) - SendMessage(client, Resources.CPRemovecurrency); - else if (split[1].Equals("Removeitem")) - SendMessage(client, Resources.CPRemoveitem); - else if (split[1].Equals("Removekeyitem")) - SendMessage(client, Resources.CPRemovekeyitem); - else if (split[1].Equals("reloaditems")) - SendMessage(client, Resources.CPreloaditems); - else if (split[1].Equals("reloadzones")) - SendMessage(client, Resources.CPreloadzones); - /* - else if (split[1].Equals("property")) - SendMessage(client, Resources.CPproperty); - else if (split[1].Equals("property2")) - SendMessage(client, Resources.CPproperty2); - else if (split[1].Equals("sendpacket")) - SendMessage(client, Resources.CPsendpacket); - else if (split[1].Equals("setgraphic")) - SendMessage(client, Resources.CPsetgraphic); - */ - } - if (split.Length == 3) - { - if(split[1].Equals("test")) - { - if (split[2].Equals("weather")) - SendMessage(client, Resources.CPtestweather); - } - } - - return true; - } - #endregion - - #region !test - else if (split[0].Equals("test")) - { - if (split.Length == 1) - { - // catch invalid commands - SendMessage(client, Resources.CPhelp); - } - else if (split.Length >= 2) - { - #region !test weather - if (split[1].Equals("weather")) - { - try - { - doWeather(client, split[2], split[3]); - return true; - } - catch (Exception e) - { - Program.Log.Error("Could not change weather: " + e); - } - } - #endregion - } - - } - #endregion - - #region !mypos - else if (split[0].Equals("mypos")) - { - try - { - PrintPos(client); + LuaEngine.RunGMCommand(player, split[1], null, true); return true; } - catch (Exception e) - { - Program.Log.Error("Could not load packet: " + e); - } - } - #endregion - #region !reloadzones - else if (split[0].Equals("reloadzones")) - { - if (client != null) + // print out all commands + foreach (var str in Directory.GetFiles("./scripts/commands/gm/")) { - Program.Log.Info(String.Format("Got request to reset zone: {0}", client.GetActor().zoneId)); - client.GetActor().zone.Clear(); - client.GetActor().zone.AddActorToZone(client.GetActor()); - client.GetActor().SendInstanceUpdate(); - client.QueuePacket(BasePacket.CreatePacket(SendMessagePacket.BuildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", String.Format("Reseting zone {0}...", client.GetActor().zoneId)), true, false)); + var c = str.Replace(".lua", ""); + c = c.Replace("./scripts/commands/gm/", ""); + + LuaEngine.RunGMCommand(player, c, null, true); } - Server.GetWorldManager().ReloadZone(client.GetActor().zoneId); return true; } - #endregion - #region !reloaditems - else if (split[0].Equals("reloaditems")) + LuaEngine.RunGMCommand(player, cmd.ToString(), split.ToArray()); + return true; + } + // Debug + //SendMessage(client, string.Join(",", split)); + + if (split.Length >= 1) + { + + // TODO: reloadzones + + #region !reloaditems + if (split[0].Equals("reloaditems")) { Program.Log.Info(String.Format("Got request to reload item gamedata")); SendMessage(client, "Reloading Item Gamedata..."); @@ -640,181 +134,6 @@ namespace FFXIVClassic_Map_Server } #endregion - #region !sendpacket - else if (split[0].Equals("sendpacket")) - { - if (split.Length < 2) - return false; - - try - { - SendPacket(client, "./packets/" + split[1]); - return true; - } - catch (Exception e) - { - Program.Log.Error("Could not load packet: " + e); - } - } - #endregion - - #region !graphic - else if (split[0].Equals("graphic")) - { - try - { - if (split.Length == 6) - SetGraphic(client, UInt32.Parse(split[1]), UInt32.Parse(split[2]), UInt32.Parse(split[3]), UInt32.Parse(split[4]), UInt32.Parse(split[5])); - return true; - } - catch (Exception e) - { - Program.Log.Error("Could not give item."); - } - } - #endregion - - #region !giveitem - else if (split[0].Equals("giveitem")) - { - try - { - if (split.Length == 2) - GiveItem(client, UInt32.Parse(split[1]), 1); - else if (split.Length == 3) - GiveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); - else if (split.Length == 4) - GiveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]), UInt16.Parse(split[3])); - return true; - } - catch (Exception e) - { - Program.Log.Error("Could not give item."); - } - } - #endregion - - #region !Removeitem - else if (split[0].Equals("Removeitem")) - { - if (split.Length < 2) - return false; - - try - { - if (split.Length == 2) - RemoveItem(client, UInt32.Parse(split[1]), 1); - else if (split.Length == 3) - RemoveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); - else if (split.Length == 4) - RemoveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]), UInt16.Parse(split[3])); - return true; - } - catch (Exception e) - { - Program.Log.Error("Could not Remove item."); - } - } - #endregion - - #region !givekeyitem - else if (split[0].Equals("givekeyitem")) - { - try - { - if (split.Length == 2) - GiveKeyItem(client, UInt32.Parse(split[1])); - } - catch (Exception e) - { - Program.Log.Error("Could not give keyitem."); - } - } - #endregion - - #region !Removekeyitem - else if (split[0].Equals("Removekeyitem")) - { - if (split.Length < 2) - return false; - - try - { - if (split.Length == 2) - RemoveKeyItem(client, UInt32.Parse(split[1])); - return true; - } - catch (Exception e) - { - Program.Log.Error("Could not Remove keyitem."); - } - } - #endregion - - #region !givecurrency - else if (split[0].Equals("givecurrency")) - { - try - { - if (split.Length == 2) - GiveCurrency(client, ITEM_GIL, Int32.Parse(split[1])); - else if (split.Length == 3) - GiveCurrency(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); - } - catch (Exception e) - { - Program.Log.Error("Could not give currency."); - } - } - #endregion - - #region !Removecurrency - else if (split[0].Equals("Removecurrency")) - { - if (split.Length < 2) - return false; - - try - { - if (split.Length == 2) - RemoveCurrency(client, ITEM_GIL, Int32.Parse(split[1])); - else if (split.Length == 3) - RemoveCurrency(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); - return true; - } - catch (Exception e) - { - Program.Log.Error("Could not Remove currency."); - } - } - #endregion - - #region !music - else if (split[0].Equals("music")) - { - if (split.Length < 2) - return false; - - try - { - DoMusic(client, split[1]); - return true; - } - catch (Exception e) - { - Program.Log.Error("Could not change music: " + e); - } - } - #endregion - - #region !warp - else if (split[0].Equals("warp")) - { - ParseWarp(client, split); - return true; - } - #endregion - #region !property else if (split[0].Equals("property")) { diff --git a/FFXIVClassic Map Server/Database.cs b/FFXIVClassic Map Server/Database.cs index 55e1b9fd..823e8b13 100644 --- a/FFXIVClassic Map Server/Database.cs +++ b/FFXIVClassic Map Server/Database.cs @@ -419,6 +419,8 @@ namespace FFXIVClassic_Map_Server player.oldRotation = player.rotation = reader.GetFloat(4); player.currentMainState = reader.GetUInt16(5); player.zoneId = reader.GetUInt32(6); + player.isZoning = true; + player.zone = Server.GetWorldManager().GetZone(player.zoneId); player.gcCurrent = reader.GetByte(7); player.gcRankLimsa = reader.GetByte(8); player.gcRankGridania = reader.GetByte(9); diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj index f01958b6..c5c79140 100644 --- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj +++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj @@ -49,8 +49,8 @@ ..\packages\MoonSharp.1.2.1.0\lib\net40-client\MoonSharp.Interpreter.dll - - ..\packages\MySql.Data.6.9.7\lib\net45\MySql.Data.dll + + ..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll True @@ -119,6 +119,7 @@ + diff --git a/FFXIVClassic Map Server/NLog.config b/FFXIVClassic Map Server/NLog.config index 1d8fb2f4..278e1605 100644 --- a/FFXIVClassic Map Server/NLog.config +++ b/FFXIVClassic Map Server/NLog.config @@ -1,16 +1,17 @@ - + + + internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log"> - + - + - - + + + + + + + + - - + + +