mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-04-21 20:27:47 +00:00
Merge branch 'proxy_server' into develop
# Conflicts: # FFXIVClassic Common Class Lib/packages.config
This commit is contained in:
commit
3864bf6d85
195 changed files with 5926 additions and 1601 deletions
|
@ -3,11 +3,11 @@ using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using FFXIVClassic.Common;
|
|
||||||
using NLog;
|
using NLog;
|
||||||
using NLog.Targets;
|
using NLog.Targets;
|
||||||
|
using Ionic.Zlib;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets
|
namespace FFXIVClassic.Common
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct BasePacketHeader
|
public struct BasePacketHeader
|
||||||
|
@ -295,6 +295,41 @@ namespace FFXIVClassic_Map_Server.packets
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Builds a packet from the incoming buffer + offset. If a packet can be built, it is returned else null.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="offset">Current offset in buffer.</param>
|
||||||
|
/// <param name="buffer">Incoming buffer.</param>
|
||||||
|
/// <returns>Returns either a BasePacket or null if not enough data.</returns>
|
||||||
|
public static BasePacket CreatePacket(ref int offset, byte[] buffer, int bytesRead)
|
||||||
|
{
|
||||||
|
BasePacket newPacket = null;
|
||||||
|
|
||||||
|
//Too small to even get length
|
||||||
|
if (bytesRead <= offset)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
ushort packetSize = BitConverter.ToUInt16(buffer, offset);
|
||||||
|
|
||||||
|
//Too small to whole packet
|
||||||
|
if (bytesRead < offset + packetSize)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (buffer.Length < offset + packetSize)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
newPacket = new BasePacket(buffer, ref offset);
|
||||||
|
}
|
||||||
|
catch (OverflowException)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newPacket;
|
||||||
|
}
|
||||||
|
|
||||||
public static unsafe void EncryptPacket(Blowfish blowfish, BasePacket packet)
|
public static unsafe void EncryptPacket(Blowfish blowfish, BasePacket packet)
|
||||||
{
|
{
|
||||||
var data = packet.data;
|
var data = packet.data;
|
||||||
|
@ -347,6 +382,28 @@ namespace FFXIVClassic_Map_Server.packets
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static unsafe void DecompressPacket(ref BasePacket packet)
|
||||||
|
{
|
||||||
|
using (var compressedStream = new MemoryStream(packet.data))
|
||||||
|
using (var zipStream = new ZlibStream(compressedStream, Ionic.Zlib.CompressionMode.Decompress))
|
||||||
|
using (var resultStream = new MemoryStream())
|
||||||
|
{
|
||||||
|
zipStream.CopyTo(resultStream);
|
||||||
|
packet.data = resultStream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe void CompressPacket(ref BasePacket packet)
|
||||||
|
{
|
||||||
|
using (var compressedStream = new MemoryStream(packet.data))
|
||||||
|
using (var zipStream = new ZlibStream(compressedStream, Ionic.Zlib.CompressionMode.Compress))
|
||||||
|
using (var resultStream = new MemoryStream())
|
||||||
|
{
|
||||||
|
zipStream.CopyTo(resultStream);
|
||||||
|
packet.data = resultStream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,9 @@
|
||||||
<Prefer32Bit>false</Prefer32Bit>
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="DotNetZip">
|
||||||
|
<HintPath>..\packages\DotNetZip.1.10.1\lib\net20\DotNetZip.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
<Reference Include="MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll</HintPath>
|
<HintPath>..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
|
@ -56,12 +59,14 @@
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="BasePacket.cs" />
|
||||||
<Compile Include="Bitfield.cs" />
|
<Compile Include="Bitfield.cs" />
|
||||||
<Compile Include="Blowfish.cs" />
|
<Compile Include="Blowfish.cs" />
|
||||||
<Compile Include="EfficientHashTables.cs" />
|
<Compile Include="EfficientHashTables.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Sql.cs" />
|
<Compile Include="Sql.cs" />
|
||||||
<Compile Include="STA_INIFile.cs" />
|
<Compile Include="STA_INIFile.cs" />
|
||||||
|
<Compile Include="SubPacket.cs" />
|
||||||
<Compile Include="Utils.cs" />
|
<Compile Include="Utils.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -4,7 +4,7 @@ using FFXIVClassic.Common;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NLog.Targets;
|
using NLog.Targets;
|
||||||
|
|
||||||
namespace FFXIVClassic_Lobby_Server.packets
|
namespace FFXIVClassic.Common
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct SubPacketHeader
|
public struct SubPacketHeader
|
||||||
|
@ -72,26 +72,38 @@ namespace FFXIVClassic_Lobby_Server.packets
|
||||||
offset += header.subpacketSize;
|
offset += header.subpacketSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubPacket(ushort opcode, uint sourceId, uint targetId, byte[] data)
|
public SubPacket(ushort opcode, uint sourceId, uint targetId, byte[] data) : this(true, opcode, sourceId, targetId, data) { }
|
||||||
|
|
||||||
|
public SubPacket(bool isGameMessage, ushort opcode, uint sourceId, uint targetId, byte[] data)
|
||||||
{
|
{
|
||||||
header = new SubPacketHeader();
|
header = new SubPacketHeader();
|
||||||
gameMessage = new GameMessageHeader();
|
|
||||||
|
|
||||||
gameMessage.opcode = opcode;
|
if (isGameMessage)
|
||||||
|
{
|
||||||
|
gameMessage = new GameMessageHeader();
|
||||||
|
gameMessage.opcode = opcode;
|
||||||
|
gameMessage.timestamp = Utils.UnixTimeStampUTC();
|
||||||
|
gameMessage.unknown4 = 0x14;
|
||||||
|
gameMessage.unknown5 = 0x00;
|
||||||
|
gameMessage.unknown6 = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
header.sourceId = sourceId;
|
header.sourceId = sourceId;
|
||||||
header.targetId = targetId;
|
header.targetId = targetId;
|
||||||
|
|
||||||
gameMessage.timestamp = Utils.UnixTimeStampUTC();
|
if (isGameMessage)
|
||||||
|
header.type = 0x03;
|
||||||
|
else
|
||||||
|
header.type = opcode;
|
||||||
|
|
||||||
header.type = 0x03;
|
|
||||||
header.unknown1 = 0x00;
|
header.unknown1 = 0x00;
|
||||||
gameMessage.unknown4 = 0x14;
|
|
||||||
gameMessage.unknown5 = 0x00;
|
|
||||||
gameMessage.unknown6 = 0x00;
|
|
||||||
|
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
|
||||||
header.subpacketSize = (ushort) (SUBPACKET_SIZE + GAMEMESSAGE_SIZE + data.Length);
|
header.subpacketSize = (ushort) (SUBPACKET_SIZE + data.Length);
|
||||||
|
|
||||||
|
if (isGameMessage)
|
||||||
|
header.subpacketSize += GAMEMESSAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubPacket(SubPacket original, uint newTargetId)
|
public SubPacket(SubPacket original, uint newTargetId)
|
||||||
|
@ -141,6 +153,41 @@ namespace FFXIVClassic_Lobby_Server.packets
|
||||||
return outBytes;
|
return outBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Builds a packet from the incoming buffer + offset. If a packet can be built, it is returned else null.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="offset">Current offset in buffer.</param>
|
||||||
|
/// <param name="buffer">Incoming buffer.</param>
|
||||||
|
/// <returns>Returns either a BasePacket or null if not enough data.</returns>
|
||||||
|
public static SubPacket CreatePacket(ref int offset, byte[] buffer, int bytesRead)
|
||||||
|
{
|
||||||
|
SubPacket newPacket = null;
|
||||||
|
|
||||||
|
//Too small to even get length
|
||||||
|
if (bytesRead <= offset)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
ushort packetSize = BitConverter.ToUInt16(buffer, offset);
|
||||||
|
|
||||||
|
//Too small to whole packet
|
||||||
|
if (bytesRead < offset + packetSize)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (buffer.Length < offset + packetSize)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
newPacket = new SubPacket(buffer, ref offset);
|
||||||
|
}
|
||||||
|
catch (OverflowException)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newPacket;
|
||||||
|
}
|
||||||
|
|
||||||
public void DebugPrintSubPacket()
|
public void DebugPrintSubPacket()
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
@ -157,7 +204,10 @@ namespace FFXIVClassic_Lobby_Server.packets
|
||||||
logger.ColorDebug(Utils.ByteArrayToHex(data, SUBPACKET_SIZE + GAMEMESSAGE_SIZE),
|
logger.ColorDebug(Utils.ByteArrayToHex(data, SUBPACKET_SIZE + GAMEMESSAGE_SIZE),
|
||||||
ConsoleOutputColor.DarkMagenta);
|
ConsoleOutputColor.DarkMagenta);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
logger.ColorDebug(Utils.ByteArrayToHex(data, SUBPACKET_SIZE),
|
||||||
|
ConsoleOutputColor.DarkMagenta);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="Microsoft.Net.Compilers" version="2.0.0-beta3" targetFramework="net45" developmentDependency="true" />
|
<package id="DotNetZip" version="1.10.1" targetFramework="net45" />
|
||||||
<package id="MySql.Data" version="6.9.8" targetFramework="net45" />
|
<package id="MySql.Data" version="6.9.8" targetFramework="net45" />
|
||||||
<package id="NLog" version="4.3.5" targetFramework="net45" />
|
<package id="NLog" version="4.3.5" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
|
@ -1,6 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using FFXIVClassic_Lobby_Server.packets;
|
|
||||||
using FFXIVClassic.Common;
|
using FFXIVClassic.Common;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using Cyotek.Collections.Generic;
|
using Cyotek.Collections.Generic;
|
||||||
|
|
|
@ -91,7 +91,6 @@
|
||||||
<Compile Include="Database.cs" />
|
<Compile Include="Database.cs" />
|
||||||
<Compile Include="dataobjects\World.cs" />
|
<Compile Include="dataobjects\World.cs" />
|
||||||
<Compile Include="PacketProcessor.cs" />
|
<Compile Include="PacketProcessor.cs" />
|
||||||
<Compile Include="packets\BasePacket.cs" />
|
|
||||||
<Compile Include="packets\receive\CharacterModifyPacket.cs" />
|
<Compile Include="packets\receive\CharacterModifyPacket.cs" />
|
||||||
<Compile Include="packets\receive\SecurityHandshakePacket.cs" />
|
<Compile Include="packets\receive\SecurityHandshakePacket.cs" />
|
||||||
<Compile Include="packets\receive\SelectCharacterPacket.cs" />
|
<Compile Include="packets\receive\SelectCharacterPacket.cs" />
|
||||||
|
@ -101,7 +100,6 @@
|
||||||
<Compile Include="packets\send\ErrorPacket.cs" />
|
<Compile Include="packets\send\ErrorPacket.cs" />
|
||||||
<Compile Include="packets\HardCoded_Packets.cs" />
|
<Compile Include="packets\HardCoded_Packets.cs" />
|
||||||
<Compile Include="packets\send\SelectCharacterConfirmPacket.cs" />
|
<Compile Include="packets\send\SelectCharacterConfirmPacket.cs" />
|
||||||
<Compile Include="packets\SubPacket.cs" />
|
|
||||||
<Compile Include="packets\send\CharacterListPacket.cs" />
|
<Compile Include="packets\send\CharacterListPacket.cs" />
|
||||||
<Compile Include="packets\send\ImportListPacket.cs" />
|
<Compile Include="packets\send\ImportListPacket.cs" />
|
||||||
<Compile Include="packets\send\AccountListPacket.cs" />
|
<Compile Include="packets\send\AccountListPacket.cs" />
|
||||||
|
|
|
@ -38,13 +38,13 @@
|
||||||
<target xsi:type="ColoredConsole" name="packets"
|
<target xsi:type="ColoredConsole" name="packets"
|
||||||
layout="${message}">
|
layout="${message}">
|
||||||
<highlight-row
|
<highlight-row
|
||||||
condition="equals('${logger}', 'FFXIVClassic_Lobby_Server.packets.BasePacket') and equals('${event-context:item=color}', '6')"
|
condition="equals('${logger}', 'FFXIVClassic.Common.BasePacket') and equals('${event-context:item=color}', '6')"
|
||||||
backgroundColor="DarkYellow" foregroundColor="NoChange" />
|
backgroundColor="DarkYellow" foregroundColor="NoChange" />
|
||||||
<highlight-row
|
<highlight-row
|
||||||
condition="equals('${logger}', 'FFXIVClassic_Lobby_Server.packets.SubPacket') and equals('${event-context:item=color}', '4')"
|
condition="equals('${logger}', 'FFXIVClassic.Common.SubPacket') and equals('${event-context:item=color}', '4')"
|
||||||
backgroundColor="DarkRed" foregroundColor="NoChange" />
|
backgroundColor="DarkRed" foregroundColor="NoChange" />
|
||||||
<highlight-row
|
<highlight-row
|
||||||
condition="equals('${logger}', 'FFXIVClassic_Lobby_Server.packets.SubPacket') and equals('${event-context:item=color}', '5')"
|
condition="equals('${logger}', 'FFXIVClassic.Common.SubPacket') and equals('${event-context:item=color}', '5')"
|
||||||
backgroundColor="DarkMagenta" foregroundColor="NoChange" />
|
backgroundColor="DarkMagenta" foregroundColor="NoChange" />
|
||||||
</target>
|
</target>
|
||||||
</targets>
|
</targets>
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using FFXIVClassic_Lobby_Server.packets;
|
|
||||||
using FFXIVClassic.Common;
|
using FFXIVClassic.Common;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
|
||||||
|
|
|
@ -1,361 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using FFXIVClassic.Common;
|
|
||||||
using NLog;
|
|
||||||
using NLog.Targets;
|
|
||||||
|
|
||||||
namespace FFXIVClassic_Lobby_Server.packets
|
|
||||||
{
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct BasePacketHeader
|
|
||||||
{
|
|
||||||
public byte isAuthenticated;
|
|
||||||
public byte isEncrypted;
|
|
||||||
public ushort connectionType;
|
|
||||||
public ushort packetSize;
|
|
||||||
public ushort numSubpackets;
|
|
||||||
public ulong timestamp; //Miliseconds
|
|
||||||
}
|
|
||||||
|
|
||||||
public class BasePacket
|
|
||||||
{
|
|
||||||
public const int TYPE_ZONE = 1;
|
|
||||||
public const int TYPE_CHAT = 2;
|
|
||||||
public const int BASEPACKET_SIZE = 0x10;
|
|
||||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
|
||||||
public byte[] data;
|
|
||||||
|
|
||||||
public BasePacketHeader header;
|
|
||||||
|
|
||||||
//Loads a sniffed packet from a file
|
|
||||||
public unsafe BasePacket(string path)
|
|
||||||
{
|
|
||||||
var bytes = File.ReadAllBytes(path);
|
|
||||||
|
|
||||||
if (bytes.Length < BASEPACKET_SIZE)
|
|
||||||
throw new OverflowException("Packet Error: Packet was too small");
|
|
||||||
|
|
||||||
fixed (byte* pdata = &bytes[0])
|
|
||||||
{
|
|
||||||
header = (BasePacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bytes.Length < header.packetSize)
|
|
||||||
throw new OverflowException("Packet Error: Packet size didn't equal given size");
|
|
||||||
|
|
||||||
int packetSize = header.packetSize;
|
|
||||||
|
|
||||||
if (packetSize - BASEPACKET_SIZE != 0)
|
|
||||||
{
|
|
||||||
data = new byte[packetSize - BASEPACKET_SIZE];
|
|
||||||
Array.Copy(bytes, BASEPACKET_SIZE, data, 0, packetSize - BASEPACKET_SIZE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
data = new byte[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
//Loads a sniffed packet from a byte array
|
|
||||||
public unsafe BasePacket(byte[] bytes)
|
|
||||||
{
|
|
||||||
if (bytes.Length < BASEPACKET_SIZE)
|
|
||||||
throw new OverflowException("Packet Error: Packet was too small");
|
|
||||||
|
|
||||||
fixed (byte* pdata = &bytes[0])
|
|
||||||
{
|
|
||||||
header = (BasePacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bytes.Length < header.packetSize)
|
|
||||||
throw new OverflowException("Packet Error: Packet size didn't equal given size");
|
|
||||||
|
|
||||||
int packetSize = header.packetSize;
|
|
||||||
|
|
||||||
data = new byte[packetSize - BASEPACKET_SIZE];
|
|
||||||
Array.Copy(bytes, BASEPACKET_SIZE, data, 0, packetSize - BASEPACKET_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public unsafe BasePacket(byte[] bytes, ref int offset)
|
|
||||||
{
|
|
||||||
if (bytes.Length < offset + BASEPACKET_SIZE)
|
|
||||||
throw new OverflowException("Packet Error: Packet was too small");
|
|
||||||
|
|
||||||
fixed (byte* pdata = &bytes[offset])
|
|
||||||
{
|
|
||||||
header = (BasePacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader));
|
|
||||||
}
|
|
||||||
|
|
||||||
int packetSize = header.packetSize;
|
|
||||||
|
|
||||||
if (bytes.Length < offset + header.packetSize)
|
|
||||||
throw new OverflowException("Packet Error: Packet size didn't equal given size");
|
|
||||||
|
|
||||||
data = new byte[packetSize - BASEPACKET_SIZE];
|
|
||||||
Array.Copy(bytes, offset + BASEPACKET_SIZE, data, 0, packetSize - BASEPACKET_SIZE);
|
|
||||||
|
|
||||||
offset += packetSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BasePacket(BasePacketHeader header, byte[] data)
|
|
||||||
{
|
|
||||||
this.header = header;
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<SubPacket> GetSubpackets()
|
|
||||||
{
|
|
||||||
var subpackets = new List<SubPacket>(header.numSubpackets);
|
|
||||||
|
|
||||||
var offset = 0;
|
|
||||||
|
|
||||||
while (offset < data.Length)
|
|
||||||
subpackets.Add(new SubPacket(data, ref offset));
|
|
||||||
|
|
||||||
return subpackets;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static unsafe BasePacketHeader GetHeader(byte[] bytes)
|
|
||||||
{
|
|
||||||
BasePacketHeader header;
|
|
||||||
if (bytes.Length < BASEPACKET_SIZE)
|
|
||||||
throw new OverflowException("Packet Error: Packet was too small");
|
|
||||||
|
|
||||||
fixed (byte* pdata = &bytes[0])
|
|
||||||
{
|
|
||||||
header = (BasePacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader));
|
|
||||||
}
|
|
||||||
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] GetHeaderBytes()
|
|
||||||
{
|
|
||||||
var size = Marshal.SizeOf(header);
|
|
||||||
var arr = new byte[size];
|
|
||||||
|
|
||||||
var ptr = Marshal.AllocHGlobal(size);
|
|
||||||
Marshal.StructureToPtr(header, ptr, true);
|
|
||||||
Marshal.Copy(ptr, arr, 0, size);
|
|
||||||
Marshal.FreeHGlobal(ptr);
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] GetPacketBytes()
|
|
||||||
{
|
|
||||||
var outBytes = new byte[header.packetSize];
|
|
||||||
Array.Copy(GetHeaderBytes(), 0, outBytes, 0, BASEPACKET_SIZE);
|
|
||||||
Array.Copy(data, 0, outBytes, BASEPACKET_SIZE, data.Length);
|
|
||||||
return outBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Replaces all instances of the sniffed actorID with the given one
|
|
||||||
public void ReplaceActorID(uint actorID)
|
|
||||||
{
|
|
||||||
using (var mem = new MemoryStream(data))
|
|
||||||
{
|
|
||||||
using (var binWriter = new BinaryWriter(mem))
|
|
||||||
{
|
|
||||||
using (var binreader = new BinaryReader(mem))
|
|
||||||
{
|
|
||||||
while (binreader.BaseStream.Position + 4 < data.Length)
|
|
||||||
{
|
|
||||||
var read = binreader.ReadUInt32();
|
|
||||||
if (read == 0x029B2941 || read == 0x02977DC7 || read == 0x0297D2C8 || read == 0x0230d573 ||
|
|
||||||
read == 0x23317df || read == 0x23344a3 || read == 0x1730bdb) //Original ID
|
|
||||||
{
|
|
||||||
binWriter.BaseStream.Seek(binreader.BaseStream.Position - 0x4, SeekOrigin.Begin);
|
|
||||||
binWriter.Write(actorID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Replaces all instances of the sniffed actorID with the given one
|
|
||||||
public void ReplaceActorID(uint fromActorID, uint actorID)
|
|
||||||
{
|
|
||||||
using (var mem = new MemoryStream(data))
|
|
||||||
{
|
|
||||||
using (var binWriter = new BinaryWriter(mem))
|
|
||||||
{
|
|
||||||
using (var binreader = new BinaryReader(mem))
|
|
||||||
{
|
|
||||||
while (binreader.BaseStream.Position + 4 < data.Length)
|
|
||||||
{
|
|
||||||
var read = binreader.ReadUInt32();
|
|
||||||
if (read == fromActorID) //Original ID
|
|
||||||
{
|
|
||||||
binWriter.BaseStream.Seek(binreader.BaseStream.Position - 0x4, SeekOrigin.Begin);
|
|
||||||
binWriter.Write(actorID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DebugPrintPacket()
|
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
logger.ColorDebug(
|
|
||||||
string.Format("IsAuth:{0} Size:0x{1:X}, NumSubpackets:{2}{3}{4}",
|
|
||||||
header.isAuthenticated, header.packetSize, header.numSubpackets,
|
|
||||||
Environment.NewLine, Utils.ByteArrayToHex(GetHeaderBytes())), ConsoleOutputColor.DarkYellow);
|
|
||||||
|
|
||||||
foreach (var sub in GetSubpackets())
|
|
||||||
{
|
|
||||||
sub.DebugPrintSubPacket();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Utility Functions
|
|
||||||
|
|
||||||
public static BasePacket CreatePacket(List<SubPacket> subpackets, bool isAuthed, bool isEncrypted)
|
|
||||||
{
|
|
||||||
//Create Header
|
|
||||||
var header = new BasePacketHeader();
|
|
||||||
byte[] data = null;
|
|
||||||
|
|
||||||
header.isAuthenticated = isAuthed ? (byte) 1 : (byte) 0;
|
|
||||||
header.isEncrypted = isEncrypted ? (byte) 1 : (byte) 0;
|
|
||||||
header.numSubpackets = (ushort) subpackets.Count;
|
|
||||||
header.packetSize = BASEPACKET_SIZE;
|
|
||||||
header.timestamp = Utils.MilisUnixTimeStampUTC();
|
|
||||||
|
|
||||||
//Get packet size
|
|
||||||
foreach (var subpacket in subpackets)
|
|
||||||
header.packetSize += subpacket.header.subpacketSize;
|
|
||||||
|
|
||||||
data = new byte[header.packetSize - 0x10];
|
|
||||||
|
|
||||||
//Add Subpackets
|
|
||||||
var offset = 0;
|
|
||||||
foreach (var subpacket in subpackets)
|
|
||||||
{
|
|
||||||
var subpacketData = subpacket.GetBytes();
|
|
||||||
Array.Copy(subpacketData, 0, data, offset, subpacketData.Length);
|
|
||||||
offset += (ushort) subpacketData.Length;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug.Assert(data != null && offset == data.Length && header.packetSize == 0x10 + offset);
|
|
||||||
|
|
||||||
var packet = new BasePacket(header, data);
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BasePacket CreatePacket(SubPacket subpacket, bool isAuthed, bool isEncrypted)
|
|
||||||
{
|
|
||||||
//Create Header
|
|
||||||
var header = new BasePacketHeader();
|
|
||||||
byte[] data = null;
|
|
||||||
|
|
||||||
header.isAuthenticated = isAuthed ? (byte) 1 : (byte) 0;
|
|
||||||
header.isEncrypted = isEncrypted ? (byte) 1 : (byte) 0;
|
|
||||||
header.numSubpackets = 1;
|
|
||||||
header.packetSize = BASEPACKET_SIZE;
|
|
||||||
header.timestamp = Utils.MilisUnixTimeStampUTC();
|
|
||||||
|
|
||||||
//Get packet size
|
|
||||||
header.packetSize += subpacket.header.subpacketSize;
|
|
||||||
|
|
||||||
data = new byte[header.packetSize - 0x10];
|
|
||||||
|
|
||||||
//Add Subpackets
|
|
||||||
var subpacketData = subpacket.GetBytes();
|
|
||||||
Array.Copy(subpacketData, 0, data, 0, subpacketData.Length);
|
|
||||||
|
|
||||||
Debug.Assert(data != null);
|
|
||||||
|
|
||||||
var packet = new BasePacket(header, data);
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BasePacket CreatePacket(byte[] data, bool isAuthed, bool isEncrypted)
|
|
||||||
{
|
|
||||||
Debug.Assert(data != null);
|
|
||||||
|
|
||||||
//Create Header
|
|
||||||
var header = new BasePacketHeader();
|
|
||||||
|
|
||||||
header.isAuthenticated = isAuthed ? (byte) 1 : (byte) 0;
|
|
||||||
header.isEncrypted = isEncrypted ? (byte) 1 : (byte) 0;
|
|
||||||
header.numSubpackets = 1;
|
|
||||||
header.packetSize = BASEPACKET_SIZE;
|
|
||||||
header.timestamp = Utils.MilisUnixTimeStampUTC();
|
|
||||||
|
|
||||||
//Get packet size
|
|
||||||
header.packetSize += (ushort) data.Length;
|
|
||||||
|
|
||||||
var packet = new BasePacket(header, data);
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static unsafe void EncryptPacket(Blowfish blowfish, BasePacket packet)
|
|
||||||
{
|
|
||||||
var data = packet.data;
|
|
||||||
int size = packet.header.packetSize;
|
|
||||||
|
|
||||||
var offset = 0;
|
|
||||||
while (offset < data.Length)
|
|
||||||
{
|
|
||||||
if (data.Length < offset + SubPacket.SUBPACKET_SIZE)
|
|
||||||
throw new OverflowException("Packet Error: Subpacket was too small");
|
|
||||||
|
|
||||||
SubPacketHeader header;
|
|
||||||
fixed (byte* pdata = &data[offset])
|
|
||||||
{
|
|
||||||
header = (SubPacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.Length < offset + header.subpacketSize)
|
|
||||||
throw new OverflowException("Packet Error: Subpacket size didn't equal subpacket data");
|
|
||||||
|
|
||||||
blowfish.Encipher(data, offset + 0x10, header.subpacketSize - 0x10);
|
|
||||||
|
|
||||||
offset += header.subpacketSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static unsafe void DecryptPacket(Blowfish blowfish, ref BasePacket packet)
|
|
||||||
{
|
|
||||||
var data = packet.data;
|
|
||||||
int size = packet.header.packetSize;
|
|
||||||
|
|
||||||
var offset = 0;
|
|
||||||
while (offset < data.Length)
|
|
||||||
{
|
|
||||||
if (data.Length < offset + SubPacket.SUBPACKET_SIZE)
|
|
||||||
throw new OverflowException("Packet Error: Subpacket was too small");
|
|
||||||
|
|
||||||
SubPacketHeader header;
|
|
||||||
fixed (byte* pdata = &data[offset])
|
|
||||||
{
|
|
||||||
header = (SubPacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.Length < offset + header.subpacketSize)
|
|
||||||
throw new OverflowException("Packet Error: Subpacket size didn't equal subpacket data");
|
|
||||||
|
|
||||||
blowfish.Decipher(data, offset + 0x10, header.subpacketSize - 0x10);
|
|
||||||
|
|
||||||
offset += header.subpacketSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class LoggerExtensions
|
|
||||||
{
|
|
||||||
public static void ColorDebug(this Logger logger, string message, ConsoleOutputColor color)
|
|
||||||
{
|
|
||||||
var logEvent = new LogEventInfo(LogLevel.Debug, logger.Name, message);
|
|
||||||
logEvent.Properties["color"] = (int) color;
|
|
||||||
logger.Log(logEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,5 @@
|
||||||
using FFXIVClassic_Lobby_Server.dataobjects;
|
using FFXIVClassic.Common;
|
||||||
|
using FFXIVClassic_Lobby_Server.dataobjects;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using FFXIVClassic.Common;
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using FFXIVClassic_Lobby_Server.dataobjects;
|
using FFXIVClassic.Common;
|
||||||
|
using FFXIVClassic_Lobby_Server.dataobjects;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using FFXIVClassic.Common;
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using FFXIVClassic.Common;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using FFXIVClassic.Common;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using FFXIVClassic.Common;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using FFXIVClassic_Lobby_Server.dataobjects;
|
using FFXIVClassic.Common;
|
||||||
|
using FFXIVClassic_Lobby_Server.dataobjects;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
|
@ -1,40 +1,25 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Sockets;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Threading;
|
|
||||||
using FFXIVClassic.Common;
|
using FFXIVClassic.Common;
|
||||||
using FFXIVClassic_Map_Server.dataobjects;
|
using FFXIVClassic_Map_Server.dataobjects;
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||||
using FFXIVClassic_Map_Server;
|
|
||||||
using FFXIVClassic_Map_Server.packets.send;
|
using FFXIVClassic_Map_Server.packets.send;
|
||||||
using FFXIVClassic_Map_Server.dataobjects.chara;
|
|
||||||
using FFXIVClassic_Map_Server.Actors;
|
|
||||||
using FFXIVClassic_Map_Server.lua;
|
using FFXIVClassic_Map_Server.lua;
|
||||||
using FFXIVClassic_Map_Server.actors.chara.player;
|
using FFXIVClassic_Map_Server.Actors;
|
||||||
using FFXIVClassic_Map_Server.Properties;
|
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server
|
namespace FFXIVClassic_Map_Server
|
||||||
{
|
{
|
||||||
class CommandProcessor
|
class CommandProcessor
|
||||||
{
|
{
|
||||||
private Dictionary<uint, ConnectedPlayer> mConnectedPlayerList;
|
|
||||||
private static Dictionary<uint, Item> gamedataItems = Server.GetGamedataItems();
|
private static Dictionary<uint, Item> gamedataItems = Server.GetGamedataItems();
|
||||||
|
|
||||||
// For the moment, this is the only predefined item
|
// For the moment, this is the only predefined item
|
||||||
// TODO: make a list/enum in the future so that items can be given by name, instead of by id
|
// TODO: make a list/enum in the future so that items can be given by name, instead of by id
|
||||||
const UInt32 ITEM_GIL = 1000001;
|
const UInt32 ITEM_GIL = 1000001;
|
||||||
|
|
||||||
public CommandProcessor(Dictionary<uint, ConnectedPlayer> playerList)
|
|
||||||
{
|
|
||||||
mConnectedPlayerList = playerList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ChangeProperty(uint id, uint value, string target)
|
public void ChangeProperty(uint id, uint value, string target)
|
||||||
{
|
{
|
||||||
SetActorPropetyPacket ChangeProperty = new SetActorPropetyPacket(target);
|
SetActorPropetyPacket ChangeProperty = new SetActorPropetyPacket(target);
|
||||||
|
@ -43,9 +28,11 @@ namespace FFXIVClassic_Map_Server
|
||||||
ChangeProperty.AddInt(id, value);
|
ChangeProperty.AddInt(id, value);
|
||||||
ChangeProperty.AddTarget();
|
ChangeProperty.AddTarget();
|
||||||
|
|
||||||
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
|
Dictionary<uint, Session> sessionList = Server.GetServer().GetSessionList();
|
||||||
|
|
||||||
|
foreach (KeyValuePair<uint, Session> entry in sessionList)
|
||||||
{
|
{
|
||||||
SubPacket ChangePropertyPacket = ChangeProperty.BuildPacket((entry.Value.actorID), (entry.Value.actorID));
|
SubPacket ChangePropertyPacket = ChangeProperty.BuildPacket((entry.Value.id), (entry.Value.id));
|
||||||
|
|
||||||
BasePacket packet = BasePacket.CreatePacket(ChangePropertyPacket, true, false);
|
BasePacket packet = BasePacket.CreatePacket(ChangePropertyPacket, true, false);
|
||||||
packet.DebugPrintPacket();
|
packet.DebugPrintPacket();
|
||||||
|
@ -60,13 +47,13 @@ namespace FFXIVClassic_Map_Server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="client"></param>
|
/// <param name="client"></param>
|
||||||
/// <param name="message"></param>
|
/// <param name="message"></param>
|
||||||
private void SendMessage(ConnectedPlayer client, String message)
|
private void SendMessage(Session session, String message)
|
||||||
{
|
{
|
||||||
if (client != null)
|
if (session != null)
|
||||||
client.GetActor().QueuePacket(SendMessagePacket.BuildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", message));
|
session.GetActor().QueuePacket(SendMessagePacket.BuildPacket(session.id, session.id, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", message));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool DoCommand(string input, ConnectedPlayer client)
|
internal bool DoCommand(string input, Session session)
|
||||||
{
|
{
|
||||||
if (!input.Any() || input.Equals(""))
|
if (!input.Any() || input.Equals(""))
|
||||||
return false;
|
return false;
|
||||||
|
@ -88,7 +75,9 @@ namespace FFXIVClassic_Map_Server
|
||||||
if (cmd.Any())
|
if (cmd.Any())
|
||||||
{
|
{
|
||||||
// if client isnt null, take player to be the player actor
|
// if client isnt null, take player to be the player actor
|
||||||
var player = client?.GetActor();
|
Player player = null;
|
||||||
|
if (session != null)
|
||||||
|
player = session.GetActor();
|
||||||
|
|
||||||
if (cmd.Equals("help"))
|
if (cmd.Equals("help"))
|
||||||
{
|
{
|
||||||
|
@ -125,11 +114,11 @@ namespace FFXIVClassic_Map_Server
|
||||||
if (split[0].Equals("reloaditems"))
|
if (split[0].Equals("reloaditems"))
|
||||||
{
|
{
|
||||||
Program.Log.Info(String.Format("Got request to reload item gamedata"));
|
Program.Log.Info(String.Format("Got request to reload item gamedata"));
|
||||||
SendMessage(client, "Reloading Item Gamedata...");
|
SendMessage(session, "Reloading Item Gamedata...");
|
||||||
gamedataItems.Clear();
|
gamedataItems.Clear();
|
||||||
gamedataItems = Database.GetItemGamedata();
|
gamedataItems = Database.GetItemGamedata();
|
||||||
Program.Log.Info(String.Format("Loaded {0} items.", gamedataItems.Count));
|
Program.Log.Info(String.Format("Loaded {0} items.", gamedataItems.Count));
|
||||||
SendMessage(client, String.Format("Loaded {0} items.", gamedataItems.Count));
|
SendMessage(session, String.Format("Loaded {0} items.", gamedataItems.Count));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace FFXIVClassic_Map_Server
|
||||||
INIFile configIni = new INIFile("./map_config.ini");
|
INIFile configIni = new INIFile("./map_config.ini");
|
||||||
|
|
||||||
ConfigConstants.OPTIONS_BINDIP = configIni.GetValue("General", "server_ip", "127.0.0.1");
|
ConfigConstants.OPTIONS_BINDIP = configIni.GetValue("General", "server_ip", "127.0.0.1");
|
||||||
ConfigConstants.OPTIONS_PORT = configIni.GetValue("General", "server_port", "54992");
|
ConfigConstants.OPTIONS_PORT = configIni.GetValue("General", "server_port", "1989");
|
||||||
ConfigConstants.OPTIONS_TIMESTAMP = configIni.GetValue("General", "showtimestamp", "true").ToLower().Equals("true");
|
ConfigConstants.OPTIONS_TIMESTAMP = configIni.GetValue("General", "showtimestamp", "true").ToLower().Equals("true");
|
||||||
|
|
||||||
ConfigConstants.DATABASE_WORLDID = UInt32.Parse(configIni.GetValue("Database", "worldid", "0"));
|
ConfigConstants.DATABASE_WORLDID = UInt32.Parse(configIni.GetValue("Database", "worldid", "0"));
|
||||||
|
|
|
@ -5,7 +5,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FFXIVClassic.Common;
|
using FFXIVClassic.Common;
|
||||||
using FFXIVClassic_Map_Server.utils;
|
using FFXIVClassic_Map_Server.utils;
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
using FFXIVClassic_Map_Server.packets.send.player;
|
using FFXIVClassic_Map_Server.packets.send.player;
|
||||||
using FFXIVClassic_Map_Server.dataobjects;
|
using FFXIVClassic_Map_Server.dataobjects;
|
||||||
using FFXIVClassic_Map_Server.Actors;
|
using FFXIVClassic_Map_Server.Actors;
|
||||||
|
@ -258,6 +258,8 @@ namespace FFXIVClassic_Map_Server
|
||||||
positionY = @y,
|
positionY = @y,
|
||||||
positionZ = @z,
|
positionZ = @z,
|
||||||
rotation = @rot,
|
rotation = @rot,
|
||||||
|
destinationZoneId = @destZone,
|
||||||
|
destinationSpawnType = @destSpawn,
|
||||||
currentZoneId = @zoneId
|
currentZoneId = @zoneId
|
||||||
WHERE id = @charaId
|
WHERE id = @charaId
|
||||||
";
|
";
|
||||||
|
@ -269,6 +271,8 @@ namespace FFXIVClassic_Map_Server
|
||||||
cmd.Parameters.AddWithValue("@z", player.positionZ);
|
cmd.Parameters.AddWithValue("@z", player.positionZ);
|
||||||
cmd.Parameters.AddWithValue("@rot", player.rotation);
|
cmd.Parameters.AddWithValue("@rot", player.rotation);
|
||||||
cmd.Parameters.AddWithValue("@zoneId", player.zoneId);
|
cmd.Parameters.AddWithValue("@zoneId", player.zoneId);
|
||||||
|
cmd.Parameters.AddWithValue("@destZone", player.destinationZone);
|
||||||
|
cmd.Parameters.AddWithValue("@destSpawn", player.destinationSpawnType);
|
||||||
|
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
|
@ -402,7 +406,9 @@ namespace FFXIVClassic_Map_Server
|
||||||
tribe,
|
tribe,
|
||||||
restBonus,
|
restBonus,
|
||||||
achievementPoints,
|
achievementPoints,
|
||||||
playTime
|
playTime,
|
||||||
|
destinationZoneId,
|
||||||
|
destinationSpawnType
|
||||||
FROM characters WHERE id = @charId";
|
FROM characters WHERE id = @charId";
|
||||||
|
|
||||||
cmd = new MySqlCommand(query, conn);
|
cmd = new MySqlCommand(query, conn);
|
||||||
|
@ -419,8 +425,7 @@ namespace FFXIVClassic_Map_Server
|
||||||
player.oldRotation = player.rotation = reader.GetFloat(4);
|
player.oldRotation = player.rotation = reader.GetFloat(4);
|
||||||
player.currentMainState = reader.GetUInt16(5);
|
player.currentMainState = reader.GetUInt16(5);
|
||||||
player.zoneId = reader.GetUInt32(6);
|
player.zoneId = reader.GetUInt32(6);
|
||||||
player.isZoning = true;
|
player.isZoning = true;
|
||||||
player.zone = Server.GetWorldManager().GetZone(player.zoneId);
|
|
||||||
player.gcCurrent = reader.GetByte(7);
|
player.gcCurrent = reader.GetByte(7);
|
||||||
player.gcRankLimsa = reader.GetByte(8);
|
player.gcRankLimsa = reader.GetByte(8);
|
||||||
player.gcRankGridania = reader.GetByte(9);
|
player.gcRankGridania = reader.GetByte(9);
|
||||||
|
@ -434,6 +439,13 @@ namespace FFXIVClassic_Map_Server
|
||||||
player.playerWork.restBonusExpRate = reader.GetInt32(17);
|
player.playerWork.restBonusExpRate = reader.GetInt32(17);
|
||||||
player.achievementPoints = reader.GetUInt32(18);
|
player.achievementPoints = reader.GetUInt32(18);
|
||||||
player.playTime = reader.GetUInt32(19);
|
player.playTime = reader.GetUInt32(19);
|
||||||
|
player.destinationZone = reader.GetUInt32("destinationZoneId");
|
||||||
|
player.destinationSpawnType = reader.GetByte("destinationSpawnType");
|
||||||
|
|
||||||
|
if (player.destinationZone != 0)
|
||||||
|
player.zoneId = player.destinationZone;
|
||||||
|
|
||||||
|
player.zone = Server.GetWorldManager().GetZone(player.zoneId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@
|
||||||
<Compile Include="actors\quest\Quest.cs" />
|
<Compile Include="actors\quest\Quest.cs" />
|
||||||
<Compile Include="actors\StaticActors.cs" />
|
<Compile Include="actors\StaticActors.cs" />
|
||||||
<Compile Include="actors\world\WorldMaster.cs" />
|
<Compile Include="actors\world\WorldMaster.cs" />
|
||||||
<Compile Include="ClientConnection.cs" />
|
<Compile Include="dataobjects\ZoneConnection.cs" />
|
||||||
<Compile Include="CommandProcessor.cs" />
|
<Compile Include="CommandProcessor.cs" />
|
||||||
<Compile Include="ConfigConstants.cs" />
|
<Compile Include="ConfigConstants.cs" />
|
||||||
<Compile Include="Database.cs" />
|
<Compile Include="Database.cs" />
|
||||||
|
@ -112,7 +112,7 @@
|
||||||
<Compile Include="actors\chara\player\PlayerWork.cs" />
|
<Compile Include="actors\chara\player\PlayerWork.cs" />
|
||||||
<Compile Include="dataobjects\DBWorld.cs" />
|
<Compile Include="dataobjects\DBWorld.cs" />
|
||||||
<Compile Include="dataobjects\InventoryItem.cs" />
|
<Compile Include="dataobjects\InventoryItem.cs" />
|
||||||
<Compile Include="dataobjects\ConnectedPlayer.cs" />
|
<Compile Include="dataobjects\Session.cs" />
|
||||||
<Compile Include="dataobjects\Item.cs" />
|
<Compile Include="dataobjects\Item.cs" />
|
||||||
<Compile Include="dataobjects\RecruitmentDetails.cs" />
|
<Compile Include="dataobjects\RecruitmentDetails.cs" />
|
||||||
<Compile Include="dataobjects\SeamlessBoundry.cs" />
|
<Compile Include="dataobjects\SeamlessBoundry.cs" />
|
||||||
|
@ -124,7 +124,6 @@
|
||||||
<Compile Include="lua\LuaPlayer.cs" />
|
<Compile Include="lua\LuaPlayer.cs" />
|
||||||
<Compile Include="lua\LuaScript.cs" />
|
<Compile Include="lua\LuaScript.cs" />
|
||||||
<Compile Include="PacketProcessor.cs" />
|
<Compile Include="PacketProcessor.cs" />
|
||||||
<Compile Include="packets\BasePacket.cs" />
|
|
||||||
<Compile Include="packets\receive\ChatMessagePacket.cs" />
|
<Compile Include="packets\receive\ChatMessagePacket.cs" />
|
||||||
<Compile Include="packets\receive\events\EventUpdatePacket.cs" />
|
<Compile Include="packets\receive\events\EventUpdatePacket.cs" />
|
||||||
<Compile Include="packets\receive\events\EventStartPacket.cs" />
|
<Compile Include="packets\receive\events\EventStartPacket.cs" />
|
||||||
|
@ -258,9 +257,13 @@
|
||||||
<Compile Include="packets\send\_0x02Packet.cs" />
|
<Compile Include="packets\send\_0x02Packet.cs" />
|
||||||
<Compile Include="packets\send\_0x10Packet.cs" />
|
<Compile Include="packets\send\_0x10Packet.cs" />
|
||||||
<Compile Include="packets\send\_0xE2Packet.cs" />
|
<Compile Include="packets\send\_0xE2Packet.cs" />
|
||||||
<Compile Include="packets\SubPacket.cs" />
|
|
||||||
<Compile Include="packets\receive\PingPacket.cs" />
|
<Compile Include="packets\receive\PingPacket.cs" />
|
||||||
<Compile Include="packets\receive\UpdatePlayerPositionPacket.cs" />
|
<Compile Include="packets\receive\UpdatePlayerPositionPacket.cs" />
|
||||||
|
<Compile Include="packets\WorldPackets\Receive\ErrorPacket.cs" />
|
||||||
|
<Compile Include="packets\WorldPackets\Receive\SessionEndPacket.cs" />
|
||||||
|
<Compile Include="packets\WorldPackets\Receive\SessionBeginPacket.cs" />
|
||||||
|
<Compile Include="packets\WorldPackets\Send\SessionBeginConfirmPacket.cs" />
|
||||||
|
<Compile Include="packets\WorldPackets\Send\SessionEndConfirmPacket.cs" />
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="lua\LuaUtils.cs" />
|
<Compile Include="lua\LuaUtils.cs" />
|
||||||
|
@ -286,6 +289,7 @@
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</None>
|
</None>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
<Compile Include="packets\WorldPackets\Send\WorldRequestZoneChangePacket.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="Properties\Resources.resx">
|
<EmbeddedResource Include="Properties\Resources.resx">
|
||||||
|
|
|
@ -38,13 +38,13 @@
|
||||||
<target xsi:type="ColoredConsole" name="packets"
|
<target xsi:type="ColoredConsole" name="packets"
|
||||||
layout="${message}">
|
layout="${message}">
|
||||||
<highlight-row
|
<highlight-row
|
||||||
condition="equals('${logger}', 'FFXIVClassic_Map_Server.packets.BasePacket') and equals('${event-context:item=color}', '6')"
|
condition="equals('${logger}', 'FFXIVClassic.Common.BasePacket') and equals('${event-context:item=color}', '6')"
|
||||||
backgroundColor="DarkYellow" foregroundColor="NoChange" />
|
backgroundColor="DarkYellow" foregroundColor="NoChange" />
|
||||||
<highlight-row
|
<highlight-row
|
||||||
condition="equals('${logger}', 'FFXIVClassic_Map_Server.packets.SubPacket') and equals('${event-context:item=color}', '4')"
|
condition="equals('${logger}', 'FFXIVClassic.Common.SubPacket') and equals('${event-context:item=color}', '4')"
|
||||||
backgroundColor="DarkRed" foregroundColor="NoChange" />
|
backgroundColor="DarkRed" foregroundColor="NoChange" />
|
||||||
<highlight-row
|
<highlight-row
|
||||||
condition="equals('${logger}', 'FFXIVClassic_Map_Server.packets.SubPacket') and equals('${event-context:item=color}', '5')"
|
condition="equals('${logger}', 'FFXIVClassic.Common.SubPacket') and equals('${event-context:item=color}', '5')"
|
||||||
backgroundColor="DarkMagenta" foregroundColor="NoChange" />
|
backgroundColor="DarkMagenta" foregroundColor="NoChange" />
|
||||||
</target>
|
</target>
|
||||||
</targets>
|
</targets>
|
||||||
|
@ -55,6 +55,7 @@
|
||||||
<logger name='FFXIVClassic_Map_Server.Program' minlevel='Trace' writeTo='console' />
|
<logger name='FFXIVClassic_Map_Server.Program' minlevel='Trace' writeTo='console' />
|
||||||
<logger name='FFXIVClassic_Map_Server.lua.*' minlevel='Trace' writeTo='console' />
|
<logger name='FFXIVClassic_Map_Server.lua.*' minlevel='Trace' writeTo='console' />
|
||||||
<logger name='FFXIVClassic_Map_Server.packets.*' minlevel='Debug' writeTo='packets' />
|
<logger name='FFXIVClassic_Map_Server.packets.*' minlevel='Debug' writeTo='packets' />
|
||||||
|
<logger name='FFXIVClassic.Common.*' minlevel='Debug' writeTo='packets' />
|
||||||
<!--
|
<!--
|
||||||
Write all events with minimal level of Debug (So Debug, Info, Warn, Error and Fatal, but not Trace) to "f"
|
Write all events with minimal level of Debug (So Debug, Info, Warn, Error and Fatal, but not Trace) to "f"
|
||||||
<logger name="*" minlevel="Debug" writeTo="f" />
|
<logger name="*" minlevel="Debug" writeTo="f" />
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
using FFXIVClassic.Common;
|
using FFXIVClassic.Common;
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -17,402 +17,319 @@ using FFXIVClassic_Map_Server.packets.receive.recruitment;
|
||||||
using FFXIVClassic_Map_Server.packets.send.recruitment;
|
using FFXIVClassic_Map_Server.packets.send.recruitment;
|
||||||
using FFXIVClassic_Map_Server.packets.receive.events;
|
using FFXIVClassic_Map_Server.packets.receive.events;
|
||||||
using FFXIVClassic_Map_Server.lua;
|
using FFXIVClassic_Map_Server.lua;
|
||||||
using FFXIVClassic_Map_Server.Actors;
|
using FFXIVClassic_Map_Server.Actors;
|
||||||
|
using FFXIVClassic_Map_Server.packets.WorldPackets.Send;
|
||||||
|
using FFXIVClassic_Map_Server.packets.WorldPackets.Receive;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server
|
namespace FFXIVClassic_Map_Server
|
||||||
{
|
{
|
||||||
class PacketProcessor
|
class PacketProcessor
|
||||||
{
|
{
|
||||||
Server mServer;
|
Server mServer;
|
||||||
CommandProcessor cp;
|
|
||||||
Dictionary<uint, ConnectedPlayer> mPlayers;
|
|
||||||
List<ClientConnection> mConnections;
|
|
||||||
|
|
||||||
public PacketProcessor(Server server, Dictionary<uint, ConnectedPlayer> playerList, List<ClientConnection> connectionList)
|
public PacketProcessor(Server server)
|
||||||
{
|
{
|
||||||
mPlayers = playerList;
|
|
||||||
mConnections = connectionList;
|
|
||||||
mServer = server;
|
mServer = server;
|
||||||
cp = new CommandProcessor(playerList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ProcessPacket(ClientConnection client, BasePacket packet)
|
public void ProcessPacket(ZoneConnection client, SubPacket subpacket)
|
||||||
{
|
{
|
||||||
if (packet.header.isCompressed == 0x01)
|
Session session = mServer.GetSession(subpacket.header.targetId);
|
||||||
BasePacket.DecryptPacket(client.blowfish, ref packet);
|
|
||||||
|
if (session == null && subpacket.gameMessage.opcode != 0x1000)
|
||||||
|
return;
|
||||||
|
|
||||||
List<SubPacket> subPackets = packet.GetSubpackets();
|
//Normal Game Opcode
|
||||||
foreach (SubPacket subpacket in subPackets)
|
switch (subpacket.gameMessage.opcode)
|
||||||
{
|
{
|
||||||
if (subpacket.header.type == 0x01)
|
//World Server - Error
|
||||||
{
|
case 0x100A:
|
||||||
packet.DebugPrintPacket();
|
ErrorPacket worldError = new ErrorPacket(subpacket.data);
|
||||||
byte[] reply1Data = {
|
switch (worldError.errorCode)
|
||||||
0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
{
|
||||||
0x18, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFD, 0xFF, 0xFF,
|
case 0x01:
|
||||||
0xE5, 0x6E, 0x01, 0xE0, 0x00, 0x00, 0x00, 0x0
|
session.GetActor().SendGameMessage(Server.GetWorldManager().GetActor(), 60005, 0x20);
|
||||||
};
|
break;
|
||||||
|
}
|
||||||
byte[] reply2Data = {
|
|
||||||
0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x38, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x2B, 0x5F, 0x26,
|
|
||||||
0x66, 0x00, 0x00, 0x00, 0xC8, 0xD6, 0xAF, 0x2B, 0x38, 0x2B, 0x5F, 0x26, 0xB8, 0x8D, 0xF0, 0x2B,
|
|
||||||
0xC8, 0xFD, 0x85, 0xFE, 0xA8, 0x7C, 0x5B, 0x09, 0x38, 0x2B, 0x5F, 0x26, 0xC8, 0xD6, 0xAF, 0x2B,
|
|
||||||
0xB8, 0x8D, 0xF0, 0x2B, 0x88, 0xAF, 0x5E, 0x26
|
|
||||||
};
|
|
||||||
|
|
||||||
BasePacket reply1 = new BasePacket(reply1Data);
|
|
||||||
BasePacket reply2 = new BasePacket(reply2Data);
|
|
||||||
|
|
||||||
//Write Timestamp into Reply1
|
|
||||||
using (MemoryStream mem = new MemoryStream(reply1.data))
|
|
||||||
{
|
|
||||||
using (BinaryWriter binReader = new BinaryWriter(mem))
|
|
||||||
{
|
|
||||||
binReader.BaseStream.Seek(0x14, SeekOrigin.Begin);
|
|
||||||
binReader.Write((UInt32)Utils.UnixTimeStampUTC());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Read in Actor Id that owns this connection
|
|
||||||
uint actorID = 0;
|
|
||||||
using (MemoryStream mem = new MemoryStream(packet.data))
|
|
||||||
{
|
|
||||||
using (BinaryReader binReader = new BinaryReader(mem))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
byte[] readIn = new byte[12];
|
|
||||||
binReader.BaseStream.Seek(0x14, SeekOrigin.Begin);
|
|
||||||
binReader.Read(readIn, 0, 12);
|
|
||||||
actorID = UInt32.Parse(Encoding.ASCII.GetString(readIn));
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{ }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Should never happen.... unless actor id IS 0!
|
|
||||||
if (actorID == 0)
|
|
||||||
break;
|
break;
|
||||||
|
//World Server - Session Begin
|
||||||
|
case 0x1000:
|
||||||
|
subpacket.DebugPrintSubPacket();
|
||||||
|
session = mServer.AddSession(subpacket.header.targetId);
|
||||||
|
|
||||||
|
if (session.GetActor().destinationZone != 0)
|
||||||
|
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);
|
||||||
|
|
||||||
|
client.QueuePacket(SessionEndConfirmPacket.BuildPacket(session, endSessionPacket.destinationZoneId), true, false);
|
||||||
|
client.FlushQueuedSendPackets();
|
||||||
|
break;
|
||||||
|
//Ping
|
||||||
|
case 0x0001:
|
||||||
|
//subpacket.DebugPrintSubPacket();
|
||||||
|
PingPacket pingPacket = new PingPacket(subpacket.data);
|
||||||
|
client.QueuePacket(BasePacket.CreatePacket(PongPacket.BuildPacket(session.id, pingPacket.time), true, false));
|
||||||
|
session.Ping();
|
||||||
|
break;
|
||||||
|
//Unknown
|
||||||
|
case 0x0002:
|
||||||
|
|
||||||
client.owner = actorID;
|
subpacket.DebugPrintSubPacket();
|
||||||
|
session = mServer.AddSession(subpacket.header.targetId);
|
||||||
//Write Actor ID into reply2
|
client.QueuePacket(_0x2Packet.BuildPacket(session.id), true, false);
|
||||||
using (MemoryStream mem = new MemoryStream(reply2.data))
|
|
||||||
{
|
LuaEngine.OnBeginLogin(session.GetActor());
|
||||||
using (BinaryWriter binReader = new BinaryWriter(mem))
|
Server.GetWorldManager().DoZoneIn(session.GetActor(), true, 0x1);
|
||||||
|
LuaEngine.OnLogin(session.GetActor());
|
||||||
|
|
||||||
|
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);
|
||||||
|
subpacket.DebugPrintSubPacket();
|
||||||
|
|
||||||
|
if (chatMessage.message.StartsWith("!"))
|
||||||
{
|
{
|
||||||
binReader.BaseStream.Seek(0x10, SeekOrigin.Begin);
|
if (Server.GetCommandProcessor().DoCommand(chatMessage.message, session))
|
||||||
binReader.Write(actorID);
|
return; ;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
session.GetActor().BroadcastPacket(SendMessagePacket.BuildPacket(session.id, session.id, chatMessage.logType, session.GetActor().customDisplayName, chatMessage.message), false);
|
||||||
|
|
||||||
ConnectedPlayer player = null;
|
break;
|
||||||
|
//Langauge Code
|
||||||
if (packet.header.connectionType == BasePacket.TYPE_ZONE)
|
case 0x0006:
|
||||||
{
|
LangaugeCodePacket langCode = new LangaugeCodePacket(subpacket.data);
|
||||||
while (mPlayers != null && !mPlayers.ContainsKey(client.owner))
|
session.languageCode = langCode.languageCode;
|
||||||
{ }
|
break;
|
||||||
player = mPlayers[client.owner];
|
//Unknown - Happens a lot at login, then once every time player zones
|
||||||
}
|
case 0x0007:
|
||||||
|
//subpacket.DebugPrintSubPacket();
|
||||||
//Create connected player if not Created
|
_0x07Packet unknown07 = new _0x07Packet(subpacket.data);
|
||||||
if (player == null)
|
break;
|
||||||
{
|
//Update Position
|
||||||
player = new ConnectedPlayer(actorID);
|
case 0x00CA:
|
||||||
mPlayers[actorID] = player;
|
|
||||||
}
|
|
||||||
|
|
||||||
player.SetConnection(packet.header.connectionType, client);
|
|
||||||
|
|
||||||
if (packet.header.connectionType == BasePacket.TYPE_ZONE)
|
|
||||||
Program.Log.Info("Got {0} connection for ActorID {1} @ {2}.", "zone", actorID, client.GetAddress());
|
|
||||||
else if (packet.header.connectionType == BasePacket.TYPE_CHAT)
|
|
||||||
Program.Log.Info("Got {0} connection for ActorID {1} @ {2}.", "chat", actorID, client.GetAddress());
|
|
||||||
|
|
||||||
//Create player actor
|
|
||||||
reply1.DebugPrintPacket();
|
|
||||||
client.QueuePacket(reply1);
|
|
||||||
client.QueuePacket(reply2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (subpacket.header.type == 0x07)
|
|
||||||
{
|
|
||||||
BasePacket init = Login0x7ResponsePacket.BuildPacket(BitConverter.ToUInt32(packet.data, 0x10), Utils.UnixTimeStampUTC(), 0x08);
|
|
||||||
//client.QueuePacket(init);
|
|
||||||
}
|
|
||||||
else if (subpacket.header.type == 0x08)
|
|
||||||
{
|
|
||||||
//Response, client's current [actorID][time]
|
|
||||||
//BasePacket init = Login0x7ResponsePacket.BuildPacket(BitConverter.ToUInt32(packet.data, 0x10), Utils.UnixTimeStampUTC(), 0x07);
|
|
||||||
//client.QueuePacket(init);
|
|
||||||
packet.DebugPrintPacket();
|
|
||||||
}
|
|
||||||
else if (subpacket.header.type == 0x03)
|
|
||||||
{
|
|
||||||
ConnectedPlayer player = null;
|
|
||||||
|
|
||||||
if(mPlayers.ContainsKey(client.owner))
|
|
||||||
player = mPlayers[client.owner];
|
|
||||||
|
|
||||||
if (player == null || !player.IsClientConnectionsReady())
|
|
||||||
return;
|
|
||||||
|
|
||||||
//Normal Game Opcode
|
|
||||||
switch (subpacket.gameMessage.opcode)
|
|
||||||
{
|
|
||||||
//Ping
|
|
||||||
case 0x0001:
|
|
||||||
//subpacket.DebugPrintSubPacket();
|
|
||||||
PingPacket pingPacket = new PingPacket(subpacket.data);
|
|
||||||
client.QueuePacket(BasePacket.CreatePacket(PongPacket.BuildPacket(player.actorID, pingPacket.time), true, false));
|
|
||||||
player.Ping();
|
|
||||||
break;
|
|
||||||
//Unknown
|
|
||||||
case 0x0002:
|
|
||||||
|
|
||||||
subpacket.DebugPrintSubPacket();
|
|
||||||
client.QueuePacket(_0x2Packet.BuildPacket(player.actorID), true, false);
|
|
||||||
|
|
||||||
Server.GetWorldManager().DoLogin(player.GetActor());
|
|
||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
subpacket.DebugPrintSubPacket();
|
|
||||||
|
|
||||||
if (chatMessage.message.StartsWith("!"))
|
|
||||||
{
|
|
||||||
if (cp.DoCommand(chatMessage.message, player))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
player.GetActor().BroadcastPacket(SendMessagePacket.BuildPacket(player.actorID, player.actorID, chatMessage.logType, player.GetActor().customDisplayName, chatMessage.message), false);
|
|
||||||
|
|
||||||
break;
|
|
||||||
//Langauge Code
|
|
||||||
case 0x0006:
|
|
||||||
LangaugeCodePacket langCode = new LangaugeCodePacket(subpacket.data);
|
|
||||||
player.languageCode = langCode.languageCode;
|
|
||||||
break;
|
|
||||||
//Unknown - Happens a lot at login, then once every time player zones
|
|
||||||
case 0x0007:
|
|
||||||
//subpacket.DebugPrintSubPacket();
|
|
||||||
_0x07Packet unknown07 = new _0x07Packet(subpacket.data);
|
|
||||||
break;
|
|
||||||
//Update Position
|
//Update Position
|
||||||
case 0x00CA:
|
UpdatePlayerPositionPacket posUpdate = new UpdatePlayerPositionPacket(subpacket.data);
|
||||||
//Update Position
|
session.UpdatePlayerActorPosition(posUpdate.x, posUpdate.y, posUpdate.z, posUpdate.rot, posUpdate.moveState);
|
||||||
//subpacket.DebugPrintSubPacket();
|
session.GetActor().SendInstanceUpdate();
|
||||||
UpdatePlayerPositionPacket posUpdate = new UpdatePlayerPositionPacket(subpacket.data);
|
|
||||||
player.UpdatePlayerActorPosition(posUpdate.x, posUpdate.y, posUpdate.z, posUpdate.rot, posUpdate.moveState);
|
if (session.GetActor().IsInZoneChange())
|
||||||
player.GetActor().SendInstanceUpdate();
|
session.GetActor().SetZoneChanging(false);
|
||||||
|
|
||||||
|
break;
|
||||||
|
//Set Target
|
||||||
|
case 0x00CD:
|
||||||
|
//subpacket.DebugPrintSubPacket();
|
||||||
|
|
||||||
|
SetTargetPacket setTarget = new SetTargetPacket(subpacket.data);
|
||||||
|
session.GetActor().currentTarget = setTarget.actorID;
|
||||||
|
session.GetActor().BroadcastPacket(SetActorTargetAnimatedPacket.BuildPacket(session.id, 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);
|
||||||
|
|
||||||
if (player.GetActor().IsInZoneChange())
|
|
||||||
player.GetActor().SetZoneChanging(false);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
//Set Target
|
}
|
||||||
case 0x00CD:
|
*/
|
||||||
//subpacket.DebugPrintSubPacket();
|
|
||||||
|
|
||||||
SetTargetPacket setTarget = new SetTargetPacket(subpacket.data);
|
Actor ownerActor = Server.GetStaticActors(eventStart.scriptOwnerActorID);
|
||||||
player.GetActor().currentTarget = setTarget.actorID;
|
|
||||||
player.GetActor().BroadcastPacket(SetActorTargetAnimatedPacket.BuildPacket(player.actorID, player.actorID, setTarget.actorID), true);
|
|
||||||
break;
|
|
||||||
//Lock Target
|
|
||||||
case 0x00CC:
|
|
||||||
LockTargetPacket lockTarget = new LockTargetPacket(subpacket.data);
|
|
||||||
player.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);
|
|
||||||
|
|
||||||
|
|
||||||
player.GetActor().currentEventOwner = eventStart.scriptOwnerActorID;
|
session.GetActor().currentEventOwner = eventStart.scriptOwnerActorID;
|
||||||
player.GetActor().currentEventName = eventStart.triggerName;
|
session.GetActor().currentEventName = eventStart.triggerName;
|
||||||
|
|
||||||
|
|
||||||
|
if (ownerActor == null)
|
||||||
|
{
|
||||||
|
//Is it a instance actor?
|
||||||
|
ownerActor = Server.GetWorldManager().GetActorInWorld(session.GetActor().currentEventOwner);
|
||||||
if (ownerActor == null)
|
if (ownerActor == null)
|
||||||
{
|
{
|
||||||
//Is it a instance actor?
|
//Is it a Director?
|
||||||
ownerActor = Server.GetWorldManager().GetActorInWorld(player.GetActor().currentEventOwner);
|
if (session.GetActor().currentDirector != null && session.GetActor().currentEventOwner == session.GetActor().currentDirector.actorId)
|
||||||
if (ownerActor == null)
|
ownerActor = session.GetActor().currentDirector;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
//Is it a Director?
|
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));
|
||||||
if (player.GetActor().currentDirector != null && player.GetActor().currentEventOwner == player.GetActor().currentDirector.actorId)
|
|
||||||
ownerActor = player.GetActor().currentDirector;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
player.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:
|
|
||||||
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(player.GetActor().currentEventOwner);
|
|
||||||
if (updateOwnerActor == null)
|
|
||||||
{
|
|
||||||
updateOwnerActor = Server.GetWorldManager().GetActorInWorld(player.GetActor().currentEventOwner);
|
|
||||||
|
|
||||||
if (player.GetActor().currentDirector != null && player.GetActor().currentEventOwner == player.GetActor().currentDirector.actorId)
|
|
||||||
updateOwnerActor = player.GetActor().currentDirector;
|
|
||||||
|
|
||||||
if (updateOwnerActor == null)
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*/
|
}
|
||||||
player.GetActor().UpdateEvent(eventUpdate);
|
}
|
||||||
|
|
||||||
//LuaEngine.DoActorOnEventUpdated(player.GetActor(), updateOwnerActor, eventUpdate);
|
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:
|
||||||
|
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;
|
break;
|
||||||
case 0x012F:
|
case 0x012F:
|
||||||
//subpacket.DebugPrintSubPacket();
|
//subpacket.DebugPrintSubPacket();
|
||||||
ParameterDataRequestPacket paramRequest = new ParameterDataRequestPacket(subpacket.data);
|
ParameterDataRequestPacket paramRequest = new ParameterDataRequestPacket(subpacket.data);
|
||||||
if (paramRequest.paramName.Equals("charaWork/exp"))
|
if (paramRequest.paramName.Equals("charaWork/exp"))
|
||||||
player.GetActor().SendCharaExpInfo();
|
session.GetActor().SendCharaExpInfo();
|
||||||
break;
|
break;
|
||||||
/* RECRUITMENT */
|
/* RECRUITMENT */
|
||||||
//Start Recruiting
|
//Start Recruiting
|
||||||
case 0x01C3:
|
case 0x01C3:
|
||||||
StartRecruitingRequestPacket recruitRequestPacket = new StartRecruitingRequestPacket(subpacket.data);
|
StartRecruitingRequestPacket recruitRequestPacket = new StartRecruitingRequestPacket(subpacket.data);
|
||||||
client.QueuePacket(BasePacket.CreatePacket(StartRecruitingResponse.BuildPacket(player.actorID, true), true, false));
|
client.QueuePacket(BasePacket.CreatePacket(StartRecruitingResponse.BuildPacket(session.id, true), true, false));
|
||||||
break;
|
break;
|
||||||
//End Recruiting
|
//End Recruiting
|
||||||
case 0x01C4:
|
case 0x01C4:
|
||||||
client.QueuePacket(BasePacket.CreatePacket(EndRecruitmentPacket.BuildPacket(player.actorID), true, false));
|
client.QueuePacket(BasePacket.CreatePacket(EndRecruitmentPacket.BuildPacket(session.id), true, false));
|
||||||
break;
|
break;
|
||||||
//Party Window Opened, Request State
|
//Party Window Opened, Request State
|
||||||
case 0x01C5:
|
case 0x01C5:
|
||||||
client.QueuePacket(BasePacket.CreatePacket(RecruiterStatePacket.BuildPacket(player.actorID, true, true, 1), true, false));
|
client.QueuePacket(BasePacket.CreatePacket(RecruiterStatePacket.BuildPacket(session.id, true, true, 1), true, false));
|
||||||
break;
|
break;
|
||||||
//Search Recruiting
|
//Search Recruiting
|
||||||
case 0x01C7:
|
case 0x01C7:
|
||||||
RecruitmentSearchRequestPacket recruitSearchPacket = new RecruitmentSearchRequestPacket(subpacket.data);
|
RecruitmentSearchRequestPacket recruitSearchPacket = new RecruitmentSearchRequestPacket(subpacket.data);
|
||||||
break;
|
break;
|
||||||
//Get Recruitment Details
|
//Get Recruitment Details
|
||||||
case 0x01C8:
|
case 0x01C8:
|
||||||
RecruitmentDetailsRequestPacket currentRecruitDetailsPacket = new RecruitmentDetailsRequestPacket(subpacket.data);
|
RecruitmentDetailsRequestPacket currentRecruitDetailsPacket = new RecruitmentDetailsRequestPacket(subpacket.data);
|
||||||
RecruitmentDetails details = new RecruitmentDetails();
|
RecruitmentDetails details = new RecruitmentDetails();
|
||||||
details.recruiterName = "Localhost Character";
|
details.recruiterName = "Localhost Character";
|
||||||
details.purposeId = 2;
|
details.purposeId = 2;
|
||||||
details.locationId = 1;
|
details.locationId = 1;
|
||||||
details.subTaskId = 1;
|
details.subTaskId = 1;
|
||||||
details.comment = "This is a test details packet sent by the server. No implementation has been Created yet...";
|
details.comment = "This is a test details packet sent by the server. No implementation has been Created yet...";
|
||||||
details.num[0] = 1;
|
details.num[0] = 1;
|
||||||
client.QueuePacket(BasePacket.CreatePacket(CurrentRecruitmentDetailsPacket.BuildPacket(player.actorID, details), true, false));
|
client.QueuePacket(BasePacket.CreatePacket(CurrentRecruitmentDetailsPacket.BuildPacket(session.id, details), true, false));
|
||||||
break;
|
break;
|
||||||
//Accepted Recruiting
|
//Accepted Recruiting
|
||||||
case 0x01C6:
|
case 0x01C6:
|
||||||
subpacket.DebugPrintSubPacket();
|
subpacket.DebugPrintSubPacket();
|
||||||
break;
|
break;
|
||||||
/* SOCIAL STUFF */
|
/* SOCIAL STUFF */
|
||||||
case 0x01C9:
|
case 0x01C9:
|
||||||
AddRemoveSocialPacket addBlackList = new AddRemoveSocialPacket(subpacket.data);
|
AddRemoveSocialPacket addBlackList = new AddRemoveSocialPacket(subpacket.data);
|
||||||
client.QueuePacket(BasePacket.CreatePacket(BlacklistAddedPacket.BuildPacket(player.actorID, true, addBlackList.name), true, false));
|
client.QueuePacket(BasePacket.CreatePacket(BlacklistAddedPacket.BuildPacket(session.id, true, addBlackList.name), true, false));
|
||||||
break;
|
break;
|
||||||
case 0x01CA:
|
case 0x01CA:
|
||||||
AddRemoveSocialPacket RemoveBlackList = new AddRemoveSocialPacket(subpacket.data);
|
AddRemoveSocialPacket RemoveBlackList = new AddRemoveSocialPacket(subpacket.data);
|
||||||
client.QueuePacket(BasePacket.CreatePacket(BlacklistRemovedPacket.BuildPacket(player.actorID, true, RemoveBlackList.name), true, false));
|
client.QueuePacket(BasePacket.CreatePacket(BlacklistRemovedPacket.BuildPacket(session.id, true, RemoveBlackList.name), true, false));
|
||||||
break;
|
break;
|
||||||
case 0x01CB:
|
case 0x01CB:
|
||||||
int offset1 = 0;
|
int offset1 = 0;
|
||||||
client.QueuePacket(BasePacket.CreatePacket(SendBlacklistPacket.BuildPacket(player.actorID, new String[] { "Test" }, ref offset1), true, false));
|
client.QueuePacket(BasePacket.CreatePacket(SendBlacklistPacket.BuildPacket(session.id, new String[] { "Test" }, ref offset1), true, false));
|
||||||
break;
|
break;
|
||||||
case 0x01CC:
|
case 0x01CC:
|
||||||
AddRemoveSocialPacket addFriendList = new AddRemoveSocialPacket(subpacket.data);
|
AddRemoveSocialPacket addFriendList = new AddRemoveSocialPacket(subpacket.data);
|
||||||
client.QueuePacket(BasePacket.CreatePacket(FriendlistAddedPacket.BuildPacket(player.actorID, true, (uint)addFriendList.name.GetHashCode(), true, addFriendList.name), true, false));
|
client.QueuePacket(BasePacket.CreatePacket(FriendlistAddedPacket.BuildPacket(session.id, true, (uint)addFriendList.name.GetHashCode(), true, addFriendList.name), true, false));
|
||||||
break;
|
break;
|
||||||
case 0x01CD:
|
case 0x01CD:
|
||||||
AddRemoveSocialPacket RemoveFriendList = new AddRemoveSocialPacket(subpacket.data);
|
AddRemoveSocialPacket RemoveFriendList = new AddRemoveSocialPacket(subpacket.data);
|
||||||
client.QueuePacket(BasePacket.CreatePacket(FriendlistRemovedPacket.BuildPacket(player.actorID, true, RemoveFriendList.name), true, false));
|
client.QueuePacket(BasePacket.CreatePacket(FriendlistRemovedPacket.BuildPacket(session.id, true, RemoveFriendList.name), true, false));
|
||||||
break;
|
break;
|
||||||
case 0x01CE:
|
case 0x01CE:
|
||||||
int offset2 = 0;
|
int offset2 = 0;
|
||||||
client.QueuePacket(BasePacket.CreatePacket(SendFriendlistPacket.BuildPacket(player.actorID, new Tuple<long, string>[] { new Tuple<long, string>(01, "Test2") }, ref offset2), true, false));
|
client.QueuePacket(BasePacket.CreatePacket(SendFriendlistPacket.BuildPacket(session.id, new Tuple<long, string>[] { new Tuple<long, string>(01, "Test2") }, ref offset2), true, false));
|
||||||
break;
|
break;
|
||||||
case 0x01CF:
|
case 0x01CF:
|
||||||
client.QueuePacket(BasePacket.CreatePacket(FriendStatusPacket.BuildPacket(player.actorID, null), true, false));
|
client.QueuePacket(BasePacket.CreatePacket(FriendStatusPacket.BuildPacket(session.id, null), true, false));
|
||||||
break;
|
break;
|
||||||
/* SUPPORT DESK STUFF */
|
/* SUPPORT DESK STUFF */
|
||||||
//Request for FAQ/Info List
|
//Request for FAQ/Info List
|
||||||
case 0x01D0:
|
case 0x01D0:
|
||||||
FaqListRequestPacket faqRequest = new FaqListRequestPacket(subpacket.data);
|
FaqListRequestPacket faqRequest = new FaqListRequestPacket(subpacket.data);
|
||||||
client.QueuePacket(BasePacket.CreatePacket(FaqListResponsePacket.BuildPacket(player.actorID, new string[] { "Testing FAQ1", "Coded style!" }), true, false));
|
client.QueuePacket(BasePacket.CreatePacket(FaqListResponsePacket.BuildPacket(session.id, new string[] { "Testing FAQ1", "Coded style!" }), true, false));
|
||||||
break;
|
break;
|
||||||
//Request for body of a faq/info selection
|
//Request for body of a faq/info selection
|
||||||
case 0x01D1:
|
case 0x01D1:
|
||||||
FaqBodyRequestPacket faqBodyRequest = new FaqBodyRequestPacket(subpacket.data);
|
FaqBodyRequestPacket faqBodyRequest = new FaqBodyRequestPacket(subpacket.data);
|
||||||
client.QueuePacket(BasePacket.CreatePacket(FaqBodyResponsePacket.BuildPacket(player.actorID, "HERE IS A GIANT BODY. Nothing else to say!"), true, false));
|
client.QueuePacket(BasePacket.CreatePacket(FaqBodyResponsePacket.BuildPacket(session.id, "HERE IS A GIANT BODY. Nothing else to say!"), true, false));
|
||||||
break;
|
break;
|
||||||
//Request issue list
|
//Request issue list
|
||||||
case 0x01D2:
|
case 0x01D2:
|
||||||
GMTicketIssuesRequestPacket issuesRequest = new GMTicketIssuesRequestPacket(subpacket.data);
|
GMTicketIssuesRequestPacket issuesRequest = new GMTicketIssuesRequestPacket(subpacket.data);
|
||||||
client.QueuePacket(BasePacket.CreatePacket(IssueListResponsePacket.BuildPacket(player.actorID, new string[] { "Test1", "Test2", "Test3", "Test4", "Test5" }), true, false));
|
client.QueuePacket(BasePacket.CreatePacket(IssueListResponsePacket.BuildPacket(session.id, new string[] { "Test1", "Test2", "Test3", "Test4", "Test5" }), true, false));
|
||||||
break;
|
break;
|
||||||
//Request if GM ticket exists
|
//Request if GM ticket exists
|
||||||
case 0x01D3:
|
case 0x01D3:
|
||||||
client.QueuePacket(BasePacket.CreatePacket(StartGMTicketPacket.BuildPacket(player.actorID, false), true, false));
|
client.QueuePacket(BasePacket.CreatePacket(StartGMTicketPacket.BuildPacket(session.id, false), true, false));
|
||||||
break;
|
break;
|
||||||
//Request for GM response message
|
//Request for GM response message
|
||||||
case 0x01D4:
|
case 0x01D4:
|
||||||
client.QueuePacket(BasePacket.CreatePacket(GMTicketPacket.BuildPacket(player.actorID, "This is a GM Ticket Title", "This is a GM Ticket Body."), true, false));
|
client.QueuePacket(BasePacket.CreatePacket(GMTicketPacket.BuildPacket(session.id, "This is a GM Ticket Title", "This is a GM Ticket Body."), true, false));
|
||||||
break;
|
break;
|
||||||
//GM Ticket Sent
|
//GM Ticket Sent
|
||||||
case 0x01D5:
|
case 0x01D5:
|
||||||
GMSupportTicketPacket gmTicket = new GMSupportTicketPacket(subpacket.data);
|
GMSupportTicketPacket gmTicket = new GMSupportTicketPacket(subpacket.data);
|
||||||
Program.Log.Info("Got GM Ticket: \n" + gmTicket.ticketTitle + "\n" + gmTicket.ticketBody);
|
Program.Log.Info("Got GM Ticket: \n" + gmTicket.ticketTitle + "\n" + gmTicket.ticketBody);
|
||||||
client.QueuePacket(BasePacket.CreatePacket(GMTicketSentResponsePacket.BuildPacket(player.actorID, true), true, false));
|
client.QueuePacket(BasePacket.CreatePacket(GMTicketSentResponsePacket.BuildPacket(session.id, true), true, false));
|
||||||
break;
|
break;
|
||||||
//Request to end ticket
|
//Request to end ticket
|
||||||
case 0x01D6:
|
case 0x01D6:
|
||||||
client.QueuePacket(BasePacket.CreatePacket(EndGMTicketPacket.BuildPacket(player.actorID), true, false));
|
client.QueuePacket(BasePacket.CreatePacket(EndGMTicketPacket.BuildPacket(session.id), true, false));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Program.Log.Debug("Unknown command 0x{0:X} received.", subpacket.gameMessage.opcode);
|
Program.Log.Debug("Unknown command 0x{0:X} received.", subpacket.gameMessage.opcode);
|
||||||
subpacket.DebugPrintSubPacket();
|
subpacket.DebugPrintSubPacket();
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
packet.DebugPrintPacket();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,14 +63,14 @@ namespace FFXIVClassic_Map_Server
|
||||||
if (startServer)
|
if (startServer)
|
||||||
{
|
{
|
||||||
Server server = new Server();
|
Server server = new Server();
|
||||||
CommandProcessor cp = new CommandProcessor(server.GetConnectedPlayerList());
|
|
||||||
server.StartServer();
|
server.StartServer();
|
||||||
|
|
||||||
while (startServer)
|
while (startServer)
|
||||||
{
|
{
|
||||||
String input = Console.ReadLine();
|
String input = Console.ReadLine();
|
||||||
Log.Info("[Console Input] " + input);
|
Log.Info("[Console Input] " + input);
|
||||||
cp.DoCommand(input, null);
|
Server.GetCommandProcessor().DoCommand(input, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,9 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Threading;
|
|
||||||
using FFXIVClassic_Map_Server.dataobjects;
|
using FFXIVClassic_Map_Server.dataobjects;
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
using FFXIVClassic.Common;
|
using FFXIVClassic.Common;
|
||||||
using NLog;
|
|
||||||
using FFXIVClassic_Map_Server.Actors;
|
using FFXIVClassic_Map_Server.Actors;
|
||||||
using FFXIVClassic_Map_Server.lua;
|
using FFXIVClassic_Map_Server.lua;
|
||||||
|
|
||||||
|
@ -17,7 +15,6 @@ namespace FFXIVClassic_Map_Server
|
||||||
public const int FFXIV_MAP_PORT = 54992;
|
public const int FFXIV_MAP_PORT = 54992;
|
||||||
public const int BUFFER_SIZE = 0xFFFF; //Max basepacket size is 0xFFFF
|
public const int BUFFER_SIZE = 0xFFFF; //Max basepacket size is 0xFFFF
|
||||||
public const int BACKLOG = 100;
|
public const int BACKLOG = 100;
|
||||||
public const int HEALTH_THREAD_SLEEP_TIME = 5;
|
|
||||||
|
|
||||||
public const string STATIC_ACTORS_PATH = "./staticactors.bin";
|
public const string STATIC_ACTORS_PATH = "./staticactors.bin";
|
||||||
|
|
||||||
|
@ -25,60 +22,28 @@ namespace FFXIVClassic_Map_Server
|
||||||
|
|
||||||
private Socket mServerSocket;
|
private Socket mServerSocket;
|
||||||
|
|
||||||
private Dictionary<uint, ConnectedPlayer> mConnectedPlayerList = new Dictionary<uint, ConnectedPlayer>();
|
private Dictionary<uint, Session> mSessionList = new Dictionary<uint, Session>();
|
||||||
private List<ClientConnection> mConnectionList = new List<ClientConnection>();
|
|
||||||
private LuaEngine mLuaEngine = new LuaEngine();
|
private LuaEngine mLuaEngine = new LuaEngine();
|
||||||
|
|
||||||
|
private static CommandProcessor mCommandProcessor = new CommandProcessor();
|
||||||
|
private static ZoneConnection mWorldConnection = new ZoneConnection();
|
||||||
private static WorldManager mWorldManager;
|
private static WorldManager mWorldManager;
|
||||||
private static Dictionary<uint, Item> gamedataItems;
|
private static Dictionary<uint, Item> mGamedataItems;
|
||||||
private static StaticActors mStaticActors;
|
private static StaticActors mStaticActors;
|
||||||
|
|
||||||
private PacketProcessor mProcessor;
|
private PacketProcessor mProcessor;
|
||||||
|
|
||||||
private Thread mConnectionHealthThread;
|
|
||||||
private bool killHealthThread = false;
|
|
||||||
|
|
||||||
private void ConnectionHealth()
|
|
||||||
{
|
|
||||||
Program.Log.Info("Connection Health thread started; it will run every {0} seconds.", HEALTH_THREAD_SLEEP_TIME);
|
|
||||||
while (!killHealthThread)
|
|
||||||
{
|
|
||||||
lock (mConnectedPlayerList)
|
|
||||||
{
|
|
||||||
List<ConnectedPlayer> dcedPlayers = new List<ConnectedPlayer>();
|
|
||||||
foreach (ConnectedPlayer cp in mConnectedPlayerList.Values)
|
|
||||||
{
|
|
||||||
if (cp.CheckIfDCing())
|
|
||||||
dcedPlayers.Add(cp);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (ConnectedPlayer cp in dcedPlayers)
|
|
||||||
cp.GetActor().CleanupAndSave();
|
|
||||||
}
|
|
||||||
Thread.Sleep(HEALTH_THREAD_SLEEP_TIME * 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Server()
|
public Server()
|
||||||
{
|
{
|
||||||
mSelf = this;
|
mSelf = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Server GetServer()
|
|
||||||
{
|
|
||||||
return mSelf;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool StartServer()
|
public bool StartServer()
|
||||||
{
|
{
|
||||||
mConnectionHealthThread = new Thread(new ThreadStart(ConnectionHealth));
|
|
||||||
mConnectionHealthThread.Name = "MapThread:Health";
|
|
||||||
//mConnectionHealthThread.Start();
|
|
||||||
|
|
||||||
mStaticActors = new StaticActors(STATIC_ACTORS_PATH);
|
mStaticActors = new StaticActors(STATIC_ACTORS_PATH);
|
||||||
|
|
||||||
gamedataItems = Database.GetItemGamedata();
|
mGamedataItems = Database.GetItemGamedata();
|
||||||
Program.Log.Info("Loaded {0} items.", gamedataItems.Count);
|
Program.Log.Info("Loaded {0} items.", mGamedataItems.Count);
|
||||||
|
|
||||||
mWorldManager = new WorldManager(this);
|
mWorldManager = new WorldManager(this);
|
||||||
mWorldManager.LoadZoneList();
|
mWorldManager.LoadZoneList();
|
||||||
|
@ -88,11 +53,11 @@ namespace FFXIVClassic_Map_Server
|
||||||
mWorldManager.LoadSpawnLocations();
|
mWorldManager.LoadSpawnLocations();
|
||||||
mWorldManager.SpawnAllActors();
|
mWorldManager.SpawnAllActors();
|
||||||
|
|
||||||
IPEndPoint serverEndPoint = new System.Net.IPEndPoint(IPAddress.Parse(ConfigConstants.OPTIONS_BINDIP), int.Parse(ConfigConstants.OPTIONS_PORT));
|
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(ConfigConstants.OPTIONS_BINDIP), int.Parse(ConfigConstants.OPTIONS_PORT));
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mServerSocket = new System.Net.Sockets.Socket(serverEndPoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
mServerSocket = new Socket(serverEndPoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -120,40 +85,73 @@ namespace FFXIVClassic_Map_Server
|
||||||
Program.Log.Info("Map Server has started @ {0}:{1}", (mServerSocket.LocalEndPoint as IPEndPoint).Address, (mServerSocket.LocalEndPoint as IPEndPoint).Port);
|
Program.Log.Info("Map Server has started @ {0}:{1}", (mServerSocket.LocalEndPoint as IPEndPoint).Address, (mServerSocket.LocalEndPoint as IPEndPoint).Port);
|
||||||
Console.ForegroundColor = ConsoleColor.Gray;
|
Console.ForegroundColor = ConsoleColor.Gray;
|
||||||
|
|
||||||
mProcessor = new PacketProcessor(this, mConnectedPlayerList, mConnectionList);
|
mProcessor = new PacketProcessor(this);
|
||||||
|
|
||||||
//mGameThread = new Thread(new ThreadStart(mProcessor.update));
|
//mGameThread = new Thread(new ThreadStart(mProcessor.update));
|
||||||
//mGameThread.Start();
|
//mGameThread.Start();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemovePlayer(Player player)
|
#region Session Handling
|
||||||
|
|
||||||
|
public Session AddSession(uint id)
|
||||||
{
|
{
|
||||||
lock (mConnectedPlayerList)
|
if (mSessionList.ContainsKey(id))
|
||||||
|
return mSessionList[id];
|
||||||
|
|
||||||
|
Session session = new Session(id);
|
||||||
|
mSessionList.Add(id, session);
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveSession(uint id)
|
||||||
|
{
|
||||||
|
if (mSessionList.ContainsKey(id))
|
||||||
{
|
{
|
||||||
if (mConnectedPlayerList.ContainsKey(player.actorId))
|
mSessionList.Remove(id);
|
||||||
mConnectedPlayerList.Remove(player.actorId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Session GetSession(uint id)
|
||||||
|
{
|
||||||
|
if (mSessionList.ContainsKey(id))
|
||||||
|
return mSessionList[id];
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Session GetSession(string name)
|
||||||
|
{
|
||||||
|
foreach (Session s in mSessionList.Values)
|
||||||
|
{
|
||||||
|
if (s.GetActor().customDisplayName.ToLower().Equals(name.ToLower()))
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<uint, Session> GetSessionList()
|
||||||
|
{
|
||||||
|
return mSessionList;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Socket Handling
|
#region Socket Handling
|
||||||
private void AcceptCallback(IAsyncResult result)
|
private void AcceptCallback(IAsyncResult result)
|
||||||
{
|
{
|
||||||
ClientConnection conn = null;
|
ZoneConnection conn = null;
|
||||||
Socket socket = (System.Net.Sockets.Socket)result.AsyncState;
|
Socket socket = (System.Net.Sockets.Socket)result.AsyncState;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
conn = new ClientConnection();
|
conn = new ZoneConnection();
|
||||||
conn.socket = socket.EndAccept(result);
|
conn.socket = socket.EndAccept(result);
|
||||||
conn.buffer = new byte[BUFFER_SIZE];
|
conn.buffer = new byte[BUFFER_SIZE];
|
||||||
|
|
||||||
lock (mConnectionList)
|
mWorldConnection = conn;
|
||||||
{
|
|
||||||
mConnectionList.Add(conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
Program.Log.Info("Connection {0}:{1} has connected.", (conn.socket.RemoteEndPoint as IPEndPoint).Address, (conn.socket.RemoteEndPoint as IPEndPoint).Port);
|
Program.Log.Info("Connection {0}:{1} has connected.", (conn.socket.RemoteEndPoint as IPEndPoint).Address, (conn.socket.RemoteEndPoint as IPEndPoint).Port);
|
||||||
//Queue recieving of data from the connection
|
//Queue recieving of data from the connection
|
||||||
conn.socket.BeginReceive(conn.buffer, 0, conn.buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), conn);
|
conn.socket.BeginReceive(conn.buffer, 0, conn.buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), conn);
|
||||||
|
@ -164,11 +162,7 @@ namespace FFXIVClassic_Map_Server
|
||||||
{
|
{
|
||||||
if (conn != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
|
mWorldConnection = null;
|
||||||
lock (mConnectionList)
|
|
||||||
{
|
|
||||||
mConnectionList.Remove(conn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mServerSocket.BeginAccept(new AsyncCallback(AcceptCallback), mServerSocket);
|
mServerSocket.BeginAccept(new AsyncCallback(AcceptCallback), mServerSocket);
|
||||||
}
|
}
|
||||||
|
@ -176,53 +170,25 @@ namespace FFXIVClassic_Map_Server
|
||||||
{
|
{
|
||||||
if (conn != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
lock (mConnectionList)
|
mWorldConnection = null;
|
||||||
{
|
|
||||||
mConnectionList.Remove(conn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mServerSocket.BeginAccept(new AsyncCallback(AcceptCallback), mServerSocket);
|
mServerSocket.BeginAccept(new AsyncCallback(AcceptCallback), mServerSocket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Actor GetStaticActors(uint id)
|
|
||||||
{
|
|
||||||
return mStaticActors.GetActor(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Actor GetStaticActors(string name)
|
|
||||||
{
|
|
||||||
return mStaticActors.FindStaticActor(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Item GetItemGamedata(uint id)
|
|
||||||
{
|
|
||||||
if (gamedataItems.ContainsKey(id))
|
|
||||||
return gamedataItems[id];
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Receive Callback. Reads in incoming data, converting them to base packets. Base packets are sent to be parsed. If not enough data at the end to build a basepacket, move to the beginning and prepend.
|
/// Receive Callback. Reads in incoming data, converting them to base packets. Base packets are sent to be parsed. If not enough data at the end to build a basepacket, move to the beginning and prepend.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="result"></param>
|
/// <param name="result"></param>
|
||||||
private void ReceiveCallback(IAsyncResult result)
|
private void ReceiveCallback(IAsyncResult result)
|
||||||
{
|
{
|
||||||
ClientConnection conn = (ClientConnection)result.AsyncState;
|
ZoneConnection conn = (ZoneConnection)result.AsyncState;
|
||||||
|
|
||||||
//Check if disconnected
|
//Check if disconnected
|
||||||
if ((conn.socket.Poll(1, SelectMode.SelectRead) && conn.socket.Available == 0))
|
if ((conn.socket.Poll(1, SelectMode.SelectRead) && conn.socket.Available == 0))
|
||||||
{
|
{
|
||||||
if (mConnectedPlayerList.ContainsKey(conn.owner))
|
mWorldConnection = null;
|
||||||
mConnectedPlayerList.Remove(conn.owner);
|
Program.Log.Info("Disconnected from world server!");
|
||||||
lock (mConnectionList)
|
|
||||||
{
|
|
||||||
mConnectionList.Remove(conn);
|
|
||||||
}
|
|
||||||
if (conn.connType == BasePacket.TYPE_ZONE)
|
|
||||||
Program.Log.Info("{0} has disconnected.", conn.owner == 0 ? conn.GetAddress() : "User " + conn.owner);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -238,13 +204,13 @@ namespace FFXIVClassic_Map_Server
|
||||||
//Build packets until can no longer or out of data
|
//Build packets until can no longer or out of data
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
BasePacket basePacket = BuildPacket(ref offset, conn.buffer, bytesRead);
|
SubPacket subPacket = SubPacket.CreatePacket(ref offset, conn.buffer, bytesRead);
|
||||||
|
|
||||||
//If can't build packet, break, else process another
|
//If can't build packet, break, else process another
|
||||||
if (basePacket == null)
|
if (subPacket == null)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
mProcessor.ProcessPacket(conn, basePacket);
|
mProcessor.ProcessPacket(conn, subPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Not all bytes consumed, transfer leftover to beginning
|
//Not all bytes consumed, transfer leftover to beginning
|
||||||
|
@ -265,79 +231,63 @@ namespace FFXIVClassic_Map_Server
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Program.Log.Info("{0} has disconnected.", conn.owner == 0 ? conn.GetAddress() : "User " + conn.owner);
|
mWorldConnection = null;
|
||||||
|
Program.Log.Info("Disconnected from world server!");
|
||||||
lock (mConnectionList)
|
|
||||||
{
|
|
||||||
mConnectionList.Remove(conn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SocketException)
|
catch (SocketException)
|
||||||
{
|
{
|
||||||
if (conn.socket != null)
|
if (conn.socket != null)
|
||||||
{
|
{
|
||||||
Program.Log.Info("{0} has disconnected.", conn.owner == 0 ? conn.GetAddress() : "User " + conn.owner);
|
mWorldConnection = null;
|
||||||
|
Program.Log.Info("Disconnected from world server!");
|
||||||
lock (mConnectionList)
|
|
||||||
{
|
|
||||||
mConnectionList.Remove(conn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Builds a packet from the incoming buffer + offset. If a packet can be built, it is returned else null.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="offset">Current offset in buffer.</param>
|
|
||||||
/// <param name="buffer">Incoming buffer.</param>
|
|
||||||
/// <returns>Returns either a BasePacket or null if not enough data.</returns>
|
|
||||||
public BasePacket BuildPacket(ref int offset, byte[] buffer, int bytesRead)
|
|
||||||
{
|
|
||||||
BasePacket newPacket = null;
|
|
||||||
|
|
||||||
//Too small to even get length
|
|
||||||
if (bytesRead <= offset)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
ushort packetSize = BitConverter.ToUInt16(buffer, offset);
|
|
||||||
|
|
||||||
//Too small to whole packet
|
|
||||||
if (bytesRead < offset + packetSize)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (buffer.Length < offset + packetSize)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
newPacket = new BasePacket(buffer, ref offset);
|
|
||||||
}
|
|
||||||
catch (OverflowException)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return newPacket;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
public static ZoneConnection GetWorldConnection()
|
||||||
|
{
|
||||||
|
return mWorldConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Server GetServer()
|
||||||
|
{
|
||||||
|
return mSelf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CommandProcessor GetCommandProcessor()
|
||||||
|
{
|
||||||
|
return mCommandProcessor;
|
||||||
|
}
|
||||||
|
|
||||||
public static WorldManager GetWorldManager()
|
public static WorldManager GetWorldManager()
|
||||||
{
|
{
|
||||||
return mWorldManager;
|
return mWorldManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dictionary<uint, ConnectedPlayer> GetConnectedPlayerList()
|
|
||||||
{
|
|
||||||
return mConnectedPlayerList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<uint, Item> GetGamedataItems()
|
public static Dictionary<uint, Item> GetGamedataItems()
|
||||||
{
|
{
|
||||||
return gamedataItems;
|
return mGamedataItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Actor GetStaticActors(uint id)
|
||||||
|
{
|
||||||
|
return mStaticActors.GetActor(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Actor GetStaticActors(string name)
|
||||||
|
{
|
||||||
|
return mStaticActors.FindStaticActor(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Item GetItemGamedata(uint id)
|
||||||
|
{
|
||||||
|
if (mGamedataItems.ContainsKey(id))
|
||||||
|
return mGamedataItems[id];
|
||||||
|
else
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,11 +61,14 @@ namespace FFXIVClassic_Map_Server
|
||||||
canRideChocobo,
|
canRideChocobo,
|
||||||
canStealth,
|
canStealth,
|
||||||
isInstanceRaid
|
isInstanceRaid
|
||||||
FROM server_zones
|
FROM server_zones
|
||||||
WHERE zoneName IS NOT NULL";
|
WHERE zoneName IS NOT NULL and serverIp = @ip and serverPort = @port";
|
||||||
|
|
||||||
MySqlCommand cmd = new MySqlCommand(query, conn);
|
MySqlCommand cmd = new MySqlCommand(query, conn);
|
||||||
|
|
||||||
|
cmd.Parameters.AddWithValue("@ip", ConfigConstants.OPTIONS_BINDIP);
|
||||||
|
cmd.Parameters.AddWithValue("@port", ConfigConstants.OPTIONS_PORT);
|
||||||
|
|
||||||
using (MySqlDataReader reader = cmd.ExecuteReader())
|
using (MySqlDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
|
@ -333,14 +336,21 @@ namespace FFXIVClassic_Map_Server
|
||||||
using (MySqlDataReader reader = cmd.ExecuteReader())
|
using (MySqlDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
|
uint zoneId = reader.GetUInt32("zoneId");
|
||||||
|
uint classId = reader.GetUInt32("actorClassId");
|
||||||
|
if (!actorClasses.ContainsKey(classId))
|
||||||
|
continue;
|
||||||
|
if (!zoneList.ContainsKey(zoneId))
|
||||||
|
continue;
|
||||||
|
Zone zone = zoneList[zoneId];
|
||||||
|
if (zone == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
string customName = null;
|
string customName = null;
|
||||||
if (!reader.IsDBNull(11))
|
if (!reader.IsDBNull(11))
|
||||||
customName = reader.GetString("customDisplayName");
|
customName = reader.GetString("customDisplayName");
|
||||||
|
string uniqueId = reader.GetString("uniqueId");
|
||||||
uint classId = reader.GetUInt32("actorClassId");
|
|
||||||
string uniqueId = reader.GetString("uniqueId");
|
|
||||||
uint zoneId = reader.GetUInt32("zoneId");
|
|
||||||
string privAreaName = reader.GetString("privateAreaName");
|
string privAreaName = reader.GetString("privateAreaName");
|
||||||
uint privAreaLevel = reader.GetUInt32("privateAreaLevel");
|
uint privAreaLevel = reader.GetUInt32("privateAreaLevel");
|
||||||
float x = reader.GetFloat("positionX");
|
float x = reader.GetFloat("positionX");
|
||||||
|
@ -349,16 +359,7 @@ namespace FFXIVClassic_Map_Server
|
||||||
float rot = reader.GetFloat("rotation");
|
float rot = reader.GetFloat("rotation");
|
||||||
ushort state = reader.GetUInt16("actorState");
|
ushort state = reader.GetUInt16("actorState");
|
||||||
uint animId = reader.GetUInt32("animationId");
|
uint animId = reader.GetUInt32("animationId");
|
||||||
|
|
||||||
if (!actorClasses.ContainsKey(classId))
|
|
||||||
continue;
|
|
||||||
if (!zoneList.ContainsKey(zoneId))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Zone zone = zoneList[zoneId];
|
|
||||||
if (zone == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
SpawnLocation spawn = new SpawnLocation(classId, uniqueId, zoneId, privAreaName, privAreaLevel, x, y, z, rot, state, animId);
|
SpawnLocation spawn = new SpawnLocation(classId, uniqueId, zoneId, privAreaName, privAreaLevel, x, y, z, rot, state, animId);
|
||||||
|
|
||||||
zone.AddSpawnLocation(spawn);
|
zone.AddSpawnLocation(spawn);
|
||||||
|
@ -523,14 +524,7 @@ namespace FFXIVClassic_Map_Server
|
||||||
|
|
||||||
//Moves actor to new zone, and sends packets to spawn at the given coords.
|
//Moves actor to new zone, and sends packets to spawn at the given coords.
|
||||||
public void DoZoneChange(Player player, uint destinationZoneId, string destinationPrivateArea, byte spawnType, float spawnX, float spawnY, float spawnZ, float spawnRotation)
|
public void DoZoneChange(Player player, uint destinationZoneId, string destinationPrivateArea, byte spawnType, float spawnX, float spawnY, float spawnZ, float spawnRotation)
|
||||||
{
|
{
|
||||||
Area oldZone = player.zone;
|
|
||||||
//Remove player from currentZone if transfer else it's login
|
|
||||||
if (player.zone != null)
|
|
||||||
{
|
|
||||||
oldZone.RemoveActorFromZone(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Add player to new zone and update
|
//Add player to new zone and update
|
||||||
Area newArea;
|
Area newArea;
|
||||||
|
|
||||||
|
@ -542,17 +536,18 @@ namespace FFXIVClassic_Map_Server
|
||||||
//This server does not contain that zoneId
|
//This server does not contain that zoneId
|
||||||
if (newArea == null)
|
if (newArea == null)
|
||||||
{
|
{
|
||||||
if (oldZone != null)
|
Program.Log.Debug("Request to change to zone not on this server by: {0}.", player.customDisplayName);
|
||||||
{
|
RequestWorldServerZoneChange(player, destinationZoneId, spawnType, spawnX, spawnY, spawnZ, spawnRotation);
|
||||||
oldZone.AddActorToZone(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
var message = "WorldManager.DoZoneChange: unable to change areas, new area is not valid.";
|
|
||||||
player.SendMessage(SendMessagePacket.MESSAGE_TYPE_SYSTEM, "[Debug]", message);
|
|
||||||
Program.Log.Debug(message);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Area oldZone = player.zone;
|
||||||
|
//Remove player from currentZone if transfer else it's login
|
||||||
|
if (player.zone != null)
|
||||||
|
{
|
||||||
|
oldZone.RemoveActorFromZone(player);
|
||||||
|
}
|
||||||
|
|
||||||
newArea.AddActorToZone(player);
|
newArea.AddActorToZone(player);
|
||||||
|
|
||||||
//Update player actor's properties
|
//Update player actor's properties
|
||||||
|
@ -613,8 +608,8 @@ namespace FFXIVClassic_Map_Server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Login Zone In
|
//Session started, zone into world
|
||||||
public void DoLogin(Player player)
|
public void DoZoneIn(Player player, bool isLogin, ushort spawnType)
|
||||||
{
|
{
|
||||||
//Add player to new zone and update
|
//Add player to new zone and update
|
||||||
Zone zone = GetZone(player.zoneId);
|
Zone zone = GetZone(player.zoneId);
|
||||||
|
@ -625,15 +620,25 @@ namespace FFXIVClassic_Map_Server
|
||||||
|
|
||||||
//Set the current zone and add player
|
//Set the current zone and add player
|
||||||
player.zone = zone;
|
player.zone = zone;
|
||||||
|
|
||||||
LuaEngine.OnBeginLogin(player);
|
|
||||||
|
|
||||||
zone.AddActorToZone(player);
|
zone.AddActorToZone(player);
|
||||||
|
|
||||||
//Send packets
|
//Send packets
|
||||||
player.SendZoneInPackets(this, 0x1);
|
if (!isLogin)
|
||||||
|
{
|
||||||
|
player.playerSession.QueuePacket(DeleteAllActorsPacket.BuildPacket(player.actorId), true, false);
|
||||||
|
player.playerSession.QueuePacket(_0xE2Packet.BuildPacket(player.actorId, 0x2), true, false);
|
||||||
|
player.SendZoneInPackets(this, spawnType);
|
||||||
|
}
|
||||||
|
|
||||||
|
player.SendZoneInPackets(this, spawnType);
|
||||||
|
|
||||||
|
player.destinationZone = 0;
|
||||||
|
player.destinationSpawnType = 0;
|
||||||
|
Database.SavePlayerPosition(player);
|
||||||
|
|
||||||
|
player.playerSession.LockUpdates(false);
|
||||||
|
|
||||||
LuaEngine.OnLogin(player);
|
|
||||||
LuaEngine.OnZoneIn(player);
|
LuaEngine.OnZoneIn(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,6 +653,12 @@ namespace FFXIVClassic_Map_Server
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void RequestWorldServerZoneChange(Player player, uint destinationZoneId, byte spawnType, float spawnX, float spawnY, float spawnZ, float spawnRotation)
|
||||||
|
{
|
||||||
|
ZoneConnection zc = Server.GetWorldConnection();
|
||||||
|
zc.RequestZoneChange(player.playerSession.id, destinationZoneId, spawnType, spawnX, spawnY, spawnZ, spawnRotation);
|
||||||
|
}
|
||||||
|
|
||||||
public Player GetPCInWorld(string name)
|
public Player GetPCInWorld(string name)
|
||||||
{
|
{
|
||||||
foreach (Zone zone in zoneList.Values)
|
foreach (Zone zone in zoneList.Values)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
using FFXIVClassic_Map_Server.actors;
|
using FFXIVClassic_Map_Server.actors;
|
||||||
using FFXIVClassic_Map_Server.lua;
|
using FFXIVClassic_Map_Server.lua;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||||
|
@ -71,7 +71,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
return SetActorSpeedPacket.BuildPacket(actorId, playerActorId);
|
return SetActorSpeedPacket.BuildPacket(actorId, playerActorId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubPacket CreateSpawnPositonPacket(uint playerActorId, uint spawnType)
|
public SubPacket CreateSpawnPositonPacket(uint playerActorId, ushort spawnType)
|
||||||
{
|
{
|
||||||
SubPacket spawnPacket;
|
SubPacket spawnPacket;
|
||||||
if (!spawnedFirstTime && playerActorId == actorId)
|
if (!spawnedFirstTime && playerActorId == actorId)
|
||||||
|
@ -92,7 +92,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
return spawnPacket;
|
return spawnPacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubPacket CreateSpawnTeleportPacket(uint playerActorId, uint spawnType)
|
public SubPacket CreateSpawnTeleportPacket(uint playerActorId, ushort spawnType)
|
||||||
{
|
{
|
||||||
SubPacket spawnPacket;
|
SubPacket spawnPacket;
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
return GetSpawnPackets(playerActorId, 0x1);
|
return GetSpawnPackets(playerActorId, 0x1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual BasePacket GetSpawnPackets(uint playerActorId, uint spawnType)
|
public virtual BasePacket GetSpawnPackets(uint playerActorId, ushort spawnType)
|
||||||
{
|
{
|
||||||
List<SubPacket> subpackets = new List<SubPacket>();
|
List<SubPacket> subpackets = new List<SubPacket>();
|
||||||
subpackets.Add(CreateAddActorPacket(playerActorId, 8));
|
subpackets.Add(CreateAddActorPacket(playerActorId, 8));
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using FFXIVClassic_Map_Server;
|
using FFXIVClassic_Map_Server;
|
||||||
using FFXIVClassic.Common;
|
using FFXIVClassic.Common;
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
using FFXIVClassic_Map_Server.actors.area;
|
using FFXIVClassic_Map_Server.actors.area;
|
||||||
using FFXIVClassic_Map_Server.actors.chara.npc;
|
using FFXIVClassic_Map_Server.actors.chara.npc;
|
||||||
using FFXIVClassic_Map_Server.dataobjects;
|
using FFXIVClassic_Map_Server.dataobjects;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
|
using FFXIVClassic.Common;
|
||||||
using FFXIVClassic_Map_Server.Actors;
|
using FFXIVClassic_Map_Server.Actors;
|
||||||
using FFXIVClassic_Map_Server.lua;
|
using FFXIVClassic_Map_Server.lua;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using FFXIVClassic_Map_Server;
|
using FFXIVClassic_Map_Server;
|
||||||
using FFXIVClassic.Common;
|
using FFXIVClassic.Common;
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
using FFXIVClassic_Map_Server.actors.chara.npc;
|
using FFXIVClassic_Map_Server.actors.chara.npc;
|
||||||
using FFXIVClassic_Map_Server.Actors;
|
using FFXIVClassic_Map_Server.Actors;
|
||||||
using FFXIVClassic_Map_Server.lua;
|
using FFXIVClassic_Map_Server.lua;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
|
using FFXIVClassic.Common;
|
||||||
using FFXIVClassic_Map_Server.Actors.Chara;
|
using FFXIVClassic_Map_Server.Actors.Chara;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||||
|
|
||||||
|
@ -35,6 +36,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
public const int L_INDEXFINGER = 26;
|
public const int L_INDEXFINGER = 26;
|
||||||
public const int UNKNOWN = 27;
|
public const int UNKNOWN = 27;
|
||||||
|
|
||||||
|
public bool isStatic = false;
|
||||||
|
|
||||||
public uint modelId;
|
public uint modelId;
|
||||||
public uint[] appearanceIds = new uint[28];
|
public uint[] appearanceIds = new uint[28];
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ using FFXIVClassic_Map_Server.actors.chara.npc;
|
||||||
using FFXIVClassic_Map_Server.Actors.Chara;
|
using FFXIVClassic_Map_Server.Actors.Chara;
|
||||||
using FFXIVClassic_Map_Server.dataobjects;
|
using FFXIVClassic_Map_Server.dataobjects;
|
||||||
using FFXIVClassic_Map_Server.lua;
|
using FFXIVClassic_Map_Server.lua;
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
using FFXIVClassic_Map_Server.packets.receive.events;
|
using FFXIVClassic_Map_Server.packets.receive.events;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||||
using FFXIVClassic_Map_Server.utils;
|
using FFXIVClassic_Map_Server.utils;
|
||||||
|
@ -86,13 +86,17 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
List<LuaParam> lParams;
|
List<LuaParam> lParams;
|
||||||
|
|
||||||
Player player = Server.GetWorldManager().GetPCInWorld(playerActorId);
|
Player player = Server.GetWorldManager().GetPCInWorld(playerActorId);
|
||||||
lParams = DoActorInit(player);
|
lParams = DoActorInit(player);
|
||||||
|
|
||||||
|
if (lParams != null && lParams.Count >= 3 && lParams[2].typeID == 0 && (int)lParams[2].value == 0)
|
||||||
|
isStatic = true;
|
||||||
|
|
||||||
if (lParams == null)
|
if (lParams == null)
|
||||||
{
|
{
|
||||||
string classPathFake = "/Chara/Npc/Populace/PopulaceStandard";
|
string classPathFake = "/Chara/Npc/Populace/PopulaceStandard";
|
||||||
string classNameFake = "PopulaceStandard";
|
string classNameFake = "PopulaceStandard";
|
||||||
lParams = LuaUtils.CreateLuaParamList(classPathFake, false, false, false, false, false, 0xF47F6, false, false, 0, 0);
|
lParams = LuaUtils.CreateLuaParamList(classPathFake, false, false, false, false, false, 0xF47F6, false, false, 0, 0);
|
||||||
|
isStatic = true;
|
||||||
//ActorInstantiatePacket.BuildPacket(actorId, playerActorId, actorName, classNameFake, lParams).DebugPrintSubPacket();
|
//ActorInstantiatePacket.BuildPacket(actorId, playerActorId, actorName, classNameFake, lParams).DebugPrintSubPacket();
|
||||||
return ActorInstantiatePacket.BuildPacket(actorId, playerActorId, actorName, classNameFake, lParams);
|
return ActorInstantiatePacket.BuildPacket(actorId, playerActorId, actorName, classNameFake, lParams);
|
||||||
}
|
}
|
||||||
|
@ -111,7 +115,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
return ActorInstantiatePacket.BuildPacket(actorId, playerActorId, actorName, className, lParams);
|
return ActorInstantiatePacket.BuildPacket(actorId, playerActorId, actorName, className, lParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override BasePacket GetSpawnPackets(uint playerActorId, uint spawnType)
|
public override BasePacket GetSpawnPackets(uint playerActorId, ushort spawnType)
|
||||||
{
|
{
|
||||||
List<SubPacket> subpackets = new List<SubPacket>();
|
List<SubPacket> subpackets = new List<SubPacket>();
|
||||||
subpackets.Add(CreateAddActorPacket(playerActorId));
|
subpackets.Add(CreateAddActorPacket(playerActorId));
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using FFXIVClassic_Map_Server.Actors;
|
using FFXIVClassic_Map_Server.Actors;
|
||||||
using FFXIVClassic_Map_Server.dataobjects;
|
using FFXIVClassic_Map_Server.dataobjects;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor.inventory;
|
using FFXIVClassic_Map_Server.packets.send.actor.inventory;
|
||||||
using FFXIVClassic_Map_Server.packets.send.Actor.inventory;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.actors.chara.player
|
namespace FFXIVClassic_Map_Server.actors.chara.player
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
|
using FFXIVClassic.Common;
|
||||||
using FFXIVClassic_Map_Server.Actors;
|
using FFXIVClassic_Map_Server.Actors;
|
||||||
using FFXIVClassic_Map_Server.dataobjects;
|
using FFXIVClassic_Map_Server.dataobjects;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor.inventory;
|
using FFXIVClassic_Map_Server.packets.send.actor.inventory;
|
||||||
using FFXIVClassic_Map_Server.packets.send.Actor.inventory;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
using FFXIVClassic.Common;
|
using FFXIVClassic.Common;
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
using FFXIVClassic_Map_Server.actors.chara.player;
|
using FFXIVClassic_Map_Server.actors.chara.player;
|
||||||
using FFXIVClassic_Map_Server.actors.director;
|
using FFXIVClassic_Map_Server.actors.director;
|
||||||
using FFXIVClassic_Map_Server.dataobjects;
|
using FFXIVClassic_Map_Server.dataobjects;
|
||||||
|
@ -7,8 +7,6 @@ using FFXIVClassic_Map_Server.dataobjects.chara;
|
||||||
using FFXIVClassic_Map_Server.lua;
|
using FFXIVClassic_Map_Server.lua;
|
||||||
using FFXIVClassic_Map_Server.packets.send;
|
using FFXIVClassic_Map_Server.packets.send;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor.events;
|
|
||||||
using FFXIVClassic_Map_Server.packets.send.Actor.inventory;
|
|
||||||
using FFXIVClassic_Map_Server.packets.send.events;
|
using FFXIVClassic_Map_Server.packets.send.events;
|
||||||
using FFXIVClassic_Map_Server.packets.send.list;
|
using FFXIVClassic_Map_Server.packets.send.list;
|
||||||
using FFXIVClassic_Map_Server.packets.send.player;
|
using FFXIVClassic_Map_Server.packets.send.player;
|
||||||
|
@ -17,7 +15,8 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using MoonSharp.Interpreter;
|
using MoonSharp.Interpreter;
|
||||||
using FFXIVClassic_Map_Server.packets.receive.events;
|
using FFXIVClassic_Map_Server.packets.receive.events;
|
||||||
|
using FFXIVClassic_Map_Server.packets.send.actor.inventory;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.Actors
|
namespace FFXIVClassic_Map_Server.Actors
|
||||||
{
|
{
|
||||||
class Player : Character
|
class Player : Character
|
||||||
|
@ -84,7 +83,9 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
|
|
||||||
public Coroutine currentEventRunning;
|
public Coroutine currentEventRunning;
|
||||||
|
|
||||||
//Player Info
|
//Player Info
|
||||||
|
public uint destinationZone;
|
||||||
|
public ushort destinationSpawnType;
|
||||||
public uint[] timers = new uint[20];
|
public uint[] timers = new uint[20];
|
||||||
public ushort currentJob;
|
public ushort currentJob;
|
||||||
public uint currentTitle;
|
public uint currentTitle;
|
||||||
|
@ -124,9 +125,9 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
|
|
||||||
public PlayerWork playerWork = new PlayerWork();
|
public PlayerWork playerWork = new PlayerWork();
|
||||||
|
|
||||||
public ConnectedPlayer playerSession;
|
public Session playerSession;
|
||||||
|
|
||||||
public Player(ConnectedPlayer cp, uint actorID) : base(actorID)
|
public Player(Session cp, uint actorID) : base(actorID)
|
||||||
{
|
{
|
||||||
playerSession = cp;
|
playerSession = cp;
|
||||||
actorName = String.Format("_pc{0:00000000}", actorID);
|
actorName = String.Format("_pc{0:00000000}", actorID);
|
||||||
|
@ -258,9 +259,9 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
else
|
else
|
||||||
lParams = LuaUtils.CreateLuaParamList("/Chara/Player/Player_work", false, false, false, false, false, true);
|
lParams = LuaUtils.CreateLuaParamList("/Chara/Player/Player_work", false, false, false, false, false, true);
|
||||||
return ActorInstantiatePacket.BuildPacket(actorId, playerActorId, actorName, className, lParams);
|
return ActorInstantiatePacket.BuildPacket(actorId, playerActorId, actorName, className, lParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override BasePacket GetSpawnPackets(uint playerActorId, uint spawnType)
|
public override BasePacket GetSpawnPackets(uint playerActorId, ushort spawnType)
|
||||||
{
|
{
|
||||||
List<SubPacket> subpackets = new List<SubPacket>();
|
List<SubPacket> subpackets = new List<SubPacket>();
|
||||||
subpackets.Add(CreateAddActorPacket(playerActorId, 8));
|
subpackets.Add(CreateAddActorPacket(playerActorId, 8));
|
||||||
|
@ -481,7 +482,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
QueuePacket(SetMapPacket.BuildPacket(actorId, zone.regionId, zone.actorId));
|
QueuePacket(SetMapPacket.BuildPacket(actorId, zone.regionId, zone.actorId));
|
||||||
|
|
||||||
QueuePacket(GetSpawnPackets(actorId, spawnType));
|
QueuePacket(GetSpawnPackets(actorId, spawnType));
|
||||||
GetSpawnPackets(actorId, spawnType).DebugPrintPacket();
|
//GetSpawnPackets(actorId, spawnType).DebugPrintPacket();
|
||||||
|
|
||||||
#region grouptest
|
#region grouptest
|
||||||
//Retainers
|
//Retainers
|
||||||
|
@ -653,16 +654,39 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CleanupAndSave()
|
public void CleanupAndSave()
|
||||||
{
|
{
|
||||||
|
playerSession.LockUpdates(true);
|
||||||
|
|
||||||
//Remove actor from zone and main server list
|
//Remove actor from zone and main server list
|
||||||
zone.RemoveActorFromZone(this);
|
zone.RemoveActorFromZone(this);
|
||||||
Server.GetServer().RemovePlayer(this);
|
|
||||||
|
//Set Destination to 0
|
||||||
|
this.destinationZone = 0;
|
||||||
|
this.destinationSpawnType = 0;
|
||||||
|
|
||||||
//Save Player
|
//Save Player
|
||||||
Database.SavePlayerPlayTime(this);
|
Database.SavePlayerPlayTime(this);
|
||||||
Database.SavePlayerPosition(this);
|
Database.SavePlayerPosition(this);
|
||||||
|
}
|
||||||
Program.Log.Info("{0} has been logged out and saved.", this.customDisplayName);
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
//Set destination
|
||||||
|
this.destinationZone = destinationZone;
|
||||||
|
this.destinationSpawnType = spawnType;
|
||||||
|
this.positionX = destinationX;
|
||||||
|
this.positionY = destinationY;
|
||||||
|
this.positionZ = destinationZ;
|
||||||
|
this.rotation = destinationRot;
|
||||||
|
|
||||||
|
//Save Player
|
||||||
|
Database.SavePlayerPlayTime(this);
|
||||||
|
Database.SavePlayerPosition(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Area GetZone()
|
public Area GetZone()
|
||||||
|
@ -730,8 +754,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendGameMessage(Actor sourceActor, Actor textIdOwner, ushort textId, byte log, params object[] msgParams)
|
public void SendGameMessage(Actor sourceActor, Actor textIdOwner, ushort textId, byte log, params object[] msgParams)
|
||||||
{
|
{
|
||||||
if (msgParams.Length == 0)
|
if (msgParams == null || msgParams.Length == 0)
|
||||||
{
|
{
|
||||||
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, sourceActor.actorId, textIdOwner.actorId, textId, log));
|
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, sourceActor.actorId, textIdOwner.actorId, textId, log));
|
||||||
}
|
}
|
||||||
|
@ -740,24 +764,24 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendGameMessage(Actor textIdOwner, ushort textId, byte log, params object[] msgParams)
|
public void SendGameMessage(Actor textIdOwner, ushort textId, byte log, params object[] msgParams)
|
||||||
{
|
{
|
||||||
if (msgParams.Length == 0)
|
if (msgParams == null || msgParams.Length == 0)
|
||||||
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, log));
|
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, log));
|
||||||
else
|
else
|
||||||
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, log, LuaUtils.CreateLuaParamList(msgParams)));
|
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, log, LuaUtils.CreateLuaParamList(msgParams)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendGameMessage(Actor textIdOwner, ushort textId, byte log, string customSender, params object[] msgParams)
|
public void SendGameMessage(Actor textIdOwner, ushort textId, byte log, string customSender, params object[] msgParams)
|
||||||
{
|
{
|
||||||
if (msgParams.Length == 0)
|
if (msgParams == null || msgParams.Length == 0)
|
||||||
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, customSender, log));
|
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, customSender, log));
|
||||||
else
|
else
|
||||||
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, customSender, log, LuaUtils.CreateLuaParamList(msgParams)));
|
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, customSender, log, LuaUtils.CreateLuaParamList(msgParams)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendGameMessage(Actor textIdOwner, ushort textId, byte log, uint displayId, params object[] msgParams)
|
public void SendGameMessage(Actor textIdOwner, ushort textId, byte log, uint displayId, params object[] msgParams)
|
||||||
{
|
{
|
||||||
if (msgParams.Length == 0)
|
if (msgParams == null || msgParams.Length == 0)
|
||||||
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, displayId, log));
|
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, displayId, log));
|
||||||
else
|
else
|
||||||
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, displayId, log, LuaUtils.CreateLuaParamList(msgParams)));
|
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, displayId, log, LuaUtils.CreateLuaParamList(msgParams)));
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using FFXIVClassic_Map_Server.packets;
|
using FFXIVClassic.Common;
|
||||||
using FFXIVClassic_Map_Server.lua;
|
using FFXIVClassic_Map_Server.lua;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
|
using FFXIVClassic.Common;
|
||||||
using FFXIVClassic_Map_Server.Actors;
|
using FFXIVClassic_Map_Server.Actors;
|
||||||
using FFXIVClassic_Map_Server.lua;
|
using FFXIVClassic_Map_Server.lua;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
|
using FFXIVClassic.Common;
|
||||||
using FFXIVClassic_Map_Server.Actors;
|
using FFXIVClassic_Map_Server.Actors;
|
||||||
using FFXIVClassic_Map_Server.lua;
|
using FFXIVClassic_Map_Server.lua;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
|
using FFXIVClassic.Common;
|
||||||
using FFXIVClassic_Map_Server.actors.director;
|
using FFXIVClassic_Map_Server.actors.director;
|
||||||
using FFXIVClassic_Map_Server.lua;
|
using FFXIVClassic_Map_Server.lua;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
|
using FFXIVClassic.Common;
|
||||||
using FFXIVClassic_Map_Server.Actors;
|
using FFXIVClassic_Map_Server.Actors;
|
||||||
using FFXIVClassic_Map_Server.lua;
|
using FFXIVClassic_Map_Server.lua;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
|
using FFXIVClassic.Common;
|
||||||
using FFXIVClassic_Map_Server.Actors;
|
using FFXIVClassic_Map_Server.Actors;
|
||||||
using FFXIVClassic_Map_Server.lua;
|
using FFXIVClassic_Map_Server.lua;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
|
using FFXIVClassic.Common;
|
||||||
using FFXIVClassic_Map_Server.Actors;
|
using FFXIVClassic_Map_Server.Actors;
|
||||||
using FFXIVClassic_Map_Server.lua;
|
using FFXIVClassic_Map_Server.lua;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
|
using FFXIVClassic.Common;
|
||||||
using FFXIVClassic_Map_Server.lua;
|
using FFXIVClassic_Map_Server.lua;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using FFXIVClassic_Map_Server;
|
using FFXIVClassic_Map_Server;
|
||||||
using FFXIVClassic.Common;
|
using FFXIVClassic.Common;
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
using FFXIVClassic_Map_Server.Actors;
|
using FFXIVClassic_Map_Server.Actors;
|
||||||
using FFXIVClassic_Map_Server.lua;
|
using FFXIVClassic_Map_Server.lua;
|
||||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||||
|
@ -12,66 +12,33 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.dataobjects
|
namespace FFXIVClassic_Map_Server.dataobjects
|
||||||
{
|
{
|
||||||
class ConnectedPlayer
|
class Session
|
||||||
{
|
{
|
||||||
public uint actorID = 0;
|
public uint id = 0;
|
||||||
Player playerActor;
|
Player playerActor;
|
||||||
public List<Actor> actorInstanceList = new List<Actor>();
|
public List<Actor> actorInstanceList = new List<Actor>();
|
||||||
|
public uint languageCode = 1;
|
||||||
public uint languageCode = 1;
|
|
||||||
|
|
||||||
private ClientConnection zoneConnection;
|
|
||||||
private ClientConnection chatConnection;
|
|
||||||
|
|
||||||
private uint lastPingPacket = Utils.UnixTimeStampUTC();
|
private uint lastPingPacket = Utils.UnixTimeStampUTC();
|
||||||
|
|
||||||
|
public bool isUpdatesLocked = true;
|
||||||
|
|
||||||
public string errorMessage = "";
|
public string errorMessage = "";
|
||||||
|
|
||||||
public ConnectedPlayer(uint actorId)
|
public Session(uint sessionId)
|
||||||
{
|
{
|
||||||
this.actorID = actorId;
|
this.id = sessionId;
|
||||||
playerActor = new Player(this, actorId);
|
playerActor = new Player(this, sessionId);
|
||||||
actorInstanceList.Add(playerActor);
|
actorInstanceList.Add(playerActor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetConnection(int type, ClientConnection conn)
|
|
||||||
{
|
|
||||||
conn.connType = type;
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case BasePacket.TYPE_ZONE:
|
|
||||||
zoneConnection = conn;
|
|
||||||
break;
|
|
||||||
case BasePacket.TYPE_CHAT:
|
|
||||||
chatConnection = conn;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsClientConnectionsReady()
|
|
||||||
{
|
|
||||||
return (zoneConnection != null && chatConnection != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Disconnect()
|
|
||||||
{
|
|
||||||
zoneConnection.Disconnect();
|
|
||||||
chatConnection.Disconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsDisconnected()
|
|
||||||
{
|
|
||||||
return (!zoneConnection.IsConnected() && !chatConnection.IsConnected());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void QueuePacket(BasePacket basePacket)
|
public void QueuePacket(BasePacket basePacket)
|
||||||
{
|
{
|
||||||
zoneConnection.QueuePacket(basePacket);
|
Server.GetWorldConnection().QueuePacket(basePacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void QueuePacket(SubPacket subPacket, bool isAuthed, bool isEncrypted)
|
public void QueuePacket(SubPacket subPacket, bool isAuthed, bool isEncrypted)
|
||||||
{
|
{
|
||||||
zoneConnection.QueuePacket(subPacket, isAuthed, isEncrypted);
|
Server.GetWorldConnection().QueuePacket(subPacket, isAuthed, isEncrypted);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player GetActor()
|
public Player GetActor()
|
||||||
|
@ -98,6 +65,9 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
||||||
|
|
||||||
public void UpdatePlayerActorPosition(float x, float y, float z, float rot, ushort moveState)
|
public void UpdatePlayerActorPosition(float x, float y, float z, float rot, ushort moveState)
|
||||||
{
|
{
|
||||||
|
if (isUpdatesLocked)
|
||||||
|
return;
|
||||||
|
|
||||||
playerActor.oldPositionX = playerActor.positionX;
|
playerActor.oldPositionX = playerActor.positionX;
|
||||||
playerActor.oldPositionY = playerActor.positionY;
|
playerActor.oldPositionY = playerActor.positionY;
|
||||||
playerActor.oldPositionZ = playerActor.positionZ;
|
playerActor.oldPositionZ = playerActor.positionZ;
|
||||||
|
@ -115,6 +85,9 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
||||||
|
|
||||||
public void UpdateInstance(List<Actor> list)
|
public void UpdateInstance(List<Actor> list)
|
||||||
{
|
{
|
||||||
|
if (isUpdatesLocked)
|
||||||
|
return;
|
||||||
|
|
||||||
List<BasePacket> basePackets = new List<BasePacket>();
|
List<BasePacket> basePackets = new List<BasePacket>();
|
||||||
List<SubPacket> RemoveActorSubpackets = new List<SubPacket>();
|
List<SubPacket> RemoveActorSubpackets = new List<SubPacket>();
|
||||||
List<SubPacket> posUpdateSubpackets = new List<SubPacket>();
|
List<SubPacket> posUpdateSubpackets = new List<SubPacket>();
|
||||||
|
@ -139,6 +112,10 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
||||||
|
|
||||||
if (actorInstanceList.Contains(actor))
|
if (actorInstanceList.Contains(actor))
|
||||||
{
|
{
|
||||||
|
//Don't send for static characters (npcs)
|
||||||
|
if (actor is Character && ((Character)actor).isStatic)
|
||||||
|
continue;
|
||||||
|
|
||||||
GetActor().QueuePacket(actor.CreatePositionUpdatePacket(playerActor.actorId));
|
GetActor().QueuePacket(actor.CreatePositionUpdatePacket(playerActor.actorId));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -163,5 +140,10 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
||||||
actorInstanceList.Clear();
|
actorInstanceList.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void LockUpdates(bool f)
|
||||||
|
{
|
||||||
|
isUpdatesLocked = f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
74
FFXIVClassic Map Server/dataobjects/ZoneConnection.cs
Normal file
74
FFXIVClassic Map Server/dataobjects/ZoneConnection.cs
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
using System;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
|
||||||
|
using FFXIVClassic.Common;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Net;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using FFXIVClassic_Map_Server.packets.WorldPackets.Send;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.dataobjects
|
||||||
|
{
|
||||||
|
class ZoneConnection
|
||||||
|
{
|
||||||
|
//Connection stuff
|
||||||
|
public Socket socket;
|
||||||
|
public byte[] buffer;
|
||||||
|
private BlockingCollection<SubPacket> SendPacketQueue = new BlockingCollection<SubPacket>(1000);
|
||||||
|
public int lastPartialSize = 0;
|
||||||
|
|
||||||
|
public void QueuePacket(BasePacket packet)
|
||||||
|
{
|
||||||
|
List<SubPacket> subPackets = packet.GetSubpackets();
|
||||||
|
foreach (SubPacket s in subPackets)
|
||||||
|
SendPacketQueue.Add(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void QueuePacket(SubPacket subpacket, bool isAuthed, bool isEncrypted)
|
||||||
|
{
|
||||||
|
SendPacketQueue.Add(subpacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FlushQueuedSendPackets()
|
||||||
|
{
|
||||||
|
if (!socket.Connected)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (SendPacketQueue.Count > 0)
|
||||||
|
{
|
||||||
|
SubPacket packet = SendPacketQueue.Take();
|
||||||
|
|
||||||
|
byte[] packetBytes = packet.GetBytes();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
socket.Send(packetBytes);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{ Program.Log.Error("Weird case, socket was d/ced: {0}", e); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String GetAddress()
|
||||||
|
{
|
||||||
|
return String.Format("{0}:{1}", (socket.RemoteEndPoint as IPEndPoint).Address, (socket.RemoteEndPoint as IPEndPoint).Port);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsConnected()
|
||||||
|
{
|
||||||
|
return (socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Disconnect()
|
||||||
|
{
|
||||||
|
if (socket.Connected)
|
||||||
|
socket.Disconnect(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RequestZoneChange(uint sessionId, uint destinationZoneId, byte spawnType, float spawnX, float spawnY, float spawnZ, float spawnRotation)
|
||||||
|
{
|
||||||
|
WorldRequestZoneChangePacket.BuildPacket(sessionId, destinationZoneId, spawnType, spawnX, spawnY, spawnZ, spawnRotation).DebugPrintSubPacket();
|
||||||
|
QueuePacket(WorldRequestZoneChangePacket.BuildPacket(sessionId, destinationZoneId, spawnType, spawnX, spawnY, spawnZ, spawnRotation), true, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,207 +1,208 @@
|
||||||
using FFXIVClassic_Map_Server.packets;
|
|
||||||
using FFXIVClassic_Map_Server.actors.director;
|
using FFXIVClassic_Map_Server.actors.director;
|
||||||
using FFXIVClassic_Map_Server.Actors;
|
using FFXIVClassic_Map_Server.Actors;
|
||||||
using FFXIVClassic_Map_Server.dataobjects;
|
using FFXIVClassic_Map_Server.dataobjects;
|
||||||
using FFXIVClassic_Map_Server.packets.receive.events;
|
using FFXIVClassic_Map_Server.packets.receive.events;
|
||||||
using FFXIVClassic_Map_Server.packets.send;
|
using FFXIVClassic_Map_Server.packets.send;
|
||||||
using FFXIVClassic_Map_Server.packets.send.events;
|
using FFXIVClassic_Map_Server.packets.send.events;
|
||||||
using MoonSharp.Interpreter;
|
using MoonSharp.Interpreter;
|
||||||
using MoonSharp.Interpreter.Interop;
|
using MoonSharp.Interpreter.Interop;
|
||||||
using MoonSharp.Interpreter.Loaders;
|
using MoonSharp.Interpreter.Loaders;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using FFXIVClassic_Map_Server.lua;
|
using FFXIVClassic_Map_Server.lua;
|
||||||
|
using FFXIVClassic.Common;
|
||||||
namespace FFXIVClassic_Map_Server.lua
|
|
||||||
{
|
namespace FFXIVClassic_Map_Server.lua
|
||||||
class LuaEngine
|
{
|
||||||
{
|
class LuaEngine
|
||||||
const string FILEPATH_PLAYER = "./scripts/player.lua";
|
{
|
||||||
const string FILEPATH_ZONE = "./scripts/zones/{0}/zone.lua";
|
const string FILEPATH_PLAYER = "./scripts/player.lua";
|
||||||
const string FILEPATH_COMMANDS = "./scripts/commands/{0}.lua";
|
const string FILEPATH_ZONE = "./scripts/zones/{0}/zone.lua";
|
||||||
const string FILEPATH_DIRECTORS = "./scripts/directors/{0}.lua";
|
const string FILEPATH_COMMANDS = "./scripts/commands/{0}.lua";
|
||||||
const string FILEPATH_NPCS = "./scripts/zones/{0}/npcs/{1}.lua";
|
const string FILEPATH_DIRECTORS = "./scripts/directors/{0}.lua";
|
||||||
|
const string FILEPATH_NPCS = "./scripts/zones/{0}/npcs/{1}.lua";
|
||||||
public LuaEngine()
|
|
||||||
{
|
public LuaEngine()
|
||||||
UserData.RegistrationPolicy = InteropRegistrationPolicy.Automatic;
|
{
|
||||||
}
|
UserData.RegistrationPolicy = InteropRegistrationPolicy.Automatic;
|
||||||
|
|
||||||
public static List<LuaParam> DoActorInstantiate(Player player, Actor target)
|
|
||||||
{
|
|
||||||
string luaPath;
|
|
||||||
|
|
||||||
if (target is Npc)
|
|
||||||
{
|
|
||||||
luaPath = String.Format(FILEPATH_NPCS, target.zoneId, target.GetName());
|
|
||||||
if (File.Exists(luaPath))
|
|
||||||
{
|
|
||||||
LuaScript script = LoadScript(luaPath);
|
|
||||||
|
|
||||||
if (script == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
DynValue result = script.Call(script.Globals["init"], target);
|
|
||||||
List<LuaParam> lparams = LuaUtils.CreateLuaParamList(result);
|
|
||||||
return lparams;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SendError(player, String.Format("ERROR: Could not find script for actor {0}.", target.GetName()));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Coroutine DoActorOnEventStarted(Player player, Actor target, EventStartPacket eventStart)
|
public static List<LuaParam> DoActorInstantiate(Player player, Actor target)
|
||||||
{
|
{
|
||||||
string luaPath;
|
string luaPath;
|
||||||
|
|
||||||
if (target is Command)
|
if (target is Npc)
|
||||||
{
|
{
|
||||||
luaPath = String.Format(FILEPATH_COMMANDS, target.GetName());
|
luaPath = String.Format(FILEPATH_NPCS, target.zoneId, target.GetName());
|
||||||
}
|
if (File.Exists(luaPath))
|
||||||
else if (target is Director)
|
{
|
||||||
{
|
LuaScript script = LoadScript(luaPath);
|
||||||
luaPath = String.Format(FILEPATH_DIRECTORS, target.GetName());
|
|
||||||
}
|
if (script == null)
|
||||||
else
|
return null;
|
||||||
luaPath = String.Format(FILEPATH_NPCS, target.zoneId, target.GetName());
|
|
||||||
|
DynValue result = script.Call(script.Globals["init"], target);
|
||||||
if (File.Exists(luaPath))
|
List<LuaParam> lparams = LuaUtils.CreateLuaParamList(result);
|
||||||
{
|
return lparams;
|
||||||
LuaScript script = LoadScript(luaPath);
|
}
|
||||||
|
else
|
||||||
if (script == null)
|
{
|
||||||
return null;
|
SendError(player, String.Format("ERROR: Could not find script for actor {0}.", target.GetName()));
|
||||||
|
return null;
|
||||||
if (!script.Globals.Get("onEventStarted").IsNil())
|
}
|
||||||
return script.CreateCoroutine(script.Globals["onEventStarted"]).Coroutine;
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SendError(player, String.Format("ERROR: Could not find script for actor {0}.", target.GetName()));
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
return null;
|
||||||
|
}
|
||||||
public static void DoActorOnSpawn(Player player, Npc target)
|
|
||||||
{
|
public static Coroutine DoActorOnEventStarted(Player player, Actor target, EventStartPacket eventStart)
|
||||||
string luaPath = String.Format(FILEPATH_NPCS, target.zoneId, target.GetName());
|
{
|
||||||
|
|
||||||
if (File.Exists(luaPath))
|
|
||||||
{
|
|
||||||
LuaScript script = LoadScript(luaPath);
|
|
||||||
|
|
||||||
if (script == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//Run Script
|
|
||||||
if (!script.Globals.Get("onSpawn").IsNil())
|
|
||||||
script.Call(script.Globals["onSpawn"], player, target);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SendError(player, String.Format("ERROR: Could not find script for actor {0}.", target.GetName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void DoActorOnEventUpdated(Player player, Actor target, EventUpdatePacket eventUpdate)
|
|
||||||
{
|
|
||||||
if (target is Npc)
|
|
||||||
{
|
|
||||||
((Npc)target).DoEventUpdate(player, eventUpdate);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
string luaPath;
|
string luaPath;
|
||||||
|
|
||||||
if (target is Command)
|
if (target is Command)
|
||||||
luaPath = String.Format(FILEPATH_COMMANDS, target.GetName());
|
{
|
||||||
else if (target is Director)
|
luaPath = String.Format(FILEPATH_COMMANDS, target.GetName());
|
||||||
luaPath = String.Format(FILEPATH_DIRECTORS, target.GetName());
|
|
||||||
else
|
|
||||||
luaPath = String.Format(FILEPATH_NPCS, target.zoneId, target.GetName());
|
|
||||||
|
|
||||||
if (File.Exists(luaPath))
|
|
||||||
{
|
|
||||||
LuaScript script = LoadScript(luaPath);
|
|
||||||
|
|
||||||
if (script == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//Have to Do this to combine LuaParams
|
|
||||||
List<Object> objects = new List<Object>();
|
|
||||||
objects.Add(player);
|
|
||||||
objects.Add(target);
|
|
||||||
objects.Add(eventUpdate.val2);
|
|
||||||
objects.AddRange(LuaUtils.CreateLuaParamObjectList(eventUpdate.luaParams));
|
|
||||||
|
|
||||||
//Run Script
|
|
||||||
if (!script.Globals.Get("onEventUpdate").IsNil())
|
|
||||||
script.Call(script.Globals["onEventUpdate"], objects.ToArray());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SendError(player, String.Format("ERROR: Could not find script for actor {0}.", target.GetName()));
|
|
||||||
}
|
}
|
||||||
}
|
else if (target is Director)
|
||||||
|
{
|
||||||
public static void OnZoneIn(Player player)
|
luaPath = String.Format(FILEPATH_DIRECTORS, target.GetName());
|
||||||
{
|
}
|
||||||
|
else
|
||||||
|
luaPath = String.Format(FILEPATH_NPCS, target.zoneId, target.GetName());
|
||||||
|
|
||||||
|
if (File.Exists(luaPath))
|
||||||
|
{
|
||||||
|
LuaScript script = LoadScript(luaPath);
|
||||||
|
|
||||||
|
if (script == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (!script.Globals.Get("onEventStarted").IsNil())
|
||||||
|
return script.CreateCoroutine(script.Globals["onEventStarted"]).Coroutine;
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendError(player, String.Format("ERROR: Could not find script for actor {0}.", target.GetName()));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DoActorOnSpawn(Player player, Npc target)
|
||||||
|
{
|
||||||
|
string luaPath = String.Format(FILEPATH_NPCS, target.zoneId, target.GetName());
|
||||||
|
|
||||||
|
if (File.Exists(luaPath))
|
||||||
|
{
|
||||||
|
LuaScript script = LoadScript(luaPath);
|
||||||
|
|
||||||
|
if (script == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Run Script
|
||||||
|
if (!script.Globals.Get("onSpawn").IsNil())
|
||||||
|
script.Call(script.Globals["onSpawn"], player, target);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendError(player, String.Format("ERROR: Could not find script for actor {0}.", target.GetName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DoActorOnEventUpdated(Player player, Actor target, EventUpdatePacket eventUpdate)
|
||||||
|
{
|
||||||
|
if (target is Npc)
|
||||||
|
{
|
||||||
|
((Npc)target).DoEventUpdate(player, eventUpdate);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string luaPath;
|
||||||
|
|
||||||
|
if (target is Command)
|
||||||
|
luaPath = String.Format(FILEPATH_COMMANDS, target.GetName());
|
||||||
|
else if (target is Director)
|
||||||
|
luaPath = String.Format(FILEPATH_DIRECTORS, target.GetName());
|
||||||
|
else
|
||||||
|
luaPath = String.Format(FILEPATH_NPCS, target.zoneId, target.GetName());
|
||||||
|
|
||||||
|
if (File.Exists(luaPath))
|
||||||
|
{
|
||||||
|
LuaScript script = LoadScript(luaPath);
|
||||||
|
|
||||||
|
if (script == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Have to Do this to combine LuaParams
|
||||||
|
List<Object> objects = new List<Object>();
|
||||||
|
objects.Add(player);
|
||||||
|
objects.Add(target);
|
||||||
|
objects.Add(eventUpdate.val2);
|
||||||
|
objects.AddRange(LuaUtils.CreateLuaParamObjectList(eventUpdate.luaParams));
|
||||||
|
|
||||||
|
//Run Script
|
||||||
|
if (!script.Globals.Get("onEventUpdate").IsNil())
|
||||||
|
script.Call(script.Globals["onEventUpdate"], objects.ToArray());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendError(player, String.Format("ERROR: Could not find script for actor {0}.", target.GetName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void OnZoneIn(Player player)
|
||||||
|
{
|
||||||
string luaPath = String.Format(FILEPATH_ZONE, player.GetZone().actorId);
|
string luaPath = String.Format(FILEPATH_ZONE, player.GetZone().actorId);
|
||||||
|
|
||||||
if (File.Exists(luaPath))
|
if (File.Exists(luaPath))
|
||||||
{
|
{
|
||||||
LuaScript script = LoadScript(luaPath);
|
LuaScript script = LoadScript(luaPath);
|
||||||
|
|
||||||
if (script == null)
|
if (script == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//Run Script
|
//Run Script
|
||||||
if (!script.Globals.Get("onZoneIn").IsNil())
|
if (!script.Globals.Get("onZoneIn").IsNil())
|
||||||
script.Call(script.Globals["onZoneIn"], player);
|
script.Call(script.Globals["onZoneIn"], player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnBeginLogin(Player player)
|
public static void OnBeginLogin(Player player)
|
||||||
{
|
{
|
||||||
if (File.Exists(FILEPATH_PLAYER))
|
if (File.Exists(FILEPATH_PLAYER))
|
||||||
{
|
{
|
||||||
LuaScript script = LoadScript(FILEPATH_PLAYER);
|
LuaScript script = LoadScript(FILEPATH_PLAYER);
|
||||||
|
|
||||||
if (script == null)
|
if (script == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//Run Script
|
//Run Script
|
||||||
if (!script.Globals.Get("onBeginLogin").IsNil())
|
if (!script.Globals.Get("onBeginLogin").IsNil())
|
||||||
script.Call(script.Globals["onBeginLogin"], player);
|
script.Call(script.Globals["onBeginLogin"], player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnLogin(Player player)
|
public static void OnLogin(Player player)
|
||||||
{
|
{
|
||||||
if (File.Exists(FILEPATH_PLAYER))
|
if (File.Exists(FILEPATH_PLAYER))
|
||||||
{
|
{
|
||||||
LuaScript script = LoadScript(FILEPATH_PLAYER);
|
LuaScript script = LoadScript(FILEPATH_PLAYER);
|
||||||
|
|
||||||
if (script == null)
|
if (script == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//Run Script
|
//Run Script
|
||||||
if (!script.Globals.Get("onLogin").IsNil())
|
if (!script.Globals.Get("onLogin").IsNil())
|
||||||
script.Call(script.Globals["onLogin"], player);
|
script.Call(script.Globals["onLogin"], player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region RunGMCommand
|
#region RunGMCommand
|
||||||
public static void RunGMCommand(Player player, String cmd, string[] param, bool help = false)
|
public static void RunGMCommand(Player player, String cmd, string[] param, bool help = false)
|
||||||
{
|
{
|
||||||
|
@ -336,22 +337,22 @@ namespace FFXIVClassic_Map_Server.lua
|
||||||
LuaScript.Log.Error("LuaEngine.RunGMCommand: Unable to find script {0}", path);
|
LuaScript.Log.Error("LuaEngine.RunGMCommand: Unable to find script {0}", path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public static LuaScript LoadScript(string filename)
|
public static LuaScript LoadScript(string filename)
|
||||||
{
|
{
|
||||||
LuaScript script = LoadGlobals();
|
LuaScript script = LoadGlobals();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
script.DoFile(filename);
|
script.DoFile(filename);
|
||||||
}
|
}
|
||||||
catch (SyntaxErrorException e)
|
catch (SyntaxErrorException e)
|
||||||
{
|
{
|
||||||
Program.Log.Error("LUAERROR: {0}.", e.DecoratedMessage);
|
Program.Log.Error("LUAERROR: {0}.", e.DecoratedMessage);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return script;
|
return script;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LuaScript LoadGlobals(LuaScript script = null)
|
public static LuaScript LoadGlobals(LuaScript script = null)
|
||||||
|
@ -367,57 +368,57 @@ namespace FFXIVClassic_Map_Server.lua
|
||||||
|
|
||||||
script.Options.DebugPrint = s => { Program.Log.Debug(s); };
|
script.Options.DebugPrint = s => { Program.Log.Debug(s); };
|
||||||
return script;
|
return script;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendError(Player player, string message)
|
public static void SendError(Player player, string message)
|
||||||
{
|
{
|
||||||
List<SubPacket> SendError = new List<SubPacket>();
|
List<SubPacket> SendError = new List<SubPacket>();
|
||||||
SendError.Add(EndEventPacket.BuildPacket(player.actorId, player.currentEventOwner, player.currentEventName));
|
SendError.Add(EndEventPacket.BuildPacket(player.actorId, player.currentEventOwner, player.currentEventName));
|
||||||
player.SendMessage(SendMessagePacket.MESSAGE_TYPE_SYSTEM_ERROR, "", message);
|
player.SendMessage(SendMessagePacket.MESSAGE_TYPE_SYSTEM_ERROR, "", message);
|
||||||
player.playerSession.QueuePacket(BasePacket.CreatePacket(SendError, true, false));
|
player.playerSession.QueuePacket(BasePacket.CreatePacket(SendError, true, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal static void DoDirectorOnTalked(Director director, Player player, Npc npc)
|
internal static void DoDirectorOnTalked(Director director, Player player, Npc npc)
|
||||||
{
|
{
|
||||||
string luaPath = String.Format(FILEPATH_DIRECTORS, director.GetName());
|
string luaPath = String.Format(FILEPATH_DIRECTORS, director.GetName());
|
||||||
|
|
||||||
if (File.Exists(luaPath))
|
if (File.Exists(luaPath))
|
||||||
{
|
{
|
||||||
LuaScript script = LoadScript(luaPath);
|
LuaScript script = LoadScript(luaPath);
|
||||||
|
|
||||||
if (script == null)
|
if (script == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//Run Script
|
//Run Script
|
||||||
if (!script.Globals.Get("onTalked").IsNil())
|
if (!script.Globals.Get("onTalked").IsNil())
|
||||||
script.Call(script.Globals["onTalked"], player, npc);
|
script.Call(script.Globals["onTalked"], player, npc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SendError(player, String.Format("ERROR: Could not find script for director {0}.", director.GetName()));
|
SendError(player, String.Format("ERROR: Could not find script for director {0}.", director.GetName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void DoDirectorOnCommand(Director director, Player player, Command command)
|
internal static void DoDirectorOnCommand(Director director, Player player, Command command)
|
||||||
{
|
{
|
||||||
string luaPath = String.Format(FILEPATH_DIRECTORS, director.GetName());
|
string luaPath = String.Format(FILEPATH_DIRECTORS, director.GetName());
|
||||||
|
|
||||||
if (File.Exists(luaPath))
|
if (File.Exists(luaPath))
|
||||||
{
|
{
|
||||||
LuaScript script = LoadScript(luaPath);
|
LuaScript script = LoadScript(luaPath);
|
||||||
|
|
||||||
if (script == null)
|
if (script == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//Run Script
|
//Run Script
|
||||||
if (!script.Globals.Get("onCommand").IsNil())
|
if (!script.Globals.Get("onCommand").IsNil())
|
||||||
script.Call(script.Globals["onCommand"], player, command);
|
script.Call(script.Globals["onCommand"], player, command);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SendError(player, String.Format("ERROR: Could not find script for director {0}.", director.GetName()));
|
SendError(player, String.Format("ERROR: Could not find script for director {0}.", director.GetName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,163 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using FFXIVClassic.Common;
|
|
||||||
using NLog;
|
|
||||||
using NLog.Targets;
|
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets
|
|
||||||
{
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct SubPacketHeader
|
|
||||||
{
|
|
||||||
public ushort subpacketSize;
|
|
||||||
public ushort type;
|
|
||||||
public uint sourceId;
|
|
||||||
public uint targetId;
|
|
||||||
public uint unknown1;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct GameMessageHeader
|
|
||||||
{
|
|
||||||
public ushort unknown4; //Always 0x14
|
|
||||||
public ushort opcode;
|
|
||||||
public uint unknown5;
|
|
||||||
public uint timestamp;
|
|
||||||
public uint unknown6;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SubPacket
|
|
||||||
{
|
|
||||||
public const int SUBPACKET_SIZE = 0x10;
|
|
||||||
public const int GAMEMESSAGE_SIZE = 0x10;
|
|
||||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
|
||||||
public byte[] data;
|
|
||||||
public GameMessageHeader gameMessage;
|
|
||||||
|
|
||||||
public SubPacketHeader header;
|
|
||||||
|
|
||||||
public unsafe SubPacket(byte[] bytes, ref int offset)
|
|
||||||
{
|
|
||||||
if (bytes.Length < offset + SUBPACKET_SIZE)
|
|
||||||
throw new OverflowException("Packet Error: Subpacket was too small");
|
|
||||||
|
|
||||||
fixed (byte* pdata = &bytes[offset])
|
|
||||||
{
|
|
||||||
header = (SubPacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (header.type == 0x3)
|
|
||||||
{
|
|
||||||
fixed (byte* pdata = &bytes[offset + SUBPACKET_SIZE])
|
|
||||||
{
|
|
||||||
gameMessage =
|
|
||||||
(GameMessageHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(GameMessageHeader));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bytes.Length < offset + header.subpacketSize)
|
|
||||||
throw new OverflowException("Packet Error: Subpacket size didn't equal subpacket data");
|
|
||||||
|
|
||||||
if (header.type == 0x3)
|
|
||||||
{
|
|
||||||
data = new byte[header.subpacketSize - SUBPACKET_SIZE - GAMEMESSAGE_SIZE];
|
|
||||||
Array.Copy(bytes, offset + SUBPACKET_SIZE + GAMEMESSAGE_SIZE, data, 0, data.Length);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
data = new byte[header.subpacketSize - SUBPACKET_SIZE];
|
|
||||||
Array.Copy(bytes, offset + SUBPACKET_SIZE, data, 0, data.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += header.subpacketSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SubPacket(ushort opcode, uint sourceId, uint targetId, byte[] data)
|
|
||||||
{
|
|
||||||
header = new SubPacketHeader();
|
|
||||||
gameMessage = new GameMessageHeader();
|
|
||||||
|
|
||||||
gameMessage.opcode = opcode;
|
|
||||||
header.sourceId = sourceId;
|
|
||||||
header.targetId = targetId;
|
|
||||||
|
|
||||||
gameMessage.timestamp = Utils.UnixTimeStampUTC();
|
|
||||||
|
|
||||||
header.type = 0x03;
|
|
||||||
header.unknown1 = 0x00;
|
|
||||||
gameMessage.unknown4 = 0x14;
|
|
||||||
gameMessage.unknown5 = 0x00;
|
|
||||||
gameMessage.unknown6 = 0x00;
|
|
||||||
|
|
||||||
this.data = data;
|
|
||||||
|
|
||||||
header.subpacketSize = (ushort) (SUBPACKET_SIZE + GAMEMESSAGE_SIZE + data.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SubPacket(SubPacket original, uint newTargetId)
|
|
||||||
{
|
|
||||||
header = new SubPacketHeader();
|
|
||||||
gameMessage = original.gameMessage;
|
|
||||||
header.subpacketSize = original.header.subpacketSize;
|
|
||||||
header.type = original.header.type;
|
|
||||||
header.sourceId = original.header.sourceId;
|
|
||||||
header.targetId = newTargetId;
|
|
||||||
data = original.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] GetHeaderBytes()
|
|
||||||
{
|
|
||||||
var size = Marshal.SizeOf(header);
|
|
||||||
var arr = new byte[size];
|
|
||||||
|
|
||||||
var ptr = Marshal.AllocHGlobal(size);
|
|
||||||
Marshal.StructureToPtr(header, ptr, true);
|
|
||||||
Marshal.Copy(ptr, arr, 0, size);
|
|
||||||
Marshal.FreeHGlobal(ptr);
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] GetGameMessageBytes()
|
|
||||||
{
|
|
||||||
var size = Marshal.SizeOf(gameMessage);
|
|
||||||
var arr = new byte[size];
|
|
||||||
|
|
||||||
var ptr = Marshal.AllocHGlobal(size);
|
|
||||||
Marshal.StructureToPtr(gameMessage, ptr, true);
|
|
||||||
Marshal.Copy(ptr, arr, 0, size);
|
|
||||||
Marshal.FreeHGlobal(ptr);
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] GetBytes()
|
|
||||||
{
|
|
||||||
var outBytes = new byte[header.subpacketSize];
|
|
||||||
Array.Copy(GetHeaderBytes(), 0, outBytes, 0, SUBPACKET_SIZE);
|
|
||||||
|
|
||||||
if (header.type == 0x3)
|
|
||||||
Array.Copy(GetGameMessageBytes(), 0, outBytes, SUBPACKET_SIZE, GAMEMESSAGE_SIZE);
|
|
||||||
|
|
||||||
Array.Copy(data, 0, outBytes, SUBPACKET_SIZE + (header.type == 0x3 ? GAMEMESSAGE_SIZE : 0), data.Length);
|
|
||||||
return outBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DebugPrintSubPacket()
|
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
logger.ColorDebug(
|
|
||||||
string.Format("Size:0x{0:X} Opcode:0x{1:X}{2}{3}", header.subpacketSize, gameMessage.opcode,
|
|
||||||
Environment.NewLine,
|
|
||||||
Utils.ByteArrayToHex(GetHeaderBytes())), ConsoleOutputColor.DarkRed);
|
|
||||||
|
|
||||||
if (header.type == 0x03)
|
|
||||||
{
|
|
||||||
logger.ColorDebug(Utils.ByteArrayToHex(GetGameMessageBytes(), SUBPACKET_SIZE),
|
|
||||||
ConsoleOutputColor.DarkRed);
|
|
||||||
|
|
||||||
logger.ColorDebug(Utils.ByteArrayToHex(data, SUBPACKET_SIZE + GAMEMESSAGE_SIZE),
|
|
||||||
ConsoleOutputColor.DarkMagenta);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Receive
|
||||||
|
{
|
||||||
|
class ErrorPacket
|
||||||
|
{
|
||||||
|
public uint errorCode;
|
||||||
|
|
||||||
|
public bool invalidPacket = false;
|
||||||
|
|
||||||
|
public ErrorPacket(byte[] data)
|
||||||
|
{
|
||||||
|
using (MemoryStream mem = new MemoryStream(data))
|
||||||
|
{
|
||||||
|
using (BinaryReader binReader = new BinaryReader(mem))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
errorCode = binReader.ReadUInt32();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
invalidPacket = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Receive
|
||||||
|
{
|
||||||
|
class SessionBeginPacket
|
||||||
|
{
|
||||||
|
public bool invalidPacket = false;
|
||||||
|
|
||||||
|
public SessionBeginPacket(byte[] data)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Receive
|
||||||
|
{
|
||||||
|
class SessionEndPacket
|
||||||
|
{
|
||||||
|
public uint destinationZoneId;
|
||||||
|
public ushort destinationSpawnType;
|
||||||
|
public float destinationX;
|
||||||
|
public float destinationY;
|
||||||
|
public float destinationZ;
|
||||||
|
public float destinationRot;
|
||||||
|
|
||||||
|
public bool invalidPacket = false;
|
||||||
|
|
||||||
|
public SessionEndPacket(byte[] data)
|
||||||
|
{
|
||||||
|
using (MemoryStream mem = new MemoryStream(data))
|
||||||
|
{
|
||||||
|
using (BinaryReader binReader = new BinaryReader(mem))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
destinationZoneId = binReader.ReadUInt32();
|
||||||
|
destinationSpawnType = binReader.ReadUInt16();
|
||||||
|
destinationX = binReader.ReadSingle();
|
||||||
|
destinationY = binReader.ReadSingle();
|
||||||
|
destinationZ = binReader.ReadSingle();
|
||||||
|
destinationRot = binReader.ReadSingle();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
invalidPacket = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
using FFXIVClassic.Common;
|
||||||
|
using FFXIVClassic_Map_Server.dataobjects;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Send
|
||||||
|
{
|
||||||
|
class SessionBeginConfirmPacket
|
||||||
|
{
|
||||||
|
public const ushort OPCODE = 0x1000;
|
||||||
|
public const uint PACKET_SIZE = 0x28;
|
||||||
|
|
||||||
|
public static SubPacket BuildPacket(Session session, ushort errorCode = 0)
|
||||||
|
{
|
||||||
|
byte[] data = new byte[PACKET_SIZE - 0x20];
|
||||||
|
using (MemoryStream mem = new MemoryStream(data))
|
||||||
|
{
|
||||||
|
using (BinaryWriter binWriter = new BinaryWriter(mem))
|
||||||
|
{
|
||||||
|
binWriter.Write((UInt32)session.id);
|
||||||
|
binWriter.Write((UInt16)errorCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new SubPacket(true, OPCODE, 0, session.id, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
using FFXIVClassic.Common;
|
||||||
|
using FFXIVClassic_Map_Server.dataobjects;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Send
|
||||||
|
{
|
||||||
|
class SessionEndConfirmPacket
|
||||||
|
{
|
||||||
|
public const ushort OPCODE = 0x1001;
|
||||||
|
public const uint PACKET_SIZE = 0x30;
|
||||||
|
|
||||||
|
public static SubPacket BuildPacket(Session session, uint destinationZone, ushort errorCode = 0)
|
||||||
|
{
|
||||||
|
byte[] data = new byte[PACKET_SIZE - 0x20];
|
||||||
|
using (MemoryStream mem = new MemoryStream(data))
|
||||||
|
{
|
||||||
|
using (BinaryWriter binWriter = new BinaryWriter(mem))
|
||||||
|
{
|
||||||
|
binWriter.Write((UInt32)session.id);
|
||||||
|
binWriter.Write((UInt16)errorCode);
|
||||||
|
binWriter.Write((UInt32)destinationZone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new SubPacket(true, OPCODE, 0, session.id, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
using FFXIVClassic.Common;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Send
|
||||||
|
{
|
||||||
|
class WorldRequestZoneChangePacket
|
||||||
|
{
|
||||||
|
public const ushort OPCODE = 0x1002;
|
||||||
|
public const uint PACKET_SIZE = 0x048;
|
||||||
|
|
||||||
|
public static SubPacket BuildPacket(uint sessionId, uint destinationZoneId, byte spawnType, float spawnX, float spawnY, float spawnZ, float spawnRotation)
|
||||||
|
{
|
||||||
|
byte[] data = new byte[PACKET_SIZE - 0x20];
|
||||||
|
|
||||||
|
using (MemoryStream mem = new MemoryStream(data))
|
||||||
|
{
|
||||||
|
using (BinaryWriter binWriter = new BinaryWriter(mem))
|
||||||
|
{
|
||||||
|
binWriter.Write((UInt32)sessionId);
|
||||||
|
binWriter.Write((UInt32)destinationZoneId);
|
||||||
|
binWriter.Write((UInt16)spawnType);
|
||||||
|
binWriter.Write((Single)spawnX);
|
||||||
|
binWriter.Write((Single)spawnY);
|
||||||
|
binWriter.Write((Single)spawnZ);
|
||||||
|
binWriter.Write((Single)spawnRotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SubPacket(OPCODE, sessionId, sessionId, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class ActorDoEmotePacket
|
class ActorDoEmotePacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,7 +4,9 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class ActorInstantiatePacket
|
class ActorInstantiatePacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class SetActorQuestGraphicPacket
|
class SetActorQuestGraphicPacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class AddActorPacket
|
class AddActorPacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
using System.IO;
|
using FFXIVClassic.Common;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class BattleAction1Packet
|
class BattleAction1Packet
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class DeleteAllActorsPacket
|
class DeleteAllActorsPacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class MoveActorToPositionPacket
|
class MoveActorToPositionPacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class RemoveActorPacket
|
class RemoveActorPacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class SetActorAppearancePacket
|
class SetActorAppearancePacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class SetActorIconPacket
|
class SetActorIconPacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class SetActorIdleAnimationPacket
|
class SetActorIdleAnimationPacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class SetActorIsZoningPacket
|
class SetActorIsZoningPacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class SetActorNamePacket
|
class SetActorNamePacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class SetActorPositionPacket
|
class SetActorPositionPacket
|
||||||
{
|
{
|
||||||
|
@ -22,7 +24,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
public const float INNPOS_Z = 165.050003f;
|
public const float INNPOS_Z = 165.050003f;
|
||||||
public const float INNPOS_ROT = -1.530000f;
|
public const float INNPOS_ROT = -1.530000f;
|
||||||
|
|
||||||
public static SubPacket BuildPacket(uint sourceActorID, uint targetActorID, uint actorId, float x, float y, float z, float rotation, uint spawnType, bool isZoningPlayer)
|
public static SubPacket BuildPacket(uint sourceActorID, uint targetActorID, uint actorId, float x, float y, float z, float rotation, ushort spawnType, bool isZoningPlayer)
|
||||||
{
|
{
|
||||||
byte[] data = new byte[PACKET_SIZE-0x20];
|
byte[] data = new byte[PACKET_SIZE-0x20];
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,9 @@ using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class SetActorPropetyPacket
|
class SetActorPropetyPacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
using System;
|
using FFXIVClassic.Common;
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class SetActorSpeedPacket
|
class SetActorSpeedPacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
using System;
|
using FFXIVClassic.Common;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class SetActorStatePacket
|
class SetActorStatePacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
using System;
|
using FFXIVClassic.Common;
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class SetActorStatusAllPacket
|
class SetActorStatusAllPacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
using System;
|
using FFXIVClassic.Common;
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class SetActorStatusPacket
|
class SetActorStatusPacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class SetActorTargetAnimatedPacket
|
class SetActorTargetAnimatedPacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using FFXIVClassic.Common;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
using System;
|
using FFXIVClassic.Common;
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class _0x132Packet
|
class _0x132Packet
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||||
{
|
{
|
||||||
class _0xFPacket
|
class _0xFPacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor.battle
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.battle
|
||||||
{
|
{
|
||||||
class BattleAction
|
class BattleAction
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
using System;
|
using FFXIVClassic.Common;
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor.battle
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.battle
|
||||||
{
|
{
|
||||||
class BattleActionX00Packet
|
class BattleActionX00Packet
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
using System;
|
using FFXIVClassic.Common;
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor.battle
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.battle
|
||||||
{
|
{
|
||||||
class BattleActionX01Packet
|
class BattleActionX01Packet
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
using System;
|
using FFXIVClassic.Common;
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor.battle
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.battle
|
||||||
{
|
{
|
||||||
class BattleActionX10Packet
|
class BattleActionX10Packet
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
using System;
|
using FFXIVClassic.Common;
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor.battle
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.battle
|
||||||
{
|
{
|
||||||
class BattleActionX18Packet
|
class BattleActionX18Packet
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
using FFXIVClassic_Map_Server.actors;
|
using FFXIVClassic.Common;
|
||||||
|
using FFXIVClassic_Map_Server.actors;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||||
{
|
{
|
||||||
class SetEmoteEventCondition
|
class SetEmoteEventCondition
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||||
{
|
{
|
||||||
class SetEventStatus
|
class SetEventStatus
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,9 @@ using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||||
{
|
{
|
||||||
class SetNoticeEventCondition
|
class SetNoticeEventCondition
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,9 @@ using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||||
{
|
{
|
||||||
class SetPushEventConditionWithCircle
|
class SetPushEventConditionWithCircle
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,9 @@ using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||||
{
|
{
|
||||||
class SetPushEventConditionWithFan
|
class SetPushEventConditionWithFan
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,9 @@ using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||||
{
|
{
|
||||||
class SetPushEventConditionWithTriggerBox
|
class SetPushEventConditionWithTriggerBox
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,9 @@ using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||||
{
|
{
|
||||||
class SetTalkEventCondition
|
class SetTalkEventCondition
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||||
{
|
{
|
||||||
class EquipmentListX01Packet
|
class EquipmentListX01Packet
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,9 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||||
{
|
{
|
||||||
class EquipmentListX08Packet
|
class EquipmentListX08Packet
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,9 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||||
{
|
{
|
||||||
class EquipmentListX16Packet
|
class EquipmentListX16Packet
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,9 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||||
{
|
{
|
||||||
class EquipmentListX32Packet
|
class EquipmentListX32Packet
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,9 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||||
{
|
{
|
||||||
class EquipmentListX64Packet
|
class EquipmentListX64Packet
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||||
{
|
{
|
||||||
class InventoryBeginChangePacket
|
class InventoryBeginChangePacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||||
{
|
{
|
||||||
class InventoryEndChangePacket
|
class InventoryEndChangePacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||||
{
|
{
|
||||||
class InventoryItemEndPacket
|
class InventoryItemEndPacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||||
{
|
{
|
||||||
class InventoryItemPacket
|
class InventoryItemPacket
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
using FFXIVClassic_Map_Server.dataobjects;
|
using FFXIVClassic_Map_Server.dataobjects;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||||
{
|
{
|
||||||
class InventoryListX01Packet
|
class InventoryListX01Packet
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,9 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||||
{
|
{
|
||||||
class InventoryListX08Packet
|
class InventoryListX08Packet
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
using FFXIVClassic.Common;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||||
{
|
{
|
||||||
class InventoryListX16Packet
|
class InventoryListX16Packet
|
||||||
{
|
{
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue