diff --git a/FFXIVClassic Common Class Lib/BasePacket.cs b/Common Class Lib/BasePacket.cs
similarity index 99%
rename from FFXIVClassic Common Class Lib/BasePacket.cs
rename to Common Class Lib/BasePacket.cs
index ba0f20d4..ab15d307 100644
--- a/FFXIVClassic Common Class Lib/BasePacket.cs
+++ b/Common Class Lib/BasePacket.cs
@@ -24,11 +24,12 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
+
+using Ionic.Zlib;
using NLog;
using NLog.Targets;
-using Ionic.Zlib;
-namespace FFXIVClassic.Common
+namespace Meteor.Common
{
[StructLayout(LayoutKind.Sequential)]
public struct BasePacketHeader
diff --git a/FFXIVClassic Common Class Lib/Bitfield.cs b/Common Class Lib/Bitfield.cs
similarity index 99%
rename from FFXIVClassic Common Class Lib/Bitfield.cs
rename to Common Class Lib/Bitfield.cs
index ccb151b6..0ccdd48a 100644
--- a/FFXIVClassic Common Class Lib/Bitfield.cs
+++ b/Common Class Lib/Bitfield.cs
@@ -21,7 +21,7 @@ along with Project Meteor Server. If not, see .
using System;
-namespace FFXIVClassic.Common
+namespace Meteor.Common
{
[global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public sealed class BitfieldLengthAttribute : Attribute
diff --git a/FFXIVClassic Common Class Lib/Blowfish.cs b/Common Class Lib/Blowfish.cs
similarity index 99%
rename from FFXIVClassic Common Class Lib/Blowfish.cs
rename to Common Class Lib/Blowfish.cs
index 04987e3c..ac397e4d 100644
--- a/FFXIVClassic Common Class Lib/Blowfish.cs
+++ b/Common Class Lib/Blowfish.cs
@@ -21,7 +21,7 @@ along with Project Meteor Server. If not, see .
using System;
-namespace FFXIVClassic.Common
+namespace Meteor.Common
{
public class Blowfish
{
diff --git a/FFXIVClassic Common Class Lib/FFXIVClassic Common Class Lib.csproj b/Common Class Lib/Common Class Lib.csproj
similarity index 96%
rename from FFXIVClassic Common Class Lib/FFXIVClassic Common Class Lib.csproj
rename to Common Class Lib/Common Class Lib.csproj
index a2c8c826..75373674 100644
--- a/FFXIVClassic Common Class Lib/FFXIVClassic Common Class Lib.csproj
+++ b/Common Class Lib/Common Class Lib.csproj
@@ -1,113 +1,113 @@
-
-
-
-
-
- Debug
- AnyCPU
- {3A3D6626-C820-4C18-8C81-64811424F20E}
- Library
- Properties
- FFXIVClassic.Common
- FFXIVClassic.Common
- v4.5.1
- 512
-
-
- 792e4711
-
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- false
- false
- true
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- false
- true
-
-
- true
- bin\Debug\
- DEBUG;TRACE
- true
- full
- x64
- prompt
- MinimumRecommendedRules.ruleset
-
-
- bin\x64\Release\
- TRACE
- true
- true
- pdbonly
- x64
- prompt
- MinimumRecommendedRules.ruleset
-
-
-
- ..\packages\DotNetZip.1.10.1\lib\net20\DotNetZip.dll
-
-
- ..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll
- True
-
-
- ..\packages\NLog.4.3.5\lib\net45\NLog.dll
- True
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 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}.
-
-
-
-
+
+
+
+
+
+ Debug
+ AnyCPU
+ {3A3D6626-C820-4C18-8C81-64811424F20E}
+ Library
+ Properties
+ Meteor.Common
+ Meteor.Common
+ v4.5.1
+ 512
+
+
+ 792e4711
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ false
+ false
+ true
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ false
+ true
+
+
+ true
+ bin\Debug\
+ DEBUG;TRACE
+ true
+ full
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+ bin\x64\Release\
+ TRACE
+ true
+ true
+ pdbonly
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+
+ ..\packages\DotNetZip.1.10.1\lib\net20\DotNetZip.dll
+
+
+ ..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll
+ True
+
+
+ ..\packages\NLog.4.3.5\lib\net45\NLog.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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}.
+
+
+
+
\ No newline at end of file
diff --git a/FFXIVClassic Common Class Lib/EfficientHashTables.cs b/Common Class Lib/EfficientHashTables.cs
similarity index 99%
rename from FFXIVClassic Common Class Lib/EfficientHashTables.cs
rename to Common Class Lib/EfficientHashTables.cs
index 71865f12..8efecc17 100644
--- a/FFXIVClassic Common Class Lib/EfficientHashTables.cs
+++ b/Common Class Lib/EfficientHashTables.cs
@@ -21,7 +21,7 @@ along with Project Meteor Server. If not, see .
using System;
-namespace FFXIVClassic.Common
+namespace Meteor.Common
{
namespace EfficientHashTables
{
diff --git a/FFXIVClassic Common Class Lib/Properties/AssemblyInfo.cs b/Common Class Lib/Properties/AssemblyInfo.cs
similarity index 97%
rename from FFXIVClassic Common Class Lib/Properties/AssemblyInfo.cs
rename to Common Class Lib/Properties/AssemblyInfo.cs
index 0d9a897b..dc121c0b 100644
--- a/FFXIVClassic Common Class Lib/Properties/AssemblyInfo.cs
+++ b/Common Class Lib/Properties/AssemblyInfo.cs
@@ -1,35 +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")]
+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")]
diff --git a/FFXIVClassic Common Class Lib/STA_INIFile.cs b/Common Class Lib/STA_INIFile.cs
similarity index 99%
rename from FFXIVClassic Common Class Lib/STA_INIFile.cs
rename to Common Class Lib/STA_INIFile.cs
index 1f0d64c3..451b804e 100644
--- a/FFXIVClassic Common Class Lib/STA_INIFile.cs
+++ b/Common Class Lib/STA_INIFile.cs
@@ -3,13 +3,14 @@
// *******************************
// *** (C)2009-2013 S.T.A. snc ***
// *******************************
+
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
-namespace FFXIVClassic.Common
+namespace Meteor.Common
{
public class INIFile
{
diff --git a/FFXIVClassic Common Class Lib/Sql.cs b/Common Class Lib/Sql.cs
similarity index 94%
rename from FFXIVClassic Common Class Lib/Sql.cs
rename to Common Class Lib/Sql.cs
index d2440f50..28022de4 100644
--- a/FFXIVClassic Common Class Lib/Sql.cs
+++ b/Common Class Lib/Sql.cs
@@ -1,33 +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 .
-===========================================================================
-*/
-
-using NLog;
-
-namespace FFXIVClassic.Common
-{
- // todo:
- // havent decided whether it's worth wrapping every sql class
- // so i'll just leave it with logger for now
- public class Sql
- {
- public static Logger Log = LogManager.GetCurrentClassLogger();
- }
-}
+/*
+===========================================================================
+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 .
+===========================================================================
+*/
+
+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();
+ }
+}
diff --git a/FFXIVClassic Common Class Lib/SubPacket.cs b/Common Class Lib/SubPacket.cs
similarity index 99%
rename from FFXIVClassic Common Class Lib/SubPacket.cs
rename to Common Class Lib/SubPacket.cs
index ee2c74fc..1336f768 100644
--- a/FFXIVClassic Common Class Lib/SubPacket.cs
+++ b/Common Class Lib/SubPacket.cs
@@ -21,10 +21,11 @@ along with Project Meteor Server. If not, see .
using System;
using System.Runtime.InteropServices;
+
using NLog;
using NLog.Targets;
-namespace FFXIVClassic.Common
+namespace Meteor.Common
{
[StructLayout(LayoutKind.Sequential)]
public struct SubPacketHeader
diff --git a/FFXIVClassic Common Class Lib/Utils.cs b/Common Class Lib/Utils.cs
similarity index 96%
rename from FFXIVClassic Common Class Lib/Utils.cs
rename to Common Class Lib/Utils.cs
index 0b22b017..7290fc52 100644
--- a/FFXIVClassic Common Class Lib/Utils.cs
+++ b/Common Class Lib/Utils.cs
@@ -1,478 +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 .
-===========================================================================
-*/
-
-using System;
-using System.IO;
-using System.Text;
-
-namespace FFXIVClassic.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(this T value, T min, T max) where T : IComparable
- {
- if (value.CompareTo(min) < 0)
- return min;
- else if (value.CompareTo(max) > 0)
- return max;
- else
- return value;
- }
-
- public static T Min(this T value, T min) where T : IComparable
- {
- if (value.CompareTo(min) > 0)
- return min;
- else
- return value;
- }
-
- public static T Max(this T value, T max) where T : IComparable
- {
-
- 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;
- }
- }
-}
+/*
+===========================================================================
+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 .
+===========================================================================
+*/
+
+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(this T value, T min, T max) where T : IComparable
+ {
+ if (value.CompareTo(min) < 0)
+ return min;
+ else if (value.CompareTo(max) > 0)
+ return max;
+ else
+ return value;
+ }
+
+ public static T Min(this T value, T min) where T : IComparable
+ {
+ if (value.CompareTo(min) > 0)
+ return min;
+ else
+ return value;
+ }
+
+ public static T Max(this T value, T max) where T : IComparable
+ {
+
+ 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;
+ }
+ }
+}
diff --git a/FFXIVClassic Common Class Lib/Vector3.cs b/Common Class Lib/Vector3.cs
similarity index 99%
rename from FFXIVClassic Common Class Lib/Vector3.cs
rename to Common Class Lib/Vector3.cs
index a6d7e2a8..57cd8604 100644
--- a/FFXIVClassic Common Class Lib/Vector3.cs
+++ b/Common Class Lib/Vector3.cs
@@ -21,7 +21,7 @@ along with Project Meteor Server. If not, see .
using System;
-namespace FFXIVClassic.Common
+namespace Meteor.Common
{
public class Vector3
{
diff --git a/FFXIVClassic Lobby Server/app.config b/Common Class Lib/app.config
similarity index 98%
rename from FFXIVClassic Lobby Server/app.config
rename to Common Class Lib/app.config
index e418f4e3..14a5fe96 100644
--- a/FFXIVClassic Lobby Server/app.config
+++ b/Common Class Lib/app.config
@@ -1,9 +1,9 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/FFXIVClassic Common Class Lib/packages.config b/Common Class Lib/packages.config
similarity index 98%
rename from FFXIVClassic Common Class Lib/packages.config
rename to Common Class Lib/packages.config
index 5436126a..7ea3d87b 100644
--- a/FFXIVClassic Common Class Lib/packages.config
+++ b/Common Class Lib/packages.config
@@ -1,6 +1,6 @@
-
-
-
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/FFXIVClassic Map Server/actors/debug/Debug.cs b/FFXIVClassic Map Server/actors/debug/Debug.cs
deleted file mode 100644
index 24d34106..00000000
--- a/FFXIVClassic Map Server/actors/debug/Debug.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
-===========================================================================
-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 .
-===========================================================================
-*/
-
-using FFXIVClassic.Common;
-using FFXIVClassic_Map_Server.lua;
-using FFXIVClassic_Map_Server.packets.send.actor;
-using System.Collections.Generic;
-
-namespace FFXIVClassic_Map_Server.Actors
-{
- class DebugProg : Actor
- {
-
- public DebugProg()
- : base(0x5FF80002)
- {
- this.displayNameId = 0;
- this.customDisplayName = "debug";
-
- this.actorName = "debug";
- this.className = "Debug";
- }
-
- public override SubPacket CreateScriptBindPacket()
- {
- List lParams;
- lParams = LuaUtils.CreateLuaParamList("/System/Debug.prog", false, false, false, false, true, 0xC51F, true, true);
- return ActorInstantiatePacket.BuildPacket(actorId, actorName, className, lParams);
- }
-
- public override List GetSpawnPackets()
- {
- List subpackets = new List();
- subpackets.Add(CreateAddActorPacket(0));
- subpackets.Add(CreateSpeedPacket());
- subpackets.Add(CreateSpawnPositonPacket(0x1));
- subpackets.Add(CreateNamePacket());
- subpackets.Add(CreateStatePacket());
- subpackets.Add(CreateIsZoneingPacket());
- subpackets.Add(CreateScriptBindPacket());
- return subpackets;
- }
-
- }
-}
diff --git a/Launcher Editor/App.config b/Launcher Editor/App.config
deleted file mode 100644
index 88fa4027..00000000
--- a/Launcher Editor/App.config
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Launcher Editor/Launcher Editor.csproj b/Launcher Editor/Launcher Editor.csproj
deleted file mode 100644
index 7a304e49..00000000
--- a/Launcher Editor/Launcher Editor.csproj
+++ /dev/null
@@ -1,80 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- {0FFA9D2F-41C6-443C-99B7-665702CF548F}
- Exe
- Properties
- Launcher_Editor
- Launcher Editor
- v4.5.2
- 512
- true
-
-
- AnyCPU
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- AnyCPU
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
- true
- bin\Debug\
- DEBUG;TRACE
- full
- x64
- prompt
- MinimumRecommendedRules.ruleset
- true
-
-
- bin\x64\Release\
- TRACE
- true
- pdbonly
- x64
- prompt
- MinimumRecommendedRules.ruleset
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Launcher Editor/Program.cs b/Launcher Editor/Program.cs
deleted file mode 100644
index 8328ccf5..00000000
--- a/Launcher Editor/Program.cs
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
-===========================================================================
-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 .
-===========================================================================
-*/
-
-using System;
-using System.IO;
-using System.Text;
-
-namespace Launcher_Editor
-{
- //ffxivboot.exe:
- //Offset
- //0x9663FC: Patch Server Port
- //0x966404: Patch Server URL
-
- //0x9663FC + 0x400000: Port Offset to search
- //0x966404 + 0x400000: URL Offset to search
-
- class Program
- {
- const string ORIGINAL_PATCH_PORT_STRING = "54996";
- const string ORIGINAL_PATCH_URL_STRING = "ver01.ffxiv.com";
- const string ORIGINAL_PATCH_LOGIN_STRING = "http://account.square-enix.com/account/content/ffxivlogin";
-
- static void Main(string[] args)
- {
- byte[] exeDataBoot;
- byte[] exeDataLogin;
-
- string patchPortString;
- string patchUrlString;
- string loginUrlString;
-
- string lobbyUrlString = "lobby01.ffxiv.com";
-
- Console.WriteLine("---------------------");
- Console.WriteLine("FFXIV 1.0 EXE Patcher");
- Console.WriteLine("By Ioncannon");
- Console.WriteLine("Version 1.0");
- Console.WriteLine("---------------------");
-
- Console.WriteLine("Please enter the full path to your FINAL FANTASY XIV folder. It should have ffxivgame.exe inside it.");
- string path = Console.ReadLine();
-
- if (!File.Exists(path + "\\ffxivboot.exe"))
- {
- Console.WriteLine("Missing ffxivboot.exe, aborting");
- Console.ReadKey();
- return;
- }
- if (!File.Exists(path + "\\ffxivgame.exe"))
- {
- Console.WriteLine("Missing ffxivgame.exe, aborting");
- Console.ReadKey();
- return;
- }
- if (!File.Exists(path + "\\ffxivlogin.exe"))
- {
- Console.WriteLine("Missing ffxivlogin.exe, aborting");
- Console.ReadKey();
- return;
- }
-
- Console.WriteLine("EXEs found!");
-
- Console.WriteLine("Please enter the url to the patch webpage (do not include \"http://\", max 32 characters).");
- patchUrlString = Console.ReadLine();
- Console.WriteLine("Please enter the port to the patch webpage (usually 80).");
- patchPortString = Console.ReadLine();
-
- try
- {
- int.Parse(patchPortString);
- }
- catch (FormatException e)
- {
- Console.WriteLine("Not a number, aborting");
- Console.ReadKey();
- return;
- }
- catch (OverflowException e)
- {
- Console.WriteLine("Not a number, aborting");
- Console.ReadKey();
- return;
- }
-
- Console.WriteLine("Please enter the url to the login webpage (max 56 characters, please include \"http://\").");
- loginUrlString = Console.ReadLine();
-
- if (loginUrlString.Length > 0x56)
- {
- Console.WriteLine("URL too long, aborting");
- Console.ReadKey();
- return;
- }
-
- long patchPortStringOffset = 0;
- long patchUrlStringOffset = 0;
- long lobbyUrlStringOffset = 0;
- long freeSpaceOffset = 0;
-
- long loginUrlOffset = 0;
- long freeSpaceInLoginOffset = 0;
-
- Console.WriteLine("Patching started!");
- exeDataBoot = File.ReadAllBytes(path + "\\ffxivboot.exe");
- exeDataLogin = File.ReadAllBytes(path + "\\ffxivlogin.exe");
-
- Console.WriteLine("---Editing FFXIVBOOT.EXE---");
-
- patchPortStringOffset = PrintSearch(exeDataBoot, ORIGINAL_PATCH_PORT_STRING);
- patchUrlStringOffset = PrintSearch(exeDataBoot, ORIGINAL_PATCH_URL_STRING);
- freeSpaceOffset = PrintFreeSpaceSearch(exeDataBoot);
-
- if (patchPortStringOffset == -1 || patchUrlStringOffset == -1 || freeSpaceOffset == -1)
- {
- Console.WriteLine("There was an error finding the address locations...");
- Console.ReadKey();
- return;
- }
-
- Console.WriteLine("Writing \"{0}\" and updating offset to 0x{1:X}.", patchPortString, freeSpaceOffset);
- WriteNewString(exeDataBoot, patchPortStringOffset, patchPortString, freeSpaceOffset);
- Console.WriteLine("Writing \"{0}\" and updating offset to 0x{1:X}.", patchUrlString, freeSpaceOffset + 0x20);
- WriteNewString(exeDataBoot, patchUrlStringOffset, patchUrlString, freeSpaceOffset + 0x20);
-
- Console.WriteLine("---Editing FFXIVLOGIN.EXE---");
- loginUrlOffset = PrintEncodedSearch(exeDataLogin, 0x739, ORIGINAL_PATCH_LOGIN_STRING);
- freeSpaceInLoginOffset = PrintFreeSpaceSearch(exeDataLogin);
-
- if (loginUrlOffset == -1 || freeSpaceInLoginOffset == -1)
- {
- Console.WriteLine("There was an error finding the address locations...");
- Console.ReadKey();
- return;
- }
-
- Console.WriteLine("Writing encoded \"{0}\" and updating offset to 0x{1:X}.", loginUrlString, freeSpaceInLoginOffset);
- WriteNewStringEncoded(exeDataLogin, loginUrlOffset, 0x739, loginUrlString, freeSpaceInLoginOffset);
-
- File.WriteAllBytes("C:\\Users\\Filip\\Desktop\\ffxivboot.exe", exeDataBoot);
- File.WriteAllBytes("C:\\Users\\Filip\\Desktop\\ffxivlogin.exe", exeDataLogin);
-
- Console.WriteLine("Done! New .EXEs created in the same folder as this application. Make sure to backup your originals!");
- Console.WriteLine("Press any key to exit...");
- Console.ReadKey();
-
- }
-
- public static void WriteNewString(byte[] exeData, long offsetLocation, string newString, long freeSpaceLocation)
- {
- using (MemoryStream memStream = new MemoryStream(exeData))
- {
- using (BinaryWriter binaryWriter = new BinaryWriter(memStream))
- {
- binaryWriter.BaseStream.Seek(offsetLocation, SeekOrigin.Begin);
- binaryWriter.Write((uint)freeSpaceLocation + 0x400000);
- binaryWriter.BaseStream.Seek(freeSpaceLocation, SeekOrigin.Begin);
- binaryWriter.Write(Encoding.ASCII.GetBytes(newString), 0, Encoding.ASCII.GetByteCount(newString) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(newString));
- }
- }
- }
-
- public static void WriteNewStringEncoded(byte[] exeData, long offsetLocation, uint key, string newString, long freeSpaceLocation)
- {
- byte[] encodedString = FFXIVLoginStringEncode(key, newString);
- using (MemoryStream memStream = new MemoryStream(exeData))
- {
- using (BinaryWriter binaryWriter = new BinaryWriter(memStream))
- {
- //binaryWriter.BaseStream.Seek(offsetLocation, SeekOrigin.Begin);
- //binaryWriter.Write((uint)freeSpaceLocation + 0x400000);
- binaryWriter.BaseStream.Seek(offsetLocation, SeekOrigin.Begin);
- binaryWriter.Write(encodedString);
- }
- }
- }
-
- public static long PrintSearch(byte[] exeData, string searchString)
- {
- Console.Write("Searching for string \"{0}\"...", searchString);
- long offset = SearchForStringOffset(exeData, searchString);
-
- if (offset != -1)
- Console.WriteLine(" FOUND @ 0x{0:X}!", offset);
- else
- {
- Console.WriteLine(" ERROR, could not find string.");
- }
-
- return offset;
- }
-
- public static long PrintEncodedSearch(byte[] exeData, uint key, string searchString)
- {
- Console.Write("Searching for encoded string \"{0}\"...", searchString);
- long offset = SearchForEncodedStringOffset(exeData, key, searchString);
-
- if (offset != -1)
- Console.WriteLine(" FOUND @ 0x{0:X}!", offset);
- else
- {
- Console.WriteLine(" ERROR, could not find string.");
- }
-
- return offset;
- }
-
- public static long PrintFreeSpaceSearch(byte[] exeData)
- {
- Console.Write("Searching for free space...");
- long freeSpaceOffset = SearchForFreeSpace(exeData);
- if (freeSpaceOffset != -1)
- Console.WriteLine(" FOUND @ 0x{0:X}!", freeSpaceOffset);
- else
- {
- Console.WriteLine(" ERROR, could not find free space.");
- }
-
- return freeSpaceOffset;
- }
-
- public static bool EditOffset(long offset, uint value)
- {
- return true;
- }
-
- public static long SearchForFreeSpace(byte[] exeData)
- {
- using (MemoryStream memStream = new MemoryStream(exeData))
- {
- using (BinaryReader binReader = new BinaryReader(memStream))
- {
- //Find the .data section header
- long textSectionOffset = -1;
- int strCheckoffset = 0;
- while (binReader.BaseStream.Position + 4 < binReader.BaseStream.Length)
- {
- if (binReader.ReadByte() == ".text"[strCheckoffset])
- {
- if (strCheckoffset == 0)
- textSectionOffset = binReader.BaseStream.Position - 1;
-
- strCheckoffset++;
- if (strCheckoffset == Encoding.ASCII.GetByteCount(".data"))
- break;
- }
- else
- {
- strCheckoffset = 0;
- textSectionOffset = -1;
- }
- }
-
- //Read in the position and size
- binReader.BaseStream.Seek(textSectionOffset, SeekOrigin.Begin);
- binReader.ReadUInt64();
- uint virtualSize = binReader.ReadUInt32();
- uint address = binReader.ReadUInt32();
- uint sizeOfRawData = binReader.ReadUInt32();
-
- if (sizeOfRawData - virtualSize < 0x50)
- return -1;
-
- //Find a spot
- binReader.BaseStream.Seek(address + sizeOfRawData, SeekOrigin.Begin);
- while (binReader.BaseStream.Position >= address + virtualSize)
- {
- binReader.BaseStream.Seek(-0x50, SeekOrigin.Current);
- long newPosition = binReader.BaseStream.Position;
-
- bool foundNotZero = false;
- for (int i = 0; i < 0x50; i++)
- {
- if (binReader.ReadByte() != 0)
- {
- foundNotZero = true;
- break;
- }
- }
-
- if (!foundNotZero)
- return newPosition;
- else
- binReader.BaseStream.Seek(newPosition, SeekOrigin.Begin);
- }
- }
- }
-
- return -1;
- }
-
- public static long SearchForStringOffset(byte[] exeData, string testString)
- {
- testString += "\0";
-
- using (MemoryStream memStream = new MemoryStream(exeData))
- {
- using (BinaryReader binReader = new BinaryReader(memStream))
- {
- long strOffset = -1;
- int strCheckoffset = 0;
- while (binReader.BaseStream.Position + 4 < binReader.BaseStream.Length)
- {
- if (binReader.ReadByte() == testString[strCheckoffset])
- {
- if (strCheckoffset == 0)
- strOffset = binReader.BaseStream.Position-1;
-
- strCheckoffset++;
- if (strCheckoffset == Encoding.ASCII.GetByteCount(testString))
- break;
- }
- else
- {
- strCheckoffset = 0;
- strOffset = -1;
- }
- }
-
- if (strOffset != -1)
- {
- strOffset += 0x400000;
-
- binReader.BaseStream.Seek(0, SeekOrigin.Begin);
-
- while (binReader.BaseStream.Position + 4 < binReader.BaseStream.Length)
- {
- if (binReader.ReadUInt32() == strOffset)
- return binReader.BaseStream.Position - 0x4;
- }
-
- return -1;
- }
- else
- return -1;
- }
- }
- }
-
- public static long SearchForEncodedStringOffset(byte[] exeData, uint testKey, string testString)
- {
- byte[] encoded = FFXIVLoginStringEncode(testKey, testString);
-
- using (MemoryStream memStream = new MemoryStream(exeData))
- {
- using (BinaryReader binReader = new BinaryReader(memStream))
- {
- long strOffset = -1;
- int strCheckoffset = 0;
- while (binReader.BaseStream.Position + 4 < binReader.BaseStream.Length)
- {
- if (binReader.ReadByte() == encoded[strCheckoffset])
- {
- if (strCheckoffset == 0)
- strOffset = binReader.BaseStream.Position - 1;
-
- strCheckoffset++;
- if (strCheckoffset == encoded.Length)
- break;
- }
- else
- {
- strCheckoffset = 0;
- strOffset = -1;
- }
- }
-
- return strOffset;
- }
- }
- }
-
- 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++;
- }
-
- return result;
- //offset += 4 + count2;
- }
- }
-
- public static string FFXIVLoginStringDecode(byte[] data)
- {
- Console.OutputEncoding = System.Text.Encoding.UTF8;
- while (true)
- {
- string result = "";
- uint key = (uint)data[0] << 8 | data[1];
- uint key2 = data[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[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;
- finalKey &= 0xFFFF;
- encrypted = encrypted ^ (finalKey & 0xFF);
-
- result += (char)encrypted;
- count--;
- count2++;
- }
-
- return result;
- //offset += 4 + count2;
- }
- }
-
- 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);
- key &= 0xFFFF;
- }
-
- count = count ^ key;
- result[3] = (byte)(count & 0xFF);
-
- key += 0x22AF;
- key &= 0xFFFF;
- key = RotateLeft(key, 1);
- key &= 0xFFFF;
-
- result[2] = (byte)(key & 0xFF);
-
- key += 0x22AF;
- key &= 0xFFFF;
- key = RotateLeft(key, 1);
- key &= 0xFFFF;
-
- result[1] = (byte)(key & 0xFF);
- result[0] = (byte)((key >> 8) & 0xFF);
-
- return result;
- }
-
- public static uint RotateLeft(uint value, int bits)
- {
- return (value << bits) | (value >> (16 - bits));
- }
-
- public static uint RotateRight(uint value, int bits)
- {
- return (value >> bits) | (value << (16 - bits));
- }
-
- }
-}
diff --git a/Launcher Editor/Properties/AssemblyInfo.cs b/Launcher Editor/Properties/AssemblyInfo.cs
deleted file mode 100644
index 3f32537b..00000000
--- a/Launcher Editor/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-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("Launcher Editor")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Launcher Editor")]
-[assembly: AssemblyCopyright("Copyright © 2017")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("0ffa9d2f-41c6-443c-99b7-665702cf548f")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/FFXIVClassic Lobby Server/utils/CharacterCreatorUtils.cs b/Lobby Server/CharacterCreatorUtils.cs
similarity index 99%
rename from FFXIVClassic Lobby Server/utils/CharacterCreatorUtils.cs
rename to Lobby Server/CharacterCreatorUtils.cs
index e5cbd737..5aec11c9 100644
--- a/FFXIVClassic Lobby Server/utils/CharacterCreatorUtils.cs
+++ b/Lobby Server/CharacterCreatorUtils.cs
@@ -21,7 +21,7 @@ along with Project Meteor Server. If not, see .
using System.Collections.Generic;
-namespace FFXIVClassic_Lobby_Server.utils
+namespace Meteor.Lobby
{
class CharacterCreatorUtils
{
diff --git a/FFXIVClassic Lobby Server/ClientConnection.cs b/Lobby Server/ClientConnection.cs
similarity index 97%
rename from FFXIVClassic Lobby Server/ClientConnection.cs
rename to Lobby Server/ClientConnection.cs
index d7f2680d..7eea428b 100644
--- a/FFXIVClassic Lobby Server/ClientConnection.cs
+++ b/Lobby Server/ClientConnection.cs
@@ -20,13 +20,14 @@ along with Project Meteor Server. If not, see .
*/
using System;
-using System.Net.Sockets;
-using FFXIVClassic.Common;
using System.Collections.Concurrent;
-using Cyotek.Collections.Generic;
using System.Net;
+using System.Net.Sockets;
-namespace FFXIVClassic_Lobby_Server
+using Cyotek.Collections.Generic;
+using Meteor.Common;
+
+namespace Meteor.Lobby
{
class ClientConnection
{
diff --git a/FFXIVClassic Lobby Server/ConfigConstants.cs b/Lobby Server/ConfigConstants.cs
similarity index 98%
rename from FFXIVClassic Lobby Server/ConfigConstants.cs
rename to Lobby Server/ConfigConstants.cs
index 1549ad50..ef474e81 100644
--- a/FFXIVClassic Lobby Server/ConfigConstants.cs
+++ b/Lobby Server/ConfigConstants.cs
@@ -19,13 +19,14 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-using FFXIVClassic.Common;
using System;
using System.IO;
using System.Linq;
using System.Net;
-namespace FFXIVClassic_Lobby_Server
+using Meteor.Common;
+
+namespace Meteor.Lobby
{
class ConfigConstants
{
diff --git a/FFXIVClassic Lobby Server/dataobjects/Account.cs b/Lobby Server/DataObjects/Account.cs
similarity index 95%
rename from FFXIVClassic Lobby Server/dataobjects/Account.cs
rename to Lobby Server/DataObjects/Account.cs
index 6f875c55..b83ce5a0 100644
--- a/FFXIVClassic Lobby Server/dataobjects/Account.cs
+++ b/Lobby Server/DataObjects/Account.cs
@@ -21,7 +21,7 @@ along with Project Meteor Server. If not, see .
using System;
-namespace FFXIVClassic_Lobby_Server.dataobjects
+namespace Meteor.Lobby.DataObjects
{
class Account
{
diff --git a/FFXIVClassic Lobby Server/dataobjects/Appearance.cs b/Lobby Server/DataObjects/Appearance.cs
similarity index 97%
rename from FFXIVClassic Lobby Server/dataobjects/Appearance.cs
rename to Lobby Server/DataObjects/Appearance.cs
index 9b2756da..b6c84454 100644
--- a/FFXIVClassic Lobby Server/dataobjects/Appearance.cs
+++ b/Lobby Server/DataObjects/Appearance.cs
@@ -19,7 +19,7 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-namespace FFXIVClassic_Lobby_Server.dataobjects
+namespace Meteor.Lobby.DataObjects
{
class Appearance
{
diff --git a/FFXIVClassic Lobby Server/dataobjects/CharaInfo.cs b/Lobby Server/DataObjects/CharaInfo.cs
similarity index 98%
rename from FFXIVClassic Lobby Server/dataobjects/CharaInfo.cs
rename to Lobby Server/DataObjects/CharaInfo.cs
index 495cc837..a9827c08 100644
--- a/FFXIVClassic Lobby Server/dataobjects/CharaInfo.cs
+++ b/Lobby Server/DataObjects/CharaInfo.cs
@@ -20,10 +20,10 @@ along with Project Meteor Server. If not, see .
*/
using System;
-using FFXIVClassic.Common;
using System.IO;
+using Meteor.Common;
-namespace FFXIVClassic_Lobby_Server.dataobjects
+namespace Meteor.Lobby.DataObjects
{
class CharaInfo
{
@@ -248,7 +248,7 @@ namespace FFXIVClassic_Lobby_Server.dataobjects
{
byte[] bytes = File.ReadAllBytes("./packets/charaappearance.bin");
- Program.Log.Debug(Utils.ByteArrayToHex(bytes));
+ Program.Log.Debug(Common.Utils.ByteArrayToHex(bytes));
return Convert.ToBase64String(bytes).Replace('+', '-').Replace('/', '_');
}
diff --git a/FFXIVClassic Lobby Server/dataobjects/Character.cs b/Lobby Server/DataObjects/Character.cs
similarity index 91%
rename from FFXIVClassic Lobby Server/dataobjects/Character.cs
rename to Lobby Server/DataObjects/Character.cs
index a2a06ea5..089e5874 100644
--- a/FFXIVClassic Lobby Server/dataobjects/Character.cs
+++ b/Lobby Server/DataObjects/Character.cs
@@ -20,11 +20,9 @@ along with Project Meteor Server. If not, see .
*/
using System;
-using FFXIVClassic.Common;
-using FFXIVClassic_Lobby_Server.dataobjects;
-namespace FFXIVClassic_Lobby_Server
-{
+namespace Meteor.Lobby.DataObjects
+{
class Character
{
public uint id;
@@ -52,10 +50,10 @@ namespace FFXIVClassic_Lobby_Server
{
charaInfo.Replace("+", "-");
charaInfo.Replace("/", "_");
- byte[] data = System.Convert.FromBase64String(charaInfo);
+ byte[] data = System.Convert.FromBase64String(charaInfo);
Program.Log.Debug("------------Base64 printout------------------");
- Program.Log.Debug(Utils.ByteArrayToHex(data));
+ Program.Log.Debug(Common.Utils.ByteArrayToHex(data));
Program.Log.Debug("------------Base64 printout------------------");
CharaInfo chara = new CharaInfo();
diff --git a/FFXIVClassic Lobby Server/dataobjects/Retainer.cs b/Lobby Server/DataObjects/Retainer.cs
similarity index 97%
rename from FFXIVClassic Lobby Server/dataobjects/Retainer.cs
rename to Lobby Server/DataObjects/Retainer.cs
index f0cfacf4..00005add 100644
--- a/FFXIVClassic Lobby Server/dataobjects/Retainer.cs
+++ b/Lobby Server/DataObjects/Retainer.cs
@@ -19,7 +19,7 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-namespace FFXIVClassic_Lobby_Server
+namespace Meteor.Lobby.DataObjects
{
class Retainer
{
diff --git a/FFXIVClassic Lobby Server/dataobjects/World.cs b/Lobby Server/DataObjects/World.cs
similarity index 97%
rename from FFXIVClassic Lobby Server/dataobjects/World.cs
rename to Lobby Server/DataObjects/World.cs
index c50ae07a..2c1ba09b 100644
--- a/FFXIVClassic Lobby Server/dataobjects/World.cs
+++ b/Lobby Server/DataObjects/World.cs
@@ -19,7 +19,7 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-namespace FFXIVClassic_Lobby_Server.dataobjects
+namespace Meteor.Lobby.DataObjects
{
class World
{
diff --git a/FFXIVClassic Lobby Server/Database.cs b/Lobby Server/Database.cs
similarity index 99%
rename from FFXIVClassic Lobby Server/Database.cs
rename to Lobby Server/Database.cs
index 7b2dee1f..874a63ec 100644
--- a/FFXIVClassic Lobby Server/Database.cs
+++ b/Lobby Server/Database.cs
@@ -19,13 +19,13 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-using FFXIVClassic_Lobby_Server.dataobjects;
-using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
-using FFXIVClassic_Lobby_Server.utils;
-namespace FFXIVClassic_Lobby_Server
+using Meteor.Lobby.DataObjects;
+using MySql.Data.MySqlClient;
+
+namespace Meteor.Lobby
{
//charState: 0 - Reserved, 1 - Inactive, 2 - Active
diff --git a/FFXIVClassic Lobby Server/FFXIVClassic Lobby Server.csproj b/Lobby Server/Lobby Server.csproj
similarity index 83%
rename from FFXIVClassic Lobby Server/FFXIVClassic Lobby Server.csproj
rename to Lobby Server/Lobby Server.csproj
index 640d1111..7d4d39ec 100644
--- a/FFXIVClassic Lobby Server/FFXIVClassic Lobby Server.csproj
+++ b/Lobby Server/Lobby Server.csproj
@@ -1,167 +1,167 @@
-
-
-
-
-
- Debug
- AnyCPU
- {703091E0-F69C-4177-8FAE-C258AC6A65AA}
- Exe
- Properties
- FFXIVClassic_Lobby_Server
- FFXIVClassic_Lobby_Server
- v4.5.1
- 512
- false
- publish\
- true
- Disk
- false
- Foreground
- 7
- Days
- false
- false
- true
- 0
- 1.0.0.%2a
- false
- true
- cc1ba6f5
-
-
-
- AnyCPU
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- true
-
-
- AnyCPU
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- true
-
-
- true
- bin\Debug\
- DEBUG;TRACE
- true
- full
- x64
- prompt
- MinimumRecommendedRules.ruleset
- true
-
-
- bin\x64\Release\
- TRACE
- true
- true
- pdbonly
- x64
- prompt
- MinimumRecommendedRules.ruleset
- true
-
-
-
- ..\packages\Cyotek.CircularBuffer.1.0.0.0\lib\net20\Cyotek.Collections.Generic.CircularBuffer.dll
-
-
- ..\FFXIVClassic Common Class Lib\bin\Debug\FFXIVClassic.Common.dll
-
-
- ..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll
- True
-
-
- ..\packages\NLog.4.3.4\lib\net45\NLog.dll
- True
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Always
-
-
-
- Designer
-
-
-
-
-
- False
- Microsoft .NET Framework 4.5 %28x86 and x64%29
- true
-
-
- False
- .NET Framework 3.5 SP1
- false
-
-
-
-
- xcopy "$(SolutionDir)data\lobby_config.ini" "$(SolutionDir)$(ProjectName)\$(OutDir)" /y
-
-
-
- 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}.
-
-
-
-
+
+
+
+
+
+ Debug
+ AnyCPU
+ {703091E0-F69C-4177-8FAE-C258AC6A65AA}
+ Exe
+ Properties
+ Meteor.Lobby
+ Lobby Server
+ v4.5.1
+ 512
+ false
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ true
+ cc1ba6f5
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ true
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ true
+
+
+ true
+ bin\Debug\
+ DEBUG;TRACE
+ true
+ full
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ bin\x64\Release\
+ TRACE
+ true
+ true
+ pdbonly
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+
+ ..\packages\Cyotek.CircularBuffer.1.0.0.0\lib\net20\Cyotek.Collections.Generic.CircularBuffer.dll
+
+
+ ..\FFXIVClassic Common Class Lib\bin\Debug\FFXIVClassic.Common.dll
+
+
+ ..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll
+ True
+
+
+ ..\packages\NLog.4.3.4\lib\net45\NLog.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+
+ Designer
+
+
+
+
+
+ False
+ Microsoft .NET Framework 4.5 %28x86 and x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+
+
+ xcopy "$(SolutionDir)data\lobby_config.ini" "$(SolutionDir)$(ProjectName)\$(OutDir)" /y
+
+
+
+ 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}.
+
+
+
+
\ No newline at end of file
diff --git a/FFXIVClassic Lobby Server/NLog.config b/Lobby Server/NLog.config
similarity index 79%
rename from FFXIVClassic Lobby Server/NLog.config
rename to Lobby Server/NLog.config
index f5debba1..4d7af06a 100644
--- a/FFXIVClassic Lobby Server/NLog.config
+++ b/Lobby Server/NLog.config
@@ -1,62 +1,62 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FFXIVClassic World Server/NLog.xsd b/Lobby Server/NLog.xsd
similarity index 100%
rename from FFXIVClassic World Server/NLog.xsd
rename to Lobby Server/NLog.xsd
diff --git a/FFXIVClassic Lobby Server/PacketProcessor.cs b/Lobby Server/PacketProcessor.cs
similarity index 98%
rename from FFXIVClassic Lobby Server/PacketProcessor.cs
rename to Lobby Server/PacketProcessor.cs
index b74996ce..99b0b759 100644
--- a/FFXIVClassic Lobby Server/PacketProcessor.cs
+++ b/Lobby Server/PacketProcessor.cs
@@ -19,18 +19,18 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-using FFXIVClassic.Common;
-using FFXIVClassic_Lobby_Server.dataobjects;
-using FFXIVClassic_Lobby_Server.packets;
-using FFXIVClassic_Lobby_Server.packets.receive;
-using FFXIVClassic_Lobby_Server.utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
-namespace FFXIVClassic_Lobby_Server
+using Meteor.Common;
+using Meteor.Lobby.DataObjects;
+using Meteor.Lobby.Packets;
+using Meteor.Lobby.Packets.Receive;
+
+namespace Meteor.Lobby
{
class PacketProcessor
{
diff --git a/FFXIVClassic Lobby Server/packets/HardCoded_Packets.cs b/Lobby Server/Packets/HardCoded_Packets.cs
similarity index 99%
rename from FFXIVClassic Lobby Server/packets/HardCoded_Packets.cs
rename to Lobby Server/Packets/HardCoded_Packets.cs
index 79e6928b..eda95541 100644
--- a/FFXIVClassic Lobby Server/packets/HardCoded_Packets.cs
+++ b/Lobby Server/Packets/HardCoded_Packets.cs
@@ -19,7 +19,7 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-namespace FFXIVClassic_Lobby_Server.packets
+namespace Meteor.Lobby.Packets
{
class HardCoded_Packets
{
diff --git a/FFXIVClassic Lobby Server/packets/receive/CharacterModifyPacket.cs b/Lobby Server/Packets/Receive/CharacterModifyPacket.cs
similarity index 97%
rename from FFXIVClassic Lobby Server/packets/receive/CharacterModifyPacket.cs
rename to Lobby Server/Packets/Receive/CharacterModifyPacket.cs
index e596e758..b5000491 100644
--- a/FFXIVClassic Lobby Server/packets/receive/CharacterModifyPacket.cs
+++ b/Lobby Server/Packets/Receive/CharacterModifyPacket.cs
@@ -23,7 +23,7 @@ using System;
using System.IO;
using System.Text;
-namespace FFXIVClassic_Lobby_Server.packets.receive
+namespace Meteor.Lobby.Packets.Receive
{
class CharacterModifyPacket
{
diff --git a/FFXIVClassic Lobby Server/packets/receive/SecurityHandshakePacket.cs b/Lobby Server/Packets/Receive/SecurityHandshakePacket.cs
similarity index 97%
rename from FFXIVClassic Lobby Server/packets/receive/SecurityHandshakePacket.cs
rename to Lobby Server/Packets/Receive/SecurityHandshakePacket.cs
index 1cddc866..b110aee6 100644
--- a/FFXIVClassic Lobby Server/packets/receive/SecurityHandshakePacket.cs
+++ b/Lobby Server/Packets/Receive/SecurityHandshakePacket.cs
@@ -23,7 +23,7 @@ using System;
using System.IO;
using System.Text;
-namespace FFXIVClassic_Lobby_Server.packets.receive
+namespace Meteor.Lobby.Packets.Receive
{
class SecurityHandshakePacket
{
diff --git a/FFXIVClassic Lobby Server/packets/receive/SelectCharacterPacket.cs b/Lobby Server/Packets/Receive/SelectCharacterPacket.cs
similarity index 97%
rename from FFXIVClassic Lobby Server/packets/receive/SelectCharacterPacket.cs
rename to Lobby Server/Packets/Receive/SelectCharacterPacket.cs
index 94e022ad..038335d7 100644
--- a/FFXIVClassic Lobby Server/packets/receive/SelectCharacterPacket.cs
+++ b/Lobby Server/Packets/Receive/SelectCharacterPacket.cs
@@ -22,7 +22,7 @@ along with Project Meteor Server. If not, see .
using System;
using System.IO;
-namespace FFXIVClassic_Lobby_Server.packets.receive
+namespace Meteor.Lobby.Packets.Receive
{
class SelectCharacterPacket
{
diff --git a/FFXIVClassic Lobby Server/packets/receive/SessionPacket.cs b/Lobby Server/Packets/Receive/SessionPacket.cs
similarity index 97%
rename from FFXIVClassic Lobby Server/packets/receive/SessionPacket.cs
rename to Lobby Server/Packets/Receive/SessionPacket.cs
index 83c7f4a2..acca0f2c 100644
--- a/FFXIVClassic Lobby Server/packets/receive/SessionPacket.cs
+++ b/Lobby Server/Packets/Receive/SessionPacket.cs
@@ -23,7 +23,7 @@ using System;
using System.IO;
using System.Text;
-namespace FFXIVClassic_Lobby_Server.packets.receive
+namespace Meteor.Lobby.Packets.Receive
{
class SessionPacket
{
diff --git a/FFXIVClassic Lobby Server/packets/send/AccountListPacket.cs b/Lobby Server/Packets/Send/AccountListPacket.cs
similarity index 97%
rename from FFXIVClassic Lobby Server/packets/send/AccountListPacket.cs
rename to Lobby Server/Packets/Send/AccountListPacket.cs
index 8ae4f77d..46144769 100644
--- a/FFXIVClassic Lobby Server/packets/send/AccountListPacket.cs
+++ b/Lobby Server/Packets/Send/AccountListPacket.cs
@@ -19,14 +19,14 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-using FFXIVClassic.Common;
-using FFXIVClassic_Lobby_Server.dataobjects;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
+using Meteor.Common;
+using Meteor.Lobby.DataObjects;
-namespace FFXIVClassic_Lobby_Server.packets
+namespace Meteor.Lobby.Packets
{
class AccountListPacket
{
diff --git a/FFXIVClassic Lobby Server/packets/send/CharaCreatorPacket.cs b/Lobby Server/Packets/Send/CharaCreatorPacket.cs
similarity index 97%
rename from FFXIVClassic Lobby Server/packets/send/CharaCreatorPacket.cs
rename to Lobby Server/Packets/Send/CharaCreatorPacket.cs
index 21585676..424a0f6e 100644
--- a/FFXIVClassic Lobby Server/packets/send/CharaCreatorPacket.cs
+++ b/Lobby Server/Packets/Send/CharaCreatorPacket.cs
@@ -19,12 +19,12 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-using FFXIVClassic.Common;
using System;
using System.IO;
using System.Text;
+using Meteor.Common;
-namespace FFXIVClassic_Lobby_Server.packets
+namespace Meteor.Lobby.Packets
{
class CharaCreatorPacket
{
diff --git a/FFXIVClassic Lobby Server/packets/send/CharacterListPacket.cs b/Lobby Server/Packets/Send/CharacterListPacket.cs
similarity index 98%
rename from FFXIVClassic Lobby Server/packets/send/CharacterListPacket.cs
rename to Lobby Server/Packets/Send/CharacterListPacket.cs
index f4069ef3..e4fc5ea0 100644
--- a/FFXIVClassic Lobby Server/packets/send/CharacterListPacket.cs
+++ b/Lobby Server/Packets/Send/CharacterListPacket.cs
@@ -19,14 +19,14 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-using FFXIVClassic.Common;
-using FFXIVClassic_Lobby_Server.dataobjects;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
+using Meteor.Common;
+using Meteor.Lobby.DataObjects;
-namespace FFXIVClassic_Lobby_Server.packets
+namespace Meteor.Lobby.Packets
{
class CharacterListPacket
{
diff --git a/FFXIVClassic Lobby Server/packets/send/ErrorPacket.cs b/Lobby Server/Packets/Send/ErrorPacket.cs
similarity index 96%
rename from FFXIVClassic Lobby Server/packets/send/ErrorPacket.cs
rename to Lobby Server/Packets/Send/ErrorPacket.cs
index 8efceea3..7f63d900 100644
--- a/FFXIVClassic Lobby Server/packets/send/ErrorPacket.cs
+++ b/Lobby Server/Packets/Send/ErrorPacket.cs
@@ -19,12 +19,12 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-using FFXIVClassic.Common;
using System;
using System.IO;
using System.Text;
+using Meteor.Common;
-namespace FFXIVClassic_Lobby_Server.packets
+namespace Meteor.Lobby.Packets
{
class ErrorPacket
{
diff --git a/FFXIVClassic Lobby Server/packets/send/ImportListPacket.cs b/Lobby Server/Packets/Send/ImportListPacket.cs
similarity index 98%
rename from FFXIVClassic Lobby Server/packets/send/ImportListPacket.cs
rename to Lobby Server/Packets/Send/ImportListPacket.cs
index 8aec0d62..ed22f160 100644
--- a/FFXIVClassic Lobby Server/packets/send/ImportListPacket.cs
+++ b/Lobby Server/Packets/Send/ImportListPacket.cs
@@ -19,13 +19,13 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-using FFXIVClassic.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
+using Meteor.Common;
-namespace FFXIVClassic_Lobby_Server.packets
+namespace Meteor.Lobby.Packets
{
class ImportListPacket
{
diff --git a/FFXIVClassic Lobby Server/packets/send/RetainerListPacket.cs b/Lobby Server/Packets/Send/RetainerListPacket.cs
similarity index 98%
rename from FFXIVClassic Lobby Server/packets/send/RetainerListPacket.cs
rename to Lobby Server/Packets/Send/RetainerListPacket.cs
index cebb94fd..ca780b39 100644
--- a/FFXIVClassic Lobby Server/packets/send/RetainerListPacket.cs
+++ b/Lobby Server/Packets/Send/RetainerListPacket.cs
@@ -19,13 +19,14 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-using FFXIVClassic.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
+using Meteor.Common;
+using Meteor.Lobby.DataObjects;
-namespace FFXIVClassic_Lobby_Server.packets
+namespace Meteor.Lobby.Packets
{
class RetainerListPacket
{
diff --git a/FFXIVClassic Lobby Server/packets/send/SelectCharacterConfirmPacket.cs b/Lobby Server/Packets/Send/SelectCharacterConfirmPacket.cs
similarity index 97%
rename from FFXIVClassic Lobby Server/packets/send/SelectCharacterConfirmPacket.cs
rename to Lobby Server/Packets/Send/SelectCharacterConfirmPacket.cs
index 6c5fcf75..d604f0d6 100644
--- a/FFXIVClassic Lobby Server/packets/send/SelectCharacterConfirmPacket.cs
+++ b/Lobby Server/Packets/Send/SelectCharacterConfirmPacket.cs
@@ -19,13 +19,13 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-using FFXIVClassic.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
+using Meteor.Common;
-namespace FFXIVClassic_Lobby_Server.packets
+namespace Meteor.Lobby.Packets
{
class SelectCharacterConfirmPacket
{
diff --git a/FFXIVClassic Lobby Server/packets/send/WorldListPacket.cs b/Lobby Server/Packets/Send/WorldListPacket.cs
similarity index 97%
rename from FFXIVClassic Lobby Server/packets/send/WorldListPacket.cs
rename to Lobby Server/Packets/Send/WorldListPacket.cs
index f4069c75..62f0f0d1 100644
--- a/FFXIVClassic Lobby Server/packets/send/WorldListPacket.cs
+++ b/Lobby Server/Packets/Send/WorldListPacket.cs
@@ -19,14 +19,14 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-using FFXIVClassic.Common;
-using FFXIVClassic_Lobby_Server.dataobjects;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
+using Meteor.Common;
+using Meteor.Lobby.DataObjects;
-namespace FFXIVClassic_Lobby_Server.packets
+namespace Meteor.Lobby.Packets
{
class WorldListPacket
{
diff --git a/FFXIVClassic Lobby Server/Program.cs b/Lobby Server/Program.cs
similarity index 98%
rename from FFXIVClassic Lobby Server/Program.cs
rename to Lobby Server/Program.cs
index a7351140..4a630c43 100644
--- a/FFXIVClassic Lobby Server/Program.cs
+++ b/Lobby Server/Program.cs
@@ -22,9 +22,11 @@ along with Project Meteor Server. If not, see .
using System;
using System.Diagnostics;
using System.Threading;
+
using MySql.Data.MySqlClient;
using NLog;
-namespace FFXIVClassic_Lobby_Server
+
+namespace Meteor.Lobby
{
class Program
{
diff --git a/FFXIVClassic Lobby Server/Properties/AssemblyInfo.cs b/Lobby Server/Properties/AssemblyInfo.cs
similarity index 100%
rename from FFXIVClassic Lobby Server/Properties/AssemblyInfo.cs
rename to Lobby Server/Properties/AssemblyInfo.cs
diff --git a/FFXIVClassic Lobby Server/Server.cs b/Lobby Server/Server.cs
similarity index 99%
rename from FFXIVClassic Lobby Server/Server.cs
rename to Lobby Server/Server.cs
index ed08ede0..3d6f28de 100644
--- a/FFXIVClassic Lobby Server/Server.cs
+++ b/Lobby Server/Server.cs
@@ -25,9 +25,9 @@ using System.Net;
using System.Net.Sockets;
using System.Threading;
-using FFXIVClassic.Common;
+using Meteor.Common;
-namespace FFXIVClassic_Lobby_Server
+namespace Meteor.Lobby
{
class Server
{
diff --git a/FFXIVClassic Common Class Lib/app.config b/Lobby Server/app.config
similarity index 98%
rename from FFXIVClassic Common Class Lib/app.config
rename to Lobby Server/app.config
index e418f4e3..14a5fe96 100644
--- a/FFXIVClassic Common Class Lib/app.config
+++ b/Lobby Server/app.config
@@ -1,9 +1,9 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/FFXIVClassic Lobby Server/packages.config b/Lobby Server/packages.config
similarity index 98%
rename from FFXIVClassic Lobby Server/packages.config
rename to Lobby Server/packages.config
index 6d704229..f5acdf38 100644
--- a/FFXIVClassic Lobby Server/packages.config
+++ b/Lobby Server/packages.config
@@ -1,9 +1,9 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FFXIVClassic Map Server/App.config b/Map Server/App.config
similarity index 97%
rename from FFXIVClassic Map Server/App.config
rename to Map Server/App.config
index 3c9bd9c6..34d13d4d 100644
--- a/FFXIVClassic Map Server/App.config
+++ b/Map Server/App.config
@@ -1,20 +1,20 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FFXIVClassic Map Server/CommandProcessor.cs b/Map Server/CommandProcessor.cs
similarity index 100%
rename from FFXIVClassic Map Server/CommandProcessor.cs
rename to Map Server/CommandProcessor.cs
diff --git a/FFXIVClassic Map Server/ConfigConstants.cs b/Map Server/ConfigConstants.cs
similarity index 99%
rename from FFXIVClassic Map Server/ConfigConstants.cs
rename to Map Server/ConfigConstants.cs
index 41d9a37e..fe9e289a 100644
--- a/FFXIVClassic Map Server/ConfigConstants.cs
+++ b/Map Server/ConfigConstants.cs
@@ -19,7 +19,7 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-using FFXIVClassic.Common;
+using Meteor.Common;
using System;
using System.IO;
using System.Linq;
diff --git a/FFXIVClassic Map Server/Database.cs b/Map Server/Database.cs
similarity index 99%
rename from FFXIVClassic Map Server/Database.cs
rename to Map Server/Database.cs
index a65af165..15c155e5 100644
--- a/FFXIVClassic Map Server/Database.cs
+++ b/Map Server/Database.cs
@@ -22,7 +22,7 @@ along with Project Meteor Server. If not, see .
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
-using FFXIVClassic.Common;
+using Meteor.Common;
using FFXIVClassic_Map_Server.utils;
using FFXIVClassic_Map_Server.packets.send.player;
diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/Map Server/Map Server.csproj
similarity index 97%
rename from FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
rename to Map Server/Map Server.csproj
index fc0432bd..5c7bfe76 100644
--- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj
+++ b/Map Server/Map Server.csproj
@@ -1,443 +1,443 @@
-
-
-
-
-
- Debug
- AnyCPU
- {E8FA2784-D4B9-4711-8CC6-712A4B1CD54F}
- Exe
- Properties
- FFXIVClassic_Map_Server
- FFXIVClassic Map Server
- v4.5.1
- 512
- 1d22ec4a
-
-
-
- AnyCPU
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- true
- true
-
-
- AnyCPU
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- true
-
-
- Always
-
-
- true
- bin\Debug\
- DEBUG;TRACE
- true
- full
- x64
- prompt
- MinimumRecommendedRules.ruleset
- true
-
-
- bin\x64\Release\
- TRACE
- true
- true
- pdbonly
- x64
- prompt
- MinimumRecommendedRules.ruleset
- true
-
-
-
- ..\packages\Cyotek.CircularBuffer.1.0.0.0\lib\net20\Cyotek.Collections.Generic.CircularBuffer.dll
- True
-
-
- False
- ..\FFXIVClassic Common Class Lib\bin\Debug\FFXIVClassic.Common.dll
-
-
- ..\packages\MoonSharp.1.2.1.0\lib\net40-client\MoonSharp.Interpreter.dll
-
-
- ..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll
- True
-
-
- False
- ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
-
-
- ..\packages\NLog.4.3.5\lib\net45\NLog.dll
- True
-
-
- False
- navmesh\SharpNav.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- True
- True
- Resources.resx
-
-
-
-
-
-
-
-
-
-
-
-
- Always
- Designer
-
-
- Designer
-
-
-
-
-
-
- PublicResXFileCodeGenerator
- Resources.Designer.cs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 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}.
-
-
-
-
+
+
+
+
+
+ Debug
+ AnyCPU
+ {E8FA2784-D4B9-4711-8CC6-712A4B1CD54F}
+ Exe
+ Properties
+ Meteor.Map
+ Map Server
+ v4.5.1
+ 512
+ 1d22ec4a
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ true
+ true
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ true
+
+
+ Always
+
+
+ true
+ bin\Debug\
+ DEBUG;TRACE
+ true
+ full
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ bin\x64\Release\
+ TRACE
+ true
+ true
+ pdbonly
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+
+ ..\packages\Cyotek.CircularBuffer.1.0.0.0\lib\net20\Cyotek.Collections.Generic.CircularBuffer.dll
+ True
+
+
+ False
+ ..\FFXIVClassic Common Class Lib\bin\Debug\FFXIVClassic.Common.dll
+
+
+ ..\packages\MoonSharp.1.2.1.0\lib\net40-client\MoonSharp.Interpreter.dll
+
+
+ ..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll
+ True
+
+
+ False
+ ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
+
+
+ ..\packages\NLog.4.3.5\lib\net45\NLog.dll
+ True
+
+
+ False
+ navmesh\SharpNav.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+ Designer
+
+
+ Designer
+
+
+
+
+
+
+ PublicResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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}.
+
+
+
+
\ No newline at end of file
diff --git a/FFXIVClassic Map Server/NLog.config b/Map Server/NLog.config
similarity index 97%
rename from FFXIVClassic Map Server/NLog.config
rename to Map Server/NLog.config
index ad616d50..c7958a7f 100644
--- a/FFXIVClassic Map Server/NLog.config
+++ b/Map Server/NLog.config
@@ -1,64 +1,64 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FFXIVClassic Lobby Server/NLog.xsd b/Map Server/NLog.xsd
similarity index 98%
rename from FFXIVClassic Lobby Server/NLog.xsd
rename to Map Server/NLog.xsd
index 395075c9..31cd6c0a 100644
--- a/FFXIVClassic Lobby Server/NLog.xsd
+++ b/Map Server/NLog.xsd
@@ -1,2601 +1,2601 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Watch config file for changes and reload automatically.
-
-
-
-
- Print internal NLog messages to the console. Default value is: false
-
-
-
-
- Print internal NLog messages to the console error output. Default value is: false
-
-
-
-
- Write internal NLog messages to the specified file.
-
-
-
-
- Log level threshold for internal log messages. Default value is: Info.
-
-
-
-
- Global log level threshold for application log messages. Messages below this level won't be logged..
-
-
-
-
- Pass NLog internal exceptions to the application. Default value is: false.
-
-
-
-
- Write internal NLog messages to the the System.Diagnostics.Trace. Default value is: false
-
-
-
-
-
-
-
-
-
-
-
-
-
- Make all targets within this section asynchronous (Creates additional threads but the calling thread isn't blocked by any target writes).
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Prefix for targets/layout renderers/filters/conditions loaded from this assembly.
-
-
-
-
- Load NLog extensions from the specified file (*.dll)
-
-
-
-
- Load NLog extensions from the specified assembly. Assembly name should be fully qualified.
-
-
-
-
-
-
-
-
-
- Name of the logger. May include '*' character which acts like a wildcard. Allowed forms are: *, Name, *Name, Name* and *Name*
-
-
-
-
- Comma separated list of levels that this rule matches.
-
-
-
-
- Minimum level that this rule matches.
-
-
-
-
- Maximum level that this rule matches.
-
-
-
-
- Level that this rule matches.
-
-
-
-
- Comma separated list of target names.
-
-
-
-
- Ignore further rules if this one matches.
-
-
-
-
- Enable or disable logging rule. Disabled rules are ignored.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the file to be included. The name is relative to the name of the current config file.
-
-
-
-
- Ignore any errors in the include file.
-
-
-
-
-
-
- Variable name.
-
-
-
-
- Variable value.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Layout used to format log messages.
-
-
-
-
- Indicates whether to add <!-- --> comments around all written texts.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Number of log events that should be processed in a batch by the lazy writer thread.
-
-
-
-
- Action to be taken when the lazy writer thread request queue count exceeds the set limit.
-
-
-
-
- Limit on the number of requests in the lazy writer thread request queue.
-
-
-
-
- Time in milliseconds to sleep between batches.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Number of log events to be buffered.
-
-
-
-
- Timeout (in milliseconds) after which the contents of buffer will be flushed if there's no write in the specified period of time. Use -1 to disable timed flushes.
-
-
-
-
- Indicates whether to use sliding timeout.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Encoding to be used.
-
-
-
-
- Instance of that is used to format log messages.
-
-
-
-
- Maximum message size in bytes.
-
-
-
-
- Indicates whether to append newline at the end of log message.
-
-
-
-
- Action that should be taken if the will be more connections than .
-
-
-
-
- Action that should be taken if the message is larger than maxMessageSize.
-
-
-
-
- Indicates whether to keep connection open whenever possible.
-
-
-
-
- Size of the connection cache (number of connections which are kept alive).
-
-
-
-
- Maximum current connections. 0 = no maximum.
-
-
-
-
- Network address.
-
-
-
-
- Maximum queue size.
-
-
-
-
- Indicates whether to include source info (file name and line number) in the information sent over the network.
-
-
-
-
- NDC item separator.
-
-
-
-
- Indicates whether to include stack contents.
-
-
-
-
- Indicates whether to include call site (class and method name) in the information sent over the network.
-
-
-
-
- AppInfo field. By default it's the friendly name of the current AppDomain.
-
-
-
-
- Indicates whether to include NLog-specific extensions to log4j schema.
-
-
-
-
- Indicates whether to include dictionary contents.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Layout that should be use to calcuate the value for the parameter.
-
-
-
-
- Viewer parameter name.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Text to be rendered.
-
-
-
-
- Header.
-
-
-
-
- Footer.
-
-
-
-
- Indicates whether to use default row highlighting rules.
-
-
-
-
- The encoding for writing messages to the .
-
-
-
-
- Indicates whether the error stream (stderr) should be used instead of the output stream (stdout).
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Condition that must be met in order to set the specified foreground and background color.
-
-
-
-
- Background color.
-
-
-
-
- Foreground color.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Indicates whether to ignore case when comparing texts.
-
-
-
-
- Regular expression to be matched. You must specify either text or regex.
-
-
-
-
- Text to be matched. You must specify either text or regex.
-
-
-
-
- Indicates whether to match whole words only.
-
-
-
-
- Compile the ? This can improve the performance, but at the costs of more memory usage. If false, the Regex Cache is used.
-
-
-
-
- Background color.
-
-
-
-
- Foreground color.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Text to be rendered.
-
-
-
-
- Header.
-
-
-
-
- Footer.
-
-
-
-
- Indicates whether to send the log messages to the standard error instead of the standard output.
-
-
-
-
- The encoding for writing messages to the .
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Connection string. When provided, it overrides the values specified in DBHost, DBUserName, DBPassword, DBDatabase.
-
-
-
-
- Name of the connection string (as specified in <connectionStrings> configuration section.
-
-
-
-
- Database name. If the ConnectionString is not provided this value will be used to construct the "Database=" part of the connection string.
-
-
-
-
- Database host name. If the ConnectionString is not provided this value will be used to construct the "Server=" part of the connection string.
-
-
-
-
- Database password. If the ConnectionString is not provided this value will be used to construct the "Password=" part of the connection string.
-
-
-
-
- Name of the database provider.
-
-
-
-
- Database user name. If the ConnectionString is not provided this value will be used to construct the "User ID=" part of the connection string.
-
-
-
-
- Indicates whether to keep the database connection open between the log events.
-
-
-
-
- Obsolete - value will be ignored! The logging code always runs outside of transaction. Gets or sets a value indicating whether to use database transactions. Some data providers require this.
-
-
-
-
- Connection string using for installation and uninstallation. If not provided, regular ConnectionString is being used.
-
-
-
-
- Text of the SQL command to be run on each log level.
-
-
-
-
- Type of the SQL command to be run on each log level.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Type of the command.
-
-
-
-
- Connection string to run the command against. If not provided, connection string from the target is used.
-
-
-
-
- Indicates whether to ignore failures.
-
-
-
-
- Command text.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Layout that should be use to calcuate the value for the parameter.
-
-
-
-
- Database parameter name.
-
-
-
-
- Database parameter precision.
-
-
-
-
- Database parameter scale.
-
-
-
-
- Database parameter size.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Text to be rendered.
-
-
-
-
- Header.
-
-
-
-
- Footer.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Layout used to format log messages.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Layout used to format log messages.
-
-
-
-
- Layout that renders event Category.
-
-
-
-
- Layout that renders event ID.
-
-
-
-
- Name of the Event Log to write to. This can be System, Application or any user-defined name.
-
-
-
-
- Name of the machine on which Event Log service is running.
-
-
-
-
- Value to be used as the event Source.
-
-
-
-
- Action to take if the message is larger than the option.
-
-
-
-
- Optional entrytype. When not set, or when not convertable to then determined by
-
-
-
-
- Message length limit to write to the Event Log.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Indicates whether to return to the first target after any successful write.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Text to be rendered.
-
-
-
-
- Header.
-
-
-
-
- Footer.
-
-
-
-
- File encoding.
-
-
-
-
- Line ending mode.
-
-
-
-
- Way file archives are numbered.
-
-
-
-
- Name of the file to be used for an archive.
-
-
-
-
- Indicates whether to automatically archive log files every time the specified time passes.
-
-
-
-
- Size in bytes above which log files will be automatically archived. Warning: combining this with isn't supported. We cannot Create multiple archive files, if they should have the same name. Choose:
-
-
-
-
- Maximum number of archive files that should be kept.
-
-
-
-
- Indicates whether to compress archive files into the zip archive format.
-
-
-
-
- Gets or set a value indicating whether a managed file stream is forced, instead of used the native implementation.
-
-
-
-
- Cleanup invalid values in a filename, e.g. slashes in a filename. If set to true, this can impact the performance of massive writes. If set to false, nothing Gets written when the filename is wrong.
-
-
-
-
- Name of the file to write to.
-
-
-
-
- Value specifying the date format to use when archiving files.
-
-
-
-
- Indicates whether to archive old log file on startup.
-
-
-
-
- Indicates whether to Create directories if they Do not exist.
-
-
-
-
- Indicates whether to enable log file(s) to be deleted.
-
-
-
-
- File attributes (Windows only).
-
-
-
-
- Indicates whether to delete old log file on startup.
-
-
-
-
- Indicates whether to replace file contents on each write instead of appending log message at the end.
-
-
-
-
- Indicates whether concurrent writes to the log file by multiple processes on the same host.
-
-
-
-
- Delay in milliseconds to wait before attempting to write to the file again.
-
-
-
-
- Maximum number of log filenames that should be stored as existing.
-
-
-
-
- Indicates whether concurrent writes to the log file by multiple processes on different network hosts.
-
-
-
-
- Number of files to be kept open. Setting this to a higher value may improve performance in a situation where a single File target is writing to many files (such as splitting by level or by logger).
-
-
-
-
- Maximum number of seconds that files are kept open. If this number is negative the files are not automatically closed after a period of inactivity.
-
-
-
-
- Log file buffer size in bytes.
-
-
-
-
- Indicates whether to automatically flush the file buffers after each log message.
-
-
-
-
- Number of times the write is appended on the file before NLog discards the log message.
-
-
-
-
- Indicates whether to keep log file open instead of opening and closing it on each logging event.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Condition expression. Log events who meet this condition will be forwarded to the wrapped target.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Windows Domain name to change context to.
-
-
-
-
- Required impersonation level.
-
-
-
-
- Type of the logon provider.
-
-
-
-
- Logon Type.
-
-
-
-
- User account password.
-
-
-
-
- Indicates whether to revert to the credentials of the process instead of impersonating another user.
-
-
-
-
- Username to change context to.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Endpoint address.
-
-
-
-
- Name of the endpoint configuration in WCF configuration file.
-
-
-
-
- Indicates whether to use a WCF service contract that is one way (fire and forGet) or two way (request-reply)
-
-
-
-
- Client ID.
-
-
-
-
- Indicates whether to include per-event properties in the payload sent to the server.
-
-
-
-
- Indicates whether to use binary message encoding.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Layout that should be use to calculate the value for the parameter.
-
-
-
-
- Name of the parameter.
-
-
-
-
- Type of the parameter.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Text to be rendered.
-
-
-
-
- Header.
-
-
-
-
- Footer.
-
-
-
-
- Indicates whether to send message as HTML instead of plain text.
-
-
-
-
- Encoding to be used for sending e-mail.
-
-
-
-
- Indicates whether to add new lines between log entries.
-
-
-
-
- CC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com).
-
-
-
-
- Recipients' email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com).
-
-
-
-
- BCC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com).
-
-
-
-
- Mail message body (repeated for each log message send in one mail).
-
-
-
-
- Mail subject.
-
-
-
-
- Sender's email address (e.g. joe@domain.com).
-
-
-
-
- Indicates whether NewLine characters in the body should be replaced with tags.
-
-
-
-
- Priority used for sending mails.
-
-
-
-
- Indicates the SMTP client timeout.
-
-
-
-
- SMTP Server to be used for sending.
-
-
-
-
- SMTP Authentication mode.
-
-
-
-
- Username used to connect to SMTP server (used when SmtpAuthentication is set to "basic").
-
-
-
-
- Password used to authenticate against SMTP server (used when SmtpAuthentication is set to "basic").
-
-
-
-
- Indicates whether SSL (secure sockets layer) should be used when communicating with SMTP server.
-
-
-
-
- Port number that SMTP Server is listening on.
-
-
-
-
- Indicates whether the default Settings from System.Net.MailSettings should be used.
-
-
-
-
- Folder where applications save mail messages to be processed by the local SMTP server.
-
-
-
-
- Specifies how outgoing email messages will be handled.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Layout used to format log messages.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Layout used to format log messages.
-
-
-
-
- Encoding to be used when writing text to the queue.
-
-
-
-
- Indicates whether to use the XML format when serializing message. This will also disable creating queues.
-
-
-
-
- Indicates whether to check if a queue exists before writing to it.
-
-
-
-
- Indicates whether to Create the queue if it Doesn't exists.
-
-
-
-
- Label to associate with each message.
-
-
-
-
- Name of the queue to write to.
-
-
-
-
- Indicates whether to use recoverable messages (with guaranteed delivery).
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Class name.
-
-
-
-
- Method name. The method must be public and static. Use the AssemblyQualifiedName , https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspx e.g.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Layout used to format log messages.
-
-
-
-
- Encoding to be used.
-
-
-
-
- Maximum message size in bytes.
-
-
-
-
- Indicates whether to append newline at the end of log message.
-
-
-
-
- Action that should be taken if the will be more connections than .
-
-
-
-
- Action that should be taken if the message is larger than maxMessageSize.
-
-
-
-
- Network address.
-
-
-
-
- Size of the connection cache (number of connections which are kept alive).
-
-
-
-
- Indicates whether to keep connection open whenever possible.
-
-
-
-
- Maximum current connections. 0 = no maximum.
-
-
-
-
- Maximum queue size.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Encoding to be used.
-
-
-
-
- Instance of that is used to format log messages.
-
-
-
-
- Maximum message size in bytes.
-
-
-
-
- Indicates whether to append newline at the end of log message.
-
-
-
-
- Action that should be taken if the will be more connections than .
-
-
-
-
- Action that should be taken if the message is larger than maxMessageSize.
-
-
-
-
- Indicates whether to keep connection open whenever possible.
-
-
-
-
- Size of the connection cache (number of connections which are kept alive).
-
-
-
-
- Maximum current connections. 0 = no maximum.
-
-
-
-
- Network address.
-
-
-
-
- Maximum queue size.
-
-
-
-
- Indicates whether to include source info (file name and line number) in the information sent over the network.
-
-
-
-
- NDC item separator.
-
-
-
-
- Indicates whether to include stack contents.
-
-
-
-
- Indicates whether to include call site (class and method name) in the information sent over the network.
-
-
-
-
- AppInfo field. By default it's the friendly name of the current AppDomain.
-
-
-
-
- Indicates whether to include NLog-specific extensions to log4j schema.
-
-
-
-
- Indicates whether to include dictionary contents.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Layout used to format log messages.
-
-
-
-
- Indicates whether to perform layout calculation.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Layout used to format log messages.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Indicates whether performance counter should be automatically Created.
-
-
-
-
- Name of the performance counter category.
-
-
-
-
- Counter help text.
-
-
-
-
- Name of the performance counter.
-
-
-
-
- Performance counter type.
-
-
-
-
- The value by which to increment the counter.
-
-
-
-
- Performance counter instance name.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Default filter to be applied when no specific rule matches.
-
-
-
-
-
-
-
-
-
-
-
-
- Condition to be tested.
-
-
-
-
- Resulting filter to be applied when the condition matches.
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Number of times to repeat each log message.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Number of retries that should be attempted on the wrapped target in case of a failure.
-
-
-
-
- Time to wait between retries in milliseconds.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Layout used to format log messages.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name of the target.
-
-
-
-
- Should we include the BOM (Byte-order-mark) for UTF? Influences the property. This will only work for UTF-8.
-
-
-
-
- Encoding.
-
-
-
-
- Web service method name. Only used with Soap.
-
-
-
-
- Web service namespace. Only used with Soap.
-
-
-
-
- Protocol to be used when calling web service.
-
-
-
-
- Web service URL.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Footer layout.
-
-
-
-
- Header layout.
-
-
-
-
- Body layout (can be repeated multiple times).
-
-
-
-
- Custom column delimiter value (valid when ColumnDelimiter is set to 'Custom').
-
-
-
-
- Column delimiter.
-
-
-
-
- Quote Character.
-
-
-
-
- Quoting mode.
-
-
-
-
- Indicates whether CVS should include header.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Layout of the column.
-
-
-
-
- Name of the column.
-
-
-
-
-
-
-
-
-
-
-
-
- Option to suppress the extra spaces in the output json
-
-
-
-
-
-
-
-
-
-
-
-
-
- Determines wether or not this attribute will be Json encoded.
-
-
-
-
- Layout that will be rendered as the attribute's value.
-
-
-
-
- Name of the attribute.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Footer layout.
-
-
-
-
- Header layout.
-
-
-
-
- Body layout (can be repeated multiple times).
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Layout text.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Action to be taken when filter matches.
-
-
-
-
- Condition expression.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Action to be taken when filter matches.
-
-
-
-
- Indicates whether to ignore case when comparing strings.
-
-
-
-
- Layout to be used to filter log messages.
-
-
-
-
- Substring to be matched.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Action to be taken when filter matches.
-
-
-
-
- String to compare the layout to.
-
-
-
-
- Indicates whether to ignore case when comparing strings.
-
-
-
-
- Layout to be used to filter log messages.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Action to be taken when filter matches.
-
-
-
-
- Indicates whether to ignore case when comparing strings.
-
-
-
-
- Layout to be used to filter log messages.
-
-
-
-
- Substring to be matched.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Action to be taken when filter matches.
-
-
-
-
- String to compare the layout to.
-
-
-
-
- Indicates whether to ignore case when comparing strings.
-
-
-
-
- Layout to be used to filter log messages.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Watch config file for changes and reload automatically.
+
+
+
+
+ Print internal NLog messages to the console. Default value is: false
+
+
+
+
+ Print internal NLog messages to the console error output. Default value is: false
+
+
+
+
+ Write internal NLog messages to the specified file.
+
+
+
+
+ Log level threshold for internal log messages. Default value is: Info.
+
+
+
+
+ Global log level threshold for application log messages. Messages below this level won't be logged..
+
+
+
+
+ Pass NLog internal exceptions to the application. Default value is: false.
+
+
+
+
+ Write internal NLog messages to the the System.Diagnostics.Trace. Default value is: false
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Make all targets within this section asynchronous (Creates additional threads but the calling thread isn't blocked by any target writes).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Prefix for targets/layout renderers/filters/conditions loaded from this assembly.
+
+
+
+
+ Load NLog extensions from the specified file (*.dll)
+
+
+
+
+ Load NLog extensions from the specified assembly. Assembly name should be fully qualified.
+
+
+
+
+
+
+
+
+
+ Name of the logger. May include '*' character which acts like a wildcard. Allowed forms are: *, Name, *Name, Name* and *Name*
+
+
+
+
+ Comma separated list of levels that this rule matches.
+
+
+
+
+ Minimum level that this rule matches.
+
+
+
+
+ Maximum level that this rule matches.
+
+
+
+
+ Level that this rule matches.
+
+
+
+
+ Comma separated list of target names.
+
+
+
+
+ Ignore further rules if this one matches.
+
+
+
+
+ Enable or disable logging rule. Disabled rules are ignored.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the file to be included. The name is relative to the name of the current config file.
+
+
+
+
+ Ignore any errors in the include file.
+
+
+
+
+
+
+ Variable name.
+
+
+
+
+ Variable value.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+ Indicates whether to add <!-- --> comments around all written texts.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Number of log events that should be processed in a batch by the lazy writer thread.
+
+
+
+
+ Action to be taken when the lazy writer thread request queue count exceeds the set limit.
+
+
+
+
+ Limit on the number of requests in the lazy writer thread request queue.
+
+
+
+
+ Time in milliseconds to sleep between batches.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Number of log events to be buffered.
+
+
+
+
+ Timeout (in milliseconds) after which the contents of buffer will be flushed if there's no write in the specified period of time. Use -1 to disable timed flushes.
+
+
+
+
+ Indicates whether to use sliding timeout.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Encoding to be used.
+
+
+
+
+ Instance of that is used to format log messages.
+
+
+
+
+ Maximum message size in bytes.
+
+
+
+
+ Indicates whether to append newline at the end of log message.
+
+
+
+
+ Action that should be taken if the will be more connections than .
+
+
+
+
+ Action that should be taken if the message is larger than maxMessageSize.
+
+
+
+
+ Indicates whether to keep connection open whenever possible.
+
+
+
+
+ Size of the connection cache (number of connections which are kept alive).
+
+
+
+
+ Maximum current connections. 0 = no maximum.
+
+
+
+
+ Network address.
+
+
+
+
+ Maximum queue size.
+
+
+
+
+ Indicates whether to include source info (file name and line number) in the information sent over the network.
+
+
+
+
+ NDC item separator.
+
+
+
+
+ Indicates whether to include stack contents.
+
+
+
+
+ Indicates whether to include call site (class and method name) in the information sent over the network.
+
+
+
+
+ AppInfo field. By default it's the friendly name of the current AppDomain.
+
+
+
+
+ Indicates whether to include NLog-specific extensions to log4j schema.
+
+
+
+
+ Indicates whether to include dictionary contents.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Layout that should be use to calcuate the value for the parameter.
+
+
+
+
+ Viewer parameter name.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Text to be rendered.
+
+
+
+
+ Header.
+
+
+
+
+ Footer.
+
+
+
+
+ Indicates whether to use default row highlighting rules.
+
+
+
+
+ The encoding for writing messages to the .
+
+
+
+
+ Indicates whether the error stream (stderr) should be used instead of the output stream (stdout).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Condition that must be met in order to set the specified foreground and background color.
+
+
+
+
+ Background color.
+
+
+
+
+ Foreground color.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Indicates whether to ignore case when comparing texts.
+
+
+
+
+ Regular expression to be matched. You must specify either text or regex.
+
+
+
+
+ Text to be matched. You must specify either text or regex.
+
+
+
+
+ Indicates whether to match whole words only.
+
+
+
+
+ Compile the ? This can improve the performance, but at the costs of more memory usage. If false, the Regex Cache is used.
+
+
+
+
+ Background color.
+
+
+
+
+ Foreground color.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Text to be rendered.
+
+
+
+
+ Header.
+
+
+
+
+ Footer.
+
+
+
+
+ Indicates whether to send the log messages to the standard error instead of the standard output.
+
+
+
+
+ The encoding for writing messages to the .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Connection string. When provided, it overrides the values specified in DBHost, DBUserName, DBPassword, DBDatabase.
+
+
+
+
+ Name of the connection string (as specified in <connectionStrings> configuration section.
+
+
+
+
+ Database name. If the ConnectionString is not provided this value will be used to construct the "Database=" part of the connection string.
+
+
+
+
+ Database host name. If the ConnectionString is not provided this value will be used to construct the "Server=" part of the connection string.
+
+
+
+
+ Database password. If the ConnectionString is not provided this value will be used to construct the "Password=" part of the connection string.
+
+
+
+
+ Name of the database provider.
+
+
+
+
+ Database user name. If the ConnectionString is not provided this value will be used to construct the "User ID=" part of the connection string.
+
+
+
+
+ Indicates whether to keep the database connection open between the log events.
+
+
+
+
+ Obsolete - value will be ignored! The logging code always runs outside of transaction. Gets or sets a value indicating whether to use database transactions. Some data providers require this.
+
+
+
+
+ Connection string using for installation and uninstallation. If not provided, regular ConnectionString is being used.
+
+
+
+
+ Text of the SQL command to be run on each log level.
+
+
+
+
+ Type of the SQL command to be run on each log level.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Type of the command.
+
+
+
+
+ Connection string to run the command against. If not provided, connection string from the target is used.
+
+
+
+
+ Indicates whether to ignore failures.
+
+
+
+
+ Command text.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Layout that should be use to calcuate the value for the parameter.
+
+
+
+
+ Database parameter name.
+
+
+
+
+ Database parameter precision.
+
+
+
+
+ Database parameter scale.
+
+
+
+
+ Database parameter size.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Text to be rendered.
+
+
+
+
+ Header.
+
+
+
+
+ Footer.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+ Layout that renders event Category.
+
+
+
+
+ Layout that renders event ID.
+
+
+
+
+ Name of the Event Log to write to. This can be System, Application or any user-defined name.
+
+
+
+
+ Name of the machine on which Event Log service is running.
+
+
+
+
+ Value to be used as the event Source.
+
+
+
+
+ Action to take if the message is larger than the option.
+
+
+
+
+ Optional entrytype. When not set, or when not convertable to then determined by
+
+
+
+
+ Message length limit to write to the Event Log.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Indicates whether to return to the first target after any successful write.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Text to be rendered.
+
+
+
+
+ Header.
+
+
+
+
+ Footer.
+
+
+
+
+ File encoding.
+
+
+
+
+ Line ending mode.
+
+
+
+
+ Way file archives are numbered.
+
+
+
+
+ Name of the file to be used for an archive.
+
+
+
+
+ Indicates whether to automatically archive log files every time the specified time passes.
+
+
+
+
+ Size in bytes above which log files will be automatically archived. Warning: combining this with isn't supported. We cannot Create multiple archive files, if they should have the same name. Choose:
+
+
+
+
+ Maximum number of archive files that should be kept.
+
+
+
+
+ Indicates whether to compress archive files into the zip archive format.
+
+
+
+
+ Gets or set a value indicating whether a managed file stream is forced, instead of used the native implementation.
+
+
+
+
+ Cleanup invalid values in a filename, e.g. slashes in a filename. If set to true, this can impact the performance of massive writes. If set to false, nothing Gets written when the filename is wrong.
+
+
+
+
+ Name of the file to write to.
+
+
+
+
+ Value specifying the date format to use when archiving files.
+
+
+
+
+ Indicates whether to archive old log file on startup.
+
+
+
+
+ Indicates whether to Create directories if they Do not exist.
+
+
+
+
+ Indicates whether to enable log file(s) to be deleted.
+
+
+
+
+ File attributes (Windows only).
+
+
+
+
+ Indicates whether to delete old log file on startup.
+
+
+
+
+ Indicates whether to replace file contents on each write instead of appending log message at the end.
+
+
+
+
+ Indicates whether concurrent writes to the log file by multiple processes on the same host.
+
+
+
+
+ Delay in milliseconds to wait before attempting to write to the file again.
+
+
+
+
+ Maximum number of log filenames that should be stored as existing.
+
+
+
+
+ Indicates whether concurrent writes to the log file by multiple processes on different network hosts.
+
+
+
+
+ Number of files to be kept open. Setting this to a higher value may improve performance in a situation where a single File target is writing to many files (such as splitting by level or by logger).
+
+
+
+
+ Maximum number of seconds that files are kept open. If this number is negative the files are not automatically closed after a period of inactivity.
+
+
+
+
+ Log file buffer size in bytes.
+
+
+
+
+ Indicates whether to automatically flush the file buffers after each log message.
+
+
+
+
+ Number of times the write is appended on the file before NLog discards the log message.
+
+
+
+
+ Indicates whether to keep log file open instead of opening and closing it on each logging event.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Condition expression. Log events who meet this condition will be forwarded to the wrapped target.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Windows Domain name to change context to.
+
+
+
+
+ Required impersonation level.
+
+
+
+
+ Type of the logon provider.
+
+
+
+
+ Logon Type.
+
+
+
+
+ User account password.
+
+
+
+
+ Indicates whether to revert to the credentials of the process instead of impersonating another user.
+
+
+
+
+ Username to change context to.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Endpoint address.
+
+
+
+
+ Name of the endpoint configuration in WCF configuration file.
+
+
+
+
+ Indicates whether to use a WCF service contract that is one way (fire and forGet) or two way (request-reply)
+
+
+
+
+ Client ID.
+
+
+
+
+ Indicates whether to include per-event properties in the payload sent to the server.
+
+
+
+
+ Indicates whether to use binary message encoding.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Layout that should be use to calculate the value for the parameter.
+
+
+
+
+ Name of the parameter.
+
+
+
+
+ Type of the parameter.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Text to be rendered.
+
+
+
+
+ Header.
+
+
+
+
+ Footer.
+
+
+
+
+ Indicates whether to send message as HTML instead of plain text.
+
+
+
+
+ Encoding to be used for sending e-mail.
+
+
+
+
+ Indicates whether to add new lines between log entries.
+
+
+
+
+ CC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com).
+
+
+
+
+ Recipients' email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com).
+
+
+
+
+ BCC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com).
+
+
+
+
+ Mail message body (repeated for each log message send in one mail).
+
+
+
+
+ Mail subject.
+
+
+
+
+ Sender's email address (e.g. joe@domain.com).
+
+
+
+
+ Indicates whether NewLine characters in the body should be replaced with tags.
+
+
+
+
+ Priority used for sending mails.
+
+
+
+
+ Indicates the SMTP client timeout.
+
+
+
+
+ SMTP Server to be used for sending.
+
+
+
+
+ SMTP Authentication mode.
+
+
+
+
+ Username used to connect to SMTP server (used when SmtpAuthentication is set to "basic").
+
+
+
+
+ Password used to authenticate against SMTP server (used when SmtpAuthentication is set to "basic").
+
+
+
+
+ Indicates whether SSL (secure sockets layer) should be used when communicating with SMTP server.
+
+
+
+
+ Port number that SMTP Server is listening on.
+
+
+
+
+ Indicates whether the default Settings from System.Net.MailSettings should be used.
+
+
+
+
+ Folder where applications save mail messages to be processed by the local SMTP server.
+
+
+
+
+ Specifies how outgoing email messages will be handled.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+ Encoding to be used when writing text to the queue.
+
+
+
+
+ Indicates whether to use the XML format when serializing message. This will also disable creating queues.
+
+
+
+
+ Indicates whether to check if a queue exists before writing to it.
+
+
+
+
+ Indicates whether to Create the queue if it Doesn't exists.
+
+
+
+
+ Label to associate with each message.
+
+
+
+
+ Name of the queue to write to.
+
+
+
+
+ Indicates whether to use recoverable messages (with guaranteed delivery).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Class name.
+
+
+
+
+ Method name. The method must be public and static. Use the AssemblyQualifiedName , https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspx e.g.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+ Encoding to be used.
+
+
+
+
+ Maximum message size in bytes.
+
+
+
+
+ Indicates whether to append newline at the end of log message.
+
+
+
+
+ Action that should be taken if the will be more connections than .
+
+
+
+
+ Action that should be taken if the message is larger than maxMessageSize.
+
+
+
+
+ Network address.
+
+
+
+
+ Size of the connection cache (number of connections which are kept alive).
+
+
+
+
+ Indicates whether to keep connection open whenever possible.
+
+
+
+
+ Maximum current connections. 0 = no maximum.
+
+
+
+
+ Maximum queue size.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Encoding to be used.
+
+
+
+
+ Instance of that is used to format log messages.
+
+
+
+
+ Maximum message size in bytes.
+
+
+
+
+ Indicates whether to append newline at the end of log message.
+
+
+
+
+ Action that should be taken if the will be more connections than .
+
+
+
+
+ Action that should be taken if the message is larger than maxMessageSize.
+
+
+
+
+ Indicates whether to keep connection open whenever possible.
+
+
+
+
+ Size of the connection cache (number of connections which are kept alive).
+
+
+
+
+ Maximum current connections. 0 = no maximum.
+
+
+
+
+ Network address.
+
+
+
+
+ Maximum queue size.
+
+
+
+
+ Indicates whether to include source info (file name and line number) in the information sent over the network.
+
+
+
+
+ NDC item separator.
+
+
+
+
+ Indicates whether to include stack contents.
+
+
+
+
+ Indicates whether to include call site (class and method name) in the information sent over the network.
+
+
+
+
+ AppInfo field. By default it's the friendly name of the current AppDomain.
+
+
+
+
+ Indicates whether to include NLog-specific extensions to log4j schema.
+
+
+
+
+ Indicates whether to include dictionary contents.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+ Indicates whether to perform layout calculation.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Indicates whether performance counter should be automatically Created.
+
+
+
+
+ Name of the performance counter category.
+
+
+
+
+ Counter help text.
+
+
+
+
+ Name of the performance counter.
+
+
+
+
+ Performance counter type.
+
+
+
+
+ The value by which to increment the counter.
+
+
+
+
+ Performance counter instance name.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Default filter to be applied when no specific rule matches.
+
+
+
+
+
+
+
+
+
+
+
+
+ Condition to be tested.
+
+
+
+
+ Resulting filter to be applied when the condition matches.
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Number of times to repeat each log message.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Number of retries that should be attempted on the wrapped target in case of a failure.
+
+
+
+
+ Time to wait between retries in milliseconds.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Should we include the BOM (Byte-order-mark) for UTF? Influences the property. This will only work for UTF-8.
+
+
+
+
+ Encoding.
+
+
+
+
+ Web service method name. Only used with Soap.
+
+
+
+
+ Web service namespace. Only used with Soap.
+
+
+
+
+ Protocol to be used when calling web service.
+
+
+
+
+ Web service URL.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Footer layout.
+
+
+
+
+ Header layout.
+
+
+
+
+ Body layout (can be repeated multiple times).
+
+
+
+
+ Custom column delimiter value (valid when ColumnDelimiter is set to 'Custom').
+
+
+
+
+ Column delimiter.
+
+
+
+
+ Quote Character.
+
+
+
+
+ Quoting mode.
+
+
+
+
+ Indicates whether CVS should include header.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Layout of the column.
+
+
+
+
+ Name of the column.
+
+
+
+
+
+
+
+
+
+
+
+
+ Option to suppress the extra spaces in the output json
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Determines wether or not this attribute will be Json encoded.
+
+
+
+
+ Layout that will be rendered as the attribute's value.
+
+
+
+
+ Name of the attribute.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Footer layout.
+
+
+
+
+ Header layout.
+
+
+
+
+ Body layout (can be repeated multiple times).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Layout text.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Action to be taken when filter matches.
+
+
+
+
+ Condition expression.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Action to be taken when filter matches.
+
+
+
+
+ Indicates whether to ignore case when comparing strings.
+
+
+
+
+ Layout to be used to filter log messages.
+
+
+
+
+ Substring to be matched.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Action to be taken when filter matches.
+
+
+
+
+ String to compare the layout to.
+
+
+
+
+ Indicates whether to ignore case when comparing strings.
+
+
+
+
+ Layout to be used to filter log messages.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Action to be taken when filter matches.
+
+
+
+
+ Indicates whether to ignore case when comparing strings.
+
+
+
+
+ Layout to be used to filter log messages.
+
+
+
+
+ Substring to be matched.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Action to be taken when filter matches.
+
+
+
+
+ String to compare the layout to.
+
+
+
+
+ Indicates whether to ignore case when comparing strings.
+
+
+
+
+ Layout to be used to filter log messages.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FFXIVClassic Map Server/PacketProcessor.cs b/Map Server/PacketProcessor.cs
similarity index 98%
rename from FFXIVClassic Map Server/PacketProcessor.cs
rename to Map Server/PacketProcessor.cs
index 5f99d859..5741a675 100644
--- a/FFXIVClassic Map Server/PacketProcessor.cs
+++ b/Map Server/PacketProcessor.cs
@@ -1,394 +1,394 @@
-/*
-===========================================================================
-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 .
-===========================================================================
-*/
-
-using FFXIVClassic.Common;
-
-using System;
-using FFXIVClassic_Map_Server.dataobjects;
-using FFXIVClassic_Map_Server.packets.receive;
-using FFXIVClassic_Map_Server.packets.send;
-using FFXIVClassic_Map_Server.packets.send.login;
-using FFXIVClassic_Map_Server.packets.send.actor;
-using FFXIVClassic_Map_Server.packets.send.supportdesk;
-using FFXIVClassic_Map_Server.packets.receive.social;
-using FFXIVClassic_Map_Server.packets.send.social;
-using FFXIVClassic_Map_Server.packets.receive.supportdesk;
-using FFXIVClassic_Map_Server.packets.receive.recruitment;
-using FFXIVClassic_Map_Server.packets.send.recruitment;
-using FFXIVClassic_Map_Server.packets.receive.events;
-using FFXIVClassic_Map_Server.lua;
-using FFXIVClassic_Map_Server.Actors;
-using FFXIVClassic_Map_Server.packets.WorldPackets.Send;
-using FFXIVClassic_Map_Server.packets.WorldPackets.Receive;
-using FFXIVClassic_Map_Server.actors.director;
-
-namespace FFXIVClassic_Map_Server
-{
- class PacketProcessor
- {
- Server mServer;
-
- public PacketProcessor(Server server)
- {
- mServer = server;
- }
-
- public void ProcessPacket(ZoneConnection client, SubPacket subpacket)
- {
- Session session = mServer.GetSession(subpacket.header.sourceId);
-
- if (session == null && subpacket.gameMessage.opcode != 0x1000)
- return;
-
- //Normal Game Opcode
- switch (subpacket.gameMessage.opcode)
- {
- //World Server - Error
- case 0x100A:
- ErrorPacket worldError = new ErrorPacket(subpacket.data);
- switch (worldError.errorCode)
- {
- case 0x01:
- session.GetActor().SendGameMessage(Server.GetWorldManager().GetActor(), 60005, 0x20);
- break;
- }
- break;
- //World Server - Session Begin
- case 0x1000:
- subpacket.DebugPrintSubPacket();
-
- SessionBeginPacket beginSessionPacket = new SessionBeginPacket(subpacket.data);
-
- session = mServer.AddSession(subpacket.header.sourceId);
-
- if (!beginSessionPacket.isLogin)
- Server.GetWorldManager().DoZoneIn(session.GetActor(), false, session.GetActor().destinationSpawnType);
-
- Program.Log.Info("{0} has been added to the session list.", session.GetActor().customDisplayName);
-
- client.FlushQueuedSendPackets();
- break;
- //World Server - Session End
- case 0x1001:
- SessionEndPacket endSessionPacket = new SessionEndPacket(subpacket.data);
-
- if (endSessionPacket.destinationZoneId == 0)
- session.GetActor().CleanupAndSave();
- else
- session.GetActor().CleanupAndSave(endSessionPacket.destinationZoneId, endSessionPacket.destinationSpawnType, endSessionPacket.destinationX, endSessionPacket.destinationY, endSessionPacket.destinationZ, endSessionPacket.destinationRot);
-
- Server.GetServer().RemoveSession(session.id);
- Program.Log.Info("{0} has been removed from the session list.", session.GetActor().customDisplayName);
-
- session.QueuePacket(SessionEndConfirmPacket.BuildPacket(session, endSessionPacket.destinationZoneId));
- client.FlushQueuedSendPackets();
- break;
- //World Server - Party Synch
- case 0x1020:
- PartySyncPacket partySyncPacket = new PartySyncPacket(subpacket.data);
- Server.GetWorldManager().PartyMemberListRecieved(partySyncPacket);
- break;
- //World Server - Linkshell Creation Result
- case 0x1025:
- LinkshellResultPacket lsResult = new LinkshellResultPacket(subpacket.data);
- LuaEngine.GetInstance().OnSignal("ls_result", lsResult.resultCode);
- break;
- //Ping
- case 0x0001:
- //subpacket.DebugPrintSubPacket();
- PingPacket pingPacket = new PingPacket(subpacket.data);
- session.QueuePacket(PongPacket.BuildPacket(session.id, pingPacket.time));
- session.Ping();
- break;
- //Unknown
- case 0x0002:
-
- subpacket.DebugPrintSubPacket();
- session.QueuePacket(_0x2Packet.BuildPacket(session.id));
- client.FlushQueuedSendPackets();
-
- break;
- //Chat Received
- case 0x0003:
- ChatMessagePacket chatMessage = new ChatMessagePacket(subpacket.data);
- //Program.Log.Info("Got type-{5} message: {0} @ {1}, {2}, {3}, Rot: {4}", chatMessage.message, chatMessage.posX, chatMessage.posY, chatMessage.posZ, chatMessage.posRot, chatMessage.logType);
-
- if (chatMessage.message.StartsWith("!"))
- {
- if (Server.GetCommandProcessor().DoCommand(chatMessage.message, session))
- return; ;
- }
-
- if (chatMessage.logType == SendMessagePacket.MESSAGE_TYPE_SAY || chatMessage.logType == SendMessagePacket.MESSAGE_TYPE_SHOUT)
- session.GetActor().BroadcastPacket(SendMessagePacket.BuildPacket(session.id, chatMessage.logType, session.GetActor().customDisplayName, chatMessage.message), false);
-
- break;
- //Langauge Code (Client safe to send packets to now)
- case 0x0006:
- LangaugeCodePacket langCode = new LangaugeCodePacket(subpacket.data);
- LuaEngine.GetInstance().CallLuaFunction(session.GetActor(), session.GetActor(), "onBeginLogin", true);
- Server.GetWorldManager().DoZoneIn(session.GetActor(), true, 0x1);
- LuaEngine.GetInstance().CallLuaFunction(session.GetActor(), session.GetActor(), "onLogin", true);
- session.languageCode = langCode.languageCode;
- break;
- //Unknown - Happens a lot at login, then once every time player zones
- case 0x0007:
- //subpacket.DebugPrintSubPacket();
- ZoneInCompletePacket zoneInCompletePacket = new ZoneInCompletePacket(subpacket.data);
- break;
- //Update Position
- case 0x00CA:
- //Update Position
- UpdatePlayerPositionPacket posUpdate = new UpdatePlayerPositionPacket(subpacket.data);
- session.UpdatePlayerActorPosition(posUpdate.x, posUpdate.y, posUpdate.z, posUpdate.rot, posUpdate.moveState);
- session.GetActor().SendInstanceUpdate();
-
- if (session.GetActor().IsInZoneChange())
- session.GetActor().SetZoneChanging(false);
-
- break;
- //Set Target
- case 0x00CD:
- //subpacket.DebugPrintSubPacket();
-
- SetTargetPacket setTarget = new SetTargetPacket(subpacket.data);
- session.GetActor().currentTarget = setTarget.actorID;
- session.GetActor().isAutoAttackEnabled = setTarget.attackTarget != 0xE0000000;
- session.GetActor().BroadcastPacket(SetActorTargetAnimatedPacket.BuildPacket(session.id, setTarget.actorID), true);
- break;
- //Lock Target
- case 0x00CC:
- LockTargetPacket lockTarget = new LockTargetPacket(subpacket.data);
- session.GetActor().currentLockedTarget = lockTarget.actorID;
- break;
- //Start Event
- case 0x012D:
- subpacket.DebugPrintSubPacket();
- EventStartPacket eventStart = new EventStartPacket(subpacket.data);
-
- /*
- if (eventStart.error != null)
- {
- player.errorMessage += eventStart.error;
-
- if (eventStart.errorIndex == eventStart.errorNum - 1)
- Program.Log.Error("\n"+player.errorMessage);
-
-
- break;
- }
- */
-
- Actor ownerActor = Server.GetStaticActors(eventStart.scriptOwnerActorID);
-
- if (ownerActor == null)
- {
- //Is it your retainer?
- if (session.GetActor().currentSpawnedRetainer != null && session.GetActor().currentSpawnedRetainer.actorId == eventStart.scriptOwnerActorID)
- ownerActor = session.GetActor().currentSpawnedRetainer;
- //Is it a instance actor?
- if (ownerActor == null)
- ownerActor = session.GetActor().zone.FindActorInArea(eventStart.scriptOwnerActorID);
- if (ownerActor == null)
- {
- //Is it a Director?
- Director director = session.GetActor().GetDirector(eventStart.scriptOwnerActorID);
- if (director != null)
- ownerActor = director;
- else
- {
- Program.Log.Debug("\n===Event START===\nCould not find actor 0x{0:X} for event started by caller: 0x{1:X}\nEvent Starter: {2}\nParams: {3}", eventStart.actorID, eventStart.scriptOwnerActorID, eventStart.triggerName, LuaUtils.DumpParams(eventStart.luaParams));
- break;
- }
- }
- }
-
- session.GetActor().StartEvent(ownerActor, eventStart);
-
- Program.Log.Debug("\n===Event START===\nSource Actor: 0x{0:X}\nCaller Actor: 0x{1:X}\nVal1: 0x{2:X}\nVal2: 0x{3:X}\nEvent Starter: {4}\nParams: {5}", eventStart.actorID, eventStart.scriptOwnerActorID, eventStart.val1, eventStart.val2, eventStart.triggerName, LuaUtils.DumpParams(eventStart.luaParams));
- break;
- //Unknown, happens at npc spawn and cutscene play????
- case 0x00CE:
- subpacket.DebugPrintSubPacket();
- break;
- //Countdown requested
- case 0x00CF:
- CountdownRequestPacket countdownPacket = new CountdownRequestPacket(subpacket.data);
- session.GetActor().BroadcastCountdown(countdownPacket.countdownLength, countdownPacket.syncTime);
- break;
- //Event Result
- case 0x012E:
- subpacket.DebugPrintSubPacket();
- EventUpdatePacket eventUpdate = new EventUpdatePacket(subpacket.data);
- Program.Log.Debug("\n===Event UPDATE===\nSource Actor: 0x{0:X}\nCaller Actor: 0x{1:X}\nVal1: 0x{2:X}\nVal2: 0x{3:X}\nStep: 0x{4:X}\nParams: {5}", eventUpdate.actorID, eventUpdate.scriptOwnerActorID, eventUpdate.val1, eventUpdate.val2, eventUpdate.step, LuaUtils.DumpParams(eventUpdate.luaParams));
- /*
- //Is it a static actor? If not look in the player's instance
- Actor updateOwnerActor = Server.GetStaticActors(session.GetActor().currentEventOwner);
- if (updateOwnerActor == null)
- {
- updateOwnerActor = Server.GetWorldManager().GetActorInWorld(session.GetActor().currentEventOwner);
-
- if (session.GetActor().currentDirector != null && session.GetActor().currentEventOwner == session.GetActor().currentDirector.actorId)
- updateOwnerActor = session.GetActor().currentDirector;
-
- if (updateOwnerActor == null)
- break;
- }
- */
- session.GetActor().UpdateEvent(eventUpdate);
-
- //LuaEngine.DoActorOnEventUpdated(session.GetActor(), updateOwnerActor, eventUpdate);
-
- break;
- case 0x012F:
- subpacket.DebugPrintSubPacket();
- ParameterDataRequestPacket paramRequest = new ParameterDataRequestPacket(subpacket.data);
- if (paramRequest.paramName.Equals("charaWork/exp"))
- session.GetActor().SendCharaExpInfo();
- break;
- //Item Package Request
- case 0x0131:
- UpdateItemPackagePacket packageRequest = new UpdateItemPackagePacket(subpacket.data);
- if (Server.GetWorldManager().GetActorInWorld(packageRequest.actorID) != null)
- {
- ((Character)Server.GetWorldManager().GetActorInWorld(packageRequest.actorID)).SendItemPackage(session.GetActor(), packageRequest.packageId);
- break;
- }
- if (session.GetActor().GetSpawnedRetainer() != null && session.GetActor().GetSpawnedRetainer().actorId == packageRequest.actorID)
- session.GetActor().GetSpawnedRetainer().SendItemPackage(session.GetActor(), packageRequest.packageId);
- break;
- //Group Created Confirm
- case 0x0133:
- GroupCreatedPacket groupCreated = new GroupCreatedPacket(subpacket.data);
- Server.GetWorldManager().SendGroupInit(session, groupCreated.groupId);
- break;
- //Achievement Progress Request
- case 0x0135:
- AchievementProgressRequestPacket progressRequest = new AchievementProgressRequestPacket(subpacket.data);
- session.QueuePacket(Database.GetAchievementProgress(session.GetActor(), progressRequest.achievementId));
- break;
- /* RECRUITMENT */
- //Start Recruiting
- case 0x01C3:
- StartRecruitingRequestPacket recruitRequestPacket = new StartRecruitingRequestPacket(subpacket.data);
- session.QueuePacket(StartRecruitingResponse.BuildPacket(session.id, true));
- break;
- //End Recruiting
- case 0x01C4:
- session.QueuePacket(EndRecruitmentPacket.BuildPacket(session.id));
- break;
- //Party Window Opened, Request State
- case 0x01C5:
- session.QueuePacket(RecruiterStatePacket.BuildPacket(session.id, false, false, 0));
- break;
- //Search Recruiting
- case 0x01C7:
- RecruitmentSearchRequestPacket recruitSearchPacket = new RecruitmentSearchRequestPacket(subpacket.data);
- break;
- //Get Recruitment Details
- case 0x01C8:
- RecruitmentDetailsRequestPacket currentRecruitDetailsPacket = new RecruitmentDetailsRequestPacket(subpacket.data);
- RecruitmentDetails details = new RecruitmentDetails();
- details.recruiterName = "Localhost Character";
- details.purposeId = 2;
- details.locationId = 1;
- details.subTaskId = 1;
- details.comment = "This is a test details packet sent by the server. No implementation has been Created yet...";
- details.num[0] = 1;
- session.QueuePacket(CurrentRecruitmentDetailsPacket.BuildPacket(session.id, details));
- break;
- //Accepted Recruiting
- case 0x01C6:
- subpacket.DebugPrintSubPacket();
- break;
- /* SOCIAL STUFF */
- case 0x01C9:
- AddRemoveSocialPacket addBlackList = new AddRemoveSocialPacket(subpacket.data);
- session.QueuePacket(BlacklistAddedPacket.BuildPacket(session.id, true, addBlackList.name));
- break;
- case 0x01CA:
- AddRemoveSocialPacket RemoveBlackList = new AddRemoveSocialPacket(subpacket.data);
- session.QueuePacket(BlacklistRemovedPacket.BuildPacket(session.id, true, RemoveBlackList.name));
- break;
- case 0x01CB:
- int offset1 = 0;
- session.QueuePacket(SendBlacklistPacket.BuildPacket(session.id, new String[] { "Test" }, ref offset1));
- break;
- case 0x01CC:
- AddRemoveSocialPacket addFriendList = new AddRemoveSocialPacket(subpacket.data);
- session.QueuePacket(FriendlistAddedPacket.BuildPacket(session.id, true, (uint)addFriendList.name.GetHashCode(), true, addFriendList.name));
- break;
- case 0x01CD:
- AddRemoveSocialPacket RemoveFriendList = new AddRemoveSocialPacket(subpacket.data);
- session.QueuePacket(FriendlistRemovedPacket.BuildPacket(session.id, true, RemoveFriendList.name));
- break;
- case 0x01CE:
- int offset2 = 0;
- session.QueuePacket(SendFriendlistPacket.BuildPacket(session.id, new Tuple[] { new Tuple(01, "Test2") }, ref offset2));
- break;
- case 0x01CF:
- session.QueuePacket(FriendStatusPacket.BuildPacket(session.id, null));
- break;
- /* SUPPORT DESK STUFF */
- //Request for FAQ/Info List
- case 0x01D0:
- FaqListRequestPacket faqRequest = new FaqListRequestPacket(subpacket.data);
- session.QueuePacket(FaqListResponsePacket.BuildPacket(session.id, new string[] { "Testing FAQ1", "Coded style!" }));
- break;
- //Request for body of a faq/info selection
- case 0x01D1:
- FaqBodyRequestPacket faqBodyRequest = new FaqBodyRequestPacket(subpacket.data);
- session.QueuePacket(FaqBodyResponsePacket.BuildPacket(session.id, "HERE IS A GIANT BODY. Nothing else to say!"));
- break;
- //Request issue list
- case 0x01D2:
- GMTicketIssuesRequestPacket issuesRequest = new GMTicketIssuesRequestPacket(subpacket.data);
- session.QueuePacket(IssueListResponsePacket.BuildPacket(session.id, new string[] { "Test1", "Test2", "Test3", "Test4", "Test5" }));
- break;
- //Request if GM ticket exists
- case 0x01D3:
- session.QueuePacket(StartGMTicketPacket.BuildPacket(session.id, false));
- break;
- //Request for GM response message
- case 0x01D4:
- session.QueuePacket(GMTicketPacket.BuildPacket(session.id, "This is a GM Ticket Title", "This is a GM Ticket Body."));
- break;
- //GM Ticket Sent
- case 0x01D5:
- GMSupportTicketPacket gmTicket = new GMSupportTicketPacket(subpacket.data);
- Program.Log.Info("Got GM Ticket: \n" + gmTicket.ticketTitle + "\n" + gmTicket.ticketBody);
- session.QueuePacket(GMTicketSentResponsePacket.BuildPacket(session.id, true));
- break;
- //Request to end ticket
- case 0x01D6:
- session.QueuePacket(EndGMTicketPacket.BuildPacket(session.id));
- break;
- default:
- Program.Log.Debug("Unknown command 0x{0:X} received.", subpacket.gameMessage.opcode);
- subpacket.DebugPrintSubPacket();
- break;
- }
-
- }
-
- }
-}
-
+/*
+===========================================================================
+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 .
+===========================================================================
+*/
+
+using Meteor.Common;
+
+using System;
+using FFXIVClassic_Map_Server.dataobjects;
+using FFXIVClassic_Map_Server.packets.receive;
+using FFXIVClassic_Map_Server.packets.send;
+using FFXIVClassic_Map_Server.packets.send.login;
+using FFXIVClassic_Map_Server.packets.send.actor;
+using FFXIVClassic_Map_Server.packets.send.supportdesk;
+using FFXIVClassic_Map_Server.packets.receive.social;
+using FFXIVClassic_Map_Server.packets.send.social;
+using FFXIVClassic_Map_Server.packets.receive.supportdesk;
+using FFXIVClassic_Map_Server.packets.receive.recruitment;
+using FFXIVClassic_Map_Server.packets.send.recruitment;
+using FFXIVClassic_Map_Server.packets.receive.events;
+using FFXIVClassic_Map_Server.lua;
+using FFXIVClassic_Map_Server.Actors;
+using FFXIVClassic_Map_Server.packets.WorldPackets.Send;
+using FFXIVClassic_Map_Server.packets.WorldPackets.Receive;
+using FFXIVClassic_Map_Server.actors.director;
+
+namespace FFXIVClassic_Map_Server
+{
+ class PacketProcessor
+ {
+ Server mServer;
+
+ public PacketProcessor(Server server)
+ {
+ mServer = server;
+ }
+
+ public void ProcessPacket(ZoneConnection client, SubPacket subpacket)
+ {
+ Session session = mServer.GetSession(subpacket.header.sourceId);
+
+ if (session == null && subpacket.gameMessage.opcode != 0x1000)
+ return;
+
+ //Normal Game Opcode
+ switch (subpacket.gameMessage.opcode)
+ {
+ //World Server - Error
+ case 0x100A:
+ ErrorPacket worldError = new ErrorPacket(subpacket.data);
+ switch (worldError.errorCode)
+ {
+ case 0x01:
+ session.GetActor().SendGameMessage(Server.GetWorldManager().GetActor(), 60005, 0x20);
+ break;
+ }
+ break;
+ //World Server - Session Begin
+ case 0x1000:
+ subpacket.DebugPrintSubPacket();
+
+ SessionBeginPacket beginSessionPacket = new SessionBeginPacket(subpacket.data);
+
+ session = mServer.AddSession(subpacket.header.sourceId);
+
+ if (!beginSessionPacket.isLogin)
+ Server.GetWorldManager().DoZoneIn(session.GetActor(), false, session.GetActor().destinationSpawnType);
+
+ Program.Log.Info("{0} has been added to the session list.", session.GetActor().customDisplayName);
+
+ client.FlushQueuedSendPackets();
+ break;
+ //World Server - Session End
+ case 0x1001:
+ SessionEndPacket endSessionPacket = new SessionEndPacket(subpacket.data);
+
+ if (endSessionPacket.destinationZoneId == 0)
+ session.GetActor().CleanupAndSave();
+ else
+ session.GetActor().CleanupAndSave(endSessionPacket.destinationZoneId, endSessionPacket.destinationSpawnType, endSessionPacket.destinationX, endSessionPacket.destinationY, endSessionPacket.destinationZ, endSessionPacket.destinationRot);
+
+ Server.GetServer().RemoveSession(session.id);
+ Program.Log.Info("{0} has been removed from the session list.", session.GetActor().customDisplayName);
+
+ session.QueuePacket(SessionEndConfirmPacket.BuildPacket(session, endSessionPacket.destinationZoneId));
+ client.FlushQueuedSendPackets();
+ break;
+ //World Server - Party Synch
+ case 0x1020:
+ PartySyncPacket partySyncPacket = new PartySyncPacket(subpacket.data);
+ Server.GetWorldManager().PartyMemberListRecieved(partySyncPacket);
+ break;
+ //World Server - Linkshell Creation Result
+ case 0x1025:
+ LinkshellResultPacket lsResult = new LinkshellResultPacket(subpacket.data);
+ LuaEngine.GetInstance().OnSignal("ls_result", lsResult.resultCode);
+ break;
+ //Ping
+ case 0x0001:
+ //subpacket.DebugPrintSubPacket();
+ PingPacket pingPacket = new PingPacket(subpacket.data);
+ session.QueuePacket(PongPacket.BuildPacket(session.id, pingPacket.time));
+ session.Ping();
+ break;
+ //Unknown
+ case 0x0002:
+
+ subpacket.DebugPrintSubPacket();
+ session.QueuePacket(_0x2Packet.BuildPacket(session.id));
+ client.FlushQueuedSendPackets();
+
+ break;
+ //Chat Received
+ case 0x0003:
+ ChatMessagePacket chatMessage = new ChatMessagePacket(subpacket.data);
+ //Program.Log.Info("Got type-{5} message: {0} @ {1}, {2}, {3}, Rot: {4}", chatMessage.message, chatMessage.posX, chatMessage.posY, chatMessage.posZ, chatMessage.posRot, chatMessage.logType);
+
+ if (chatMessage.message.StartsWith("!"))
+ {
+ if (Server.GetCommandProcessor().DoCommand(chatMessage.message, session))
+ return; ;
+ }
+
+ if (chatMessage.logType == SendMessagePacket.MESSAGE_TYPE_SAY || chatMessage.logType == SendMessagePacket.MESSAGE_TYPE_SHOUT)
+ session.GetActor().BroadcastPacket(SendMessagePacket.BuildPacket(session.id, chatMessage.logType, session.GetActor().customDisplayName, chatMessage.message), false);
+
+ break;
+ //Langauge Code (Client safe to send packets to now)
+ case 0x0006:
+ LangaugeCodePacket langCode = new LangaugeCodePacket(subpacket.data);
+ LuaEngine.GetInstance().CallLuaFunction(session.GetActor(), session.GetActor(), "onBeginLogin", true);
+ Server.GetWorldManager().DoZoneIn(session.GetActor(), true, 0x1);
+ LuaEngine.GetInstance().CallLuaFunction(session.GetActor(), session.GetActor(), "onLogin", true);
+ session.languageCode = langCode.languageCode;
+ break;
+ //Unknown - Happens a lot at login, then once every time player zones
+ case 0x0007:
+ //subpacket.DebugPrintSubPacket();
+ ZoneInCompletePacket zoneInCompletePacket = new ZoneInCompletePacket(subpacket.data);
+ break;
+ //Update Position
+ case 0x00CA:
+ //Update Position
+ UpdatePlayerPositionPacket posUpdate = new UpdatePlayerPositionPacket(subpacket.data);
+ session.UpdatePlayerActorPosition(posUpdate.x, posUpdate.y, posUpdate.z, posUpdate.rot, posUpdate.moveState);
+ session.GetActor().SendInstanceUpdate();
+
+ if (session.GetActor().IsInZoneChange())
+ session.GetActor().SetZoneChanging(false);
+
+ break;
+ //Set Target
+ case 0x00CD:
+ //subpacket.DebugPrintSubPacket();
+
+ SetTargetPacket setTarget = new SetTargetPacket(subpacket.data);
+ session.GetActor().currentTarget = setTarget.actorID;
+ session.GetActor().isAutoAttackEnabled = setTarget.attackTarget != 0xE0000000;
+ session.GetActor().BroadcastPacket(SetActorTargetAnimatedPacket.BuildPacket(session.id, setTarget.actorID), true);
+ break;
+ //Lock Target
+ case 0x00CC:
+ LockTargetPacket lockTarget = new LockTargetPacket(subpacket.data);
+ session.GetActor().currentLockedTarget = lockTarget.actorID;
+ break;
+ //Start Event
+ case 0x012D:
+ subpacket.DebugPrintSubPacket();
+ EventStartPacket eventStart = new EventStartPacket(subpacket.data);
+
+ /*
+ if (eventStart.error != null)
+ {
+ player.errorMessage += eventStart.error;
+
+ if (eventStart.errorIndex == eventStart.errorNum - 1)
+ Program.Log.Error("\n"+player.errorMessage);
+
+
+ break;
+ }
+ */
+
+ Actor ownerActor = Server.GetStaticActors(eventStart.scriptOwnerActorID);
+
+ if (ownerActor == null)
+ {
+ //Is it your retainer?
+ if (session.GetActor().currentSpawnedRetainer != null && session.GetActor().currentSpawnedRetainer.actorId == eventStart.scriptOwnerActorID)
+ ownerActor = session.GetActor().currentSpawnedRetainer;
+ //Is it a instance actor?
+ if (ownerActor == null)
+ ownerActor = session.GetActor().zone.FindActorInArea(eventStart.scriptOwnerActorID);
+ if (ownerActor == null)
+ {
+ //Is it a Director?
+ Director director = session.GetActor().GetDirector(eventStart.scriptOwnerActorID);
+ if (director != null)
+ ownerActor = director;
+ else
+ {
+ Program.Log.Debug("\n===Event START===\nCould not find actor 0x{0:X} for event started by caller: 0x{1:X}\nEvent Starter: {2}\nParams: {3}", eventStart.actorID, eventStart.scriptOwnerActorID, eventStart.triggerName, LuaUtils.DumpParams(eventStart.luaParams));
+ break;
+ }
+ }
+ }
+
+ session.GetActor().StartEvent(ownerActor, eventStart);
+
+ Program.Log.Debug("\n===Event START===\nSource Actor: 0x{0:X}\nCaller Actor: 0x{1:X}\nVal1: 0x{2:X}\nVal2: 0x{3:X}\nEvent Starter: {4}\nParams: {5}", eventStart.actorID, eventStart.scriptOwnerActorID, eventStart.val1, eventStart.val2, eventStart.triggerName, LuaUtils.DumpParams(eventStart.luaParams));
+ break;
+ //Unknown, happens at npc spawn and cutscene play????
+ case 0x00CE:
+ subpacket.DebugPrintSubPacket();
+ break;
+ //Countdown requested
+ case 0x00CF:
+ CountdownRequestPacket countdownPacket = new CountdownRequestPacket(subpacket.data);
+ session.GetActor().BroadcastCountdown(countdownPacket.countdownLength, countdownPacket.syncTime);
+ break;
+ //Event Result
+ case 0x012E:
+ subpacket.DebugPrintSubPacket();
+ EventUpdatePacket eventUpdate = new EventUpdatePacket(subpacket.data);
+ Program.Log.Debug("\n===Event UPDATE===\nSource Actor: 0x{0:X}\nCaller Actor: 0x{1:X}\nVal1: 0x{2:X}\nVal2: 0x{3:X}\nStep: 0x{4:X}\nParams: {5}", eventUpdate.actorID, eventUpdate.scriptOwnerActorID, eventUpdate.val1, eventUpdate.val2, eventUpdate.step, LuaUtils.DumpParams(eventUpdate.luaParams));
+ /*
+ //Is it a static actor? If not look in the player's instance
+ Actor updateOwnerActor = Server.GetStaticActors(session.GetActor().currentEventOwner);
+ if (updateOwnerActor == null)
+ {
+ updateOwnerActor = Server.GetWorldManager().GetActorInWorld(session.GetActor().currentEventOwner);
+
+ if (session.GetActor().currentDirector != null && session.GetActor().currentEventOwner == session.GetActor().currentDirector.actorId)
+ updateOwnerActor = session.GetActor().currentDirector;
+
+ if (updateOwnerActor == null)
+ break;
+ }
+ */
+ session.GetActor().UpdateEvent(eventUpdate);
+
+ //LuaEngine.DoActorOnEventUpdated(session.GetActor(), updateOwnerActor, eventUpdate);
+
+ break;
+ case 0x012F:
+ subpacket.DebugPrintSubPacket();
+ ParameterDataRequestPacket paramRequest = new ParameterDataRequestPacket(subpacket.data);
+ if (paramRequest.paramName.Equals("charaWork/exp"))
+ session.GetActor().SendCharaExpInfo();
+ break;
+ //Item Package Request
+ case 0x0131:
+ UpdateItemPackagePacket packageRequest = new UpdateItemPackagePacket(subpacket.data);
+ if (Server.GetWorldManager().GetActorInWorld(packageRequest.actorID) != null)
+ {
+ ((Character)Server.GetWorldManager().GetActorInWorld(packageRequest.actorID)).SendItemPackage(session.GetActor(), packageRequest.packageId);
+ break;
+ }
+ if (session.GetActor().GetSpawnedRetainer() != null && session.GetActor().GetSpawnedRetainer().actorId == packageRequest.actorID)
+ session.GetActor().GetSpawnedRetainer().SendItemPackage(session.GetActor(), packageRequest.packageId);
+ break;
+ //Group Created Confirm
+ case 0x0133:
+ GroupCreatedPacket groupCreated = new GroupCreatedPacket(subpacket.data);
+ Server.GetWorldManager().SendGroupInit(session, groupCreated.groupId);
+ break;
+ //Achievement Progress Request
+ case 0x0135:
+ AchievementProgressRequestPacket progressRequest = new AchievementProgressRequestPacket(subpacket.data);
+ session.QueuePacket(Database.GetAchievementProgress(session.GetActor(), progressRequest.achievementId));
+ break;
+ /* RECRUITMENT */
+ //Start Recruiting
+ case 0x01C3:
+ StartRecruitingRequestPacket recruitRequestPacket = new StartRecruitingRequestPacket(subpacket.data);
+ session.QueuePacket(StartRecruitingResponse.BuildPacket(session.id, true));
+ break;
+ //End Recruiting
+ case 0x01C4:
+ session.QueuePacket(EndRecruitmentPacket.BuildPacket(session.id));
+ break;
+ //Party Window Opened, Request State
+ case 0x01C5:
+ session.QueuePacket(RecruiterStatePacket.BuildPacket(session.id, false, false, 0));
+ break;
+ //Search Recruiting
+ case 0x01C7:
+ RecruitmentSearchRequestPacket recruitSearchPacket = new RecruitmentSearchRequestPacket(subpacket.data);
+ break;
+ //Get Recruitment Details
+ case 0x01C8:
+ RecruitmentDetailsRequestPacket currentRecruitDetailsPacket = new RecruitmentDetailsRequestPacket(subpacket.data);
+ RecruitmentDetails details = new RecruitmentDetails();
+ details.recruiterName = "Localhost Character";
+ details.purposeId = 2;
+ details.locationId = 1;
+ details.subTaskId = 1;
+ details.comment = "This is a test details packet sent by the server. No implementation has been Created yet...";
+ details.num[0] = 1;
+ session.QueuePacket(CurrentRecruitmentDetailsPacket.BuildPacket(session.id, details));
+ break;
+ //Accepted Recruiting
+ case 0x01C6:
+ subpacket.DebugPrintSubPacket();
+ break;
+ /* SOCIAL STUFF */
+ case 0x01C9:
+ AddRemoveSocialPacket addBlackList = new AddRemoveSocialPacket(subpacket.data);
+ session.QueuePacket(BlacklistAddedPacket.BuildPacket(session.id, true, addBlackList.name));
+ break;
+ case 0x01CA:
+ AddRemoveSocialPacket RemoveBlackList = new AddRemoveSocialPacket(subpacket.data);
+ session.QueuePacket(BlacklistRemovedPacket.BuildPacket(session.id, true, RemoveBlackList.name));
+ break;
+ case 0x01CB:
+ int offset1 = 0;
+ session.QueuePacket(SendBlacklistPacket.BuildPacket(session.id, new String[] { "Test" }, ref offset1));
+ break;
+ case 0x01CC:
+ AddRemoveSocialPacket addFriendList = new AddRemoveSocialPacket(subpacket.data);
+ session.QueuePacket(FriendlistAddedPacket.BuildPacket(session.id, true, (uint)addFriendList.name.GetHashCode(), true, addFriendList.name));
+ break;
+ case 0x01CD:
+ AddRemoveSocialPacket RemoveFriendList = new AddRemoveSocialPacket(subpacket.data);
+ session.QueuePacket(FriendlistRemovedPacket.BuildPacket(session.id, true, RemoveFriendList.name));
+ break;
+ case 0x01CE:
+ int offset2 = 0;
+ session.QueuePacket(SendFriendlistPacket.BuildPacket(session.id, new Tuple[] { new Tuple(01, "Test2") }, ref offset2));
+ break;
+ case 0x01CF:
+ session.QueuePacket(FriendStatusPacket.BuildPacket(session.id, null));
+ break;
+ /* SUPPORT DESK STUFF */
+ //Request for FAQ/Info List
+ case 0x01D0:
+ FaqListRequestPacket faqRequest = new FaqListRequestPacket(subpacket.data);
+ session.QueuePacket(FaqListResponsePacket.BuildPacket(session.id, new string[] { "Testing FAQ1", "Coded style!" }));
+ break;
+ //Request for body of a faq/info selection
+ case 0x01D1:
+ FaqBodyRequestPacket faqBodyRequest = new FaqBodyRequestPacket(subpacket.data);
+ session.QueuePacket(FaqBodyResponsePacket.BuildPacket(session.id, "HERE IS A GIANT BODY. Nothing else to say!"));
+ break;
+ //Request issue list
+ case 0x01D2:
+ GMTicketIssuesRequestPacket issuesRequest = new GMTicketIssuesRequestPacket(subpacket.data);
+ session.QueuePacket(IssueListResponsePacket.BuildPacket(session.id, new string[] { "Test1", "Test2", "Test3", "Test4", "Test5" }));
+ break;
+ //Request if GM ticket exists
+ case 0x01D3:
+ session.QueuePacket(StartGMTicketPacket.BuildPacket(session.id, false));
+ break;
+ //Request for GM response message
+ case 0x01D4:
+ session.QueuePacket(GMTicketPacket.BuildPacket(session.id, "This is a GM Ticket Title", "This is a GM Ticket Body."));
+ break;
+ //GM Ticket Sent
+ case 0x01D5:
+ GMSupportTicketPacket gmTicket = new GMSupportTicketPacket(subpacket.data);
+ Program.Log.Info("Got GM Ticket: \n" + gmTicket.ticketTitle + "\n" + gmTicket.ticketBody);
+ session.QueuePacket(GMTicketSentResponsePacket.BuildPacket(session.id, true));
+ break;
+ //Request to end ticket
+ case 0x01D6:
+ session.QueuePacket(EndGMTicketPacket.BuildPacket(session.id));
+ break;
+ default:
+ Program.Log.Debug("Unknown command 0x{0:X} received.", subpacket.gameMessage.opcode);
+ subpacket.DebugPrintSubPacket();
+ break;
+ }
+
+ }
+
+ }
+}
+
diff --git a/FFXIVClassic Map Server/Program.cs b/Map Server/Program.cs
similarity index 100%
rename from FFXIVClassic Map Server/Program.cs
rename to Map Server/Program.cs
diff --git a/FFXIVClassic Map Server/Properties/AssemblyInfo.cs b/Map Server/Properties/AssemblyInfo.cs
similarity index 100%
rename from FFXIVClassic Map Server/Properties/AssemblyInfo.cs
rename to Map Server/Properties/AssemblyInfo.cs
diff --git a/FFXIVClassic Map Server/Properties/Resources.Designer.cs b/Map Server/Properties/Resources.Designer.cs
similarity index 95%
rename from FFXIVClassic Map Server/Properties/Resources.Designer.cs
rename to Map Server/Properties/Resources.Designer.cs
index 11a22948..e3920e57 100644
--- a/FFXIVClassic Map Server/Properties/Resources.Designer.cs
+++ b/Map Server/Properties/Resources.Designer.cs
@@ -1,270 +1,270 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated by a tool.
-// Runtime Version:4.0.30319.42000
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-namespace FFXIVClassic_Map_Server.Properties {
- using System;
-
-
- ///
- /// A strongly-typed resource class, for looking up localized strings, etc.
- ///
- // This class was auto-generated by the StronglyTypedResourceBuilder
- // class via a tool like ResGen or Visual Studio.
- // To add or remove a member, edit your .ResX file then rerun ResGen
- // with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- public class Resources {
-
- private static global::System.Resources.ResourceManager resourceMan;
-
- private static global::System.Globalization.CultureInfo resourceCulture;
-
- [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal Resources() {
- }
-
- ///
- /// Returns the cached ResourceManager instance used by this class.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- public static global::System.Resources.ResourceManager ResourceManager {
- get {
- if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("FFXIVClassic_Map_Server.Properties.Resources", typeof(Resources).Assembly);
- resourceMan = temp;
- }
- return resourceMan;
- }
- }
-
- ///
- /// Overrides the current thread's CurrentUICulture property for all
- /// resource lookups using this strongly typed resource class.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- public static global::System.Globalization.CultureInfo Culture {
- get {
- return resourceCulture;
- }
- set {
- resourceCulture = value;
- }
- }
-
- ///
- /// Looks up a localized string similar to Adds the specified currency to the current player's inventory
- ///
- ///*Syntax: givecurrency <quantity>
- /// givecurrency <type> <quantity>
- ///<type> is the specific type of currency desired, defaults to gil if no type specified.
- ///
- public static string CPgivecurrency {
- get {
- return ResourceManager.GetString("CPgivecurrency", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Adds the specified items to the current player's inventory
- ///
- ///*Syntax: giveitem <item id>
- /// giveitem <item id> <quantity>
- /// giveitem <item id> <quantity> <type>
- ///<item id> is the item's specific id as defined in the server database
- ///<type> is the type as defined in the server database (defaults to standard item if not specified).
- ///
- public static string CPgiveitem {
- get {
- return ResourceManager.GetString("CPgiveitem", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Adds the specified key item to the current player's inventory
- ///
- ///*Syntax: givekeyitem <item id>
- ///<item id> is the key item's specific id as defined in the server database.
- ///
- public static string CPgivekeyitem {
- get {
- return ResourceManager.GetString("CPgivekeyitem", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Use !help(command) for details
- ///
- ///Available commands:
- ///Standard: mypos, music, warp
- ///Server Administration: givecurrency, giveitem, givekeyitem, removecurrency, removekeyitem, reloaditems, reloadzones
- ///Test: test weather.
- ///
- public static string CPhelp {
- get {
- return ResourceManager.GetString("CPhelp", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Changes the currently playing background music
- ///
- ///*Syntax: music <music id>
- ///<music id> is the music's specific id as defined in the client.
- ///
- public static string CPmusic {
- get {
- return ResourceManager.GetString("CPmusic", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Prints out your current location
- ///
- ///*Note: The X/Y/Z coordinates Do not correspond to the coordinates listed in the in-game map, they are based on the underlying game data.
- ///
- public static string CPmypos {
- get {
- return ResourceManager.GetString("CPmypos", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to *Syntax: property <value 1> <value 2> <value 3>.
- ///
- public static string CPproperty {
- get {
- return ResourceManager.GetString("CPproperty", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to *Syntax: property2 <value 1> <value 2> <value 3>.
- ///
- public static string CPproperty2 {
- get {
- return ResourceManager.GetString("CPproperty2", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Reloads the current item data from the database.
- ///
- public static string CPreloaditems {
- get {
- return ResourceManager.GetString("CPreloaditems", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Reloads the current zone data from the database.
- ///
- public static string CPreloadzones {
- get {
- return ResourceManager.GetString("CPreloadzones", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Removes the specified currency from the current player's inventory
- ///
- ///*Syntax: removecurrency <quantity>
- /// removecurrency <type> <quantity>
- ///<type> is the specific type of currency desired, defaults to gil if no type specified.
- ///
- public static string CPremovecurrency {
- get {
- return ResourceManager.GetString("CPremovecurrency", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Removes the specified items to the current player's inventory
- ///
- ///*Syntax: removeitem <itemid>
- /// removeitem <itemid> <quantity>
- ///<item id> is the item's specific id as defined in the server database.
- ///
- public static string CPremoveitem {
- get {
- return ResourceManager.GetString("CPremoveitem", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Removes the specified key item to the current player's inventory
- ///
- ///*Syntax: removekeyitem <itemid>
- ///<item id> is the key item's specific id as defined in the server database.
- ///
- public static string CPremovekeyitem {
- get {
- return ResourceManager.GetString("CPremovekeyitem", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Server sends a special packet to the client
- ///
- ///*Syntax: sendpacket <path to packet>
- ///<Path to packet> is the path to the packet, starting in <map server install location>\packet.
- ///
- public static string CPsendpacket {
- get {
- return ResourceManager.GetString("CPsendpacket", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Overrides the currently displayed character equipment in a specific slot
- ///
- ///*Note: Similar to Glamours in FFXIV:ARR, the overridden graphics are purely cosmetic, they Do not affect the underlying stats of whatever is equipped on that slot
- ///
- ///*Syntax: sendpacket <slot> <wid> <eid> <vid> <cid>
- ///<w/e/v/c id> are as defined in the client game data.
- ///
- public static string CPsetgraphic {
- get {
- return ResourceManager.GetString("CPsetgraphic", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Changes the current weather
- ///
- ///*Syntax: test weather <weather id>
- ///<weather id> is the weather's specific id as defined in the client.
- ///
- public static string CPtestweather {
- get {
- return ResourceManager.GetString("CPtestweather", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Teleports the player to the specified location
- ///
- ///*Note: You can teleport relative to your current position by putting a @ in front of a value, cannot be combined with a zone id or instance name
- ///
- ///*Syntax: warp <location list>
- /// warp <X coordinate> <Y coordinate> <Z coordinate>
- /// warp <zone id> <X coordinate> <Y coordinate> <Z coordinate>
- /// warp <zone id> <instance> <X coordinate> <Y coordinate> <Z coordinate>
- ///<location list> is a pre-defined list of locations from the server database
- ///<zone id> is the [rest of string was truncated]";.
- ///
- public static string CPwarp {
- get {
- return ResourceManager.GetString("CPwarp", resourceCulture);
- }
- }
- }
-}
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace Meteor.Map.Properties {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ public class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Meteor.Map.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Adds the specified currency to the current player's inventory
+ ///
+ ///*Syntax: givecurrency <quantity>
+ /// givecurrency <type> <quantity>
+ ///<type> is the specific type of currency desired, defaults to gil if no type specified.
+ ///
+ public static string CPgivecurrency {
+ get {
+ return ResourceManager.GetString("CPgivecurrency", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Adds the specified items to the current player's inventory
+ ///
+ ///*Syntax: giveitem <item id>
+ /// giveitem <item id> <quantity>
+ /// giveitem <item id> <quantity> <type>
+ ///<item id> is the item's specific id as defined in the server database
+ ///<type> is the type as defined in the server database (defaults to standard item if not specified).
+ ///
+ public static string CPgiveitem {
+ get {
+ return ResourceManager.GetString("CPgiveitem", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Adds the specified key item to the current player's inventory
+ ///
+ ///*Syntax: givekeyitem <item id>
+ ///<item id> is the key item's specific id as defined in the server database.
+ ///
+ public static string CPgivekeyitem {
+ get {
+ return ResourceManager.GetString("CPgivekeyitem", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Use !help(command) for details
+ ///
+ ///Available commands:
+ ///Standard: mypos, music, warp
+ ///Server Administration: givecurrency, giveitem, givekeyitem, removecurrency, removekeyitem, reloaditems, reloadzones
+ ///Test: test weather.
+ ///
+ public static string CPhelp {
+ get {
+ return ResourceManager.GetString("CPhelp", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Changes the currently playing background music
+ ///
+ ///*Syntax: music <music id>
+ ///<music id> is the music's specific id as defined in the client.
+ ///
+ public static string CPmusic {
+ get {
+ return ResourceManager.GetString("CPmusic", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Prints out your current location
+ ///
+ ///*Note: The X/Y/Z coordinates Do not correspond to the coordinates listed in the in-game map, they are based on the underlying game data.
+ ///
+ public static string CPmypos {
+ get {
+ return ResourceManager.GetString("CPmypos", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to *Syntax: property <value 1> <value 2> <value 3>.
+ ///
+ public static string CPproperty {
+ get {
+ return ResourceManager.GetString("CPproperty", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to *Syntax: property2 <value 1> <value 2> <value 3>.
+ ///
+ public static string CPproperty2 {
+ get {
+ return ResourceManager.GetString("CPproperty2", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Reloads the current item data from the database.
+ ///
+ public static string CPreloaditems {
+ get {
+ return ResourceManager.GetString("CPreloaditems", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Reloads the current zone data from the database.
+ ///
+ public static string CPreloadzones {
+ get {
+ return ResourceManager.GetString("CPreloadzones", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Removes the specified currency from the current player's inventory
+ ///
+ ///*Syntax: removecurrency <quantity>
+ /// removecurrency <type> <quantity>
+ ///<type> is the specific type of currency desired, defaults to gil if no type specified.
+ ///
+ public static string CPremovecurrency {
+ get {
+ return ResourceManager.GetString("CPremovecurrency", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Removes the specified items to the current player's inventory
+ ///
+ ///*Syntax: removeitem <itemid>
+ /// removeitem <itemid> <quantity>
+ ///<item id> is the item's specific id as defined in the server database.
+ ///
+ public static string CPremoveitem {
+ get {
+ return ResourceManager.GetString("CPremoveitem", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Removes the specified key item to the current player's inventory
+ ///
+ ///*Syntax: removekeyitem <itemid>
+ ///<item id> is the key item's specific id as defined in the server database.
+ ///
+ public static string CPremovekeyitem {
+ get {
+ return ResourceManager.GetString("CPremovekeyitem", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Server sends a special packet to the client
+ ///
+ ///*Syntax: sendpacket <path to packet>
+ ///<Path to packet> is the path to the packet, starting in <map server install location>\packet.
+ ///
+ public static string CPsendpacket {
+ get {
+ return ResourceManager.GetString("CPsendpacket", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Overrides the currently displayed character equipment in a specific slot
+ ///
+ ///*Note: Similar to Glamours in FFXIV:ARR, the overridden graphics are purely cosmetic, they Do not affect the underlying stats of whatever is equipped on that slot
+ ///
+ ///*Syntax: sendpacket <slot> <wid> <eid> <vid> <cid>
+ ///<w/e/v/c id> are as defined in the client game data.
+ ///
+ public static string CPsetgraphic {
+ get {
+ return ResourceManager.GetString("CPsetgraphic", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Changes the current weather
+ ///
+ ///*Syntax: test weather <weather id>
+ ///<weather id> is the weather's specific id as defined in the client.
+ ///
+ public static string CPtestweather {
+ get {
+ return ResourceManager.GetString("CPtestweather", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Teleports the player to the specified location
+ ///
+ ///*Note: You can teleport relative to your current position by putting a @ in front of a value, cannot be combined with a zone id or instance name
+ ///
+ ///*Syntax: warp <location list>
+ /// warp <X coordinate> <Y coordinate> <Z coordinate>
+ /// warp <zone id> <X coordinate> <Y coordinate> <Z coordinate>
+ /// warp <zone id> <instance> <X coordinate> <Y coordinate> <Z coordinate>
+ ///<location list> is a pre-defined list of locations from the server database
+ ///<zone id> is the [rest of string was truncated]";.
+ ///
+ public static string CPwarp {
+ get {
+ return ResourceManager.GetString("CPwarp", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/FFXIVClassic Map Server/Properties/Resources.resx b/Map Server/Properties/Resources.resx
similarity index 97%
rename from FFXIVClassic Map Server/Properties/Resources.resx
rename to Map Server/Properties/Resources.resx
index a5538877..bcd909e9 100644
--- a/FFXIVClassic Map Server/Properties/Resources.resx
+++ b/Map Server/Properties/Resources.resx
@@ -1,226 +1,226 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- Adds the specified currency to the current player's inventory
-
-*Syntax: givecurrency <quantity>
- givecurrency <type> <quantity>
-<type> is the specific type of currency desired, defaults to gil if no type specified
-
-
- Adds the specified items to the current player's inventory
-
-*Syntax: giveitem <item id>
- giveitem <item id> <quantity>
- giveitem <item id> <quantity> <type>
-<item id> is the item's specific id as defined in the server database
-<type> is the type as defined in the server database (defaults to standard item if not specified)
-
-
- Adds the specified key item to the current player's inventory
-
-*Syntax: givekeyitem <item id>
-<item id> is the key item's specific id as defined in the server database
-
-
- Use !help(command) for details
-
-Available commands:
-Standard: mypos, music, warp
-Server Administration: givecurrency, giveitem, givekeyitem, removecurrency, removekeyitem, reloaditems, reloadzones
-Test: test weather
-
-
- Changes the currently playing background music
-
-*Syntax: music <music id>
-<music id> is the music's specific id as defined in the client
-
-
- Prints out your current location
-
-*Note: The X/Y/Z coordinates Do not correspond to the coordinates listed in the in-game map, they are based on the underlying game data
-
-
- *Syntax: property <value 1> <value 2> <value 3>
-
-
- *Syntax: property2 <value 1> <value 2> <value 3>
-
-
- Reloads the current item data from the database
-
-
- Reloads the current zone data from the database
-
-
- Removes the specified currency from the current player's inventory
-
-*Syntax: removecurrency <quantity>
- removecurrency <type> <quantity>
-<type> is the specific type of currency desired, defaults to gil if no type specified
-
-
- Removes the specified items to the current player's inventory
-
-*Syntax: removeitem <itemid>
- removeitem <itemid> <quantity>
-<item id> is the item's specific id as defined in the server database
-
-
- Removes the specified key item to the current player's inventory
-
-*Syntax: removekeyitem <itemid>
-<item id> is the key item's specific id as defined in the server database
-
-
- Server sends a special packet to the client
-
-*Syntax: sendpacket <path to packet>
-<Path to packet> is the path to the packet, starting in <map server install location>\packet
-
-
- Overrides the currently displayed character equipment in a specific slot
-
-*Note: Similar to Glamours in FFXIV:ARR, the overridden graphics are purely cosmetic, they Do not affect the underlying stats of whatever is equipped on that slot
-
-*Syntax: sendpacket <slot> <wid> <eid> <vid> <cid>
-<w/e/v/c id> are as defined in the client game data
-
-
- Changes the current weather
-
-*Syntax: test weather <weather id>
-<weather id> is the weather's specific id as defined in the client
-
-
- Teleports the player to the specified location
-
-*Note: You can teleport relative to your current position by putting a @ in front of a value, cannot be combined with a zone id or instance name
-
-*Syntax: warp <location list>
- warp <X coordinate> <Y coordinate> <Z coordinate>
- warp <zone id> <X coordinate> <Y coordinate> <Z coordinate>
- warp <zone id> <instance> <X coordinate> <Y coordinate> <Z coordinate>
-<location list> is a pre-defined list of locations from the server database
-<zone id> is the zone's id as defined in the server database
-<instance> is an instanced copy of the desired zone that's only visible to the current player
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Adds the specified currency to the current player's inventory
+
+*Syntax: givecurrency <quantity>
+ givecurrency <type> <quantity>
+<type> is the specific type of currency desired, defaults to gil if no type specified
+
+
+ Adds the specified items to the current player's inventory
+
+*Syntax: giveitem <item id>
+ giveitem <item id> <quantity>
+ giveitem <item id> <quantity> <type>
+<item id> is the item's specific id as defined in the server database
+<type> is the type as defined in the server database (defaults to standard item if not specified)
+
+
+ Adds the specified key item to the current player's inventory
+
+*Syntax: givekeyitem <item id>
+<item id> is the key item's specific id as defined in the server database
+
+
+ Use !help(command) for details
+
+Available commands:
+Standard: mypos, music, warp
+Server Administration: givecurrency, giveitem, givekeyitem, removecurrency, removekeyitem, reloaditems, reloadzones
+Test: test weather
+
+
+ Changes the currently playing background music
+
+*Syntax: music <music id>
+<music id> is the music's specific id as defined in the client
+
+
+ Prints out your current location
+
+*Note: The X/Y/Z coordinates Do not correspond to the coordinates listed in the in-game map, they are based on the underlying game data
+
+
+ *Syntax: property <value 1> <value 2> <value 3>
+
+
+ *Syntax: property2 <value 1> <value 2> <value 3>
+
+
+ Reloads the current item data from the database
+
+
+ Reloads the current zone data from the database
+
+
+ Removes the specified currency from the current player's inventory
+
+*Syntax: removecurrency <quantity>
+ removecurrency <type> <quantity>
+<type> is the specific type of currency desired, defaults to gil if no type specified
+
+
+ Removes the specified items to the current player's inventory
+
+*Syntax: removeitem <itemid>
+ removeitem <itemid> <quantity>
+<item id> is the item's specific id as defined in the server database
+
+
+ Removes the specified key item to the current player's inventory
+
+*Syntax: removekeyitem <itemid>
+<item id> is the key item's specific id as defined in the server database
+
+
+ Server sends a special packet to the client
+
+*Syntax: sendpacket <path to packet>
+<Path to packet> is the path to the packet, starting in <map server install location>\packet
+
+
+ Overrides the currently displayed character equipment in a specific slot
+
+*Note: Similar to Glamours in FFXIV:ARR, the overridden graphics are purely cosmetic, they Do not affect the underlying stats of whatever is equipped on that slot
+
+*Syntax: sendpacket <slot> <wid> <eid> <vid> <cid>
+<w/e/v/c id> are as defined in the client game data
+
+
+ Changes the current weather
+
+*Syntax: test weather <weather id>
+<weather id> is the weather's specific id as defined in the client
+
+
+ Teleports the player to the specified location
+
+*Note: You can teleport relative to your current position by putting a @ in front of a value, cannot be combined with a zone id or instance name
+
+*Syntax: warp <location list>
+ warp <X coordinate> <Y coordinate> <Z coordinate>
+ warp <zone id> <X coordinate> <Y coordinate> <Z coordinate>
+ warp <zone id> <instance> <X coordinate> <Y coordinate> <Z coordinate>
+<location list> is a pre-defined list of locations from the server database
+<zone id> is the zone's id as defined in the server database
+<instance> is an instanced copy of the desired zone that's only visible to the current player
+
\ No newline at end of file
diff --git a/FFXIVClassic Map Server/Server.cs b/Map Server/Server.cs
similarity index 99%
rename from FFXIVClassic Map Server/Server.cs
rename to Map Server/Server.cs
index ba0460bc..5f1e6927 100644
--- a/FFXIVClassic Map Server/Server.cs
+++ b/Map Server/Server.cs
@@ -25,7 +25,7 @@ using System.Net;
using System.Net.Sockets;
using FFXIVClassic_Map_Server.dataobjects;
-using FFXIVClassic.Common;
+using Meteor.Common;
using FFXIVClassic_Map_Server.Actors;
namespace FFXIVClassic_Map_Server
diff --git a/FFXIVClassic Map Server/SharpNav.dll b/Map Server/SharpNav.dll
similarity index 100%
rename from FFXIVClassic Map Server/SharpNav.dll
rename to Map Server/SharpNav.dll
diff --git a/FFXIVClassic Map Server/WorldManager.cs b/Map Server/WorldManager.cs
similarity index 99%
rename from FFXIVClassic Map Server/WorldManager.cs
rename to Map Server/WorldManager.cs
index 9650e41d..b819d5d7 100644
--- a/FFXIVClassic Map Server/WorldManager.cs
+++ b/Map Server/WorldManager.cs
@@ -19,7 +19,7 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-using FFXIVClassic.Common;
+using Meteor.Common;
using FFXIVClassic_Map_Server.actors.area;
using FFXIVClassic_Map_Server.actors.chara.npc;
using FFXIVClassic_Map_Server.Actors;
diff --git a/FFXIVClassic Map Server/actors/Actor.cs b/Map Server/actors/Actor.cs
similarity index 97%
rename from FFXIVClassic Map Server/actors/Actor.cs
rename to Map Server/actors/Actor.cs
index ada34752..9595482f 100644
--- a/FFXIVClassic Map Server/actors/Actor.cs
+++ b/Map Server/actors/Actor.cs
@@ -1,787 +1,787 @@
-/*
-===========================================================================
-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 .
-===========================================================================
-*/
-
-
-using FFXIVClassic_Map_Server.actors;
-using FFXIVClassic_Map_Server.lua;
-using FFXIVClassic_Map_Server.packets.send.actor;
-using FFXIVClassic_Map_Server.packets.send.actor.events;
-using FFXIVClassic.Common;
-using System;
-using System.Collections.Generic;
-using FFXIVClassic_Map_Server.actors.area;
-using System.Reflection;
-using System.ComponentModel;
-using FFXIVClassic_Map_Server.actors.chara;
-
-namespace FFXIVClassic_Map_Server.Actors
-{
- [Flags]
- enum ActorUpdateFlags
- {
- None = 0x00,
- Position = 0x01,
- HpTpMp = 0x02,
- State = 0x04,
- SubState = 0x08,
- Combat = 0x0F,
- Name = 0x10,
- Appearance = 0x20,
- Speed = 0x40,
- Work = 0x80,
- Stats = 0x100,
- Status = 0x200,
- StatusTime = 0x400,
- Hotbar = 0x800,
-
- AllNpc = 0xDF,
- AllPlayer = 0x13F
- }
-
- class Actor
- {
- public static uint INVALID_ACTORID = 0xC0000000;
- public uint actorId;
- public string actorName;
-
- public uint displayNameId = 0xFFFFFFFF;
- public string customDisplayName;
-
- public ushort currentMainState = SetActorStatePacket.MAIN_STATE_PASSIVE;
-
- public SubState currentSubState = new SubState();
-
- public float positionX, positionY, positionZ, rotation;
- public float oldPositionX, oldPositionY, oldPositionZ, oldRotation;
- public ushort moveState, oldMoveState;
- public float[] moveSpeeds = new float[4];
-
- public uint zoneId, zoneId2;
- public string privateArea;
- public uint privateAreaType;
- public Area zone = null;
- public Area zone2 = null;
- public bool isZoning = false;
-
- public bool spawnedFirstTime = false;
-
- public string classPath;
- public string className;
- public List classParams;
-
- public List positionUpdates;
- protected DateTime lastUpdateScript;
- protected DateTime lastUpdate;
- public Actor target;
-
- public bool isAtSpawn = true;
-
- public ActorUpdateFlags updateFlags;
-
- public EventList eventConditions;
-
- public Actor(uint actorId)
- {
- this.actorId = actorId;
- }
-
- public Actor(uint actorId, string actorName, string className, List classParams)
- {
- this.actorId = actorId;
- this.actorName = actorName;
- this.className = className;
- this.classParams = classParams;
-
- this.moveSpeeds[0] = SetActorSpeedPacket.DEFAULT_STOP;
- this.moveSpeeds[1] = SetActorSpeedPacket.DEFAULT_WALK;
- this.moveSpeeds[2] = SetActorSpeedPacket.DEFAULT_RUN;
- this.moveSpeeds[3] = SetActorSpeedPacket.DEFAULT_ACTIVE;
- positionUpdates = new List();
- }
-
- public void SetPushCircleRange(string triggerName, float size)
- {
- if (eventConditions == null || eventConditions.pushWithCircleEventConditions == null)
- return;
-
- foreach (EventList.PushCircleEventCondition condition in eventConditions.pushWithCircleEventConditions)
- {
- if (condition.conditionName.Equals(triggerName))
- {
- condition.radius = size;
- break;
- }
- }
- }
-
- public virtual void ResetMoveSpeeds()
- {
- this.moveSpeeds[0] = SetActorSpeedPacket.DEFAULT_STOP;
- this.moveSpeeds[1] = SetActorSpeedPacket.DEFAULT_WALK;
- this.moveSpeeds[2] = SetActorSpeedPacket.DEFAULT_RUN;
- this.moveSpeeds[3] = SetActorSpeedPacket.DEFAULT_ACTIVE;
-
- this.moveState = this.oldMoveState;
- this.updateFlags |= ActorUpdateFlags.Speed;
- }
-
- public SubPacket CreateAddActorPacket(byte val)
- {
- return AddActorPacket.BuildPacket(actorId, val);
- }
-
- public SubPacket CreateNamePacket()
- {
- return SetActorNamePacket.BuildPacket(actorId, customDisplayName != null ? 0 : displayNameId, displayNameId == 0xFFFFFFFF | displayNameId == 0x0 | customDisplayName != null ? customDisplayName : "");
- }
-
- public SubPacket CreateSpeedPacket()
- {
- return SetActorSpeedPacket.BuildPacket(actorId, moveSpeeds[0], moveSpeeds[1], moveSpeeds[2], moveSpeeds[3]);
- }
-
- public SubPacket CreateSpawnPositonPacket(ushort spawnType)
- {
- return CreateSpawnPositonPacket(null, spawnType);
- }
-
- public SubPacket CreateSpawnPositonPacket(Player player, ushort spawnType)
- {
- //TODO: FIX THIS IF
- uint playerActorId = player == null ? 0 : player.actorId; //Get Rid
- SubPacket spawnPacket;
- if (!spawnedFirstTime && playerActorId == actorId)
- spawnPacket = SetActorPositionPacket.BuildPacket(actorId, 0, positionX, positionY, positionZ, rotation, 0x1, false);
- else if (playerActorId == actorId)
- spawnPacket = SetActorPositionPacket.BuildPacket(actorId, 0xFFFFFFFF, positionX, positionY, positionZ, rotation, spawnType, true);
- else
- {
- if (this is Player)
- spawnPacket = SetActorPositionPacket.BuildPacket(actorId, 0, positionX, positionY, positionZ, rotation, spawnType, false);
- else
- spawnPacket = SetActorPositionPacket.BuildPacket(actorId, actorId, positionX, positionY, positionZ, rotation, spawnType, false);
- }
-
- //return SetActorPositionPacket.BuildPacket(actorId, -211.895477f, 190.000000f, 29.651011f, 2.674819f, SetActorPositionPacket.SPAWNTYPE_PLAYERWAKE);
- spawnedFirstTime = true;
-
- return spawnPacket;
- }
-
- public SubPacket CreateSpawnTeleportPacket(ushort spawnType)
- {
- SubPacket spawnPacket;
-
- spawnPacket = SetActorPositionPacket.BuildPacket(actorId, 0xFFFFFFFF, positionX, positionY, positionZ, rotation, spawnType, false);
-
- //return SetActorPositionPacket.BuildPacket(actorId, -211.895477f, 190.000000f, 29.651011f, 2.674819f, SetActorPositionPacket.SPAWNTYPE_PLAYERWAKE);
-
- //spawnPacket.DebugPrintSubPacket();
-
- return spawnPacket;
- }
-
- public SubPacket CreatePositionUpdatePacket()
- {
- return MoveActorToPositionPacket.BuildPacket(actorId, positionX, positionY, positionZ, rotation, moveState);
- }
-
- public SubPacket CreateStatePacket()
- {
- return SetActorStatePacket.BuildPacket(actorId, currentMainState, 0);
- }
-
- public List GetEventConditionPackets()
- {
- List subpackets = new List();
-
- //Return empty list
- if (eventConditions == null)
- return subpackets;
-
- if (eventConditions.talkEventConditions != null)
- {
- foreach (EventList.TalkEventCondition condition in eventConditions.talkEventConditions)
- subpackets.Add(SetTalkEventCondition.BuildPacket(actorId, condition));
- }
-
- if (eventConditions.noticeEventConditions != null)
- {
- foreach (EventList.NoticeEventCondition condition in eventConditions.noticeEventConditions)
- subpackets.Add(SetNoticeEventCondition.BuildPacket(actorId, condition));
- }
-
- if (eventConditions.emoteEventConditions != null)
- {
- foreach (EventList.EmoteEventCondition condition in eventConditions.emoteEventConditions)
- subpackets.Add(SetEmoteEventCondition.BuildPacket(actorId, condition));
- }
-
- if (eventConditions.pushWithCircleEventConditions != null)
- {
- foreach (EventList.PushCircleEventCondition condition in eventConditions.pushWithCircleEventConditions)
- subpackets.Add(SetPushEventConditionWithCircle.BuildPacket(actorId, condition));
- }
-
- if (eventConditions.pushWithFanEventConditions != null)
- {
- foreach (EventList.PushFanEventCondition condition in eventConditions.pushWithFanEventConditions)
- subpackets.Add(SetPushEventConditionWithFan.BuildPacket(actorId, condition));
- }
-
- if (eventConditions.pushWithBoxEventConditions != null)
- {
- foreach (EventList.PushBoxEventCondition condition in eventConditions.pushWithBoxEventConditions)
- subpackets.Add(SetPushEventConditionWithTriggerBox.BuildPacket(actorId, condition));
- }
-
- return subpackets;
- }
-
- public List GetSetEventStatusPackets()
- {
- List subpackets = new List();
-
- //Return empty list
- if (eventConditions == null)
- return subpackets;
-
- if (eventConditions.talkEventConditions != null)
- {
- foreach (EventList.TalkEventCondition condition in eventConditions.talkEventConditions)
- subpackets.Add(SetEventStatus.BuildPacket(actorId, true, 1, condition.conditionName));
- }
-
- if (eventConditions.noticeEventConditions != null)
- {
- foreach (EventList.NoticeEventCondition condition in eventConditions.noticeEventConditions)
- subpackets.Add(SetEventStatus.BuildPacket(actorId, true, 1, condition.conditionName));
- }
-
- if (eventConditions.emoteEventConditions != null)
- {
- foreach (EventList.EmoteEventCondition condition in eventConditions.emoteEventConditions)
- subpackets.Add(SetEventStatus.BuildPacket(actorId, true, 3, condition.conditionName));
- }
-
- if (eventConditions.pushWithCircleEventConditions != null)
- {
- foreach (EventList.PushCircleEventCondition condition in eventConditions.pushWithCircleEventConditions)
- subpackets.Add(SetEventStatus.BuildPacket(actorId, true, 2, condition.conditionName));
- }
-
- if (eventConditions.pushWithFanEventConditions != null)
- {
- foreach (EventList.PushFanEventCondition condition in eventConditions.pushWithFanEventConditions)
- subpackets.Add(SetEventStatus.BuildPacket(actorId, true, 2, condition.conditionName));
- }
-
- if (eventConditions.pushWithBoxEventConditions != null)
- {
- foreach (EventList.PushBoxEventCondition condition in eventConditions.pushWithBoxEventConditions)
- subpackets.Add(SetEventStatus.BuildPacket(actorId, true, 2, condition.conditionName));
- }
-
- return subpackets;
- }
-
- public SubPacket CreateIsZoneingPacket()
- {
- return SetActorIsZoningPacket.BuildPacket(actorId, false);
- }
-
- public virtual SubPacket CreateScriptBindPacket(Player player)
- {
- return ActorInstantiatePacket.BuildPacket(actorId, actorName, className, classParams);
- }
-
- public virtual SubPacket CreateScriptBindPacket()
- {
- return ActorInstantiatePacket.BuildPacket(actorId, actorName, className, classParams);
- }
-
- public virtual List GetSpawnPackets(Player player, ushort spawnType)
- {
- List subpackets = new List();
- subpackets.Add(CreateAddActorPacket(8));
- subpackets.AddRange(GetEventConditionPackets());
- subpackets.Add(CreateSpeedPacket());
- subpackets.Add(CreateSpawnPositonPacket(player, spawnType));
- subpackets.Add(CreateNamePacket());
- subpackets.Add(CreateStatePacket());
- subpackets.Add(CreateIsZoneingPacket());
- subpackets.Add(CreateScriptBindPacket(player));
- return subpackets;
- }
-
- public virtual List GetSpawnPackets()
- {
- return GetSpawnPackets(0x1);
- }
-
- public virtual List GetSpawnPackets(ushort spawnType)
- {
- List subpackets = new List();
- subpackets.Add(CreateAddActorPacket(8));
- subpackets.AddRange(GetEventConditionPackets());
- subpackets.Add(CreateSpeedPacket());
- subpackets.Add(CreateSpawnPositonPacket(null, spawnType));
- subpackets.Add(CreateNamePacket());
- subpackets.Add(CreateStatePacket());
- subpackets.Add(CreateIsZoneingPacket());
- subpackets.Add(CreateScriptBindPacket());
- return subpackets;
- }
-
- public virtual List GetInitPackets()
- {
- List packets = new List();
- SetActorPropetyPacket initProperties = new SetActorPropetyPacket("/_init");
- initProperties.AddByte(0xE14B0CA8, 1);
- initProperties.AddByte(0x2138FD71, 1);
- initProperties.AddByte(0xFBFBCFB1, 1);
- initProperties.AddTarget();
- packets.Add(initProperties.BuildPacket(actorId));
- return packets;
- }
-
- public override bool Equals(Object obj)
- {
- Actor actorObj = obj as Actor;
- if (actorObj == null)
- return false;
- else
- return actorId == actorObj.actorId;
- }
-
- public string GetName()
- {
- return actorName;
- }
-
- public string GetClassName()
- {
- return className;
- }
-
- public ushort GetState()
- {
- return currentMainState;
- }
-
- public List GetLuaParams()
- {
- return classParams;
- }
-
- //character's newMainState kind of messes with this
- public void ChangeState(ushort newState)
- {
- if (newState != currentMainState)
- {
- currentMainState = newState;
-
- updateFlags |= (ActorUpdateFlags.State | ActorUpdateFlags.Position);
- }
- }
-
- public SubState GetSubState()
- {
- return currentSubState;
- }
-
- public void SubstateModified()
- {
- updateFlags |= (ActorUpdateFlags.SubState);
- }
-
- public void ModifySpeed(float mod)
- {
- for (int i = 0; i < 4; i++)
- {
- moveSpeeds[i] *= mod;
- }
- updateFlags |= ActorUpdateFlags.Speed;
- }
-
- public void ChangeSpeed(int type, float value)
- {
- moveSpeeds[type] = value;
- updateFlags |= ActorUpdateFlags.Speed;
- }
-
- public void ChangeSpeed(float speedStop, float speedWalk, float speedRun, float speedActive)
- {
- moveSpeeds[0] = speedStop;
- moveSpeeds[1] = speedWalk;
- moveSpeeds[2] = speedRun;
- moveSpeeds[3] = speedActive;
- updateFlags |= ActorUpdateFlags.Speed;
- }
-
- public virtual void Update(DateTime tick)
- {
-
- }
-
- public virtual void PostUpdate(DateTime tick, List packets = null)
- {
- if (updateFlags != ActorUpdateFlags.None)
- {
- packets = packets ?? new List();
- if ((updateFlags & ActorUpdateFlags.Position) != 0)
- {
- if (positionUpdates != null && positionUpdates.Count > 0)
- {
- var pos = positionUpdates[0];
- if (pos != null)
- {
- oldPositionX = positionX;
- oldPositionY = positionY;
- oldPositionZ = positionZ;
- oldRotation = rotation;
-
- positionX = pos.X;
- positionY = pos.Y;
- positionZ = pos.Z;
-
- zone.UpdateActorPosition(this);
-
- //Program.Server.GetInstance().mLuaEngine.OnPath(actor, position, positionUpdates)
- }
- positionUpdates.Remove(pos);
-
- }
- packets.Add(CreatePositionUpdatePacket());
- }
-
- if ((updateFlags & ActorUpdateFlags.Speed) != 0)
- {
- packets.Add(SetActorSpeedPacket.BuildPacket(actorId, moveSpeeds[0], moveSpeeds[1], moveSpeeds[2], moveSpeeds[3]));
- }
-
- if ((updateFlags & ActorUpdateFlags.Name) != 0)
- {
- packets.Add(SetActorNamePacket.BuildPacket(actorId, displayNameId, customDisplayName));
- }
-
- if ((updateFlags & ActorUpdateFlags.State) != 0)
- {
- packets.Add(SetActorStatePacket.BuildPacket(actorId, currentMainState, 0x3B));
- }
-
- if ((updateFlags & ActorUpdateFlags.SubState) != 0)
- {
- packets.Add(SetActorSubStatePacket.BuildPacket(actorId, currentSubState));
- }
-
- updateFlags = ActorUpdateFlags.None;
- }
- zone.BroadcastPacketsAroundActor(this, packets);
- }
-
- public void GenerateActorName(int actorNumber)
- {
- //Format Class Name
- string className = this.className.Replace("Populace", "Ppl")
- .Replace("Monster", "Mon")
- .Replace("Crowd", "Crd")
- .Replace("MapObj", "Map")
- .Replace("Object", "Obj")
- .Replace("Retainer", "Rtn")
- .Replace("Standard", "Std");
- className = Char.ToLowerInvariant(className[0]) + className.Substring(1);
-
- //Format Zone Name
- string zoneName = zone.zoneName.Replace("Field", "Fld")
- .Replace("Dungeon", "Dgn")
- .Replace("Town", "Twn")
- .Replace("Battle", "Btl")
- .Replace("Test", "Tes")
- .Replace("Event", "Evt")
- .Replace("Ship", "Shp")
- .Replace("Office", "Ofc");
- if (zone is PrivateArea)
- {
- //Check if "normal"
- zoneName = zoneName.Remove(zoneName.Length - 1, 1) + "P";
- }
- zoneName = Char.ToLowerInvariant(zoneName[0]) + zoneName.Substring(1);
-
- try
- {
- className = className.Substring(0, 20 - zoneName.Length);
- }
- catch (ArgumentOutOfRangeException)
- { }
-
- //Convert actor number to base 63
- string classNumber = Utils.ToStringBase63(actorNumber);
-
- //Get stuff after @
- uint zoneId = zone.actorId;
- uint privLevel = 0;
- if (zone is PrivateArea)
- privLevel = ((PrivateArea)zone).GetPrivateAreaType();
-
- actorName = String.Format("{0}_{1}_{2}@{3:X3}{4:X2}", className, zoneName, classNumber, zoneId, privLevel);
- }
-
- public bool SetWorkValue(Player player, string name, string uiFunc, object value)
- {
- string[] split = name.Split('.');
- int arrayIndex = 0;
-
- if (!(split[0].Equals("work") || split[0].Equals("charaWork") || split[0].Equals("playerWork") || split[0].Equals("npcWork")))
- return false;
-
- Object parentObj = null;
- Object curObj = this;
- for (int i = 0; i < split.Length; i++)
- {
- //For arrays
- if (split[i].Contains("["))
- {
- if (split[i].LastIndexOf(']') - split[i].IndexOf('[') <= 0)
- return false;
-
- arrayIndex = Convert.ToInt32(split[i].Substring(split[i].IndexOf('[') + 1, split[i].LastIndexOf(']') - split[i].LastIndexOf('[') - 1));
- split[i] = split[i].Substring(0, split[i].IndexOf('['));
- }
-
- FieldInfo field = curObj.GetType().GetField(split[i]);
- if (field == null)
- return false;
-
- if (i == split.Length - 1)
- parentObj = curObj;
- curObj = field.GetValue(curObj);
- if (curObj == null)
- return false;
- }
-
- if (curObj == null)
- return false;
- else
- {
- //Array, we actually care whats inside
- if (curObj.GetType().IsArray)
- {
- if (((Array)curObj).Length <= arrayIndex)
- return false;
-
- if (value.GetType() == ((Array)curObj).GetType().GetElementType() || TypeDescriptor.GetConverter(value.GetType()).CanConvertTo(((Array)curObj).GetType().GetElementType()))
- {
- if (value.GetType() == ((Array)curObj).GetType().GetElementType())
- ((Array)curObj).SetValue(value, arrayIndex);
- else
- ((Array)curObj).SetValue(TypeDescriptor.GetConverter(value.GetType()).ConvertTo(value, curObj.GetType().GetElementType()), arrayIndex);
-
- SetActorPropetyPacket changeProperty = new SetActorPropetyPacket(uiFunc);
- changeProperty.AddProperty(this, name);
- changeProperty.AddTarget();
- SubPacket subpacket = changeProperty.BuildPacket(player.actorId);
- player.playerSession.QueuePacket(subpacket);
- subpacket.DebugPrintSubPacket();
- return true;
- }
- }
- else
- {
- if (value.GetType() == curObj.GetType() || TypeDescriptor.GetConverter(value.GetType()).CanConvertTo(curObj.GetType()))
- {
- if (value.GetType() == curObj.GetType())
- parentObj.GetType().GetField(split[split.Length - 1]).SetValue(parentObj, value);
- else
- parentObj.GetType().GetField(split[split.Length - 1]).SetValue(parentObj, TypeDescriptor.GetConverter(value.GetType()).ConvertTo(value, curObj.GetType()));
-
- SetActorPropetyPacket changeProperty = new SetActorPropetyPacket(uiFunc);
- changeProperty.AddProperty(this, name);
- changeProperty.AddTarget();
- SubPacket subpacket = changeProperty.BuildPacket(player.actorId);
- player.playerSession.QueuePacket(subpacket);
- subpacket.DebugPrintSubPacket();
- return true;
- }
- }
- return false;
- }
- }
-
- #region positioning
- public List GetPos()
- {
- List pos = new List();
-
- pos.Add(positionX);
- pos.Add(positionY);
- pos.Add(positionZ);
- pos.Add(rotation);
- pos.Add(zoneId);
-
- return pos;
- }
-
- public Vector3 GetPosAsVector3()
- {
- return new Vector3(positionX, positionY, positionZ);
- }
-
- public void SetPos(float x, float y, float z, float rot = 0, uint zoneId = 0)
- {
- oldPositionX = positionX;
- oldPositionY = positionY;
- oldPositionZ = positionZ;
- oldRotation = rotation;
-
- positionX = x;
- positionY = y;
- positionZ = z;
- rotation = rot;
-
- // todo: handle zone?
- zone.BroadcastPacketAroundActor(this, MoveActorToPositionPacket.BuildPacket(actorId, x, y, z, rot, moveState));
- }
-
- public Area GetZone()
- {
- return zone;
- }
-
- public uint GetZoneID()
- {
- return zoneId;
- }
-
- public void LookAt(Actor actor)
- {
- if (actor != null)
- {
- LookAt(actor.positionX, actor.positionZ);
- }
- else
- {
- Program.Log.Error("[{0}][{1}] Actor.LookAt() unable to find actor!", actorId, actorName);
- }
- }
-
- public void LookAt(Vector3 pos)
- {
- if (pos != null)
- {
- LookAt(pos.X, pos.Z);
- }
- }
-
- public void LookAt(float x, float z)
- {
- //Don't rotate if the lookat position is same as our current position
- if (positionX != x || positionZ != z)
- {
- var rot1 = this.rotation;
-
- var dX = this.positionX - x;
- var dY = this.positionZ - z;
- var rot2 = Math.Atan2(dY, dX);
- var dRot = Math.PI - rot2 + Math.PI / 2;
-
- // pending move, dont need to unset it
- this.updateFlags |= ActorUpdateFlags.Position;
- rotation = (float)dRot;
- }
- }
-
- // todo: is this legit?
- public bool IsFacing(float x, float z, float angle = 90.0f)
- {
- angle = (float)(Math.PI * angle / 180);
- var a = Vector3.GetAngle(positionX, positionZ, x, z);
- return new Vector3(x, 0, z).IsWithinCone(GetPosAsVector3(), rotation, angle);
- }
-
- public bool IsFacing(Actor target, float angle = 40.0f)
- {
- if (target == null)
- {
- Program.Log.Error("[{0}][{1}] IsFacing no target!", actorId, actorName);
- return false;
- }
-
- return IsFacing(target.positionX, target.positionZ, angle);
- }
-
- public void QueuePositionUpdate(Vector3 pos)
- {
- if (positionUpdates == null)
- positionUpdates = new List();
-
- positionUpdates.Add(pos);
- this.updateFlags |= ActorUpdateFlags.Position;
- }
-
- public void QueuePositionUpdate(float x, float y, float z)
- {
- QueuePositionUpdate(new Vector3(x, y, z));
- }
-
- public void ClearPositionUpdates()
- {
- positionUpdates.Clear();
- }
-
- public Vector3 FindRandomPoint(float x, float y, float z, float minRadius, float maxRadius)
- {
- var angle = Program.Random.NextDouble() * Math.PI * 2;
- var radius = Math.Sqrt(Program.Random.NextDouble() * (maxRadius - minRadius)) + minRadius;
-
- return new Vector3(x + (float)(radius * Math.Cos(angle)), y, z + (float)(radius * Math.Sin(angle)));
- }
-
- public Vector3 FindRandomPointAroundTarget(Actor target, float minRadius, float maxRadius)
- {
- if (target == null)
- {
- Program.Log.Error(String.Format("[{0} {1}] FindRandomPointAroundTarget: no target found!", this.actorId, this.customDisplayName));
- return GetPosAsVector3();
- }
- return FindRandomPoint(target.positionX, target.positionY, target.positionZ, minRadius, maxRadius);
- }
-
- public Vector3 FindRandomPointAroundActor(float minRadius, float maxRadius)
- {
- return FindRandomPoint(positionX, positionY, positionZ, minRadius, maxRadius);
- }
- #endregion
-
- public override string ToString()
- {
- if (className != null)
- {
- return string.Format("{0} [0x{1:X}]", className, actorId);
- }
- else
- {
- return string.Format("Unknown [0x{0:X}]", actorId);
- }
- }
- }
-}
-
+/*
+===========================================================================
+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 .
+===========================================================================
+*/
+
+
+using FFXIVClassic_Map_Server.actors;
+using FFXIVClassic_Map_Server.lua;
+using FFXIVClassic_Map_Server.packets.send.actor;
+using FFXIVClassic_Map_Server.packets.send.actor.events;
+using Meteor.Common;
+using System;
+using System.Collections.Generic;
+using FFXIVClassic_Map_Server.actors.area;
+using System.Reflection;
+using System.ComponentModel;
+using FFXIVClassic_Map_Server.actors.chara;
+
+namespace FFXIVClassic_Map_Server.Actors
+{
+ [Flags]
+ enum ActorUpdateFlags
+ {
+ None = 0x00,
+ Position = 0x01,
+ HpTpMp = 0x02,
+ State = 0x04,
+ SubState = 0x08,
+ Combat = 0x0F,
+ Name = 0x10,
+ Appearance = 0x20,
+ Speed = 0x40,
+ Work = 0x80,
+ Stats = 0x100,
+ Status = 0x200,
+ StatusTime = 0x400,
+ Hotbar = 0x800,
+
+ AllNpc = 0xDF,
+ AllPlayer = 0x13F
+ }
+
+ class Actor
+ {
+ public static uint INVALID_ACTORID = 0xC0000000;
+ public uint actorId;
+ public string actorName;
+
+ public uint displayNameId = 0xFFFFFFFF;
+ public string customDisplayName;
+
+ public ushort currentMainState = SetActorStatePacket.MAIN_STATE_PASSIVE;
+
+ public SubState currentSubState = new SubState();
+
+ public float positionX, positionY, positionZ, rotation;
+ public float oldPositionX, oldPositionY, oldPositionZ, oldRotation;
+ public ushort moveState, oldMoveState;
+ public float[] moveSpeeds = new float[4];
+
+ public uint zoneId, zoneId2;
+ public string privateArea;
+ public uint privateAreaType;
+ public Area zone = null;
+ public Area zone2 = null;
+ public bool isZoning = false;
+
+ public bool spawnedFirstTime = false;
+
+ public string classPath;
+ public string className;
+ public List classParams;
+
+ public List positionUpdates;
+ protected DateTime lastUpdateScript;
+ protected DateTime lastUpdate;
+ public Actor target;
+
+ public bool isAtSpawn = true;
+
+ public ActorUpdateFlags updateFlags;
+
+ public EventList eventConditions;
+
+ public Actor(uint actorId)
+ {
+ this.actorId = actorId;
+ }
+
+ public Actor(uint actorId, string actorName, string className, List classParams)
+ {
+ this.actorId = actorId;
+ this.actorName = actorName;
+ this.className = className;
+ this.classParams = classParams;
+
+ this.moveSpeeds[0] = SetActorSpeedPacket.DEFAULT_STOP;
+ this.moveSpeeds[1] = SetActorSpeedPacket.DEFAULT_WALK;
+ this.moveSpeeds[2] = SetActorSpeedPacket.DEFAULT_RUN;
+ this.moveSpeeds[3] = SetActorSpeedPacket.DEFAULT_ACTIVE;
+ positionUpdates = new List();
+ }
+
+ public void SetPushCircleRange(string triggerName, float size)
+ {
+ if (eventConditions == null || eventConditions.pushWithCircleEventConditions == null)
+ return;
+
+ foreach (EventList.PushCircleEventCondition condition in eventConditions.pushWithCircleEventConditions)
+ {
+ if (condition.conditionName.Equals(triggerName))
+ {
+ condition.radius = size;
+ break;
+ }
+ }
+ }
+
+ public virtual void ResetMoveSpeeds()
+ {
+ this.moveSpeeds[0] = SetActorSpeedPacket.DEFAULT_STOP;
+ this.moveSpeeds[1] = SetActorSpeedPacket.DEFAULT_WALK;
+ this.moveSpeeds[2] = SetActorSpeedPacket.DEFAULT_RUN;
+ this.moveSpeeds[3] = SetActorSpeedPacket.DEFAULT_ACTIVE;
+
+ this.moveState = this.oldMoveState;
+ this.updateFlags |= ActorUpdateFlags.Speed;
+ }
+
+ public SubPacket CreateAddActorPacket(byte val)
+ {
+ return AddActorPacket.BuildPacket(actorId, val);
+ }
+
+ public SubPacket CreateNamePacket()
+ {
+ return SetActorNamePacket.BuildPacket(actorId, customDisplayName != null ? 0 : displayNameId, displayNameId == 0xFFFFFFFF | displayNameId == 0x0 | customDisplayName != null ? customDisplayName : "");
+ }
+
+ public SubPacket CreateSpeedPacket()
+ {
+ return SetActorSpeedPacket.BuildPacket(actorId, moveSpeeds[0], moveSpeeds[1], moveSpeeds[2], moveSpeeds[3]);
+ }
+
+ public SubPacket CreateSpawnPositonPacket(ushort spawnType)
+ {
+ return CreateSpawnPositonPacket(null, spawnType);
+ }
+
+ public SubPacket CreateSpawnPositonPacket(Player player, ushort spawnType)
+ {
+ //TODO: FIX THIS IF
+ uint playerActorId = player == null ? 0 : player.actorId; //Get Rid
+ SubPacket spawnPacket;
+ if (!spawnedFirstTime && playerActorId == actorId)
+ spawnPacket = SetActorPositionPacket.BuildPacket(actorId, 0, positionX, positionY, positionZ, rotation, 0x1, false);
+ else if (playerActorId == actorId)
+ spawnPacket = SetActorPositionPacket.BuildPacket(actorId, 0xFFFFFFFF, positionX, positionY, positionZ, rotation, spawnType, true);
+ else
+ {
+ if (this is Player)
+ spawnPacket = SetActorPositionPacket.BuildPacket(actorId, 0, positionX, positionY, positionZ, rotation, spawnType, false);
+ else
+ spawnPacket = SetActorPositionPacket.BuildPacket(actorId, actorId, positionX, positionY, positionZ, rotation, spawnType, false);
+ }
+
+ //return SetActorPositionPacket.BuildPacket(actorId, -211.895477f, 190.000000f, 29.651011f, 2.674819f, SetActorPositionPacket.SPAWNTYPE_PLAYERWAKE);
+ spawnedFirstTime = true;
+
+ return spawnPacket;
+ }
+
+ public SubPacket CreateSpawnTeleportPacket(ushort spawnType)
+ {
+ SubPacket spawnPacket;
+
+ spawnPacket = SetActorPositionPacket.BuildPacket(actorId, 0xFFFFFFFF, positionX, positionY, positionZ, rotation, spawnType, false);
+
+ //return SetActorPositionPacket.BuildPacket(actorId, -211.895477f, 190.000000f, 29.651011f, 2.674819f, SetActorPositionPacket.SPAWNTYPE_PLAYERWAKE);
+
+ //spawnPacket.DebugPrintSubPacket();
+
+ return spawnPacket;
+ }
+
+ public SubPacket CreatePositionUpdatePacket()
+ {
+ return MoveActorToPositionPacket.BuildPacket(actorId, positionX, positionY, positionZ, rotation, moveState);
+ }
+
+ public SubPacket CreateStatePacket()
+ {
+ return SetActorStatePacket.BuildPacket(actorId, currentMainState, 0);
+ }
+
+ public List GetEventConditionPackets()
+ {
+ List subpackets = new List();
+
+ //Return empty list
+ if (eventConditions == null)
+ return subpackets;
+
+ if (eventConditions.talkEventConditions != null)
+ {
+ foreach (EventList.TalkEventCondition condition in eventConditions.talkEventConditions)
+ subpackets.Add(SetTalkEventCondition.BuildPacket(actorId, condition));
+ }
+
+ if (eventConditions.noticeEventConditions != null)
+ {
+ foreach (EventList.NoticeEventCondition condition in eventConditions.noticeEventConditions)
+ subpackets.Add(SetNoticeEventCondition.BuildPacket(actorId, condition));
+ }
+
+ if (eventConditions.emoteEventConditions != null)
+ {
+ foreach (EventList.EmoteEventCondition condition in eventConditions.emoteEventConditions)
+ subpackets.Add(SetEmoteEventCondition.BuildPacket(actorId, condition));
+ }
+
+ if (eventConditions.pushWithCircleEventConditions != null)
+ {
+ foreach (EventList.PushCircleEventCondition condition in eventConditions.pushWithCircleEventConditions)
+ subpackets.Add(SetPushEventConditionWithCircle.BuildPacket(actorId, condition));
+ }
+
+ if (eventConditions.pushWithFanEventConditions != null)
+ {
+ foreach (EventList.PushFanEventCondition condition in eventConditions.pushWithFanEventConditions)
+ subpackets.Add(SetPushEventConditionWithFan.BuildPacket(actorId, condition));
+ }
+
+ if (eventConditions.pushWithBoxEventConditions != null)
+ {
+ foreach (EventList.PushBoxEventCondition condition in eventConditions.pushWithBoxEventConditions)
+ subpackets.Add(SetPushEventConditionWithTriggerBox.BuildPacket(actorId, condition));
+ }
+
+ return subpackets;
+ }
+
+ public List GetSetEventStatusPackets()
+ {
+ List subpackets = new List();
+
+ //Return empty list
+ if (eventConditions == null)
+ return subpackets;
+
+ if (eventConditions.talkEventConditions != null)
+ {
+ foreach (EventList.TalkEventCondition condition in eventConditions.talkEventConditions)
+ subpackets.Add(SetEventStatus.BuildPacket(actorId, true, 1, condition.conditionName));
+ }
+
+ if (eventConditions.noticeEventConditions != null)
+ {
+ foreach (EventList.NoticeEventCondition condition in eventConditions.noticeEventConditions)
+ subpackets.Add(SetEventStatus.BuildPacket(actorId, true, 1, condition.conditionName));
+ }
+
+ if (eventConditions.emoteEventConditions != null)
+ {
+ foreach (EventList.EmoteEventCondition condition in eventConditions.emoteEventConditions)
+ subpackets.Add(SetEventStatus.BuildPacket(actorId, true, 3, condition.conditionName));
+ }
+
+ if (eventConditions.pushWithCircleEventConditions != null)
+ {
+ foreach (EventList.PushCircleEventCondition condition in eventConditions.pushWithCircleEventConditions)
+ subpackets.Add(SetEventStatus.BuildPacket(actorId, true, 2, condition.conditionName));
+ }
+
+ if (eventConditions.pushWithFanEventConditions != null)
+ {
+ foreach (EventList.PushFanEventCondition condition in eventConditions.pushWithFanEventConditions)
+ subpackets.Add(SetEventStatus.BuildPacket(actorId, true, 2, condition.conditionName));
+ }
+
+ if (eventConditions.pushWithBoxEventConditions != null)
+ {
+ foreach (EventList.PushBoxEventCondition condition in eventConditions.pushWithBoxEventConditions)
+ subpackets.Add(SetEventStatus.BuildPacket(actorId, true, 2, condition.conditionName));
+ }
+
+ return subpackets;
+ }
+
+ public SubPacket CreateIsZoneingPacket()
+ {
+ return SetActorIsZoningPacket.BuildPacket(actorId, false);
+ }
+
+ public virtual SubPacket CreateScriptBindPacket(Player player)
+ {
+ return ActorInstantiatePacket.BuildPacket(actorId, actorName, className, classParams);
+ }
+
+ public virtual SubPacket CreateScriptBindPacket()
+ {
+ return ActorInstantiatePacket.BuildPacket(actorId, actorName, className, classParams);
+ }
+
+ public virtual List GetSpawnPackets(Player player, ushort spawnType)
+ {
+ List subpackets = new List();
+ subpackets.Add(CreateAddActorPacket(8));
+ subpackets.AddRange(GetEventConditionPackets());
+ subpackets.Add(CreateSpeedPacket());
+ subpackets.Add(CreateSpawnPositonPacket(player, spawnType));
+ subpackets.Add(CreateNamePacket());
+ subpackets.Add(CreateStatePacket());
+ subpackets.Add(CreateIsZoneingPacket());
+ subpackets.Add(CreateScriptBindPacket(player));
+ return subpackets;
+ }
+
+ public virtual List GetSpawnPackets()
+ {
+ return GetSpawnPackets(0x1);
+ }
+
+ public virtual List GetSpawnPackets(ushort spawnType)
+ {
+ List subpackets = new List();
+ subpackets.Add(CreateAddActorPacket(8));
+ subpackets.AddRange(GetEventConditionPackets());
+ subpackets.Add(CreateSpeedPacket());
+ subpackets.Add(CreateSpawnPositonPacket(null, spawnType));
+ subpackets.Add(CreateNamePacket());
+ subpackets.Add(CreateStatePacket());
+ subpackets.Add(CreateIsZoneingPacket());
+ subpackets.Add(CreateScriptBindPacket());
+ return subpackets;
+ }
+
+ public virtual List GetInitPackets()
+ {
+ List packets = new List();
+ SetActorPropetyPacket initProperties = new SetActorPropetyPacket("/_init");
+ initProperties.AddByte(0xE14B0CA8, 1);
+ initProperties.AddByte(0x2138FD71, 1);
+ initProperties.AddByte(0xFBFBCFB1, 1);
+ initProperties.AddTarget();
+ packets.Add(initProperties.BuildPacket(actorId));
+ return packets;
+ }
+
+ public override bool Equals(Object obj)
+ {
+ Actor actorObj = obj as Actor;
+ if (actorObj == null)
+ return false;
+ else
+ return actorId == actorObj.actorId;
+ }
+
+ public string GetName()
+ {
+ return actorName;
+ }
+
+ public string GetClassName()
+ {
+ return className;
+ }
+
+ public ushort GetState()
+ {
+ return currentMainState;
+ }
+
+ public List GetLuaParams()
+ {
+ return classParams;
+ }
+
+ //character's newMainState kind of messes with this
+ public void ChangeState(ushort newState)
+ {
+ if (newState != currentMainState)
+ {
+ currentMainState = newState;
+
+ updateFlags |= (ActorUpdateFlags.State | ActorUpdateFlags.Position);
+ }
+ }
+
+ public SubState GetSubState()
+ {
+ return currentSubState;
+ }
+
+ public void SubstateModified()
+ {
+ updateFlags |= (ActorUpdateFlags.SubState);
+ }
+
+ public void ModifySpeed(float mod)
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ moveSpeeds[i] *= mod;
+ }
+ updateFlags |= ActorUpdateFlags.Speed;
+ }
+
+ public void ChangeSpeed(int type, float value)
+ {
+ moveSpeeds[type] = value;
+ updateFlags |= ActorUpdateFlags.Speed;
+ }
+
+ public void ChangeSpeed(float speedStop, float speedWalk, float speedRun, float speedActive)
+ {
+ moveSpeeds[0] = speedStop;
+ moveSpeeds[1] = speedWalk;
+ moveSpeeds[2] = speedRun;
+ moveSpeeds[3] = speedActive;
+ updateFlags |= ActorUpdateFlags.Speed;
+ }
+
+ public virtual void Update(DateTime tick)
+ {
+
+ }
+
+ public virtual void PostUpdate(DateTime tick, List packets = null)
+ {
+ if (updateFlags != ActorUpdateFlags.None)
+ {
+ packets = packets ?? new List();
+ if ((updateFlags & ActorUpdateFlags.Position) != 0)
+ {
+ if (positionUpdates != null && positionUpdates.Count > 0)
+ {
+ var pos = positionUpdates[0];
+ if (pos != null)
+ {
+ oldPositionX = positionX;
+ oldPositionY = positionY;
+ oldPositionZ = positionZ;
+ oldRotation = rotation;
+
+ positionX = pos.X;
+ positionY = pos.Y;
+ positionZ = pos.Z;
+
+ zone.UpdateActorPosition(this);
+
+ //Program.Server.GetInstance().mLuaEngine.OnPath(actor, position, positionUpdates)
+ }
+ positionUpdates.Remove(pos);
+
+ }
+ packets.Add(CreatePositionUpdatePacket());
+ }
+
+ if ((updateFlags & ActorUpdateFlags.Speed) != 0)
+ {
+ packets.Add(SetActorSpeedPacket.BuildPacket(actorId, moveSpeeds[0], moveSpeeds[1], moveSpeeds[2], moveSpeeds[3]));
+ }
+
+ if ((updateFlags & ActorUpdateFlags.Name) != 0)
+ {
+ packets.Add(SetActorNamePacket.BuildPacket(actorId, displayNameId, customDisplayName));
+ }
+
+ if ((updateFlags & ActorUpdateFlags.State) != 0)
+ {
+ packets.Add(SetActorStatePacket.BuildPacket(actorId, currentMainState, 0x3B));
+ }
+
+ if ((updateFlags & ActorUpdateFlags.SubState) != 0)
+ {
+ packets.Add(SetActorSubStatePacket.BuildPacket(actorId, currentSubState));
+ }
+
+ updateFlags = ActorUpdateFlags.None;
+ }
+ zone.BroadcastPacketsAroundActor(this, packets);
+ }
+
+ public void GenerateActorName(int actorNumber)
+ {
+ //Format Class Name
+ string className = this.className.Replace("Populace", "Ppl")
+ .Replace("Monster", "Mon")
+ .Replace("Crowd", "Crd")
+ .Replace("MapObj", "Map")
+ .Replace("Object", "Obj")
+ .Replace("Retainer", "Rtn")
+ .Replace("Standard", "Std");
+ className = Char.ToLowerInvariant(className[0]) + className.Substring(1);
+
+ //Format Zone Name
+ string zoneName = zone.zoneName.Replace("Field", "Fld")
+ .Replace("Dungeon", "Dgn")
+ .Replace("Town", "Twn")
+ .Replace("Battle", "Btl")
+ .Replace("Test", "Tes")
+ .Replace("Event", "Evt")
+ .Replace("Ship", "Shp")
+ .Replace("Office", "Ofc");
+ if (zone is PrivateArea)
+ {
+ //Check if "normal"
+ zoneName = zoneName.Remove(zoneName.Length - 1, 1) + "P";
+ }
+ zoneName = Char.ToLowerInvariant(zoneName[0]) + zoneName.Substring(1);
+
+ try
+ {
+ className = className.Substring(0, 20 - zoneName.Length);
+ }
+ catch (ArgumentOutOfRangeException)
+ { }
+
+ //Convert actor number to base 63
+ string classNumber = Utils.ToStringBase63(actorNumber);
+
+ //Get stuff after @
+ uint zoneId = zone.actorId;
+ uint privLevel = 0;
+ if (zone is PrivateArea)
+ privLevel = ((PrivateArea)zone).GetPrivateAreaType();
+
+ actorName = String.Format("{0}_{1}_{2}@{3:X3}{4:X2}", className, zoneName, classNumber, zoneId, privLevel);
+ }
+
+ public bool SetWorkValue(Player player, string name, string uiFunc, object value)
+ {
+ string[] split = name.Split('.');
+ int arrayIndex = 0;
+
+ if (!(split[0].Equals("work") || split[0].Equals("charaWork") || split[0].Equals("playerWork") || split[0].Equals("npcWork")))
+ return false;
+
+ Object parentObj = null;
+ Object curObj = this;
+ for (int i = 0; i < split.Length; i++)
+ {
+ //For arrays
+ if (split[i].Contains("["))
+ {
+ if (split[i].LastIndexOf(']') - split[i].IndexOf('[') <= 0)
+ return false;
+
+ arrayIndex = Convert.ToInt32(split[i].Substring(split[i].IndexOf('[') + 1, split[i].LastIndexOf(']') - split[i].LastIndexOf('[') - 1));
+ split[i] = split[i].Substring(0, split[i].IndexOf('['));
+ }
+
+ FieldInfo field = curObj.GetType().GetField(split[i]);
+ if (field == null)
+ return false;
+
+ if (i == split.Length - 1)
+ parentObj = curObj;
+ curObj = field.GetValue(curObj);
+ if (curObj == null)
+ return false;
+ }
+
+ if (curObj == null)
+ return false;
+ else
+ {
+ //Array, we actually care whats inside
+ if (curObj.GetType().IsArray)
+ {
+ if (((Array)curObj).Length <= arrayIndex)
+ return false;
+
+ if (value.GetType() == ((Array)curObj).GetType().GetElementType() || TypeDescriptor.GetConverter(value.GetType()).CanConvertTo(((Array)curObj).GetType().GetElementType()))
+ {
+ if (value.GetType() == ((Array)curObj).GetType().GetElementType())
+ ((Array)curObj).SetValue(value, arrayIndex);
+ else
+ ((Array)curObj).SetValue(TypeDescriptor.GetConverter(value.GetType()).ConvertTo(value, curObj.GetType().GetElementType()), arrayIndex);
+
+ SetActorPropetyPacket changeProperty = new SetActorPropetyPacket(uiFunc);
+ changeProperty.AddProperty(this, name);
+ changeProperty.AddTarget();
+ SubPacket subpacket = changeProperty.BuildPacket(player.actorId);
+ player.playerSession.QueuePacket(subpacket);
+ subpacket.DebugPrintSubPacket();
+ return true;
+ }
+ }
+ else
+ {
+ if (value.GetType() == curObj.GetType() || TypeDescriptor.GetConverter(value.GetType()).CanConvertTo(curObj.GetType()))
+ {
+ if (value.GetType() == curObj.GetType())
+ parentObj.GetType().GetField(split[split.Length - 1]).SetValue(parentObj, value);
+ else
+ parentObj.GetType().GetField(split[split.Length - 1]).SetValue(parentObj, TypeDescriptor.GetConverter(value.GetType()).ConvertTo(value, curObj.GetType()));
+
+ SetActorPropetyPacket changeProperty = new SetActorPropetyPacket(uiFunc);
+ changeProperty.AddProperty(this, name);
+ changeProperty.AddTarget();
+ SubPacket subpacket = changeProperty.BuildPacket(player.actorId);
+ player.playerSession.QueuePacket(subpacket);
+ subpacket.DebugPrintSubPacket();
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ #region positioning
+ public List GetPos()
+ {
+ List pos = new List();
+
+ pos.Add(positionX);
+ pos.Add(positionY);
+ pos.Add(positionZ);
+ pos.Add(rotation);
+ pos.Add(zoneId);
+
+ return pos;
+ }
+
+ public Vector3 GetPosAsVector3()
+ {
+ return new Vector3(positionX, positionY, positionZ);
+ }
+
+ public void SetPos(float x, float y, float z, float rot = 0, uint zoneId = 0)
+ {
+ oldPositionX = positionX;
+ oldPositionY = positionY;
+ oldPositionZ = positionZ;
+ oldRotation = rotation;
+
+ positionX = x;
+ positionY = y;
+ positionZ = z;
+ rotation = rot;
+
+ // todo: handle zone?
+ zone.BroadcastPacketAroundActor(this, MoveActorToPositionPacket.BuildPacket(actorId, x, y, z, rot, moveState));
+ }
+
+ public Area GetZone()
+ {
+ return zone;
+ }
+
+ public uint GetZoneID()
+ {
+ return zoneId;
+ }
+
+ public void LookAt(Actor actor)
+ {
+ if (actor != null)
+ {
+ LookAt(actor.positionX, actor.positionZ);
+ }
+ else
+ {
+ Program.Log.Error("[{0}][{1}] Actor.LookAt() unable to find actor!", actorId, actorName);
+ }
+ }
+
+ public void LookAt(Vector3 pos)
+ {
+ if (pos != null)
+ {
+ LookAt(pos.X, pos.Z);
+ }
+ }
+
+ public void LookAt(float x, float z)
+ {
+ //Don't rotate if the lookat position is same as our current position
+ if (positionX != x || positionZ != z)
+ {
+ var rot1 = this.rotation;
+
+ var dX = this.positionX - x;
+ var dY = this.positionZ - z;
+ var rot2 = Math.Atan2(dY, dX);
+ var dRot = Math.PI - rot2 + Math.PI / 2;
+
+ // pending move, dont need to unset it
+ this.updateFlags |= ActorUpdateFlags.Position;
+ rotation = (float)dRot;
+ }
+ }
+
+ // todo: is this legit?
+ public bool IsFacing(float x, float z, float angle = 90.0f)
+ {
+ angle = (float)(Math.PI * angle / 180);
+ var a = Vector3.GetAngle(positionX, positionZ, x, z);
+ return new Vector3(x, 0, z).IsWithinCone(GetPosAsVector3(), rotation, angle);
+ }
+
+ public bool IsFacing(Actor target, float angle = 40.0f)
+ {
+ if (target == null)
+ {
+ Program.Log.Error("[{0}][{1}] IsFacing no target!", actorId, actorName);
+ return false;
+ }
+
+ return IsFacing(target.positionX, target.positionZ, angle);
+ }
+
+ public void QueuePositionUpdate(Vector3 pos)
+ {
+ if (positionUpdates == null)
+ positionUpdates = new List();
+
+ positionUpdates.Add(pos);
+ this.updateFlags |= ActorUpdateFlags.Position;
+ }
+
+ public void QueuePositionUpdate(float x, float y, float z)
+ {
+ QueuePositionUpdate(new Vector3(x, y, z));
+ }
+
+ public void ClearPositionUpdates()
+ {
+ positionUpdates.Clear();
+ }
+
+ public Vector3 FindRandomPoint(float x, float y, float z, float minRadius, float maxRadius)
+ {
+ var angle = Program.Random.NextDouble() * Math.PI * 2;
+ var radius = Math.Sqrt(Program.Random.NextDouble() * (maxRadius - minRadius)) + minRadius;
+
+ return new Vector3(x + (float)(radius * Math.Cos(angle)), y, z + (float)(radius * Math.Sin(angle)));
+ }
+
+ public Vector3 FindRandomPointAroundTarget(Actor target, float minRadius, float maxRadius)
+ {
+ if (target == null)
+ {
+ Program.Log.Error(String.Format("[{0} {1}] FindRandomPointAroundTarget: no target found!", this.actorId, this.customDisplayName));
+ return GetPosAsVector3();
+ }
+ return FindRandomPoint(target.positionX, target.positionY, target.positionZ, minRadius, maxRadius);
+ }
+
+ public Vector3 FindRandomPointAroundActor(float minRadius, float maxRadius)
+ {
+ return FindRandomPoint(positionX, positionY, positionZ, minRadius, maxRadius);
+ }
+ #endregion
+
+ public override string ToString()
+ {
+ if (className != null)
+ {
+ return string.Format("{0} [0x{1:X}]", className, actorId);
+ }
+ else
+ {
+ return string.Format("Unknown [0x{0:X}]", actorId);
+ }
+ }
+ }
+}
+
diff --git a/FFXIVClassic Map Server/actors/EventList.cs b/Map Server/actors/EventList.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/EventList.cs
rename to Map Server/actors/EventList.cs
diff --git a/FFXIVClassic Map Server/actors/StaticActors.cs b/Map Server/actors/StaticActors.cs
similarity index 99%
rename from FFXIVClassic Map Server/actors/StaticActors.cs
rename to Map Server/actors/StaticActors.cs
index 1628893e..7a29a548 100644
--- a/FFXIVClassic Map Server/actors/StaticActors.cs
+++ b/Map Server/actors/StaticActors.cs
@@ -19,7 +19,7 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-using FFXIVClassic.Common;
+using Meteor.Common;
using System;
using System.Collections.Generic;
using System.IO;
diff --git a/FFXIVClassic Map Server/actors/area/Area.cs b/Map Server/actors/area/Area.cs
similarity index 96%
rename from FFXIVClassic Map Server/actors/area/Area.cs
rename to Map Server/actors/area/Area.cs
index 94d7a6ab..c66dae07 100644
--- a/FFXIVClassic Map Server/actors/area/Area.cs
+++ b/Map Server/actors/area/Area.cs
@@ -1,696 +1,696 @@
-/*
-===========================================================================
-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 .
-===========================================================================
-*/
-
-using FFXIVClassic.Common;
-using FFXIVClassic_Map_Server.actors.area;
-using FFXIVClassic_Map_Server.actors.chara.npc;
-using FFXIVClassic_Map_Server.lua;
-using FFXIVClassic_Map_Server.packets.send.actor;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using FFXIVClassic_Map_Server.packets.send;
-using FFXIVClassic_Map_Server.actors.director;
-
-namespace FFXIVClassic_Map_Server.Actors
-{
- class Area : Actor
- {
- public string zoneName;
- public ushort regionId;
- public bool isIsolated, canStealth, isInn, canRideChocobo, isInstanceRaid;
- public ushort weatherNormal, weatherCommon, weatherRare;
- public ushort bgmDay, bgmNight, bgmBattle;
-
- protected string classPath;
-
- public int boundingGridSize = 50;
- public int minX = -5000, minY = -5000, maxX = 5000, maxY = 5000;
- protected int numXBlocks, numYBlocks;
- protected int halfWidth, halfHeight;
-
- private Dictionary currentDirectors = new Dictionary();
- private Object directorLock = new Object();
- private uint directorIdCount = 0;
-
- protected Director mWeatherDirector;
-
- protected List mSpawnLocations = new List();
- protected Dictionary mActorList = new Dictionary();
- protected List[,] mActorBlock;
-
- LuaScript areaScript;
-
- public Area(uint id, string zoneName, ushort regionId, string classPath, ushort bgmDay, ushort bgmNight, ushort bgmBattle, bool isIsolated, bool isInn, bool canRideChocobo, bool canStealth, bool isInstanceRaid)
- : base(id)
- {
-
- this.zoneName = zoneName;
- this.regionId = regionId;
- this.canStealth = canStealth;
- this.isIsolated = isIsolated;
- this.isInn = isInn;
- this.canRideChocobo = canRideChocobo;
- this.isInstanceRaid = isInstanceRaid;
-
- this.bgmDay = bgmDay;
- this.bgmNight = bgmNight;
- this.bgmBattle = bgmBattle;
-
- this.displayNameId = 0;
- this.customDisplayName = "_areaMaster";
- this.actorName = String.Format("_areaMaster@{0:X5}", id << 8);
-
- this.classPath = classPath;
- this.className = classPath.Substring(classPath.LastIndexOf("/") + 1);
-
- numXBlocks = (maxX - minX) / boundingGridSize;
- numYBlocks = (maxY - minY) / boundingGridSize;
- mActorBlock = new List[numXBlocks, numYBlocks];
- halfWidth = numXBlocks / 2;
- halfHeight = numYBlocks / 2;
-
- for (int y = 0; y < numYBlocks; y++)
- {
- for (int x = 0; x < numXBlocks; x++)
- {
- mActorBlock[x, y] = new List();
- }
- }
- }
-
- public override SubPacket CreateScriptBindPacket()
- {
- List lParams;
- lParams = LuaUtils.CreateLuaParamList(classPath, false, true, zoneName, "/Area/Zone/ZoneDefault", -1, (byte)1, true, false, false, false, false, false, false, false);
- return ActorInstantiatePacket.BuildPacket(actorId, actorName, "ZoneDefault", lParams);
- }
-
- public override List GetSpawnPackets()
- {
- List subpackets = new List();
- subpackets.Add(CreateAddActorPacket(0));
- subpackets.Add(CreateSpeedPacket());
- subpackets.Add(CreateSpawnPositonPacket(0x1));
- subpackets.Add(CreateNamePacket());
- subpackets.Add(CreateStatePacket());
- subpackets.Add(CreateIsZoneingPacket());
- subpackets.Add(CreateScriptBindPacket());
- return subpackets;
- }
-
- // todo: handle instance areas in derived class? (see virtuals)
- #region Actor Management
-
- public void AddActorToZone(Actor actor)
- {
- lock (mActorList)
- {
- if (actor is Character)
- ((Character)actor).ResetTempVars();
-
- if (!mActorList.ContainsKey(actor.actorId))
- mActorList.Add(actor.actorId, actor);
-
-
- int gridX = (int)actor.positionX / boundingGridSize;
- int gridY = (int)actor.positionZ / boundingGridSize;
-
- gridX += halfWidth;
- gridY += halfHeight;
-
- //Boundries
- if (gridX < 0)
- gridX = 0;
- if (gridX >= numXBlocks)
- gridX = numXBlocks - 1;
- if (gridY < 0)
- gridY = 0;
- if (gridY >= numYBlocks)
- gridY = numYBlocks - 1;
-
- lock (mActorBlock)
- mActorBlock[gridX, gridY].Add(actor);
- }
- }
-
- public void RemoveActorFromZone(Actor actor)
- {
- if (actor != null)
- lock (mActorList)
- {
- mActorList.Remove(actor.actorId);
-
- int gridX = (int)actor.positionX / boundingGridSize;
- int gridY = (int)actor.positionZ / boundingGridSize;
-
- gridX += halfWidth;
- gridY += halfHeight;
-
- //Boundries
- if (gridX < 0)
- gridX = 0;
- if (gridX >= numXBlocks)
- gridX = numXBlocks - 1;
- if (gridY < 0)
- gridY = 0;
- if (gridY >= numYBlocks)
- gridY = numYBlocks - 1;
-
- lock (mActorBlock)
- mActorBlock[gridX, gridY].Remove(actor);
- }
- }
-
- public void UpdateActorPosition(Actor actor)
- {
- int gridX = (int)actor.positionX / boundingGridSize;
- int gridY = (int)actor.positionZ / boundingGridSize;
-
- gridX += halfWidth;
- gridY += halfHeight;
-
- //Boundries
- if (gridX < 0)
- gridX = 0;
- if (gridX >= numXBlocks)
- gridX = numXBlocks - 1;
- if (gridY < 0)
- gridY = 0;
- if (gridY >= numYBlocks)
- gridY = numYBlocks - 1;
-
- int gridOldX = (int)actor.oldPositionX / boundingGridSize;
- int gridOldY = (int)actor.oldPositionZ / boundingGridSize;
-
- gridOldX += halfWidth;
- gridOldY += halfHeight;
-
- //Boundries
- if (gridOldX < 0)
- gridOldX = 0;
- if (gridOldX >= numXBlocks)
- gridOldX = numXBlocks - 1;
- if (gridOldY < 0)
- gridOldY = 0;
- if (gridOldY >= numYBlocks)
- gridOldY = numYBlocks - 1;
-
- //Still in same block
- if (gridX == gridOldX && gridY == gridOldY)
- return;
-
- lock (mActorBlock)
- {
- mActorBlock[gridOldX, gridOldY].Remove(actor);
- mActorBlock[gridX, gridY].Add(actor);
- }
- }
-
- public virtual List GetActorsAroundPoint(float x, float y, int checkDistance) where T : Actor
- {
- checkDistance /= boundingGridSize;
-
- int gridX = (int)x / boundingGridSize;
- int gridY = (int)y / boundingGridSize;
-
- gridX += halfWidth;
- gridY += halfHeight;
-
- //Boundries
- if (gridX < 0)
- gridX = 0;
- if (gridX >= numXBlocks)
- gridX = numXBlocks - 1;
- if (gridY < 0)
- gridY = 0;
- if (gridY >= numYBlocks)
- gridY = numYBlocks - 1;
-
- List result = new List();
-
- lock (mActorBlock)
- {
- for (int gx = gridX - checkDistance; gx <= gridX + checkDistance; gx++)
- {
- for (int gy = gridY - checkDistance; gy <= gridY + checkDistance; gy++)
- {
- result.AddRange(mActorBlock[gx, gy].OfType());
- }
- }
- }
-
- //Remove players if isolation zone
- if (isIsolated)
- {
- for (int i = 0; i < result.Count; i++)
- {
- if (result[i] is Player)
- result.RemoveAt(i);
- }
- }
- return result;
- }
-
- public virtual List GetActorsAroundPoint(float x, float y, int checkDistance)
- {
- return GetActorsAroundPoint(x, y, checkDistance);
- }
-
- public virtual List GetActorsAroundActor(Actor actor, int checkDistance)
- {
- return GetActorsAroundActor(actor, checkDistance);
- }
-
- public virtual List GetActorsAroundActor(Actor actor, int checkDistance) where T : Actor
- {
- checkDistance /= boundingGridSize;
-
- int gridX = (int)actor.positionX / boundingGridSize;
- int gridY = (int)actor.positionZ / boundingGridSize;
-
- gridX += halfWidth;
- gridY += halfHeight;
-
- //Boundries
- if (gridX < 0)
- gridX = 0;
- if (gridX >= numXBlocks)
- gridX = numXBlocks - 1;
- if (gridY < 0)
- gridY = 0;
- if (gridY >= numYBlocks)
- gridY = numYBlocks - 1;
-
- var result = new List();
-
- lock (mActorBlock)
- {
- for (int gy = ((gridY - checkDistance) < 0 ? 0 : (gridY - checkDistance)); gy <= ((gridY + checkDistance) >= numYBlocks ? numYBlocks - 1 : (gridY + checkDistance)); gy++)
- {
- for (int gx = ((gridX - checkDistance) < 0 ? 0 : (gridX - checkDistance)); gx <= ((gridX + checkDistance) >= numXBlocks ? numXBlocks - 1 : (gridX + checkDistance)); gx++)
- {
- result.AddRange(mActorBlock[gx, gy].OfType());
- }
- }
- }
-
- //Remove players if isolation zone
- if (isIsolated)
- {
- for (int i = 0; i < result.Count; i++)
- {
- if (result[i] is Player)
- result.RemoveAt(i);
- }
- }
-
- return result;
- }
-
- #endregion
-
- public Actor FindActorInArea(uint id)
- {
- lock (mActorList)
- {
- if (!mActorList.ContainsKey(id))
- return null;
- return mActorList[id];
- }
- }
-
- public T FindActorInArea(uint id) where T : Actor
- {
- return FindActorInArea(id) as T;
- }
-
- public Actor FindActorInZoneByUniqueID(string uniqueId)
- {
- lock (mActorList)
- {
- foreach (Actor a in mActorList.Values)
- {
- if (a is Npc)
- {
- if (((Npc)a).GetUniqueId().ToLower().Equals(uniqueId))
- return a;
- }
- }
- }
- return null;
- }
-
- public Player FindPCInZone(string name)
- {
- lock (mActorList)
- {
- foreach (Player player in mActorList.Values.OfType())
- {
- if (player.customDisplayName.ToLower().Equals(name.ToLower()))
- return player;
- }
- return null;
- }
- }
-
- public Player FindPCInZone(uint id)
- {
- lock (mActorList)
- {
- if (!mActorList.ContainsKey(id))
- return null;
- return (Player)mActorList[id];
- }
- }
-
- public void Clear()
- {
- lock (mActorList)
- {
- //Clear All
- mActorList.Clear();
- lock (mActorBlock)
- {
- for (int y = 0; y < numYBlocks; y++)
- {
- for (int x = 0; x < numXBlocks; x++)
- {
- mActorBlock[x, y].Clear();
- }
- }
- }
- }
- }
-
- // todo: for zones override this to search contentareas (assuming flag is passed)
- public virtual List GetAllActors() where T : Actor
- {
- lock (mActorList)
- {
- List actorList = new List(mActorList.Count);
- actorList.AddRange(mActorList.Values.OfType());
- return actorList;
- }
- }
-
- public int GetActorCount()
- {
- lock (mActorList)
- {
- return mActorList.Count;
- }
- }
-
- public virtual List GetAllActors()
- {
- return GetAllActors();
- }
-
- public virtual List GetPlayers()
- {
- return GetAllActors();
- }
-
- public virtual List GetMonsters()
- {
- return GetAllActors();
- }
-
- public virtual List GetAllies()
- {
- return GetAllActors();
- }
-
- public void BroadcastPacketsAroundActor(Actor actor, List packets)
- {
- foreach (SubPacket packet in packets)
- BroadcastPacketAroundActor(actor, packet);
- }
-
- public void BroadcastPacketAroundActor(Actor actor, SubPacket packet)
- {
- if (isIsolated)
- return;
-
- List aroundActor = GetActorsAroundActor(actor, 50);
- foreach (Actor a in aroundActor)
- {
- if (a is Player)
- {
- if (isIsolated)
- continue;
-
- SubPacket clonedPacket = new SubPacket(packet, a.actorId);
- Player p = (Player)a;
- p.QueuePacket(clonedPacket);
- }
- }
- }
-
- public void SpawnActor(SpawnLocation location)
- {
- lock (mActorList)
- {
- ActorClass actorClass = Server.GetWorldManager().GetActorClass(location.classId);
-
- if (actorClass == null)
- return;
-
- uint zoneId;
-
- if (this is PrivateArea)
- zoneId = ((PrivateArea)this).GetParentZone().actorId;
- else
- zoneId = actorId;
-
- Npc npc = new Npc(mActorList.Count + 1, actorClass, location.uniqueId, this, location.x, location.y, location.z, location.rot, location.state, location.animId, null);
-
-
- npc.LoadEventConditions(actorClass.eventConditions);
-
- AddActorToZone(npc);
- }
- }
-
- public Npc SpawnActor(uint classId, string uniqueId, float x, float y, float z, float rot = 0, ushort state = 0, uint animId = 0, bool isMob = false)
- {
- lock (mActorList)
- {
- ActorClass actorClass = Server.GetWorldManager().GetActorClass(classId);
-
- if (actorClass == null)
- return null;
-
- uint zoneId;
- if (this is PrivateArea)
- zoneId = ((PrivateArea)this).GetParentZone().actorId;
- else
- zoneId = actorId;
-
- Npc npc;
- if (isMob)
- npc = new BattleNpc(mActorList.Count + 1, actorClass, uniqueId, this, x, y, z, rot, state, animId, null);
- else
- npc = new Npc(mActorList.Count + 1, actorClass, uniqueId, this, x, y, z, rot, state, animId, null);
-
- npc.LoadEventConditions(actorClass.eventConditions);
- npc.SetMaxHP(100);
- npc.SetHP(100);
- npc.ResetMoveSpeeds();
-
- AddActorToZone(npc);
-
- return npc;
- }
- }
-
- public Npc SpawnActor(uint classId, string uniqueId, float x, float y, float z, uint regionId, uint layoutId)
- {
- lock (mActorList)
- {
- ActorClass actorClass = Server.GetWorldManager().GetActorClass(classId);
-
- if (actorClass == null)
- return null;
-
- uint zoneId;
-
- if (this is PrivateArea)
- zoneId = ((PrivateArea)this).GetParentZone().actorId;
- else
- zoneId = actorId;
-
- Npc npc = new Npc(mActorList.Count + 1, actorClass, uniqueId, this, x, y, z, 0, regionId, layoutId);
-
- npc.LoadEventConditions(actorClass.eventConditions);
-
- AddActorToZone(npc);
-
- return npc;
- }
- }
-
- public BattleNpc GetBattleNpcById(uint id)
- {
- foreach (var bnpc in GetAllActors())
- {
- if (bnpc.GetBattleNpcId() == id)
- return bnpc;
- }
- return null;
- }
-
- public void DespawnActor(string uniqueId)
- {
- RemoveActorFromZone(FindActorInZoneByUniqueID(uniqueId));
- }
-
- public void DespawnActor(Actor actor)
- {
- RemoveActorFromZone(actor);
- }
-
- public Director GetWeatherDirector()
- {
- return mWeatherDirector;
- }
-
- public void ChangeWeather(ushort weather, ushort transitionTime, Player player, bool zoneWide = false)
- {
- weatherNormal = weather;
-
- if (player != null && !zoneWide)
- {
- player.QueuePacket(SetWeatherPacket.BuildPacket(player.actorId, weather, transitionTime));
- }
- if (zoneWide)
- {
- lock (mActorList)
- {
- foreach (var actor in mActorList)
- {
- if (actor.Value is Player)
- {
- player = ((Player)actor.Value);
- player.QueuePacket(SetWeatherPacket.BuildPacket(player.actorId, weather, transitionTime));
- }
- }
- }
- }
- }
-
- public Director CreateDirector(string path, bool hasContentGroup, params object[] args)
- {
- lock (directorLock)
- {
- Director director = new Director(directorIdCount, this, path, hasContentGroup, args);
- currentDirectors.Add(director.actorId, director);
- directorIdCount++;
- return director;
- }
- }
-
- public Director CreateGuildleveDirector(uint glid, byte difficulty, Player owner, params object[] args)
- {
- String directorScriptPath = "";
-
- uint type = Server.GetGuildleveGamedata(glid).plateId;
-
- if (glid == 10801 || glid == 12401 || glid == 11601)
- directorScriptPath = "Guildleve/PrivateGLBattleTutorial";
- else
- {
- switch (type)
- {
- case 20021:
- directorScriptPath = "Guildleve/PrivateGLBattleSweepNormal";
- break;
- case 20022:
- directorScriptPath = "Guildleve/PrivateGLBattleChaseNormal";
- break;
- case 20023:
- directorScriptPath = "Guildleve/PrivateGLBattleOrbNormal";
- break;
- case 20024:
- directorScriptPath = "Guildleve/PrivateGLBattleHuntNormal";
- break;
- case 20025:
- directorScriptPath = "Guildleve/PrivateGLBattleGatherNormal";
- break;
- case 20026:
- directorScriptPath = "Guildleve/PrivateGLBattleRoundNormal";
- break;
- case 20027:
- directorScriptPath = "Guildleve/PrivateGLBattleSurviveNormal";
- break;
- case 20028:
- directorScriptPath = "Guildleve/PrivateGLBattleDetectNormal";
- break;
- }
- }
-
- lock (directorLock)
- {
- GuildleveDirector director = new GuildleveDirector(directorIdCount, this, directorScriptPath, glid, difficulty, owner, args);
- currentDirectors.Add(director.actorId, director);
- directorIdCount++;
- return director;
- }
- }
-
- public void DeleteDirector(uint id)
- {
- lock (directorLock)
- {
- if (currentDirectors.ContainsKey(id))
- {
- if (!currentDirectors[id].IsDeleted())
- currentDirectors[id].EndDirector();
- currentDirectors.Remove(id);
- }
- }
- }
-
- public Director GetDirectorById(uint id)
- {
- if (currentDirectors.ContainsKey(id))
- return currentDirectors[id];
- return null;
- }
-
- public override void Update(DateTime tick)
- {
- lock (mActorList)
- {
- foreach (Actor a in mActorList.Values.ToList())
- a.Update(tick);
-
- if ((tick - lastUpdateScript).TotalMilliseconds > 1500)
- {
- //LuaEngine.GetInstance().CallLuaFunctionForReturn(LuaEngine.GetScriptPath(this), "onUpdate", true, this, tick);
- lastUpdateScript = tick;
- }
- }
- }
-
- }
-}
+/*
+===========================================================================
+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 .
+===========================================================================
+*/
+
+using Meteor.Common;
+using FFXIVClassic_Map_Server.actors.area;
+using FFXIVClassic_Map_Server.actors.chara.npc;
+using FFXIVClassic_Map_Server.lua;
+using FFXIVClassic_Map_Server.packets.send.actor;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using FFXIVClassic_Map_Server.packets.send;
+using FFXIVClassic_Map_Server.actors.director;
+
+namespace FFXIVClassic_Map_Server.Actors
+{
+ class Area : Actor
+ {
+ public string zoneName;
+ public ushort regionId;
+ public bool isIsolated, canStealth, isInn, canRideChocobo, isInstanceRaid;
+ public ushort weatherNormal, weatherCommon, weatherRare;
+ public ushort bgmDay, bgmNight, bgmBattle;
+
+ protected string classPath;
+
+ public int boundingGridSize = 50;
+ public int minX = -5000, minY = -5000, maxX = 5000, maxY = 5000;
+ protected int numXBlocks, numYBlocks;
+ protected int halfWidth, halfHeight;
+
+ private Dictionary currentDirectors = new Dictionary();
+ private Object directorLock = new Object();
+ private uint directorIdCount = 0;
+
+ protected Director mWeatherDirector;
+
+ protected List mSpawnLocations = new List();
+ protected Dictionary mActorList = new Dictionary();
+ protected List[,] mActorBlock;
+
+ LuaScript areaScript;
+
+ public Area(uint id, string zoneName, ushort regionId, string classPath, ushort bgmDay, ushort bgmNight, ushort bgmBattle, bool isIsolated, bool isInn, bool canRideChocobo, bool canStealth, bool isInstanceRaid)
+ : base(id)
+ {
+
+ this.zoneName = zoneName;
+ this.regionId = regionId;
+ this.canStealth = canStealth;
+ this.isIsolated = isIsolated;
+ this.isInn = isInn;
+ this.canRideChocobo = canRideChocobo;
+ this.isInstanceRaid = isInstanceRaid;
+
+ this.bgmDay = bgmDay;
+ this.bgmNight = bgmNight;
+ this.bgmBattle = bgmBattle;
+
+ this.displayNameId = 0;
+ this.customDisplayName = "_areaMaster";
+ this.actorName = String.Format("_areaMaster@{0:X5}", id << 8);
+
+ this.classPath = classPath;
+ this.className = classPath.Substring(classPath.LastIndexOf("/") + 1);
+
+ numXBlocks = (maxX - minX) / boundingGridSize;
+ numYBlocks = (maxY - minY) / boundingGridSize;
+ mActorBlock = new List[numXBlocks, numYBlocks];
+ halfWidth = numXBlocks / 2;
+ halfHeight = numYBlocks / 2;
+
+ for (int y = 0; y < numYBlocks; y++)
+ {
+ for (int x = 0; x < numXBlocks; x++)
+ {
+ mActorBlock[x, y] = new List();
+ }
+ }
+ }
+
+ public override SubPacket CreateScriptBindPacket()
+ {
+ List lParams;
+ lParams = LuaUtils.CreateLuaParamList(classPath, false, true, zoneName, "/Area/Zone/ZoneDefault", -1, (byte)1, true, false, false, false, false, false, false, false);
+ return ActorInstantiatePacket.BuildPacket(actorId, actorName, "ZoneDefault", lParams);
+ }
+
+ public override List GetSpawnPackets()
+ {
+ List subpackets = new List();
+ subpackets.Add(CreateAddActorPacket(0));
+ subpackets.Add(CreateSpeedPacket());
+ subpackets.Add(CreateSpawnPositonPacket(0x1));
+ subpackets.Add(CreateNamePacket());
+ subpackets.Add(CreateStatePacket());
+ subpackets.Add(CreateIsZoneingPacket());
+ subpackets.Add(CreateScriptBindPacket());
+ return subpackets;
+ }
+
+ // todo: handle instance areas in derived class? (see virtuals)
+ #region Actor Management
+
+ public void AddActorToZone(Actor actor)
+ {
+ lock (mActorList)
+ {
+ if (actor is Character)
+ ((Character)actor).ResetTempVars();
+
+ if (!mActorList.ContainsKey(actor.actorId))
+ mActorList.Add(actor.actorId, actor);
+
+
+ int gridX = (int)actor.positionX / boundingGridSize;
+ int gridY = (int)actor.positionZ / boundingGridSize;
+
+ gridX += halfWidth;
+ gridY += halfHeight;
+
+ //Boundries
+ if (gridX < 0)
+ gridX = 0;
+ if (gridX >= numXBlocks)
+ gridX = numXBlocks - 1;
+ if (gridY < 0)
+ gridY = 0;
+ if (gridY >= numYBlocks)
+ gridY = numYBlocks - 1;
+
+ lock (mActorBlock)
+ mActorBlock[gridX, gridY].Add(actor);
+ }
+ }
+
+ public void RemoveActorFromZone(Actor actor)
+ {
+ if (actor != null)
+ lock (mActorList)
+ {
+ mActorList.Remove(actor.actorId);
+
+ int gridX = (int)actor.positionX / boundingGridSize;
+ int gridY = (int)actor.positionZ / boundingGridSize;
+
+ gridX += halfWidth;
+ gridY += halfHeight;
+
+ //Boundries
+ if (gridX < 0)
+ gridX = 0;
+ if (gridX >= numXBlocks)
+ gridX = numXBlocks - 1;
+ if (gridY < 0)
+ gridY = 0;
+ if (gridY >= numYBlocks)
+ gridY = numYBlocks - 1;
+
+ lock (mActorBlock)
+ mActorBlock[gridX, gridY].Remove(actor);
+ }
+ }
+
+ public void UpdateActorPosition(Actor actor)
+ {
+ int gridX = (int)actor.positionX / boundingGridSize;
+ int gridY = (int)actor.positionZ / boundingGridSize;
+
+ gridX += halfWidth;
+ gridY += halfHeight;
+
+ //Boundries
+ if (gridX < 0)
+ gridX = 0;
+ if (gridX >= numXBlocks)
+ gridX = numXBlocks - 1;
+ if (gridY < 0)
+ gridY = 0;
+ if (gridY >= numYBlocks)
+ gridY = numYBlocks - 1;
+
+ int gridOldX = (int)actor.oldPositionX / boundingGridSize;
+ int gridOldY = (int)actor.oldPositionZ / boundingGridSize;
+
+ gridOldX += halfWidth;
+ gridOldY += halfHeight;
+
+ //Boundries
+ if (gridOldX < 0)
+ gridOldX = 0;
+ if (gridOldX >= numXBlocks)
+ gridOldX = numXBlocks - 1;
+ if (gridOldY < 0)
+ gridOldY = 0;
+ if (gridOldY >= numYBlocks)
+ gridOldY = numYBlocks - 1;
+
+ //Still in same block
+ if (gridX == gridOldX && gridY == gridOldY)
+ return;
+
+ lock (mActorBlock)
+ {
+ mActorBlock[gridOldX, gridOldY].Remove(actor);
+ mActorBlock[gridX, gridY].Add(actor);
+ }
+ }
+
+ public virtual List GetActorsAroundPoint(float x, float y, int checkDistance) where T : Actor
+ {
+ checkDistance /= boundingGridSize;
+
+ int gridX = (int)x / boundingGridSize;
+ int gridY = (int)y / boundingGridSize;
+
+ gridX += halfWidth;
+ gridY += halfHeight;
+
+ //Boundries
+ if (gridX < 0)
+ gridX = 0;
+ if (gridX >= numXBlocks)
+ gridX = numXBlocks - 1;
+ if (gridY < 0)
+ gridY = 0;
+ if (gridY >= numYBlocks)
+ gridY = numYBlocks - 1;
+
+ List result = new List();
+
+ lock (mActorBlock)
+ {
+ for (int gx = gridX - checkDistance; gx <= gridX + checkDistance; gx++)
+ {
+ for (int gy = gridY - checkDistance; gy <= gridY + checkDistance; gy++)
+ {
+ result.AddRange(mActorBlock[gx, gy].OfType());
+ }
+ }
+ }
+
+ //Remove players if isolation zone
+ if (isIsolated)
+ {
+ for (int i = 0; i < result.Count; i++)
+ {
+ if (result[i] is Player)
+ result.RemoveAt(i);
+ }
+ }
+ return result;
+ }
+
+ public virtual List GetActorsAroundPoint(float x, float y, int checkDistance)
+ {
+ return GetActorsAroundPoint(x, y, checkDistance);
+ }
+
+ public virtual List GetActorsAroundActor(Actor actor, int checkDistance)
+ {
+ return GetActorsAroundActor(actor, checkDistance);
+ }
+
+ public virtual List GetActorsAroundActor(Actor actor, int checkDistance) where T : Actor
+ {
+ checkDistance /= boundingGridSize;
+
+ int gridX = (int)actor.positionX / boundingGridSize;
+ int gridY = (int)actor.positionZ / boundingGridSize;
+
+ gridX += halfWidth;
+ gridY += halfHeight;
+
+ //Boundries
+ if (gridX < 0)
+ gridX = 0;
+ if (gridX >= numXBlocks)
+ gridX = numXBlocks - 1;
+ if (gridY < 0)
+ gridY = 0;
+ if (gridY >= numYBlocks)
+ gridY = numYBlocks - 1;
+
+ var result = new List();
+
+ lock (mActorBlock)
+ {
+ for (int gy = ((gridY - checkDistance) < 0 ? 0 : (gridY - checkDistance)); gy <= ((gridY + checkDistance) >= numYBlocks ? numYBlocks - 1 : (gridY + checkDistance)); gy++)
+ {
+ for (int gx = ((gridX - checkDistance) < 0 ? 0 : (gridX - checkDistance)); gx <= ((gridX + checkDistance) >= numXBlocks ? numXBlocks - 1 : (gridX + checkDistance)); gx++)
+ {
+ result.AddRange(mActorBlock[gx, gy].OfType());
+ }
+ }
+ }
+
+ //Remove players if isolation zone
+ if (isIsolated)
+ {
+ for (int i = 0; i < result.Count; i++)
+ {
+ if (result[i] is Player)
+ result.RemoveAt(i);
+ }
+ }
+
+ return result;
+ }
+
+ #endregion
+
+ public Actor FindActorInArea(uint id)
+ {
+ lock (mActorList)
+ {
+ if (!mActorList.ContainsKey(id))
+ return null;
+ return mActorList[id];
+ }
+ }
+
+ public T FindActorInArea(uint id) where T : Actor
+ {
+ return FindActorInArea(id) as T;
+ }
+
+ public Actor FindActorInZoneByUniqueID(string uniqueId)
+ {
+ lock (mActorList)
+ {
+ foreach (Actor a in mActorList.Values)
+ {
+ if (a is Npc)
+ {
+ if (((Npc)a).GetUniqueId().ToLower().Equals(uniqueId))
+ return a;
+ }
+ }
+ }
+ return null;
+ }
+
+ public Player FindPCInZone(string name)
+ {
+ lock (mActorList)
+ {
+ foreach (Player player in mActorList.Values.OfType())
+ {
+ if (player.customDisplayName.ToLower().Equals(name.ToLower()))
+ return player;
+ }
+ return null;
+ }
+ }
+
+ public Player FindPCInZone(uint id)
+ {
+ lock (mActorList)
+ {
+ if (!mActorList.ContainsKey(id))
+ return null;
+ return (Player)mActorList[id];
+ }
+ }
+
+ public void Clear()
+ {
+ lock (mActorList)
+ {
+ //Clear All
+ mActorList.Clear();
+ lock (mActorBlock)
+ {
+ for (int y = 0; y < numYBlocks; y++)
+ {
+ for (int x = 0; x < numXBlocks; x++)
+ {
+ mActorBlock[x, y].Clear();
+ }
+ }
+ }
+ }
+ }
+
+ // todo: for zones override this to search contentareas (assuming flag is passed)
+ public virtual List GetAllActors() where T : Actor
+ {
+ lock (mActorList)
+ {
+ List actorList = new List(mActorList.Count);
+ actorList.AddRange(mActorList.Values.OfType());
+ return actorList;
+ }
+ }
+
+ public int GetActorCount()
+ {
+ lock (mActorList)
+ {
+ return mActorList.Count;
+ }
+ }
+
+ public virtual List GetAllActors()
+ {
+ return GetAllActors();
+ }
+
+ public virtual List GetPlayers()
+ {
+ return GetAllActors();
+ }
+
+ public virtual List GetMonsters()
+ {
+ return GetAllActors();
+ }
+
+ public virtual List GetAllies()
+ {
+ return GetAllActors();
+ }
+
+ public void BroadcastPacketsAroundActor(Actor actor, List packets)
+ {
+ foreach (SubPacket packet in packets)
+ BroadcastPacketAroundActor(actor, packet);
+ }
+
+ public void BroadcastPacketAroundActor(Actor actor, SubPacket packet)
+ {
+ if (isIsolated)
+ return;
+
+ List aroundActor = GetActorsAroundActor(actor, 50);
+ foreach (Actor a in aroundActor)
+ {
+ if (a is Player)
+ {
+ if (isIsolated)
+ continue;
+
+ SubPacket clonedPacket = new SubPacket(packet, a.actorId);
+ Player p = (Player)a;
+ p.QueuePacket(clonedPacket);
+ }
+ }
+ }
+
+ public void SpawnActor(SpawnLocation location)
+ {
+ lock (mActorList)
+ {
+ ActorClass actorClass = Server.GetWorldManager().GetActorClass(location.classId);
+
+ if (actorClass == null)
+ return;
+
+ uint zoneId;
+
+ if (this is PrivateArea)
+ zoneId = ((PrivateArea)this).GetParentZone().actorId;
+ else
+ zoneId = actorId;
+
+ Npc npc = new Npc(mActorList.Count + 1, actorClass, location.uniqueId, this, location.x, location.y, location.z, location.rot, location.state, location.animId, null);
+
+
+ npc.LoadEventConditions(actorClass.eventConditions);
+
+ AddActorToZone(npc);
+ }
+ }
+
+ public Npc SpawnActor(uint classId, string uniqueId, float x, float y, float z, float rot = 0, ushort state = 0, uint animId = 0, bool isMob = false)
+ {
+ lock (mActorList)
+ {
+ ActorClass actorClass = Server.GetWorldManager().GetActorClass(classId);
+
+ if (actorClass == null)
+ return null;
+
+ uint zoneId;
+ if (this is PrivateArea)
+ zoneId = ((PrivateArea)this).GetParentZone().actorId;
+ else
+ zoneId = actorId;
+
+ Npc npc;
+ if (isMob)
+ npc = new BattleNpc(mActorList.Count + 1, actorClass, uniqueId, this, x, y, z, rot, state, animId, null);
+ else
+ npc = new Npc(mActorList.Count + 1, actorClass, uniqueId, this, x, y, z, rot, state, animId, null);
+
+ npc.LoadEventConditions(actorClass.eventConditions);
+ npc.SetMaxHP(100);
+ npc.SetHP(100);
+ npc.ResetMoveSpeeds();
+
+ AddActorToZone(npc);
+
+ return npc;
+ }
+ }
+
+ public Npc SpawnActor(uint classId, string uniqueId, float x, float y, float z, uint regionId, uint layoutId)
+ {
+ lock (mActorList)
+ {
+ ActorClass actorClass = Server.GetWorldManager().GetActorClass(classId);
+
+ if (actorClass == null)
+ return null;
+
+ uint zoneId;
+
+ if (this is PrivateArea)
+ zoneId = ((PrivateArea)this).GetParentZone().actorId;
+ else
+ zoneId = actorId;
+
+ Npc npc = new Npc(mActorList.Count + 1, actorClass, uniqueId, this, x, y, z, 0, regionId, layoutId);
+
+ npc.LoadEventConditions(actorClass.eventConditions);
+
+ AddActorToZone(npc);
+
+ return npc;
+ }
+ }
+
+ public BattleNpc GetBattleNpcById(uint id)
+ {
+ foreach (var bnpc in GetAllActors())
+ {
+ if (bnpc.GetBattleNpcId() == id)
+ return bnpc;
+ }
+ return null;
+ }
+
+ public void DespawnActor(string uniqueId)
+ {
+ RemoveActorFromZone(FindActorInZoneByUniqueID(uniqueId));
+ }
+
+ public void DespawnActor(Actor actor)
+ {
+ RemoveActorFromZone(actor);
+ }
+
+ public Director GetWeatherDirector()
+ {
+ return mWeatherDirector;
+ }
+
+ public void ChangeWeather(ushort weather, ushort transitionTime, Player player, bool zoneWide = false)
+ {
+ weatherNormal = weather;
+
+ if (player != null && !zoneWide)
+ {
+ player.QueuePacket(SetWeatherPacket.BuildPacket(player.actorId, weather, transitionTime));
+ }
+ if (zoneWide)
+ {
+ lock (mActorList)
+ {
+ foreach (var actor in mActorList)
+ {
+ if (actor.Value is Player)
+ {
+ player = ((Player)actor.Value);
+ player.QueuePacket(SetWeatherPacket.BuildPacket(player.actorId, weather, transitionTime));
+ }
+ }
+ }
+ }
+ }
+
+ public Director CreateDirector(string path, bool hasContentGroup, params object[] args)
+ {
+ lock (directorLock)
+ {
+ Director director = new Director(directorIdCount, this, path, hasContentGroup, args);
+ currentDirectors.Add(director.actorId, director);
+ directorIdCount++;
+ return director;
+ }
+ }
+
+ public Director CreateGuildleveDirector(uint glid, byte difficulty, Player owner, params object[] args)
+ {
+ String directorScriptPath = "";
+
+ uint type = Server.GetGuildleveGamedata(glid).plateId;
+
+ if (glid == 10801 || glid == 12401 || glid == 11601)
+ directorScriptPath = "Guildleve/PrivateGLBattleTutorial";
+ else
+ {
+ switch (type)
+ {
+ case 20021:
+ directorScriptPath = "Guildleve/PrivateGLBattleSweepNormal";
+ break;
+ case 20022:
+ directorScriptPath = "Guildleve/PrivateGLBattleChaseNormal";
+ break;
+ case 20023:
+ directorScriptPath = "Guildleve/PrivateGLBattleOrbNormal";
+ break;
+ case 20024:
+ directorScriptPath = "Guildleve/PrivateGLBattleHuntNormal";
+ break;
+ case 20025:
+ directorScriptPath = "Guildleve/PrivateGLBattleGatherNormal";
+ break;
+ case 20026:
+ directorScriptPath = "Guildleve/PrivateGLBattleRoundNormal";
+ break;
+ case 20027:
+ directorScriptPath = "Guildleve/PrivateGLBattleSurviveNormal";
+ break;
+ case 20028:
+ directorScriptPath = "Guildleve/PrivateGLBattleDetectNormal";
+ break;
+ }
+ }
+
+ lock (directorLock)
+ {
+ GuildleveDirector director = new GuildleveDirector(directorIdCount, this, directorScriptPath, glid, difficulty, owner, args);
+ currentDirectors.Add(director.actorId, director);
+ directorIdCount++;
+ return director;
+ }
+ }
+
+ public void DeleteDirector(uint id)
+ {
+ lock (directorLock)
+ {
+ if (currentDirectors.ContainsKey(id))
+ {
+ if (!currentDirectors[id].IsDeleted())
+ currentDirectors[id].EndDirector();
+ currentDirectors.Remove(id);
+ }
+ }
+ }
+
+ public Director GetDirectorById(uint id)
+ {
+ if (currentDirectors.ContainsKey(id))
+ return currentDirectors[id];
+ return null;
+ }
+
+ public override void Update(DateTime tick)
+ {
+ lock (mActorList)
+ {
+ foreach (Actor a in mActorList.Values.ToList())
+ a.Update(tick);
+
+ if ((tick - lastUpdateScript).TotalMilliseconds > 1500)
+ {
+ //LuaEngine.GetInstance().CallLuaFunctionForReturn(LuaEngine.GetScriptPath(this), "onUpdate", true, this, tick);
+ lastUpdateScript = tick;
+ }
+ }
+ }
+
+ }
+}
diff --git a/FFXIVClassic Map Server/actors/area/PrivateArea.cs b/Map Server/actors/area/PrivateArea.cs
similarity index 99%
rename from FFXIVClassic Map Server/actors/area/PrivateArea.cs
rename to Map Server/actors/area/PrivateArea.cs
index 1ae09c70..bc44886c 100644
--- a/FFXIVClassic Map Server/actors/area/PrivateArea.cs
+++ b/Map Server/actors/area/PrivateArea.cs
@@ -20,7 +20,7 @@ along with Project Meteor Server. If not, see .
*/
-using FFXIVClassic.Common;
+using Meteor.Common;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
diff --git a/FFXIVClassic Map Server/actors/area/PrivateAreaContent.cs b/Map Server/actors/area/PrivateAreaContent.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/area/PrivateAreaContent.cs
rename to Map Server/actors/area/PrivateAreaContent.cs
diff --git a/FFXIVClassic Map Server/actors/area/SpawnLocation.cs b/Map Server/actors/area/SpawnLocation.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/area/SpawnLocation.cs
rename to Map Server/actors/area/SpawnLocation.cs
diff --git a/FFXIVClassic Map Server/actors/area/Zone.cs b/Map Server/actors/area/Zone.cs
similarity index 99%
rename from FFXIVClassic Map Server/actors/area/Zone.cs
rename to Map Server/actors/area/Zone.cs
index 547cbf73..fd7ca0fa 100644
--- a/FFXIVClassic Map Server/actors/area/Zone.cs
+++ b/Map Server/actors/area/Zone.cs
@@ -19,7 +19,7 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-using FFXIVClassic.Common;
+using Meteor.Common;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
diff --git a/FFXIVClassic Map Server/actors/chara/AetheryteWork.cs b/Map Server/actors/chara/AetheryteWork.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/AetheryteWork.cs
rename to Map Server/actors/chara/AetheryteWork.cs
diff --git a/FFXIVClassic Map Server/actors/chara/BattleSave.cs b/Map Server/actors/chara/BattleSave.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/BattleSave.cs
rename to Map Server/actors/chara/BattleSave.cs
diff --git a/FFXIVClassic Map Server/actors/chara/BattleTemp.cs b/Map Server/actors/chara/BattleTemp.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/BattleTemp.cs
rename to Map Server/actors/chara/BattleTemp.cs
diff --git a/FFXIVClassic Map Server/actors/chara/CharaWork.cs b/Map Server/actors/chara/CharaWork.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/CharaWork.cs
rename to Map Server/actors/chara/CharaWork.cs
diff --git a/FFXIVClassic Map Server/actors/chara/Character.cs b/Map Server/actors/chara/Character.cs
similarity index 99%
rename from FFXIVClassic Map Server/actors/chara/Character.cs
rename to Map Server/actors/chara/Character.cs
index 7866c74c..107f697e 100644
--- a/FFXIVClassic Map Server/actors/chara/Character.cs
+++ b/Map Server/actors/chara/Character.cs
@@ -20,7 +20,7 @@ along with Project Meteor Server. If not, see .
*/
-using FFXIVClassic.Common;
+using Meteor.Common;
using FFXIVClassic_Map_Server.actors.chara.player;
using FFXIVClassic_Map_Server.actors.group;
using FFXIVClassic_Map_Server.Actors.Chara;
diff --git a/FFXIVClassic Map Server/actors/chara/EventSave.cs b/Map Server/actors/chara/EventSave.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/EventSave.cs
rename to Map Server/actors/chara/EventSave.cs
diff --git a/FFXIVClassic Map Server/actors/chara/EventTemp.cs b/Map Server/actors/chara/EventTemp.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/EventTemp.cs
rename to Map Server/actors/chara/EventTemp.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ItemPackage.cs b/Map Server/actors/chara/ItemPackage.cs
similarity index 99%
rename from FFXIVClassic Map Server/actors/chara/ItemPackage.cs
rename to Map Server/actors/chara/ItemPackage.cs
index db630ce9..ce692cfd 100644
--- a/FFXIVClassic Map Server/actors/chara/ItemPackage.cs
+++ b/Map Server/actors/chara/ItemPackage.cs
@@ -19,7 +19,7 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-using FFXIVClassic.Common;
+using Meteor.Common;
using FFXIVClassic_Map_Server.actors.chara.npc;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.dataobjects;
diff --git a/FFXIVClassic Map Server/actors/chara/Modifier.cs b/Map Server/actors/chara/Modifier.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/Modifier.cs
rename to Map Server/actors/chara/Modifier.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ModifierList.cs b/Map Server/actors/chara/ModifierList.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/ModifierList.cs
rename to Map Server/actors/chara/ModifierList.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ParameterSave.cs b/Map Server/actors/chara/ParameterSave.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/ParameterSave.cs
rename to Map Server/actors/chara/ParameterSave.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ParameterTemp.cs b/Map Server/actors/chara/ParameterTemp.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/ParameterTemp.cs
rename to Map Server/actors/chara/ParameterTemp.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ReferencedItemPackage.cs b/Map Server/actors/chara/ReferencedItemPackage.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/ReferencedItemPackage.cs
rename to Map Server/actors/chara/ReferencedItemPackage.cs
diff --git a/FFXIVClassic Map Server/actors/chara/SubState.cs b/Map Server/actors/chara/SubState.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/SubState.cs
rename to Map Server/actors/chara/SubState.cs
diff --git a/FFXIVClassic Map Server/actors/chara/Work.cs b/Map Server/actors/chara/Work.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/Work.cs
rename to Map Server/actors/chara/Work.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ai/AIContainer.cs b/Map Server/actors/chara/ai/AIContainer.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/ai/AIContainer.cs
rename to Map Server/actors/chara/ai/AIContainer.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ai/BattleCommand.cs b/Map Server/actors/chara/ai/BattleCommand.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/ai/BattleCommand.cs
rename to Map Server/actors/chara/ai/BattleCommand.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ai/BattleTrait.cs b/Map Server/actors/chara/ai/BattleTrait.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/ai/BattleTrait.cs
rename to Map Server/actors/chara/ai/BattleTrait.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ai/HateContainer.cs b/Map Server/actors/chara/ai/HateContainer.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/ai/HateContainer.cs
rename to Map Server/actors/chara/ai/HateContainer.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ai/StatusEffect.cs b/Map Server/actors/chara/ai/StatusEffect.cs
similarity index 99%
rename from FFXIVClassic Map Server/actors/chara/ai/StatusEffect.cs
rename to Map Server/actors/chara/ai/StatusEffect.cs
index 4bfecc0c..4b8cf39d 100644
--- a/FFXIVClassic Map Server/actors/chara/ai/StatusEffect.cs
+++ b/Map Server/actors/chara/ai/StatusEffect.cs
@@ -24,7 +24,7 @@ using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor.battle;
using System;
using MoonSharp.Interpreter;
-using FFXIVClassic.Common;
+using Meteor.Common;
namespace FFXIVClassic_Map_Server.actors.chara.ai
{
diff --git a/FFXIVClassic Map Server/actors/chara/ai/StatusEffectContainer.cs b/Map Server/actors/chara/ai/StatusEffectContainer.cs
similarity index 99%
rename from FFXIVClassic Map Server/actors/chara/ai/StatusEffectContainer.cs
rename to Map Server/actors/chara/ai/StatusEffectContainer.cs
index 2822b733..7195686f 100644
--- a/FFXIVClassic Map Server/actors/chara/ai/StatusEffectContainer.cs
+++ b/Map Server/actors/chara/ai/StatusEffectContainer.cs
@@ -22,7 +22,7 @@ along with Project Meteor Server. If not, see .
using System;
using System.Collections.Generic;
using System.Linq;
-using FFXIVClassic.Common;
+using Meteor.Common;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
diff --git a/FFXIVClassic Map Server/actors/chara/ai/controllers/AllyController.cs b/Map Server/actors/chara/ai/controllers/AllyController.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/ai/controllers/AllyController.cs
rename to Map Server/actors/chara/ai/controllers/AllyController.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ai/controllers/BattleNpcController.cs b/Map Server/actors/chara/ai/controllers/BattleNpcController.cs
similarity index 99%
rename from FFXIVClassic Map Server/actors/chara/ai/controllers/BattleNpcController.cs
rename to Map Server/actors/chara/ai/controllers/BattleNpcController.cs
index 61465457..81c9fb04 100644
--- a/FFXIVClassic Map Server/actors/chara/ai/controllers/BattleNpcController.cs
+++ b/Map Server/actors/chara/ai/controllers/BattleNpcController.cs
@@ -21,7 +21,7 @@ along with Project Meteor Server. If not, see .
using System;
using System.Collections.Generic;
-using FFXIVClassic.Common;
+using Meteor.Common;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server.actors.area;
diff --git a/FFXIVClassic Map Server/actors/chara/ai/controllers/Controller.cs b/Map Server/actors/chara/ai/controllers/Controller.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/ai/controllers/Controller.cs
rename to Map Server/actors/chara/ai/controllers/Controller.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ai/controllers/PetController.cs b/Map Server/actors/chara/ai/controllers/PetController.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/ai/controllers/PetController.cs
rename to Map Server/actors/chara/ai/controllers/PetController.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ai/controllers/PlayerController.cs b/Map Server/actors/chara/ai/controllers/PlayerController.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/ai/controllers/PlayerController.cs
rename to Map Server/actors/chara/ai/controllers/PlayerController.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ai/helpers/ActionQueue.cs b/Map Server/actors/chara/ai/helpers/ActionQueue.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/ai/helpers/ActionQueue.cs
rename to Map Server/actors/chara/ai/helpers/ActionQueue.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ai/helpers/PathFind.cs b/Map Server/actors/chara/ai/helpers/PathFind.cs
similarity index 99%
rename from FFXIVClassic Map Server/actors/chara/ai/helpers/PathFind.cs
rename to Map Server/actors/chara/ai/helpers/PathFind.cs
index d52ed2ba..e5d742e2 100644
--- a/FFXIVClassic Map Server/actors/chara/ai/helpers/PathFind.cs
+++ b/Map Server/actors/chara/ai/helpers/PathFind.cs
@@ -23,7 +23,7 @@ using System;
using System.Collections.Generic;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.utils;
-using FFXIVClassic.Common;
+using Meteor.Common;
using FFXIVClassic_Map_Server.actors.area;
// port of https://github.com/DarkstarProject/darkstar/blob/master/src/map/ai/helpers/pathfind.h
diff --git a/FFXIVClassic Map Server/actors/chara/ai/helpers/TargetFind.cs b/Map Server/actors/chara/ai/helpers/TargetFind.cs
similarity index 99%
rename from FFXIVClassic Map Server/actors/chara/ai/helpers/TargetFind.cs
rename to Map Server/actors/chara/ai/helpers/TargetFind.cs
index bede5a8a..3064b71f 100644
--- a/FFXIVClassic Map Server/actors/chara/ai/helpers/TargetFind.cs
+++ b/Map Server/actors/chara/ai/helpers/TargetFind.cs
@@ -23,7 +23,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using FFXIVClassic_Map_Server.Actors;
-using FFXIVClassic.Common;
+using Meteor.Common;
using FFXIVClassic_Map_Server.actors.chara.ai.controllers;
using FFXIVClassic_Map_Server.actors.group;
diff --git a/FFXIVClassic Map Server/actors/chara/ai/state/AbilityState.cs b/Map Server/actors/chara/ai/state/AbilityState.cs
similarity index 99%
rename from FFXIVClassic Map Server/actors/chara/ai/state/AbilityState.cs
rename to Map Server/actors/chara/ai/state/AbilityState.cs
index 9c30a7f2..b2f68b03 100644
--- a/FFXIVClassic Map Server/actors/chara/ai/state/AbilityState.cs
+++ b/Map Server/actors/chara/ai/state/AbilityState.cs
@@ -20,7 +20,7 @@ along with Project Meteor Server. If not, see .
*/
using System;
-using FFXIVClassic.Common;
+using Meteor.Common;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.packets.send.actor.battle;
diff --git a/FFXIVClassic Map Server/actors/chara/ai/state/AttackState.cs b/Map Server/actors/chara/ai/state/AttackState.cs
similarity index 99%
rename from FFXIVClassic Map Server/actors/chara/ai/state/AttackState.cs
rename to Map Server/actors/chara/ai/state/AttackState.cs
index fc19f1c8..0081a5dd 100644
--- a/FFXIVClassic Map Server/actors/chara/ai/state/AttackState.cs
+++ b/Map Server/actors/chara/ai/state/AttackState.cs
@@ -20,7 +20,7 @@ along with Project Meteor Server. If not, see .
*/
using System;
-using FFXIVClassic.Common;
+using Meteor.Common;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server.packets.send.actor.battle;
diff --git a/FFXIVClassic Map Server/actors/chara/ai/state/DeathState.cs b/Map Server/actors/chara/ai/state/DeathState.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/ai/state/DeathState.cs
rename to Map Server/actors/chara/ai/state/DeathState.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ai/state/DespawnState.cs b/Map Server/actors/chara/ai/state/DespawnState.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/ai/state/DespawnState.cs
rename to Map Server/actors/chara/ai/state/DespawnState.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ai/state/InactiveState.cs b/Map Server/actors/chara/ai/state/InactiveState.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/ai/state/InactiveState.cs
rename to Map Server/actors/chara/ai/state/InactiveState.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ai/state/ItemState.cs b/Map Server/actors/chara/ai/state/ItemState.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/ai/state/ItemState.cs
rename to Map Server/actors/chara/ai/state/ItemState.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ai/state/MagicState.cs b/Map Server/actors/chara/ai/state/MagicState.cs
similarity index 99%
rename from FFXIVClassic Map Server/actors/chara/ai/state/MagicState.cs
rename to Map Server/actors/chara/ai/state/MagicState.cs
index 4bdd79d1..9fa4dc40 100644
--- a/FFXIVClassic Map Server/actors/chara/ai/state/MagicState.cs
+++ b/Map Server/actors/chara/ai/state/MagicState.cs
@@ -21,7 +21,7 @@ along with Project Meteor Server. If not, see .
using System;
using System.Collections.Generic;
-using FFXIVClassic.Common;
+using Meteor.Common;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.packets.send.actor.battle;
diff --git a/FFXIVClassic Map Server/actors/chara/ai/state/State.cs b/Map Server/actors/chara/ai/state/State.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/ai/state/State.cs
rename to Map Server/actors/chara/ai/state/State.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ai/state/WeaponSkillState.cs b/Map Server/actors/chara/ai/state/WeaponSkillState.cs
similarity index 99%
rename from FFXIVClassic Map Server/actors/chara/ai/state/WeaponSkillState.cs
rename to Map Server/actors/chara/ai/state/WeaponSkillState.cs
index 1e0a82e9..752542b0 100644
--- a/FFXIVClassic Map Server/actors/chara/ai/state/WeaponSkillState.cs
+++ b/Map Server/actors/chara/ai/state/WeaponSkillState.cs
@@ -20,7 +20,7 @@ along with Project Meteor Server. If not, see .
*/
using System;
-using FFXIVClassic.Common;
+using Meteor.Common;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.packets.send.actor.battle;
diff --git a/FFXIVClassic Map Server/actors/chara/ai/utils/AttackUtils.cs b/Map Server/actors/chara/ai/utils/AttackUtils.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/ai/utils/AttackUtils.cs
rename to Map Server/actors/chara/ai/utils/AttackUtils.cs
diff --git a/FFXIVClassic Map Server/actors/chara/ai/utils/BattleUtils.cs b/Map Server/actors/chara/ai/utils/BattleUtils.cs
similarity index 99%
rename from FFXIVClassic Map Server/actors/chara/ai/utils/BattleUtils.cs
rename to Map Server/actors/chara/ai/utils/BattleUtils.cs
index f2841673..5776dd8b 100644
--- a/FFXIVClassic Map Server/actors/chara/ai/utils/BattleUtils.cs
+++ b/Map Server/actors/chara/ai/utils/BattleUtils.cs
@@ -26,7 +26,7 @@ using System.Linq;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.packets.send.actor.battle;
using FFXIVClassic_Map_Server.actors.chara.npc;
-using FFXIVClassic.Common;
+using Meteor.Common;
namespace FFXIVClassic_Map_Server.actors.chara.ai.utils
{
diff --git a/FFXIVClassic Map Server/actors/chara/npc/ActorClass.cs b/Map Server/actors/chara/npc/ActorClass.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/npc/ActorClass.cs
rename to Map Server/actors/chara/npc/ActorClass.cs
diff --git a/FFXIVClassic Map Server/actors/chara/npc/Ally.cs b/Map Server/actors/chara/npc/Ally.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/npc/Ally.cs
rename to Map Server/actors/chara/npc/Ally.cs
diff --git a/FFXIVClassic Map Server/actors/chara/npc/BattleNpc.cs b/Map Server/actors/chara/npc/BattleNpc.cs
similarity index 99%
rename from FFXIVClassic Map Server/actors/chara/npc/BattleNpc.cs
rename to Map Server/actors/chara/npc/BattleNpc.cs
index e78de87e..937de90e 100644
--- a/FFXIVClassic Map Server/actors/chara/npc/BattleNpc.cs
+++ b/Map Server/actors/chara/npc/BattleNpc.cs
@@ -21,7 +21,7 @@ along with Project Meteor Server. If not, see .
using System;
using System.Collections.Generic;
-using FFXIVClassic.Common;
+using Meteor.Common;
using FFXIVClassic_Map_Server.actors.chara.npc;
using FFXIVClassic_Map_Server.actors.chara;
using FFXIVClassic_Map_Server.actors.chara.ai;
diff --git a/FFXIVClassic Map Server/actors/chara/npc/MobModifier.cs b/Map Server/actors/chara/npc/MobModifier.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/npc/MobModifier.cs
rename to Map Server/actors/chara/npc/MobModifier.cs
diff --git a/FFXIVClassic Map Server/actors/chara/npc/Npc.cs b/Map Server/actors/chara/npc/Npc.cs
similarity index 99%
rename from FFXIVClassic Map Server/actors/chara/npc/Npc.cs
rename to Map Server/actors/chara/npc/Npc.cs
index 4d41d997..e0bc30f6 100644
--- a/FFXIVClassic Map Server/actors/chara/npc/Npc.cs
+++ b/Map Server/actors/chara/npc/Npc.cs
@@ -19,7 +19,7 @@ along with Project Meteor Server. If not, see .
===========================================================================
*/
-using FFXIVClassic.Common;
+using Meteor.Common;
using FFXIVClassic_Map_Server.actors;
using FFXIVClassic_Map_Server.actors.chara.npc;
using FFXIVClassic_Map_Server.Actors.Chara;
diff --git a/FFXIVClassic Map Server/actors/chara/npc/NpcWork.cs b/Map Server/actors/chara/npc/NpcWork.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/npc/NpcWork.cs
rename to Map Server/actors/chara/npc/NpcWork.cs
diff --git a/FFXIVClassic Map Server/actors/chara/npc/Pet.cs b/Map Server/actors/chara/npc/Pet.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/npc/Pet.cs
rename to Map Server/actors/chara/npc/Pet.cs
diff --git a/FFXIVClassic Map Server/actors/chara/npc/Retainer.cs b/Map Server/actors/chara/npc/Retainer.cs
similarity index 100%
rename from FFXIVClassic Map Server/actors/chara/npc/Retainer.cs
rename to Map Server/actors/chara/npc/Retainer.cs
diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/Map Server/actors/chara/player/Player.cs
similarity index 97%
rename from FFXIVClassic Map Server/actors/chara/player/Player.cs
rename to Map Server/actors/chara/player/Player.cs
index 0f64f881..0f26bb43 100644
--- a/FFXIVClassic Map Server/actors/chara/player/Player.cs
+++ b/Map Server/actors/chara/player/Player.cs
@@ -1,2816 +1,2816 @@
-/*
-===========================================================================
-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 .
-===========================================================================
-*/
-
-using FFXIVClassic.Common;
-using System;
-using System.Collections.Generic;
-using MoonSharp.Interpreter;
-using FFXIVClassic_Map_Server.dataobjects;
-using FFXIVClassic_Map_Server.dataobjects.chara;
-using FFXIVClassic_Map_Server.lua;
-using FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group;
-using FFXIVClassic_Map_Server.utils;
-using FFXIVClassic_Map_Server.actors.group;
-using FFXIVClassic_Map_Server.actors.chara.player;
-using FFXIVClassic_Map_Server.actors.director;
-using FFXIVClassic_Map_Server.actors.chara.npc;
-using FFXIVClassic_Map_Server.actors.chara.ai;
-using FFXIVClassic_Map_Server.actors.chara.ai.controllers;
-using FFXIVClassic_Map_Server.actors.chara.ai.utils;
-using FFXIVClassic_Map_Server.actors.chara.ai.state;
-using FFXIVClassic_Map_Server.actors.chara;
-using FFXIVClassic_Map_Server.packets.send;
-using FFXIVClassic_Map_Server.packets.send.actor;
-using FFXIVClassic_Map_Server.packets.send.events;
-using FFXIVClassic_Map_Server.packets.send.actor.inventory;
-using FFXIVClassic_Map_Server.packets.send.player;
-using FFXIVClassic_Map_Server.packets.send.actor.battle;
-using FFXIVClassic_Map_Server.packets.receive.events;
-using static FFXIVClassic_Map_Server.LuaUtils;
-
-namespace FFXIVClassic_Map_Server.Actors
-{
- class Player : Character
- {
- public const int TIMER_TOTORAK = 0;
- public const int TIMER_DZEMAEL = 1;
- public const int TIMER_BOWL_OF_EMBERS_HARD = 2;
- public const int TIMER_BOWL_OF_EMBERS = 3;
- public const int TIMER_THORNMARCH = 4;
- public const int TIMER_AURUMVALE = 5;
- public const int TIMER_CUTTERSCRY = 6;
- public const int TIMER_BATTLE_ALEPORT = 7;
- public const int TIMER_BATTLE_HYRSTMILL = 8;
- public const int TIMER_BATTLE_GOLDENBAZAAR = 9;
- public const int TIMER_HOWLING_EYE_HARD = 10;
- public const int TIMER_HOWLING_EYE = 11;
- public const int TIMER_CASTRUM_TOWER = 12;
- public const int TIMER_BOWL_OF_EMBERS_EXTREME = 13;
- public const int TIMER_RIVENROAD = 14;
- public const int TIMER_RIVENROAD_HARD = 15;
- public const int TIMER_BEHEST = 16;
- public const int TIMER_COMPANYBEHEST = 17;
- public const int TIMER_RETURN = 18;
- public const int TIMER_SKIRMISH = 19;
-
- public const int NPCLS_GONE = 0;
- public const int NPCLS_INACTIVE = 1;
- public const int NPCLS_ACTIVE = 2;
- public const int NPCLS_ALERT = 3;
-
- public const int SLOT_MAINHAND = 0;
- public const int SLOT_OFFHAND = 1;
- public const int SLOT_THROWINGWEAPON = 4;
- public const int SLOT_PACK = 5;
- public const int SLOT_POUCH = 6;
- public const int SLOT_HEAD = 8;
- public const int SLOT_UNDERSHIRT = 9;
- public const int SLOT_BODY = 10;
- public const int SLOT_UNDERGARMENT = 11;
- public const int SLOT_LEGS = 12;
- public const int SLOT_HANDS = 13;
- public const int SLOT_BOOTS = 14;
- public const int SLOT_WAIST = 15;
- public const int SLOT_NECK = 16;
- public const int SLOT_EARS = 17;
- public const int SLOT_WRISTS = 19;
- public const int SLOT_RIGHTFINGER = 21;
- public const int SLOT_LEFTFINGER = 22;
-
- public static int[] MAXEXP = {570, 700, 880, 1100, 1500, 1800, 2300, 3200, 4300, 5000, //Level <= 10
- 5900, 6800, 7700, 8700, 9700, 11000, 12000, 13000, 15000, 16000, //Level <= 20
- 20000, 22000, 23000, 25000, 27000, 29000, 31000, 33000, 35000, 38000, //Level <= 30
- 45000, 47000, 50000, 53000, 56000, 59000, 62000, 65000, 68000, 71000, //Level <= 40
- 74000, 78000, 81000, 85000, 89000, 92000, 96000, 100000, 100000, 110000}; //Level <= 50
-
- //Event Related
- public uint currentEventOwner = 0;
- public string currentEventName = "";
- public Coroutine currentEventRunning;
-
- //Player Info
- public uint destinationZone;
- public ushort destinationSpawnType;
- public uint[] timers = new uint[20];
- public uint currentTitle;
- public uint playTime;
- public uint lastPlayTimeUpdate;
- public bool isGM = false;
- public bool isZoneChanging = true;
-
- //Trading
- private Player otherTrader = null;
- private ReferencedItemPackage myOfferings;
- private bool isTradeAccepted = false;
-
- //GC Related
- public byte gcCurrent;
- public byte gcRankLimsa;
- public byte gcRankGridania;
- public byte gcRankUldah;
-
- //Mount Related
- public bool hasChocobo;
- public bool hasGoobbue;
- public byte chocoboAppearance;
- public string chocoboName;
- public byte mountState = 0;
-
- public uint achievementPoints;
-
- //Property Array Request Stuff
- private int lastPosition = 0;
- private int lastStep = 0;
-
- //Quest Actors (MUST MATCH playerWork.questScenario/questGuildleve)
- public Quest[] questScenario = new Quest[16];
- public uint[] questGuildleve = new uint[8];
-
- //Aetheryte
- public uint homepoint = 0;
- public byte homepointInn = 0;
-
- //Nameplate Stuff
- public uint currentLSPlate = 0;
- public byte repairType = 0;
-
- //Retainer
- RetainerMeetingRelationGroup retainerMeetingGroup = null;
- public Retainer currentSpawnedRetainer = null;
- public bool sentRetainerSpawn = false;
-
- private List ownedDirectors = new List();
- private Director loginInitDirector = null;
-
- List hotbarSlotsToUpdate = new List();
-
- public PlayerWork playerWork = new PlayerWork();
-
- public Session playerSession;
-
- public Player(Session cp, uint actorID) : base(actorID)
- {
- playerSession = cp;
- actorName = String.Format("_pc{0:00000000}", actorID);
- className = "Player";
-
- moveSpeeds[0] = SetActorSpeedPacket.DEFAULT_STOP;
- moveSpeeds[1] = SetActorSpeedPacket.DEFAULT_WALK;
- moveSpeeds[2] = SetActorSpeedPacket.DEFAULT_RUN;
- moveSpeeds[3] = SetActorSpeedPacket.DEFAULT_ACTIVE;
-
- itemPackages[ItemPackage.NORMAL] = new ItemPackage(this, ItemPackage.MAXSIZE_NORMAL, ItemPackage.NORMAL);
- itemPackages[ItemPackage.KEYITEMS] = new ItemPackage(this, ItemPackage.MAXSIZE_KEYITEMS, ItemPackage.KEYITEMS);
- itemPackages[ItemPackage.CURRENCY_CRYSTALS] = new ItemPackage(this, ItemPackage.MAXSIZE_CURRANCY, ItemPackage.CURRENCY_CRYSTALS);
- itemPackages[ItemPackage.MELDREQUEST] = new ItemPackage(this, ItemPackage.MAXSIZE_MELDREQUEST, ItemPackage.MELDREQUEST);
- itemPackages[ItemPackage.BAZAAR] = new ItemPackage(this, ItemPackage.MAXSIZE_BAZAAR, ItemPackage.BAZAAR);
- itemPackages[ItemPackage.LOOT] = new ItemPackage(this, ItemPackage.MAXSIZE_LOOT, ItemPackage.LOOT);
- equipment = new ReferencedItemPackage(this, ItemPackage.MAXSIZE_EQUIPMENT, ItemPackage.EQUIPMENT);
-
- //Set the Skill level caps of all FFXIV (classes)skills to 50
- for (int i = 0; i < charaWork.battleSave.skillLevelCap.Length; i++)
- {
- if (i != CLASSID_PUG &&
- i != CLASSID_MRD &&
- i != CLASSID_GLA &&
- i != CLASSID_MRD &&
- i != CLASSID_ARC &&
- i != CLASSID_LNC &&
- i != CLASSID_THM &&
- i != CLASSID_CNJ &&
- i != CLASSID_CRP &&
- i != CLASSID_BSM &&
- i != CLASSID_ARM &&
- i != CLASSID_GSM &&
- i != CLASSID_LTW &&
- i != CLASSID_WVR &&
- i != CLASSID_ALC &&
- i != CLASSID_CUL &&
- i != CLASSID_MIN &&
- i != CLASSID_BTN &&
- i != CLASSID_FSH)
- charaWork.battleSave.skillLevelCap[i] = 0xFF;
- else
- charaWork.battleSave.skillLevelCap[i] = 50;
-
- }
-
- charaWork.property[0] = 1;
- charaWork.property[1] = 1;
- charaWork.property[2] = 1;
- charaWork.property[4] = 1;
-
- charaWork.command[0] = 0xA0F00000 | 21001;
- charaWork.command[1] = 0xA0F00000 | 21001;
-
- charaWork.command[2] = 0xA0F00000 | 21002;
- charaWork.command[3] = 0xA0F00000 | 12004;
- charaWork.command[4] = 0xA0F00000 | 21005;
- charaWork.command[5] = 0xA0F00000 | 21006;
- charaWork.command[6] = 0xA0F00000 | 21007;
- charaWork.command[7] = 0xA0F00000 | 12009;
- charaWork.command[8] = 0xA0F00000 | 12010;
- charaWork.command[9] = 0xA0F00000 | 12005;
- charaWork.command[10] = 0xA0F00000 | 12007;
- charaWork.command[11] = 0xA0F00000 | 12011;
- charaWork.command[12] = 0xA0F00000 | 22012;
- charaWork.command[13] = 0xA0F00000 | 22013;
- charaWork.command[14] = 0xA0F00000 | 29497;
- charaWork.command[15] = 0xA0F00000 | 22015;
-
- charaWork.commandAcquired[27150 - 26000] = true;
-
- playerWork.questScenarioComplete[110001 - 110001] = true;
- playerWork.questGuildleveComplete[120050 - 120001] = true;
-
- for (int i = 0; i < charaWork.additionalCommandAcquired.Length; i++ )
- charaWork.additionalCommandAcquired[i] = true;
-
- for (int i = 0; i < charaWork.commandCategory.Length; i++)
- charaWork.commandCategory[i] = 1;
-
- charaWork.battleTemp.generalParameter[3] = 1;
-
- charaWork.eventSave.bazaarTax = 5;
- charaWork.battleSave.potencial = 6.6f;
-
- charaWork.battleSave.negotiationFlag[0] = true;
-
- charaWork.commandCategory[0] = 1;
- charaWork.commandCategory[1] = 1;
-
- charaWork.parameterSave.commandSlot_compatibility[0] = true;
- charaWork.parameterSave.commandSlot_compatibility[1] = true;
-
- charaWork.commandBorder = 0x20;
-
- charaWork.parameterTemp.tp = 0;
-
- Database.LoadPlayerCharacter(this);
- lastPlayTimeUpdate = Utils.UnixTimeStampUTC();
-
- this.aiContainer = new AIContainer(this, new PlayerController(this), null, new TargetFind(this));
- allegiance = CharacterTargetingAllegiance.Player;
- CalculateBaseStats();
- }
-
- public List Create0x132Packets()
- {
- List packets = new List();
- packets.Add(_0x132Packet.BuildPacket(actorId, 0xB, "commandForced"));
- packets.Add(_0x132Packet.BuildPacket(actorId, 0xA, "commandDefault"));
- packets.Add(_0x132Packet.BuildPacket(actorId, 0x6, "commandWeak"));
- packets.Add(_0x132Packet.BuildPacket(actorId, 0x4, "commandContent"));
- packets.Add(_0x132Packet.BuildPacket(actorId, 0x6, "commandJudgeMode"));
- packets.Add(_0x132Packet.BuildPacket(actorId, 0x100, "commandRequest"));
- packets.Add(_0x132Packet.BuildPacket(actorId, 0x100, "widgetCreate"));
- packets.Add(_0x132Packet.BuildPacket(actorId, 0x100, "macroRequest"));
- return packets;
- }
-
- /*
- * PLAYER ARGS:
- * Unknown - Bool
- * Unknown - Bool
- * Is Init Director - Bool
- * Unknown - Bool
- * Unknown - Number
- * Unknown - Bool
- * Timer Array - 20 Number
- */
-
- public override SubPacket CreateScriptBindPacket(Player requestPlayer)
- {
- List lParams;
- if (IsMyPlayer(requestPlayer.actorId))
- {
- if (loginInitDirector != null)
- lParams = LuaUtils.CreateLuaParamList("/Chara/Player/Player_work", false, false, true, loginInitDirector, true, 0, false, timers, true);
- else
- lParams = LuaUtils.CreateLuaParamList("/Chara/Player/Player_work", true, false, false, true, 0, false, timers, true);
- }
- else
- lParams = LuaUtils.CreateLuaParamList("/Chara/Player/Player_work", false, false, false, false, false, true);
-
- ActorInstantiatePacket.BuildPacket(actorId, actorName, className, lParams).DebugPrintSubPacket();
-
-
- return ActorInstantiatePacket.BuildPacket(actorId, actorName, className, lParams);
- }
-
- public override List GetSpawnPackets(Player requestPlayer, ushort spawnType)
- {
- List subpackets = new List();
- subpackets.Add(CreateAddActorPacket(8));
- if (IsMyPlayer(requestPlayer.actorId))
- subpackets.AddRange(Create0x132Packets());
- subpackets.Add(CreateSpeedPacket());
- subpackets.Add(CreateSpawnPositonPacket(this, spawnType));
- subpackets.Add(CreateAppearancePacket());
- subpackets.Add(CreateNamePacket());
- subpackets.Add(_0xFPacket.BuildPacket(actorId));
- subpackets.Add(CreateStatePacket());
- subpackets.Add(CreateSubStatePacket());
- subpackets.Add(CreateInitStatusPacket());
- subpackets.Add(CreateSetActorIconPacket());
- subpackets.Add(CreateIsZoneingPacket());
- subpackets.AddRange(CreatePlayerRelatedPackets(requestPlayer.actorId));
- subpackets.Add(CreateScriptBindPacket(requestPlayer));
- return subpackets;
- }
-
- public List CreatePlayerRelatedPackets(uint requestingPlayerActorId)
- {
- List subpackets = new List();
-
- if (gcCurrent != 0)
- subpackets.Add(SetGrandCompanyPacket.BuildPacket(actorId, gcCurrent, gcRankLimsa, gcRankGridania, gcRankUldah));
-
- if (currentTitle != 0)
- subpackets.Add(SetPlayerTitlePacket.BuildPacket(actorId, currentTitle));
-
- if (currentJob != 0)
- subpackets.Add(SetCurrentJobPacket.BuildPacket(actorId, currentJob));
-
- if (IsMyPlayer(requestingPlayerActorId))
- {
- subpackets.Add(SetSpecialEventWorkPacket.BuildPacket(actorId));
-
- if (hasChocobo && chocoboName != null && !chocoboName.Equals(""))
- {
- subpackets.Add(SetChocoboNamePacket.BuildPacket(actorId, chocoboName));
- subpackets.Add(SetHasChocoboPacket.BuildPacket(actorId, hasChocobo));
- }
-
- if (hasGoobbue)
- subpackets.Add(SetHasGoobbuePacket.BuildPacket(actorId, hasGoobbue));
-
- subpackets.Add(SetAchievementPointsPacket.BuildPacket(actorId, achievementPoints));
-
- subpackets.Add(Database.GetLatestAchievements(this));
- subpackets.Add(Database.GetAchievementsPacket(this));
- }
-
- if (mountState == 1)
- subpackets.Add(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance));
- else if (mountState == 2)
- subpackets.Add(SetCurrentMountGoobbuePacket.BuildPacket(actorId, 1));
-
- return subpackets;
- }
-
- public override List GetInitPackets()
- {
- ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("/_init", this);
-
- propPacketUtil.AddProperty("charaWork.eventSave.bazaarTax");
- propPacketUtil.AddProperty("charaWork.battleSave.potencial");
-
- //Properties
- for (int i = 0; i < charaWork.property.Length; i++)
- {
- if (charaWork.property[i] != 0)
- propPacketUtil.AddProperty(String.Format("charaWork.property[{0}]", i));
- }
-
- //Parameters
- propPacketUtil.AddProperty("charaWork.parameterSave.hp[0]");
- propPacketUtil.AddProperty("charaWork.parameterSave.hpMax[0]");
- propPacketUtil.AddProperty("charaWork.parameterSave.mp");
- propPacketUtil.AddProperty("charaWork.parameterSave.mpMax");
- propPacketUtil.AddProperty("charaWork.parameterTemp.tp");
- propPacketUtil.AddProperty("charaWork.parameterSave.state_mainSkill[0]");
- propPacketUtil.AddProperty("charaWork.parameterSave.state_mainSkillLevel");
-
- //Status Times
- for (int i = 0; i < charaWork.statusShownTime.Length; i++)
- {
- if (charaWork.statusShownTime[i] != 0)
- propPacketUtil.AddProperty(String.Format("charaWork.statusShownTime[{0}]", i));
- }
-
- //General Parameters
- for (int i = 3; i < charaWork.battleTemp.generalParameter.Length; i++)
- {
- if (charaWork.battleTemp.generalParameter[i] != 0)
- propPacketUtil.AddProperty(String.Format("charaWork.battleTemp.generalParameter[{0}]", i));
- }
-
- propPacketUtil.AddProperty("charaWork.battleTemp.castGauge_speed[0]");
- propPacketUtil.AddProperty("charaWork.battleTemp.castGauge_speed[1]");
-
- //Battle Save Skillpoint
- propPacketUtil.AddProperty(String.Format("charaWork.battleSave.skillPoint[{0}]", charaWork.parameterSave.state_mainSkill[0] - 1));
-
- //Commands
- propPacketUtil.AddProperty("charaWork.commandBorder");
-
- propPacketUtil.AddProperty("charaWork.battleSave.negotiationFlag[0]");
-
- for (int i = 0; i < charaWork.command.Length; i++)
- {
- if (charaWork.command[i] != 0)
- {
- propPacketUtil.AddProperty(String.Format("charaWork.command[{0}]", i));
- //Recast Timers
- if(i >= charaWork.commandBorder)
- {
- propPacketUtil.AddProperty(String.Format("charaWork.parameterTemp.maxCommandRecastTime[{0}]", i - charaWork.commandBorder));
- propPacketUtil.AddProperty(String.Format("charaWork.parameterSave.commandSlot_recastTime[{0}]", i - charaWork.commandBorder));
- }
- }
- }
-
- for (int i = 0; i < charaWork.commandCategory.Length; i++)
- {
- charaWork.commandCategory[i] = 1;
- if (charaWork.commandCategory[i] != 0)
- propPacketUtil.AddProperty(String.Format("charaWork.commandCategory[{0}]", i));
- }
-
- for (int i = 0; i < charaWork.commandAcquired.Length; i++)
- {
- if (charaWork.commandAcquired[i] != false)
- propPacketUtil.AddProperty(String.Format("charaWork.commandAcquired[{0}]", i));
- }
-
- for (int i = 0; i < charaWork.additionalCommandAcquired.Length; i++)
- {
- if (charaWork.additionalCommandAcquired[i] != false)
- propPacketUtil.AddProperty(String.Format("charaWork.additionalCommandAcquired[{0}]", i));
- }
-
- for (int i = 0; i < charaWork.parameterSave.commandSlot_compatibility.Length; i++)
- {
- charaWork.parameterSave.commandSlot_compatibility[i] = true;
- if (charaWork.parameterSave.commandSlot_compatibility[i])
- propPacketUtil.AddProperty(String.Format("charaWork.parameterSave.commandSlot_compatibility[{0}]", i));
- }
-
- for (int i = 0; i < charaWork.parameterSave.commandSlot_recastTime.Length; i++)
- {
- if (charaWork.parameterSave.commandSlot_recastTime[i] != 0)
- propPacketUtil.AddProperty(String.Format("charaWork.parameterSave.commandSlot_recastTime[{0}]", i));
- }
-
- //System
- propPacketUtil.AddProperty("charaWork.parameterTemp.forceControl_float_forClientSelf[0]");
- propPacketUtil.AddProperty("charaWork.parameterTemp.forceControl_float_forClientSelf[1]");
- propPacketUtil.AddProperty("charaWork.parameterTemp.forceControl_int16_forClientSelf[0]");
- propPacketUtil.AddProperty("charaWork.parameterTemp.forceControl_int16_forClientSelf[1]");
-
- charaWork.parameterTemp.otherClassAbilityCount[0] = 4;
- charaWork.parameterTemp.otherClassAbilityCount[1] = 5;
- charaWork.parameterTemp.giftCount[1] = 5;
-
- propPacketUtil.AddProperty("charaWork.parameterTemp.otherClassAbilityCount[0]");
- propPacketUtil.AddProperty("charaWork.parameterTemp.otherClassAbilityCount[1]");
- propPacketUtil.AddProperty("charaWork.parameterTemp.giftCount[1]");
-
- propPacketUtil.AddProperty("charaWork.depictionJudge");
-
- //Scenario
- for (int i = 0; i < playerWork.questScenario.Length; i++)
- {
- if (playerWork.questScenario[i] != 0)
- propPacketUtil.AddProperty(String.Format("playerWork.questScenario[{0}]", i));
- }
-
- //Guildleve - Local
- for (int i = 0; i < playerWork.questGuildleve.Length; i++)
- {
- if (playerWork.questGuildleve[i] != 0)
- propPacketUtil.AddProperty(String.Format("playerWork.questGuildleve[{0}]", i));
- }
-
- //Guildleve - Regional
- for (int i = 0; i < work.guildleveId.Length; i++)
- {
- if (work.guildleveId[i] != 0)
- propPacketUtil.AddProperty(String.Format("work.guildleveId[{0}]", i));
- if (work.guildleveDone[i] != false)
- propPacketUtil.AddProperty(String.Format("work.guildleveDone[{0}]", i));
- if (work.guildleveChecked[i] != false)
- propPacketUtil.AddProperty(String.Format("work.guildleveChecked[{0}]", i));
- }
-
- //Bazaar
- CheckBazaarFlags(true);
- if (charaWork.eventSave.repairType != 0)
- propPacketUtil.AddProperty("charaWork.eventSave.repairType");
- if (charaWork.eventTemp.bazaarRetail)
- propPacketUtil.AddProperty("charaWork.eventTemp.bazaarRetail");
- if (charaWork.eventTemp.bazaarRepair)
- propPacketUtil.AddProperty("charaWork.eventTemp.bazaarRepair");
- if (charaWork.eventTemp.bazaarMateria)
- propPacketUtil.AddProperty("charaWork.eventTemp.bazaarMateria");
-
- //NPC Linkshell
- for (int i = 0; i < playerWork.npcLinkshellChatCalling.Length; i++)
- {
- if (playerWork.npcLinkshellChatCalling[i] != false)
- propPacketUtil.AddProperty(String.Format("playerWork.npcLinkshellChatCalling[{0}]", i));
- if (playerWork.npcLinkshellChatExtra[i] != false)
- propPacketUtil.AddProperty(String.Format("playerWork.npcLinkshellChatExtra[{0}]", i));
- }
-
- propPacketUtil.AddProperty("playerWork.restBonusExpRate");
-
- //Profile
- propPacketUtil.AddProperty("playerWork.tribe");
- propPacketUtil.AddProperty("playerWork.guardian");
- propPacketUtil.AddProperty("playerWork.birthdayMonth");
- propPacketUtil.AddProperty("playerWork.birthdayDay");
- propPacketUtil.AddProperty("playerWork.initialTown");
-
- return propPacketUtil.Done();
- }
-
- public void SendSeamlessZoneInPackets()
- {
- QueuePacket(SetMusicPacket.BuildPacket(actorId, zone.bgmDay, SetMusicPacket.EFFECT_FADEIN));
- QueuePacket(SetWeatherPacket.BuildPacket(actorId, SetWeatherPacket.WEATHER_CLEAR, 1));
- }
-
- public void SendZoneInPackets(WorldManager world, ushort spawnType)
- {
- QueuePacket(SetActorIsZoningPacket.BuildPacket(actorId, false));
- QueuePacket(SetDalamudPacket.BuildPacket(actorId, 0));
- QueuePacket(SetMusicPacket.BuildPacket(actorId, zone.bgmDay, 0x01));
- QueuePacket(SetWeatherPacket.BuildPacket(actorId, SetWeatherPacket.WEATHER_CLEAR, 1));
-
- QueuePacket(SetMapPacket.BuildPacket(actorId, zone.regionId, zone.actorId));
-
- QueuePackets(GetSpawnPackets(this, spawnType));
- //GetSpawnPackets(actorId, spawnType).DebugPrintPacket();
-
- #region Inventory & Equipment
- QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
- itemPackages[ItemPackage.NORMAL].SendFullPackage(this);
- itemPackages[ItemPackage.CURRENCY_CRYSTALS].SendFullPackage(this);
- itemPackages[ItemPackage.KEYITEMS].SendFullPackage(this);
- itemPackages[ItemPackage.BAZAAR].SendFullPackage(this);
- itemPackages[ItemPackage.MELDREQUEST].SendFullPackage(this);
- itemPackages[ItemPackage.LOOT].SendFullPackage(this);
- equipment.SendUpdate(this);
- playerSession.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
- #endregion
-
- playerSession.QueuePacket(GetInitPackets());
-
- List areaMasterSpawn = zone.GetSpawnPackets();
- List debugSpawn = world.GetDebugActor().GetSpawnPackets();
- List worldMasterSpawn = world.GetActor().GetSpawnPackets();
-
- playerSession.QueuePacket(areaMasterSpawn);
- playerSession.QueuePacket(debugSpawn);
- playerSession.QueuePacket(worldMasterSpawn);
-
- //Inn Packets (Dream, Cutscenes, Armoire)
-
- if (zone.isInn)
- {
- SetCutsceneBookPacket cutsceneBookPacket = new SetCutsceneBookPacket();
- for (int i = 0; i < 2048; i++)
- cutsceneBookPacket.cutsceneFlags[i] = true;
- SubPacket packet = cutsceneBookPacket.BuildPacket(actorId, "", 11, 1, 1);
-
- packet.DebugPrintSubPacket();
- QueuePacket(packet);
- QueuePacket(SetPlayerItemStoragePacket.BuildPacket(actorId));
- }
-
- if (zone.GetWeatherDirector() != null)
- {
- playerSession.QueuePacket(zone.GetWeatherDirector().GetSpawnPackets());
- }
-
-
- foreach (Director director in ownedDirectors)
- {
- QueuePackets(director.GetSpawnPackets());
- QueuePackets(director.GetInitPackets());
- }
-
- if (currentContentGroup != null)
- currentContentGroup.SendGroupPackets(playerSession);
-
- if (currentParty != null)
- currentParty.SendGroupPackets(playerSession);
- }
-
- private void SendRemoveInventoryPackets(List slots)
- {
- int currentIndex = 0;
-
- while (true)
- {
- if (slots.Count - currentIndex >= 64)
- QueuePacket(InventoryRemoveX64Packet.BuildPacket(actorId, slots, ref currentIndex));
- else if (slots.Count - currentIndex >= 32)
- QueuePacket(InventoryRemoveX32Packet.BuildPacket(actorId, slots, ref currentIndex));
- else if (slots.Count - currentIndex >= 16)
- QueuePacket(InventoryRemoveX16Packet.BuildPacket(actorId, slots, ref currentIndex));
- else if (slots.Count - currentIndex >= 8)
- QueuePacket(InventoryRemoveX08Packet.BuildPacket(actorId, slots, ref currentIndex));
- else if (slots.Count - currentIndex == 1)
- QueuePacket(InventoryRemoveX01Packet.BuildPacket(actorId, slots[currentIndex]));
- else
- break;
- }
-
- }
-
- public bool IsMyPlayer(uint otherActorId)
- {
- return actorId == otherActorId;
- }
-
- public void QueuePacket(SubPacket packet)
-
- {
- playerSession.QueuePacket(packet);
- }
-
- public void QueuePackets(List packets)
- {
- playerSession.QueuePacket(packets);
- }
-
- public void SendPacket(string path)
- {
- try
- {
- BasePacket packet = new BasePacket(path);
-
- packet.ReplaceActorID(actorId);
- var packets = packet.GetSubpackets();
- QueuePackets(packets);
- }
- catch (Exception e)
- {
- this.SendMessage(SendMessagePacket.MESSAGE_TYPE_SYSTEM_ERROR, "[SendPacket]", "Unable to send packet.");
- this.SendMessage(SendMessagePacket.MESSAGE_TYPE_SYSTEM_ERROR, "[SendPacket]", e.Message);
- }
- }
-
- public void BroadcastPackets(List packets, bool sendToSelf)
- {
- foreach (SubPacket packet in packets)
- {
- if (sendToSelf)
- {
-
- SubPacket clonedPacket = new SubPacket(packet, actorId);
- QueuePacket(clonedPacket);
- }
-
- foreach (Actor a in playerSession.actorInstanceList)
- {
- if (a is Player)
- {
- Player p = (Player)a;
-
- if (p.Equals(this))
- continue;
-
- SubPacket clonedPacket = new SubPacket(packet, a.actorId);
- p.QueuePacket(clonedPacket);
- }
- }
- }
- }
-
- public void BroadcastPacket(SubPacket packet, bool sendToSelf)
- {
- if (sendToSelf)
- {
- SubPacket clonedPacket = new SubPacket(packet, actorId);
- QueuePacket(clonedPacket);
- }
-
- foreach (Actor a in playerSession.actorInstanceList)
- {
- if (a is Player)
- {
- Player p = (Player)a;
-
- if (p.Equals(this))
- continue;
-
- SubPacket clonedPacket = new SubPacket(packet, a.actorId);
- p.QueuePacket(clonedPacket);
- }
- }
- }
-
- public void ChangeAnimation(uint animId)
- {
- Actor a = zone.FindActorInArea(currentTarget);
- if (a is Npc)
- ((Npc)a).animationId = animId;
- }
-
- public void SetDCFlag(bool flag)
- {
- if (flag)
- {
- BroadcastPacket(SetActorIconPacket.BuildPacket(actorId, SetActorIconPacket.DISCONNECTING), true);
- }
- else
- {
- if (isGM)
- BroadcastPacket(SetActorIconPacket.BuildPacket(actorId, SetActorIconPacket.ISGM), true);
- else
- BroadcastPacket(SetActorIconPacket.BuildPacket(actorId, 0), true);
- }
- }
-
- public void CleanupAndSave()
- {
- playerSession.LockUpdates(true);
-
- //Remove actor from zone and main server list
- zone.RemoveActorFromZone(this);
-
- //Set Destination to 0
- this.destinationZone = 0;
- this.destinationSpawnType = 0;
-
- //Clean up parties
- RemoveFromCurrentPartyAndCleanup();
-
- //Save Player
- Database.SavePlayerPlayTime(this);
- Database.SavePlayerPosition(this);
- Database.SavePlayerStatusEffects(this);
- }
-
- public void CleanupAndSave(uint destinationZone, ushort spawnType, float destinationX, float destinationY, float destinationZ, float destinationRot)
- {
- playerSession.LockUpdates(true);
-
- //Remove actor from zone and main server list
- zone.RemoveActorFromZone(this);
-
- //Clean up parties
- RemoveFromCurrentPartyAndCleanup();
-
- //Set destination
- this.destinationZone = destinationZone;
- this.destinationSpawnType = spawnType;
- this.positionX = destinationX;
- this.positionY = destinationY;
- this.positionZ = destinationZ;
- this.rotation = destinationRot;
-
- this.statusEffects.RemoveStatusEffectsByFlags((uint)StatusEffectFlags.LoseOnZoning);
-
- //Save Player
- Database.SavePlayerPlayTime(this);
- Database.SavePlayerPosition(this);
- Database.SavePlayerStatusEffects(this);
- }
-
- public Area GetZone()
- {
- return zone;
- }
-
- public void SendMessage(uint logType, string sender, string message)
- {
- QueuePacket(SendMessagePacket.BuildPacket(actorId, logType, sender, message));
- }
-
- public void Logout()
- {
- // todo: really this should be in CleanupAndSave but we might want logout/disconnect handled separately for some effects
- QueuePacket(LogoutPacket.BuildPacket(actorId));
- statusEffects.RemoveStatusEffectsByFlags((uint)StatusEffectFlags.LoseOnLogout);
- CleanupAndSave();
- }
-
- public void QuitGame()
- {
- QueuePacket(QuitPacket.BuildPacket(actorId));
- statusEffects.RemoveStatusEffectsByFlags((uint)StatusEffectFlags.LoseOnLogout);
- CleanupAndSave();
- }
-
- public uint GetPlayTime(bool doUpdate)
- {
- if (doUpdate)
- {
- uint curTime = Utils.UnixTimeStampUTC();
- playTime += curTime - lastPlayTimeUpdate;
- lastPlayTimeUpdate = curTime;
- }
-
- return playTime;
- }
-
- public void SavePlayTime()
- {
- Database.SavePlayerPlayTime(this);
- }
-
- public void ChangeMusic(ushort musicId)
- {
- QueuePacket(SetMusicPacket.BuildPacket(actorId, musicId, 1));
- }
-
- public void SendMountAppearance()
- {
- if (mountState == 1)
- BroadcastPacket(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance), true);
- else if (mountState == 2)
- BroadcastPacket(SetCurrentMountGoobbuePacket.BuildPacket(actorId, 1), true);
- }
-
- public void SetMountState(byte mountState)
- {
- this.mountState = mountState;
- SendMountAppearance();
- }
-
- public byte GetMountState()
- {
- return mountState;
- }
-
- public void DoEmote(uint targettedActor, uint animId, uint descId)
- {
- BroadcastPacket(ActorDoEmotePacket.BuildPacket(actorId, targettedActor, animId, descId), true);
- }
-
- public void SendGameMessage(Actor sourceActor, Actor textIdOwner, ushort textId, byte log, params object[] msgParams)
- {
- if (msgParams == null || msgParams.Length == 0)
- {
- QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, sourceActor.actorId, textIdOwner.actorId, textId, log));
- }
- else
- QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, sourceActor.actorId, textIdOwner.actorId, textId, log, LuaUtils.CreateLuaParamList(msgParams)));
- }
-
- public void SendGameMessage(Actor textIdOwner, ushort textId, byte log, params object[] msgParams)
- {
- if (msgParams == null || msgParams.Length == 0)
- QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, textIdOwner.actorId, textId, log));
- else
- QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, textIdOwner.actorId, textId, log, LuaUtils.CreateLuaParamList(msgParams)));
- }
-
- public void SendGameMessageCustomSender(Actor textIdOwner, ushort textId, byte log, string customSender, params object[] msgParams)
- {
- if (msgParams == null || msgParams.Length == 0)
- QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, textIdOwner.actorId, textId, customSender, log));
- else
- QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, textIdOwner.actorId, textId, customSender, log, LuaUtils.CreateLuaParamList(msgParams)));
- }
-
- public void SendGameMessageDisplayIDSender(Actor textIdOwner, ushort textId, byte log, uint displayId, params object[] msgParams)
- {
- if (msgParams == null || msgParams.Length == 0)
- QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, textIdOwner.actorId, textId, displayId, log));
- else
- QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, textIdOwner.actorId, textId, displayId, log, LuaUtils.CreateLuaParamList(msgParams)));
- }
-
- public void BroadcastWorldMessage(ushort worldMasterId, params object[] msgParams)
- {
- //SubPacket worldMasterMessage =
- //zone.BroadcastPacketAroundActor(this, worldMasterMessage);
- }
-
- public void GraphicChange(uint slot, uint graphicId)
- {
- appearanceIds[slot] = graphicId;
- }
-
- public void GraphicChange(uint slot, uint weapId, uint equipId, uint variantId, uint colorId)
- {
-
- uint mixedVariantId;
-
- if (weapId == 0)
- mixedVariantId = ((variantId & 0x1F) << 5) | colorId;
- else
- mixedVariantId = variantId;
-
- uint graphicId =
- (weapId & 0x3FF) << 20 |
- (equipId & 0x3FF) << 10 |
- (mixedVariantId & 0x3FF);
-
- appearanceIds[slot] = graphicId;
-
- }
-
- public void SendAppearance()
- {
- BroadcastPacket(CreateAppearancePacket(), true);
- }
-
- public void SendCharaExpInfo()
- {
- if (lastStep == 0)
- {
- int maxLength;
- if ((sizeof(short) * charaWork.battleSave.skillLevel.Length)-lastPosition < 0x5E)
- maxLength = (sizeof(short) * charaWork.battleSave.skillLevel.Length) - lastPosition;
- else
- maxLength = 0x5E;
-
- byte[] skillLevelBuffer = new byte[maxLength];
- Buffer.BlockCopy(charaWork.battleSave.skillLevel, 0, skillLevelBuffer, 0, skillLevelBuffer.Length);
- SetActorPropetyPacket charaInfo1 = new SetActorPropetyPacket("charaWork/exp");
-
- charaInfo1.SetIsArrayMode(true);
- if (maxLength == 0x5E)
- {
- charaInfo1.AddBuffer(Utils.MurmurHash2("charaWork.battleSave.skillLevel", 0), skillLevelBuffer, 0, skillLevelBuffer.Length, 0x0);
- lastPosition += maxLength;
- }
- else
- {
- charaInfo1.AddBuffer(Utils.MurmurHash2("charaWork.battleSave.skillLevel", 0), skillLevelBuffer, 0, skillLevelBuffer.Length, 0x3);
- lastPosition = 0;
- lastStep++;
- }
-
- charaInfo1.AddTarget();
-
- QueuePacket(charaInfo1.BuildPacket(actorId));
- }
- else if (lastStep == 1)
- {
- int maxLength;
- if ((sizeof(short) * charaWork.battleSave.skillLevelCap.Length) - lastPosition < 0x5E)
- maxLength = (sizeof(short) * charaWork.battleSave.skillLevelCap.Length) - lastPosition;
- else
- maxLength = 0x5E;
-
- byte[] skillCapBuffer = new byte[maxLength];
- Buffer.BlockCopy(charaWork.battleSave.skillLevelCap, lastPosition, skillCapBuffer, 0, skillCapBuffer.Length);
- SetActorPropetyPacket charaInfo1 = new SetActorPropetyPacket("charaWork/exp");
-
-
- if (maxLength == 0x5E)
- {
- charaInfo1.SetIsArrayMode(true);
- charaInfo1.AddBuffer(Utils.MurmurHash2("charaWork.battleSave.skillLevelCap", 0), skillCapBuffer, 0, skillCapBuffer.Length, 0x1);
- lastPosition += maxLength;
- }
- else
- {
- charaInfo1.SetIsArrayMode(false);
- charaInfo1.AddBuffer(Utils.MurmurHash2("charaWork.battleSave.skillLevelCap", 0), skillCapBuffer, 0, skillCapBuffer.Length, 0x3);
- lastStep = 0;
- lastPosition = 0;
- }
-
- charaInfo1.AddTarget();
-
- QueuePacket(charaInfo1.BuildPacket(actorId));
- }
-
- }
-
- public int GetHighestLevel()
- {
- int max = 0;
- foreach (short level in charaWork.battleSave.skillLevel)
- {
- if (level > max)
- max = level;
- }
- return max;
- }
-
- public InventoryItem[] GetGearset(ushort classId)
- {
- return Database.GetEquipment(this, classId);
- }
-
- public void PrepareClassChange(byte classId)
- {
- SendCharaExpInfo();
- }
-
- public void DoClassChange(byte classId)
- {
- //load hotbars
- //Calculate stats
- //Calculate hp/mp
-
- //Get Potenciel ??????
-
- //Set HP/MP/TP PARAMS
-
- //Set mainskill and level
-
- //Set Parameters
-
- //Set current EXP
-
- //Set Hotbar Commands 1
- //Set Hotbar Commands 2
- //Set Hotbar Commands 3
-
- //Check if bonus point available... set
-
- //Remove buffs that fall off when changing class
- CommandResultContainer resultContainer = new CommandResultContainer();
- statusEffects.RemoveStatusEffectsByFlags((uint)StatusEffectFlags.LoseOnClassChange, resultContainer);
- resultContainer.CombineLists();
- DoBattleAction(0, 0x7c000062, resultContainer.GetList());
-
- //Set rested EXP
- charaWork.parameterSave.state_mainSkill[0] = classId;
- charaWork.parameterSave.state_mainSkillLevel = charaWork.battleSave.skillLevel[classId-1];
- playerWork.restBonusExpRate = 0.0f;
- for(int i = charaWork.commandBorder; i < charaWork.command.Length; i++)
- {
- charaWork.command[i] = 0;
- charaWork.commandCategory[i] = 0;
- }
-
- //If new class, init abilties and level
- if (charaWork.battleSave.skillLevel[classId - 1] <= 0)
- {
- UpdateClassLevel(classId, 1);
- EquipAbilitiesAtLevel(classId, 1);
- }
-
- ActorPropertyPacketUtil propertyBuilder = new ActorPropertyPacketUtil("charaWork/stateForAll", this);
-
- propertyBuilder.AddProperty("charaWork.parameterSave.state_mainSkill[0]");
- propertyBuilder.AddProperty("charaWork.parameterSave.state_mainSkillLevel");
- propertyBuilder.NewTarget("playerWork/expBonus");
- propertyBuilder.AddProperty("playerWork.restBonusExpRate");
- propertyBuilder.NewTarget("charaWork/battleStateForSelf");
- propertyBuilder.AddProperty(String.Format("charaWork.battleSave.skillPoint[{0}]", classId - 1));
- Database.LoadHotbar(this);
-
- var time = Utils.UnixTimeStampUTC();
- for(int i = charaWork.commandBorder; i < charaWork.command.Length; i++)
- {
- if(charaWork.command[i] != 0)
- {
- charaWork.parameterSave.commandSlot_recastTime[i - charaWork.commandBorder] = time + charaWork.parameterTemp.maxCommandRecastTime[i - charaWork.commandBorder];
- }
- }
-
- UpdateHotbar();
-
- List packets = propertyBuilder.Done();
-
- foreach (SubPacket packet in packets)
- BroadcastPacket(packet, true);
-
- Database.SavePlayerCurrentClass(this);
- RecalculateStats();
- }
-
- public void UpdateClassLevel(byte classId, short level)
- {
- Database.PlayerCharacterUpdateClassLevel(this, classId, level);
- charaWork.battleSave.skillLevel[classId - 1] = level;
- ActorPropertyPacketUtil propertyBuilder = new ActorPropertyPacketUtil("charaWork/stateForAll", this);
- propertyBuilder.AddProperty(String.Format("charaWork.battleSave.skillLevel[{0}]", classId-1));
- List packets = propertyBuilder.Done();
- QueuePackets(packets);
- }
-
- public void GraphicChange(int slot, InventoryItem invItem)
- {
- if (invItem == null)
- appearanceIds[slot] = 0;
- else
- {
- ItemData item = Server.GetItemGamedata(invItem.itemId);
-
- if (item is EquipmentItem)
- {
- EquipmentItem eqItem = (EquipmentItem)item;
-
- uint mixedVariantId;
-
- if (eqItem.graphicsWeaponId == 0)
- mixedVariantId = ((eqItem.graphicsVariantId & 0x1F) << 5) | eqItem.graphicsColorId;
- else
- mixedVariantId = eqItem.graphicsVariantId;
-
- uint graphicId =
- (eqItem.graphicsWeaponId & 0x3FF) << 20 |
- (eqItem.graphicsEquipmentId & 0x3FF) << 10 |
- (mixedVariantId & 0x3FF);
-
- appearanceIds[slot] = graphicId;
- }
-
- //Handle offhand
- if (slot == MAINHAND && item is WeaponItem)
- {
- WeaponItem wpItem = (WeaponItem)item;
-
- uint graphicId =
- (wpItem.graphicsOffhandWeaponId & 0x3FF) << 20 |
- (wpItem.graphicsOffhandEquipmentId & 0x3FF) << 10 |
- (wpItem.graphicsOffhandVariantId & 0x3FF);
-
- appearanceIds[SetActorAppearancePacket.OFFHAND] = graphicId;
- }
- }
-
- Database.SavePlayerAppearance(this);
- BroadcastPacket(CreateAppearancePacket(), true);
- }
-
- public void SetRepairRequest(byte type)
- {
- charaWork.eventSave.repairType = type;
- ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("charaWork/bazaar", this);
- propPacketUtil.AddProperty("charaWork.eventSave.repairType");
- QueuePackets(propPacketUtil.Done());
- }
-
- public void CheckBazaarFlags(bool noUpdate = false)
- {
- bool isDealing = false, isRepairing = false, seekingItem = false;
- lock (GetItemPackage(ItemPackage.BAZAAR))
- {
- foreach (InventoryItem item in GetItemPackage(ItemPackage.BAZAAR).GetRawList())
- {
- if (item == null)
- break;
-
- if (item.GetBazaarMode() == InventoryItem.MODE_SELL_SINGLE || item.GetBazaarMode() == InventoryItem.MODE_SELL_PSTACK || item.GetBazaarMode() == InventoryItem.MODE_SELL_FSTACK)
- isDealing = true;
- if (item.GetBazaarMode() == InventoryItem.MODE_SEEK_REPAIR)
- isRepairing = true;
- if (item.GetBazaarMode() == InventoryItem.MODE_SEEK_ITEM)
- isDealing = true;
-
- if (isDealing && isRepairing && seekingItem)
- break;
- }
- }
-
- bool doUpdate = false;
-
- ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("charaWork/bazaar", this);
- if (charaWork.eventTemp.bazaarRetail != isDealing)
- {
- charaWork.eventTemp.bazaarRetail = isDealing;
- propPacketUtil.AddProperty("charaWork.eventTemp.bazaarRetail");
- doUpdate = true;
- }
-
- if (charaWork.eventTemp.bazaarRepair != isRepairing)
- {
- charaWork.eventTemp.bazaarRepair = isRepairing;
- propPacketUtil.AddProperty("charaWork.eventTemp.bazaarRepair");
- doUpdate = true;
- }
-
- if (charaWork.eventTemp.bazaarMateria != (GetItemPackage(ItemPackage.MELDREQUEST).GetCount() != 0))
- {
- charaWork.eventTemp.bazaarMateria = GetItemPackage(ItemPackage.MELDREQUEST).GetCount() != 0;
- propPacketUtil.AddProperty("charaWork.eventTemp.bazaarMateria");
- doUpdate = true;
- }
-
- if (!noUpdate && doUpdate)
- BroadcastPackets(propPacketUtil.Done(), true);
- }
-
- public int GetCurrentGil()
- {
- if (HasItem(1000001))
- return GetItemPackage(ItemPackage.CURRENCY_CRYSTALS).GetItemByCatelogId(1000001).quantity;
- else
- return 0;
- }
-
- public Actor GetActorInInstance(uint actorId)
- {
- foreach (Actor a in playerSession.actorInstanceList)
- {
- if (a.actorId == actorId)
- return a;
- }
-
- return null;
- }
-
- public void SetZoneChanging(bool flag)
- {
- isZoneChanging = flag;
- }
-
- public bool IsInZoneChange()
- {
- return isZoneChanging;
- }
-
- public ReferencedItemPackage GetEquipment()
- {
- return equipment;
- }
-
- public byte GetInitialTown()
- {
- return playerWork.initialTown;
- }
-
- public uint GetHomePoint()
- {
- return homepoint;
- }
-
- public byte GetHomePointInn()
- {
- return homepointInn;
- }
-
- public void SetHomePoint(uint aetheryteId)
- {
- homepoint = aetheryteId;
- Database.SavePlayerHomePoints(this);
- }
-
- public void SetHomePointInn(byte townId)
- {
- homepointInn = townId;
- Database.SavePlayerHomePoints(this);
- }
-
- public bool HasAetheryteNodeUnlocked(uint aetheryteId)
- {
- if (aetheryteId != 0)
- return true;
- else
- return false;
- }
-
- public int GetFreeQuestSlot()
- {
- for (int i = 0; i < questScenario.Length; i++)
- {
- if (questScenario[i] == null)
- return i;
- }
-
- return -1;
- }
-
- public int GetFreeGuildleveSlot()
- {
- for (int i = 0; i < work.guildleveId.Length; i++)
- {
- if (work.guildleveId[i] == 0)
- return i;
- }
-
- return -1;
- }
-
- //For Lua calls, cause MoonSharp goes retard with uint
- public void AddQuest(int id, bool isSilent = false)
- {
- AddQuest((uint)id, isSilent);
- }
- public void CompleteQuest(int id)
- {
- CompleteQuest((uint)id);
- }
- public bool HasQuest(int id)
- {
- return HasQuest((uint)id);
- }
- public Quest GetQuest(int id)
- {
- return GetQuest((uint)id);
- }
- public bool IsQuestCompleted(int id)
- {
- return IsQuestCompleted((uint)id);
- }
- public bool CanAcceptQuest(int id)
- {
- return CanAcceptQuest((uint)id);
- }
- //For Lua calls, cause MoonSharp goes retard with uint
-
- public void AddGuildleve(uint id)
- {
- int freeSlot = GetFreeGuildleveSlot();
-
- if (freeSlot == -1)
- return;
-
- work.guildleveId[freeSlot] = (ushort)id;
- Database.SaveGuildleve(this, id, freeSlot);
- SendGuildleveClientUpdate(freeSlot);
- }
-
- public void MarkGuildleve(uint id, bool abandoned, bool completed)
- {
- if (HasGuildleve(id))
- {
- for (int i = 0; i < work.guildleveId.Length; i++)
- {
- if (work.guildleveId[i] == id)
- {
- work.guildleveChecked[i] = completed;
- work.guildleveDone[i] = abandoned;
- Database.MarkGuildleve(this, id, abandoned, completed);
- SendGuildleveMarkClientUpdate(i);
- }
- }
- }
- }
-
- public void RemoveGuildleve(uint id)
- {
- if (HasGuildleve(id))
- {
- for (int i = 0; i < work.guildleveId.Length; i++)
- {
- if (work.guildleveId[i] == id)
- {
- Database.RemoveGuildleve(this, id);
- work.guildleveId[i] = 0;
- SendGuildleveClientUpdate(i);
- break;
- }
- }
- }
- }
-
- public void AddQuest(uint id, bool isSilent = false)
- {
- Actor actor = Server.GetStaticActors((0xA0F00000 | id));
- AddQuest(actor.actorName, isSilent);
- }
-
- public void AddQuest(string name, bool isSilent = false)
- {
- Actor actor = Server.GetStaticActors(name);
-
- if (actor == null)
- return;
-
- uint id = actor.actorId;
-
- int freeSlot = GetFreeQuestSlot();
-
- if (freeSlot == -1)
- return;
-
- playerWork.questScenario[freeSlot] = id;
- questScenario[freeSlot] = new Quest(this, playerWork.questScenario[freeSlot], name, null, 0, 0);
- Database.SaveQuest(this, questScenario[freeSlot]);
- SendQuestClientUpdate(freeSlot);
-
- if (!isSilent)
- {
- SendGameMessage(Server.GetWorldManager().GetActor(), 25224, 0x20, (object)questScenario[freeSlot].GetQuestId());
- questScenario[freeSlot].NextPhase(0);
- }
- }
-
- public void CompleteQuest(uint id)
- {
- Actor actor = Server.GetStaticActors((0xA0F00000 | id));
- CompleteQuest(actor.actorName);
- }
-
- public void CompleteQuest(string name)
- {
- Actor actor = Server.GetStaticActors(name);
-
- if (actor == null)
- return;
-
- uint id = actor.actorId;
- if (HasQuest(id))
- {
- Database.CompleteQuest(playerSession.GetActor(), id);
- SendGameMessage(Server.GetWorldManager().GetActor(), 25086, 0x20, (object)GetQuest(id).GetQuestId());
- RemoveQuest(id);
- }
- }
-
- //TODO: Add checks for you being in an instance or main scenario
- public void AbandonQuest(uint id)
- {
- Quest quest = GetQuest(id);
- RemoveQuestByQuestId(id);
- quest.DoAbandon();
- }
-
- public void RemoveQuestByQuestId(uint id)
- {
- RemoveQuest((0xA0F00000 | id));
- }
-
- public void RemoveQuest(uint id)
- {
- if (HasQuest(id))
- {
- for (int i = 0; i < questScenario.Length; i++)
- {
- if (questScenario[i] != null && questScenario[i].actorId == id)
- {
- Database.RemoveQuest(this, questScenario[i].actorId);
- questScenario[i] = null;
- playerWork.questScenario[i] = 0;
- SendQuestClientUpdate(i);
- break;
- }
- }
- }
- }
-
- public void ReplaceQuest(uint oldId, uint newId)
- {
- if (HasQuest(oldId))
- {
- for (int i = 0; i < questScenario.Length; i++)
- {
- if (questScenario[i] != null && questScenario[i].GetQuestId() == oldId)
- {
- Actor actor = Server.GetStaticActors((0xA0F00000 | newId));
- playerWork.questScenario[i] = (0xA0F00000 | newId);
- questScenario[i] = new Quest(this, playerWork.questScenario[i], actor.actorName, null, 0, 0);
- Database.SaveQuest(this, questScenario[i]);
- SendQuestClientUpdate(i);
- break;
- }
- }
- }
- }
-
- public bool CanAcceptQuest(string name)
- {
- if (!IsQuestCompleted(name) && !HasQuest(name))
- return true;
- else
- return false;
- }
-
- public bool CanAcceptQuest(uint id)
- {
- Actor actor = Server.GetStaticActors((0xA0F00000 | id));
- return CanAcceptQuest(actor.actorName);
- }
-
- public bool IsQuestCompleted(string questName)
- {
- Actor actor = Server.GetStaticActors(questName);
- return IsQuestCompleted(actor.actorId);
- }
-
- public bool IsQuestCompleted(uint questId)
- {
- return Database.IsQuestCompleted(this, 0xFFFFF & questId);
- }
-
- public Quest GetQuest(uint id)
- {
- for (int i = 0; i < questScenario.Length; i++)
- {
- if (questScenario[i] != null && questScenario[i].actorId == (0xA0F00000 | id))
- return questScenario[i];
- }
-
- return null;
- }
-
- public Quest GetQuest(string name)
- {
- for (int i = 0; i < questScenario.Length; i++)
- {
- if (questScenario[i] != null && questScenario[i].actorName.ToLower().Equals(name.ToLower()))
- return questScenario[i];
- }
-
- return null;
- }
-
- public bool HasQuest(string name)
- {
- for (int i = 0; i < questScenario.Length; i++)
- {
- if (questScenario[i] != null && questScenario[i].actorName.ToLower().Equals(name.ToLower()))
- return true;
- }
-
- return false;
- }
-
- public bool HasQuest(uint id)
- {
- for (int i = 0; i < questScenario.Length; i++)
- {
- if (questScenario[i] != null && questScenario[i].actorId == (0xA0F00000 | id))
- return true;
- }
-
- return false;
- }
-
- public bool HasGuildleve(uint id)
- {
- for (int i = 0; i < work.guildleveId.Length; i++)
- {
- if (work.guildleveId[i] == id)
- return true;
- }
-
- return false;
- }
-
- public int GetQuestSlot(uint id)
- {
- for (int i = 0; i < questScenario.Length; i++)
- {
- if (questScenario[i] != null && questScenario[i].actorId == (0xA0F00000 | id))
- return i;
- }
-
- return -1;
- }
-
- public void SetNpcLS(uint npcLSId, uint state)
- {
- bool isCalling, isExtra;
- isCalling = isExtra = false;
-
- switch (state)
- {
- case NPCLS_INACTIVE:
-
- if (playerWork.npcLinkshellChatExtra[npcLSId] == true && playerWork.npcLinkshellChatCalling[npcLSId] == false)
- return;
-
- isExtra = true;
- break;
- case NPCLS_ACTIVE:
-
- if (playerWork.npcLinkshellChatExtra[npcLSId] == false && playerWork.npcLinkshellChatCalling[npcLSId] == true)
- return;
-
- isCalling = true;
- break;
- case NPCLS_ALERT:
-
- if (playerWork.npcLinkshellChatExtra[npcLSId] == true && playerWork.npcLinkshellChatCalling[npcLSId] == true)
- return;
-
- isExtra = isCalling = true;
- break;
- }
-
- playerWork.npcLinkshellChatExtra[npcLSId] = isExtra;
- playerWork.npcLinkshellChatCalling[npcLSId] = isCalling;
-
- Database.SaveNpcLS(this, npcLSId, isCalling, isExtra);
-
- ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("playerWork/npcLinkshellChat", this);
- propPacketUtil.AddProperty(String.Format("playerWork.npcLinkshellChatExtra[{0}]", npcLSId));
- propPacketUtil.AddProperty(String.Format("playerWork.npcLinkshellChatCalling[{0}]", npcLSId));
- QueuePackets(propPacketUtil.Done());
- }
-
- private void SendQuestClientUpdate(int slot)
- {
- ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("playerWork/journal", this);
- propPacketUtil.AddProperty(String.Format("playerWork.questScenario[{0}]", slot));
- QueuePackets(propPacketUtil.Done());
- }
-
- private void SendGuildleveClientUpdate(int slot)
- {
- ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("work/guildleve", this);
- propPacketUtil.AddProperty(String.Format("work.guildleveId[{0}]", slot));
- QueuePackets(propPacketUtil.Done());
- }
-
- private void SendGuildleveMarkClientUpdate(int slot)
- {
- ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("work/guildleve", this);
- propPacketUtil.AddProperty(String.Format("work.guildleveDone[{0}]", slot));
- propPacketUtil.AddProperty(String.Format("work.guildleveChecked[{0}]", slot));
- QueuePackets(propPacketUtil.Done());
- }
-
- public void SendStartCastbar(uint commandId, uint endTime)
- {
- playerWork.castCommandClient = commandId;
- playerWork.castEndClient = endTime;
- ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("playerWork/castState", this);
- propPacketUtil.AddProperty("playerWork.castEndClient");
- propPacketUtil.AddProperty("playerWork.castCommandClient");
- QueuePackets(propPacketUtil.Done());
- }
-
- public void SendEndCastbar()
- {
- playerWork.castCommandClient = 0;
- playerWork.castEndClient = 0;
- ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("playerWork/castState", this);
- propPacketUtil.AddProperty("playerWork.castCommandClient");
- QueuePackets(propPacketUtil.Done());
- }
-
- public void SetLoginDirector(Director director)
- {
- if (ownedDirectors.Contains(director))
- loginInitDirector = director;
- }
-
- public void AddDirector(Director director, bool spawnImmediatly = false)
- {
- if (!ownedDirectors.Contains(director))
- {
- ownedDirectors.Add(director);
- director.AddMember(this);
- }
- }
-
- public void SendDirectorPackets(Director director)
- {
- QueuePackets(director.GetSpawnPackets());
- QueuePackets(director.GetInitPackets());
- }
-
- public void RemoveDirector(Director director)
- {
- if (ownedDirectors.Contains(director))
- {
- QueuePacket(RemoveActorPacket.BuildPacket(director.actorId));
- ownedDirectors.Remove(director);
- director.RemoveMember(this);
- }
- }
-
- public GuildleveDirector GetGuildleveDirector()
- {
- foreach (Director d in ownedDirectors)
- {
- if (d is GuildleveDirector)
- return (GuildleveDirector)d;
- }
-
- return null;
- }
-
- public Director GetDirector(string directorName)
- {
- foreach (Director d in ownedDirectors)
- {
- if (d.GetScriptPath().Equals(directorName))
- return d;
- }
-
- return null;
- }
-
- public Director GetDirector(uint id)
- {
- foreach (Director d in ownedDirectors)
- {
- if (d.actorId == id)
- return d;
- }
-
- return null;
- }
-
- public void ExaminePlayer(Actor examinee)
- {
- Player toBeExamined;
- if (examinee is Player)
- toBeExamined = (Player)examinee;
- else
- return;
-
- QueuePacket(InventoryBeginChangePacket.BuildPacket(toBeExamined.actorId, true));
- toBeExamined.GetEquipment().SendUpdateAsItemPackage(this, ItemPackage.MAXSIZE_EQUIPMENT_OTHERPLAYER, ItemPackage.EQUIPMENT_OTHERPLAYER);
- QueuePacket(InventoryEndChangePacket.BuildPacket(toBeExamined.actorId));
- }
-
- public void SendDataPacket(params object[] parameters)
- {
- List lParams = LuaUtils.CreateLuaParamList(parameters);
- SubPacket spacket = GenericDataPacket.BuildPacket(actorId, lParams);
- spacket.DebugPrintSubPacket();
- QueuePacket(spacket);
- }
-
- public void StartEvent(Actor owner, EventStartPacket start)
- {
- currentEventOwner = start.scriptOwnerActorID;
- currentEventName = start.triggerName;
- LuaEngine.GetInstance().EventStarted(this, owner, start);
- }
-
- public void UpdateEvent(EventUpdatePacket update)
- {
- LuaEngine.GetInstance().OnEventUpdate(this, update.luaParams);
- }
-
- public void KickEvent(Actor actor, string conditionName, params object[] parameters)
- {
- if (actor == null)
- return;
-
- List lParams = LuaUtils.CreateLuaParamList(parameters);
- SubPacket spacket = KickEventPacket.BuildPacket(actorId, actor.actorId, 0x75dc1705, conditionName, lParams);
- spacket.DebugPrintSubPacket();
- QueuePacket(spacket);
- }
-
- public void KickEventSpecial(Actor actor, uint unknown, string conditionName, params object[] parameters)
- {
- if (actor == null)
- return;
-
- List lParams = LuaUtils.CreateLuaParamList(parameters);
- SubPacket spacket = KickEventPacket.BuildPacket(actorId, actor.actorId, unknown, conditionName, lParams);
- spacket.DebugPrintSubPacket();
- QueuePacket(spacket);
- }
-
- public void SetEventStatus(Actor actor, string conditionName, bool enabled, byte unknown)
- {
- QueuePacket(packets.send.actor.events.SetEventStatus.BuildPacket(actor.actorId, enabled, unknown, conditionName));
- }
-
- public void RunEventFunction(string functionName, params object[] parameters)
- {
- List lParams = LuaUtils.CreateLuaParamList(parameters);
- SubPacket spacket = RunEventFunctionPacket.BuildPacket(actorId, currentEventOwner, currentEventName, functionName, lParams);
- spacket.DebugPrintSubPacket();
- QueuePacket(spacket);
- }
-
- public void EndEvent()
- {
- SubPacket p = EndEventPacket.BuildPacket(actorId, currentEventOwner, currentEventName);
- p.DebugPrintSubPacket();
- QueuePacket(p);
-
- currentEventOwner = 0;
- currentEventName = "";
- currentEventRunning = null;
- }
-
- public void BroadcastCountdown(byte countdownLength, ulong syncTime)
- {
- BroadcastPacket(StartCountdownPacket.BuildPacket(actorId, countdownLength, syncTime, "Go!"), true);
- }
-
- public void SendInstanceUpdate()
- {
- //Server.GetWorldManager().SeamlessCheck(this);
-
- //Update Instance
- List aroundMe = new List();
-
- if (zone != null)
- aroundMe.AddRange(zone.GetActorsAroundActor(this, 50));
- if (zone2 != null)
- aroundMe.AddRange(zone2.GetActorsAroundActor(this, 50));
- playerSession.UpdateInstance(aroundMe);
- }
-
- public bool IsInParty()
- {
- return currentParty != null;
- }
-
- public bool IsPartyLeader()
- {
- if (IsInParty())
- {
- Party party = (Party)currentParty;
- return party.GetLeader() == actorId;
- }
- else
- return false;
- }
-
- public void PartyOustPlayer(uint actorId)
- {
- SubPacket oustPacket = PartyModifyPacket.BuildPacket(playerSession, 1, actorId);
- QueuePacket(oustPacket);
- }
-
- public void PartyOustPlayer(string name)
- {
- SubPacket oustPacket = PartyModifyPacket.BuildPacket(playerSession, 1, name);
- QueuePacket(oustPacket);
- }
-
- public void PartyLeave()
- {
- SubPacket leavePacket = PartyLeavePacket.BuildPacket(playerSession, false);
- QueuePacket(leavePacket);
- }
-
- public void PartyDisband()
- {
- SubPacket disbandPacket = PartyLeavePacket.BuildPacket(playerSession, true);
- QueuePacket(disbandPacket);
- }
-
- public void PartyPromote(uint actorId)
- {
- SubPacket promotePacket = PartyModifyPacket.BuildPacket(playerSession, 0, actorId);
- QueuePacket(promotePacket);
- }
-
- public void PartyPromote(string name)
- {
- SubPacket promotePacket = PartyModifyPacket.BuildPacket(playerSession, 0, name);
- QueuePacket(promotePacket);
- }
-
- //A party member list packet came, set the party
- public void SetParty(Party group)
- {
- if (group is Party && currentParty != group)
- {
- RemoveFromCurrentPartyAndCleanup();
- currentParty = group;
- }
- }
-
- //Removes the player from the party and cleans it up if needed
- public void RemoveFromCurrentPartyAndCleanup()
- {
- if (currentParty == null)
- return;
-
- Party partyGroup = (Party) currentParty;
-
- for (int i = 0; i < partyGroup.members.Count; i++)
- {
- if (partyGroup.members[i] == actorId)
- {
- partyGroup.members.RemoveAt(i);
- break;
- }
- }
-
- //currentParty.members.Remove(this);
- if (partyGroup.members.Count == 0)
- Server.GetWorldManager().NoMembersInParty((Party)currentParty);
-
- currentParty = null;
- }
-
- public void IssueChocobo(byte appearanceId, string nameResponse)
- {
- Database.IssuePlayerChocobo(this, appearanceId, nameResponse);
- hasChocobo = true;
- chocoboAppearance = appearanceId;
- chocoboName = nameResponse;
- }
-
- public void ChangeChocoboAppearance(byte appearanceId)
- {
- Database.ChangePlayerChocoboAppearance(this, appearanceId);
- chocoboAppearance = appearanceId;
- }
-
- public Retainer SpawnMyRetainer(Npc bell, int retainerIndex)
- {
- Retainer retainer = Database.LoadRetainer(this, retainerIndex);
-
- float distance = (float)Math.Sqrt(((positionX - bell.positionX) * (positionX - bell.positionX)) + ((positionZ - bell.positionZ) * (positionZ - bell.positionZ)));
- float posX = bell.positionX - ((-1.0f * (bell.positionX - positionX)) / distance);
- float posZ = bell.positionZ - ((-1.0f * (bell.positionZ - positionZ)) / distance);
-
- retainer.positionX = posX;
- retainer.positionY = positionY;
- retainer.positionZ = posZ;
- retainer.rotation = (float)Math.Atan2(positionX - posX, positionZ - posZ);
-
- retainerMeetingGroup = new RetainerMeetingRelationGroup(5555, this, retainer);
- retainerMeetingGroup.SendGroupPackets(playerSession);
-
- currentSpawnedRetainer = retainer;
- sentRetainerSpawn = false;
-
- return retainer;
- }
-
- public void DespawnMyRetainer()
- {
- if (currentSpawnedRetainer != null)
- {
- currentSpawnedRetainer = null;
- retainerMeetingGroup.SendDeletePacket(playerSession);
- retainerMeetingGroup = null;
- }
- }
-
- public override void Update(DateTime tick)
- {
- aiContainer.Update(tick);
- statusEffects.Update(tick);
- }
-
- public override void PostUpdate(DateTime tick, List packets = null)
- {
- // todo: is this correct?
- if (this.playerSession.isUpdatesLocked)
- return;
-
- // todo: should probably add another flag for battleTemp since all this uses reflection
- packets = new List();
-
- // we only want the latest update for the player
- if ((updateFlags & ActorUpdateFlags.Position) != 0)
- {
- if (positionUpdates.Count > 1)
- positionUpdates.RemoveRange(1, positionUpdates.Count - 1);
- }
-
- if ((updateFlags & ActorUpdateFlags.HpTpMp) != 0)
- {
- var propPacketUtil = new ActorPropertyPacketUtil("charaWork/stateAtQuicklyForAll", this);
-
- // todo: should this be using job as index?
- propPacketUtil.AddProperty("charaWork.parameterSave.hp[0]");
- propPacketUtil.AddProperty("charaWork.parameterSave.hpMax[0]");
- propPacketUtil.AddProperty("charaWork.parameterSave.state_mainSkill[0]");
- propPacketUtil.AddProperty("charaWork.parameterSave.state_mainSkillLevel");
-
- packets.AddRange(propPacketUtil.Done());
- }
-
-
- if ((updateFlags & ActorUpdateFlags.Stats) != 0)
- {
- var propPacketUtil = new ActorPropertyPacketUtil("charaWork/battleParameter", this);
-
- for (uint i = 0; i < 35; i++)
- {
- if (GetMod(i) != charaWork.battleTemp.generalParameter[i])
- {
- charaWork.battleTemp.generalParameter[i] = (short)GetMod(i);
- propPacketUtil.AddProperty(String.Format("charaWork.battleTemp.generalParameter[{0}]", i));
- }
- }
-
- QueuePackets(propPacketUtil.Done());
- }
-
- if ((updateFlags & ActorUpdateFlags.Hotbar) != 0)
- {
- UpdateHotbar(hotbarSlotsToUpdate);
- hotbarSlotsToUpdate.Clear();
-
- updateFlags ^= ActorUpdateFlags.Hotbar;
- }
-
-
- base.PostUpdate(tick, packets);
- }
-
- public override void Die(DateTime tick, CommandResultContainer actionContainer = null)
- {
- // todo: death timer
- aiContainer.InternalDie(tick, 60);
- }
-
- //Update commands and recast timers for the entire hotbar
- public void UpdateHotbar()
- {
- for (ushort i = charaWork.commandBorder; i < charaWork.commandBorder + 30; i++)
- {
- hotbarSlotsToUpdate.Add(i);
- }
- updateFlags |= ActorUpdateFlags.Hotbar;
- }
-
- //Updates the hotbar and recast timers for only certain hotbar slots
- public void UpdateHotbar(List slotsToUpdate)
- {
- UpdateHotbarCommands(slotsToUpdate);
- UpdateRecastTimers(slotsToUpdate);
- }
-
- //Update command ids for the passed in hotbar slots
- public void UpdateHotbarCommands(List slotsToUpdate)
- {
- ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("charaWork/command", this);
- foreach (ushort slot in slotsToUpdate)
- {
- propPacketUtil.AddProperty(String.Format("charaWork.command[{0}]", slot));
- propPacketUtil.AddProperty(String.Format("charaWork.commandCategory[{0}]", slot));
- }
-
- propPacketUtil.NewTarget("charaWork/commandDetailForSelf");
- //Enable or disable slots based on whether there is an ability in that slot
- foreach (ushort slot in slotsToUpdate)
- {
- charaWork.parameterSave.commandSlot_compatibility[slot - charaWork.commandBorder] = charaWork.command[slot] != 0;
- propPacketUtil.AddProperty(String.Format("charaWork.parameterSave.commandSlot_compatibility[{0}]", slot - charaWork.commandBorder));
- }
-
- QueuePackets(propPacketUtil.Done());
- //QueuePackets(compatibiltyUtil.Done());
- }
-
- //Update recast timers for the passed in hotbar slots
- public void UpdateRecastTimers(List slotsToUpdate)
- {
- ActorPropertyPacketUtil recastPacketUtil = new ActorPropertyPacketUtil("charaWork/commandDetailForSelf", this);
-
- foreach (ushort slot in slotsToUpdate)
- {
- recastPacketUtil.AddProperty(String.Format("charaWork.parameterTemp.maxCommandRecastTime[{0}]", slot - charaWork.commandBorder));
- recastPacketUtil.AddProperty(String.Format("charaWork.parameterSave.commandSlot_recastTime[{0}]", slot - charaWork.commandBorder));
- }
-
- QueuePackets(recastPacketUtil.Done());
- }
-
- //Find the first open slot in classId's hotbar and equip an ability there.
- public void EquipAbilityInFirstOpenSlot(byte classId, uint commandId, bool printMessage = true)
- {
- //Find first open slot on class's hotbar slot, then call EquipAbility with that slot.
- ushort hotbarSlot = 0;
-
- //If the class we're equipping for is the current class, we can just look at charawork.command
- if(classId == charaWork.parameterSave.state_mainSkill[0])
- hotbarSlot = FindFirstCommandSlotById(0);
- //Otherwise, we need to check the database.
- else
- hotbarSlot = (ushort) (Database.FindFirstCommandSlot(this, classId) + charaWork.commandBorder);
-
- EquipAbility(classId, commandId, hotbarSlot, printMessage);
- }
-
- //Add commandId to classId's hotbar at hotbarSlot.
- //If classId is not the current class, do it in the database
- //hotbarSlot starts at 32
- public void EquipAbility(byte classId, uint commandId, ushort hotbarSlot, bool printMessage = true)
- {
- var ability = Server.GetWorldManager().GetBattleCommand(commandId);
- uint trueCommandId = 0xA0F00000 | commandId;
- ushort lowHotbarSlot = (ushort)(hotbarSlot - charaWork.commandBorder);
- ushort maxRecastTime = (ushort)(ability != null ? ability.maxRecastTimeSeconds : 5);
- uint recastEnd = Utils.UnixTimeStampUTC() + maxRecastTime;
-
- Database.EquipAbility(this, classId, (ushort) (hotbarSlot - charaWork.commandBorder), commandId, recastEnd);
- //If the class we're equipping for is the current class (need to find out if state_mainSkill is supposed to change when you're a job)
- //then equip the ability in charawork.commands and save in databse, otherwise just save in database
- if (classId == GetCurrentClassOrJob())
- {
- charaWork.command[hotbarSlot] = trueCommandId;
- charaWork.commandCategory[hotbarSlot] = 1;
- charaWork.parameterTemp.maxCommandRecastTime[lowHotbarSlot] = maxRecastTime;
- charaWork.parameterSave.commandSlot_recastTime[lowHotbarSlot] = recastEnd;
-
- hotbarSlotsToUpdate.Add(hotbarSlot);
- updateFlags |= ActorUpdateFlags.Hotbar;
- }
-
-
- if(printMessage)
- SendGameMessage(Server.GetWorldManager().GetActor(), 30603, 0x20, 0, commandId);
- }
-
- //Doesn't take a classId because the only way to swap abilities is through the ability equip widget oe /eaction, which only apply to current class
- //hotbarSlot 1 and 2 are 32-indexed.
- public void SwapAbilities(ushort hotbarSlot1, ushort hotbarSlot2)
- {
- //0 indexed hotbar slots for saving to database and recast timers
- uint lowHotbarSlot1 = (ushort)(hotbarSlot1 - charaWork.commandBorder);
- uint lowHotbarSlot2 = (ushort)(hotbarSlot2 - charaWork.commandBorder);
-
- //Store information about first command
- uint commandId = charaWork.command[hotbarSlot1];
- uint recastEnd = charaWork.parameterSave.commandSlot_recastTime[lowHotbarSlot1];
- ushort recastMax = charaWork.parameterTemp.maxCommandRecastTime[lowHotbarSlot1];
-
- //Move second command's info to first hotbar slot
- charaWork.command[hotbarSlot1] = charaWork.command[hotbarSlot2];
- charaWork.parameterTemp.maxCommandRecastTime[lowHotbarSlot1] = charaWork.parameterTemp.maxCommandRecastTime[lowHotbarSlot2];
- charaWork.parameterSave.commandSlot_recastTime[lowHotbarSlot1] = charaWork.parameterSave.commandSlot_recastTime[lowHotbarSlot2];
-
- //Move first command's info to second slot
- charaWork.command[hotbarSlot2] = commandId;
- charaWork.parameterTemp.maxCommandRecastTime[lowHotbarSlot2] = recastMax;
- charaWork.parameterSave.commandSlot_recastTime[lowHotbarSlot2] = recastEnd;
-
- //Save changes to both slots
- Database.EquipAbility(this, GetCurrentClassOrJob(), (ushort)(lowHotbarSlot1), 0xA0F00000 ^ charaWork.command[hotbarSlot1], charaWork.parameterSave.commandSlot_recastTime[lowHotbarSlot1]);
- Database.EquipAbility(this, GetCurrentClassOrJob(), (ushort)(lowHotbarSlot2), 0xA0F00000 ^ charaWork.command[hotbarSlot2], charaWork.parameterSave.commandSlot_recastTime[lowHotbarSlot2]);
-
- //Update slots on client
- hotbarSlotsToUpdate.Add(hotbarSlot1);
- hotbarSlotsToUpdate.Add(hotbarSlot2);
- updateFlags |= ActorUpdateFlags.Hotbar;
- }
-
- public void UnequipAbility(ushort hotbarSlot, bool printMessage = true)
- {
- ushort trueHotbarSlot = (ushort)(hotbarSlot + charaWork.commandBorder);
- uint commandId = charaWork.command[trueHotbarSlot];
- Database.UnequipAbility(this, hotbarSlot);
- charaWork.command[trueHotbarSlot] = 0;
- hotbarSlotsToUpdate.Add(trueHotbarSlot);
-
- if (printMessage && commandId != 0)
- SendGameMessage(Server.GetWorldManager().GetActor(), 30604, 0x20, 0, 0xA0F00000 ^ commandId);
-
- updateFlags |= ActorUpdateFlags.Hotbar;
- }
-
- //Finds the first hotbar slot with a given commandId.
- //If the returned value is outside the hotbar, it indicates it wasn't found.
- public ushort FindFirstCommandSlotById(uint commandId)
- {
- if(commandId != 0)
- commandId |= 0xA0F00000;
-
- ushort firstSlot = (ushort)(charaWork.commandBorder + 30);
-
- for (ushort i = charaWork.commandBorder; i < charaWork.commandBorder + 30; i++)
- {
- if (charaWork.command[i] == commandId)
- {
- firstSlot = i;
- break;
- }
- }
-
- return firstSlot;
- }
-
- private void UpdateHotbarTimer(uint commandId, uint recastTimeMs)
- {
- ushort slot = FindFirstCommandSlotById(commandId);
- charaWork.parameterSave.commandSlot_recastTime[slot - charaWork.commandBorder] = Utils.UnixTimeStampUTC(DateTime.Now.AddMilliseconds(recastTimeMs));
- var slots = new List();
- slots.Add(slot);
- UpdateRecastTimers(slots);
- }
-
- private uint GetHotbarTimer(uint commandId)
- {
- ushort slot = FindFirstCommandSlotById(commandId);
- return charaWork.parameterSave.commandSlot_recastTime[slot - charaWork.commandBorder];
- }
-
- public override void Cast(uint spellId, uint targetId = 0)
- {
- if (aiContainer.CanChangeState())
- aiContainer.Cast(zone.FindActorInArea(targetId == 0 ? currentTarget : targetId), spellId);
- else if (aiContainer.IsCurrentState())
- // You are already casting.
- SendGameMessage(Server.GetWorldManager().GetActor(), 32536, 0x20);
- else
- // Please wait a moment and try again.
- SendGameMessage(Server.GetWorldManager().GetActor(), 32535, 0x20);
- }
-
- public override void Ability(uint abilityId, uint targetId = 0)
- {
- if (aiContainer.CanChangeState())
- aiContainer.Ability(zone.FindActorInArea(targetId == 0 ? currentTarget : targetId), abilityId);
- else
- // Please wait a moment and try again.
- SendGameMessage(Server.GetWorldManager().GetActor(), 32535, 0x20);
- }
-
- public override void WeaponSkill(uint skillId, uint targetId = 0)
- {
- if (aiContainer.CanChangeState())
- aiContainer.WeaponSkill(zone.FindActorInArea(targetId == 0 ? currentTarget : targetId), skillId);
- else
- // Please wait a moment and try again.
- SendGameMessage(Server.GetWorldManager().GetActor(), 32535, 0x20);
- }
-
- public override bool IsValidTarget(Character target, ValidTarget validTarget)
- {
- if (target == null)
- {
- // Target does not exist.
- SendGameMessage(Server.GetWorldManager().GetActor(), 32511, 0x20);
- return false;
- }
-
- if (target.isMovingToSpawn)
- {
- // That command cannot be performed on the current target.
- SendGameMessage(Server.GetWorldManager().GetActor(), 32547, 0x20);
- return false;
- }
-
- // enemy only
- if ((validTarget & ValidTarget.Enemy) != 0)
- {
- // todo: this seems ambiguous
- if (target.isStatic)
- {
- // That command cannot be performed on the current target.
- SendGameMessage(Server.GetWorldManager().GetActor(), 32547, 0x20);
- return false;
- }
- if (currentParty != null && target.currentParty == currentParty)
- {
- // That command cannot be performed on a party member.
- SendGameMessage(Server.GetWorldManager().GetActor(), 32548, 0x20);
- return false;
- }
- // todo: pvp?
- if (target.allegiance == allegiance)
- {
- // That command cannot be performed on an ally.
- SendGameMessage(Server.GetWorldManager().GetActor(), 32549, 0x20);
- return false;
- }
-
- bool partyEngaged = false;
- // todo: replace with confrontation status effect? (see how dsp does it)
- if (target.aiContainer.IsEngaged())
- {
- if (currentParty != null)
- {
- if (target is BattleNpc)
- {
- var helpingActorId = ((BattleNpc)target).GetMobMod((uint)MobModifier.CallForHelp);
- partyEngaged = this.actorId == helpingActorId || (((BattleNpc)target).GetMobMod((uint)MobModifier.FreeForAll) != 0);
- }
-
- if (!partyEngaged)
- {
- foreach (var memberId in ((Party)currentParty).members)
- {
- if (memberId == target.currentLockedTarget)
- {
- partyEngaged = true;
- break;
- }
- }
- }
- }
- else if (target.currentLockedTarget == actorId)
- {
- partyEngaged = true;
- }
- }
- else
- {
- partyEngaged = true;
- }
-
- if (!partyEngaged)
- {
- // That target is already engaged.
- SendGameMessage(Server.GetWorldManager().GetActor(), 32520, 0x20);
- return false;
- }
- }
-
- if ((validTarget & ValidTarget.Ally) != 0 && target.allegiance != allegiance)
- {
- // That command cannot be performed on the current target.
- SendGameMessage(Server.GetWorldManager().GetActor(), 32547, 0x20);
- return false;
- }
-
- // todo: isStatic seems ambiguous?
- if ((validTarget & ValidTarget.NPC) != 0 && target.isStatic)
- return true;
-
- // todo: why is player always zoning?
- // cant target if zoning
- if (target is Player && ((Player)target).playerSession.isUpdatesLocked)
- {
- // That command cannot be performed on the current target.
- SendGameMessage(Server.GetWorldManager().GetActor(), 32547, 0x20);
- return false;
- }
-
- return true;
- }
-
- //Do we need separate functions? they check the same things
- public override bool CanUse(Character target, BattleCommand skill, CommandResult error = null)
- {
- if (!skill.IsValidMainTarget(this, target, error) || !IsValidTarget(target, skill.mainTarget))
- {
- // error packet is set in IsValidTarget
- return false;
- }
-
- //Might want to do these with a BattleAction instead to be consistent with the rest of command stuff
- if (GetHotbarTimer(skill.id) > Utils.UnixTimeStampUTC())
- {
- // todo: this needs confirming
- // Please wait a moment and try again.
- error?.SetTextId(32535);
- return false;
- }
-
- if (Utils.XZDistance(positionX, positionZ, target.positionX, target.positionZ) > skill.range)
- {
- // The target is too far away.
- error?.SetTextId(32539);
- return false;
- }
-
- if (Utils.XZDistance(positionX, positionZ, target.positionX, target.positionZ) < skill.minRange)
- {
- // The target is too close.
- error?.SetTextId(32538);
- return false;
- }
-
- if (target.positionY - positionY > (skill.rangeHeight / 2))
- {
- // The target is too far above you.
- error?.SetTextId(32540);
- return false;
- }
-
- if (positionY - target.positionY > (skill.rangeHeight / 2))
- {
- // The target is too far below you.
- error?.SetTextId(32541);
- return false;
- }
-
- if (skill.CalculateMpCost(this) > GetMP())
- {
- // You do not have enough MP.
- error?.SetTextId(32545);
- return false;
- }
-
- if (skill.CalculateTpCost(this) > GetTP())
- {
- // You do not have enough TP.
- error?.SetTextId(32546);
- return false;
- }
-
- //Proc requirement
- if (skill.procRequirement != BattleCommandProcRequirement.None && !charaWork.battleTemp.timingCommandFlag[(int)skill.procRequirement - 1])
- {
- //Conditions for use are not met
- error?.SetTextId(32556);
- return false;
- }
-
-
- return true;
- }
-
- public override void OnAttack(State state, CommandResult action, ref CommandResult error)
- {
- var target = state.GetTarget();
-
- base.OnAttack(state, action, ref error);
-
- // todo: switch based on main weap (also probably move this anim assignment somewhere else)
- action.animation = 0x19001000;
- if (error == null)
- {
- // melee attack animation
- //action.animation = 0x19001000;
- }
- if (target is BattleNpc)
- {
- ((BattleNpc)target).hateContainer.UpdateHate(this, action.enmity);
- }
-
- LuaEngine.GetInstance().OnSignal("playerAttack");
- }
-
- public override void OnCast(State state, CommandResult[] actions, BattleCommand spell, ref CommandResult[] errors)
- {
- // todo: update hotbar timers to skill's recast time (also needs to be done on class change or equip crap)
- base.OnCast(state, actions, spell, ref errors);
- // todo: should just make a thing that updates the one slot cause this is dumb as hell
- UpdateHotbarTimer(spell.id, spell.recastTimeMs);
- //LuaEngine.GetInstance().OnSignal("spellUse");
- }
-
- public override void OnWeaponSkill(State state, CommandResult[] actions, BattleCommand skill, ref CommandResult[] errors)
- {
- // todo: update hotbar timers to skill's recast time (also needs to be done on class change or equip crap)
- base.OnWeaponSkill(state, actions, skill, ref errors);
-
- // todo: should just make a thing that updates the one slot cause this is dumb as hell
- UpdateHotbarTimer(skill.id, skill.recastTimeMs);
- // todo: this really shouldnt be called on each ws?
- lua.LuaEngine.CallLuaBattleFunction(this, "onWeaponSkill", this, state.GetTarget(), skill);
- LuaEngine.GetInstance().OnSignal("weaponskillUse");
- }
-
- public override void OnAbility(State state, CommandResult[] actions, BattleCommand ability, ref CommandResult[] errors)
- {
- base.OnAbility(state, actions, ability, ref errors);
- UpdateHotbarTimer(ability.id, ability.recastTimeMs);
- LuaEngine.GetInstance().OnSignal("abilityUse");
- }
-
- //Handles exp being added, does not handle figuring out exp bonus from buffs or skill/link chains or any of that
- //Returns CommandResults that can be sent to display the EXP gained number and level ups
- //exp should be a ushort single the exp graphic overflows after ~65k
- public List AddExp(int exp, byte classId, byte bonusPercent = 0)
- {
- List actionList = new List();
- exp += (int) Math.Ceiling((exp * bonusPercent / 100.0f));
-
- //You earn [exp] (+[bonusPercent]%) experience points.
- //In non-english languages there are unique messages for each language, hence the use of ClassExperienceTextIds
- actionList.Add(new CommandResult(actorId, BattleUtils.ClassExperienceTextIds[classId], 0, (ushort)exp, bonusPercent));
-
- bool leveled = false;
- int diff = MAXEXP[GetLevel() - 1] - charaWork.battleSave.skillPoint[classId - 1];
- //While there is enough experience to level up, keep leveling up, unlocking skills and removing experience from exp until we don't have enough to level up
- while (exp >= diff && GetLevel() < charaWork.battleSave.skillLevelCap[classId])
- {
- //Level up
- LevelUp(classId, actionList);
- leveled = true;
- //Reduce exp based on how much exp is needed to level
- exp -= diff;
- diff = MAXEXP[GetLevel() - 1];
- }
-
- if(leveled)
- {
- //Set exp to current class to 0 so that exp is added correctly
- charaWork.battleSave.skillPoint[classId - 1] = 0;
- //send new level
- ActorPropertyPacketUtil levelPropertyPacket = new ActorPropertyPacketUtil("charaWork/stateForAll", this);
- levelPropertyPacket.AddProperty(String.Format("charaWork.battleSave.skillLevel[{0}]", classId - 1));
- levelPropertyPacket.AddProperty("charaWork.parameterSave.state_mainSkillLevel");
- QueuePackets(levelPropertyPacket.Done());
-
- Database.SetLevel(this, classId, GetLevel());
- Database.SavePlayerCurrentClass(this);
- }
- //Cap experience for level 50
- charaWork.battleSave.skillPoint[classId - 1] = Math.Min(charaWork.battleSave.skillPoint[classId - 1] + exp, MAXEXP[GetLevel() - 1]);
-
- ActorPropertyPacketUtil expPropertyPacket = new ActorPropertyPacketUtil("charaWork/battleStateForSelf", this);
- expPropertyPacket.AddProperty(String.Format("charaWork.battleSave.skillPoint[{0}]", classId - 1));
-
- QueuePackets(expPropertyPacket.Done());
- Database.SetExp(this, classId, charaWork.battleSave.skillPoint[classId - 1]);
-
- return actionList;
- }
-
- //Equips any abilities for the given classId at the given level. If actionList is not null, adds a "You learn Command" message
- private void EquipAbilitiesAtLevel(byte classId, short level, List actionList = null)
- {
- //If there's any abilites that unlocks at this level, equip them.
- List commandIds = Server.GetWorldManager().GetBattleCommandIdByLevel(classId, GetLevel());
- foreach (ushort commandId in commandIds)
- {
- EquipAbilityInFirstOpenSlot(classId, commandId, false);
- byte jobId = ConvertClassIdToJobId(classId);
- if (jobId != classId)
- EquipAbilityInFirstOpenSlot(jobId, commandId, false);
-
- //33926: You learn [command].
- if (actionList != null)
- {
- if (classId == GetCurrentClassOrJob() || jobId == GetCurrentClassOrJob())
- actionList.Add(new CommandResult(actorId, 33926, 0, commandId));
- }
- }
- }
-
- //Increaess level of current class and equips new abilities earned at that level
- public void LevelUp(byte classId, List actionList = null)
- {
- if (charaWork.battleSave.skillLevel[classId - 1] < charaWork.battleSave.skillLevelCap[classId])
- {
- //Increase level
- charaWork.battleSave.skillLevel[classId - 1]++;
- charaWork.parameterSave.state_mainSkillLevel++;
-
- //33909: You attain level [level].
- if (actionList != null)
- actionList.Add(new CommandResult(actorId, 33909, 0, (ushort)charaWork.battleSave.skillLevel[classId - 1]));
-
- EquipAbilitiesAtLevel(classId, GetLevel(), actionList);
- }
- }
-
- public static byte ConvertClassIdToJobId(byte classId)
- {
- byte jobId = classId;
-
- switch(classId)
- {
- case CLASSID_PUG:
- case CLASSID_GLA:
- case CLASSID_MRD:
- jobId += 13;
- break;
- case CLASSID_ARC:
- case CLASSID_LNC:
- jobId += 11;
- break;
- case CLASSID_THM:
- case CLASSID_CNJ:
- jobId += 4;
- break;
- }
-
- return jobId;
- }
-
- public void SetCurrentJob(byte jobId)
- {
- currentJob = jobId;
- BroadcastPacket(SetCurrentJobPacket.BuildPacket(actorId, jobId), true);
- Database.LoadHotbar(this);
- SendCharaExpInfo();
- }
-
- //Gets the id of the player's current job. If they aren't a job, gets the id of their class
- public byte GetCurrentClassOrJob()
- {
- if (currentJob != 0)
- return (byte) currentJob;
- return charaWork.parameterSave.state_mainSkill[0];
- }
-
- public void hpstuff(uint hp)
- {
- SetMaxHP(hp);
- SetHP(hp);
- mpMaxBase = (ushort)hp;
- charaWork.parameterSave.mpMax = (short)hp;
- charaWork.parameterSave.mp = (short)hp;
- AddTP(3000);
- updateFlags |= ActorUpdateFlags.HpTpMp;
- }
-
- public void SetCombos(int comboId1 = 0, int comboId2 = 0)
- {
- SetCombos(new int[] { comboId1, comboId2 });
- }
-
- public void SetCombos(int[] comboIds)
- {
- Array.Copy(comboIds, playerWork.comboNextCommandId, 2);
-
- //If we're starting or continuing a combo chain, add the status effect and combo cost bonus
- if (comboIds[0] != 0)
- {
- StatusEffect comboEffect = new StatusEffect(this, Server.GetWorldManager().GetStatusEffect((uint) StatusEffectId.Combo));
- comboEffect.SetDuration(13);
- comboEffect.SetOverwritable(1);
- statusEffects.AddStatusEffect(comboEffect, this);
- playerWork.comboCostBonusRate = 1;
- }
- //Otherwise we're ending a combo, remove the status
- else
- {
- statusEffects.RemoveStatusEffect(statusEffects.GetStatusEffectById((uint) StatusEffectId.Combo));
- playerWork.comboCostBonusRate = 0;
- }
-
- ActorPropertyPacketUtil comboPropertyPacket = new ActorPropertyPacketUtil("playerWork/combo", this);
- comboPropertyPacket.AddProperty("playerWork.comboCostBonusRate");
- comboPropertyPacket.AddProperty("playerWork.comboNextCommandId[0]");
- comboPropertyPacket.AddProperty("playerWork.comboNextCommandId[1]");
- QueuePackets(comboPropertyPacket.Done());
- }
-
- public override void CalculateBaseStats()
- {
- base.CalculateBaseStats();
- //Add weapon property mod
- var equip = GetEquipment();
- var mainHandItem = equip.GetItemAtSlot(SLOT_MAINHAND);
- var damageAttribute = 0;
- var attackDelay = 3000;
- var hitCount = 1;
-
- if (mainHandItem != null)
- {
- var mainHandWeapon = (Server.GetItemGamedata(mainHandItem.itemId) as WeaponItem);
- damageAttribute = mainHandWeapon.damageAttributeType1;
- attackDelay = (int) (mainHandWeapon.damageInterval * 1000);
- hitCount = mainHandWeapon.frequency;
- }
-
- var hasShield = equip.GetItemAtSlot(SLOT_OFFHAND) != null ? 1 : 0;
- SetMod((uint)Modifier.CanBlock, hasShield);
-
- SetMod((uint)Modifier.AttackType, damageAttribute);
- SetMod((uint)Modifier.Delay, attackDelay);
- SetMod((uint)Modifier.HitCount, hitCount);
-
- //These stats all correlate in a 3:2 fashion
- //It seems these stats don't actually increase their respective stats. The magic stats do, however
- AddMod((uint)Modifier.Attack, (long)(GetMod(Modifier.Strength) * 0.667));
- AddMod((uint)Modifier.Accuracy, (long)(GetMod(Modifier.Dexterity) * 0.667));
- AddMod((uint)Modifier.Defense, (long)(GetMod(Modifier.Vitality) * 0.667));
-
- //These stats correlate in a 4:1 fashion. (Unsure if MND is accurate but it would make sense for it to be)
- AddMod((uint)Modifier.AttackMagicPotency, (long)((float)GetMod(Modifier.Intelligence) * 0.25));
-
- AddMod((uint)Modifier.MagicAccuracy, (long)((float)GetMod(Modifier.Mind) * 0.25));
- AddMod((uint)Modifier.HealingMagicPotency, (long)((float)GetMod(Modifier.Mind) * 0.25));
-
- AddMod((uint)Modifier.MagicEvasion, (long)((float)GetMod(Modifier.Piety) * 0.25));
- AddMod((uint)Modifier.EnfeeblingMagicPotency, (long)((float)GetMod(Modifier.Piety) * 0.25));
-
- //VIT correlates to HP in a 1:1 fashion
- AddMod((uint)Modifier.Hp, (long)((float)Modifier.Vitality));
-
- CalculateTraitMods();
- }
-
- public bool HasTrait(ushort id)
- {
- BattleTrait trait = Server.GetWorldManager().GetBattleTrait(id);
-
- return HasTrait(trait);
- }
-
- public bool HasTrait(BattleTrait trait)
- {
- return (trait != null) && (trait.job == GetClass()) && (trait.level <= GetLevel());
- }
-
- public void CalculateTraitMods()
- {
- var traitIds = Server.GetWorldManager().GetAllBattleTraitIdsForClass((byte) GetClass());
-
- foreach(var traitId in traitIds)
- {
- var trait = Server.GetWorldManager().GetBattleTrait(traitId);
- if(HasTrait(trait))
- {
- AddMod(trait.modifier, trait.bonus);
- }
- }
- }
-
- public bool HasItemEquippedInSlot(uint itemId, ushort slot)
- {
- var equippedItem = equipment.GetItemAtSlot(slot);
-
- return equippedItem != null && equippedItem.itemId == itemId;
- }
-
- public Retainer GetSpawnedRetainer()
- {
- return currentSpawnedRetainer;
- }
-
- public void StartTradeTransaction(Player otherPlayer)
- {
- myOfferings = new ReferencedItemPackage(this, ItemPackage.MAXSIZE_TRADE, ItemPackage.TRADE);
- otherTrader = otherPlayer;
- isTradeAccepted = false;
- }
-
- public Player GetOtherTrader()
- {
- return otherTrader;
- }
-
- public ReferencedItemPackage GetTradeOfferings()
- {
- return myOfferings;
- }
-
- public bool IsTrading()
- {
- return otherTrader != null;
- }
-
- public bool IsTradeAccepted()
- {
- return isTradeAccepted;
- }
-
- public void AddTradeItem(ushort slot, ItemRefParam chosenItem, int tradeQuantity)
- {
- if (!IsTrading())
- return;
-
- //Get chosen item
- InventoryItem offeredItem = itemPackages[chosenItem.itemPackage].GetItemAtSlot(chosenItem.slot);
- offeredItem.SetTradeQuantity(tradeQuantity);
-
- myOfferings.Set(slot, offeredItem);
- SendTradePackets();
- }
-
- public void RemoveTradeItem(ushort slot)
- {
- if (!IsTrading())
- return;
-
- InventoryItem offeredItem = myOfferings.GetItemAtSlot(slot);
- offeredItem.SetNormal();
-
- myOfferings.Clear(slot);
- SendTradePackets();
- }
-
- public void ClearTradeItems()
- {
- if (!IsTrading())
- return;
-
- for (ushort i = 0; i < myOfferings.GetCapacity(); i++)
- {
- InventoryItem offeredItem = myOfferings.GetItemAtSlot(i);
- if (offeredItem != null)
- offeredItem.SetNormal();
- }
-
- myOfferings.ClearAll();
- SendTradePackets();
- }
-
- private void SendTradePackets()
- {
- //Send to self
- QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
- myOfferings.SendUpdate(this);
- QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
-
- //Send to other trader
- otherTrader.QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
- myOfferings.SendUpdateAsItemPackage(otherTrader);
- otherTrader.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
- }
-
- public void AcceptTrade(bool accepted)
- {
- if (!IsTrading())
- return;
- isTradeAccepted = accepted;
- }
-
- public void FinishTradeTransaction()
- {
- if (myOfferings != null)
- {
- myOfferings.ClearAll();
- for (ushort i = 0; i < myOfferings.GetCapacity(); i++)
- {
- InventoryItem offeredItem = myOfferings.GetItemAtSlot(i);
- if (offeredItem != null)
- offeredItem.SetNormal();
- }
-
- QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
- myOfferings.SendUpdate(this);
- QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
- }
-
- isTradeAccepted = false;
- myOfferings = null;
- otherTrader = null;
- }
-
- }
-}
+/*
+===========================================================================
+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 .
+===========================================================================
+*/
+
+using Meteor.Common;
+using System;
+using System.Collections.Generic;
+using MoonSharp.Interpreter;
+using FFXIVClassic_Map_Server.dataobjects;
+using FFXIVClassic_Map_Server.dataobjects.chara;
+using FFXIVClassic_Map_Server.lua;
+using FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group;
+using FFXIVClassic_Map_Server.utils;
+using FFXIVClassic_Map_Server.actors.group;
+using FFXIVClassic_Map_Server.actors.chara.player;
+using FFXIVClassic_Map_Server.actors.director;
+using FFXIVClassic_Map_Server.actors.chara.npc;
+using FFXIVClassic_Map_Server.actors.chara.ai;
+using FFXIVClassic_Map_Server.actors.chara.ai.controllers;
+using FFXIVClassic_Map_Server.actors.chara.ai.utils;
+using FFXIVClassic_Map_Server.actors.chara.ai.state;
+using FFXIVClassic_Map_Server.actors.chara;
+using FFXIVClassic_Map_Server.packets.send;
+using FFXIVClassic_Map_Server.packets.send.actor;
+using FFXIVClassic_Map_Server.packets.send.events;
+using FFXIVClassic_Map_Server.packets.send.actor.inventory;
+using FFXIVClassic_Map_Server.packets.send.player;
+using FFXIVClassic_Map_Server.packets.send.actor.battle;
+using FFXIVClassic_Map_Server.packets.receive.events;
+using static FFXIVClassic_Map_Server.LuaUtils;
+
+namespace FFXIVClassic_Map_Server.Actors
+{
+ class Player : Character
+ {
+ public const int TIMER_TOTORAK = 0;
+ public const int TIMER_DZEMAEL = 1;
+ public const int TIMER_BOWL_OF_EMBERS_HARD = 2;
+ public const int TIMER_BOWL_OF_EMBERS = 3;
+ public const int TIMER_THORNMARCH = 4;
+ public const int TIMER_AURUMVALE = 5;
+ public const int TIMER_CUTTERSCRY = 6;
+ public const int TIMER_BATTLE_ALEPORT = 7;
+ public const int TIMER_BATTLE_HYRSTMILL = 8;
+ public const int TIMER_BATTLE_GOLDENBAZAAR = 9;
+ public const int TIMER_HOWLING_EYE_HARD = 10;
+ public const int TIMER_HOWLING_EYE = 11;
+ public const int TIMER_CASTRUM_TOWER = 12;
+ public const int TIMER_BOWL_OF_EMBERS_EXTREME = 13;
+ public const int TIMER_RIVENROAD = 14;
+ public const int TIMER_RIVENROAD_HARD = 15;
+ public const int TIMER_BEHEST = 16;
+ public const int TIMER_COMPANYBEHEST = 17;
+ public const int TIMER_RETURN = 18;
+ public const int TIMER_SKIRMISH = 19;
+
+ public const int NPCLS_GONE = 0;
+ public const int NPCLS_INACTIVE = 1;
+ public const int NPCLS_ACTIVE = 2;
+ public const int NPCLS_ALERT = 3;
+
+ public const int SLOT_MAINHAND = 0;
+ public const int SLOT_OFFHAND = 1;
+ public const int SLOT_THROWINGWEAPON = 4;
+ public const int SLOT_PACK = 5;
+ public const int SLOT_POUCH = 6;
+ public const int SLOT_HEAD = 8;
+ public const int SLOT_UNDERSHIRT = 9;
+ public const int SLOT_BODY = 10;
+ public const int SLOT_UNDERGARMENT = 11;
+ public const int SLOT_LEGS = 12;
+ public const int SLOT_HANDS = 13;
+ public const int SLOT_BOOTS = 14;
+ public const int SLOT_WAIST = 15;
+ public const int SLOT_NECK = 16;
+ public const int SLOT_EARS = 17;
+ public const int SLOT_WRISTS = 19;
+ public const int SLOT_RIGHTFINGER = 21;
+ public const int SLOT_LEFTFINGER = 22;
+
+ public static int[] MAXEXP = {570, 700, 880, 1100, 1500, 1800, 2300, 3200, 4300, 5000, //Level <= 10
+ 5900, 6800, 7700, 8700, 9700, 11000, 12000, 13000, 15000, 16000, //Level <= 20
+ 20000, 22000, 23000, 25000, 27000, 29000, 31000, 33000, 35000, 38000, //Level <= 30
+ 45000, 47000, 50000, 53000, 56000, 59000, 62000, 65000, 68000, 71000, //Level <= 40
+ 74000, 78000, 81000, 85000, 89000, 92000, 96000, 100000, 100000, 110000}; //Level <= 50
+
+ //Event Related
+ public uint currentEventOwner = 0;
+ public string currentEventName = "";
+ public Coroutine currentEventRunning;
+
+ //Player Info
+ public uint destinationZone;
+ public ushort destinationSpawnType;
+ public uint[] timers = new uint[20];
+ public uint currentTitle;
+ public uint playTime;
+ public uint lastPlayTimeUpdate;
+ public bool isGM = false;
+ public bool isZoneChanging = true;
+
+ //Trading
+ private Player otherTrader = null;
+ private ReferencedItemPackage myOfferings;
+ private bool isTradeAccepted = false;
+
+ //GC Related
+ public byte gcCurrent;
+ public byte gcRankLimsa;
+ public byte gcRankGridania;
+ public byte gcRankUldah;
+
+ //Mount Related
+ public bool hasChocobo;
+ public bool hasGoobbue;
+ public byte chocoboAppearance;
+ public string chocoboName;
+ public byte mountState = 0;
+
+ public uint achievementPoints;
+
+ //Property Array Request Stuff
+ private int lastPosition = 0;
+ private int lastStep = 0;
+
+ //Quest Actors (MUST MATCH playerWork.questScenario/questGuildleve)
+ public Quest[] questScenario = new Quest[16];
+ public uint[] questGuildleve = new uint[8];
+
+ //Aetheryte
+ public uint homepoint = 0;
+ public byte homepointInn = 0;
+
+ //Nameplate Stuff
+ public uint currentLSPlate = 0;
+ public byte repairType = 0;
+
+ //Retainer
+ RetainerMeetingRelationGroup retainerMeetingGroup = null;
+ public Retainer currentSpawnedRetainer = null;
+ public bool sentRetainerSpawn = false;
+
+ private List ownedDirectors = new List();
+ private Director loginInitDirector = null;
+
+ List hotbarSlotsToUpdate = new List();
+
+ public PlayerWork playerWork = new PlayerWork();
+
+ public Session playerSession;
+
+ public Player(Session cp, uint actorID) : base(actorID)
+ {
+ playerSession = cp;
+ actorName = String.Format("_pc{0:00000000}", actorID);
+ className = "Player";
+
+ moveSpeeds[0] = SetActorSpeedPacket.DEFAULT_STOP;
+ moveSpeeds[1] = SetActorSpeedPacket.DEFAULT_WALK;
+ moveSpeeds[2] = SetActorSpeedPacket.DEFAULT_RUN;
+ moveSpeeds[3] = SetActorSpeedPacket.DEFAULT_ACTIVE;
+
+ itemPackages[ItemPackage.NORMAL] = new ItemPackage(this, ItemPackage.MAXSIZE_NORMAL, ItemPackage.NORMAL);
+ itemPackages[ItemPackage.KEYITEMS] = new ItemPackage(this, ItemPackage.MAXSIZE_KEYITEMS, ItemPackage.KEYITEMS);
+ itemPackages[ItemPackage.CURRENCY_CRYSTALS] = new ItemPackage(this, ItemPackage.MAXSIZE_CURRANCY, ItemPackage.CURRENCY_CRYSTALS);
+ itemPackages[ItemPackage.MELDREQUEST] = new ItemPackage(this, ItemPackage.MAXSIZE_MELDREQUEST, ItemPackage.MELDREQUEST);
+ itemPackages[ItemPackage.BAZAAR] = new ItemPackage(this, ItemPackage.MAXSIZE_BAZAAR, ItemPackage.BAZAAR);
+ itemPackages[ItemPackage.LOOT] = new ItemPackage(this, ItemPackage.MAXSIZE_LOOT, ItemPackage.LOOT);
+ equipment = new ReferencedItemPackage(this, ItemPackage.MAXSIZE_EQUIPMENT, ItemPackage.EQUIPMENT);
+
+ //Set the Skill level caps of all FFXIV (classes)skills to 50
+ for (int i = 0; i < charaWork.battleSave.skillLevelCap.Length; i++)
+ {
+ if (i != CLASSID_PUG &&
+ i != CLASSID_MRD &&
+ i != CLASSID_GLA &&
+ i != CLASSID_MRD &&
+ i != CLASSID_ARC &&
+ i != CLASSID_LNC &&
+ i != CLASSID_THM &&
+ i != CLASSID_CNJ &&
+ i != CLASSID_CRP &&
+ i != CLASSID_BSM &&
+ i != CLASSID_ARM &&
+ i != CLASSID_GSM &&
+ i != CLASSID_LTW &&
+ i != CLASSID_WVR &&
+ i != CLASSID_ALC &&
+ i != CLASSID_CUL &&
+ i != CLASSID_MIN &&
+ i != CLASSID_BTN &&
+ i != CLASSID_FSH)
+ charaWork.battleSave.skillLevelCap[i] = 0xFF;
+ else
+ charaWork.battleSave.skillLevelCap[i] = 50;
+
+ }
+
+ charaWork.property[0] = 1;
+ charaWork.property[1] = 1;
+ charaWork.property[2] = 1;
+ charaWork.property[4] = 1;
+
+ charaWork.command[0] = 0xA0F00000 | 21001;
+ charaWork.command[1] = 0xA0F00000 | 21001;
+
+ charaWork.command[2] = 0xA0F00000 | 21002;
+ charaWork.command[3] = 0xA0F00000 | 12004;
+ charaWork.command[4] = 0xA0F00000 | 21005;
+ charaWork.command[5] = 0xA0F00000 | 21006;
+ charaWork.command[6] = 0xA0F00000 | 21007;
+ charaWork.command[7] = 0xA0F00000 | 12009;
+ charaWork.command[8] = 0xA0F00000 | 12010;
+ charaWork.command[9] = 0xA0F00000 | 12005;
+ charaWork.command[10] = 0xA0F00000 | 12007;
+ charaWork.command[11] = 0xA0F00000 | 12011;
+ charaWork.command[12] = 0xA0F00000 | 22012;
+ charaWork.command[13] = 0xA0F00000 | 22013;
+ charaWork.command[14] = 0xA0F00000 | 29497;
+ charaWork.command[15] = 0xA0F00000 | 22015;
+
+ charaWork.commandAcquired[27150 - 26000] = true;
+
+ playerWork.questScenarioComplete[110001 - 110001] = true;
+ playerWork.questGuildleveComplete[120050 - 120001] = true;
+
+ for (int i = 0; i < charaWork.additionalCommandAcquired.Length; i++ )
+ charaWork.additionalCommandAcquired[i] = true;
+
+ for (int i = 0; i < charaWork.commandCategory.Length; i++)
+ charaWork.commandCategory[i] = 1;
+
+ charaWork.battleTemp.generalParameter[3] = 1;
+
+ charaWork.eventSave.bazaarTax = 5;
+ charaWork.battleSave.potencial = 6.6f;
+
+ charaWork.battleSave.negotiationFlag[0] = true;
+
+ charaWork.commandCategory[0] = 1;
+ charaWork.commandCategory[1] = 1;
+
+ charaWork.parameterSave.commandSlot_compatibility[0] = true;
+ charaWork.parameterSave.commandSlot_compatibility[1] = true;
+
+ charaWork.commandBorder = 0x20;
+
+ charaWork.parameterTemp.tp = 0;
+
+ Database.LoadPlayerCharacter(this);
+ lastPlayTimeUpdate = Utils.UnixTimeStampUTC();
+
+ this.aiContainer = new AIContainer(this, new PlayerController(this), null, new TargetFind(this));
+ allegiance = CharacterTargetingAllegiance.Player;
+ CalculateBaseStats();
+ }
+
+ public List Create0x132Packets()
+ {
+ List packets = new List();
+ packets.Add(_0x132Packet.BuildPacket(actorId, 0xB, "commandForced"));
+ packets.Add(_0x132Packet.BuildPacket(actorId, 0xA, "commandDefault"));
+ packets.Add(_0x132Packet.BuildPacket(actorId, 0x6, "commandWeak"));
+ packets.Add(_0x132Packet.BuildPacket(actorId, 0x4, "commandContent"));
+ packets.Add(_0x132Packet.BuildPacket(actorId, 0x6, "commandJudgeMode"));
+ packets.Add(_0x132Packet.BuildPacket(actorId, 0x100, "commandRequest"));
+ packets.Add(_0x132Packet.BuildPacket(actorId, 0x100, "widgetCreate"));
+ packets.Add(_0x132Packet.BuildPacket(actorId, 0x100, "macroRequest"));
+ return packets;
+ }
+
+ /*
+ * PLAYER ARGS:
+ * Unknown - Bool
+ * Unknown - Bool
+ * Is Init Director - Bool
+ * Unknown - Bool
+ * Unknown - Number
+ * Unknown - Bool
+ * Timer Array - 20 Number
+ */
+
+ public override SubPacket CreateScriptBindPacket(Player requestPlayer)
+ {
+ List lParams;
+ if (IsMyPlayer(requestPlayer.actorId))
+ {
+ if (loginInitDirector != null)
+ lParams = LuaUtils.CreateLuaParamList("/Chara/Player/Player_work", false, false, true, loginInitDirector, true, 0, false, timers, true);
+ else
+ lParams = LuaUtils.CreateLuaParamList("/Chara/Player/Player_work", true, false, false, true, 0, false, timers, true);
+ }
+ else
+ lParams = LuaUtils.CreateLuaParamList("/Chara/Player/Player_work", false, false, false, false, false, true);
+
+ ActorInstantiatePacket.BuildPacket(actorId, actorName, className, lParams).DebugPrintSubPacket();
+
+
+ return ActorInstantiatePacket.BuildPacket(actorId, actorName, className, lParams);
+ }
+
+ public override List GetSpawnPackets(Player requestPlayer, ushort spawnType)
+ {
+ List subpackets = new List();
+ subpackets.Add(CreateAddActorPacket(8));
+ if (IsMyPlayer(requestPlayer.actorId))
+ subpackets.AddRange(Create0x132Packets());
+ subpackets.Add(CreateSpeedPacket());
+ subpackets.Add(CreateSpawnPositonPacket(this, spawnType));
+ subpackets.Add(CreateAppearancePacket());
+ subpackets.Add(CreateNamePacket());
+ subpackets.Add(_0xFPacket.BuildPacket(actorId));
+ subpackets.Add(CreateStatePacket());
+ subpackets.Add(CreateSubStatePacket());
+ subpackets.Add(CreateInitStatusPacket());
+ subpackets.Add(CreateSetActorIconPacket());
+ subpackets.Add(CreateIsZoneingPacket());
+ subpackets.AddRange(CreatePlayerRelatedPackets(requestPlayer.actorId));
+ subpackets.Add(CreateScriptBindPacket(requestPlayer));
+ return subpackets;
+ }
+
+ public List CreatePlayerRelatedPackets(uint requestingPlayerActorId)
+ {
+ List subpackets = new List();
+
+ if (gcCurrent != 0)
+ subpackets.Add(SetGrandCompanyPacket.BuildPacket(actorId, gcCurrent, gcRankLimsa, gcRankGridania, gcRankUldah));
+
+ if (currentTitle != 0)
+ subpackets.Add(SetPlayerTitlePacket.BuildPacket(actorId, currentTitle));
+
+ if (currentJob != 0)
+ subpackets.Add(SetCurrentJobPacket.BuildPacket(actorId, currentJob));
+
+ if (IsMyPlayer(requestingPlayerActorId))
+ {
+ subpackets.Add(SetSpecialEventWorkPacket.BuildPacket(actorId));
+
+ if (hasChocobo && chocoboName != null && !chocoboName.Equals(""))
+ {
+ subpackets.Add(SetChocoboNamePacket.BuildPacket(actorId, chocoboName));
+ subpackets.Add(SetHasChocoboPacket.BuildPacket(actorId, hasChocobo));
+ }
+
+ if (hasGoobbue)
+ subpackets.Add(SetHasGoobbuePacket.BuildPacket(actorId, hasGoobbue));
+
+ subpackets.Add(SetAchievementPointsPacket.BuildPacket(actorId, achievementPoints));
+
+ subpackets.Add(Database.GetLatestAchievements(this));
+ subpackets.Add(Database.GetAchievementsPacket(this));
+ }
+
+ if (mountState == 1)
+ subpackets.Add(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance));
+ else if (mountState == 2)
+ subpackets.Add(SetCurrentMountGoobbuePacket.BuildPacket(actorId, 1));
+
+ return subpackets;
+ }
+
+ public override List GetInitPackets()
+ {
+ ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("/_init", this);
+
+ propPacketUtil.AddProperty("charaWork.eventSave.bazaarTax");
+ propPacketUtil.AddProperty("charaWork.battleSave.potencial");
+
+ //Properties
+ for (int i = 0; i < charaWork.property.Length; i++)
+ {
+ if (charaWork.property[i] != 0)
+ propPacketUtil.AddProperty(String.Format("charaWork.property[{0}]", i));
+ }
+
+ //Parameters
+ propPacketUtil.AddProperty("charaWork.parameterSave.hp[0]");
+ propPacketUtil.AddProperty("charaWork.parameterSave.hpMax[0]");
+ propPacketUtil.AddProperty("charaWork.parameterSave.mp");
+ propPacketUtil.AddProperty("charaWork.parameterSave.mpMax");
+ propPacketUtil.AddProperty("charaWork.parameterTemp.tp");
+ propPacketUtil.AddProperty("charaWork.parameterSave.state_mainSkill[0]");
+ propPacketUtil.AddProperty("charaWork.parameterSave.state_mainSkillLevel");
+
+ //Status Times
+ for (int i = 0; i < charaWork.statusShownTime.Length; i++)
+ {
+ if (charaWork.statusShownTime[i] != 0)
+ propPacketUtil.AddProperty(String.Format("charaWork.statusShownTime[{0}]", i));
+ }
+
+ //General Parameters
+ for (int i = 3; i < charaWork.battleTemp.generalParameter.Length; i++)
+ {
+ if (charaWork.battleTemp.generalParameter[i] != 0)
+ propPacketUtil.AddProperty(String.Format("charaWork.battleTemp.generalParameter[{0}]", i));
+ }
+
+ propPacketUtil.AddProperty("charaWork.battleTemp.castGauge_speed[0]");
+ propPacketUtil.AddProperty("charaWork.battleTemp.castGauge_speed[1]");
+
+ //Battle Save Skillpoint
+ propPacketUtil.AddProperty(String.Format("charaWork.battleSave.skillPoint[{0}]", charaWork.parameterSave.state_mainSkill[0] - 1));
+
+ //Commands
+ propPacketUtil.AddProperty("charaWork.commandBorder");
+
+ propPacketUtil.AddProperty("charaWork.battleSave.negotiationFlag[0]");
+
+ for (int i = 0; i < charaWork.command.Length; i++)
+ {
+ if (charaWork.command[i] != 0)
+ {
+ propPacketUtil.AddProperty(String.Format("charaWork.command[{0}]", i));
+ //Recast Timers
+ if(i >= charaWork.commandBorder)
+ {
+ propPacketUtil.AddProperty(String.Format("charaWork.parameterTemp.maxCommandRecastTime[{0}]", i - charaWork.commandBorder));
+ propPacketUtil.AddProperty(String.Format("charaWork.parameterSave.commandSlot_recastTime[{0}]", i - charaWork.commandBorder));
+ }
+ }
+ }
+
+ for (int i = 0; i < charaWork.commandCategory.Length; i++)
+ {
+ charaWork.commandCategory[i] = 1;
+ if (charaWork.commandCategory[i] != 0)
+ propPacketUtil.AddProperty(String.Format("charaWork.commandCategory[{0}]", i));
+ }
+
+ for (int i = 0; i < charaWork.commandAcquired.Length; i++)
+ {
+ if (charaWork.commandAcquired[i] != false)
+ propPacketUtil.AddProperty(String.Format("charaWork.commandAcquired[{0}]", i));
+ }
+
+ for (int i = 0; i < charaWork.additionalCommandAcquired.Length; i++)
+ {
+ if (charaWork.additionalCommandAcquired[i] != false)
+ propPacketUtil.AddProperty(String.Format("charaWork.additionalCommandAcquired[{0}]", i));
+ }
+
+ for (int i = 0; i < charaWork.parameterSave.commandSlot_compatibility.Length; i++)
+ {
+ charaWork.parameterSave.commandSlot_compatibility[i] = true;
+ if (charaWork.parameterSave.commandSlot_compatibility[i])
+ propPacketUtil.AddProperty(String.Format("charaWork.parameterSave.commandSlot_compatibility[{0}]", i));
+ }
+
+ for (int i = 0; i < charaWork.parameterSave.commandSlot_recastTime.Length; i++)
+ {
+ if (charaWork.parameterSave.commandSlot_recastTime[i] != 0)
+ propPacketUtil.AddProperty(String.Format("charaWork.parameterSave.commandSlot_recastTime[{0}]", i));
+ }
+
+ //System
+ propPacketUtil.AddProperty("charaWork.parameterTemp.forceControl_float_forClientSelf[0]");
+ propPacketUtil.AddProperty("charaWork.parameterTemp.forceControl_float_forClientSelf[1]");
+ propPacketUtil.AddProperty("charaWork.parameterTemp.forceControl_int16_forClientSelf[0]");
+ propPacketUtil.AddProperty("charaWork.parameterTemp.forceControl_int16_forClientSelf[1]");
+
+ charaWork.parameterTemp.otherClassAbilityCount[0] = 4;
+ charaWork.parameterTemp.otherClassAbilityCount[1] = 5;
+ charaWork.parameterTemp.giftCount[1] = 5;
+
+ propPacketUtil.AddProperty("charaWork.parameterTemp.otherClassAbilityCount[0]");
+ propPacketUtil.AddProperty("charaWork.parameterTemp.otherClassAbilityCount[1]");
+ propPacketUtil.AddProperty("charaWork.parameterTemp.giftCount[1]");
+
+ propPacketUtil.AddProperty("charaWork.depictionJudge");
+
+ //Scenario
+ for (int i = 0; i < playerWork.questScenario.Length; i++)
+ {
+ if (playerWork.questScenario[i] != 0)
+ propPacketUtil.AddProperty(String.Format("playerWork.questScenario[{0}]", i));
+ }
+
+ //Guildleve - Local
+ for (int i = 0; i < playerWork.questGuildleve.Length; i++)
+ {
+ if (playerWork.questGuildleve[i] != 0)
+ propPacketUtil.AddProperty(String.Format("playerWork.questGuildleve[{0}]", i));
+ }
+
+ //Guildleve - Regional
+ for (int i = 0; i < work.guildleveId.Length; i++)
+ {
+ if (work.guildleveId[i] != 0)
+ propPacketUtil.AddProperty(String.Format("work.guildleveId[{0}]", i));
+ if (work.guildleveDone[i] != false)
+ propPacketUtil.AddProperty(String.Format("work.guildleveDone[{0}]", i));
+ if (work.guildleveChecked[i] != false)
+ propPacketUtil.AddProperty(String.Format("work.guildleveChecked[{0}]", i));
+ }
+
+ //Bazaar
+ CheckBazaarFlags(true);
+ if (charaWork.eventSave.repairType != 0)
+ propPacketUtil.AddProperty("charaWork.eventSave.repairType");
+ if (charaWork.eventTemp.bazaarRetail)
+ propPacketUtil.AddProperty("charaWork.eventTemp.bazaarRetail");
+ if (charaWork.eventTemp.bazaarRepair)
+ propPacketUtil.AddProperty("charaWork.eventTemp.bazaarRepair");
+ if (charaWork.eventTemp.bazaarMateria)
+ propPacketUtil.AddProperty("charaWork.eventTemp.bazaarMateria");
+
+ //NPC Linkshell
+ for (int i = 0; i < playerWork.npcLinkshellChatCalling.Length; i++)
+ {
+ if (playerWork.npcLinkshellChatCalling[i] != false)
+ propPacketUtil.AddProperty(String.Format("playerWork.npcLinkshellChatCalling[{0}]", i));
+ if (playerWork.npcLinkshellChatExtra[i] != false)
+ propPacketUtil.AddProperty(String.Format("playerWork.npcLinkshellChatExtra[{0}]", i));
+ }
+
+ propPacketUtil.AddProperty("playerWork.restBonusExpRate");
+
+ //Profile
+ propPacketUtil.AddProperty("playerWork.tribe");
+ propPacketUtil.AddProperty("playerWork.guardian");
+ propPacketUtil.AddProperty("playerWork.birthdayMonth");
+ propPacketUtil.AddProperty("playerWork.birthdayDay");
+ propPacketUtil.AddProperty("playerWork.initialTown");
+
+ return propPacketUtil.Done();
+ }
+
+ public void SendSeamlessZoneInPackets()
+ {
+ QueuePacket(SetMusicPacket.BuildPacket(actorId, zone.bgmDay, SetMusicPacket.EFFECT_FADEIN));
+ QueuePacket(SetWeatherPacket.BuildPacket(actorId, SetWeatherPacket.WEATHER_CLEAR, 1));
+ }
+
+ public void SendZoneInPackets(WorldManager world, ushort spawnType)
+ {
+ QueuePacket(SetActorIsZoningPacket.BuildPacket(actorId, false));
+ QueuePacket(SetDalamudPacket.BuildPacket(actorId, 0));
+ QueuePacket(SetMusicPacket.BuildPacket(actorId, zone.bgmDay, 0x01));
+ QueuePacket(SetWeatherPacket.BuildPacket(actorId, SetWeatherPacket.WEATHER_CLEAR, 1));
+
+ QueuePacket(SetMapPacket.BuildPacket(actorId, zone.regionId, zone.actorId));
+
+ QueuePackets(GetSpawnPackets(this, spawnType));
+ //GetSpawnPackets(actorId, spawnType).DebugPrintPacket();
+
+ #region Inventory & Equipment
+ QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true));
+ itemPackages[ItemPackage.NORMAL].SendFullPackage(this);
+ itemPackages[ItemPackage.CURRENCY_CRYSTALS].SendFullPackage(this);
+ itemPackages[ItemPackage.KEYITEMS].SendFullPackage(this);
+ itemPackages[ItemPackage.BAZAAR].SendFullPackage(this);
+ itemPackages[ItemPackage.MELDREQUEST].SendFullPackage(this);
+ itemPackages[ItemPackage.LOOT].SendFullPackage(this);
+ equipment.SendUpdate(this);
+ playerSession.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId));
+ #endregion
+
+ playerSession.QueuePacket(GetInitPackets());
+
+ List areaMasterSpawn = zone.GetSpawnPackets();
+ List debugSpawn = world.GetDebugActor().GetSpawnPackets();
+ List worldMasterSpawn = world.GetActor().GetSpawnPackets();
+
+ playerSession.QueuePacket(areaMasterSpawn);
+ playerSession.QueuePacket(debugSpawn);
+ playerSession.QueuePacket(worldMasterSpawn);
+
+ //Inn Packets (Dream, Cutscenes, Armoire)
+
+ if (zone.isInn)
+ {
+ SetCutsceneBookPacket cutsceneBookPacket = new SetCutsceneBookPacket();
+ for (int i = 0; i < 2048; i++)
+ cutsceneBookPacket.cutsceneFlags[i] = true;
+ SubPacket packet = cutsceneBookPacket.BuildPacket(actorId, "", 11, 1, 1);
+
+ packet.DebugPrintSubPacket();
+ QueuePacket(packet);
+ QueuePacket(SetPlayerItemStoragePacket.BuildPacket(actorId));
+ }
+
+ if (zone.GetWeatherDirector() != null)
+ {
+ playerSession.QueuePacket(zone.GetWeatherDirector().GetSpawnPackets());
+ }
+
+
+ foreach (Director director in ownedDirectors)
+ {
+ QueuePackets(director.GetSpawnPackets());
+ QueuePackets(director.GetInitPackets());
+ }
+
+ if (currentContentGroup != null)
+ currentContentGroup.SendGroupPackets(playerSession);
+
+ if (currentParty != null)
+ currentParty.SendGroupPackets(playerSession);
+ }
+
+ private void SendRemoveInventoryPackets(List slots)
+ {
+ int currentIndex = 0;
+
+ while (true)
+ {
+ if (slots.Count - currentIndex >= 64)
+ QueuePacket(InventoryRemoveX64Packet.BuildPacket(actorId, slots, ref currentIndex));
+ else if (slots.Count - currentIndex >= 32)
+ QueuePacket(InventoryRemoveX32Packet.BuildPacket(actorId, slots, ref currentIndex));
+ else if (slots.Count - currentIndex >= 16)
+ QueuePacket(InventoryRemoveX16Packet.BuildPacket(actorId, slots, ref currentIndex));
+ else if (slots.Count - currentIndex >= 8)
+ QueuePacket(InventoryRemoveX08Packet.BuildPacket(actorId, slots, ref currentIndex));
+ else if (slots.Count - currentIndex == 1)
+ QueuePacket(InventoryRemoveX01Packet.BuildPacket(actorId, slots[currentIndex]));
+ else
+ break;
+ }
+
+ }
+
+ public bool IsMyPlayer(uint otherActorId)
+ {
+ return actorId == otherActorId;
+ }
+
+ public void QueuePacket(SubPacket packet)
+
+ {
+ playerSession.QueuePacket(packet);
+ }
+
+ public void QueuePackets(List packets)
+ {
+ playerSession.QueuePacket(packets);
+ }
+
+ public void SendPacket(string path)
+ {
+ try
+ {
+ BasePacket packet = new BasePacket(path);
+
+ packet.ReplaceActorID(actorId);
+ var packets = packet.GetSubpackets();
+ QueuePackets(packets);
+ }
+ catch (Exception e)
+ {
+ this.SendMessage(SendMessagePacket.MESSAGE_TYPE_SYSTEM_ERROR, "[SendPacket]", "Unable to send packet.");
+ this.SendMessage(SendMessagePacket.MESSAGE_TYPE_SYSTEM_ERROR, "[SendPacket]", e.Message);
+ }
+ }
+
+ public void BroadcastPackets(List packets, bool sendToSelf)
+ {
+ foreach (SubPacket packet in packets)
+ {
+ if (sendToSelf)
+ {
+
+ SubPacket clonedPacket = new SubPacket(packet, actorId);
+ QueuePacket(clonedPacket);
+ }
+
+ foreach (Actor a in playerSession.actorInstanceList)
+ {
+ if (a is Player)
+ {
+ Player p = (Player)a;
+
+ if (p.Equals(this))
+ continue;
+
+ SubPacket clonedPacket = new SubPacket(packet, a.actorId);
+ p.QueuePacket(clonedPacket);
+ }
+ }
+ }
+ }
+
+ public void BroadcastPacket(SubPacket packet, bool sendToSelf)
+ {
+ if (sendToSelf)
+ {
+ SubPacket clonedPacket = new SubPacket(packet, actorId);
+ QueuePacket(clonedPacket);
+ }
+
+ foreach (Actor a in playerSession.actorInstanceList)
+ {
+ if (a is Player)
+ {
+ Player p = (Player)a;
+
+ if (p.Equals(this))
+ continue;
+
+ SubPacket clonedPacket = new SubPacket(packet, a.actorId);
+ p.QueuePacket(clonedPacket);
+ }
+ }
+ }
+
+ public void ChangeAnimation(uint animId)
+ {
+ Actor a = zone.FindActorInArea(currentTarget);
+ if (a is Npc)
+ ((Npc)a).animationId = animId;
+ }
+
+ public void SetDCFlag(bool flag)
+ {
+ if (flag)
+ {
+ BroadcastPacket(SetActorIconPacket.BuildPacket(actorId, SetActorIconPacket.DISCONNECTING), true);
+ }
+ else
+ {
+ if (isGM)
+ BroadcastPacket(SetActorIconPacket.BuildPacket(actorId, SetActorIconPacket.ISGM), true);
+ else
+ BroadcastPacket(SetActorIconPacket.BuildPacket(actorId, 0), true);
+ }
+ }
+
+ public void CleanupAndSave()
+ {
+ playerSession.LockUpdates(true);
+
+ //Remove actor from zone and main server list
+ zone.RemoveActorFromZone(this);
+
+ //Set Destination to 0
+ this.destinationZone = 0;
+ this.destinationSpawnType = 0;
+
+ //Clean up parties
+ RemoveFromCurrentPartyAndCleanup();
+
+ //Save Player
+ Database.SavePlayerPlayTime(this);
+ Database.SavePlayerPosition(this);
+ Database.SavePlayerStatusEffects(this);
+ }
+
+ public void CleanupAndSave(uint destinationZone, ushort spawnType, float destinationX, float destinationY, float destinationZ, float destinationRot)
+ {
+ playerSession.LockUpdates(true);
+
+ //Remove actor from zone and main server list
+ zone.RemoveActorFromZone(this);
+
+ //Clean up parties
+ RemoveFromCurrentPartyAndCleanup();
+
+ //Set destination
+ this.destinationZone = destinationZone;
+ this.destinationSpawnType = spawnType;
+ this.positionX = destinationX;
+ this.positionY = destinationY;
+ this.positionZ = destinationZ;
+ this.rotation = destinationRot;
+
+ this.statusEffects.RemoveStatusEffectsByFlags((uint)StatusEffectFlags.LoseOnZoning);
+
+ //Save Player
+ Database.SavePlayerPlayTime(this);
+ Database.SavePlayerPosition(this);
+ Database.SavePlayerStatusEffects(this);
+ }
+
+ public Area GetZone()
+ {
+ return zone;
+ }
+
+ public void SendMessage(uint logType, string sender, string message)
+ {
+ QueuePacket(SendMessagePacket.BuildPacket(actorId, logType, sender, message));
+ }
+
+ public void Logout()
+ {
+ // todo: really this should be in CleanupAndSave but we might want logout/disconnect handled separately for some effects
+ QueuePacket(LogoutPacket.BuildPacket(actorId));
+ statusEffects.RemoveStatusEffectsByFlags((uint)StatusEffectFlags.LoseOnLogout);
+ CleanupAndSave();
+ }
+
+ public void QuitGame()
+ {
+ QueuePacket(QuitPacket.BuildPacket(actorId));
+ statusEffects.RemoveStatusEffectsByFlags((uint)StatusEffectFlags.LoseOnLogout);
+ CleanupAndSave();
+ }
+
+ public uint GetPlayTime(bool doUpdate)
+ {
+ if (doUpdate)
+ {
+ uint curTime = Utils.UnixTimeStampUTC();
+ playTime += curTime - lastPlayTimeUpdate;
+ lastPlayTimeUpdate = curTime;
+ }
+
+ return playTime;
+ }
+
+ public void SavePlayTime()
+ {
+ Database.SavePlayerPlayTime(this);
+ }
+
+ public void ChangeMusic(ushort musicId)
+ {
+ QueuePacket(SetMusicPacket.BuildPacket(actorId, musicId, 1));
+ }
+
+ public void SendMountAppearance()
+ {
+ if (mountState == 1)
+ BroadcastPacket(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance), true);
+ else if (mountState == 2)
+ BroadcastPacket(SetCurrentMountGoobbuePacket.BuildPacket(actorId, 1), true);
+ }
+
+ public void SetMountState(byte mountState)
+ {
+ this.mountState = mountState;
+ SendMountAppearance();
+ }
+
+ public byte GetMountState()
+ {
+ return mountState;
+ }
+
+ public void DoEmote(uint targettedActor, uint animId, uint descId)
+ {
+ BroadcastPacket(ActorDoEmotePacket.BuildPacket(actorId, targettedActor, animId, descId), true);
+ }
+
+ public void SendGameMessage(Actor sourceActor, Actor textIdOwner, ushort textId, byte log, params object[] msgParams)
+ {
+ if (msgParams == null || msgParams.Length == 0)
+ {
+ QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, sourceActor.actorId, textIdOwner.actorId, textId, log));
+ }
+ else
+ QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, sourceActor.actorId, textIdOwner.actorId, textId, log, LuaUtils.CreateLuaParamList(msgParams)));
+ }
+
+ public void SendGameMessage(Actor textIdOwner, ushort textId, byte log, params object[] msgParams)
+ {
+ if (msgParams == null || msgParams.Length == 0)
+ QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, textIdOwner.actorId, textId, log));
+ else
+ QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, textIdOwner.actorId, textId, log, LuaUtils.CreateLuaParamList(msgParams)));
+ }
+
+ public void SendGameMessageCustomSender(Actor textIdOwner, ushort textId, byte log, string customSender, params object[] msgParams)
+ {
+ if (msgParams == null || msgParams.Length == 0)
+ QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, textIdOwner.actorId, textId, customSender, log));
+ else
+ QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, textIdOwner.actorId, textId, customSender, log, LuaUtils.CreateLuaParamList(msgParams)));
+ }
+
+ public void SendGameMessageDisplayIDSender(Actor textIdOwner, ushort textId, byte log, uint displayId, params object[] msgParams)
+ {
+ if (msgParams == null || msgParams.Length == 0)
+ QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, textIdOwner.actorId, textId, displayId, log));
+ else
+ QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, textIdOwner.actorId, textId, displayId, log, LuaUtils.CreateLuaParamList(msgParams)));
+ }
+
+ public void BroadcastWorldMessage(ushort worldMasterId, params object[] msgParams)
+ {
+ //SubPacket worldMasterMessage =
+ //zone.BroadcastPacketAroundActor(this, worldMasterMessage);
+ }
+
+ public void GraphicChange(uint slot, uint graphicId)
+ {
+ appearanceIds[slot] = graphicId;
+ }
+
+ public void GraphicChange(uint slot, uint weapId, uint equipId, uint variantId, uint colorId)
+ {
+
+ uint mixedVariantId;
+
+ if (weapId == 0)
+ mixedVariantId = ((variantId & 0x1F) << 5) | colorId;
+ else
+ mixedVariantId = variantId;
+
+ uint graphicId =
+ (weapId & 0x3FF) << 20 |
+ (equipId & 0x3FF) << 10 |
+ (mixedVariantId & 0x3FF);
+
+ appearanceIds[slot] = graphicId;
+
+ }
+
+ public void SendAppearance()
+ {
+ BroadcastPacket(CreateAppearancePacket(), true);
+ }
+
+ public void SendCharaExpInfo()
+ {
+ if (lastStep == 0)
+ {
+ int maxLength;
+ if ((sizeof(short) * charaWork.battleSave.skillLevel.Length)-lastPosition < 0x5E)
+ maxLength = (sizeof(short) * charaWork.battleSave.skillLevel.Length) - lastPosition;
+ else
+ maxLength = 0x5E;
+
+ byte[] skillLevelBuffer = new byte[maxLength];
+ Buffer.BlockCopy(charaWork.battleSave.skillLevel, 0, skillLevelBuffer, 0, skillLevelBuffer.Length);
+ SetActorPropetyPacket charaInfo1 = new SetActorPropetyPacket("charaWork/exp");
+
+ charaInfo1.SetIsArrayMode(true);
+ if (maxLength == 0x5E)
+ {
+ charaInfo1.AddBuffer(Utils.MurmurHash2("charaWork.battleSave.skillLevel", 0), skillLevelBuffer, 0, skillLevelBuffer.Length, 0x0);
+ lastPosition += maxLength;
+ }
+ else
+ {
+ charaInfo1.AddBuffer(Utils.MurmurHash2("charaWork.battleSave.skillLevel", 0), skillLevelBuffer, 0, skillLevelBuffer.Length, 0x3);
+ lastPosition = 0;
+ lastStep++;
+ }
+
+ charaInfo1.AddTarget();
+
+ QueuePacket(charaInfo1.BuildPacket(actorId));
+ }
+ else if (lastStep == 1)
+ {
+ int maxLength;
+ if ((sizeof(short) * charaWork.battleSave.skillLevelCap.Length) - lastPosition < 0x5E)
+ maxLength = (sizeof(short) * charaWork.battleSave.skillLevelCap.Length) - lastPosition;
+ else
+ maxLength = 0x5E;
+
+ byte[] skillCapBuffer = new byte[maxLength];
+ Buffer.BlockCopy(charaWork.battleSave.skillLevelCap, lastPosition, skillCapBuffer, 0, skillCapBuffer.Length);
+ SetActorPropetyPacket charaInfo1 = new SetActorPropetyPacket("charaWork/exp");
+
+
+ if (maxLength == 0x5E)
+ {
+ charaInfo1.SetIsArrayMode(true);
+ charaInfo1.AddBuffer(Utils.MurmurHash2("charaWork.battleSave.skillLevelCap", 0), skillCapBuffer, 0, skillCapBuffer.Length, 0x1);
+ lastPosition += maxLength;
+ }
+ else
+ {
+ charaInfo1.SetIsArrayMode(false);
+ charaInfo1.AddBuffer(Utils.MurmurHash2("charaWork.battleSave.skillLevelCap", 0), skillCapBuffer, 0, skillCapBuffer.Length, 0x3);
+ lastStep = 0;
+ lastPosition = 0;
+ }
+
+ charaInfo1.AddTarget();
+
+ QueuePacket(charaInfo1.BuildPacket(actorId));
+ }
+
+ }
+
+ public int GetHighestLevel()
+ {
+ int max = 0;
+ foreach (short level in charaWork.battleSave.skillLevel)
+ {
+ if (level > max)
+ max = level;
+ }
+ return max;
+ }
+
+ public InventoryItem[] GetGearset(ushort classId)
+ {
+ return Database.GetEquipment(this, classId);
+ }
+
+ public void PrepareClassChange(byte classId)
+ {
+ SendCharaExpInfo();
+ }
+
+ public void DoClassChange(byte classId)
+ {
+ //load hotbars
+ //Calculate stats
+ //Calculate hp/mp
+
+ //Get Potenciel ??????
+
+ //Set HP/MP/TP PARAMS
+
+ //Set mainskill and level
+
+ //Set Parameters
+
+ //Set current EXP
+
+ //Set Hotbar Commands 1
+ //Set Hotbar Commands 2
+ //Set Hotbar Commands 3
+
+ //Check if bonus point available... set
+
+ //Remove buffs that fall off when changing class
+ CommandResultContainer resultContainer = new CommandResultContainer();
+ statusEffects.RemoveStatusEffectsByFlags((uint)StatusEffectFlags.LoseOnClassChange, resultContainer);
+ resultContainer.CombineLists();
+ DoBattleAction(0, 0x7c000062, resultContainer.GetList());
+
+ //Set rested EXP
+ charaWork.parameterSave.state_mainSkill[0] = classId;
+ charaWork.parameterSave.state_mainSkillLevel = charaWork.battleSave.skillLevel[classId-1];
+ playerWork.restBonusExpRate = 0.0f;
+ for(int i = charaWork.commandBorder; i < charaWork.command.Length; i++)
+ {
+ charaWork.command[i] = 0;
+ charaWork.commandCategory[i] = 0;
+ }
+
+ //If new class, init abilties and level
+ if (charaWork.battleSave.skillLevel[classId - 1] <= 0)
+ {
+ UpdateClassLevel(classId, 1);
+ EquipAbilitiesAtLevel(classId, 1);
+ }
+
+ ActorPropertyPacketUtil propertyBuilder = new ActorPropertyPacketUtil("charaWork/stateForAll", this);
+
+ propertyBuilder.AddProperty("charaWork.parameterSave.state_mainSkill[0]");
+ propertyBuilder.AddProperty("charaWork.parameterSave.state_mainSkillLevel");
+ propertyBuilder.NewTarget("playerWork/expBonus");
+ propertyBuilder.AddProperty("playerWork.restBonusExpRate");
+ propertyBuilder.NewTarget("charaWork/battleStateForSelf");
+ propertyBuilder.AddProperty(String.Format("charaWork.battleSave.skillPoint[{0}]", classId - 1));
+ Database.LoadHotbar(this);
+
+ var time = Utils.UnixTimeStampUTC();
+ for(int i = charaWork.commandBorder; i < charaWork.command.Length; i++)
+ {
+ if(charaWork.command[i] != 0)
+ {
+ charaWork.parameterSave.commandSlot_recastTime[i - charaWork.commandBorder] = time + charaWork.parameterTemp.maxCommandRecastTime[i - charaWork.commandBorder];
+ }
+ }
+
+ UpdateHotbar();
+
+ List packets = propertyBuilder.Done();
+
+ foreach (SubPacket packet in packets)
+ BroadcastPacket(packet, true);
+
+ Database.SavePlayerCurrentClass(this);
+ RecalculateStats();
+ }
+
+ public void UpdateClassLevel(byte classId, short level)
+ {
+ Database.PlayerCharacterUpdateClassLevel(this, classId, level);
+ charaWork.battleSave.skillLevel[classId - 1] = level;
+ ActorPropertyPacketUtil propertyBuilder = new ActorPropertyPacketUtil("charaWork/stateForAll", this);
+ propertyBuilder.AddProperty(String.Format("charaWork.battleSave.skillLevel[{0}]", classId-1));
+ List packets = propertyBuilder.Done();
+ QueuePackets(packets);
+ }
+
+ public void GraphicChange(int slot, InventoryItem invItem)
+ {
+ if (invItem == null)
+ appearanceIds[slot] = 0;
+ else
+ {
+ ItemData item = Server.GetItemGamedata(invItem.itemId);
+
+ if (item is EquipmentItem)
+ {
+ EquipmentItem eqItem = (EquipmentItem)item;
+
+ uint mixedVariantId;
+
+ if (eqItem.graphicsWeaponId == 0)
+ mixedVariantId = ((eqItem.graphicsVariantId & 0x1F) << 5) | eqItem.graphicsColorId;
+ else
+ mixedVariantId = eqItem.graphicsVariantId;
+
+ uint graphicId =
+ (eqItem.graphicsWeaponId & 0x3FF) << 20 |
+ (eqItem.graphicsEquipmentId & 0x3FF) << 10 |
+ (mixedVariantId & 0x3FF);
+
+ appearanceIds[slot] = graphicId;
+ }
+
+ //Handle offhand
+ if (slot == MAINHAND && item is WeaponItem)
+ {
+ WeaponItem wpItem = (WeaponItem)item;
+
+ uint graphicId =
+ (wpItem.graphicsOffhandWeaponId & 0x3FF) << 20 |
+ (wpItem.graphicsOffhandEquipmentId & 0x3FF) << 10 |
+ (wpItem.graphicsOffhandVariantId & 0x3FF);
+
+ appearanceIds[SetActorAppearancePacket.OFFHAND] = graphicId;
+ }
+ }
+
+ Database.SavePlayerAppearance(this);
+ BroadcastPacket(CreateAppearancePacket(), true);
+ }
+
+ public void SetRepairRequest(byte type)
+ {
+ charaWork.eventSave.repairType = type;
+ ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("charaWork/bazaar", this);
+ propPacketUtil.AddProperty("charaWork.eventSave.repairType");
+ QueuePackets(propPacketUtil.Done());
+ }
+
+ public void CheckBazaarFlags(bool noUpdate = false)
+ {
+ bool isDealing = false, isRepairing = false, seekingItem = false;
+ lock (GetItemPackage(ItemPackage.BAZAAR))
+ {
+ foreach (InventoryItem item in GetItemPackage(ItemPackage.BAZAAR).GetRawList())
+ {
+ if (item == null)
+ break;
+
+ if (item.GetBazaarMode() == InventoryItem.MODE_SELL_SINGLE || item.GetBazaarMode() == InventoryItem.MODE_SELL_PSTACK || item.GetBazaarMode() == InventoryItem.MODE_SELL_FSTACK)
+ isDealing = true;
+ if (item.GetBazaarMode() == InventoryItem.MODE_SEEK_REPAIR)
+ isRepairing = true;
+ if (item.GetBazaarMode() == InventoryItem.MODE_SEEK_ITEM)
+ isDealing = true;
+
+ if (isDealing && isRepairing && seekingItem)
+ break;
+ }
+ }
+
+ bool doUpdate = false;
+
+ ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("charaWork/bazaar", this);
+ if (charaWork.eventTemp.bazaarRetail != isDealing)
+ {
+ charaWork.eventTemp.bazaarRetail = isDealing;
+ propPacketUtil.AddProperty("charaWork.eventTemp.bazaarRetail");
+ doUpdate = true;
+ }
+
+ if (charaWork.eventTemp.bazaarRepair != isRepairing)
+ {
+ charaWork.eventTemp.bazaarRepair = isRepairing;
+ propPacketUtil.AddProperty("charaWork.eventTemp.bazaarRepair");
+ doUpdate = true;
+ }
+
+ if (charaWork.eventTemp.bazaarMateria != (GetItemPackage(ItemPackage.MELDREQUEST).GetCount() != 0))
+ {
+ charaWork.eventTemp.bazaarMateria = GetItemPackage(ItemPackage.MELDREQUEST).GetCount() != 0;
+ propPacketUtil.AddProperty("charaWork.eventTemp.bazaarMateria");
+ doUpdate = true;
+ }
+
+ if (!noUpdate && doUpdate)
+ BroadcastPackets(propPacketUtil.Done(), true);
+ }
+
+ public int GetCurrentGil()
+ {
+ if (HasItem(1000001))
+ return GetItemPackage(ItemPackage.CURRENCY_CRYSTALS).GetItemByCatelogId(1000001).quantity;
+ else
+ return 0;
+ }
+
+ public Actor GetActorInInstance(uint actorId)
+ {
+ foreach (Actor a in playerSession.actorInstanceList)
+ {
+ if (a.actorId == actorId)
+ return a;
+ }
+
+ return null;
+ }
+
+ public void SetZoneChanging(bool flag)
+ {
+ isZoneChanging = flag;
+ }
+
+ public bool IsInZoneChange()
+ {
+ return isZoneChanging;
+ }
+
+ public ReferencedItemPackage GetEquipment()
+ {
+ return equipment;
+ }
+
+ public byte GetInitialTown()
+ {
+ return playerWork.initialTown;
+ }
+
+ public uint GetHomePoint()
+ {
+ return homepoint;
+ }
+
+ public byte GetHomePointInn()
+ {
+ return homepointInn;
+ }
+
+ public void SetHomePoint(uint aetheryteId)
+ {
+ homepoint = aetheryteId;
+ Database.SavePlayerHomePoints(this);
+ }
+
+ public void SetHomePointInn(byte townId)
+ {
+ homepointInn = townId;
+ Database.SavePlayerHomePoints(this);
+ }
+
+ public bool HasAetheryteNodeUnlocked(uint aetheryteId)
+ {
+ if (aetheryteId != 0)
+ return true;
+ else
+ return false;
+ }
+
+ public int GetFreeQuestSlot()
+ {
+ for (int i = 0; i < questScenario.Length; i++)
+ {
+ if (questScenario[i] == null)
+ return i;
+ }
+
+ return -1;
+ }
+
+ public int GetFreeGuildleveSlot()
+ {
+ for (int i = 0; i < work.guildleveId.Length; i++)
+ {
+ if (work.guildleveId[i] == 0)
+ return i;
+ }
+
+ return -1;
+ }
+
+ //For Lua calls, cause MoonSharp goes retard with uint
+ public void AddQuest(int id, bool isSilent = false)
+ {
+ AddQuest((uint)id, isSilent);
+ }
+ public void CompleteQuest(int id)
+ {
+ CompleteQuest((uint)id);
+ }
+ public bool HasQuest(int id)
+ {
+ return HasQuest((uint)id);
+ }
+ public Quest GetQuest(int id)
+ {
+ return GetQuest((uint)id);
+ }
+ public bool IsQuestCompleted(int id)
+ {
+ return IsQuestCompleted((uint)id);
+ }
+ public bool CanAcceptQuest(int id)
+ {
+ return CanAcceptQuest((uint)id);
+ }
+ //For Lua calls, cause MoonSharp goes retard with uint
+
+ public void AddGuildleve(uint id)
+ {
+ int freeSlot = GetFreeGuildleveSlot();
+
+ if (freeSlot == -1)
+ return;
+
+ work.guildleveId[freeSlot] = (ushort)id;
+ Database.SaveGuildleve(this, id, freeSlot);
+ SendGuildleveClientUpdate(freeSlot);
+ }
+
+ public void MarkGuildleve(uint id, bool abandoned, bool completed)
+ {
+ if (HasGuildleve(id))
+ {
+ for (int i = 0; i < work.guildleveId.Length; i++)
+ {
+ if (work.guildleveId[i] == id)
+ {
+ work.guildleveChecked[i] = completed;
+ work.guildleveDone[i] = abandoned;
+ Database.MarkGuildleve(this, id, abandoned, completed);
+ SendGuildleveMarkClientUpdate(i);
+ }
+ }
+ }
+ }
+
+ public void RemoveGuildleve(uint id)
+ {
+ if (HasGuildleve(id))
+ {
+ for (int i = 0; i < work.guildleveId.Length; i++)
+ {
+ if (work.guildleveId[i] == id)
+ {
+ Database.RemoveGuildleve(this, id);
+ work.guildleveId[i] = 0;
+ SendGuildleveClientUpdate(i);
+ break;
+ }
+ }
+ }
+ }
+
+ public void AddQuest(uint id, bool isSilent = false)
+ {
+ Actor actor = Server.GetStaticActors((0xA0F00000 | id));
+ AddQuest(actor.actorName, isSilent);
+ }
+
+ public void AddQuest(string name, bool isSilent = false)
+ {
+ Actor actor = Server.GetStaticActors(name);
+
+ if (actor == null)
+ return;
+
+ uint id = actor.actorId;
+
+ int freeSlot = GetFreeQuestSlot();
+
+ if (freeSlot == -1)
+ return;
+
+ playerWork.questScenario[freeSlot] = id;
+ questScenario[freeSlot] = new Quest(this, playerWork.questScenario[freeSlot], name, null, 0, 0);
+ Database.SaveQuest(this, questScenario[freeSlot]);
+ SendQuestClientUpdate(freeSlot);
+
+ if (!isSilent)
+ {
+ SendGameMessage(Server.GetWorldManager().GetActor(), 25224, 0x20, (object)questScenario[freeSlot].GetQuestId());
+ questScenario[freeSlot].NextPhase(0);
+ }
+ }
+
+ public void CompleteQuest(uint id)
+ {
+ Actor actor = Server.GetStaticActors((0xA0F00000 | id));
+ CompleteQuest(actor.actorName);
+ }
+
+ public void CompleteQuest(string name)
+ {
+ Actor actor = Server.GetStaticActors(name);
+
+ if (actor == null)
+ return;
+
+ uint id = actor.actorId;
+ if (HasQuest(id))
+ {
+ Database.CompleteQuest(playerSession.GetActor(), id);
+ SendGameMessage(Server.GetWorldManager().GetActor(), 25086, 0x20, (object)GetQuest(id).GetQuestId());
+ RemoveQuest(id);
+ }
+ }
+
+ //TODO: Add checks for you being in an instance or main scenario
+ public void AbandonQuest(uint id)
+ {
+ Quest quest = GetQuest(id);
+ RemoveQuestByQuestId(id);
+ quest.DoAbandon();
+ }
+
+ public void RemoveQuestByQuestId(uint id)
+ {
+ RemoveQuest((0xA0F00000 | id));
+ }
+
+ public void RemoveQuest(uint id)
+ {
+ if (HasQuest(id))
+ {
+ for (int i = 0; i < questScenario.Length; i++)
+ {
+ if (questScenario[i] != null && questScenario[i].actorId == id)
+ {
+ Database.RemoveQuest(this, questScenario[i].actorId);
+ questScenario[i] = null;
+ playerWork.questScenario[i] = 0;
+ SendQuestClientUpdate(i);
+ break;
+ }
+ }
+ }
+ }
+
+ public void ReplaceQuest(uint oldId, uint newId)
+ {
+ if (HasQuest(oldId))
+ {
+ for (int i = 0; i < questScenario.Length; i++)
+ {
+ if (questScenario[i] != null && questScenario[i].GetQuestId() == oldId)
+ {
+ Actor actor = Server.GetStaticActors((0xA0F00000 | newId));
+ playerWork.questScenario[i] = (0xA0F00000 | newId);
+ questScenario[i] = new Quest(this, playerWork.questScenario[i], actor.actorName, null, 0, 0);
+ Database.SaveQuest(this, questScenario[i]);
+ SendQuestClientUpdate(i);
+ break;
+ }
+ }
+ }
+ }
+
+ public bool CanAcceptQuest(string name)
+ {
+ if (!IsQuestCompleted(name) && !HasQuest(name))
+ return true;
+ else
+ return false;
+ }
+
+ public bool CanAcceptQuest(uint id)
+ {
+ Actor actor = Server.GetStaticActors((0xA0F00000 | id));
+ return CanAcceptQuest(actor.actorName);
+ }
+
+ public bool IsQuestCompleted(string questName)
+ {
+ Actor actor = Server.GetStaticActors(questName);
+ return IsQuestCompleted(actor.actorId);
+ }
+
+ public bool IsQuestCompleted(uint questId)
+ {
+ return Database.IsQuestCompleted(this, 0xFFFFF & questId);
+ }
+
+ public Quest GetQuest(uint id)
+ {
+ for (int i = 0; i < questScenario.Length; i++)
+ {
+ if (questScenario[i] != null && questScenario[i].actorId == (0xA0F00000 | id))
+ return questScenario[i];
+ }
+
+ return null;
+ }
+
+ public Quest GetQuest(string name)
+ {
+ for (int i = 0; i < questScenario.Length; i++)
+ {
+ if (questScenario[i] != null && questScenario[i].actorName.ToLower().Equals(name.ToLower()))
+ return questScenario[i];
+ }
+
+ return null;
+ }
+
+ public bool HasQuest(string name)
+ {
+ for (int i = 0; i < questScenario.Length; i++)
+ {
+ if (questScenario[i] != null && questScenario[i].actorName.ToLower().Equals(name.ToLower()))
+ return true;
+ }
+
+ return false;
+ }
+
+ public bool HasQuest(uint id)
+ {
+ for (int i = 0; i < questScenario.Length; i++)
+ {
+ if (questScenario[i] != null && questScenario[i].actorId == (0xA0F00000 | id))
+ return true;
+ }
+
+ return false;
+ }
+
+ public bool HasGuildleve(uint id)
+ {
+ for (int i = 0; i < work.guildleveId.Length; i++)
+ {
+ if (work.guildleveId[i] == id)
+ return true;
+ }
+
+ return false;
+ }
+
+ public int GetQuestSlot(uint id)
+ {
+ for (int i = 0; i < questScenario.Length; i++)
+ {
+ if (questScenario[i] != null && questScenario[i].actorId == (0xA0F00000 | id))
+ return i;
+ }
+
+ return -1;
+ }
+
+ public void SetNpcLS(uint npcLSId, uint state)
+ {
+ bool isCalling, isExtra;
+ isCalling = isExtra = false;
+
+ switch (state)
+ {
+ case NPCLS_INACTIVE:
+
+ if (playerWork.npcLinkshellChatExtra[npcLSId] == true && playerWork.npcLinkshellChatCalling[npcLSId] == false)
+ return;
+
+ isExtra = true;
+ break;
+ case NPCLS_ACTIVE:
+
+ if (playerWork.npcLinkshellChatExtra[npcLSId] == false && playerWork.npcLinkshellChatCalling[npcLSId] == true)
+ return;
+
+ isCalling = true;
+ break;
+ case NPCLS_ALERT:
+
+ if (playerWork.npcLinkshellChatExtra[npcLSId] == true && playerWork.npcLinkshellChatCalling[npcLSId] == true)
+ return;
+
+ isExtra = isCalling = true;
+ break;
+ }
+
+ playerWork.npcLinkshellChatExtra[npcLSId] = isExtra;
+ playerWork.npcLinkshellChatCalling[npcLSId] = isCalling;
+
+ Database.SaveNpcLS(this, npcLSId, isCalling, isExtra);
+
+ ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("playerWork/npcLinkshellChat", this);
+ propPacketUtil.AddProperty(String.Format("playerWork.npcLinkshellChatExtra[{0}]", npcLSId));
+ propPacketUtil.AddProperty(String.Format("playerWork.npcLinkshellChatCalling[{0}]", npcLSId));
+ QueuePackets(propPacketUtil.Done());
+ }
+
+ private void SendQuestClientUpdate(int slot)
+ {
+ ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("playerWork/journal", this);
+ propPacketUtil.AddProperty(String.Format("playerWork.questScenario[{0}]", slot));
+ QueuePackets(propPacketUtil.Done());
+ }
+
+ private void SendGuildleveClientUpdate(int slot)
+ {
+ ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("work/guildleve", this);
+ propPacketUtil.AddProperty(String.Format("work.guildleveId[{0}]", slot));
+ QueuePackets(propPacketUtil.Done());
+ }
+
+ private void SendGuildleveMarkClientUpdate(int slot)
+ {
+ ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("work/guildleve", this);
+ propPacketUtil.AddProperty(String.Format("work.guildleveDone[{0}]", slot));
+ propPacketUtil.AddProperty(String.Format("work.guildleveChecked[{0}]", slot));
+ QueuePackets(propPacketUtil.Done());
+ }
+
+ public void SendStartCastbar(uint commandId, uint endTime)
+ {
+ playerWork.castCommandClient = commandId;
+ playerWork.castEndClient = endTime;
+ ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("playerWork/castState", this);
+ propPacketUtil.AddProperty("playerWork.castEndClient");
+ propPacketUtil.AddProperty("playerWork.castCommandClient");
+ QueuePackets(propPacketUtil.Done());
+ }
+
+ public void SendEndCastbar()
+ {
+ playerWork.castCommandClient = 0;
+ playerWork.castEndClient = 0;
+ ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("playerWork/castState", this);
+ propPacketUtil.AddProperty("playerWork.castCommandClient");
+ QueuePackets(propPacketUtil.Done());
+ }
+
+ public void SetLoginDirector(Director director)
+ {
+ if (ownedDirectors.Contains(director))
+ loginInitDirector = director;
+ }
+
+ public void AddDirector(Director director, bool spawnImmediatly = false)
+ {
+ if (!ownedDirectors.Contains(director))
+ {
+ ownedDirectors.Add(director);
+ director.AddMember(this);
+ }
+ }
+
+ public void SendDirectorPackets(Director director)
+ {
+ QueuePackets(director.GetSpawnPackets());
+ QueuePackets(director.GetInitPackets());
+ }
+
+ public void RemoveDirector(Director director)
+ {
+ if (ownedDirectors.Contains(director))
+ {
+ QueuePacket(RemoveActorPacket.BuildPacket(director.actorId));
+ ownedDirectors.Remove(director);
+ director.RemoveMember(this);
+ }
+ }
+
+ public GuildleveDirector GetGuildleveDirector()
+ {
+ foreach (Director d in ownedDirectors)
+ {
+ if (d is GuildleveDirector)
+ return (GuildleveDirector)d;
+ }
+
+ return null;
+ }
+
+ public Director GetDirector(string directorName)
+ {
+ foreach (Director d in ownedDirectors)
+ {
+ if (d.GetScriptPath().Equals(directorName))
+ return d;
+ }
+
+ return null;
+ }
+
+ public Director GetDirector(uint id)
+ {
+ foreach (Director d in ownedDirectors)
+ {
+ if (d.actorId == id)
+ return d;
+ }
+
+ return null;
+ }
+
+ public void ExaminePlayer(Actor examinee)
+ {
+ Player toBeExamined;
+ if (examinee is Player)
+ toBeExamined = (Player)examinee;
+ else
+ return;
+
+ QueuePacket(InventoryBeginChangePacket.BuildPacket(toBeExamined.actorId, true));
+ toBeExamined.GetEquipment().SendUpdateAsItemPackage(this, ItemPackage.MAXSIZE_EQUIPMENT_OTHERPLAYER, ItemPackage.EQUIPMENT_OTHERPLAYER);
+ QueuePacket(InventoryEndChangePacket.BuildPacket(toBeExamined.actorId));
+ }
+
+ public void SendDataPacket(params object[] parameters)
+ {
+ List lParams = LuaUtils.CreateLuaParamList(parameters);
+ SubPacket spacket = GenericDataPacket.BuildPacket(actorId, lParams);
+ spacket.DebugPrintSubPacket();
+ QueuePacket(spacket);
+ }
+
+ public void StartEvent(Actor owner, EventStartPacket start)
+ {
+ currentEventOwner = start.scriptOwnerActorID;
+ currentEventName = start.triggerName;
+ LuaEngine.GetInstance().EventStarted(this, owner, start);
+ }
+
+ public void UpdateEvent(EventUpdatePacket update)
+ {
+ LuaEngine.GetInstance().OnEventUpdate(this, update.luaParams);
+ }
+
+ public void KickEvent(Actor actor, string conditionName, params object[] parameters)
+ {
+ if (actor == null)
+ return;
+
+ List lParams = LuaUtils.CreateLuaParamList(parameters);
+ SubPacket spacket = KickEventPacket.BuildPacket(actorId, actor.actorId, 0x75dc1705, conditionName, lParams);
+ spacket.DebugPrintSubPacket();
+ QueuePacket(spacket);
+ }
+
+ public void KickEventSpecial(Actor actor, uint unknown, string conditionName, params object[] parameters)
+ {
+ if (actor == null)
+ return;
+
+ List lParams = LuaUtils.CreateLuaParamList(parameters);
+ SubPacket spacket = KickEventPacket.BuildPacket(actorId, actor.actorId, unknown, conditionName, lParams);
+ spacket.DebugPrintSubPacket();
+ QueuePacket(spacket);
+ }
+
+ public void SetEventStatus(Actor actor, string conditionName, bool enabled, byte unknown)
+ {
+ QueuePacket(packets.send.actor.events.SetEventStatus.BuildPacket(actor.actorId, enabled, unknown, conditionName));
+ }
+
+ public void RunEventFunction(string functionName, params object[] parameters)
+ {
+ List lParams = LuaUtils.CreateLuaParamList(parameters);
+ SubPacket spacket = RunEventFunctionPacket.BuildPacket(actorId, currentEventOwner, currentEventName, functionName, lParams);
+ spacket.DebugPrintSubPacket();
+ QueuePacket(spacket);
+ }
+
+ public void EndEvent()
+ {
+ SubPacket p = EndEventPacket.BuildPacket(actorId, currentEventOwner, currentEventName);
+ p.DebugPrintSubPacket();
+ QueuePacket(p);
+
+ currentEventOwner = 0;
+ currentEventName = "";
+ currentEventRunning = null;
+ }
+
+ public void BroadcastCountdown(byte countdownLength, ulong syncTime)
+ {
+ BroadcastPacket(StartCountdownPacket.BuildPacket(actorId, countdownLength, syncTime, "Go!"), true);
+ }
+
+ public void SendInstanceUpdate()
+ {
+ //Server.GetWorldManager().SeamlessCheck(this);
+
+ //Update Instance
+ List aroundMe = new List();
+
+ if (zone != null)
+ aroundMe.AddRange(zone.GetActorsAroundActor(this, 50));
+ if (zone2 != null)
+ aroundMe.AddRange(zone2.GetActorsAroundActor(this, 50));
+ playerSession.UpdateInstance(aroundMe);
+ }
+
+ public bool IsInParty()
+ {
+ return currentParty != null;
+ }
+
+ public bool IsPartyLeader()
+ {
+ if (IsInParty())
+ {
+ Party party = (Party)currentParty;
+ return party.GetLeader() == actorId;
+ }
+ else
+ return false;
+ }
+
+ public void PartyOustPlayer(uint actorId)
+ {
+ SubPacket oustPacket = PartyModifyPacket.BuildPacket(playerSession, 1, actorId);
+ QueuePacket(oustPacket);
+ }
+
+ public void PartyOustPlayer(string name)
+ {
+ SubPacket oustPacket = PartyModifyPacket.BuildPacket(playerSession, 1, name);
+ QueuePacket(oustPacket);
+ }
+
+ public void PartyLeave()
+ {
+ SubPacket leavePacket = PartyLeavePacket.BuildPacket(playerSession, false);
+ QueuePacket(leavePacket);
+ }
+
+ public void PartyDisband()
+ {
+ SubPacket disbandPacket = PartyLeavePacket.BuildPacket(playerSession, true);
+ QueuePacket(disbandPacket);
+ }
+
+ public void PartyPromote(uint actorId)
+ {
+ SubPacket promotePacket = PartyModifyPacket.BuildPacket(playerSession, 0, actorId);
+ QueuePacket(promotePacket);
+ }
+
+ public void PartyPromote(string name)
+ {
+ SubPacket promotePacket = PartyModifyPacket.BuildPacket(playerSession, 0, name);
+ QueuePacket(promotePacket);
+ }
+
+ //A party member list packet came, set the party
+ public void SetParty(Party group)
+ {
+ if (group is Party && currentParty != group)
+ {
+ RemoveFromCurrentPartyAndCleanup();
+ currentParty = group;
+ }
+ }
+
+ //Removes the player from the party and cleans it up if needed
+ public void RemoveFromCurrentPartyAndCleanup()
+ {
+ if (currentParty == null)
+ return;
+
+ Party partyGroup = (Party) currentParty;
+
+ for (int i = 0; i < partyGroup.members.Count; i++)
+ {
+ if (partyGroup.members[i] == actorId)
+ {
+ partyGroup.members.RemoveAt(i);
+ break;
+ }
+ }
+
+ //currentParty.members.Remove(this);
+ if (partyGroup.members.Count == 0)
+ Server.GetWorldManager().NoMembersInParty((Party)currentParty);
+
+ currentParty = null;
+ }
+
+ public void IssueChocobo(byte appearanceId, string nameResponse)
+ {
+ Database.IssuePlayerChocobo(this, appearanceId, nameResponse);
+ hasChocobo = true;
+ chocoboAppearance = appearanceId;
+ chocoboName = nameResponse;
+ }
+
+ public void ChangeChocoboAppearance(byte appearanceId)
+ {
+ Database.ChangePlayerChocoboAppearance(this, appearanceId);
+ chocoboAppearance = appearanceId;
+ }
+
+ public Retainer SpawnMyRetainer(Npc bell, int retainerIndex)
+ {
+ Retainer retainer = Database.LoadRetainer(this, retainerIndex);
+
+ float distance = (float)Math.Sqrt(((positionX - bell.positionX) * (positionX - bell.positionX)) + ((positionZ - bell.positionZ) * (positionZ - bell.positionZ)));
+ float posX = bell.positionX - ((-1.0f * (bell.positionX - positionX)) / distance);
+ float posZ = bell.positionZ - ((-1.0f * (bell.positionZ - positionZ)) / distance);
+
+ retainer.positionX = posX;
+ retainer.positionY = positionY;
+ retainer.positionZ = posZ;
+ retainer.rotation = (float)Math.Atan2(positionX - posX, positionZ - posZ);
+
+ retainerMeetingGroup = new RetainerMeetingRelationGroup(5555, this, retainer);
+ retainerMeetingGroup.SendGroupPackets(playerSession);
+
+ currentSpawnedRetainer = retainer;
+ sentRetainerSpawn = false;
+
+ return retainer;
+ }
+
+ public void DespawnMyRetainer()
+ {
+ if (currentSpawnedRetainer != null)
+ {
+ currentSpawnedRetainer = null;
+ retainerMeetingGroup.SendDeletePacket(playerSession);
+ retainerMeetingGroup = null;
+ }
+ }
+
+ public override void Update(DateTime tick)
+ {
+ aiContainer.Update(tick);
+ statusEffects.Update(tick);
+ }
+
+ public override void PostUpdate(DateTime tick, List packets = null)
+ {
+ // todo: is this correct?
+ if (this.playerSession.isUpdatesLocked)
+ return;
+
+ // todo: should probably add another flag for battleTemp since all this uses reflection
+ packets = new List();
+
+ // we only want the latest update for the player
+ if ((updateFlags & ActorUpdateFlags.Position) != 0)
+ {
+ if (positionUpdates.Count > 1)
+ positionUpdates.RemoveRange(1, positionUpdates.Count - 1);
+ }
+
+ if ((updateFlags & ActorUpdateFlags.HpTpMp) != 0)
+ {
+ var propPacketUtil = new ActorPropertyPacketUtil("charaWork/stateAtQuicklyForAll", this);
+
+ // todo: should this be using job as index?
+ propPacketUtil.AddProperty("charaWork.parameterSave.hp[0]");
+ propPacketUtil.AddProperty("charaWork.parameterSave.hpMax[0]");
+ propPacketUtil.AddProperty("charaWork.parameterSave.state_mainSkill[0]");
+ propPacketUtil.AddProperty("charaWork.parameterSave.state_mainSkillLevel");
+
+ packets.AddRange(propPacketUtil.Done());
+ }
+
+
+ if ((updateFlags & ActorUpdateFlags.Stats) != 0)
+ {
+ var propPacketUtil = new ActorPropertyPacketUtil("charaWork/battleParameter", this);
+
+ for (uint i = 0; i < 35; i++)
+ {
+ if (GetMod(i) != charaWork.battleTemp.generalParameter[i])
+ {
+ charaWork.battleTemp.generalParameter[i] = (short)GetMod(i);
+ propPacketUtil.AddProperty(String.Format("charaWork.battleTemp.generalParameter[{0}]", i));
+ }
+ }
+
+ QueuePackets(propPacketUtil.Done());
+ }
+
+ if ((updateFlags & ActorUpdateFlags.Hotbar) != 0)
+ {
+ UpdateHotbar(hotbarSlotsToUpdate);
+ hotbarSlotsToUpdate.Clear();
+
+ updateFlags ^= ActorUpdateFlags.Hotbar;
+ }
+
+
+ base.PostUpdate(tick, packets);
+ }
+
+ public override void Die(DateTime tick, CommandResultContainer actionContainer = null)
+ {
+ // todo: death timer
+ aiContainer.InternalDie(tick, 60);
+ }
+
+ //Update commands and recast timers for the entire hotbar
+ public void UpdateHotbar()
+ {
+ for (ushort i = charaWork.commandBorder; i < charaWork.commandBorder + 30; i++)
+ {
+ hotbarSlotsToUpdate.Add(i);
+ }
+ updateFlags |= ActorUpdateFlags.Hotbar;
+ }
+
+ //Updates the hotbar and recast timers for only certain hotbar slots
+ public void UpdateHotbar(List slotsToUpdate)
+ {
+ UpdateHotbarCommands(slotsToUpdate);
+ UpdateRecastTimers(slotsToUpdate);
+ }
+
+ //Update command ids for the passed in hotbar slots
+ public void UpdateHotbarCommands(List slotsToUpdate)
+ {
+ ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("charaWork/command", this);
+ foreach (ushort slot in slotsToUpdate)
+ {
+ propPacketUtil.AddProperty(String.Format("charaWork.command[{0}]", slot));
+ propPacketUtil.AddProperty(String.Format("charaWork.commandCategory[{0}]", slot));
+ }
+
+ propPacketUtil.NewTarget("charaWork/commandDetailForSelf");
+ //Enable or disable slots based on whether there is an ability in that slot
+ foreach (ushort slot in slotsToUpdate)
+ {
+ charaWork.parameterSave.commandSlot_compatibility[slot - charaWork.commandBorder] = charaWork.command[slot] != 0;
+ propPacketUtil.AddProperty(String.Format("charaWork.parameterSave.commandSlot_compatibility[{0}]", slot - charaWork.commandBorder));
+ }
+
+ QueuePackets(propPacketUtil.Done());
+ //QueuePackets(compatibiltyUtil.Done());
+ }
+
+ //Update recast timers for the passed in hotbar slots
+ public void UpdateRecastTimers(List slotsToUpdate)
+ {
+ ActorPropertyPacketUtil recastPacketUtil = new ActorPropertyPacketUtil("charaWork/commandDetailForSelf", this);
+
+ foreach (ushort slot in slotsToUpdate)
+ {
+ recastPacketUtil.AddProperty(String.Format("charaWork.parameterTemp.maxCommandRecastTime[{0}]", slot - charaWork.commandBorder));
+ recastPacketUtil.AddProperty(String.Format("charaWork.parameterSave.commandSlot_recastTime[{0}]", slot - charaWork.commandBorder));
+ }
+
+ QueuePackets(recastPacketUtil.Done());
+ }
+
+ //Find the first open slot in classId's hotbar and equip an ability there.
+ public void EquipAbilityInFirstOpenSlot(byte classId, uint commandId, bool printMessage = true)
+ {
+ //Find first open slot on class's hotbar slot, then call EquipAbility with that slot.
+ ushort hotbarSlot = 0;
+
+ //If the class we're equipping for is the current class, we can just look at charawork.command
+ if(classId == charaWork.parameterSave.state_mainSkill[0])
+ hotbarSlot = FindFirstCommandSlotById(0);
+ //Otherwise, we need to check the database.
+ else
+ hotbarSlot = (ushort) (Database.FindFirstCommandSlot(this, classId) + charaWork.commandBorder);
+
+ EquipAbility(classId, commandId, hotbarSlot, printMessage);
+ }
+
+ //Add commandId to classId's hotbar at hotbarSlot.
+ //If classId is not the current class, do it in the database
+ //hotbarSlot starts at 32
+ public void EquipAbility(byte classId, uint commandId, ushort hotbarSlot, bool printMessage = true)
+ {
+ var ability = Server.GetWorldManager().GetBattleCommand(commandId);
+ uint trueCommandId = 0xA0F00000 | commandId;
+ ushort lowHotbarSlot = (ushort)(hotbarSlot - charaWork.commandBorder);
+ ushort maxRecastTime = (ushort)(ability != null ? ability.maxRecastTimeSeconds : 5);
+ uint recastEnd = Utils.UnixTimeStampUTC() + maxRecastTime;
+
+ Database.EquipAbility(this, classId, (ushort) (hotbarSlot - charaWork.commandBorder), commandId, recastEnd);
+ //If the class we're equipping for is the current class (need to find out if state_mainSkill is supposed to change when you're a job)
+ //then equip the ability in charawork.commands and save in databse, otherwise just save in database
+ if (classId == GetCurrentClassOrJob())
+ {
+ charaWork.command[hotbarSlot] = trueCommandId;
+ charaWork.commandCategory[hotbarSlot] = 1;
+ charaWork.parameterTemp.maxCommandRecastTime[lowHotbarSlot] = maxRecastTime;
+ charaWork.parameterSave.commandSlot_recastTime[lowHotbarSlot] = recastEnd;
+
+ hotbarSlotsToUpdate.Add(hotbarSlot);
+ updateFlags |= ActorUpdateFlags.Hotbar;
+ }
+
+
+ if(printMessage)
+ SendGameMessage(Server.GetWorldManager().GetActor(), 30603, 0x20, 0, commandId);
+ }
+
+ //Doesn't take a classId because the only way to swap abilities is through the ability equip widget oe /eaction, which only apply to current class
+ //hotbarSlot 1 and 2 are 32-indexed.
+ public void SwapAbilities(ushort hotbarSlot1, ushort hotbarSlot2)
+ {
+ //0 indexed hotbar slots for saving to database and recast timers
+ uint lowHotbarSlot1 = (ushort)(hotbarSlot1 - charaWork.commandBorder);
+ uint lowHotbarSlot2 = (ushort)(hotbarSlot2 - charaWork.commandBorder);
+
+ //Store information about first command
+ uint commandId = charaWork.command[hotbarSlot1];
+ uint recastEnd = charaWork.parameterSave.commandSlot_recastTime[lowHotbarSlot1];
+ ushort recastMax = charaWork.parameterTemp.maxCommandRecastTime[lowHotbarSlot1];
+
+ //Move second command's info to first hotbar slot
+ charaWork.command[hotbarSlot1] = charaWork.command[hotbarSlot2];
+ charaWork.parameterTemp.maxCommandRecastTime[lowHotbarSlot1] = charaWork.parameterTemp.maxCommandRecastTime[lowHotbarSlot2];
+ charaWork.parameterSave.commandSlot_recastTime[lowHotbarSlot1] = charaWork.parameterSave.commandSlot_recastTime[lowHotbarSlot2];
+
+ //Move first command's info to second slot
+ charaWork.command[hotbarSlot2] = commandId;
+ charaWork.parameterTemp.maxCommandRecastTime[lowHotbarSlot2] = recastMax;
+ charaWork.parameterSave.commandSlot_recastTime[lowHotbarSlot2] = recastEnd;
+
+ //Save changes to both slots
+ Database.EquipAbility(this, GetCurrentClassOrJob(), (ushort)(lowHotbarSlot1), 0xA0F00000 ^ charaWork.command[hotbarSlot1], charaWork.parameterSave.commandSlot_recastTime[lowHotbarSlot1]);
+ Database.EquipAbility(this, GetCurrentClassOrJob(), (ushort)(lowHotbarSlot2), 0xA0F00000 ^ charaWork.command[hotbarSlot2], charaWork.parameterSave.commandSlot_recastTime[lowHotbarSlot2]);
+
+ //Update slots on client
+ hotbarSlotsToUpdate.Add(hotbarSlot1);
+ hotbarSlotsToUpdate.Add(hotbarSlot2);
+ updateFlags |= ActorUpdateFlags.Hotbar;
+ }
+
+ public void UnequipAbility(ushort hotbarSlot, bool printMessage = true)
+ {
+ ushort trueHotbarSlot = (ushort)(hotbarSlot + charaWork.commandBorder);
+ uint commandId = charaWork.command[trueHotbarSlot];
+ Database.UnequipAbility(this, hotbarSlot);
+ charaWork.command[trueHotbarSlot] = 0;
+ hotbarSlotsToUpdate.Add(trueHotbarSlot);
+
+ if (printMessage && commandId != 0)
+ SendGameMessage(Server.GetWorldManager().GetActor(), 30604, 0x20, 0, 0xA0F00000 ^ commandId);
+
+ updateFlags |= ActorUpdateFlags.Hotbar;
+ }
+
+ //Finds the first hotbar slot with a given commandId.
+ //If the returned value is outside the hotbar, it indicates it wasn't found.
+ public ushort FindFirstCommandSlotById(uint commandId)
+ {
+ if(commandId != 0)
+ commandId |= 0xA0F00000;
+
+ ushort firstSlot = (ushort)(charaWork.commandBorder + 30);
+
+ for (ushort i = charaWork.commandBorder; i < charaWork.commandBorder + 30; i++)
+ {
+ if (charaWork.command[i] == commandId)
+ {
+ firstSlot = i;
+ break;
+ }
+ }
+
+ return firstSlot;
+ }
+
+ private void UpdateHotbarTimer(uint commandId, uint recastTimeMs)
+ {
+ ushort slot = FindFirstCommandSlotById(commandId);
+ charaWork.parameterSave.commandSlot_recastTime[slot - charaWork.commandBorder] = Utils.UnixTimeStampUTC(DateTime.Now.AddMilliseconds(recastTimeMs));
+ var slots = new List();
+ slots.Add(slot);
+ UpdateRecastTimers(slots);
+ }
+
+ private uint GetHotbarTimer(uint commandId)
+ {
+ ushort slot = FindFirstCommandSlotById(commandId);
+ return charaWork.parameterSave.commandSlot_recastTime[slot - charaWork.commandBorder];
+ }
+
+ public override void Cast(uint spellId, uint targetId = 0)
+ {
+ if (aiContainer.CanChangeState())
+ aiContainer.Cast(zone.FindActorInArea(targetId == 0 ? currentTarget : targetId), spellId);
+ else if (aiContainer.IsCurrentState