mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-04-02 19:42:05 -04:00
Merge branch 'proxy_server' into develop
# Conflicts: # FFXIVClassic Common Class Lib/packages.config
This commit is contained in:
commit
3864bf6d85
@ -3,11 +3,11 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using FFXIVClassic.Common;
|
||||
using NLog;
|
||||
using NLog.Targets;
|
||||
using Ionic.Zlib;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets
|
||||
namespace FFXIVClassic.Common
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct BasePacketHeader
|
||||
@ -295,6 +295,41 @@ namespace FFXIVClassic_Map_Server.packets
|
||||
return packet;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a packet from the incoming buffer + offset. If a packet can be built, it is returned else null.
|
||||
/// </summary>
|
||||
/// <param name="offset">Current offset in buffer.</param>
|
||||
/// <param name="buffer">Incoming buffer.</param>
|
||||
/// <returns>Returns either a BasePacket or null if not enough data.</returns>
|
||||
public static BasePacket CreatePacket(ref int offset, byte[] buffer, int bytesRead)
|
||||
{
|
||||
BasePacket newPacket = null;
|
||||
|
||||
//Too small to even get length
|
||||
if (bytesRead <= offset)
|
||||
return null;
|
||||
|
||||
ushort packetSize = BitConverter.ToUInt16(buffer, offset);
|
||||
|
||||
//Too small to whole packet
|
||||
if (bytesRead < offset + packetSize)
|
||||
return null;
|
||||
|
||||
if (buffer.Length < offset + packetSize)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
newPacket = new BasePacket(buffer, ref offset);
|
||||
}
|
||||
catch (OverflowException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return newPacket;
|
||||
}
|
||||
|
||||
public static unsafe void EncryptPacket(Blowfish blowfish, BasePacket packet)
|
||||
{
|
||||
var data = packet.data;
|
||||
@ -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
|
||||
}
|
||||
|
@ -38,6 +38,9 @@
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="DotNetZip">
|
||||
<HintPath>..\packages\DotNetZip.1.10.1\lib\net20\DotNetZip.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
@ -56,12 +59,14 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BasePacket.cs" />
|
||||
<Compile Include="Bitfield.cs" />
|
||||
<Compile Include="Blowfish.cs" />
|
||||
<Compile Include="EfficientHashTables.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Sql.cs" />
|
||||
<Compile Include="STA_INIFile.cs" />
|
||||
<Compile Include="SubPacket.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -4,7 +4,7 @@ using FFXIVClassic.Common;
|
||||
using NLog;
|
||||
using NLog.Targets;
|
||||
|
||||
namespace FFXIVClassic_Lobby_Server.packets
|
||||
namespace FFXIVClassic.Common
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SubPacketHeader
|
||||
@ -72,26 +72,38 @@ namespace FFXIVClassic_Lobby_Server.packets
|
||||
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();
|
||||
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.targetId = targetId;
|
||||
|
||||
gameMessage.timestamp = Utils.UnixTimeStampUTC();
|
||||
if (isGameMessage)
|
||||
header.type = 0x03;
|
||||
else
|
||||
header.type = opcode;
|
||||
|
||||
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);
|
||||
header.subpacketSize = (ushort) (SUBPACKET_SIZE + data.Length);
|
||||
|
||||
if (isGameMessage)
|
||||
header.subpacketSize += GAMEMESSAGE_SIZE;
|
||||
}
|
||||
|
||||
public SubPacket(SubPacket original, uint newTargetId)
|
||||
@ -141,6 +153,41 @@ namespace FFXIVClassic_Lobby_Server.packets
|
||||
return outBytes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a packet from the incoming buffer + offset. If a packet can be built, it is returned else null.
|
||||
/// </summary>
|
||||
/// <param name="offset">Current offset in buffer.</param>
|
||||
/// <param name="buffer">Incoming buffer.</param>
|
||||
/// <returns>Returns either a BasePacket or null if not enough data.</returns>
|
||||
public static SubPacket CreatePacket(ref int offset, byte[] buffer, int bytesRead)
|
||||
{
|
||||
SubPacket newPacket = null;
|
||||
|
||||
//Too small to even get length
|
||||
if (bytesRead <= offset)
|
||||
return null;
|
||||
|
||||
ushort packetSize = BitConverter.ToUInt16(buffer, offset);
|
||||
|
||||
//Too small to whole packet
|
||||
if (bytesRead < offset + packetSize)
|
||||
return null;
|
||||
|
||||
if (buffer.Length < offset + packetSize)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
newPacket = new SubPacket(buffer, ref offset);
|
||||
}
|
||||
catch (OverflowException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return newPacket;
|
||||
}
|
||||
|
||||
public void DebugPrintSubPacket()
|
||||
{
|
||||
#if DEBUG
|
||||
@ -157,7 +204,10 @@ namespace FFXIVClassic_Lobby_Server.packets
|
||||
logger.ColorDebug(Utils.ByteArrayToHex(data, SUBPACKET_SIZE + GAMEMESSAGE_SIZE),
|
||||
ConsoleOutputColor.DarkMagenta);
|
||||
}
|
||||
else
|
||||
logger.ColorDebug(Utils.ByteArrayToHex(data, SUBPACKET_SIZE),
|
||||
ConsoleOutputColor.DarkMagenta);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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="NLog" version="4.3.5" targetFramework="net45" />
|
||||
</packages>
|
@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using FFXIVClassic_Lobby_Server.packets;
|
||||
using FFXIVClassic.Common;
|
||||
using System.Collections.Concurrent;
|
||||
using Cyotek.Collections.Generic;
|
||||
|
@ -91,7 +91,6 @@
|
||||
<Compile Include="Database.cs" />
|
||||
<Compile Include="dataobjects\World.cs" />
|
||||
<Compile Include="PacketProcessor.cs" />
|
||||
<Compile Include="packets\BasePacket.cs" />
|
||||
<Compile Include="packets\receive\CharacterModifyPacket.cs" />
|
||||
<Compile Include="packets\receive\SecurityHandshakePacket.cs" />
|
||||
<Compile Include="packets\receive\SelectCharacterPacket.cs" />
|
||||
@ -101,7 +100,6 @@
|
||||
<Compile Include="packets\send\ErrorPacket.cs" />
|
||||
<Compile Include="packets\HardCoded_Packets.cs" />
|
||||
<Compile Include="packets\send\SelectCharacterConfirmPacket.cs" />
|
||||
<Compile Include="packets\SubPacket.cs" />
|
||||
<Compile Include="packets\send\CharacterListPacket.cs" />
|
||||
<Compile Include="packets\send\ImportListPacket.cs" />
|
||||
<Compile Include="packets\send\AccountListPacket.cs" />
|
||||
|
@ -38,13 +38,13 @@
|
||||
<target xsi:type="ColoredConsole" name="packets"
|
||||
layout="${message}">
|
||||
<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" />
|
||||
<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" />
|
||||
<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" />
|
||||
</target>
|
||||
</targets>
|
||||
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using FFXIVClassic_Lobby_Server.packets;
|
||||
|
||||
using FFXIVClassic.Common;
|
||||
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.Collections.Generic;
|
||||
using System.IO;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using FFXIVClassic.Common;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using FFXIVClassic_Lobby_Server.dataobjects;
|
||||
using FFXIVClassic.Common;
|
||||
using FFXIVClassic_Lobby_Server.dataobjects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using FFXIVClassic.Common;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using FFXIVClassic.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using FFXIVClassic.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using FFXIVClassic.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using FFXIVClassic_Lobby_Server.dataobjects;
|
||||
using FFXIVClassic.Common;
|
||||
using FFXIVClassic_Lobby_Server.dataobjects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
@ -1,40 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
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_Map_Server.dataobjects;
|
||||
using FFXIVClassic_Map_Server.packets;
|
||||
|
||||
using System.IO;
|
||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||
using FFXIVClassic_Map_Server;
|
||||
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.actors.chara.player;
|
||||
using FFXIVClassic_Map_Server.Properties;
|
||||
using FFXIVClassic_Map_Server.Actors;
|
||||
|
||||
namespace FFXIVClassic_Map_Server
|
||||
{
|
||||
class CommandProcessor
|
||||
{
|
||||
private Dictionary<uint, ConnectedPlayer> mConnectedPlayerList;
|
||||
private static Dictionary<uint, Item> gamedataItems = Server.GetGamedataItems();
|
||||
|
||||
// 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
|
||||
const UInt32 ITEM_GIL = 1000001;
|
||||
|
||||
public CommandProcessor(Dictionary<uint, ConnectedPlayer> playerList)
|
||||
{
|
||||
mConnectedPlayerList = playerList;
|
||||
}
|
||||
|
||||
|
||||
public void ChangeProperty(uint id, uint value, string target)
|
||||
{
|
||||
SetActorPropetyPacket ChangeProperty = new SetActorPropetyPacket(target);
|
||||
@ -43,9 +28,11 @@ namespace FFXIVClassic_Map_Server
|
||||
ChangeProperty.AddInt(id, value);
|
||||
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);
|
||||
packet.DebugPrintPacket();
|
||||
@ -60,13 +47,13 @@ namespace FFXIVClassic_Map_Server
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="message"></param>
|
||||
private void SendMessage(ConnectedPlayer client, String message)
|
||||
private void SendMessage(Session session, String message)
|
||||
{
|
||||
if (client != null)
|
||||
client.GetActor().QueuePacket(SendMessagePacket.BuildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", message));
|
||||
if (session != null)
|
||||
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(""))
|
||||
return false;
|
||||
@ -88,7 +75,9 @@ namespace FFXIVClassic_Map_Server
|
||||
if (cmd.Any())
|
||||
{
|
||||
// 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"))
|
||||
{
|
||||
@ -125,11 +114,11 @@ namespace FFXIVClassic_Map_Server
|
||||
if (split[0].Equals("reloaditems"))
|
||||
{
|
||||
Program.Log.Info(String.Format("Got request to reload item gamedata"));
|
||||
SendMessage(client, "Reloading Item Gamedata...");
|
||||
SendMessage(session, "Reloading Item Gamedata...");
|
||||
gamedataItems.Clear();
|
||||
gamedataItems = Database.GetItemGamedata();
|
||||
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;
|
||||
}
|
||||
#endregion
|
||||
|
@ -30,7 +30,7 @@ namespace FFXIVClassic_Map_Server
|
||||
INIFile configIni = new INIFile("./map_config.ini");
|
||||
|
||||
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.DATABASE_WORLDID = UInt32.Parse(configIni.GetValue("Database", "worldid", "0"));
|
||||
|
@ -5,7 +5,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FFXIVClassic.Common;
|
||||
using FFXIVClassic_Map_Server.utils;
|
||||
using FFXIVClassic_Map_Server.packets;
|
||||
|
||||
using FFXIVClassic_Map_Server.packets.send.player;
|
||||
using FFXIVClassic_Map_Server.dataobjects;
|
||||
using FFXIVClassic_Map_Server.Actors;
|
||||
@ -258,6 +258,8 @@ namespace FFXIVClassic_Map_Server
|
||||
positionY = @y,
|
||||
positionZ = @z,
|
||||
rotation = @rot,
|
||||
destinationZoneId = @destZone,
|
||||
destinationSpawnType = @destSpawn,
|
||||
currentZoneId = @zoneId
|
||||
WHERE id = @charaId
|
||||
";
|
||||
@ -269,6 +271,8 @@ namespace FFXIVClassic_Map_Server
|
||||
cmd.Parameters.AddWithValue("@z", player.positionZ);
|
||||
cmd.Parameters.AddWithValue("@rot", player.rotation);
|
||||
cmd.Parameters.AddWithValue("@zoneId", player.zoneId);
|
||||
cmd.Parameters.AddWithValue("@destZone", player.destinationZone);
|
||||
cmd.Parameters.AddWithValue("@destSpawn", player.destinationSpawnType);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
@ -402,7 +406,9 @@ namespace FFXIVClassic_Map_Server
|
||||
tribe,
|
||||
restBonus,
|
||||
achievementPoints,
|
||||
playTime
|
||||
playTime,
|
||||
destinationZoneId,
|
||||
destinationSpawnType
|
||||
FROM characters WHERE id = @charId";
|
||||
|
||||
cmd = new MySqlCommand(query, conn);
|
||||
@ -419,8 +425,7 @@ namespace FFXIVClassic_Map_Server
|
||||
player.oldRotation = player.rotation = reader.GetFloat(4);
|
||||
player.currentMainState = reader.GetUInt16(5);
|
||||
player.zoneId = reader.GetUInt32(6);
|
||||
player.isZoning = true;
|
||||
player.zone = Server.GetWorldManager().GetZone(player.zoneId);
|
||||
player.isZoning = true;
|
||||
player.gcCurrent = reader.GetByte(7);
|
||||
player.gcRankLimsa = reader.GetByte(8);
|
||||
player.gcRankGridania = reader.GetByte(9);
|
||||
@ -434,6 +439,13 @@ namespace FFXIVClassic_Map_Server
|
||||
player.playerWork.restBonusExpRate = reader.GetInt32(17);
|
||||
player.achievementPoints = reader.GetUInt32(18);
|
||||
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\StaticActors.cs" />
|
||||
<Compile Include="actors\world\WorldMaster.cs" />
|
||||
<Compile Include="ClientConnection.cs" />
|
||||
<Compile Include="dataobjects\ZoneConnection.cs" />
|
||||
<Compile Include="CommandProcessor.cs" />
|
||||
<Compile Include="ConfigConstants.cs" />
|
||||
<Compile Include="Database.cs" />
|
||||
@ -112,7 +112,7 @@
|
||||
<Compile Include="actors\chara\player\PlayerWork.cs" />
|
||||
<Compile Include="dataobjects\DBWorld.cs" />
|
||||
<Compile Include="dataobjects\InventoryItem.cs" />
|
||||
<Compile Include="dataobjects\ConnectedPlayer.cs" />
|
||||
<Compile Include="dataobjects\Session.cs" />
|
||||
<Compile Include="dataobjects\Item.cs" />
|
||||
<Compile Include="dataobjects\RecruitmentDetails.cs" />
|
||||
<Compile Include="dataobjects\SeamlessBoundry.cs" />
|
||||
@ -124,7 +124,6 @@
|
||||
<Compile Include="lua\LuaPlayer.cs" />
|
||||
<Compile Include="lua\LuaScript.cs" />
|
||||
<Compile Include="PacketProcessor.cs" />
|
||||
<Compile Include="packets\BasePacket.cs" />
|
||||
<Compile Include="packets\receive\ChatMessagePacket.cs" />
|
||||
<Compile Include="packets\receive\events\EventUpdatePacket.cs" />
|
||||
<Compile Include="packets\receive\events\EventStartPacket.cs" />
|
||||
@ -258,9 +257,13 @@
|
||||
<Compile Include="packets\send\_0x02Packet.cs" />
|
||||
<Compile Include="packets\send\_0x10Packet.cs" />
|
||||
<Compile Include="packets\send\_0xE2Packet.cs" />
|
||||
<Compile Include="packets\SubPacket.cs" />
|
||||
<Compile Include="packets\receive\PingPacket.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="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="lua\LuaUtils.cs" />
|
||||
@ -286,6 +289,7 @@
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
<Compile Include="packets\WorldPackets\Send\WorldRequestZoneChangePacket.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
|
@ -38,13 +38,13 @@
|
||||
<target xsi:type="ColoredConsole" name="packets"
|
||||
layout="${message}">
|
||||
<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" />
|
||||
<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" />
|
||||
<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" />
|
||||
</target>
|
||||
</targets>
|
||||
@ -55,6 +55,7 @@
|
||||
<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.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"
|
||||
<logger name="*" minlevel="Debug" writeTo="f" />
|
||||
|
@ -1,5 +1,5 @@
|
||||
using FFXIVClassic.Common;
|
||||
using FFXIVClassic_Map_Server.packets;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
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.receive.events;
|
||||
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
|
||||
{
|
||||
class PacketProcessor
|
||||
{
|
||||
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;
|
||||
cp = new CommandProcessor(playerList);
|
||||
}
|
||||
|
||||
public void ProcessPacket(ClientConnection client, BasePacket packet)
|
||||
{
|
||||
if (packet.header.isCompressed == 0x01)
|
||||
BasePacket.DecryptPacket(client.blowfish, ref packet);
|
||||
public void ProcessPacket(ZoneConnection client, SubPacket subpacket)
|
||||
{
|
||||
Session session = mServer.GetSession(subpacket.header.targetId);
|
||||
|
||||
if (session == null && subpacket.gameMessage.opcode != 0x1000)
|
||||
return;
|
||||
|
||||
List<SubPacket> subPackets = packet.GetSubpackets();
|
||||
foreach (SubPacket subpacket in subPackets)
|
||||
{
|
||||
if (subpacket.header.type == 0x01)
|
||||
{
|
||||
packet.DebugPrintPacket();
|
||||
byte[] reply1Data = {
|
||||
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,
|
||||
0xE5, 0x6E, 0x01, 0xE0, 0x00, 0x00, 0x00, 0x0
|
||||
};
|
||||
|
||||
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)
|
||||
//Normal Game Opcode
|
||||
switch (subpacket.gameMessage.opcode)
|
||||
{
|
||||
//World Server - Error
|
||||
case 0x100A:
|
||||
ErrorPacket worldError = new ErrorPacket(subpacket.data);
|
||||
switch (worldError.errorCode)
|
||||
{
|
||||
case 0x01:
|
||||
session.GetActor().SendGameMessage(Server.GetWorldManager().GetActor(), 60005, 0x20);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
//World Server - Session Begin
|
||||
case 0x1000:
|
||||
subpacket.DebugPrintSubPacket();
|
||||
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;
|
||||
|
||||
//Write Actor ID into reply2
|
||||
using (MemoryStream mem = new MemoryStream(reply2.data))
|
||||
{
|
||||
using (BinaryWriter binReader = new BinaryWriter(mem))
|
||||
subpacket.DebugPrintSubPacket();
|
||||
session = mServer.AddSession(subpacket.header.targetId);
|
||||
client.QueuePacket(_0x2Packet.BuildPacket(session.id), true, false);
|
||||
|
||||
LuaEngine.OnBeginLogin(session.GetActor());
|
||||
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);
|
||||
binReader.Write(actorID);
|
||||
}
|
||||
}
|
||||
if (Server.GetCommandProcessor().DoCommand(chatMessage.message, session))
|
||||
return; ;
|
||||
}
|
||||
|
||||
session.GetActor().BroadcastPacket(SendMessagePacket.BuildPacket(session.id, session.id, chatMessage.logType, session.GetActor().customDisplayName, chatMessage.message), false);
|
||||
|
||||
ConnectedPlayer player = null;
|
||||
|
||||
if (packet.header.connectionType == BasePacket.TYPE_ZONE)
|
||||
{
|
||||
while (mPlayers != null && !mPlayers.ContainsKey(client.owner))
|
||||
{ }
|
||||
player = mPlayers[client.owner];
|
||||
}
|
||||
|
||||
//Create connected player if not Created
|
||||
if (player == null)
|
||||
{
|
||||
player = new ConnectedPlayer(actorID);
|
||||
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;
|
||||
break;
|
||||
//Langauge Code
|
||||
case 0x0006:
|
||||
LangaugeCodePacket langCode = new LangaugeCodePacket(subpacket.data);
|
||||
session.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
|
||||
case 0x00CA:
|
||||
//Update Position
|
||||
case 0x00CA:
|
||||
//Update Position
|
||||
//subpacket.DebugPrintSubPacket();
|
||||
UpdatePlayerPositionPacket posUpdate = new UpdatePlayerPositionPacket(subpacket.data);
|
||||
player.UpdatePlayerActorPosition(posUpdate.x, posUpdate.y, posUpdate.z, posUpdate.rot, posUpdate.moveState);
|
||||
player.GetActor().SendInstanceUpdate();
|
||||
UpdatePlayerPositionPacket posUpdate = new UpdatePlayerPositionPacket(subpacket.data);
|
||||
session.UpdatePlayerActorPosition(posUpdate.x, posUpdate.y, posUpdate.z, posUpdate.rot, posUpdate.moveState);
|
||||
session.GetActor().SendInstanceUpdate();
|
||||
|
||||
if (session.GetActor().IsInZoneChange())
|
||||
session.GetActor().SetZoneChanging(false);
|
||||
|
||||
break;
|
||||
//Set Target
|
||||
case 0x00CD:
|
||||
//subpacket.DebugPrintSubPacket();
|
||||
|
||||
SetTargetPacket setTarget = new SetTargetPacket(subpacket.data);
|
||||
session.GetActor().currentTarget = setTarget.actorID;
|
||||
session.GetActor().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;
|
||||
//Set Target
|
||||
case 0x00CD:
|
||||
//subpacket.DebugPrintSubPacket();
|
||||
}
|
||||
*/
|
||||
|
||||
SetTargetPacket setTarget = new SetTargetPacket(subpacket.data);
|
||||
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);
|
||||
Actor ownerActor = Server.GetStaticActors(eventStart.scriptOwnerActorID);
|
||||
|
||||
|
||||
player.GetActor().currentEventOwner = eventStart.scriptOwnerActorID;
|
||||
player.GetActor().currentEventName = eventStart.triggerName;
|
||||
session.GetActor().currentEventOwner = eventStart.scriptOwnerActorID;
|
||||
session.GetActor().currentEventName = eventStart.triggerName;
|
||||
|
||||
|
||||
if (ownerActor == null)
|
||||
{
|
||||
//Is it a instance actor?
|
||||
ownerActor = Server.GetWorldManager().GetActorInWorld(session.GetActor().currentEventOwner);
|
||||
if (ownerActor == null)
|
||||
{
|
||||
//Is it a instance actor?
|
||||
ownerActor = Server.GetWorldManager().GetActorInWorld(player.GetActor().currentEventOwner);
|
||||
if (ownerActor == null)
|
||||
//Is it a Director?
|
||||
if (session.GetActor().currentDirector != null && session.GetActor().currentEventOwner == session.GetActor().currentDirector.actorId)
|
||||
ownerActor = session.GetActor().currentDirector;
|
||||
else
|
||||
{
|
||||
//Is it a Director?
|
||||
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)
|
||||
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().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;
|
||||
case 0x012F:
|
||||
//subpacket.DebugPrintSubPacket();
|
||||
ParameterDataRequestPacket paramRequest = new ParameterDataRequestPacket(subpacket.data);
|
||||
if (paramRequest.paramName.Equals("charaWork/exp"))
|
||||
player.GetActor().SendCharaExpInfo();
|
||||
break;
|
||||
/* RECRUITMENT */
|
||||
//Start Recruiting
|
||||
case 0x01C3:
|
||||
StartRecruitingRequestPacket recruitRequestPacket = new StartRecruitingRequestPacket(subpacket.data);
|
||||
client.QueuePacket(BasePacket.CreatePacket(StartRecruitingResponse.BuildPacket(player.actorID, true), true, false));
|
||||
break;
|
||||
//End Recruiting
|
||||
case 0x01C4:
|
||||
client.QueuePacket(BasePacket.CreatePacket(EndRecruitmentPacket.BuildPacket(player.actorID), true, false));
|
||||
break;
|
||||
//Party Window Opened, Request State
|
||||
case 0x01C5:
|
||||
client.QueuePacket(BasePacket.CreatePacket(RecruiterStatePacket.BuildPacket(player.actorID, true, true, 1), true, false));
|
||||
break;
|
||||
//Search Recruiting
|
||||
case 0x01C7:
|
||||
RecruitmentSearchRequestPacket recruitSearchPacket = new RecruitmentSearchRequestPacket(subpacket.data);
|
||||
break;
|
||||
//Get Recruitment Details
|
||||
case 0x01C8:
|
||||
RecruitmentDetailsRequestPacket currentRecruitDetailsPacket = new RecruitmentDetailsRequestPacket(subpacket.data);
|
||||
RecruitmentDetails details = new RecruitmentDetails();
|
||||
details.recruiterName = "Localhost Character";
|
||||
details.purposeId = 2;
|
||||
details.locationId = 1;
|
||||
details.subTaskId = 1;
|
||||
details.comment = "This is a test details packet sent by the server. No implementation has been Created yet...";
|
||||
details.num[0] = 1;
|
||||
client.QueuePacket(BasePacket.CreatePacket(CurrentRecruitmentDetailsPacket.BuildPacket(player.actorID, details), true, false));
|
||||
break;
|
||||
//Accepted Recruiting
|
||||
case 0x01C6:
|
||||
subpacket.DebugPrintSubPacket();
|
||||
break;
|
||||
/* SOCIAL STUFF */
|
||||
case 0x01C9:
|
||||
AddRemoveSocialPacket addBlackList = new AddRemoveSocialPacket(subpacket.data);
|
||||
client.QueuePacket(BasePacket.CreatePacket(BlacklistAddedPacket.BuildPacket(player.actorID, true, addBlackList.name), true, false));
|
||||
break;
|
||||
case 0x01CA:
|
||||
AddRemoveSocialPacket RemoveBlackList = new AddRemoveSocialPacket(subpacket.data);
|
||||
client.QueuePacket(BasePacket.CreatePacket(BlacklistRemovedPacket.BuildPacket(player.actorID, true, RemoveBlackList.name), true, false));
|
||||
break;
|
||||
case 0x01CB:
|
||||
int offset1 = 0;
|
||||
client.QueuePacket(BasePacket.CreatePacket(SendBlacklistPacket.BuildPacket(player.actorID, new String[] { "Test" }, ref offset1), true, false));
|
||||
break;
|
||||
case 0x01CC:
|
||||
AddRemoveSocialPacket addFriendList = new AddRemoveSocialPacket(subpacket.data);
|
||||
client.QueuePacket(BasePacket.CreatePacket(FriendlistAddedPacket.BuildPacket(player.actorID, true, (uint)addFriendList.name.GetHashCode(), true, addFriendList.name), true, false));
|
||||
break;
|
||||
case 0x01CD:
|
||||
AddRemoveSocialPacket RemoveFriendList = new AddRemoveSocialPacket(subpacket.data);
|
||||
client.QueuePacket(BasePacket.CreatePacket(FriendlistRemovedPacket.BuildPacket(player.actorID, true, RemoveFriendList.name), true, false));
|
||||
break;
|
||||
case 0x01CE:
|
||||
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));
|
||||
break;
|
||||
case 0x01CF:
|
||||
client.QueuePacket(BasePacket.CreatePacket(FriendStatusPacket.BuildPacket(player.actorID, null), true, false));
|
||||
break;
|
||||
/* SUPPORT DESK STUFF */
|
||||
//Request for FAQ/Info List
|
||||
case 0x01D0:
|
||||
FaqListRequestPacket faqRequest = new FaqListRequestPacket(subpacket.data);
|
||||
client.QueuePacket(BasePacket.CreatePacket(FaqListResponsePacket.BuildPacket(player.actorID, new string[] { "Testing FAQ1", "Coded style!" }), true, false));
|
||||
break;
|
||||
//Request for body of a faq/info selection
|
||||
case 0x01D1:
|
||||
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));
|
||||
break;
|
||||
//Request issue list
|
||||
case 0x01D2:
|
||||
GMTicketIssuesRequestPacket issuesRequest = new GMTicketIssuesRequestPacket(subpacket.data);
|
||||
client.QueuePacket(BasePacket.CreatePacket(IssueListResponsePacket.BuildPacket(player.actorID, new string[] { "Test1", "Test2", "Test3", "Test4", "Test5" }), true, false));
|
||||
break;
|
||||
//Request if GM ticket exists
|
||||
case 0x01D3:
|
||||
client.QueuePacket(BasePacket.CreatePacket(StartGMTicketPacket.BuildPacket(player.actorID, false), true, false));
|
||||
break;
|
||||
//Request for GM response message
|
||||
case 0x01D4:
|
||||
client.QueuePacket(BasePacket.CreatePacket(GMTicketPacket.BuildPacket(player.actorID, "This is a GM Ticket Title", "This is a GM Ticket Body."), true, false));
|
||||
break;
|
||||
//GM Ticket Sent
|
||||
case 0x01D5:
|
||||
GMSupportTicketPacket gmTicket = new GMSupportTicketPacket(subpacket.data);
|
||||
Program.Log.Info("Got GM Ticket: \n" + gmTicket.ticketTitle + "\n" + gmTicket.ticketBody);
|
||||
client.QueuePacket(BasePacket.CreatePacket(GMTicketSentResponsePacket.BuildPacket(player.actorID, true), true, false));
|
||||
break;
|
||||
//Request to end ticket
|
||||
case 0x01D6:
|
||||
client.QueuePacket(BasePacket.CreatePacket(EndGMTicketPacket.BuildPacket(player.actorID), true, false));
|
||||
break;
|
||||
default:
|
||||
Program.Log.Debug("Unknown command 0x{0:X} received.", subpacket.gameMessage.opcode);
|
||||
subpacket.DebugPrintSubPacket();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x012F:
|
||||
//subpacket.DebugPrintSubPacket();
|
||||
ParameterDataRequestPacket paramRequest = new ParameterDataRequestPacket(subpacket.data);
|
||||
if (paramRequest.paramName.Equals("charaWork/exp"))
|
||||
session.GetActor().SendCharaExpInfo();
|
||||
break;
|
||||
/* RECRUITMENT */
|
||||
//Start Recruiting
|
||||
case 0x01C3:
|
||||
StartRecruitingRequestPacket recruitRequestPacket = new StartRecruitingRequestPacket(subpacket.data);
|
||||
client.QueuePacket(BasePacket.CreatePacket(StartRecruitingResponse.BuildPacket(session.id, true), true, false));
|
||||
break;
|
||||
//End Recruiting
|
||||
case 0x01C4:
|
||||
client.QueuePacket(BasePacket.CreatePacket(EndRecruitmentPacket.BuildPacket(session.id), true, false));
|
||||
break;
|
||||
//Party Window Opened, Request State
|
||||
case 0x01C5:
|
||||
client.QueuePacket(BasePacket.CreatePacket(RecruiterStatePacket.BuildPacket(session.id, true, true, 1), true, false));
|
||||
break;
|
||||
//Search Recruiting
|
||||
case 0x01C7:
|
||||
RecruitmentSearchRequestPacket recruitSearchPacket = new RecruitmentSearchRequestPacket(subpacket.data);
|
||||
break;
|
||||
//Get Recruitment Details
|
||||
case 0x01C8:
|
||||
RecruitmentDetailsRequestPacket currentRecruitDetailsPacket = new RecruitmentDetailsRequestPacket(subpacket.data);
|
||||
RecruitmentDetails details = new RecruitmentDetails();
|
||||
details.recruiterName = "Localhost Character";
|
||||
details.purposeId = 2;
|
||||
details.locationId = 1;
|
||||
details.subTaskId = 1;
|
||||
details.comment = "This is a test details packet sent by the server. No implementation has been Created yet...";
|
||||
details.num[0] = 1;
|
||||
client.QueuePacket(BasePacket.CreatePacket(CurrentRecruitmentDetailsPacket.BuildPacket(session.id, details), true, false));
|
||||
break;
|
||||
//Accepted Recruiting
|
||||
case 0x01C6:
|
||||
subpacket.DebugPrintSubPacket();
|
||||
break;
|
||||
/* SOCIAL STUFF */
|
||||
case 0x01C9:
|
||||
AddRemoveSocialPacket addBlackList = new AddRemoveSocialPacket(subpacket.data);
|
||||
client.QueuePacket(BasePacket.CreatePacket(BlacklistAddedPacket.BuildPacket(session.id, true, addBlackList.name), true, false));
|
||||
break;
|
||||
case 0x01CA:
|
||||
AddRemoveSocialPacket RemoveBlackList = new AddRemoveSocialPacket(subpacket.data);
|
||||
client.QueuePacket(BasePacket.CreatePacket(BlacklistRemovedPacket.BuildPacket(session.id, true, RemoveBlackList.name), true, false));
|
||||
break;
|
||||
case 0x01CB:
|
||||
int offset1 = 0;
|
||||
client.QueuePacket(BasePacket.CreatePacket(SendBlacklistPacket.BuildPacket(session.id, new String[] { "Test" }, ref offset1), true, false));
|
||||
break;
|
||||
case 0x01CC:
|
||||
AddRemoveSocialPacket addFriendList = new AddRemoveSocialPacket(subpacket.data);
|
||||
client.QueuePacket(BasePacket.CreatePacket(FriendlistAddedPacket.BuildPacket(session.id, true, (uint)addFriendList.name.GetHashCode(), true, addFriendList.name), true, false));
|
||||
break;
|
||||
case 0x01CD:
|
||||
AddRemoveSocialPacket RemoveFriendList = new AddRemoveSocialPacket(subpacket.data);
|
||||
client.QueuePacket(BasePacket.CreatePacket(FriendlistRemovedPacket.BuildPacket(session.id, true, RemoveFriendList.name), true, false));
|
||||
break;
|
||||
case 0x01CE:
|
||||
int offset2 = 0;
|
||||
client.QueuePacket(BasePacket.CreatePacket(SendFriendlistPacket.BuildPacket(session.id, new Tuple<long, string>[] { new Tuple<long, string>(01, "Test2") }, ref offset2), true, false));
|
||||
break;
|
||||
case 0x01CF:
|
||||
client.QueuePacket(BasePacket.CreatePacket(FriendStatusPacket.BuildPacket(session.id, null), true, false));
|
||||
break;
|
||||
/* SUPPORT DESK STUFF */
|
||||
//Request for FAQ/Info List
|
||||
case 0x01D0:
|
||||
FaqListRequestPacket faqRequest = new FaqListRequestPacket(subpacket.data);
|
||||
client.QueuePacket(BasePacket.CreatePacket(FaqListResponsePacket.BuildPacket(session.id, new string[] { "Testing FAQ1", "Coded style!" }), true, false));
|
||||
break;
|
||||
//Request for body of a faq/info selection
|
||||
case 0x01D1:
|
||||
FaqBodyRequestPacket faqBodyRequest = new FaqBodyRequestPacket(subpacket.data);
|
||||
client.QueuePacket(BasePacket.CreatePacket(FaqBodyResponsePacket.BuildPacket(session.id, "HERE IS A GIANT BODY. Nothing else to say!"), true, false));
|
||||
break;
|
||||
//Request issue list
|
||||
case 0x01D2:
|
||||
GMTicketIssuesRequestPacket issuesRequest = new GMTicketIssuesRequestPacket(subpacket.data);
|
||||
client.QueuePacket(BasePacket.CreatePacket(IssueListResponsePacket.BuildPacket(session.id, new string[] { "Test1", "Test2", "Test3", "Test4", "Test5" }), true, false));
|
||||
break;
|
||||
//Request if GM ticket exists
|
||||
case 0x01D3:
|
||||
client.QueuePacket(BasePacket.CreatePacket(StartGMTicketPacket.BuildPacket(session.id, false), true, false));
|
||||
break;
|
||||
//Request for GM response message
|
||||
case 0x01D4:
|
||||
client.QueuePacket(BasePacket.CreatePacket(GMTicketPacket.BuildPacket(session.id, "This is a GM Ticket Title", "This is a GM Ticket Body."), true, false));
|
||||
break;
|
||||
//GM Ticket Sent
|
||||
case 0x01D5:
|
||||
GMSupportTicketPacket gmTicket = new GMSupportTicketPacket(subpacket.data);
|
||||
Program.Log.Info("Got GM Ticket: \n" + gmTicket.ticketTitle + "\n" + gmTicket.ticketBody);
|
||||
client.QueuePacket(BasePacket.CreatePacket(GMTicketSentResponsePacket.BuildPacket(session.id, true), true, false));
|
||||
break;
|
||||
//Request to end ticket
|
||||
case 0x01D6:
|
||||
client.QueuePacket(BasePacket.CreatePacket(EndGMTicketPacket.BuildPacket(session.id), true, false));
|
||||
break;
|
||||
default:
|
||||
Program.Log.Debug("Unknown command 0x{0:X} received.", subpacket.gameMessage.opcode);
|
||||
subpacket.DebugPrintSubPacket();
|
||||
break;
|
||||
}
|
||||
else
|
||||
packet.DebugPrintPacket();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -63,14 +63,14 @@ namespace FFXIVClassic_Map_Server
|
||||
if (startServer)
|
||||
{
|
||||
Server server = new Server();
|
||||
CommandProcessor cp = new CommandProcessor(server.GetConnectedPlayerList());
|
||||
|
||||
server.StartServer();
|
||||
|
||||
while (startServer)
|
||||
{
|
||||
String input = Console.ReadLine();
|
||||
Log.Info("[Console Input] " + input);
|
||||
cp.DoCommand(input, null);
|
||||
Server.GetCommandProcessor().DoCommand(input, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using FFXIVClassic_Map_Server.dataobjects;
|
||||
using FFXIVClassic_Map_Server.packets;
|
||||
|
||||
using FFXIVClassic.Common;
|
||||
using NLog;
|
||||
using FFXIVClassic_Map_Server.Actors;
|
||||
using FFXIVClassic_Map_Server.lua;
|
||||
|
||||
@ -17,7 +15,6 @@ namespace FFXIVClassic_Map_Server
|
||||
public const int FFXIV_MAP_PORT = 54992;
|
||||
public const int BUFFER_SIZE = 0xFFFF; //Max basepacket size is 0xFFFF
|
||||
public const int BACKLOG = 100;
|
||||
public const int HEALTH_THREAD_SLEEP_TIME = 5;
|
||||
|
||||
public const string STATIC_ACTORS_PATH = "./staticactors.bin";
|
||||
|
||||
@ -25,60 +22,28 @@ namespace FFXIVClassic_Map_Server
|
||||
|
||||
private Socket mServerSocket;
|
||||
|
||||
private Dictionary<uint, ConnectedPlayer> mConnectedPlayerList = new Dictionary<uint, ConnectedPlayer>();
|
||||
private List<ClientConnection> mConnectionList = new List<ClientConnection>();
|
||||
private Dictionary<uint, Session> mSessionList = new Dictionary<uint, Session>();
|
||||
private LuaEngine mLuaEngine = new LuaEngine();
|
||||
|
||||
private static CommandProcessor mCommandProcessor = new CommandProcessor();
|
||||
private static ZoneConnection mWorldConnection = new ZoneConnection();
|
||||
private static WorldManager mWorldManager;
|
||||
private static Dictionary<uint, Item> gamedataItems;
|
||||
private static Dictionary<uint, Item> mGamedataItems;
|
||||
private static StaticActors mStaticActors;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
private PacketProcessor mProcessor;
|
||||
|
||||
public Server()
|
||||
{
|
||||
mSelf = this;
|
||||
}
|
||||
|
||||
public static Server GetServer()
|
||||
{
|
||||
return mSelf;
|
||||
}
|
||||
|
||||
|
||||
public bool StartServer()
|
||||
{
|
||||
mConnectionHealthThread = new Thread(new ThreadStart(ConnectionHealth));
|
||||
mConnectionHealthThread.Name = "MapThread:Health";
|
||||
//mConnectionHealthThread.Start();
|
||||
|
||||
{
|
||||
mStaticActors = new StaticActors(STATIC_ACTORS_PATH);
|
||||
|
||||
gamedataItems = Database.GetItemGamedata();
|
||||
Program.Log.Info("Loaded {0} items.", gamedataItems.Count);
|
||||
mGamedataItems = Database.GetItemGamedata();
|
||||
Program.Log.Info("Loaded {0} items.", mGamedataItems.Count);
|
||||
|
||||
mWorldManager = new WorldManager(this);
|
||||
mWorldManager.LoadZoneList();
|
||||
@ -88,11 +53,11 @@ namespace FFXIVClassic_Map_Server
|
||||
mWorldManager.LoadSpawnLocations();
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
|
||||
mProcessor = new PacketProcessor(this, mConnectedPlayerList, mConnectionList);
|
||||
mProcessor = new PacketProcessor(this);
|
||||
|
||||
//mGameThread = new Thread(new ThreadStart(mProcessor.update));
|
||||
//mGameThread.Start();
|
||||
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))
|
||||
mConnectedPlayerList.Remove(player.actorId);
|
||||
mSessionList.Remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
private void AcceptCallback(IAsyncResult result)
|
||||
{
|
||||
ClientConnection conn = null;
|
||||
ZoneConnection conn = null;
|
||||
Socket socket = (System.Net.Sockets.Socket)result.AsyncState;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
conn = new ClientConnection();
|
||||
conn = new ZoneConnection();
|
||||
conn.socket = socket.EndAccept(result);
|
||||
conn.buffer = new byte[BUFFER_SIZE];
|
||||
|
||||
lock (mConnectionList)
|
||||
{
|
||||
mConnectionList.Add(conn);
|
||||
}
|
||||
|
||||
mWorldConnection = conn;
|
||||
|
||||
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
|
||||
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)
|
||||
{
|
||||
|
||||
lock (mConnectionList)
|
||||
{
|
||||
mConnectionList.Remove(conn);
|
||||
}
|
||||
mWorldConnection = null;
|
||||
}
|
||||
mServerSocket.BeginAccept(new AsyncCallback(AcceptCallback), mServerSocket);
|
||||
}
|
||||
@ -176,53 +170,25 @@ namespace FFXIVClassic_Map_Server
|
||||
{
|
||||
if (conn != null)
|
||||
{
|
||||
lock (mConnectionList)
|
||||
{
|
||||
mConnectionList.Remove(conn);
|
||||
}
|
||||
mWorldConnection = null;
|
||||
}
|
||||
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>
|
||||
/// 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>
|
||||
/// <param name="result"></param>
|
||||
private void ReceiveCallback(IAsyncResult result)
|
||||
{
|
||||
ClientConnection conn = (ClientConnection)result.AsyncState;
|
||||
ZoneConnection conn = (ZoneConnection)result.AsyncState;
|
||||
|
||||
//Check if disconnected
|
||||
if ((conn.socket.Poll(1, SelectMode.SelectRead) && conn.socket.Available == 0))
|
||||
{
|
||||
if (mConnectedPlayerList.ContainsKey(conn.owner))
|
||||
mConnectedPlayerList.Remove(conn.owner);
|
||||
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;
|
||||
mWorldConnection = null;
|
||||
Program.Log.Info("Disconnected from world server!");
|
||||
}
|
||||
|
||||
try
|
||||
@ -238,13 +204,13 @@ namespace FFXIVClassic_Map_Server
|
||||
//Build packets until can no longer or out of data
|
||||
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 (basePacket == null)
|
||||
if (subPacket == null)
|
||||
break;
|
||||
else
|
||||
mProcessor.ProcessPacket(conn, basePacket);
|
||||
mProcessor.ProcessPacket(conn, subPacket);
|
||||
}
|
||||
|
||||
//Not all bytes consumed, transfer leftover to beginning
|
||||
@ -265,79 +231,63 @@ namespace FFXIVClassic_Map_Server
|
||||
}
|
||||
else
|
||||
{
|
||||
Program.Log.Info("{0} has disconnected.", conn.owner == 0 ? conn.GetAddress() : "User " + conn.owner);
|
||||
|
||||
lock (mConnectionList)
|
||||
{
|
||||
mConnectionList.Remove(conn);
|
||||
}
|
||||
mWorldConnection = null;
|
||||
Program.Log.Info("Disconnected from world server!");
|
||||
}
|
||||
}
|
||||
catch (SocketException)
|
||||
{
|
||||
if (conn.socket != null)
|
||||
{
|
||||
Program.Log.Info("{0} has disconnected.", conn.owner == 0 ? conn.GetAddress() : "User " + conn.owner);
|
||||
|
||||
lock (mConnectionList)
|
||||
{
|
||||
mConnectionList.Remove(conn);
|
||||
}
|
||||
mWorldConnection = null;
|
||||
Program.Log.Info("Disconnected from world server!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <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
|
||||
|
||||
public static ZoneConnection GetWorldConnection()
|
||||
{
|
||||
return mWorldConnection;
|
||||
}
|
||||
|
||||
public static Server GetServer()
|
||||
{
|
||||
return mSelf;
|
||||
}
|
||||
|
||||
public static CommandProcessor GetCommandProcessor()
|
||||
{
|
||||
return mCommandProcessor;
|
||||
}
|
||||
|
||||
public static WorldManager GetWorldManager()
|
||||
{
|
||||
return mWorldManager;
|
||||
}
|
||||
|
||||
public Dictionary<uint, ConnectedPlayer> GetConnectedPlayerList()
|
||||
{
|
||||
return mConnectedPlayerList;
|
||||
}
|
||||
|
||||
|
||||
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,
|
||||
canStealth,
|
||||
isInstanceRaid
|
||||
FROM server_zones
|
||||
WHERE zoneName IS NOT NULL";
|
||||
FROM server_zones
|
||||
WHERE zoneName IS NOT NULL and serverIp = @ip and serverPort = @port";
|
||||
|
||||
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())
|
||||
{
|
||||
while (reader.Read())
|
||||
@ -333,14 +336,21 @@ namespace FFXIVClassic_Map_Server
|
||||
using (MySqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
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;
|
||||
if (!reader.IsDBNull(11))
|
||||
customName = reader.GetString("customDisplayName");
|
||||
|
||||
uint classId = reader.GetUInt32("actorClassId");
|
||||
string uniqueId = reader.GetString("uniqueId");
|
||||
uint zoneId = reader.GetUInt32("zoneId");
|
||||
string uniqueId = reader.GetString("uniqueId");
|
||||
string privAreaName = reader.GetString("privateAreaName");
|
||||
uint privAreaLevel = reader.GetUInt32("privateAreaLevel");
|
||||
float x = reader.GetFloat("positionX");
|
||||
@ -349,16 +359,7 @@ namespace FFXIVClassic_Map_Server
|
||||
float rot = reader.GetFloat("rotation");
|
||||
ushort state = reader.GetUInt16("actorState");
|
||||
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);
|
||||
|
||||
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.
|
||||
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
|
||||
Area newArea;
|
||||
|
||||
@ -542,17 +536,18 @@ namespace FFXIVClassic_Map_Server
|
||||
//This server does not contain that zoneId
|
||||
if (newArea == null)
|
||||
{
|
||||
if (oldZone != null)
|
||||
{
|
||||
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);
|
||||
Program.Log.Debug("Request to change to zone not on this server by: {0}.", player.customDisplayName);
|
||||
RequestWorldServerZoneChange(player, destinationZoneId, spawnType, spawnX, spawnY, spawnZ, spawnRotation);
|
||||
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);
|
||||
|
||||
//Update player actor's properties
|
||||
@ -613,8 +608,8 @@ namespace FFXIVClassic_Map_Server
|
||||
}
|
||||
}
|
||||
|
||||
//Login Zone In
|
||||
public void DoLogin(Player player)
|
||||
//Session started, zone into world
|
||||
public void DoZoneIn(Player player, bool isLogin, ushort spawnType)
|
||||
{
|
||||
//Add player to new zone and update
|
||||
Zone zone = GetZone(player.zoneId);
|
||||
@ -625,15 +620,25 @@ namespace FFXIVClassic_Map_Server
|
||||
|
||||
//Set the current zone and add player
|
||||
player.zone = zone;
|
||||
|
||||
LuaEngine.OnBeginLogin(player);
|
||||
|
||||
zone.AddActorToZone(player);
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
foreach (Zone zone in zoneList.Values)
|
||||
|
@ -1,4 +1,4 @@
|
||||
using FFXIVClassic_Map_Server.packets;
|
||||
|
||||
using FFXIVClassic_Map_Server.actors;
|
||||
using FFXIVClassic_Map_Server.lua;
|
||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||
@ -71,7 +71,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
return SetActorSpeedPacket.BuildPacket(actorId, playerActorId);
|
||||
}
|
||||
|
||||
public SubPacket CreateSpawnPositonPacket(uint playerActorId, uint spawnType)
|
||||
public SubPacket CreateSpawnPositonPacket(uint playerActorId, ushort spawnType)
|
||||
{
|
||||
SubPacket spawnPacket;
|
||||
if (!spawnedFirstTime && playerActorId == actorId)
|
||||
@ -92,7 +92,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
return spawnPacket;
|
||||
}
|
||||
|
||||
public SubPacket CreateSpawnTeleportPacket(uint playerActorId, uint spawnType)
|
||||
public SubPacket CreateSpawnTeleportPacket(uint playerActorId, ushort spawnType)
|
||||
{
|
||||
SubPacket spawnPacket;
|
||||
|
||||
@ -224,7 +224,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
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>();
|
||||
subpackets.Add(CreateAddActorPacket(playerActorId, 8));
|
||||
|
@ -1,6 +1,6 @@
|
||||
using FFXIVClassic_Map_Server;
|
||||
using FFXIVClassic.Common;
|
||||
using FFXIVClassic_Map_Server.packets;
|
||||
|
||||
using FFXIVClassic_Map_Server.actors.area;
|
||||
using FFXIVClassic_Map_Server.actors.chara.npc;
|
||||
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.lua;
|
||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||
|
@ -1,6 +1,6 @@
|
||||
using FFXIVClassic_Map_Server;
|
||||
using FFXIVClassic.Common;
|
||||
using FFXIVClassic_Map_Server.packets;
|
||||
|
||||
using FFXIVClassic_Map_Server.actors.chara.npc;
|
||||
using FFXIVClassic_Map_Server.Actors;
|
||||
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.packets.send.actor;
|
||||
|
||||
@ -35,6 +36,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
public const int L_INDEXFINGER = 26;
|
||||
public const int UNKNOWN = 27;
|
||||
|
||||
public bool isStatic = false;
|
||||
|
||||
public uint modelId;
|
||||
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.dataobjects;
|
||||
using FFXIVClassic_Map_Server.lua;
|
||||
using FFXIVClassic_Map_Server.packets;
|
||||
|
||||
using FFXIVClassic_Map_Server.packets.receive.events;
|
||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||
using FFXIVClassic_Map_Server.utils;
|
||||
@ -86,13 +86,17 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
List<LuaParam> lParams;
|
||||
|
||||
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)
|
||||
{
|
||||
string classPathFake = "/Chara/Npc/Populace/PopulaceStandard";
|
||||
string classNameFake = "PopulaceStandard";
|
||||
lParams = LuaUtils.CreateLuaParamList(classPathFake, false, false, false, false, false, 0xF47F6, false, false, 0, 0);
|
||||
isStatic = true;
|
||||
//ActorInstantiatePacket.BuildPacket(actorId, playerActorId, actorName, classNameFake, lParams).DebugPrintSubPacket();
|
||||
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);
|
||||
}
|
||||
|
||||
public override BasePacket GetSpawnPackets(uint playerActorId, uint spawnType)
|
||||
public override BasePacket GetSpawnPackets(uint playerActorId, ushort spawnType)
|
||||
{
|
||||
List<SubPacket> subpackets = new List<SubPacket>();
|
||||
subpackets.Add(CreateAddActorPacket(playerActorId));
|
||||
|
@ -1,7 +1,6 @@
|
||||
using FFXIVClassic_Map_Server.Actors;
|
||||
using FFXIVClassic_Map_Server.dataobjects;
|
||||
using FFXIVClassic_Map_Server.packets.send.actor.inventory;
|
||||
using FFXIVClassic_Map_Server.packets.send.Actor.inventory;
|
||||
using System.Collections.Generic;
|
||||
|
||||
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.dataobjects;
|
||||
using FFXIVClassic_Map_Server.packets.send.actor.inventory;
|
||||
using FFXIVClassic_Map_Server.packets.send.Actor.inventory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -1,5 +1,5 @@
|
||||
using FFXIVClassic.Common;
|
||||
using FFXIVClassic_Map_Server.packets;
|
||||
|
||||
using FFXIVClassic_Map_Server.actors.chara.player;
|
||||
using FFXIVClassic_Map_Server.actors.director;
|
||||
using FFXIVClassic_Map_Server.dataobjects;
|
||||
@ -7,8 +7,6 @@ using FFXIVClassic_Map_Server.dataobjects.chara;
|
||||
using FFXIVClassic_Map_Server.lua;
|
||||
using FFXIVClassic_Map_Server.packets.send;
|
||||
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.list;
|
||||
using FFXIVClassic_Map_Server.packets.send.player;
|
||||
@ -17,7 +15,8 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using MoonSharp.Interpreter;
|
||||
using FFXIVClassic_Map_Server.packets.receive.events;
|
||||
|
||||
using FFXIVClassic_Map_Server.packets.send.actor.inventory;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.Actors
|
||||
{
|
||||
class Player : Character
|
||||
@ -84,7 +83,9 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
|
||||
public Coroutine currentEventRunning;
|
||||
|
||||
//Player Info
|
||||
//Player Info
|
||||
public uint destinationZone;
|
||||
public ushort destinationSpawnType;
|
||||
public uint[] timers = new uint[20];
|
||||
public ushort currentJob;
|
||||
public uint currentTitle;
|
||||
@ -124,9 +125,9 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
|
||||
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;
|
||||
actorName = String.Format("_pc{0:00000000}", actorID);
|
||||
@ -258,9 +259,9 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
else
|
||||
lParams = LuaUtils.CreateLuaParamList("/Chara/Player/Player_work", false, false, false, false, false, true);
|
||||
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>();
|
||||
subpackets.Add(CreateAddActorPacket(playerActorId, 8));
|
||||
@ -481,7 +482,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
QueuePacket(SetMapPacket.BuildPacket(actorId, zone.regionId, zone.actorId));
|
||||
|
||||
QueuePacket(GetSpawnPackets(actorId, spawnType));
|
||||
GetSpawnPackets(actorId, spawnType).DebugPrintPacket();
|
||||
//GetSpawnPackets(actorId, spawnType).DebugPrintPacket();
|
||||
|
||||
#region grouptest
|
||||
//Retainers
|
||||
@ -653,16 +654,39 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
}
|
||||
|
||||
public void CleanupAndSave()
|
||||
{
|
||||
{
|
||||
playerSession.LockUpdates(true);
|
||||
|
||||
//Remove actor from zone and main server list
|
||||
zone.RemoveActorFromZone(this);
|
||||
Server.GetServer().RemovePlayer(this);
|
||||
|
||||
//Set Destination to 0
|
||||
this.destinationZone = 0;
|
||||
this.destinationSpawnType = 0;
|
||||
|
||||
//Save Player
|
||||
Database.SavePlayerPlayTime(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()
|
||||
@ -730,8 +754,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
@ -740,24 +764,24 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||
}
|
||||
|
||||
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));
|
||||
else
|
||||
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)
|
||||
{
|
||||
if (msgParams.Length == 0)
|
||||
{
|
||||
if (msgParams == null || msgParams.Length == 0)
|
||||
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, customSender, log));
|
||||
else
|
||||
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)
|
||||
{
|
||||
if (msgParams.Length == 0)
|
||||
{
|
||||
if (msgParams == null || msgParams.Length == 0)
|
||||
QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, displayId, log));
|
||||
else
|
||||
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.packets.send.actor;
|
||||
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.lua;
|
||||
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.lua;
|
||||
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.lua;
|
||||
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.lua;
|
||||
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.lua;
|
||||
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.lua;
|
||||
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.packets.send.actor;
|
||||
using System.Collections.Generic;
|
||||
|
@ -1,6 +1,6 @@
|
||||
using FFXIVClassic_Map_Server;
|
||||
using FFXIVClassic.Common;
|
||||
using FFXIVClassic_Map_Server.packets;
|
||||
|
||||
using FFXIVClassic_Map_Server.Actors;
|
||||
using FFXIVClassic_Map_Server.lua;
|
||||
using FFXIVClassic_Map_Server.packets.send.actor;
|
||||
@ -12,66 +12,33 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.dataobjects
|
||||
{
|
||||
class ConnectedPlayer
|
||||
class Session
|
||||
{
|
||||
public uint actorID = 0;
|
||||
public uint id = 0;
|
||||
Player playerActor;
|
||||
public List<Actor> actorInstanceList = new List<Actor>();
|
||||
|
||||
public uint languageCode = 1;
|
||||
|
||||
private ClientConnection zoneConnection;
|
||||
private ClientConnection chatConnection;
|
||||
|
||||
public uint languageCode = 1;
|
||||
private uint lastPingPacket = Utils.UnixTimeStampUTC();
|
||||
|
||||
public bool isUpdatesLocked = true;
|
||||
|
||||
public string errorMessage = "";
|
||||
|
||||
public ConnectedPlayer(uint actorId)
|
||||
public Session(uint sessionId)
|
||||
{
|
||||
this.actorID = actorId;
|
||||
playerActor = new Player(this, actorId);
|
||||
this.id = sessionId;
|
||||
playerActor = new Player(this, sessionId);
|
||||
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)
|
||||
{
|
||||
zoneConnection.QueuePacket(basePacket);
|
||||
Server.GetWorldConnection().QueuePacket(basePacket);
|
||||
}
|
||||
|
||||
public void QueuePacket(SubPacket subPacket, bool isAuthed, bool isEncrypted)
|
||||
{
|
||||
zoneConnection.QueuePacket(subPacket, isAuthed, isEncrypted);
|
||||
{
|
||||
Server.GetWorldConnection().QueuePacket(subPacket, isAuthed, isEncrypted);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (isUpdatesLocked)
|
||||
return;
|
||||
|
||||
playerActor.oldPositionX = playerActor.positionX;
|
||||
playerActor.oldPositionY = playerActor.positionY;
|
||||
playerActor.oldPositionZ = playerActor.positionZ;
|
||||
@ -115,6 +85,9 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
||||
|
||||
public void UpdateInstance(List<Actor> list)
|
||||
{
|
||||
if (isUpdatesLocked)
|
||||
return;
|
||||
|
||||
List<BasePacket> basePackets = new List<BasePacket>();
|
||||
List<SubPacket> RemoveActorSubpackets = new List<SubPacket>();
|
||||
List<SubPacket> posUpdateSubpackets = new List<SubPacket>();
|
||||
@ -139,6 +112,10 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
||||
|
||||
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));
|
||||
}
|
||||
else
|
||||
@ -163,5 +140,10 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
||||
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;
|
||||
using FFXIVClassic_Map_Server.dataobjects;
|
||||
using FFXIVClassic_Map_Server.packets.receive.events;
|
||||
using FFXIVClassic_Map_Server.packets.send;
|
||||
using FFXIVClassic_Map_Server.packets.send.events;
|
||||
using MoonSharp.Interpreter;
|
||||
using MoonSharp.Interpreter.Interop;
|
||||
using MoonSharp.Interpreter.Loaders;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using FFXIVClassic_Map_Server.lua;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.lua
|
||||
{
|
||||
class LuaEngine
|
||||
{
|
||||
const string FILEPATH_PLAYER = "./scripts/player.lua";
|
||||
const string FILEPATH_ZONE = "./scripts/zones/{0}/zone.lua";
|
||||
const string FILEPATH_COMMANDS = "./scripts/commands/{0}.lua";
|
||||
const string FILEPATH_DIRECTORS = "./scripts/directors/{0}.lua";
|
||||
const string FILEPATH_NPCS = "./scripts/zones/{0}/npcs/{1}.lua";
|
||||
|
||||
public LuaEngine()
|
||||
{
|
||||
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;
|
||||
|
||||
using FFXIVClassic_Map_Server.actors.director;
|
||||
using FFXIVClassic_Map_Server.Actors;
|
||||
using FFXIVClassic_Map_Server.dataobjects;
|
||||
using FFXIVClassic_Map_Server.packets.receive.events;
|
||||
using FFXIVClassic_Map_Server.packets.send;
|
||||
using FFXIVClassic_Map_Server.packets.send.events;
|
||||
using MoonSharp.Interpreter;
|
||||
using MoonSharp.Interpreter.Interop;
|
||||
using MoonSharp.Interpreter.Loaders;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using FFXIVClassic_Map_Server.lua;
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.lua
|
||||
{
|
||||
class LuaEngine
|
||||
{
|
||||
const string FILEPATH_PLAYER = "./scripts/player.lua";
|
||||
const string FILEPATH_ZONE = "./scripts/zones/{0}/zone.lua";
|
||||
const string FILEPATH_COMMANDS = "./scripts/commands/{0}.lua";
|
||||
const string FILEPATH_DIRECTORS = "./scripts/directors/{0}.lua";
|
||||
const string FILEPATH_NPCS = "./scripts/zones/{0}/npcs/{1}.lua";
|
||||
|
||||
public LuaEngine()
|
||||
{
|
||||
UserData.RegistrationPolicy = InteropRegistrationPolicy.Automatic;
|
||||
}
|
||||
|
||||
public static Coroutine DoActorOnEventStarted(Player player, Actor target, EventStartPacket eventStart)
|
||||
{
|
||||
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 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 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Coroutine DoActorOnEventStarted(Player player, Actor target, EventStartPacket eventStart)
|
||||
{
|
||||
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()));
|
||||
{
|
||||
luaPath = String.Format(FILEPATH_COMMANDS, target.GetName());
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnZoneIn(Player player)
|
||||
{
|
||||
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 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);
|
||||
|
||||
if (File.Exists(luaPath))
|
||||
{
|
||||
LuaScript script = LoadScript(luaPath);
|
||||
|
||||
if (script == null)
|
||||
return;
|
||||
|
||||
//Run Script
|
||||
if (!script.Globals.Get("onZoneIn").IsNil())
|
||||
script.Call(script.Globals["onZoneIn"], player);
|
||||
if (File.Exists(luaPath))
|
||||
{
|
||||
LuaScript script = LoadScript(luaPath);
|
||||
|
||||
if (script == null)
|
||||
return;
|
||||
|
||||
//Run Script
|
||||
if (!script.Globals.Get("onZoneIn").IsNil())
|
||||
script.Call(script.Globals["onZoneIn"], player);
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnBeginLogin(Player player)
|
||||
{
|
||||
if (File.Exists(FILEPATH_PLAYER))
|
||||
{
|
||||
LuaScript script = LoadScript(FILEPATH_PLAYER);
|
||||
|
||||
if (script == null)
|
||||
return;
|
||||
|
||||
//Run Script
|
||||
if (!script.Globals.Get("onBeginLogin").IsNil())
|
||||
script.Call(script.Globals["onBeginLogin"], player);
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnLogin(Player player)
|
||||
{
|
||||
if (File.Exists(FILEPATH_PLAYER))
|
||||
{
|
||||
LuaScript script = LoadScript(FILEPATH_PLAYER);
|
||||
|
||||
if (script == null)
|
||||
return;
|
||||
|
||||
//Run Script
|
||||
if (!script.Globals.Get("onLogin").IsNil())
|
||||
script.Call(script.Globals["onLogin"], player);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void OnBeginLogin(Player player)
|
||||
{
|
||||
if (File.Exists(FILEPATH_PLAYER))
|
||||
{
|
||||
LuaScript script = LoadScript(FILEPATH_PLAYER);
|
||||
|
||||
if (script == null)
|
||||
return;
|
||||
|
||||
//Run Script
|
||||
if (!script.Globals.Get("onBeginLogin").IsNil())
|
||||
script.Call(script.Globals["onBeginLogin"], player);
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnLogin(Player player)
|
||||
{
|
||||
if (File.Exists(FILEPATH_PLAYER))
|
||||
{
|
||||
LuaScript script = LoadScript(FILEPATH_PLAYER);
|
||||
|
||||
if (script == null)
|
||||
return;
|
||||
|
||||
//Run Script
|
||||
if (!script.Globals.Get("onLogin").IsNil())
|
||||
script.Call(script.Globals["onLogin"], player);
|
||||
}
|
||||
}
|
||||
|
||||
#region RunGMCommand
|
||||
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);
|
||||
return;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public static LuaScript LoadScript(string filename)
|
||||
{
|
||||
LuaScript script = LoadGlobals();
|
||||
|
||||
try
|
||||
{
|
||||
script.DoFile(filename);
|
||||
}
|
||||
catch (SyntaxErrorException e)
|
||||
{
|
||||
Program.Log.Error("LUAERROR: {0}.", e.DecoratedMessage);
|
||||
return null;
|
||||
}
|
||||
return script;
|
||||
#endregion
|
||||
|
||||
public static LuaScript LoadScript(string filename)
|
||||
{
|
||||
LuaScript script = LoadGlobals();
|
||||
|
||||
try
|
||||
{
|
||||
script.DoFile(filename);
|
||||
}
|
||||
catch (SyntaxErrorException e)
|
||||
{
|
||||
Program.Log.Error("LUAERROR: {0}.", e.DecoratedMessage);
|
||||
return null;
|
||||
}
|
||||
return script;
|
||||
}
|
||||
|
||||
public static LuaScript LoadGlobals(LuaScript script = null)
|
||||
@ -367,57 +368,57 @@ namespace FFXIVClassic_Map_Server.lua
|
||||
|
||||
script.Options.DebugPrint = s => { Program.Log.Debug(s); };
|
||||
return script;
|
||||
}
|
||||
|
||||
public static void SendError(Player player, string message)
|
||||
{
|
||||
List<SubPacket> SendError = new List<SubPacket>();
|
||||
SendError.Add(EndEventPacket.BuildPacket(player.actorId, player.currentEventOwner, player.currentEventName));
|
||||
player.SendMessage(SendMessagePacket.MESSAGE_TYPE_SYSTEM_ERROR, "", message);
|
||||
player.playerSession.QueuePacket(BasePacket.CreatePacket(SendError, true, false));
|
||||
}
|
||||
|
||||
|
||||
internal static void DoDirectorOnTalked(Director director, Player player, Npc npc)
|
||||
{
|
||||
string luaPath = String.Format(FILEPATH_DIRECTORS, director.GetName());
|
||||
|
||||
if (File.Exists(luaPath))
|
||||
{
|
||||
LuaScript script = LoadScript(luaPath);
|
||||
|
||||
if (script == null)
|
||||
return;
|
||||
|
||||
//Run Script
|
||||
if (!script.Globals.Get("onTalked").IsNil())
|
||||
script.Call(script.Globals["onTalked"], player, npc);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendError(player, String.Format("ERROR: Could not find script for director {0}.", director.GetName()));
|
||||
}
|
||||
}
|
||||
|
||||
internal static void DoDirectorOnCommand(Director director, Player player, Command command)
|
||||
{
|
||||
string luaPath = String.Format(FILEPATH_DIRECTORS, director.GetName());
|
||||
|
||||
if (File.Exists(luaPath))
|
||||
{
|
||||
LuaScript script = LoadScript(luaPath);
|
||||
|
||||
if (script == null)
|
||||
return;
|
||||
|
||||
//Run Script
|
||||
if (!script.Globals.Get("onCommand").IsNil())
|
||||
script.Call(script.Globals["onCommand"], player, command);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendError(player, String.Format("ERROR: Could not find script for director {0}.", director.GetName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SendError(Player player, string message)
|
||||
{
|
||||
List<SubPacket> SendError = new List<SubPacket>();
|
||||
SendError.Add(EndEventPacket.BuildPacket(player.actorId, player.currentEventOwner, player.currentEventName));
|
||||
player.SendMessage(SendMessagePacket.MESSAGE_TYPE_SYSTEM_ERROR, "", message);
|
||||
player.playerSession.QueuePacket(BasePacket.CreatePacket(SendError, true, false));
|
||||
}
|
||||
|
||||
|
||||
internal static void DoDirectorOnTalked(Director director, Player player, Npc npc)
|
||||
{
|
||||
string luaPath = String.Format(FILEPATH_DIRECTORS, director.GetName());
|
||||
|
||||
if (File.Exists(luaPath))
|
||||
{
|
||||
LuaScript script = LoadScript(luaPath);
|
||||
|
||||
if (script == null)
|
||||
return;
|
||||
|
||||
//Run Script
|
||||
if (!script.Globals.Get("onTalked").IsNil())
|
||||
script.Call(script.Globals["onTalked"], player, npc);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendError(player, String.Format("ERROR: Could not find script for director {0}.", director.GetName()));
|
||||
}
|
||||
}
|
||||
|
||||
internal static void DoDirectorOnCommand(Director director, Player player, Command command)
|
||||
{
|
||||
string luaPath = String.Format(FILEPATH_DIRECTORS, director.GetName());
|
||||
|
||||
if (File.Exists(luaPath))
|
||||
{
|
||||
LuaScript script = LoadScript(luaPath);
|
||||
|
||||
if (script == null)
|
||||
return;
|
||||
|
||||
//Run Script
|
||||
if (!script.Globals.Get("onCommand").IsNil())
|
||||
script.Call(script.Globals["onCommand"], player, command);
|
||||
}
|
||||
else
|
||||
{
|
||||
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.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
class ActorDoEmotePacket
|
||||
{
|
||||
|
@ -4,7 +4,9 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
class ActorInstantiatePacket
|
||||
{
|
||||
|
@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
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
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
class MoveActorToPositionPacket
|
||||
{
|
||||
|
@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
class RemoveActorPacket
|
||||
{
|
||||
|
@ -1,6 +1,8 @@
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
class SetActorAppearancePacket
|
||||
{
|
||||
|
@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
class SetActorIconPacket
|
||||
{
|
||||
|
@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
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
|
||||
{
|
||||
|
@ -2,7 +2,9 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
class SetActorNamePacket
|
||||
{
|
||||
|
@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
class SetActorPositionPacket
|
||||
{
|
||||
@ -22,7 +24,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
public const float INNPOS_Z = 165.050003f;
|
||||
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];
|
||||
|
||||
|
@ -5,7 +5,9 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
class SetActorPropetyPacket
|
||||
{
|
||||
|
@ -1,7 +1,8 @@
|
||||
using System;
|
||||
using FFXIVClassic.Common;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
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
|
||||
{
|
||||
|
@ -1,7 +1,10 @@
|
||||
using System;
|
||||
using FFXIVClassic.Common;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
class SetActorStatusAllPacket
|
||||
{
|
||||
|
@ -1,7 +1,10 @@
|
||||
using System;
|
||||
using FFXIVClassic.Common;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
class SetActorStatusPacket
|
||||
{
|
||||
|
@ -1,6 +1,8 @@
|
||||
using System;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
class SetActorTargetAnimatedPacket
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using FFXIVClassic.Common;
|
||||
using System;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
|
@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using FFXIVClassic.Common;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
using FFXIVClassic.Common;
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
class _0x132Packet
|
||||
{
|
||||
|
@ -1,6 +1,8 @@
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor
|
||||
{
|
||||
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
|
||||
{
|
||||
|
@ -1,7 +1,10 @@
|
||||
using System;
|
||||
using FFXIVClassic.Common;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.battle
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.battle
|
||||
{
|
||||
class BattleActionX00Packet
|
||||
{
|
||||
|
@ -1,7 +1,10 @@
|
||||
using System;
|
||||
using FFXIVClassic.Common;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.battle
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.battle
|
||||
{
|
||||
class BattleActionX01Packet
|
||||
{
|
||||
|
@ -1,7 +1,10 @@
|
||||
using System;
|
||||
using FFXIVClassic.Common;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.battle
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.battle
|
||||
{
|
||||
class BattleActionX10Packet
|
||||
{
|
||||
|
@ -1,7 +1,10 @@
|
||||
using System;
|
||||
using FFXIVClassic.Common;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.battle
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.battle
|
||||
{
|
||||
class BattleActionX18Packet
|
||||
{
|
||||
|
@ -1,9 +1,12 @@
|
||||
using FFXIVClassic_Map_Server.actors;
|
||||
using FFXIVClassic.Common;
|
||||
using FFXIVClassic_Map_Server.actors;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||
{
|
||||
class SetEmoteEventCondition
|
||||
{
|
||||
|
@ -2,7 +2,9 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||
{
|
||||
class SetEventStatus
|
||||
{
|
||||
|
@ -3,7 +3,9 @@ using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||
{
|
||||
class SetNoticeEventCondition
|
||||
{
|
||||
|
@ -3,7 +3,9 @@ using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||
{
|
||||
class SetPushEventConditionWithCircle
|
||||
{
|
||||
|
@ -3,7 +3,9 @@ using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||
{
|
||||
class SetPushEventConditionWithFan
|
||||
{
|
||||
|
@ -3,7 +3,9 @@ using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||
{
|
||||
class SetPushEventConditionWithTriggerBox
|
||||
{
|
||||
|
@ -3,7 +3,9 @@ using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.events
|
||||
{
|
||||
class SetTalkEventCondition
|
||||
{
|
||||
|
@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||
{
|
||||
class EquipmentListX01Packet
|
||||
{
|
||||
|
@ -3,7 +3,9 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||
{
|
||||
class EquipmentListX08Packet
|
||||
{
|
||||
|
@ -3,7 +3,9 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||
{
|
||||
class EquipmentListX16Packet
|
||||
{
|
||||
|
@ -3,7 +3,9 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||
{
|
||||
class EquipmentListX32Packet
|
||||
{
|
||||
|
@ -3,7 +3,9 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||
{
|
||||
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
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -2,7 +2,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||
{
|
||||
class InventoryItemEndPacket
|
||||
{
|
||||
|
@ -2,7 +2,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.Actor.inventory
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||
{
|
||||
class InventoryItemPacket
|
||||
{
|
||||
|
@ -1,7 +1,9 @@
|
||||
using FFXIVClassic_Map_Server.dataobjects;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||
{
|
||||
class InventoryListX01Packet
|
||||
{
|
||||
|
@ -3,7 +3,9 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||
{
|
||||
class InventoryListX08Packet
|
||||
{
|
||||
|
@ -2,7 +2,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_Map_Server.packets.send.actor.inventory
|
||||
{
|
||||
class InventoryListX16Packet
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user