From 9a9388aabf697d46dba9574334782c2099969c0b Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Sun, 11 Oct 2015 14:57:24 -0400 Subject: [PATCH] Figured out a lot of the 19X and 1AX packets. Adding test packet data used in experiments. --- .../FFXIVClassic Map Server.csproj | 7 + FFXIVClassic Map Server/PacketProcessor.cs | 5 +- .../bin/Debug/packets/d0packet | Bin 184 -> 184 bytes .../bin/Debug/packets/deleteplayer | Bin 0 -> 56 bytes .../bin/Debug/packets/login/login7_data.bin | Bin 2744 -> 2080 bytes .../bin/Debug/packets/login/login7_data2.bin | Bin 0 -> 2704 bytes .../bin/Debug/packets/login7_data.bin | Bin 0 -> 2744 bytes .../bin/Debug/packets/move_player | Bin 0 -> 96 bytes .../bin/Debug/packets/move_player2 | Bin 0 -> 96 bytes .../bin/Debug/packets/music.bin | Bin 56 -> 56 bytes .../bin/Debug/packets/test | Bin 0 -> 80 bytes .../bin/Debug/packets/test_player | Bin 0 -> 1824 bytes .../bin/Debug/packets/test_player2 | Bin 0 -> 1824 bytes .../send/Actor/MoveActorToPositionPacket.cs | 14 +- .../packets/send/Actor/SetActorTarget.cs | 20 +++ .../send/player/CutsceneBookSetPacket.cs | 167 ++++++++++++++++++ .../send/player/SetChocoboNamePacket.cs | 22 +++ .../packets/send/player/SetGCInfoPacket.cs | 12 ++ .../player/SetLatestAchievementsPacket.cs | 23 +++ .../send/player/SetPlayerTitlePacket.cs | 20 +++ 20 files changed, 283 insertions(+), 7 deletions(-) create mode 100644 FFXIVClassic Map Server/bin/Debug/packets/deleteplayer create mode 100644 FFXIVClassic Map Server/bin/Debug/packets/login/login7_data2.bin create mode 100644 FFXIVClassic Map Server/bin/Debug/packets/login7_data.bin create mode 100644 FFXIVClassic Map Server/bin/Debug/packets/move_player create mode 100644 FFXIVClassic Map Server/bin/Debug/packets/move_player2 create mode 100644 FFXIVClassic Map Server/bin/Debug/packets/test create mode 100644 FFXIVClassic Map Server/bin/Debug/packets/test_player create mode 100644 FFXIVClassic Map Server/bin/Debug/packets/test_player2 create mode 100644 FFXIVClassic Map Server/packets/send/Actor/SetActorTarget.cs create mode 100644 FFXIVClassic Map Server/packets/send/player/CutsceneBookSetPacket.cs create mode 100644 FFXIVClassic Map Server/packets/send/player/SetChocoboNamePacket.cs create mode 100644 FFXIVClassic Map Server/packets/send/player/SetGCInfoPacket.cs create mode 100644 FFXIVClassic Map Server/packets/send/player/SetLatestAchievementsPacket.cs create mode 100644 FFXIVClassic Map Server/packets/send/player/SetPlayerTitlePacket.cs diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj index 24cd9ea4..5250028a 100644 --- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj +++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj @@ -92,12 +92,19 @@ + + + + + + + diff --git a/FFXIVClassic Map Server/PacketProcessor.cs b/FFXIVClassic Map Server/PacketProcessor.cs index bdb62d47..2c0e02dd 100644 --- a/FFXIVClassic Map Server/PacketProcessor.cs +++ b/FFXIVClassic Map Server/PacketProcessor.cs @@ -293,7 +293,7 @@ namespace FFXIVClassic_Lobby_Server client.queuePacket(reply8); client.queuePacket(reply9); client.queuePacket(reply10); - client.queuePacket(reply11); + //client.queuePacket(reply11); client.queuePacket(reply12); break; //Chat Received @@ -309,6 +309,7 @@ namespace FFXIVClassic_Lobby_Server case 0x00CD: SetTargetPacket setTarget = new SetTargetPacket(subpacket.data); player.setTarget(setTarget.actorID); + client.queuePacket(BasePacket.createPacket(SetActorTarget.buildPacket(player.actorID, player.actorID, setTarget.actorID), true, false)); break; //Lock Target case 0x00CC: @@ -350,7 +351,7 @@ namespace FFXIVClassic_Lobby_Server return; BasePacket packet = new BasePacket(path); - + foreach (KeyValuePair entry in mPlayers) { packet.replaceActorID(entry.Value.actorID); diff --git a/FFXIVClassic Map Server/bin/Debug/packets/d0packet b/FFXIVClassic Map Server/bin/Debug/packets/d0packet index ee17c877a0778e6d6330212b2e1e439b1efa99ef..3f76e7836e7d23cd6c71ab4d0745258e76d4ebcb 100644 GIT binary patch delta 19 bcmdnNxPx(m7qfvQ^TfdTi3uzdH*f#|K8yxK delta 19 bcmdnNxPx(m7qfsP^TfdTi3uzdH*f#|Jq!jT diff --git a/FFXIVClassic Map Server/bin/Debug/packets/deleteplayer b/FFXIVClassic Map Server/bin/Debug/packets/deleteplayer new file mode 100644 index 0000000000000000000000000000000000000000..6fbfdd6d4d3835d0d3b8bbb2fc57ca9f429dac94 GIT binary patch literal 56 zcmZQ%U|_IdU}O-J?tW*@$iSe%z|3%2eKwP$=4>X02bcbdFq{UeU|@J5`!E1RUseN( G0|5X}aMYa51i}mtF8vc>m^U9N v%wX~2K>&zOo7kw%&&t5bAOM6Az&P={ChLEo?*EfnnUtCSGi+YOEXEE1SA!Qz delta 574 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 YrQjM@`XK*e4Yhom8x$8iyPG=y1|vX^b^rhX literal 0 HcmV?d00001 diff --git a/FFXIVClassic Map Server/bin/Debug/packets/move_player b/FFXIVClassic Map Server/bin/Debug/packets/move_player new file mode 100644 index 0000000000000000000000000000000000000000..433e2de6e1fef629ecce0eacbd763887750ad29d GIT binary patch literal 96 zcmZQ%U|>jKU}O-J?tW*@$iNW5z|3%2eKwP$=4>X02bcbdFq{XfU|{f(ei#5|Knbqv X^3KM_#`dk+>dt4+`0PWLLuLa2l!y>L literal 0 HcmV?d00001 diff --git a/FFXIVClassic Map Server/bin/Debug/packets/move_player2 b/FFXIVClassic Map Server/bin/Debug/packets/move_player2 new file mode 100644 index 0000000000000000000000000000000000000000..6f057d946ef62ca3546f3b9352ba541677f1e46e GIT binary patch literal 96 zcmZQ%U|>jKU}O-J?tW*@$iNW5z|3%2eKwP$=4>X02bcbdFq{XfU|{f(ei#5|K#7OH Y{oy_)pc&Wz0O@=Zp8x;= literal 0 HcmV?d00001 diff --git a/FFXIVClassic Map Server/bin/Debug/packets/music.bin b/FFXIVClassic Map Server/bin/Debug/packets/music.bin index 77fa4332bd7d0e7aef569da293237f27b192f948..56742acc11ce2f8f5eee42f9e53a782089550584 100644 GIT binary patch delta 13 RcmcDpm|(ym!obJ?0ssz!0Zsq_ delta 13 RcmcDpm|(ym%D~6~0ssz+0Z#w` diff --git a/FFXIVClassic Map Server/bin/Debug/packets/test b/FFXIVClassic Map Server/bin/Debug/packets/test new file mode 100644 index 0000000000000000000000000000000000000000..e7f841b8bc6d935e74bc61c6e91d976e2a43e34a GIT binary patch literal 80 zcmZQ%U|Cji5S<3XKmtT# F0|0*041xdv literal 0 HcmV?d00001 diff --git a/FFXIVClassic Map Server/bin/Debug/packets/test_player b/FFXIVClassic Map Server/bin/Debug/packets/test_player new file mode 100644 index 0000000000000000000000000000000000000000..a8d6db195967d7d682365201a3469e17daede90e GIT binary patch literal 1824 zcmZQ%U|>*S7hw>S?tW*@$iSe%z|3%2eKwP$=4>X02bcbdFq{IaU|@J5`!E1RbASjS zSb?GL0$3cT4$OfN4nSjpV1WY@lx7Cgv?W-e#(QA6^Bh29O*-5VL~#EC*QFfHb4P z2S#=v4FWJTI3ZjHE-1|nrFnpKq5=a0FOXIQa`=FBlLo|05MKZ)E(oL<-Y_xd(SdFc!bb8~0M*VjEdT%j literal 0 HcmV?d00001 diff --git a/FFXIVClassic Map Server/bin/Debug/packets/test_player2 b/FFXIVClassic Map Server/bin/Debug/packets/test_player2 new file mode 100644 index 0000000000000000000000000000000000000000..a729c2b7b16a5ffc3aaf8f9f947b3ded1e13261d GIT binary patch literal 1824 zcmZQ%U|>*S7hw>S?tW*@$iSe%z|3%2eKwP$=4>X02bcbdFq{IaU|@J5`!E1RbASjS zSb?GL0$3cT4$OfN4nSjpV1WY@lx7Cgv?W-e#(QA6^Bh29O*-5VL~#EC*QFfHb4P z2S#=v4FWJTI3ZjHE-1|nrFnpKq5=a0FOXIQa`=FBlLo|05MKZ)E(oL<-Y_xSc#I*P-GbxnDm`95{nY`A?l!1e0hFRHUkR?Fhi0cny$gcU4fBr%u&L# zmT~{mt-M@JvQuX4iC|>;p8M^s_eu}?gwm)D(8$!nHe9S_mALW>M&)SCe6T- z{nVvrlH$Vvmc_ZoJ^z7KN1A?oW?p6qBCH6x)0SnYaab;>v|#a4J$e<)IO_6<5zJV! c;eP;_v9>Y75zP3P+n5MqbfDXVu#r3#0LX7NIsgCw literal 0 HcmV?d00001 diff --git a/FFXIVClassic Map Server/packets/send/Actor/MoveActorToPositionPacket.cs b/FFXIVClassic Map Server/packets/send/Actor/MoveActorToPositionPacket.cs index a4e71fd4..a869e1ea 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/MoveActorToPositionPacket.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/MoveActorToPositionPacket.cs @@ -11,9 +11,9 @@ namespace FFXIVClassic_Map_Server.packets.send.actor class MoveActorToPositionPacket { public const ushort OPCODE = 0x00CF; - public const uint PACKET_SIZE = 0x48; + public const uint PACKET_SIZE = 0x50; - public static SubPacket buildPacket(uint playerActorID, uint actorID) + public static SubPacket buildPacket(uint playerActorID, uint targetActorID, float x, float y, float z, float rot, ushort moveState) { byte[] data = new byte[PACKET_SIZE - 0x20]; @@ -21,12 +21,16 @@ namespace FFXIVClassic_Map_Server.packets.send.actor { using (BinaryWriter binWriter = new BinaryWriter(mem)) { - + binWriter.BaseStream.Seek(0x8, SeekOrigin.Begin); + binWriter.Write((Single)x); + binWriter.Write((Single)y); + binWriter.Write((Single)z); + binWriter.Write((Single)rot); + binWriter.Write((ushort)moveState); } - data = mem.GetBuffer(); } - SubPacket packet = new SubPacket(OPCODE, playerActorID, actorID, data); + SubPacket packet = new SubPacket(OPCODE, playerActorID, targetActorID, data); return packet; } diff --git a/FFXIVClassic Map Server/packets/send/Actor/SetActorTarget.cs b/FFXIVClassic Map Server/packets/send/Actor/SetActorTarget.cs new file mode 100644 index 00000000..6d86b3f4 --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/Actor/SetActorTarget.cs @@ -0,0 +1,20 @@ +using FFXIVClassic_Lobby_Server.packets; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.packets.send.actor +{ + class SetActorTarget + { + public const ushort OPCODE = 0x00DB; + public const uint PACKET_SIZE = 0x28; + + public static SubPacket buildPacket(uint playerActorID, uint targetActorID, uint targetID) + { + return new SubPacket(OPCODE, playerActorID, targetID, BitConverter.GetBytes((ulong)targetID)); + } + } +} diff --git a/FFXIVClassic Map Server/packets/send/player/CutsceneBookSetPacket.cs b/FFXIVClassic Map Server/packets/send/player/CutsceneBookSetPacket.cs new file mode 100644 index 00000000..b0cf66b9 --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/player/CutsceneBookSetPacket.cs @@ -0,0 +1,167 @@ +using FFXIVClassic_Lobby_Server.packets; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.packets.send.player +{ + class CutsceneBookSetPacket + { + public const ushort OPCODE = 0x01A3; + public const uint PACKET_SIZE = 0150; + + private byte[] mainstoryFlags = new byte[7]; + private byte[] classFlags = new byte[2*17]; + + public static SubPacket buildPacket(uint playerActorID) + { + byte[] data = new byte[PACKET_SIZE - 0x20]; + + byte currentOut = 0; + int byteIndex = 0; + int currentBit = 0; + + //Main Scenario + for (int i = 0; i < 60; i++) + { + currentOut = (byte) (1|(currentOut << currentBit)); + currentBit++; + + if (currentBit >= 8) + { + currentBit = 0; + data[byteIndex] = currentOut; + byteIndex++; + currentOut = 0; + } + } + + //Classes + for (int i = 0; i < 340; i++) + { + currentOut = (byte)(1 | (currentOut << currentBit)); + currentBit++; + + if (currentBit >= 8) + { + currentBit = 0; + data[byteIndex] = currentOut; + byteIndex++; + currentOut = 0; + } + } + + //GAP + for (int i = 0; i < 60; i++) + { + currentBit++; + if (currentBit >= 8) + { + currentBit = 0; + byteIndex++; + } + } + + //Side Quests + for (int i = 0; i < 372; i++) + { + currentOut = (byte)(1 | (currentOut << currentBit)); + currentBit++; + + if (currentBit >= 8) + { + currentBit = 0; + data[byteIndex] = currentOut; + byteIndex++; + currentOut = 0; + } + } + + //GAP + for (int i = 0; i < 228; i++) + { + currentBit++; + if (currentBit >= 8) + { + currentBit = 0; + byteIndex++; + } + } + + //Jobs + for (int i = 0; i < 140; i++) + { + currentOut = (byte)(1 | (currentOut << currentBit)); + currentBit++; + + if (currentBit >= 8) + { + currentBit = 0; + data[byteIndex] = currentOut; + byteIndex++; + currentOut = 0; + } + } + + //GAP + for (int i = 0; i < 61; i++) + { + currentBit++; + if (currentBit >= 8) + { + currentBit = 0; + byteIndex++; + } + } + + //Maelstrom + for (int i = 0; i < 200; i++) + { + currentOut = (byte)(1 | (currentOut << currentBit)); + currentBit++; + + if (currentBit >= 8) + { + currentBit = 0; + data[byteIndex] = currentOut; + byteIndex++; + currentOut = 0; + } + } + + //Adders + for (int i = 0; i < 200; i++) + { + currentOut = (byte)(1 | (currentOut << currentBit)); + currentBit++; + + if (currentBit >= 8) + { + currentBit = 0; + data[byteIndex] = currentOut; + byteIndex++; + currentOut = 0; + } + } + + //Flames + for (int i = 0; i < 200; i++) + { + currentOut = (byte)(1 | (currentOut << currentBit)); + currentBit++; + + if (currentBit >= 8) + { + currentBit = 0; + data[byteIndex] = currentOut; + byteIndex++; + currentOut = 0; + } + } + + return new SubPacket(OPCODE, playerActorID, playerActorID, data); + } + } +} diff --git a/FFXIVClassic Map Server/packets/send/player/SetChocoboNamePacket.cs b/FFXIVClassic Map Server/packets/send/player/SetChocoboNamePacket.cs new file mode 100644 index 00000000..3ef9833d --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/player/SetChocoboNamePacket.cs @@ -0,0 +1,22 @@ +using FFXIVClassic_Lobby_Server.packets; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.packets.send.player +{ + class SetChocoboNamePacket + { + public const ushort OPCODE = 0x0198; + public const uint PACKET_SIZE = 0x40; + + public static SubPacket buildPacket(uint playerActorID, uint targetActorID, string name) + { + if (Encoding.Unicode.GetByteCount(name) >= 0x20) + name = "ERR: Too Long"; + return new SubPacket(OPCODE, playerActorID, targetActorID, Encoding.Unicode.GetBytes(name)); + } + } +} diff --git a/FFXIVClassic Map Server/packets/send/player/SetGCInfoPacket.cs b/FFXIVClassic Map Server/packets/send/player/SetGCInfoPacket.cs new file mode 100644 index 00000000..62d2c294 --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/player/SetGCInfoPacket.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.packets.send.player +{ + class SetGCInfoPacket + { + } +} diff --git a/FFXIVClassic Map Server/packets/send/player/SetLatestAchievementsPacket.cs b/FFXIVClassic Map Server/packets/send/player/SetLatestAchievementsPacket.cs new file mode 100644 index 00000000..25c4156f --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/player/SetLatestAchievementsPacket.cs @@ -0,0 +1,23 @@ +using FFXIVClassic_Lobby_Server.packets; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.packets.send.player +{ + class SetLatestAchievementsPacket + { + public const ushort OPCODE = 0x01A3; + public const uint PACKET_SIZE = 0150; + + private byte[] mainstoryFlags = new byte[7]; + private byte[] classFlags = new byte[2*17]; + + public static SubPacket buildPacket(uint playerActorID) + { + return null; + } + } +} diff --git a/FFXIVClassic Map Server/packets/send/player/SetPlayerTitlePacket.cs b/FFXIVClassic Map Server/packets/send/player/SetPlayerTitlePacket.cs new file mode 100644 index 00000000..a019c97e --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/player/SetPlayerTitlePacket.cs @@ -0,0 +1,20 @@ +using FFXIVClassic_Lobby_Server.packets; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.packets.send.player +{ + class SetPlayerTitlePacket + { + public const ushort OPCODE = 0x019D; + public const uint PACKET_SIZE = 0x28; + + public static SubPacket buildPacket(uint playerActorID, uint targetActorID, uint titleID) + { + return new SubPacket(OPCODE, playerActorID, targetActorID, BitConverter.GetBytes((ulong)titleID)); + } + } +}