mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-06-11 23:14:39 +02:00
Cleaned up namespaces (still have to do Map Project) and removed references to FFXIV Classic from the code. Removed the Launcher Editor project as it is no longer needed (host file editing is cleaner).
This commit is contained in:
parent
7587a6e142
commit
0f61c4c0e1
544 changed files with 54548 additions and 55498 deletions
477
Common Class Lib/BasePacket.cs
Normal file
477
Common Class Lib/BasePacket.cs
Normal file
|
@ -0,0 +1,477 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015-2019 Project Meteor Dev Team
|
||||
|
||||
This file is part of Project Meteor Server.
|
||||
|
||||
Project Meteor Server is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Project Meteor Server 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Ionic.Zlib;
|
||||
using NLog;
|
||||
using NLog.Targets;
|
||||
|
||||
namespace Meteor.Common
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct BasePacketHeader
|
||||
{
|
||||
public byte isAuthenticated;
|
||||
public byte isCompressed;
|
||||
public ushort connectionType;
|
||||
public ushort packetSize;
|
||||
public ushort numSubpackets;
|
||||
public ulong timestamp; //Miliseconds
|
||||
}
|
||||
|
||||
public class BasePacket
|
||||
{
|
||||
public const int TYPE_ZONE = 1;
|
||||
public const int TYPE_CHAT = 2;
|
||||
public const int BASEPACKET_SIZE = 0x10;
|
||||
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)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
if (bytes.Length < header.packetSize)
|
||||
throw new OverflowException("Packet Error: Packet size didn't equal given size");
|
||||
|
||||
int packetSize = header.packetSize;
|
||||
|
||||
if (packetSize - BASEPACKET_SIZE != 0)
|
||||
{
|
||||
data = new byte[packetSize - BASEPACKET_SIZE];
|
||||
Array.Copy(bytes, BASEPACKET_SIZE, data, 0, packetSize - BASEPACKET_SIZE);
|
||||
}
|
||||
else
|
||||
data = new byte[0];
|
||||
}
|
||||
|
||||
//Loads a sniffed packet from a byte array
|
||||
public unsafe BasePacket(byte[] bytes)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
if (bytes.Length < header.packetSize)
|
||||
throw new OverflowException("Packet Error: Packet size didn't equal given size");
|
||||
|
||||
int packetSize = header.packetSize;
|
||||
|
||||
data = new byte[packetSize - BASEPACKET_SIZE];
|
||||
Array.Copy(bytes, BASEPACKET_SIZE, data, 0, packetSize - BASEPACKET_SIZE);
|
||||
}
|
||||
|
||||
public unsafe BasePacket(byte[] bytes, ref int offset)
|
||||
{
|
||||
if (bytes.Length < offset + BASEPACKET_SIZE)
|
||||
throw new OverflowException("Packet Error: Packet was too small");
|
||||
|
||||
fixed (byte* pdata = &bytes[offset])
|
||||
{
|
||||
header = (BasePacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader));
|
||||
}
|
||||
|
||||
int packetSize = header.packetSize;
|
||||
|
||||
if (bytes.Length < offset + header.packetSize)
|
||||
throw new OverflowException("Packet Error: Packet size didn't equal given size");
|
||||
|
||||
data = new byte[packetSize - BASEPACKET_SIZE];
|
||||
Array.Copy(bytes, offset + BASEPACKET_SIZE, data, 0, packetSize - BASEPACKET_SIZE);
|
||||
|
||||
offset += packetSize;
|
||||
}
|
||||
|
||||
public BasePacket(BasePacketHeader header, byte[] data)
|
||||
{
|
||||
this.header = header;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public List<SubPacket> GetSubpackets()
|
||||
{
|
||||
var subpackets = new List<SubPacket>(header.numSubpackets);
|
||||
|
||||
var offset = 0;
|
||||
|
||||
while (offset < data.Length)
|
||||
subpackets.Add(new SubPacket(data, ref offset));
|
||||
|
||||
return subpackets;
|
||||
}
|
||||
|
||||
public static unsafe BasePacketHeader GetHeader(byte[] bytes)
|
||||
{
|
||||
BasePacketHeader header;
|
||||
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));
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
public byte[] GetHeaderBytes()
|
||||
{
|
||||
var size = Marshal.SizeOf(header);
|
||||
var arr = new byte[size];
|
||||
|
||||
var ptr = Marshal.AllocHGlobal(size);
|
||||
Marshal.StructureToPtr(header, ptr, true);
|
||||
Marshal.Copy(ptr, arr, 0, size);
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
return arr;
|
||||
}
|
||||
|
||||
public byte[] GetPacketBytes()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
//Replaces all instances of the sniffed actorID with the given one
|
||||
public void ReplaceActorID(uint actorID)
|
||||
{
|
||||
using (var mem = new MemoryStream(data))
|
||||
{
|
||||
using (var binWriter = new BinaryWriter(mem))
|
||||
{
|
||||
using (var binreader = new BinaryReader(mem))
|
||||
{
|
||||
while (binreader.BaseStream.Position + 4 < data.Length)
|
||||
{
|
||||
var read = binreader.ReadUInt32();
|
||||
if (read == 0x029B2941 || read == 0x02977DC7 || read == 0x0297D2C8 || read == 0x0230d573 ||
|
||||
read == 0x23317df || read == 0x23344a3 || read == 0x1730bdb || read == 0x6c)
|
||||
//Original ID
|
||||
{
|
||||
binWriter.BaseStream.Seek(binreader.BaseStream.Position - 0x4, SeekOrigin.Begin);
|
||||
binWriter.Write(actorID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Replaces all instances of the sniffed actorID with the given one
|
||||
public void ReplaceActorID(uint fromActorID, uint actorID)
|
||||
{
|
||||
using (var mem = new MemoryStream(data))
|
||||
{
|
||||
using (var binWriter = new BinaryWriter(mem))
|
||||
{
|
||||
using (var binreader = new BinaryReader(mem))
|
||||
{
|
||||
while (binreader.BaseStream.Position + 4 < data.Length)
|
||||
{
|
||||
var read = binreader.ReadUInt32();
|
||||
if (read == fromActorID) //Original ID
|
||||
{
|
||||
binWriter.BaseStream.Seek(binreader.BaseStream.Position - 0x4, SeekOrigin.Begin);
|
||||
binWriter.Write(actorID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DebugPrintPacket()
|
||||
{
|
||||
#if DEBUG
|
||||
logger.ColorDebug(
|
||||
string.Format("IsAuth:{0} IsEncrypted:{1}, Size:0x{2:X}, NumSubpackets:{3}{4}{5}",
|
||||
header.isAuthenticated, header.isCompressed, 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<SubPacket> subpackets, bool isAuthed, bool isCompressed)
|
||||
{
|
||||
//Create Header
|
||||
var header = new BasePacketHeader();
|
||||
byte[] data = null;
|
||||
|
||||
header.isAuthenticated = isAuthed ? (byte) 1 : (byte) 0;
|
||||
header.isCompressed = isCompressed ? (byte) 1 : (byte) 0;
|
||||
header.numSubpackets = (ushort) subpackets.Count;
|
||||
header.packetSize = BASEPACKET_SIZE;
|
||||
header.timestamp = Utils.MilisUnixTimeStampUTC();
|
||||
|
||||
//Get packet size
|
||||
foreach (var subpacket in subpackets)
|
||||
header.packetSize += subpacket.header.subpacketSize;
|
||||
|
||||
data = new byte[header.packetSize - 0x10];
|
||||
|
||||
//Add Subpackets
|
||||
var offset = 0;
|
||||
foreach (var subpacket in subpackets)
|
||||
{
|
||||
var subpacketData = subpacket.GetBytes();
|
||||
Array.Copy(subpacketData, 0, data, offset, subpacketData.Length);
|
||||
offset += (ushort)subpacketData.Length;
|
||||
}
|
||||
|
||||
//Compress this array into a new one if needed
|
||||
if (isCompressed)
|
||||
{
|
||||
data = CompressData(data);
|
||||
header.packetSize = (ushort)(BASEPACKET_SIZE + data.Length);
|
||||
}
|
||||
|
||||
Debug.Assert(data != null && offset == data.Length && header.packetSize == 0x10 + offset);
|
||||
|
||||
var packet = new BasePacket(header, data);
|
||||
return packet;
|
||||
}
|
||||
|
||||
public static BasePacket CreatePacket(SubPacket subpacket, bool isAuthed, bool isCompressed)
|
||||
{
|
||||
//Create Header
|
||||
var header = new BasePacketHeader();
|
||||
byte[] data = null;
|
||||
|
||||
header.isAuthenticated = isAuthed ? (byte) 1 : (byte) 0;
|
||||
header.isCompressed = isCompressed ? (byte) 1 : (byte) 0;
|
||||
header.numSubpackets = 1;
|
||||
header.packetSize = BASEPACKET_SIZE;
|
||||
header.timestamp = Utils.MilisUnixTimeStampUTC();
|
||||
|
||||
//Get packet size
|
||||
header.packetSize += subpacket.header.subpacketSize;
|
||||
|
||||
data = new byte[header.packetSize - 0x10];
|
||||
|
||||
//Add Subpackets
|
||||
byte[] subpacketData = subpacket.GetBytes();
|
||||
|
||||
//Compress this array into a new one if needed
|
||||
if (isCompressed)
|
||||
{
|
||||
subpacketData = CompressData(subpacketData);
|
||||
header.packetSize = (ushort)(BASEPACKET_SIZE + data.Length);
|
||||
}
|
||||
|
||||
Array.Copy(subpacketData, 0, data, 0, subpacketData.Length);
|
||||
|
||||
Debug.Assert(data != null);
|
||||
|
||||
var packet = new BasePacket(header, data);
|
||||
return packet;
|
||||
}
|
||||
|
||||
public static BasePacket CreatePacket(byte[] data, bool isAuthed, bool isCompressed)
|
||||
{
|
||||
Debug.Assert(data != null);
|
||||
|
||||
//Create Header
|
||||
var header = new BasePacketHeader();
|
||||
|
||||
header.isAuthenticated = isAuthed ? (byte) 1 : (byte) 0;
|
||||
header.isCompressed = isCompressed ? (byte) 1 : (byte) 0;
|
||||
header.numSubpackets = 1;
|
||||
header.packetSize = BASEPACKET_SIZE;
|
||||
header.timestamp = Utils.MilisUnixTimeStampUTC();
|
||||
|
||||
//Get packet size
|
||||
header.packetSize += (ushort) data.Length;
|
||||
|
||||
//Compress this array into a new one if needed
|
||||
if (isCompressed)
|
||||
{
|
||||
data = CompressData(data);
|
||||
header.packetSize = (ushort)(BASEPACKET_SIZE + data.Length);
|
||||
}
|
||||
|
||||
var packet = new BasePacket(header, data);
|
||||
return packet;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a packet from the incoming buffer + offset. If a packet can be built, it is returned else null.
|
||||
/// </summary>
|
||||
/// <param name="offset">Current offset in buffer.</param>
|
||||
/// <param name="buffer">Incoming buffer.</param>
|
||||
/// <returns>Returns either a BasePacket or null if not enough data.</returns>
|
||||
public static BasePacket CreatePacket(ref int offset, byte[] buffer, int bytesRead)
|
||||
{
|
||||
BasePacket newPacket = null;
|
||||
|
||||
//Too small to even get length
|
||||
if (bytesRead <= offset)
|
||||
return null;
|
||||
|
||||
ushort packetSize = BitConverter.ToUInt16(buffer, offset);
|
||||
|
||||
//Too small to whole packet
|
||||
if (bytesRead < offset + packetSize)
|
||||
return null;
|
||||
|
||||
if (buffer.Length < offset + packetSize)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
newPacket = new BasePacket(buffer, ref offset);
|
||||
}
|
||||
catch (OverflowException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return newPacket;
|
||||
}
|
||||
|
||||
public static unsafe void EncryptPacket(Blowfish blowfish, BasePacket packet)
|
||||
{
|
||||
var data = packet.data;
|
||||
int size = packet.header.packetSize;
|
||||
|
||||
var offset = 0;
|
||||
while (offset < data.Length)
|
||||
{
|
||||
if (data.Length < offset + SubPacket.SUBPACKET_SIZE)
|
||||
throw new OverflowException("Packet Error: Subpacket was too small");
|
||||
|
||||
SubPacketHeader header;
|
||||
fixed (byte* pdata = &data[offset])
|
||||
{
|
||||
header = (SubPacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader));
|
||||
}
|
||||
|
||||
if (data.Length < offset + header.subpacketSize)
|
||||
throw new OverflowException("Packet Error: Subpacket size didn't equal subpacket data");
|
||||
|
||||
blowfish.Encipher(data, offset + 0x10, header.subpacketSize - 0x10);
|
||||
|
||||
offset += header.subpacketSize;
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void DecryptPacket(Blowfish blowfish, ref BasePacket packet)
|
||||
{
|
||||
var data = packet.data;
|
||||
int size = packet.header.packetSize;
|
||||
|
||||
var offset = 0;
|
||||
while (offset < data.Length)
|
||||
{
|
||||
if (data.Length < offset + SubPacket.SUBPACKET_SIZE)
|
||||
throw new OverflowException("Packet Error: Subpacket was too small");
|
||||
|
||||
SubPacketHeader header;
|
||||
fixed (byte* pdata = &data[offset])
|
||||
{
|
||||
header = (SubPacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader));
|
||||
}
|
||||
|
||||
if (data.Length < offset + header.subpacketSize)
|
||||
throw new OverflowException("Packet Error: Subpacket size didn't equal subpacket data");
|
||||
|
||||
blowfish.Decipher(data, offset + 0x10, header.subpacketSize - 0x10);
|
||||
|
||||
offset += header.subpacketSize;
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe void DecompressPacket(ref BasePacket packet)
|
||||
{
|
||||
using (var compressedStream = new MemoryStream(packet.data))
|
||||
using (var zipStream = new ZlibStream(compressedStream, Ionic.Zlib.CompressionMode.Decompress))
|
||||
using (var resultStream = new MemoryStream())
|
||||
{
|
||||
zipStream.CopyTo(resultStream);
|
||||
packet.data = resultStream.ToArray();
|
||||
packet.header.isCompressed = 0;
|
||||
packet.header.packetSize = (ushort)(BASEPACKET_SIZE + packet.data.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe BasePacket CompressPacket(BasePacket uncompressedPacket)
|
||||
{
|
||||
using (var compressedStream = new MemoryStream(uncompressedPacket.data))
|
||||
using (var zipStream = new ZlibStream(compressedStream, Ionic.Zlib.CompressionMode.Compress))
|
||||
using (var resultStream = new MemoryStream())
|
||||
{
|
||||
zipStream.CopyTo(resultStream);
|
||||
BasePacket compressedPacket = BasePacket.CreatePacket(resultStream.ToArray(), uncompressedPacket.header.isAuthenticated == 1, true);
|
||||
return compressedPacket;
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe byte[] CompressData(byte[] data)
|
||||
{
|
||||
using (var compressedStream = new MemoryStream(data))
|
||||
using (var zipStream = new ZlibStream(compressedStream, Ionic.Zlib.CompressionMode.Compress))
|
||||
using (var resultStream = new MemoryStream())
|
||||
{
|
||||
zipStream.CopyTo(resultStream);
|
||||
return resultStream.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
95
Common Class Lib/Bitfield.cs
Normal file
95
Common Class Lib/Bitfield.cs
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015-2019 Project Meteor Dev Team
|
||||
|
||||
This file is part of Project Meteor Server.
|
||||
|
||||
Project Meteor Server is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Project Meteor Server 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Meteor.Common
|
||||
{
|
||||
[global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
|
||||
public sealed class BitfieldLengthAttribute : Attribute
|
||||
{
|
||||
uint length;
|
||||
|
||||
public BitfieldLengthAttribute(uint length)
|
||||
{
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public uint Length { get { return length; } }
|
||||
}
|
||||
|
||||
public static class PrimitiveConversion
|
||||
{
|
||||
public static UInt32 ToUInt32<T>(T t) where T : struct
|
||||
{
|
||||
UInt32 r = 0;
|
||||
int offset = 0;
|
||||
|
||||
// For every field suitably attributed with a BitfieldLength
|
||||
foreach (System.Reflection.FieldInfo f in t.GetType().GetFields())
|
||||
{
|
||||
object[] attrs = f.GetCustomAttributes(typeof(BitfieldLengthAttribute), false);
|
||||
if (attrs.Length == 1)
|
||||
{
|
||||
uint fieldLength = ((BitfieldLengthAttribute)attrs[0]).Length;
|
||||
|
||||
// Calculate a bitmask of the desired length
|
||||
uint mask = 0;
|
||||
for (int i = 0; i < fieldLength; i++)
|
||||
mask |= (UInt32)1 << i;
|
||||
|
||||
r |= ((UInt32)f.GetValue(t) & mask) << offset;
|
||||
|
||||
offset += (int)fieldLength;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
public static long ToLong<T>(T t) where T : struct
|
||||
{
|
||||
long r = 0;
|
||||
int offset = 0;
|
||||
|
||||
// For every field suitably attributed with a BitfieldLength
|
||||
foreach (System.Reflection.FieldInfo f in t.GetType().GetFields())
|
||||
{
|
||||
object[] attrs = f.GetCustomAttributes(typeof(BitfieldLengthAttribute), false);
|
||||
if (attrs.Length == 1)
|
||||
{
|
||||
uint fieldLength = ((BitfieldLengthAttribute)attrs[0]).Length;
|
||||
|
||||
// Calculate a bitmask of the desired length
|
||||
long mask = 0;
|
||||
for (int i = 0; i < fieldLength; i++)
|
||||
mask |= 1L << i;
|
||||
|
||||
r |= ((UInt32)f.GetValue(t) & mask) << offset;
|
||||
|
||||
offset += (int)fieldLength;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
477
Common Class Lib/Blowfish.cs
Normal file
477
Common Class Lib/Blowfish.cs
Normal file
|
@ -0,0 +1,477 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015-2019 Project Meteor Dev Team
|
||||
|
||||
This file is part of Project Meteor Server.
|
||||
|
||||
Project Meteor Server is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Project Meteor Server 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Meteor.Common
|
||||
{
|
||||
public class Blowfish
|
||||
{
|
||||
const int N = 16;
|
||||
UInt32 [] P = new uint[16 + 2];
|
||||
UInt32 [,] S = new UInt32[4,256];
|
||||
|
||||
#region P and S Values
|
||||
|
||||
byte [] P_values =
|
||||
{
|
||||
0x88, 0x6A, 0x3F, 0x24, 0xD3, 0x08, 0xA3, 0x85, 0x2E, 0x8A, 0x19, 0x13, 0x44, 0x73, 0x70, 0x03,
|
||||
0x22, 0x38, 0x09, 0xA4, 0xD0, 0x31, 0x9F, 0x29, 0x98, 0xFA, 0x2E, 0x08, 0x89, 0x6C, 0x4E, 0xEC,
|
||||
0xE6, 0x21, 0x28, 0x45, 0x77, 0x13, 0xD0, 0x38, 0xCF, 0x66, 0x54, 0xBE, 0x6C, 0x0C, 0xE9, 0x34,
|
||||
0xB7, 0x29, 0xAC, 0xC0, 0xDD, 0x50, 0x7C, 0xC9, 0xB5, 0xD5, 0x84, 0x3F, 0x17, 0x09, 0x47, 0xB5,
|
||||
0xD9, 0xD5, 0x16, 0x92, 0x1B, 0xFB, 0x79, 0x89
|
||||
};
|
||||
|
||||
byte [] S_values =
|
||||
{
|
||||
0xA6, 0x0B, 0x31, 0xD1, 0xAC, 0xB5, 0xDF, 0x98, 0xDB, 0x72, 0xFD, 0x2F, 0xB7, 0xDF, 0x1A, 0xD0,
|
||||
0xED, 0xAF, 0xE1, 0xB8, 0x96, 0x7E, 0x26, 0x6A, 0x45, 0x90, 0x7C, 0xBA, 0x99, 0x7F, 0x2C, 0xF1,
|
||||
0x47, 0x99, 0xA1, 0x24, 0xF7, 0x6C, 0x91, 0xB3, 0xE2, 0xF2, 0x01, 0x08, 0x16, 0xFC, 0x8E, 0x85,
|
||||
0xD8, 0x20, 0x69, 0x63, 0x69, 0x4E, 0x57, 0x71, 0xA3, 0xFE, 0x58, 0xA4, 0x7E, 0x3D, 0x93, 0xF4,
|
||||
0x8F, 0x74, 0x95, 0x0D, 0x58, 0xB6, 0x8E, 0x72, 0x58, 0xCD, 0x8B, 0x71, 0xEE, 0x4A, 0x15, 0x82,
|
||||
0x1D, 0xA4, 0x54, 0x7B, 0xB5, 0x59, 0x5A, 0xC2, 0x39, 0xD5, 0x30, 0x9C, 0x13, 0x60, 0xF2, 0x2A,
|
||||
0x23, 0xB0, 0xD1, 0xC5, 0xF0, 0x85, 0x60, 0x28, 0x18, 0x79, 0x41, 0xCA, 0xEF, 0x38, 0xDB, 0xB8,
|
||||
0xB0, 0xDC, 0x79, 0x8E, 0x0E, 0x18, 0x3A, 0x60, 0x8B, 0x0E, 0x9E, 0x6C, 0x3E, 0x8A, 0x1E, 0xB0,
|
||||
0xC1, 0x77, 0x15, 0xD7, 0x27, 0x4B, 0x31, 0xBD, 0xDA, 0x2F, 0xAF, 0x78, 0x60, 0x5C, 0x60, 0x55,
|
||||
0xF3, 0x25, 0x55, 0xE6, 0x94, 0xAB, 0x55, 0xAA, 0x62, 0x98, 0x48, 0x57, 0x40, 0x14, 0xE8, 0x63,
|
||||
0x6A, 0x39, 0xCA, 0x55, 0xB6, 0x10, 0xAB, 0x2A, 0x34, 0x5C, 0xCC, 0xB4, 0xCE, 0xE8, 0x41, 0x11,
|
||||
0xAF, 0x86, 0x54, 0xA1, 0x93, 0xE9, 0x72, 0x7C, 0x11, 0x14, 0xEE, 0xB3, 0x2A, 0xBC, 0x6F, 0x63,
|
||||
0x5D, 0xC5, 0xA9, 0x2B, 0xF6, 0x31, 0x18, 0x74, 0x16, 0x3E, 0x5C, 0xCE, 0x1E, 0x93, 0x87, 0x9B,
|
||||
0x33, 0xBA, 0xD6, 0xAF, 0x5C, 0xCF, 0x24, 0x6C, 0x81, 0x53, 0x32, 0x7A, 0x77, 0x86, 0x95, 0x28,
|
||||
0x98, 0x48, 0x8F, 0x3B, 0xAF, 0xB9, 0x4B, 0x6B, 0x1B, 0xE8, 0xBF, 0xC4, 0x93, 0x21, 0x28, 0x66,
|
||||
0xCC, 0x09, 0xD8, 0x61, 0x91, 0xA9, 0x21, 0xFB, 0x60, 0xAC, 0x7C, 0x48, 0x32, 0x80, 0xEC, 0x5D,
|
||||
0x5D, 0x5D, 0x84, 0xEF, 0xB1, 0x75, 0x85, 0xE9, 0x02, 0x23, 0x26, 0xDC, 0x88, 0x1B, 0x65, 0xEB,
|
||||
0x81, 0x3E, 0x89, 0x23, 0xC5, 0xAC, 0x96, 0xD3, 0xF3, 0x6F, 0x6D, 0x0F, 0x39, 0x42, 0xF4, 0x83,
|
||||
0x82, 0x44, 0x0B, 0x2E, 0x04, 0x20, 0x84, 0xA4, 0x4A, 0xF0, 0xC8, 0x69, 0x5E, 0x9B, 0x1F, 0x9E,
|
||||
0x42, 0x68, 0xC6, 0x21, 0x9A, 0x6C, 0xE9, 0xF6, 0x61, 0x9C, 0x0C, 0x67, 0xF0, 0x88, 0xD3, 0xAB,
|
||||
0xD2, 0xA0, 0x51, 0x6A, 0x68, 0x2F, 0x54, 0xD8, 0x28, 0xA7, 0x0F, 0x96, 0xA3, 0x33, 0x51, 0xAB,
|
||||
0x6C, 0x0B, 0xEF, 0x6E, 0xE4, 0x3B, 0x7A, 0x13, 0x50, 0xF0, 0x3B, 0xBA, 0x98, 0x2A, 0xFB, 0x7E,
|
||||
0x1D, 0x65, 0xF1, 0xA1, 0x76, 0x01, 0xAF, 0x39, 0x3E, 0x59, 0xCA, 0x66, 0x88, 0x0E, 0x43, 0x82,
|
||||
0x19, 0x86, 0xEE, 0x8C, 0xB4, 0x9F, 0x6F, 0x45, 0xC3, 0xA5, 0x84, 0x7D, 0xBE, 0x5E, 0x8B, 0x3B,
|
||||
0xD8, 0x75, 0x6F, 0xE0, 0x73, 0x20, 0xC1, 0x85, 0x9F, 0x44, 0x1A, 0x40, 0xA6, 0x6A, 0xC1, 0x56,
|
||||
0x62, 0xAA, 0xD3, 0x4E, 0x06, 0x77, 0x3F, 0x36, 0x72, 0xDF, 0xFE, 0x1B, 0x3D, 0x02, 0x9B, 0x42,
|
||||
0x24, 0xD7, 0xD0, 0x37, 0x48, 0x12, 0x0A, 0xD0, 0xD3, 0xEA, 0x0F, 0xDB, 0x9B, 0xC0, 0xF1, 0x49,
|
||||
0xC9, 0x72, 0x53, 0x07, 0x7B, 0x1B, 0x99, 0x80, 0xD8, 0x79, 0xD4, 0x25, 0xF7, 0xDE, 0xE8, 0xF6,
|
||||
0x1A, 0x50, 0xFE, 0xE3, 0x3B, 0x4C, 0x79, 0xB6, 0xBD, 0xE0, 0x6C, 0x97, 0xBA, 0x06, 0xC0, 0x04,
|
||||
0xB6, 0x4F, 0xA9, 0xC1, 0xC4, 0x60, 0x9F, 0x40, 0xC2, 0x9E, 0x5C, 0x5E, 0x63, 0x24, 0x6A, 0x19,
|
||||
0xAF, 0x6F, 0xFB, 0x68, 0xB5, 0x53, 0x6C, 0x3E, 0xEB, 0xB2, 0x39, 0x13, 0x6F, 0xEC, 0x52, 0x3B,
|
||||
0x1F, 0x51, 0xFC, 0x6D, 0x2C, 0x95, 0x30, 0x9B, 0x44, 0x45, 0x81, 0xCC, 0x09, 0xBD, 0x5E, 0xAF,
|
||||
0x04, 0xD0, 0xE3, 0xBE, 0xFD, 0x4A, 0x33, 0xDE, 0x07, 0x28, 0x0F, 0x66, 0xB3, 0x4B, 0x2E, 0x19,
|
||||
0x57, 0xA8, 0xCB, 0xC0, 0x0F, 0x74, 0xC8, 0x45, 0x39, 0x5F, 0x0B, 0xD2, 0xDB, 0xFB, 0xD3, 0xB9,
|
||||
0xBD, 0xC0, 0x79, 0x55, 0x0A, 0x32, 0x60, 0x1A, 0xC6, 0x00, 0xA1, 0xD6, 0x79, 0x72, 0x2C, 0x40,
|
||||
0xFE, 0x25, 0x9F, 0x67, 0xCC, 0xA3, 0x1F, 0xFB, 0xF8, 0xE9, 0xA5, 0x8E, 0xF8, 0x22, 0x32, 0xDB,
|
||||
0xDF, 0x16, 0x75, 0x3C, 0x15, 0x6B, 0x61, 0xFD, 0xC8, 0x1E, 0x50, 0x2F, 0xAB, 0x52, 0x05, 0xAD,
|
||||
0xFA, 0xB5, 0x3D, 0x32, 0x60, 0x87, 0x23, 0xFD, 0x48, 0x7B, 0x31, 0x53, 0x82, 0xDF, 0x00, 0x3E,
|
||||
0xBB, 0x57, 0x5C, 0x9E, 0xA0, 0x8C, 0x6F, 0xCA, 0x2E, 0x56, 0x87, 0x1A, 0xDB, 0x69, 0x17, 0xDF,
|
||||
0xF6, 0xA8, 0x42, 0xD5, 0xC3, 0xFF, 0x7E, 0x28, 0xC6, 0x32, 0x67, 0xAC, 0x73, 0x55, 0x4F, 0x8C,
|
||||
0xB0, 0x27, 0x5B, 0x69, 0xC8, 0x58, 0xCA, 0xBB, 0x5D, 0xA3, 0xFF, 0xE1, 0xA0, 0x11, 0xF0, 0xB8,
|
||||
0x98, 0x3D, 0xFA, 0x10, 0xB8, 0x83, 0x21, 0xFD, 0x6C, 0xB5, 0xFC, 0x4A, 0x5B, 0xD3, 0xD1, 0x2D,
|
||||
0x79, 0xE4, 0x53, 0x9A, 0x65, 0x45, 0xF8, 0xB6, 0xBC, 0x49, 0x8E, 0xD2, 0x90, 0x97, 0xFB, 0x4B,
|
||||
0xDA, 0xF2, 0xDD, 0xE1, 0x33, 0x7E, 0xCB, 0xA4, 0x41, 0x13, 0xFB, 0x62, 0xE8, 0xC6, 0xE4, 0xCE,
|
||||
0xDA, 0xCA, 0x20, 0xEF, 0x01, 0x4C, 0x77, 0x36, 0xFE, 0x9E, 0x7E, 0xD0, 0xB4, 0x1F, 0xF1, 0x2B,
|
||||
0x4D, 0xDA, 0xDB, 0x95, 0x98, 0x91, 0x90, 0xAE, 0x71, 0x8E, 0xAD, 0xEA, 0xA0, 0xD5, 0x93, 0x6B,
|
||||
0xD0, 0xD1, 0x8E, 0xD0, 0xE0, 0x25, 0xC7, 0xAF, 0x2F, 0x5B, 0x3C, 0x8E, 0xB7, 0x94, 0x75, 0x8E,
|
||||
0xFB, 0xE2, 0xF6, 0x8F, 0x64, 0x2B, 0x12, 0xF2, 0x12, 0xB8, 0x88, 0x88, 0x1C, 0xF0, 0x0D, 0x90,
|
||||
0xA0, 0x5E, 0xAD, 0x4F, 0x1C, 0xC3, 0x8F, 0x68, 0x91, 0xF1, 0xCF, 0xD1, 0xAD, 0xC1, 0xA8, 0xB3,
|
||||
0x18, 0x22, 0x2F, 0x2F, 0x77, 0x17, 0x0E, 0xBE, 0xFE, 0x2D, 0x75, 0xEA, 0xA1, 0x1F, 0x02, 0x8B,
|
||||
0x0F, 0xCC, 0xA0, 0xE5, 0xE8, 0x74, 0x6F, 0xB5, 0xD6, 0xF3, 0xAC, 0x18, 0x99, 0xE2, 0x89, 0xCE,
|
||||
0xE0, 0x4F, 0xA8, 0xB4, 0xB7, 0xE0, 0x13, 0xFD, 0x81, 0x3B, 0xC4, 0x7C, 0xD9, 0xA8, 0xAD, 0xD2,
|
||||
0x66, 0xA2, 0x5F, 0x16, 0x05, 0x77, 0x95, 0x80, 0x14, 0x73, 0xCC, 0x93, 0x77, 0x14, 0x1A, 0x21,
|
||||
0x65, 0x20, 0xAD, 0xE6, 0x86, 0xFA, 0xB5, 0x77, 0xF5, 0x42, 0x54, 0xC7, 0xCF, 0x35, 0x9D, 0xFB,
|
||||
0x0C, 0xAF, 0xCD, 0xEB, 0xA0, 0x89, 0x3E, 0x7B, 0xD3, 0x1B, 0x41, 0xD6, 0x49, 0x7E, 0x1E, 0xAE,
|
||||
0x2D, 0x0E, 0x25, 0x00, 0x5E, 0xB3, 0x71, 0x20, 0xBB, 0x00, 0x68, 0x22, 0xAF, 0xE0, 0xB8, 0x57,
|
||||
0x9B, 0x36, 0x64, 0x24, 0x1E, 0xB9, 0x09, 0xF0, 0x1D, 0x91, 0x63, 0x55, 0xAA, 0xA6, 0xDF, 0x59,
|
||||
0x89, 0x43, 0xC1, 0x78, 0x7F, 0x53, 0x5A, 0xD9, 0xA2, 0x5B, 0x7D, 0x20, 0xC5, 0xB9, 0xE5, 0x02,
|
||||
0x76, 0x03, 0x26, 0x83, 0xA9, 0xCF, 0x95, 0x62, 0x68, 0x19, 0xC8, 0x11, 0x41, 0x4A, 0x73, 0x4E,
|
||||
0xCA, 0x2D, 0x47, 0xB3, 0x4A, 0xA9, 0x14, 0x7B, 0x52, 0x00, 0x51, 0x1B, 0x15, 0x29, 0x53, 0x9A,
|
||||
0x3F, 0x57, 0x0F, 0xD6, 0xE4, 0xC6, 0x9B, 0xBC, 0x76, 0xA4, 0x60, 0x2B, 0x00, 0x74, 0xE6, 0x81,
|
||||
0xB5, 0x6F, 0xBA, 0x08, 0x1F, 0xE9, 0x1B, 0x57, 0x6B, 0xEC, 0x96, 0xF2, 0x15, 0xD9, 0x0D, 0x2A,
|
||||
0x21, 0x65, 0x63, 0xB6, 0xB6, 0xF9, 0xB9, 0xE7, 0x2E, 0x05, 0x34, 0xFF, 0x64, 0x56, 0x85, 0xC5,
|
||||
0x5D, 0x2D, 0xB0, 0x53, 0xA1, 0x8F, 0x9F, 0xA9, 0x99, 0x47, 0xBA, 0x08, 0x6A, 0x07, 0x85, 0x6E,
|
||||
0xE9, 0x70, 0x7A, 0x4B, 0x44, 0x29, 0xB3, 0xB5, 0x2E, 0x09, 0x75, 0xDB, 0x23, 0x26, 0x19, 0xC4,
|
||||
0xB0, 0xA6, 0x6E, 0xAD, 0x7D, 0xDF, 0xA7, 0x49, 0xB8, 0x60, 0xEE, 0x9C, 0x66, 0xB2, 0xED, 0x8F,
|
||||
0x71, 0x8C, 0xAA, 0xEC, 0xFF, 0x17, 0x9A, 0x69, 0x6C, 0x52, 0x64, 0x56, 0xE1, 0x9E, 0xB1, 0xC2,
|
||||
0xA5, 0x02, 0x36, 0x19, 0x29, 0x4C, 0x09, 0x75, 0x40, 0x13, 0x59, 0xA0, 0x3E, 0x3A, 0x18, 0xE4,
|
||||
0x9A, 0x98, 0x54, 0x3F, 0x65, 0x9D, 0x42, 0x5B, 0xD6, 0xE4, 0x8F, 0x6B, 0xD6, 0x3F, 0xF7, 0x99,
|
||||
0x07, 0x9C, 0xD2, 0xA1, 0xF5, 0x30, 0xE8, 0xEF, 0xE6, 0x38, 0x2D, 0x4D, 0xC1, 0x5D, 0x25, 0xF0,
|
||||
0x86, 0x20, 0xDD, 0x4C, 0x26, 0xEB, 0x70, 0x84, 0xC6, 0xE9, 0x82, 0x63, 0x5E, 0xCC, 0x1E, 0x02,
|
||||
0x3F, 0x6B, 0x68, 0x09, 0xC9, 0xEF, 0xBA, 0x3E, 0x14, 0x18, 0x97, 0x3C, 0xA1, 0x70, 0x6A, 0x6B,
|
||||
0x84, 0x35, 0x7F, 0x68, 0x86, 0xE2, 0xA0, 0x52, 0x05, 0x53, 0x9C, 0xB7, 0x37, 0x07, 0x50, 0xAA,
|
||||
0x1C, 0x84, 0x07, 0x3E, 0x5C, 0xAE, 0xDE, 0x7F, 0xEC, 0x44, 0x7D, 0x8E, 0xB8, 0xF2, 0x16, 0x57,
|
||||
0x37, 0xDA, 0x3A, 0xB0, 0x0D, 0x0C, 0x50, 0xF0, 0x04, 0x1F, 0x1C, 0xF0, 0xFF, 0xB3, 0x00, 0x02,
|
||||
0x1A, 0xF5, 0x0C, 0xAE, 0xB2, 0x74, 0xB5, 0x3C, 0x58, 0x7A, 0x83, 0x25, 0xBD, 0x21, 0x09, 0xDC,
|
||||
0xF9, 0x13, 0x91, 0xD1, 0xF6, 0x2F, 0xA9, 0x7C, 0x73, 0x47, 0x32, 0x94, 0x01, 0x47, 0xF5, 0x22,
|
||||
0x81, 0xE5, 0xE5, 0x3A, 0xDC, 0xDA, 0xC2, 0x37, 0x34, 0x76, 0xB5, 0xC8, 0xA7, 0xDD, 0xF3, 0x9A,
|
||||
0x46, 0x61, 0x44, 0xA9, 0x0E, 0x03, 0xD0, 0x0F, 0x3E, 0xC7, 0xC8, 0xEC, 0x41, 0x1E, 0x75, 0xA4,
|
||||
0x99, 0xCD, 0x38, 0xE2, 0x2F, 0x0E, 0xEA, 0x3B, 0xA1, 0xBB, 0x80, 0x32, 0x31, 0xB3, 0x3E, 0x18,
|
||||
0x38, 0x8B, 0x54, 0x4E, 0x08, 0xB9, 0x6D, 0x4F, 0x03, 0x0D, 0x42, 0x6F, 0xBF, 0x04, 0x0A, 0xF6,
|
||||
0x90, 0x12, 0xB8, 0x2C, 0x79, 0x7C, 0x97, 0x24, 0x72, 0xB0, 0x79, 0x56, 0xAF, 0x89, 0xAF, 0xBC,
|
||||
0x1F, 0x77, 0x9A, 0xDE, 0x10, 0x08, 0x93, 0xD9, 0x12, 0xAE, 0x8B, 0xB3, 0x2E, 0x3F, 0xCF, 0xDC,
|
||||
0x1F, 0x72, 0x12, 0x55, 0x24, 0x71, 0x6B, 0x2E, 0xE6, 0xDD, 0x1A, 0x50, 0x87, 0xCD, 0x84, 0x9F,
|
||||
0x18, 0x47, 0x58, 0x7A, 0x17, 0xDA, 0x08, 0x74, 0xBC, 0x9A, 0x9F, 0xBC, 0x8C, 0x7D, 0x4B, 0xE9,
|
||||
0x3A, 0xEC, 0x7A, 0xEC, 0xFA, 0x1D, 0x85, 0xDB, 0x66, 0x43, 0x09, 0x63, 0xD2, 0xC3, 0x64, 0xC4,
|
||||
0x47, 0x18, 0x1C, 0xEF, 0x08, 0xD9, 0x15, 0x32, 0x37, 0x3B, 0x43, 0xDD, 0x16, 0xBA, 0xC2, 0x24,
|
||||
0x43, 0x4D, 0xA1, 0x12, 0x51, 0xC4, 0x65, 0x2A, 0x02, 0x00, 0x94, 0x50, 0xDD, 0xE4, 0x3A, 0x13,
|
||||
0x9E, 0xF8, 0xDF, 0x71, 0x55, 0x4E, 0x31, 0x10, 0xD6, 0x77, 0xAC, 0x81, 0x9B, 0x19, 0x11, 0x5F,
|
||||
0xF1, 0x56, 0x35, 0x04, 0x6B, 0xC7, 0xA3, 0xD7, 0x3B, 0x18, 0x11, 0x3C, 0x09, 0xA5, 0x24, 0x59,
|
||||
0xED, 0xE6, 0x8F, 0xF2, 0xFA, 0xFB, 0xF1, 0x97, 0x2C, 0xBF, 0xBA, 0x9E, 0x6E, 0x3C, 0x15, 0x1E,
|
||||
0x70, 0x45, 0xE3, 0x86, 0xB1, 0x6F, 0xE9, 0xEA, 0x0A, 0x5E, 0x0E, 0x86, 0xB3, 0x2A, 0x3E, 0x5A,
|
||||
0x1C, 0xE7, 0x1F, 0x77, 0xFA, 0x06, 0x3D, 0x4E, 0xB9, 0xDC, 0x65, 0x29, 0x0F, 0x1D, 0xE7, 0x99,
|
||||
0xD6, 0x89, 0x3E, 0x80, 0x25, 0xC8, 0x66, 0x52, 0x78, 0xC9, 0x4C, 0x2E, 0x6A, 0xB3, 0x10, 0x9C,
|
||||
0xBA, 0x0E, 0x15, 0xC6, 0x78, 0xEA, 0xE2, 0x94, 0x53, 0x3C, 0xFC, 0xA5, 0xF4, 0x2D, 0x0A, 0x1E,
|
||||
0xA7, 0x4E, 0xF7, 0xF2, 0x3D, 0x2B, 0x1D, 0x36, 0x0F, 0x26, 0x39, 0x19, 0x60, 0x79, 0xC2, 0x19,
|
||||
0x08, 0xA7, 0x23, 0x52, 0xB6, 0x12, 0x13, 0xF7, 0x6E, 0xFE, 0xAD, 0xEB, 0x66, 0x1F, 0xC3, 0xEA,
|
||||
0x95, 0x45, 0xBC, 0xE3, 0x83, 0xC8, 0x7B, 0xA6, 0xD1, 0x37, 0x7F, 0xB1, 0x28, 0xFF, 0x8C, 0x01,
|
||||
0xEF, 0xDD, 0x32, 0xC3, 0xA5, 0x5A, 0x6C, 0xBE, 0x85, 0x21, 0x58, 0x65, 0x02, 0x98, 0xAB, 0x68,
|
||||
0x0F, 0xA5, 0xCE, 0xEE, 0x3B, 0x95, 0x2F, 0xDB, 0xAD, 0x7D, 0xEF, 0x2A, 0x84, 0x2F, 0x6E, 0x5B,
|
||||
0x28, 0xB6, 0x21, 0x15, 0x70, 0x61, 0x07, 0x29, 0x75, 0x47, 0xDD, 0xEC, 0x10, 0x15, 0x9F, 0x61,
|
||||
0x30, 0xA8, 0xCC, 0x13, 0x96, 0xBD, 0x61, 0xEB, 0x1E, 0xFE, 0x34, 0x03, 0xCF, 0x63, 0x03, 0xAA,
|
||||
0x90, 0x5C, 0x73, 0xB5, 0x39, 0xA2, 0x70, 0x4C, 0x0B, 0x9E, 0x9E, 0xD5, 0x14, 0xDE, 0xAA, 0xCB,
|
||||
0xBC, 0x86, 0xCC, 0xEE, 0xA7, 0x2C, 0x62, 0x60, 0xAB, 0x5C, 0xAB, 0x9C, 0x6E, 0x84, 0xF3, 0xB2,
|
||||
0xAF, 0x1E, 0x8B, 0x64, 0xCA, 0xF0, 0xBD, 0x19, 0xB9, 0x69, 0x23, 0xA0, 0x50, 0xBB, 0x5A, 0x65,
|
||||
0x32, 0x5A, 0x68, 0x40, 0xB3, 0xB4, 0x2A, 0x3C, 0xD5, 0xE9, 0x9E, 0x31, 0xF7, 0xB8, 0x21, 0xC0,
|
||||
0x19, 0x0B, 0x54, 0x9B, 0x99, 0xA0, 0x5F, 0x87, 0x7E, 0x99, 0xF7, 0x95, 0xA8, 0x7D, 0x3D, 0x62,
|
||||
0x9A, 0x88, 0x37, 0xF8, 0x77, 0x2D, 0xE3, 0x97, 0x5F, 0x93, 0xED, 0x11, 0x81, 0x12, 0x68, 0x16,
|
||||
0x29, 0x88, 0x35, 0x0E, 0xD6, 0x1F, 0xE6, 0xC7, 0xA1, 0xDF, 0xDE, 0x96, 0x99, 0xBA, 0x58, 0x78,
|
||||
0xA5, 0x84, 0xF5, 0x57, 0x63, 0x72, 0x22, 0x1B, 0xFF, 0xC3, 0x83, 0x9B, 0x96, 0x46, 0xC2, 0x1A,
|
||||
0xEB, 0x0A, 0xB3, 0xCD, 0x54, 0x30, 0x2E, 0x53, 0xE4, 0x48, 0xD9, 0x8F, 0x28, 0x31, 0xBC, 0x6D,
|
||||
0xEF, 0xF2, 0xEB, 0x58, 0xEA, 0xFF, 0xC6, 0x34, 0x61, 0xED, 0x28, 0xFE, 0x73, 0x3C, 0x7C, 0xEE,
|
||||
0xD9, 0x14, 0x4A, 0x5D, 0xE3, 0xB7, 0x64, 0xE8, 0x14, 0x5D, 0x10, 0x42, 0xE0, 0x13, 0x3E, 0x20,
|
||||
0xB6, 0xE2, 0xEE, 0x45, 0xEA, 0xAB, 0xAA, 0xA3, 0x15, 0x4F, 0x6C, 0xDB, 0xD0, 0x4F, 0xCB, 0xFA,
|
||||
0x42, 0xF4, 0x42, 0xC7, 0xB5, 0xBB, 0x6A, 0xEF, 0x1D, 0x3B, 0x4F, 0x65, 0x05, 0x21, 0xCD, 0x41,
|
||||
0x9E, 0x79, 0x1E, 0xD8, 0xC7, 0x4D, 0x85, 0x86, 0x6A, 0x47, 0x4B, 0xE4, 0x50, 0x62, 0x81, 0x3D,
|
||||
0xF2, 0xA1, 0x62, 0xCF, 0x46, 0x26, 0x8D, 0x5B, 0xA0, 0x83, 0x88, 0xFC, 0xA3, 0xB6, 0xC7, 0xC1,
|
||||
0xC3, 0x24, 0x15, 0x7F, 0x92, 0x74, 0xCB, 0x69, 0x0B, 0x8A, 0x84, 0x47, 0x85, 0xB2, 0x92, 0x56,
|
||||
0x00, 0xBF, 0x5B, 0x09, 0x9D, 0x48, 0x19, 0xAD, 0x74, 0xB1, 0x62, 0x14, 0x00, 0x0E, 0x82, 0x23,
|
||||
0x2A, 0x8D, 0x42, 0x58, 0xEA, 0xF5, 0x55, 0x0C, 0x3E, 0xF4, 0xAD, 0x1D, 0x61, 0x70, 0x3F, 0x23,
|
||||
0x92, 0xF0, 0x72, 0x33, 0x41, 0x7E, 0x93, 0x8D, 0xF1, 0xEC, 0x5F, 0xD6, 0xDB, 0x3B, 0x22, 0x6C,
|
||||
0x59, 0x37, 0xDE, 0x7C, 0x60, 0x74, 0xEE, 0xCB, 0xA7, 0xF2, 0x85, 0x40, 0x6E, 0x32, 0x77, 0xCE,
|
||||
0x84, 0x80, 0x07, 0xA6, 0x9E, 0x50, 0xF8, 0x19, 0x55, 0xD8, 0xEF, 0xE8, 0x35, 0x97, 0xD9, 0x61,
|
||||
0xAA, 0xA7, 0x69, 0xA9, 0xC2, 0x06, 0x0C, 0xC5, 0xFC, 0xAB, 0x04, 0x5A, 0xDC, 0xCA, 0x0B, 0x80,
|
||||
0x2E, 0x7A, 0x44, 0x9E, 0x84, 0x34, 0x45, 0xC3, 0x05, 0x67, 0xD5, 0xFD, 0xC9, 0x9E, 0x1E, 0x0E,
|
||||
0xD3, 0xDB, 0x73, 0xDB, 0xCD, 0x88, 0x55, 0x10, 0x79, 0xDA, 0x5F, 0x67, 0x40, 0x43, 0x67, 0xE3,
|
||||
0x65, 0x34, 0xC4, 0xC5, 0xD8, 0x38, 0x3E, 0x71, 0x9E, 0xF8, 0x28, 0x3D, 0x20, 0xFF, 0x6D, 0xF1,
|
||||
0xE7, 0x21, 0x3E, 0x15, 0x4A, 0x3D, 0xB0, 0x8F, 0x2B, 0x9F, 0xE3, 0xE6, 0xF7, 0xAD, 0x83, 0xDB,
|
||||
0x68, 0x5A, 0x3D, 0xE9, 0xF7, 0x40, 0x81, 0x94, 0x1C, 0x26, 0x4C, 0xF6, 0x34, 0x29, 0x69, 0x94,
|
||||
0xF7, 0x20, 0x15, 0x41, 0xF7, 0xD4, 0x02, 0x76, 0x2E, 0x6B, 0xF4, 0xBC, 0x68, 0x00, 0xA2, 0xD4,
|
||||
0x71, 0x24, 0x08, 0xD4, 0x6A, 0xF4, 0x20, 0x33, 0xB7, 0xD4, 0xB7, 0x43, 0xAF, 0x61, 0x00, 0x50,
|
||||
0x2E, 0xF6, 0x39, 0x1E, 0x46, 0x45, 0x24, 0x97, 0x74, 0x4F, 0x21, 0x14, 0x40, 0x88, 0x8B, 0xBF,
|
||||
0x1D, 0xFC, 0x95, 0x4D, 0xAF, 0x91, 0xB5, 0x96, 0xD3, 0xDD, 0xF4, 0x70, 0x45, 0x2F, 0xA0, 0x66,
|
||||
0xEC, 0x09, 0xBC, 0xBF, 0x85, 0x97, 0xBD, 0x03, 0xD0, 0x6D, 0xAC, 0x7F, 0x04, 0x85, 0xCB, 0x31,
|
||||
0xB3, 0x27, 0xEB, 0x96, 0x41, 0x39, 0xFD, 0x55, 0xE6, 0x47, 0x25, 0xDA, 0x9A, 0x0A, 0xCA, 0xAB,
|
||||
0x25, 0x78, 0x50, 0x28, 0xF4, 0x29, 0x04, 0x53, 0xDA, 0x86, 0x2C, 0x0A, 0xFB, 0x6D, 0xB6, 0xE9,
|
||||
0x62, 0x14, 0xDC, 0x68, 0x00, 0x69, 0x48, 0xD7, 0xA4, 0xC0, 0x0E, 0x68, 0xEE, 0x8D, 0xA1, 0x27,
|
||||
0xA2, 0xFE, 0x3F, 0x4F, 0x8C, 0xAD, 0x87, 0xE8, 0x06, 0xE0, 0x8C, 0xB5, 0xB6, 0xD6, 0xF4, 0x7A,
|
||||
0x7C, 0x1E, 0xCE, 0xAA, 0xEC, 0x5F, 0x37, 0xD3, 0x99, 0xA3, 0x78, 0xCE, 0x42, 0x2A, 0x6B, 0x40,
|
||||
0x35, 0x9E, 0xFE, 0x20, 0xB9, 0x85, 0xF3, 0xD9, 0xAB, 0xD7, 0x39, 0xEE, 0x8B, 0x4E, 0x12, 0x3B,
|
||||
0xF7, 0xFA, 0xC9, 0x1D, 0x56, 0x18, 0x6D, 0x4B, 0x31, 0x66, 0xA3, 0x26, 0xB2, 0x97, 0xE3, 0xEA,
|
||||
0x74, 0xFA, 0x6E, 0x3A, 0x32, 0x43, 0x5B, 0xDD, 0xF7, 0xE7, 0x41, 0x68, 0xFB, 0x20, 0x78, 0xCA,
|
||||
0x4E, 0xF5, 0x0A, 0xFB, 0x97, 0xB3, 0xFE, 0xD8, 0xAC, 0x56, 0x40, 0x45, 0x27, 0x95, 0x48, 0xBA,
|
||||
0x3A, 0x3A, 0x53, 0x55, 0x87, 0x8D, 0x83, 0x20, 0xB7, 0xA9, 0x6B, 0xFE, 0x4B, 0x95, 0x96, 0xD0,
|
||||
0xBC, 0x67, 0xA8, 0x55, 0x58, 0x9A, 0x15, 0xA1, 0x63, 0x29, 0xA9, 0xCC, 0x33, 0xDB, 0xE1, 0x99,
|
||||
0x56, 0x4A, 0x2A, 0xA6, 0xF9, 0x25, 0x31, 0x3F, 0x1C, 0x7E, 0xF4, 0x5E, 0x7C, 0x31, 0x29, 0x90,
|
||||
0x02, 0xE8, 0xF8, 0xFD, 0x70, 0x2F, 0x27, 0x04, 0x5C, 0x15, 0xBB, 0x80, 0xE3, 0x2C, 0x28, 0x05,
|
||||
0x48, 0x15, 0xC1, 0x95, 0x22, 0x6D, 0xC6, 0xE4, 0x3F, 0x13, 0xC1, 0x48, 0xDC, 0x86, 0x0F, 0xC7,
|
||||
0xEE, 0xC9, 0xF9, 0x07, 0x0F, 0x1F, 0x04, 0x41, 0xA4, 0x79, 0x47, 0x40, 0x17, 0x6E, 0x88, 0x5D,
|
||||
0xEB, 0x51, 0x5F, 0x32, 0xD1, 0xC0, 0x9B, 0xD5, 0x8F, 0xC1, 0xBC, 0xF2, 0x64, 0x35, 0x11, 0x41,
|
||||
0x34, 0x78, 0x7B, 0x25, 0x60, 0x9C, 0x2A, 0x60, 0xA3, 0xE8, 0xF8, 0xDF, 0x1B, 0x6C, 0x63, 0x1F,
|
||||
0xC2, 0xB4, 0x12, 0x0E, 0x9E, 0x32, 0xE1, 0x02, 0xD1, 0x4F, 0x66, 0xAF, 0x15, 0x81, 0xD1, 0xCA,
|
||||
0xE0, 0x95, 0x23, 0x6B, 0xE1, 0x92, 0x3E, 0x33, 0x62, 0x0B, 0x24, 0x3B, 0x22, 0xB9, 0xBE, 0xEE,
|
||||
0x0E, 0xA2, 0xB2, 0x85, 0x99, 0x0D, 0xBA, 0xE6, 0x8C, 0x0C, 0x72, 0xDE, 0x28, 0xF7, 0xA2, 0x2D,
|
||||
0x45, 0x78, 0x12, 0xD0, 0xFD, 0x94, 0xB7, 0x95, 0x62, 0x08, 0x7D, 0x64, 0xF0, 0xF5, 0xCC, 0xE7,
|
||||
0x6F, 0xA3, 0x49, 0x54, 0xFA, 0x48, 0x7D, 0x87, 0x27, 0xFD, 0x9D, 0xC3, 0x1E, 0x8D, 0x3E, 0xF3,
|
||||
0x41, 0x63, 0x47, 0x0A, 0x74, 0xFF, 0x2E, 0x99, 0xAB, 0x6E, 0x6F, 0x3A, 0x37, 0xFD, 0xF8, 0xF4,
|
||||
0x60, 0xDC, 0x12, 0xA8, 0xF8, 0xDD, 0xEB, 0xA1, 0x4C, 0xE1, 0x1B, 0x99, 0x0D, 0x6B, 0x6E, 0xDB,
|
||||
0x10, 0x55, 0x7B, 0xC6, 0x37, 0x2C, 0x67, 0x6D, 0x3B, 0xD4, 0x65, 0x27, 0x04, 0xE8, 0xD0, 0xDC,
|
||||
0xC7, 0x0D, 0x29, 0xF1, 0xA3, 0xFF, 0x00, 0xCC, 0x92, 0x0F, 0x39, 0xB5, 0x0B, 0xED, 0x0F, 0x69,
|
||||
0xFB, 0x9F, 0x7B, 0x66, 0x9C, 0x7D, 0xDB, 0xCE, 0x0B, 0xCF, 0x91, 0xA0, 0xA3, 0x5E, 0x15, 0xD9,
|
||||
0x88, 0x2F, 0x13, 0xBB, 0x24, 0xAD, 0x5B, 0x51, 0xBF, 0x79, 0x94, 0x7B, 0xEB, 0xD6, 0x3B, 0x76,
|
||||
0xB3, 0x2E, 0x39, 0x37, 0x79, 0x59, 0x11, 0xCC, 0x97, 0xE2, 0x26, 0x80, 0x2D, 0x31, 0x2E, 0xF4,
|
||||
0xA7, 0xAD, 0x42, 0x68, 0x3B, 0x2B, 0x6A, 0xC6, 0xCC, 0x4C, 0x75, 0x12, 0x1C, 0xF1, 0x2E, 0x78,
|
||||
0x37, 0x42, 0x12, 0x6A, 0xE7, 0x51, 0x92, 0xB7, 0xE6, 0xBB, 0xA1, 0x06, 0x50, 0x63, 0xFB, 0x4B,
|
||||
0x18, 0x10, 0x6B, 0x1A, 0xFA, 0xED, 0xCA, 0x11, 0xD8, 0xBD, 0x25, 0x3D, 0xC9, 0xC3, 0xE1, 0xE2,
|
||||
0x59, 0x16, 0x42, 0x44, 0x86, 0x13, 0x12, 0x0A, 0x6E, 0xEC, 0x0C, 0xD9, 0x2A, 0xEA, 0xAB, 0xD5,
|
||||
0x4E, 0x67, 0xAF, 0x64, 0x5F, 0xA8, 0x86, 0xDA, 0x88, 0xE9, 0xBF, 0xBE, 0xFE, 0xC3, 0xE4, 0x64,
|
||||
0x57, 0x80, 0xBC, 0x9D, 0x86, 0xC0, 0xF7, 0xF0, 0xF8, 0x7B, 0x78, 0x60, 0x4D, 0x60, 0x03, 0x60,
|
||||
0x46, 0x83, 0xFD, 0xD1, 0xB0, 0x1F, 0x38, 0xF6, 0x04, 0xAE, 0x45, 0x77, 0xCC, 0xFC, 0x36, 0xD7,
|
||||
0x33, 0x6B, 0x42, 0x83, 0x71, 0xAB, 0x1E, 0xF0, 0x87, 0x41, 0x80, 0xB0, 0x5F, 0x5E, 0x00, 0x3C,
|
||||
0xBE, 0x57, 0xA0, 0x77, 0x24, 0xAE, 0xE8, 0xBD, 0x99, 0x42, 0x46, 0x55, 0x61, 0x2E, 0x58, 0xBF,
|
||||
0x8F, 0xF4, 0x58, 0x4E, 0xA2, 0xFD, 0xDD, 0xF2, 0x38, 0xEF, 0x74, 0xF4, 0xC2, 0xBD, 0x89, 0x87,
|
||||
0xC3, 0xF9, 0x66, 0x53, 0x74, 0x8E, 0xB3, 0xC8, 0x55, 0xF2, 0x75, 0xB4, 0xB9, 0xD9, 0xFC, 0x46,
|
||||
0x61, 0x26, 0xEB, 0x7A, 0x84, 0xDF, 0x1D, 0x8B, 0x79, 0x0E, 0x6A, 0x84, 0xE2, 0x95, 0x5F, 0x91,
|
||||
0x8E, 0x59, 0x6E, 0x46, 0x70, 0x57, 0xB4, 0x20, 0x91, 0x55, 0xD5, 0x8C, 0x4C, 0xDE, 0x02, 0xC9,
|
||||
0xE1, 0xAC, 0x0B, 0xB9, 0xD0, 0x05, 0x82, 0xBB, 0x48, 0x62, 0xA8, 0x11, 0x9E, 0xA9, 0x74, 0x75,
|
||||
0xB6, 0x19, 0x7F, 0xB7, 0x09, 0xDC, 0xA9, 0xE0, 0xA1, 0x09, 0x2D, 0x66, 0x33, 0x46, 0x32, 0xC4,
|
||||
0x02, 0x1F, 0x5A, 0xE8, 0x8C, 0xBE, 0xF0, 0x09, 0x25, 0xA0, 0x99, 0x4A, 0x10, 0xFE, 0x6E, 0x1D,
|
||||
0x1D, 0x3D, 0xB9, 0x1A, 0xDF, 0xA4, 0xA5, 0x0B, 0x0F, 0xF2, 0x86, 0xA1, 0x69, 0xF1, 0x68, 0x28,
|
||||
0x83, 0xDA, 0xB7, 0xDC, 0xFE, 0x06, 0x39, 0x57, 0x9B, 0xCE, 0xE2, 0xA1, 0x52, 0x7F, 0xCD, 0x4F,
|
||||
0x01, 0x5E, 0x11, 0x50, 0xFA, 0x83, 0x06, 0xA7, 0xC4, 0xB5, 0x02, 0xA0, 0x27, 0xD0, 0xE6, 0x0D,
|
||||
0x27, 0x8C, 0xF8, 0x9A, 0x41, 0x86, 0x3F, 0x77, 0x06, 0x4C, 0x60, 0xC3, 0xB5, 0x06, 0xA8, 0x61,
|
||||
0x28, 0x7A, 0x17, 0xF0, 0xE0, 0x86, 0xF5, 0xC0, 0xAA, 0x58, 0x60, 0x00, 0x62, 0x7D, 0xDC, 0x30,
|
||||
0xD7, 0x9E, 0xE6, 0x11, 0x63, 0xEA, 0x38, 0x23, 0x94, 0xDD, 0xC2, 0x53, 0x34, 0x16, 0xC2, 0xC2,
|
||||
0x56, 0xEE, 0xCB, 0xBB, 0xDE, 0xB6, 0xBC, 0x90, 0xA1, 0x7D, 0xFC, 0xEB, 0x76, 0x1D, 0x59, 0xCE,
|
||||
0x09, 0xE4, 0x05, 0x6F, 0x88, 0x01, 0x7C, 0x4B, 0x3D, 0x0A, 0x72, 0x39, 0x24, 0x7C, 0x92, 0x7C,
|
||||
0x5F, 0x72, 0xE3, 0x86, 0xB9, 0x9D, 0x4D, 0x72, 0xB4, 0x5B, 0xC1, 0x1A, 0xFC, 0xB8, 0x9E, 0xD3,
|
||||
0x78, 0x55, 0x54, 0xED, 0xB5, 0xA5, 0xFC, 0x08, 0xD3, 0x7C, 0x3D, 0xD8, 0xC4, 0x0F, 0xAD, 0x4D,
|
||||
0x5E, 0xEF, 0x50, 0x1E, 0xF8, 0xE6, 0x61, 0xB1, 0xD9, 0x14, 0x85, 0xA2, 0x3C, 0x13, 0x51, 0x6C,
|
||||
0xE7, 0xC7, 0xD5, 0x6F, 0xC4, 0x4E, 0xE1, 0x56, 0xCE, 0xBF, 0x2A, 0x36, 0x37, 0xC8, 0xC6, 0xDD,
|
||||
0x34, 0x32, 0x9A, 0xD7, 0x12, 0x82, 0x63, 0x92, 0x8E, 0xFA, 0x0E, 0x67, 0xE0, 0x00, 0x60, 0x40,
|
||||
0x37, 0xCE, 0x39, 0x3A, 0xCF, 0xF5, 0xFA, 0xD3, 0x37, 0x77, 0xC2, 0xAB, 0x1B, 0x2D, 0xC5, 0x5A,
|
||||
0x9E, 0x67, 0xB0, 0x5C, 0x42, 0x37, 0xA3, 0x4F, 0x40, 0x27, 0x82, 0xD3, 0xBE, 0x9B, 0xBC, 0x99,
|
||||
0x9D, 0x8E, 0x11, 0xD5, 0x15, 0x73, 0x0F, 0xBF, 0x7E, 0x1C, 0x2D, 0xD6, 0x7B, 0xC4, 0x00, 0xC7,
|
||||
0x6B, 0x1B, 0x8C, 0xB7, 0x45, 0x90, 0xA1, 0x21, 0xBE, 0xB1, 0x6E, 0xB2, 0xB4, 0x6E, 0x36, 0x6A,
|
||||
0x2F, 0xAB, 0x48, 0x57, 0x79, 0x6E, 0x94, 0xBC, 0xD2, 0x76, 0xA3, 0xC6, 0xC8, 0xC2, 0x49, 0x65,
|
||||
0xEE, 0xF8, 0x0F, 0x53, 0x7D, 0xDE, 0x8D, 0x46, 0x1D, 0x0A, 0x73, 0xD5, 0xC6, 0x4D, 0xD0, 0x4C,
|
||||
0xDB, 0xBB, 0x39, 0x29, 0x50, 0x46, 0xBA, 0xA9, 0xE8, 0x26, 0x95, 0xAC, 0x04, 0xE3, 0x5E, 0xBE,
|
||||
0xF0, 0xD5, 0xFA, 0xA1, 0x9A, 0x51, 0x2D, 0x6A, 0xE2, 0x8C, 0xEF, 0x63, 0x22, 0xEE, 0x86, 0x9A,
|
||||
0xB8, 0xC2, 0x89, 0xC0, 0xF6, 0x2E, 0x24, 0x43, 0xAA, 0x03, 0x1E, 0xA5, 0xA4, 0xD0, 0xF2, 0x9C,
|
||||
0xBA, 0x61, 0xC0, 0x83, 0x4D, 0x6A, 0xE9, 0x9B, 0x50, 0x15, 0xE5, 0x8F, 0xD6, 0x5B, 0x64, 0xBA,
|
||||
0xF9, 0xA2, 0x26, 0x28, 0xE1, 0x3A, 0x3A, 0xA7, 0x86, 0x95, 0xA9, 0x4B, 0xE9, 0x62, 0x55, 0xEF,
|
||||
0xD3, 0xEF, 0x2F, 0xC7, 0xDA, 0xF7, 0x52, 0xF7, 0x69, 0x6F, 0x04, 0x3F, 0x59, 0x0A, 0xFA, 0x77,
|
||||
0x15, 0xA9, 0xE4, 0x80, 0x01, 0x86, 0xB0, 0x87, 0xAD, 0xE6, 0x09, 0x9B, 0x93, 0xE5, 0x3E, 0x3B,
|
||||
0x5A, 0xFD, 0x90, 0xE9, 0x97, 0xD7, 0x34, 0x9E, 0xD9, 0xB7, 0xF0, 0x2C, 0x51, 0x8B, 0x2B, 0x02,
|
||||
0x3A, 0xAC, 0xD5, 0x96, 0x7D, 0xA6, 0x7D, 0x01, 0xD6, 0x3E, 0xCF, 0xD1, 0x28, 0x2D, 0x7D, 0x7C,
|
||||
0xCF, 0x25, 0x9F, 0x1F, 0x9B, 0xB8, 0xF2, 0xAD, 0x72, 0xB4, 0xD6, 0x5A, 0x4C, 0xF5, 0x88, 0x5A,
|
||||
0x71, 0xAC, 0x29, 0xE0, 0xE6, 0xA5, 0x19, 0xE0, 0xFD, 0xAC, 0xB0, 0x47, 0x9B, 0xFA, 0x93, 0xED,
|
||||
0x8D, 0xC4, 0xD3, 0xE8, 0xCC, 0x57, 0x3B, 0x28, 0x29, 0x66, 0xD5, 0xF8, 0x28, 0x2E, 0x13, 0x79,
|
||||
0x91, 0x01, 0x5F, 0x78, 0x55, 0x60, 0x75, 0xED, 0x44, 0x0E, 0x96, 0xF7, 0x8C, 0x5E, 0xD3, 0xE3,
|
||||
0xD4, 0x6D, 0x05, 0x15, 0xBA, 0x6D, 0xF4, 0x88, 0x25, 0x61, 0xA1, 0x03, 0xBD, 0xF0, 0x64, 0x05,
|
||||
0x15, 0x9E, 0xEB, 0xC3, 0xA2, 0x57, 0x90, 0x3C, 0xEC, 0x1A, 0x27, 0x97, 0x2A, 0x07, 0x3A, 0xA9,
|
||||
0x9B, 0x6D, 0x3F, 0x1B, 0xF5, 0x21, 0x63, 0x1E, 0xFB, 0x66, 0x9C, 0xF5, 0x19, 0xF3, 0xDC, 0x26,
|
||||
0x28, 0xD9, 0x33, 0x75, 0xF5, 0xFD, 0x55, 0xB1, 0x82, 0x34, 0x56, 0x03, 0xBB, 0x3C, 0xBA, 0x8A,
|
||||
0x11, 0x77, 0x51, 0x28, 0xF8, 0xD9, 0x0A, 0xC2, 0x67, 0x51, 0xCC, 0xAB, 0x5F, 0x92, 0xAD, 0xCC,
|
||||
0x51, 0x17, 0xE8, 0x4D, 0x8E, 0xDC, 0x30, 0x38, 0x62, 0x58, 0x9D, 0x37, 0x91, 0xF9, 0x20, 0x93,
|
||||
0xC2, 0x90, 0x7A, 0xEA, 0xCE, 0x7B, 0x3E, 0xFB, 0x64, 0xCE, 0x21, 0x51, 0x32, 0xBE, 0x4F, 0x77,
|
||||
0x7E, 0xE3, 0xB6, 0xA8, 0x46, 0x3D, 0x29, 0xC3, 0x69, 0x53, 0xDE, 0x48, 0x80, 0xE6, 0x13, 0x64,
|
||||
0x10, 0x08, 0xAE, 0xA2, 0x24, 0xB2, 0x6D, 0xDD, 0xFD, 0x2D, 0x85, 0x69, 0x66, 0x21, 0x07, 0x09,
|
||||
0x0A, 0x46, 0x9A, 0xB3, 0xDD, 0xC0, 0x45, 0x64, 0xCF, 0xDE, 0x6C, 0x58, 0xAE, 0xC8, 0x20, 0x1C,
|
||||
0xDD, 0xF7, 0xBE, 0x5B, 0x40, 0x8D, 0x58, 0x1B, 0x7F, 0x01, 0xD2, 0xCC, 0xBB, 0xE3, 0xB4, 0x6B,
|
||||
0x7E, 0x6A, 0xA2, 0xDD, 0x45, 0xFF, 0x59, 0x3A, 0x44, 0x0A, 0x35, 0x3E, 0xD5, 0xCD, 0xB4, 0xBC,
|
||||
0xA8, 0xCE, 0xEA, 0x72, 0xBB, 0x84, 0x64, 0xFA, 0xAE, 0x12, 0x66, 0x8D, 0x47, 0x6F, 0x3C, 0xBF,
|
||||
0x63, 0xE4, 0x9B, 0xD2, 0x9E, 0x5D, 0x2F, 0x54, 0x1B, 0x77, 0xC2, 0xAE, 0x70, 0x63, 0x4E, 0xF6,
|
||||
0x8D, 0x0D, 0x0E, 0x74, 0x57, 0x13, 0x5B, 0xE7, 0x71, 0x16, 0x72, 0xF8, 0x5D, 0x7D, 0x53, 0xAF,
|
||||
0x08, 0xCB, 0x40, 0x40, 0xCC, 0xE2, 0xB4, 0x4E, 0x6A, 0x46, 0xD2, 0x34, 0x84, 0xAF, 0x15, 0x01,
|
||||
0x28, 0x04, 0xB0, 0xE1, 0x1D, 0x3A, 0x98, 0x95, 0xB4, 0x9F, 0xB8, 0x06, 0x48, 0xA0, 0x6E, 0xCE,
|
||||
0x82, 0x3B, 0x3F, 0x6F, 0x82, 0xAB, 0x20, 0x35, 0x4B, 0x1D, 0x1A, 0x01, 0xF8, 0x27, 0x72, 0x27,
|
||||
0xB1, 0x60, 0x15, 0x61, 0xDC, 0x3F, 0x93, 0xE7, 0x2B, 0x79, 0x3A, 0xBB, 0xBD, 0x25, 0x45, 0x34,
|
||||
0xE1, 0x39, 0x88, 0xA0, 0x4B, 0x79, 0xCE, 0x51, 0xB7, 0xC9, 0x32, 0x2F, 0xC9, 0xBA, 0x1F, 0xA0,
|
||||
0x7E, 0xC8, 0x1C, 0xE0, 0xF6, 0xD1, 0xC7, 0xBC, 0xC3, 0x11, 0x01, 0xCF, 0xC7, 0xAA, 0xE8, 0xA1,
|
||||
0x49, 0x87, 0x90, 0x1A, 0x9A, 0xBD, 0x4F, 0xD4, 0xCB, 0xDE, 0xDA, 0xD0, 0x38, 0xDA, 0x0A, 0xD5,
|
||||
0x2A, 0xC3, 0x39, 0x03, 0x67, 0x36, 0x91, 0xC6, 0x7C, 0x31, 0xF9, 0x8D, 0x4F, 0x2B, 0xB1, 0xE0,
|
||||
0xB7, 0x59, 0x9E, 0xF7, 0x3A, 0xBB, 0xF5, 0x43, 0xFF, 0x19, 0xD5, 0xF2, 0x9C, 0x45, 0xD9, 0x27,
|
||||
0x2C, 0x22, 0x97, 0xBF, 0x2A, 0xFC, 0xE6, 0x15, 0x71, 0xFC, 0x91, 0x0F, 0x25, 0x15, 0x94, 0x9B,
|
||||
0x61, 0x93, 0xE5, 0xFA, 0xEB, 0x9C, 0xB6, 0xCE, 0x59, 0x64, 0xA8, 0xC2, 0xD1, 0xA8, 0xBA, 0x12,
|
||||
0x5E, 0x07, 0xC1, 0xB6, 0x0C, 0x6A, 0x05, 0xE3, 0x65, 0x50, 0xD2, 0x10, 0x42, 0xA4, 0x03, 0xCB,
|
||||
0x0E, 0x6E, 0xEC, 0xE0, 0x3B, 0xDB, 0x98, 0x16, 0xBE, 0xA0, 0x98, 0x4C, 0x64, 0xE9, 0x78, 0x32,
|
||||
0x32, 0x95, 0x1F, 0x9F, 0xDF, 0x92, 0xD3, 0xE0, 0x2B, 0x34, 0xA0, 0xD3, 0x1E, 0xF2, 0x71, 0x89,
|
||||
0x41, 0x74, 0x0A, 0x1B, 0x8C, 0x34, 0xA3, 0x4B, 0x20, 0x71, 0xBE, 0xC5, 0xD8, 0x32, 0x76, 0xC3,
|
||||
0x8D, 0x9F, 0x35, 0xDF, 0x2E, 0x2F, 0x99, 0x9B, 0x47, 0x6F, 0x0B, 0xE6, 0x1D, 0xF1, 0xE3, 0x0F,
|
||||
0x54, 0xDA, 0x4C, 0xE5, 0x91, 0xD8, 0xDA, 0x1E, 0xCF, 0x79, 0x62, 0xCE, 0x6F, 0x7E, 0x3E, 0xCD,
|
||||
0x66, 0xB1, 0x18, 0x16, 0x05, 0x1D, 0x2C, 0xFD, 0xC5, 0xD2, 0x8F, 0x84, 0x99, 0x22, 0xFB, 0xF6,
|
||||
0x57, 0xF3, 0x23, 0xF5, 0x23, 0x76, 0x32, 0xA6, 0x31, 0x35, 0xA8, 0x93, 0x02, 0xCD, 0xCC, 0x56,
|
||||
0x62, 0x81, 0xF0, 0xAC, 0xB5, 0xEB, 0x75, 0x5A, 0x97, 0x36, 0x16, 0x6E, 0xCC, 0x73, 0xD2, 0x88,
|
||||
0x92, 0x62, 0x96, 0xDE, 0xD0, 0x49, 0xB9, 0x81, 0x1B, 0x90, 0x50, 0x4C, 0x14, 0x56, 0xC6, 0x71,
|
||||
0xBD, 0xC7, 0xC6, 0xE6, 0x0A, 0x14, 0x7A, 0x32, 0x06, 0xD0, 0xE1, 0x45, 0x9A, 0x7B, 0xF2, 0xC3,
|
||||
0xFD, 0x53, 0xAA, 0xC9, 0x00, 0x0F, 0xA8, 0x62, 0xE2, 0xBF, 0x25, 0xBB, 0xF6, 0xD2, 0xBD, 0x35,
|
||||
0x05, 0x69, 0x12, 0x71, 0x22, 0x02, 0x04, 0xB2, 0x7C, 0xCF, 0xCB, 0xB6, 0x2B, 0x9C, 0x76, 0xCD,
|
||||
0xC0, 0x3E, 0x11, 0x53, 0xD3, 0xE3, 0x40, 0x16, 0x60, 0xBD, 0xAB, 0x38, 0xF0, 0xAD, 0x47, 0x25,
|
||||
0x9C, 0x20, 0x38, 0xBA, 0x76, 0xCE, 0x46, 0xF7, 0xC5, 0xA1, 0xAF, 0x77, 0x60, 0x60, 0x75, 0x20,
|
||||
0x4E, 0xFE, 0xCB, 0x85, 0xD8, 0x8D, 0xE8, 0x8A, 0xB0, 0xF9, 0xAA, 0x7A, 0x7E, 0xAA, 0xF9, 0x4C,
|
||||
0x5C, 0xC2, 0x48, 0x19, 0x8C, 0x8A, 0xFB, 0x02, 0xE4, 0x6A, 0xC3, 0x01, 0xF9, 0xE1, 0xEB, 0xD6,
|
||||
0x69, 0xF8, 0xD4, 0x90, 0xA0, 0xDE, 0x5C, 0xA6, 0x2D, 0x25, 0x09, 0x3F, 0x9F, 0xE6, 0x08, 0xC2,
|
||||
0x32, 0x61, 0x4E, 0xB7, 0x5B, 0xE2, 0x77, 0xCE, 0xE3, 0xDF, 0x8F, 0x57, 0xE6, 0x72, 0xC3, 0x3A
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
public Blowfish(byte[] key)
|
||||
{
|
||||
InitializeBlowfish(key);
|
||||
}
|
||||
|
||||
public void Encipher(byte[] data, int offset, int length)
|
||||
{
|
||||
if ((length - offset) % 8 != 0)
|
||||
throw new ArgumentException("Needs to be a multiple of 8");
|
||||
|
||||
for (int i = offset; i < offset + length; i += 8)
|
||||
{
|
||||
uint xl = (uint)((data[i + 0]) | (data[i + 1] << 8) | (data[i + 2] << 16) | (data[i + 3] << 24));
|
||||
uint xr = (uint)((data[i + 4]) | (data[i + 5] << 8) | (data[i + 6] << 16) | (data[i + 7] << 24));
|
||||
BlowfishEncipher(ref xl, ref xr);
|
||||
data[i + 0] = (byte)(xl >> 0);
|
||||
data[i + 1] = (byte)(xl >> 8);
|
||||
data[i + 2] = (byte)(xl >> 16);
|
||||
data[i + 3] = (byte)(xl >> 24);
|
||||
data[i + 4] = (byte)(xr >> 0);
|
||||
data[i + 5] = (byte)(xr >> 8);
|
||||
data[i + 6] = (byte)(xr >> 16);
|
||||
data[i + 7] = (byte)(xr >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
public void Decipher(byte[] data, int offset, int length)
|
||||
{
|
||||
if ((length - offset) % 8 != 0)
|
||||
throw new ArgumentException("Needs to be a multiple of 8");
|
||||
|
||||
for (int i = offset; i < offset + length; i += 8)
|
||||
{
|
||||
uint xl = (uint)((data[i + 0]) | (data[i + 1] << 8) | (data[i + 2] << 16) | (data[i + 3] << 24));
|
||||
uint xr = (uint)((data[i + 4]) | (data[i + 5] << 8) | (data[i + 6] << 16) | (data[i + 7] << 24));
|
||||
BlowfishDecipher(ref xl, ref xr);
|
||||
data[i + 0] = (byte)(xl >> 0);
|
||||
data[i + 1] = (byte)(xl >> 8);
|
||||
data[i + 2] = (byte)(xl >> 16);
|
||||
data[i + 3] = (byte)(xl >> 24);
|
||||
data[i + 4] = (byte)(xr >> 0);
|
||||
data[i + 5] = (byte)(xr >> 8);
|
||||
data[i + 6] = (byte)(xr >> 16);
|
||||
data[i + 7] = (byte)(xr >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
private UInt32 F(UInt32 x)
|
||||
{
|
||||
UInt16 a;
|
||||
UInt16 b;
|
||||
UInt16 c;
|
||||
UInt16 d;
|
||||
UInt32 y;
|
||||
|
||||
d = (UInt16)(x & 0x00FF);
|
||||
x >>= 8;
|
||||
c = (UInt16)(x & 0x00FF);
|
||||
x >>= 8;
|
||||
b = (UInt16)(x & 0x00FF);
|
||||
x >>= 8;
|
||||
a = (UInt16)(x & 0x00FF);
|
||||
//y = ((S[0][a] + S[1][b]) ^ S[2][c]) + S[3][d];
|
||||
y = S[0,a] + S[1,b];
|
||||
y = y ^ S[2,c];
|
||||
y = y + S[3,d];
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
private void BlowfishEncipher(ref UInt32 xl, ref UInt32 xr)
|
||||
{
|
||||
UInt32 temp;
|
||||
Int32 i;
|
||||
|
||||
for (i = 0; i < N; ++i) {
|
||||
xl = xl ^ P[i];
|
||||
xr = F(xl) ^ xr;
|
||||
|
||||
temp = xl;
|
||||
xl = xr;
|
||||
xr = temp;
|
||||
}
|
||||
|
||||
temp = xl;
|
||||
xl = xr;
|
||||
xr = temp;
|
||||
|
||||
xr = xr ^ P[N];
|
||||
xl = xl ^ P[N + 1];
|
||||
|
||||
}
|
||||
|
||||
private void BlowfishDecipher(ref UInt32 xl, ref UInt32 xr)
|
||||
{
|
||||
UInt32 temp;
|
||||
Int32 i;
|
||||
|
||||
for (i = N + 1; i > 1; --i) {
|
||||
xl = xl ^ P[i];
|
||||
xr = F(xl) ^ xr;
|
||||
|
||||
/* ExChange xl and xr */
|
||||
temp = xl;
|
||||
xl = xr;
|
||||
xr = temp;
|
||||
}
|
||||
|
||||
/* ExChange xl and xr */
|
||||
temp = xl;
|
||||
xl = xr;
|
||||
xr = temp;
|
||||
|
||||
xr = xr ^ P[1];
|
||||
xl = xl ^ P[0];
|
||||
|
||||
}
|
||||
|
||||
private int InitializeBlowfish(byte [] key)
|
||||
{
|
||||
Int16 i;
|
||||
Int16 j;
|
||||
Int16 k;
|
||||
|
||||
int data;
|
||||
uint datal;
|
||||
uint datar;
|
||||
|
||||
Buffer.BlockCopy(P_values, 0, P, 0, P_values.Length);
|
||||
Buffer.BlockCopy(S_values, 0, S, 0, S_values.Length);
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < N + 2; ++i)
|
||||
{
|
||||
data = 0x00000000;
|
||||
for (k = 0; k < 4; ++k)
|
||||
{
|
||||
data = (data << 8) | (SByte)key[j];
|
||||
j = (short)(j + 1);
|
||||
if (j >= key.Length)
|
||||
{
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
P[i] = P[i] ^ (uint)data;
|
||||
}
|
||||
|
||||
datal = 0x00000000;
|
||||
datar = 0x00000000;
|
||||
|
||||
for (i = 0; i < N + 2; i += 2)
|
||||
{
|
||||
BlowfishEncipher(ref datal, ref datar);
|
||||
|
||||
P[i] = datal;
|
||||
P[i + 1] = datar;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
for (j = 0; j < 256; j += 2)
|
||||
{
|
||||
BlowfishEncipher(ref datal, ref datar);
|
||||
S[i,j] = datal;
|
||||
S[i,j + 1] = datar;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
113
Common Class Lib/Common Class Lib.csproj
Normal file
113
Common Class Lib/Common Class Lib.csproj
Normal file
|
@ -0,0 +1,113 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\Microsoft.Net.Compilers.2.0.0-beta3\build\Microsoft.Net.Compilers.props" Condition="Exists('..\packages\Microsoft.Net.Compilers.2.0.0-beta3\build\Microsoft.Net.Compilers.props') AND '$(OS)' == 'Windows_NT'" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props') AND '$(OS)' == 'Windows_NT'" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{3A3D6626-C820-4C18-8C81-64811424F20E}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Meteor.Common</RootNamespace>
|
||||
<AssemblyName>Meteor.Common</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
<NuGetPackageImportStamp>792e4711</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="DotNetZip">
|
||||
<HintPath>..\packages\DotNetZip.1.10.1\lib\net20\DotNetZip.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.4.3.5\lib\net45\NLog.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BasePacket.cs" />
|
||||
<Compile Include="Bitfield.cs" />
|
||||
<Compile Include="Blowfish.cs" />
|
||||
<Compile Include="EfficientHashTables.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Sql.cs" />
|
||||
<Compile Include="STA_INIFile.cs" />
|
||||
<Compile Include="SubPacket.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
<Compile Include="Vector3.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Net.Compilers.2.0.0-beta3\build\Microsoft.Net.Compilers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Net.Compilers.2.0.0-beta3\build\Microsoft.Net.Compilers.props'))" />
|
||||
</Target>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
179
Common Class Lib/EfficientHashTables.cs
Normal file
179
Common Class Lib/EfficientHashTables.cs
Normal file
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015-2019 Project Meteor Dev Team
|
||||
|
||||
This file is part of Project Meteor Server.
|
||||
|
||||
Project Meteor Server is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Project Meteor Server 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Meteor.Common
|
||||
{
|
||||
namespace EfficientHashTables
|
||||
{
|
||||
public class Efficient64bitHashTable<T>
|
||||
{
|
||||
private class element
|
||||
{
|
||||
public ulong _key;
|
||||
public T _value;
|
||||
};
|
||||
private element[][] _buckets;
|
||||
private uint _capacity;
|
||||
|
||||
public Efficient64bitHashTable()
|
||||
{
|
||||
_capacity = 214373; // some prime number
|
||||
_buckets = new element[_capacity][];
|
||||
}
|
||||
public Efficient64bitHashTable(uint capacity)
|
||||
{
|
||||
_capacity = capacity;
|
||||
_buckets = new element[_capacity][];
|
||||
}
|
||||
|
||||
public uint Hash(ulong key)
|
||||
{
|
||||
return (uint)(key % _capacity);
|
||||
}
|
||||
|
||||
public void Add(ulong key, T value)
|
||||
{
|
||||
uint hsh = Hash(key);
|
||||
element[] e;
|
||||
if (_buckets[hsh] == null)
|
||||
_buckets[hsh] = e = new element[1];
|
||||
else
|
||||
{
|
||||
foreach (var elem in _buckets[hsh])
|
||||
if (elem._key == key)
|
||||
{
|
||||
elem._value = value;
|
||||
return;
|
||||
}
|
||||
e = new element[_buckets[hsh].Length + 1];
|
||||
Array.Copy(_buckets[hsh], 0, e, 1, _buckets[hsh].Length);
|
||||
_buckets[hsh] = e;
|
||||
}
|
||||
e[0] = new element { _key = key, _value = value };
|
||||
}
|
||||
|
||||
public T Get(ulong key)
|
||||
{
|
||||
uint hsh = Hash(key);
|
||||
element[] e = _buckets[hsh];
|
||||
if (e == null) return default(T);
|
||||
foreach (var f in e)
|
||||
if (f._key == key)
|
||||
return f._value;
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public bool Has(ulong key)
|
||||
{
|
||||
uint hsh = Hash(key);
|
||||
element[] e = _buckets[hsh];
|
||||
if (e == null) return false;
|
||||
foreach (var f in e)
|
||||
if (f._key == key)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public int Count()
|
||||
{
|
||||
int r = 0;
|
||||
foreach (var e in _buckets)
|
||||
if (e != null)
|
||||
r += e.Length;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
public class Efficient32bitHashTable<T>
|
||||
{
|
||||
private class element
|
||||
{
|
||||
public uint _key;
|
||||
public T _value;
|
||||
};
|
||||
private element[][] _buckets;
|
||||
private uint _capacity;
|
||||
|
||||
public Efficient32bitHashTable()
|
||||
{
|
||||
_capacity = 463; // some prime number
|
||||
_buckets = new element[_capacity][];
|
||||
}
|
||||
public Efficient32bitHashTable(uint capacity)
|
||||
{
|
||||
_capacity = capacity;
|
||||
_buckets = new element[_capacity][];
|
||||
}
|
||||
|
||||
public uint Hash(uint key)
|
||||
{
|
||||
return (uint)(key % _capacity);
|
||||
}
|
||||
|
||||
public void Add(uint key, T value)
|
||||
{
|
||||
uint hsh = Hash(key);
|
||||
element[] e;
|
||||
if (_buckets[hsh] == null)
|
||||
_buckets[hsh] = e = new element[1];
|
||||
else
|
||||
{
|
||||
foreach (var elem in _buckets[hsh])
|
||||
if (elem._key == key)
|
||||
{
|
||||
elem._value = value;
|
||||
return;
|
||||
}
|
||||
e = new element[_buckets[hsh].Length + 1];
|
||||
Array.Copy(_buckets[hsh], 0, e, 1, _buckets[hsh].Length);
|
||||
_buckets[hsh] = e;
|
||||
}
|
||||
e[0] = new element { _key = key, _value = value };
|
||||
}
|
||||
|
||||
public T Get(uint key)
|
||||
{
|
||||
uint hsh = Hash(key);
|
||||
element[] e = _buckets[hsh];
|
||||
if (e == null) return default(T);
|
||||
foreach (var f in e)
|
||||
if (f._key == key)
|
||||
return f._value;
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public int Count()
|
||||
{
|
||||
int r = 0;
|
||||
foreach (var e in _buckets)
|
||||
if (e != null)
|
||||
r += e.Length;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
35
Common Class Lib/Properties/AssemblyInfo.cs
Normal file
35
Common Class Lib/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
using System.Reflection;
|
||||
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("FFXIVClassic.Common")]
|
||||
[assembly: AssemblyDescription("Common class library for FFXIVClassic project")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("ffxivclassic.fragmenterworks.com")]
|
||||
[assembly: AssemblyProduct("FFXIVClassic.Common")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("3a3d6626-c820-4c18-8c81-64811424f20e")]
|
||||
|
||||
// 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")]
|
541
Common Class Lib/STA_INIFile.cs
Normal file
541
Common Class Lib/STA_INIFile.cs
Normal file
|
@ -0,0 +1,541 @@
|
|||
// *******************************
|
||||
// *** INIFile class V2.1 ***
|
||||
// *******************************
|
||||
// *** (C)2009-2013 S.T.A. snc ***
|
||||
// *******************************
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Meteor.Common
|
||||
{
|
||||
public class INIFile
|
||||
{
|
||||
|
||||
#region "Declarations"
|
||||
|
||||
// *** Lock for thread-safe access to file and local cache ***
|
||||
private object m_Lock = new object();
|
||||
|
||||
// *** File name ***
|
||||
private string m_FileName = null;
|
||||
internal string FileName
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_FileName;
|
||||
}
|
||||
}
|
||||
|
||||
// *** Lazy loading flag ***
|
||||
private bool m_Lazy = false;
|
||||
|
||||
// *** Automatic flushing flag ***
|
||||
private bool m_AutoFlush = false;
|
||||
|
||||
// *** Local cache ***
|
||||
private Dictionary<string, Dictionary<string, string>> m_Sections = new Dictionary<string, Dictionary<string, string>>();
|
||||
private Dictionary<string, Dictionary<string, string>> m_Modified = new Dictionary<string, Dictionary<string, string>>();
|
||||
|
||||
// *** Local cache modified flag ***
|
||||
private bool m_CacheModified = false;
|
||||
|
||||
#endregion
|
||||
|
||||
#region "Methods"
|
||||
|
||||
// *** Constructor ***
|
||||
public INIFile(string FileName)
|
||||
{
|
||||
Initialize(FileName, false, false);
|
||||
}
|
||||
|
||||
public INIFile(string FileName, bool Lazy, bool AutoFlush)
|
||||
{
|
||||
Initialize(FileName, Lazy, AutoFlush);
|
||||
}
|
||||
|
||||
// *** Initialization ***
|
||||
private void Initialize(string FileName, bool Lazy, bool AutoFlush)
|
||||
{
|
||||
m_FileName = FileName;
|
||||
m_Lazy = Lazy;
|
||||
m_AutoFlush = AutoFlush;
|
||||
if (!m_Lazy) Refresh();
|
||||
}
|
||||
|
||||
// *** Parse section name ***
|
||||
private string ParseSectionName(string Line)
|
||||
{
|
||||
if (!Line.StartsWith("[")) return null;
|
||||
if (!Line.EndsWith("]")) return null;
|
||||
if (Line.Length < 3) return null;
|
||||
return Line.Substring(1, Line.Length - 2);
|
||||
}
|
||||
|
||||
// *** Parse key+value pair ***
|
||||
private bool ParseKeyValuePair(string Line, ref string Key, ref string Value)
|
||||
{
|
||||
// *** Check for key+value pair ***
|
||||
int i;
|
||||
if ((i = Line.IndexOf('=')) <= 0) return false;
|
||||
|
||||
int j = Line.Length - i - 1;
|
||||
Key = Line.Substring(0, i).Trim();
|
||||
if (Key.Length <= 0) return false;
|
||||
|
||||
Value = (j > 0) ? (Line.Substring(i + 1, j).Trim()) : ("");
|
||||
return true;
|
||||
}
|
||||
|
||||
// *** Read file contents into local cache ***
|
||||
internal void Refresh()
|
||||
{
|
||||
lock (m_Lock)
|
||||
{
|
||||
StreamReader sr = null;
|
||||
try
|
||||
{
|
||||
// *** Clear local cache ***
|
||||
m_Sections.Clear();
|
||||
m_Modified.Clear();
|
||||
|
||||
// *** Open the INI file ***
|
||||
try
|
||||
{
|
||||
sr = new StreamReader(m_FileName);
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// *** Read up the file content ***
|
||||
Dictionary<string, string> CurrentSection = null;
|
||||
string s;
|
||||
string SectionName;
|
||||
string Key = null;
|
||||
string Value = null;
|
||||
while ((s = sr.ReadLine()) != null)
|
||||
{
|
||||
s = s.Trim();
|
||||
|
||||
// *** Check for section names ***
|
||||
SectionName = ParseSectionName(s);
|
||||
if (SectionName != null)
|
||||
{
|
||||
// *** Only first occurrence of a section is loaded ***
|
||||
if (m_Sections.ContainsKey(SectionName))
|
||||
{
|
||||
CurrentSection = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentSection = new Dictionary<string, string>();
|
||||
m_Sections.Add(SectionName, CurrentSection);
|
||||
}
|
||||
}
|
||||
else if (CurrentSection != null)
|
||||
{
|
||||
// *** Check for key+value pair ***
|
||||
if (ParseKeyValuePair(s, ref Key, ref Value))
|
||||
{
|
||||
// *** Only first occurrence of a key is loaded ***
|
||||
if (!CurrentSection.ContainsKey(Key))
|
||||
{
|
||||
CurrentSection.Add(Key, Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// *** Cleanup: close file ***
|
||||
if (sr != null) sr.Close();
|
||||
sr = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *** Flush local cache content ***
|
||||
internal void Flush()
|
||||
{
|
||||
lock (m_Lock)
|
||||
{
|
||||
PerformFlush();
|
||||
}
|
||||
}
|
||||
|
||||
private void PerformFlush()
|
||||
{
|
||||
// *** If local cache was not modified, exit ***
|
||||
if (!m_CacheModified) return;
|
||||
m_CacheModified = false;
|
||||
|
||||
// *** Check if original file exists ***
|
||||
bool OriginalFileExists = File.Exists(m_FileName);
|
||||
|
||||
// *** get temporary file name ***
|
||||
string TmpFileName = Path.ChangeExtension(m_FileName, "$n$");
|
||||
|
||||
// *** Copy content of original file to temporary file, replace modified values ***
|
||||
StreamWriter sw = null;
|
||||
|
||||
// *** Create the temporary file ***
|
||||
sw = new StreamWriter(TmpFileName);
|
||||
|
||||
try
|
||||
{
|
||||
Dictionary<string, string> CurrentSection = null;
|
||||
if (OriginalFileExists)
|
||||
{
|
||||
StreamReader sr = null;
|
||||
try
|
||||
{
|
||||
// *** Open the original file ***
|
||||
sr = new StreamReader(m_FileName);
|
||||
|
||||
// *** Read the file original content, replace Changes with local cache values ***
|
||||
string s;
|
||||
string SectionName;
|
||||
string Key = null;
|
||||
string Value = null;
|
||||
bool Unmodified;
|
||||
bool Reading = true;
|
||||
while (Reading)
|
||||
{
|
||||
s = sr.ReadLine();
|
||||
Reading = (s != null);
|
||||
|
||||
// *** Check for end of file ***
|
||||
if (Reading)
|
||||
{
|
||||
Unmodified = true;
|
||||
s = s.Trim();
|
||||
SectionName = ParseSectionName(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
Unmodified = false;
|
||||
SectionName = null;
|
||||
}
|
||||
|
||||
// *** Check for section names ***
|
||||
if ((SectionName != null) || (!Reading))
|
||||
{
|
||||
if (CurrentSection != null)
|
||||
{
|
||||
// *** Write all remaining modified values before leaving a section ****
|
||||
if (CurrentSection.Count > 0)
|
||||
{
|
||||
foreach (string fkey in CurrentSection.Keys)
|
||||
{
|
||||
if (CurrentSection.TryGetValue(fkey, out Value))
|
||||
{
|
||||
sw.Write(fkey);
|
||||
sw.Write('=');
|
||||
sw.WriteLine(Value);
|
||||
}
|
||||
}
|
||||
sw.WriteLine();
|
||||
CurrentSection.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (Reading)
|
||||
{
|
||||
// *** Check if current section is in local modified cache ***
|
||||
if (!m_Modified.TryGetValue(SectionName, out CurrentSection))
|
||||
{
|
||||
CurrentSection = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (CurrentSection != null)
|
||||
{
|
||||
// *** Check for key+value pair ***
|
||||
if (ParseKeyValuePair(s, ref Key, ref Value))
|
||||
{
|
||||
if (CurrentSection.TryGetValue(Key, out Value))
|
||||
{
|
||||
// *** Write modified value to temporary file ***
|
||||
Unmodified = false;
|
||||
CurrentSection.Remove(Key);
|
||||
|
||||
sw.Write(Key);
|
||||
sw.Write('=');
|
||||
sw.WriteLine(Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *** Write unmodified lines from the original file ***
|
||||
if (Unmodified)
|
||||
{
|
||||
sw.WriteLine(s);
|
||||
}
|
||||
}
|
||||
|
||||
// *** Close the original file ***
|
||||
sr.Close();
|
||||
sr = null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// *** Cleanup: close files ***
|
||||
if (sr != null) sr.Close();
|
||||
sr = null;
|
||||
}
|
||||
}
|
||||
|
||||
// *** Cycle on all remaining modified values ***
|
||||
foreach (KeyValuePair<string, Dictionary<string, string>> SectionPair in m_Modified)
|
||||
{
|
||||
CurrentSection = SectionPair.Value;
|
||||
if (CurrentSection.Count > 0)
|
||||
{
|
||||
sw.WriteLine();
|
||||
|
||||
// *** Write the section name ***
|
||||
sw.Write('[');
|
||||
sw.Write(SectionPair.Key);
|
||||
sw.WriteLine(']');
|
||||
|
||||
// *** Cycle on all key+value pairs in the section ***
|
||||
foreach (KeyValuePair<string, string> ValuePair in CurrentSection)
|
||||
{
|
||||
// *** Write the key+value pair ***
|
||||
sw.Write(ValuePair.Key);
|
||||
sw.Write('=');
|
||||
sw.WriteLine(ValuePair.Value);
|
||||
}
|
||||
CurrentSection.Clear();
|
||||
}
|
||||
}
|
||||
m_Modified.Clear();
|
||||
|
||||
// *** Close the temporary file ***
|
||||
sw.Close();
|
||||
sw = null;
|
||||
|
||||
// *** Rename the temporary file ***
|
||||
File.Copy(TmpFileName, m_FileName, true);
|
||||
|
||||
// *** Delete the temporary file ***
|
||||
File.Delete(TmpFileName);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// *** Cleanup: close files ***
|
||||
if (sw != null) sw.Close();
|
||||
sw = null;
|
||||
}
|
||||
}
|
||||
|
||||
// *** Read a value from local cache ***
|
||||
public string GetValue(string SectionName, string Key, string DefaultValue)
|
||||
{
|
||||
// *** Lazy loading ***
|
||||
if (m_Lazy)
|
||||
{
|
||||
m_Lazy = false;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
lock (m_Lock)
|
||||
{
|
||||
// *** Check if the section exists ***
|
||||
Dictionary<string, string> Section;
|
||||
if (!m_Sections.TryGetValue(SectionName, out Section)) return DefaultValue;
|
||||
|
||||
// *** Check if the key exists ***
|
||||
string Value;
|
||||
if (!Section.TryGetValue(Key, out Value)) return DefaultValue;
|
||||
|
||||
// *** Return the found value ***
|
||||
return Value;
|
||||
}
|
||||
}
|
||||
|
||||
// *** Insert or modify a value in local cache ***
|
||||
internal void SetValue(string SectionName, string Key, string Value)
|
||||
{
|
||||
// *** Lazy loading ***
|
||||
if (m_Lazy)
|
||||
{
|
||||
m_Lazy = false;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
lock (m_Lock)
|
||||
{
|
||||
// *** Flag local cache modification ***
|
||||
m_CacheModified = true;
|
||||
|
||||
// *** Check if the section exists ***
|
||||
Dictionary<string, string> Section;
|
||||
if (!m_Sections.TryGetValue(SectionName, out Section))
|
||||
{
|
||||
// *** If it Doesn't, Add it ***
|
||||
Section = new Dictionary<string, string>();
|
||||
m_Sections.Add(SectionName,Section);
|
||||
}
|
||||
|
||||
// *** Modify the value ***
|
||||
if (Section.ContainsKey(Key)) Section.Remove(Key);
|
||||
Section.Add(Key, Value);
|
||||
|
||||
// *** Add the modified value to local modified values cache ***
|
||||
if (!m_Modified.TryGetValue(SectionName, out Section))
|
||||
{
|
||||
Section = new Dictionary<string, string>();
|
||||
m_Modified.Add(SectionName, Section);
|
||||
}
|
||||
|
||||
if (Section.ContainsKey(Key)) Section.Remove(Key);
|
||||
Section.Add(Key, Value);
|
||||
|
||||
// *** Automatic flushing : immediately write any modification to the file ***
|
||||
if (m_AutoFlush) PerformFlush();
|
||||
}
|
||||
}
|
||||
|
||||
// *** Encode byte array ***
|
||||
private string EncodeByteArray(byte[] Value)
|
||||
{
|
||||
if (Value == null) return null;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (byte b in Value)
|
||||
{
|
||||
string hex = Convert.ToString(b, 16);
|
||||
int l = hex.Length;
|
||||
if (l > 2)
|
||||
{
|
||||
sb.Append(hex.Substring(l - 2, 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (l < 2) sb.Append("0");
|
||||
sb.Append(hex);
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
// *** Decode byte array ***
|
||||
private byte[] DecodeByteArray(string Value)
|
||||
{
|
||||
if (Value == null) return null;
|
||||
|
||||
int l = Value.Length;
|
||||
if (l < 2) return new byte[] { };
|
||||
|
||||
l /= 2;
|
||||
byte[] Result = new byte[l];
|
||||
for (int i = 0; i < l; i++) Result[i] = Convert.ToByte(Value.Substring(i * 2, 2), 16);
|
||||
return Result;
|
||||
}
|
||||
|
||||
// *** Getters for various types ***
|
||||
internal bool GetValue(string SectionName, string Key, bool DefaultValue)
|
||||
{
|
||||
string StringValue = GetValue(SectionName, Key, DefaultValue.ToString(System.Globalization.CultureInfo.InvariantCulture));
|
||||
int Value;
|
||||
if (int.TryParse(StringValue, out Value)) return (Value != 0);
|
||||
return DefaultValue;
|
||||
}
|
||||
|
||||
internal int GetValue(string SectionName, string Key, int DefaultValue)
|
||||
{
|
||||
string StringValue = GetValue(SectionName, Key, DefaultValue.ToString(CultureInfo.InvariantCulture));
|
||||
int Value;
|
||||
if (int.TryParse(StringValue, NumberStyles.Any, CultureInfo.InvariantCulture, out Value)) return Value;
|
||||
return DefaultValue;
|
||||
}
|
||||
|
||||
internal uint GetValue(string SectionName, string Key, uint DefaultValue)
|
||||
{
|
||||
string StringValue = GetValue(SectionName, Key, DefaultValue.ToString(CultureInfo.InvariantCulture));
|
||||
uint Value;
|
||||
if (uint.TryParse(StringValue, NumberStyles.Any, CultureInfo.InvariantCulture, out Value)) return Value;
|
||||
return DefaultValue;
|
||||
}
|
||||
|
||||
internal long GetValue(string SectionName, string Key, long DefaultValue)
|
||||
{
|
||||
string StringValue = GetValue(SectionName, Key, DefaultValue.ToString(CultureInfo.InvariantCulture));
|
||||
long Value;
|
||||
if (long.TryParse(StringValue, NumberStyles.Any, CultureInfo.InvariantCulture, out Value)) return Value;
|
||||
return DefaultValue;
|
||||
}
|
||||
|
||||
internal Double GetValue(string SectionName, string Key, Double DefaultValue)
|
||||
{
|
||||
string StringValue = GetValue(SectionName, Key, DefaultValue.ToString(CultureInfo.InvariantCulture));
|
||||
double Value;
|
||||
if (double.TryParse(StringValue, NumberStyles.Any, CultureInfo.InvariantCulture, out Value)) return Value;
|
||||
return DefaultValue;
|
||||
}
|
||||
|
||||
internal byte[] GetValue(string SectionName, string Key, byte[] DefaultValue)
|
||||
{
|
||||
string StringValue = GetValue(SectionName, Key, EncodeByteArray(DefaultValue));
|
||||
try
|
||||
{
|
||||
return DecodeByteArray(StringValue);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
return DefaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
internal DateTime GetValue(string SectionName, string Key, DateTime DefaultValue)
|
||||
{
|
||||
string StringValue = GetValue(SectionName, Key, DefaultValue.ToString(CultureInfo.InvariantCulture));
|
||||
DateTime Value;
|
||||
if (DateTime.TryParse(StringValue, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.NoCurrentDateDefault | DateTimeStyles.AssumeLocal, out Value)) return Value;
|
||||
return DefaultValue;
|
||||
}
|
||||
|
||||
// *** Setters for various types ***
|
||||
internal void SetValue(string SectionName, string Key, bool Value)
|
||||
{
|
||||
SetValue(SectionName, Key, (Value) ? ("1") : ("0"));
|
||||
}
|
||||
|
||||
internal void SetValue(string SectionName, string Key, int Value)
|
||||
{
|
||||
SetValue(SectionName, Key, Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
internal void SetValue(string SectionName, string Key, long Value)
|
||||
{
|
||||
SetValue(SectionName, Key, Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
internal void SetValue(string SectionName, string Key, Double Value)
|
||||
{
|
||||
SetValue(SectionName, Key, Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
internal void SetValue(string SectionName, string Key, byte[] Value)
|
||||
{
|
||||
SetValue(SectionName, Key, EncodeByteArray(Value));
|
||||
}
|
||||
|
||||
internal void SetValue(string SectionName, string Key, DateTime Value)
|
||||
{
|
||||
SetValue(SectionName, Key, Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
}
|
33
Common Class Lib/Sql.cs
Normal file
33
Common Class Lib/Sql.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015-2019 Project Meteor Dev Team
|
||||
|
||||
This file is part of Project Meteor Server.
|
||||
|
||||
Project Meteor Server is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Project Meteor Server 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
using NLog;
|
||||
|
||||
namespace Meteor.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();
|
||||
}
|
||||
}
|
239
Common Class Lib/SubPacket.cs
Normal file
239
Common Class Lib/SubPacket.cs
Normal file
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015-2019 Project Meteor Dev Team
|
||||
|
||||
This file is part of Project Meteor Server.
|
||||
|
||||
Project Meteor Server is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Project Meteor Server 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using NLog;
|
||||
using NLog.Targets;
|
||||
|
||||
namespace Meteor.Common
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SubPacketHeader
|
||||
{
|
||||
public ushort subpacketSize;
|
||||
public ushort type;
|
||||
public uint sourceId;
|
||||
public uint targetId;
|
||||
public uint unknown1;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct GameMessageHeader
|
||||
{
|
||||
public ushort unknown4; //Always 0x14
|
||||
public ushort opcode;
|
||||
public uint unknown5;
|
||||
public uint timestamp;
|
||||
public uint unknown6;
|
||||
}
|
||||
|
||||
public class SubPacket
|
||||
{
|
||||
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 unsafe SubPacket(byte[] bytes, ref int offset)
|
||||
{
|
||||
if (bytes.Length < offset + SUBPACKET_SIZE)
|
||||
throw new OverflowException("Packet Error: Subpacket was too small");
|
||||
|
||||
fixed (byte* pdata = &bytes[offset])
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
if (bytes.Length < offset + header.subpacketSize)
|
||||
throw new OverflowException("Packet Error: Subpacket size didn't equal subpacket data");
|
||||
|
||||
if (header.type == 0x3)
|
||||
{
|
||||
data = new byte[header.subpacketSize - SUBPACKET_SIZE - GAMEMESSAGE_SIZE];
|
||||
Array.Copy(bytes, offset + SUBPACKET_SIZE + GAMEMESSAGE_SIZE, data, 0, data.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = new byte[header.subpacketSize - SUBPACKET_SIZE];
|
||||
Array.Copy(bytes, offset + SUBPACKET_SIZE, data, 0, data.Length);
|
||||
}
|
||||
|
||||
offset += header.subpacketSize;
|
||||
}
|
||||
|
||||
public SubPacket(ushort opcode, uint sourceId, byte[] data) : this(true, opcode, sourceId, data) { }
|
||||
|
||||
public SubPacket(bool isGameMessage, ushort opcode, uint sourceId, byte[] data)
|
||||
{
|
||||
header = new SubPacketHeader();
|
||||
|
||||
if (isGameMessage)
|
||||
{
|
||||
gameMessage = new GameMessageHeader();
|
||||
gameMessage.opcode = opcode;
|
||||
gameMessage.timestamp = Utils.UnixTimeStampUTC();
|
||||
gameMessage.unknown4 = 0x14;
|
||||
gameMessage.unknown5 = 0x00;
|
||||
gameMessage.unknown6 = 0x00;
|
||||
}
|
||||
|
||||
header.sourceId = sourceId;
|
||||
header.targetId = 0;
|
||||
|
||||
if (isGameMessage)
|
||||
header.type = 0x03;
|
||||
else
|
||||
header.type = opcode;
|
||||
|
||||
header.unknown1 = 0x00;
|
||||
|
||||
this.data = data;
|
||||
|
||||
header.subpacketSize = (ushort) (SUBPACKET_SIZE + data.Length);
|
||||
|
||||
if (isGameMessage)
|
||||
header.subpacketSize += GAMEMESSAGE_SIZE;
|
||||
}
|
||||
|
||||
public SubPacket(SubPacket original, uint newTargetId)
|
||||
{
|
||||
header = new SubPacketHeader();
|
||||
gameMessage = original.gameMessage;
|
||||
header.subpacketSize = original.header.subpacketSize;
|
||||
header.type = original.header.type;
|
||||
header.sourceId = original.header.sourceId;
|
||||
header.targetId = newTargetId;
|
||||
data = original.data;
|
||||
}
|
||||
|
||||
public void SetTargetId(uint target)
|
||||
{
|
||||
this.header.targetId = target;
|
||||
}
|
||||
|
||||
public byte[] GetHeaderBytes()
|
||||
{
|
||||
var size = Marshal.SizeOf(header);
|
||||
var arr = new byte[size];
|
||||
|
||||
var ptr = Marshal.AllocHGlobal(size);
|
||||
Marshal.StructureToPtr(header, ptr, true);
|
||||
Marshal.Copy(ptr, arr, 0, size);
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
return arr;
|
||||
}
|
||||
|
||||
public byte[] GetGameMessageBytes()
|
||||
{
|
||||
var size = Marshal.SizeOf(gameMessage);
|
||||
var arr = new byte[size];
|
||||
|
||||
var ptr = Marshal.AllocHGlobal(size);
|
||||
Marshal.StructureToPtr(gameMessage, ptr, true);
|
||||
Marshal.Copy(ptr, arr, 0, size);
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
return arr;
|
||||
}
|
||||
|
||||
public byte[] GetBytes()
|
||||
{
|
||||
var outBytes = new byte[header.subpacketSize];
|
||||
Array.Copy(GetHeaderBytes(), 0, outBytes, 0, SUBPACKET_SIZE);
|
||||
|
||||
if (header.type == 0x3)
|
||||
Array.Copy(GetGameMessageBytes(), 0, outBytes, SUBPACKET_SIZE, GAMEMESSAGE_SIZE);
|
||||
|
||||
Array.Copy(data, 0, outBytes, SUBPACKET_SIZE + (header.type == 0x3 ? GAMEMESSAGE_SIZE : 0), data.Length);
|
||||
return outBytes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a packet from the incoming buffer + offset. If a packet can be built, it is returned else null.
|
||||
/// </summary>
|
||||
/// <param name="offset">Current offset in buffer.</param>
|
||||
/// <param name="buffer">Incoming buffer.</param>
|
||||
/// <returns>Returns either a BasePacket or null if not enough data.</returns>
|
||||
public static SubPacket CreatePacket(ref int offset, byte[] buffer, int bytesRead)
|
||||
{
|
||||
SubPacket newPacket = null;
|
||||
|
||||
//Too small to even get length
|
||||
if (bytesRead <= offset)
|
||||
return null;
|
||||
|
||||
ushort packetSize = BitConverter.ToUInt16(buffer, offset);
|
||||
|
||||
//Too small to whole packet
|
||||
if (bytesRead < offset + packetSize)
|
||||
return null;
|
||||
|
||||
if (buffer.Length < offset + packetSize)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
newPacket = new SubPacket(buffer, ref offset);
|
||||
}
|
||||
catch (OverflowException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return newPacket;
|
||||
}
|
||||
|
||||
public void DebugPrintSubPacket()
|
||||
{
|
||||
#if DEBUG
|
||||
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)
|
||||
{
|
||||
logger.ColorDebug(Utils.ByteArrayToHex(GetGameMessageBytes(), SUBPACKET_SIZE),
|
||||
ConsoleOutputColor.DarkRed);
|
||||
|
||||
logger.ColorDebug(Utils.ByteArrayToHex(data, SUBPACKET_SIZE + GAMEMESSAGE_SIZE),
|
||||
ConsoleOutputColor.DarkMagenta);
|
||||
}
|
||||
else
|
||||
logger.ColorDebug(Utils.ByteArrayToHex(data, SUBPACKET_SIZE),
|
||||
ConsoleOutputColor.DarkMagenta);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
478
Common Class Lib/Utils.cs
Normal file
478
Common Class Lib/Utils.cs
Normal file
|
@ -0,0 +1,478 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015-2019 Project Meteor Dev Team
|
||||
|
||||
This file is part of Project Meteor Server.
|
||||
|
||||
Project Meteor Server is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Project Meteor Server 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Meteor.Common
|
||||
{
|
||||
public static class Utils
|
||||
{
|
||||
private static readonly uint[] _lookup32 = CreateLookup32();
|
||||
private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
|
||||
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(DateTime? time = null)
|
||||
{
|
||||
uint unixTimeStamp;
|
||||
var currentTime = time ?? 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(DateTime? time = null)
|
||||
{
|
||||
ulong unixTimeStamp;
|
||||
var currentTime = time ?? DateTime.Now;
|
||||
var zuluTime = currentTime.ToUniversalTime();
|
||||
var unixEpoch = new DateTime(1970, 1, 1);
|
||||
unixTimeStamp = (ulong)zuluTime.Subtract(unixEpoch).TotalMilliseconds;
|
||||
|
||||
return unixTimeStamp;
|
||||
}
|
||||
|
||||
public static DateTime UnixTimeStampToDateTime(uint timestamp)
|
||||
{
|
||||
return epoch.AddSeconds(timestamp);
|
||||
}
|
||||
|
||||
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 ushort SwapEndian(ushort input)
|
||||
{
|
||||
return (ushort)(((input << 8) & 0xff00) |
|
||||
((input >> 8) & 0x00ff));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
var lookup = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
var secondDigit = lookup.Substring((int)Math.Floor(number / (double)lookup.Length), 1);
|
||||
var firstDigit = lookup.Substring(number % lookup.Length, 1);
|
||||
|
||||
return secondDigit + firstDigit;
|
||||
}
|
||||
|
||||
|
||||
public static string FFXIVLoginStringDecodeBinary(string path)
|
||||
{
|
||||
Console.OutputEncoding = System.Text.Encoding.UTF8;
|
||||
byte[] data = File.ReadAllBytes(path);
|
||||
int offset = 0x5405a;
|
||||
//int offset = 0x5425d;
|
||||
//int offset = 0x53ea0;
|
||||
while (true)
|
||||
{
|
||||
string result = "";
|
||||
uint key = (uint)data[offset + 0] << 8 | data[offset + 1];
|
||||
uint key2 = data[offset + 2];
|
||||
key = RotateRight(key, 1) & 0xFFFF;
|
||||
key -= 0x22AF;
|
||||
key &= 0xFFFF;
|
||||
key2 = key2 ^ key;
|
||||
key = RotateRight(key, 1) & 0xFFFF;
|
||||
key -= 0x22AF;
|
||||
key &= 0xFFFF;
|
||||
uint finalKey = key;
|
||||
key = data[offset + 3];
|
||||
uint count = (key2 & 0xFF) << 8;
|
||||
key = key ^ finalKey;
|
||||
key &= 0xFF;
|
||||
count |= key;
|
||||
|
||||
int count2 = 0;
|
||||
while (count != 0)
|
||||
{
|
||||
uint encrypted = data[offset + 4 + count2];
|
||||
finalKey = RotateRight(finalKey, 1) & 0xFFFF;
|
||||
finalKey -= 0x22AF;
|
||||
finalKey &= 0xFFFF;
|
||||
encrypted = encrypted ^ (finalKey & 0xFF);
|
||||
|
||||
result += (char)encrypted;
|
||||
count--;
|
||||
count2++;
|
||||
}
|
||||
|
||||
offset += 4 + count2;
|
||||
}
|
||||
}
|
||||
|
||||
public static string FFXIVLoginStringDecode(byte[] data)
|
||||
{
|
||||
string result = "";
|
||||
uint key = (uint)data[0] << 8 | data[1];
|
||||
uint key2 = data[2];
|
||||
key = RotateRight(key, 1) & 0xFFFF;
|
||||
key -= 0x22AF;
|
||||
key2 = key2 ^ key;
|
||||
key = RotateRight(key, 1) & 0xFFFF;
|
||||
key -= 0x22AF;
|
||||
uint finalKey = key;
|
||||
key = data[3];
|
||||
uint count = (key2 & 0xFF) << 8;
|
||||
key = key ^ finalKey;
|
||||
key &= 0xFF;
|
||||
count |= key;
|
||||
|
||||
int count2 = 0;
|
||||
while (count != 0)
|
||||
{
|
||||
uint encrypted = data[4 + count2];
|
||||
finalKey = RotateRight(finalKey, 1) & 0xFFFF;
|
||||
finalKey -= 0x22AF;
|
||||
encrypted = encrypted ^ (finalKey & 0xFF);
|
||||
result += (char)encrypted;
|
||||
count--;
|
||||
count2++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] FFXIVLoginStringEncode(uint key, string text)
|
||||
{
|
||||
key = key & 0xFFFF;
|
||||
|
||||
uint count = 0;
|
||||
byte[] asciiBytes = Encoding.ASCII.GetBytes(text);
|
||||
byte[] result = new byte[4 + text.Length];
|
||||
for (count = 0; count < text.Length; count++)
|
||||
{
|
||||
result[result.Length - count - 1] = (byte)(asciiBytes[asciiBytes.Length - count - 1] ^ (key & 0xFF));
|
||||
key += 0x22AF;
|
||||
key &= 0xFFFF;
|
||||
key = RotateLeft(key, 1) & 0xFFFF;
|
||||
}
|
||||
|
||||
count = count ^ key;
|
||||
result[3] = (byte)(count & 0xFF);
|
||||
|
||||
key += 0x22AF & 0xFFFF;
|
||||
key = RotateLeft(key, 1) & 0xFFFF;
|
||||
|
||||
result[2] = (byte)(key & 0xFF);
|
||||
|
||||
key += 0x22AF & 0xFFFF;
|
||||
key = RotateLeft(key, 1) & 0xFFFF;
|
||||
|
||||
|
||||
result[1] = (byte)(key & 0xFF);
|
||||
result[0] = (byte)((key >> 8) & 0xFF);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static uint RotateLeft(uint value, int bits)
|
||||
{
|
||||
return (value << bits) | (value >> (16 - bits));
|
||||
}
|
||||
|
||||
public static uint RotateRight(uint value, int bits)
|
||||
{
|
||||
return (value >> bits) | (value << (16 - bits));
|
||||
}
|
||||
|
||||
public static T Clamp<T>(this T value, T min, T max) where T : IComparable<T>
|
||||
{
|
||||
if (value.CompareTo(min) < 0)
|
||||
return min;
|
||||
else if (value.CompareTo(max) > 0)
|
||||
return max;
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
public static T Min<T>(this T value, T min) where T : IComparable<T>
|
||||
{
|
||||
if (value.CompareTo(min) > 0)
|
||||
return min;
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
public static T Max<T>(this T value, T max) where T : IComparable<T>
|
||||
{
|
||||
|
||||
if (value.CompareTo(max) < 0)
|
||||
return max;
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
public static float DistanceSquared(Vector3 lhs, Vector3 rhs)
|
||||
{
|
||||
return DistanceSquared(lhs.X, lhs.Y, lhs.Z, rhs.X, rhs.Y, rhs.Z);
|
||||
}
|
||||
|
||||
public static float Distance(Vector3 lhs, Vector3 rhs)
|
||||
{
|
||||
return Distance(lhs.X, lhs.Y, lhs.Z, rhs.X, rhs.Y, rhs.Z);
|
||||
}
|
||||
|
||||
public static float Distance(float x, float y, float z, float x2, float y2, float z2)
|
||||
{
|
||||
if (x == x2 && y == y2 && z == z2)
|
||||
return 0.0f;
|
||||
|
||||
return (float)Math.Sqrt(DistanceSquared(x, y, z, x2, y2, z2));
|
||||
}
|
||||
|
||||
public static float DistanceSquared(float x, float y, float z, float x2, float y2, float z2)
|
||||
{
|
||||
if (x == x2 && y == y2 && z == z2)
|
||||
return 0.0f;
|
||||
|
||||
// todo: my maths is shit
|
||||
var dx = x - x2;
|
||||
var dy = y - y2;
|
||||
var dz = z - z2;
|
||||
|
||||
return dx * dx + dy * dy + dz * dz;
|
||||
}
|
||||
|
||||
//Distance of just the x and z valeus, ignoring y
|
||||
public static float XZDistanceSquared(Vector3 lhs, Vector3 rhs)
|
||||
{
|
||||
return XZDistanceSquared(lhs.X, lhs.Z, rhs.X, rhs.Z);
|
||||
}
|
||||
|
||||
public static float XZDistance(Vector3 lhs, Vector3 rhs)
|
||||
{
|
||||
return XZDistance(lhs.X, lhs.Z, rhs.X, rhs.Z);
|
||||
}
|
||||
|
||||
public static float XZDistance(float x, float z, float x2, float z2)
|
||||
{
|
||||
if (x == x2 && z == z2)
|
||||
return 0.0f;
|
||||
|
||||
return (float)Math.Sqrt(XZDistanceSquared(x, z, x2, z2));
|
||||
}
|
||||
|
||||
|
||||
public static float XZDistanceSquared(float x, float z, float x2, float z2)
|
||||
{
|
||||
if (x == x2 && z == z2)
|
||||
return 0.0f;
|
||||
|
||||
// todo: mz maths is shit
|
||||
var dx = x - x2;
|
||||
var dz = z - z2;
|
||||
|
||||
return dx * dx + dz * dz;
|
||||
}
|
||||
}
|
||||
}
|
180
Common Class Lib/Vector3.cs
Normal file
180
Common Class Lib/Vector3.cs
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2015-2019 Project Meteor Dev Team
|
||||
|
||||
This file is part of Project Meteor Server.
|
||||
|
||||
Project Meteor Server is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Project Meteor Server 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Meteor.Common
|
||||
{
|
||||
public class Vector3
|
||||
{
|
||||
public float X;
|
||||
public float Y;
|
||||
public float Z;
|
||||
public static Vector3 Zero = new Vector3();
|
||||
|
||||
public Vector3(float x, float y, float z)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
}
|
||||
|
||||
public Vector3()
|
||||
{
|
||||
X = 0.0f;
|
||||
Y = 0.0f;
|
||||
Z = 0.0f;
|
||||
}
|
||||
|
||||
public static Vector3 operator +(Vector3 lhs, Vector3 rhs)
|
||||
{
|
||||
Vector3 newVec = new Vector3(lhs.X, lhs.Y, lhs.Z);
|
||||
newVec.X += rhs.X;
|
||||
newVec.Y += rhs.Y;
|
||||
newVec.Z += rhs.Z;
|
||||
return newVec;
|
||||
}
|
||||
|
||||
public static Vector3 operator -(Vector3 lhs, Vector3 rhs)
|
||||
{
|
||||
return new Vector3(lhs.X - rhs.X, lhs.Y - rhs.Y, lhs.Z - rhs.Z);
|
||||
}
|
||||
|
||||
public static Vector3 operator *(Vector3 lhs, Vector3 rhs)
|
||||
{
|
||||
return new Vector3(lhs.X * rhs.X, lhs.Y * rhs.Y, lhs.Z * rhs.Z);
|
||||
}
|
||||
|
||||
public static Vector3 operator *(float scalar, Vector3 rhs)
|
||||
{
|
||||
return new Vector3(scalar * rhs.X, scalar * rhs.Y, scalar * rhs.Z);
|
||||
}
|
||||
|
||||
public static Vector3 operator /(Vector3 lhs, float scalar)
|
||||
{
|
||||
return new Vector3(lhs.X / scalar, lhs.Y / scalar, lhs.Z / scalar);
|
||||
}
|
||||
|
||||
public static bool operator !=(Vector3 lhs, Vector3 rhs)
|
||||
{
|
||||
return !(lhs?.X == rhs?.X && lhs?.Y == rhs?.Y && lhs?.Z == rhs?.Z);
|
||||
}
|
||||
|
||||
public static bool operator ==(Vector3 lhs, Vector3 rhs)
|
||||
{
|
||||
return (lhs?.X == rhs?.X && lhs?.Y == rhs?.Y && lhs?.Z == rhs?.Z);
|
||||
}
|
||||
|
||||
public float Length()
|
||||
{
|
||||
return (float)Math.Sqrt(this.LengthSquared());
|
||||
}
|
||||
|
||||
public float LengthSquared()
|
||||
{
|
||||
return (this.X * this.X) + (this.Y * this.Y) + (this.Z * this.Z);
|
||||
}
|
||||
|
||||
public static float Dot(Vector3 lhs, Vector3 rhs)
|
||||
{
|
||||
return (lhs.X * rhs.X) + (lhs.Y * rhs.Y) + (lhs.Z * rhs.Z);
|
||||
}
|
||||
|
||||
public static float GetAngle(Vector3 lhs, Vector3 rhs)
|
||||
{
|
||||
return GetAngle(lhs.X, lhs.Z, rhs.X, rhs.Z);
|
||||
}
|
||||
|
||||
public static float GetAngle(float x, float z, float x2, float z2)
|
||||
{
|
||||
if (x == x2)
|
||||
return 0.0f;
|
||||
|
||||
var angle = (float)(Math.Atan((z2 - z) / (x2 - x)));
|
||||
return (float)(x > x2 ? angle + Math.PI : angle);
|
||||
}
|
||||
|
||||
public Vector3 NewHorizontalVector(float angle, float extents)
|
||||
{
|
||||
var newVec = new Vector3();
|
||||
newVec.Y = this.Y;
|
||||
newVec.X = this.X + (float)Math.Cos(angle) * extents;
|
||||
newVec.Z = this.Z + (float)Math.Sin(angle) * extents;
|
||||
|
||||
return newVec;
|
||||
}
|
||||
|
||||
public bool IsWithinCircle(Vector3 center, float maxRadius, float minRadius)
|
||||
{
|
||||
if (this.X == center.X && this.Z == center.Z)
|
||||
return true;
|
||||
|
||||
float diffX = center.X - this.X;
|
||||
float diffZ = center.Z - this.Z;
|
||||
|
||||
float distance = Utils.XZDistance(center.X, center.Z, X, Z);
|
||||
|
||||
return distance <= maxRadius && distance >= minRadius;
|
||||
}
|
||||
|
||||
public bool IsWithinBox(Vector3 upperLeftCorner, Vector3 lowerRightCorner)
|
||||
{
|
||||
return upperLeftCorner.X <= this.X &&
|
||||
upperLeftCorner.Y <= this.Y &&
|
||||
upperLeftCorner.Z <= this.Z &&
|
||||
lowerRightCorner.X >= this.X &&
|
||||
lowerRightCorner.Y >= this.Y &&
|
||||
lowerRightCorner.Z >= this.Z;
|
||||
}
|
||||
|
||||
//Checks if this vector is in a cone, note it doesn't check for distance
|
||||
public bool IsWithinCone(Vector3 coneCenter, float coneRotation, float coneAngle)
|
||||
{
|
||||
float angleToTarget = GetAngle(coneCenter, this);
|
||||
float halfAngleOfAoe = (float) (coneAngle * Math.PI / 2);
|
||||
float rotationToAdd = coneRotation + halfAngleOfAoe;
|
||||
|
||||
//This is the angle relative to the lower angle of the cone
|
||||
angleToTarget = (angleToTarget + rotationToAdd - (0.5f * (float)Math.PI)) % (2 * (float) Math.PI);
|
||||
|
||||
//If the relative angle is less than the total angle of the cone, the target is inside the cone
|
||||
return angleToTarget >= 0 && angleToTarget <= (coneAngle * Math.PI);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var vector = obj as Vector3;
|
||||
return vector != null &&
|
||||
X == vector.X &&
|
||||
Y == vector.Y &&
|
||||
Z == vector.Z;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var hashCode = -307843816;
|
||||
hashCode = hashCode * -1521134295 + X.GetHashCode();
|
||||
hashCode = hashCode * -1521134295 + Y.GetHashCode();
|
||||
hashCode = hashCode * -1521134295 + Z.GetHashCode();
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
}
|
9
Common Class Lib/app.config
Normal file
9
Common Class Lib/app.config
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<system.data>
|
||||
<DbProviderFactories>
|
||||
<remove invariant="MySql.Data.MySqlClient"/>
|
||||
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"/>
|
||||
</DbProviderFactories>
|
||||
</system.data>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/></startup></configuration>
|
6
Common Class Lib/packages.config
Normal file
6
Common Class Lib/packages.config
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="DotNetZip" version="1.10.1" targetFramework="net45" />
|
||||
<package id="MySql.Data" version="6.9.8" targetFramework="net45" />
|
||||
<package id="NLog" version="4.3.5" targetFramework="net45" />
|
||||
</packages>
|
Loading…
Add table
Add a link
Reference in a new issue