From 8f7e7d4c0d72672db505f676f1cd823203b64c3d Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Sun, 4 Oct 2015 22:43:22 -0400 Subject: [PATCH] Implemented item packets, did some fixes with one of the conns going null. --- .../FFXIVClassic Map Server.csproj | 17 +- FFXIVClassic Map Server/PacketProcessor.cs | 276 +++++++++++++++++- FFXIVClassic Map Server/Program.cs | 22 +- FFXIVClassic Map Server/Server.cs | 20 +- FFXIVClassic Map Server/bin/Debug/config.ini | 6 +- FFXIVClassic Map Server/common/Utils.cs | 1 + ...sic Map Server.csproj.FileListAbsolute.txt | 14 + FFXIVClassic Map Server/packets/BasePacket.cs | 25 ++ 8 files changed, 353 insertions(+), 28 deletions(-) diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj index 21984eaa..9598507e 100644 --- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj +++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj @@ -33,17 +33,21 @@ 4 - + ..\packages\Cyotek.CircularBuffer.1.0.0.0\lib\net20\Cyotek.Collections.Generic.CircularBuffer.dll + True - + ..\packages\Dapper.1.42\lib\net45\Dapper.dll + True - + ..\packages\MySql.Data.6.9.7\lib\net45\MySql.Data.dll + True - + ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + True @@ -65,11 +69,16 @@ + + + + + diff --git a/FFXIVClassic Map Server/PacketProcessor.cs b/FFXIVClassic Map Server/PacketProcessor.cs index a6cae8dc..6d40e112 100644 --- a/FFXIVClassic Map Server/PacketProcessor.cs +++ b/FFXIVClassic Map Server/PacketProcessor.cs @@ -14,17 +14,19 @@ using FFXIVClassic_Map_Server.packets; using FFXIVClassic_Map_Server.packets.receive; using FFXIVClassic_Map_Server.packets.send; using FFXIVClassic_Map_Server.packets.send.login; +using FFXIVClassic_Map_Server.packets.send.Actor.inventory; namespace FFXIVClassic_Lobby_Server { class PacketProcessor { - Dictionary mPlayers = new Dictionary(); + Dictionary mPlayers; List mConnections; Boolean isAlive = true; - public PacketProcessor(List connectionList) + public PacketProcessor(Dictionary playerList, List connectionList) { + mPlayers = playerList; mConnections = connectionList; } @@ -131,6 +133,10 @@ namespace FFXIVClassic_Lobby_Server if (actorID == 0) break; + //Second connection + if (mPlayers.ContainsKey(actorID)) + player = mPlayers[actorID]; + using (MemoryStream mem = new MemoryStream(reply2.data)) { using (BinaryWriter binReader = new BinaryWriter(mem)) @@ -164,7 +170,7 @@ namespace FFXIVClassic_Lobby_Server break; //Ping case 0x0001: - subpacket.debugPrintSubPacket(); + //subpacket.debugPrintSubPacket(); PingPacket pingPacket = new PingPacket(subpacket.data); client.queuePacket(BasePacket.createPacket(PongPacket.buildPacket(player.actorID, pingPacket.time), true, false)); break; @@ -175,22 +181,79 @@ namespace FFXIVClassic_Lobby_Server BasePacket setMapPacket = BasePacket.createPacket(SetMapPacket.buildPacket(player.actorID, 0xD1), true, false); BasePacket setPlayerActorPacket = BasePacket.createPacket(_0x2Packet.buildPacket(player.actorID), true, false); - BasePacket reply5 = new BasePacket("./packets/asd/login5.bin"); - BasePacket reply6 = new BasePacket("./packets/asd/login6_data.bin"); - BasePacket reply7 = new BasePacket("./packets/asd/login7_data.bin"); - BasePacket reply8 = new BasePacket("./packets/asd/login8_data.bin"); - BasePacket reply9 = new BasePacket("./packets/asd/login9_zonesetup.bin"); - BasePacket reply10 = new BasePacket("./packets/asd/login10.bin"); + BasePacket reply5 = new BasePacket("./packets/login/login5.bin"); + BasePacket reply6 = new BasePacket("./packets/login/login6_data.bin"); + BasePacket reply7 = new BasePacket("./packets/login/login7_data.bin"); + BasePacket reply8 = new BasePacket("./packets/login/login8_data.bin"); + BasePacket reply9 = new BasePacket("./packets/login/login9_zonesetup.bin"); + BasePacket reply10 = new BasePacket("./packets/login/login10.bin"); + BasePacket setinv = new BasePacket("./packets/login/inventory_backup.bin"); + BasePacket keyitems = new BasePacket("./packets/login/keyitems.bin"); + BasePacket currancy = new BasePacket("./packets/login/currancy.bin"); + + setinv.replaceActorID(player.actorID); + currancy.replaceActorID(player.actorID); + keyitems.replaceActorID(player.actorID); + + reply5.replaceActorID(player.actorID); + reply6.replaceActorID(player.actorID); + reply7.replaceActorID(player.actorID); + reply8.replaceActorID(player.actorID); + reply9.replaceActorID(player.actorID); client.sendPacketQueue.Add(setMapPacket); client.sendPacketQueue.Add(setPlayerActorPacket); client.sendPacketQueue.Add(reply5); client.sendPacketQueue.Add(reply6); + + + //TEST + List items = new List(); + items.Add(new Item(1337, 8030920, 0)); //Leather Jacket + items.Add(new Item(1338, 8013626, 1)); //Chocobo Mask + items.Add(new Item(1339, 5030402, 2)); //Thyrus + items.Add(new Item(1340, 8013635, 3)); //Dalamud Horn + items.Add(new Item(1341, 10100132, 4)); //Savage Might 4 + + int count = 0; + + items[2].isHighQuality = true; + items[0].durability = 9999; + items[0].spiritbind = 10000; + items[0].materia1 = 6; + items[0].materia2 = 7; + items[0].materia3 = 8; + items[0].materia4 = 9; + items[0].materia5 = 10; + items[1].durability = 9999; + items[2].durability = 0xFFFFFFF; + items[3].durability = 9999; + items[4].quantity = 99; + + //Reused + SubPacket endInventory = InventorySetEndPacket.buildPacket(player.actorID); + SubPacket beginInventory = InventorySetBeginPacket.buildPacket(player.actorID, 200, 00); + SubPacket setInventory = InventoryItemPacket.buildPacket(player.actorID, items, ref count); + + List setinvPackets = new List(); + setinvPackets.Add(beginInventory); + setinvPackets.Add(setInventory); + setinvPackets.Add(endInventory); + + BasePacket setInvBasePacket = BasePacket.createPacket(setinvPackets, true, false); + client.sendPacketQueue.Add(setInvBasePacket); + + + //client.sendPacketQueue.Add(setinv); + //client.sendPacketQueue.Add(currancy); + //client.sendPacketQueue.Add(keyitems); + + client.sendPacketQueue.Add(reply7); client.sendPacketQueue.Add(reply8); client.sendPacketQueue.Add(reply9); - //client.sendPacketQueue.Add(reply10); + client.sendPacketQueue.Add(reply10); break; //Chat Received @@ -212,15 +275,202 @@ namespace FFXIVClassic_Lobby_Server break; case 0x012E: subpacket.debugPrintSubPacket(); - //ProcessScriptResult(subPacket); + processScriptResult(subpacket); break; + case 0x012F: + subpacket.debugPrintSubPacket(); + BasePacket scriptReply = new BasePacket("./packets/charawork2"); + BasePacket scriptReply2 = new BasePacket("./packets/charawork3"); + BasePacket scriptReply3 = new BasePacket("./packets/charawork4"); + client.queuePacket(scriptReply); + client.queuePacket(scriptReply2); + client.queuePacket(scriptReply3); + break; default: Log.debug(String.Format("Unknown command 0x{0:X} received.", subpacket.header.opcode)); subpacket.debugPrintSubPacket(); break; } } - } - + } + + + public void sendPacket(string path, int conn) + { + if (mPlayers.Count == 0) + return; + + BasePacket packet = new BasePacket(path); + + foreach (KeyValuePair entry in mPlayers) + { + packet.replaceActorID(entry.Value.actorID); + if (conn == 1 || conn == 3) + entry.Value.getConnection1().sendPacketQueue.Add(packet); + if (conn == 2 || conn == 3) + entry.Value.getConnection2().sendPacketQueue.Add(packet); + } + } + + public void processScriptResult(SubPacket subpacket) + { + uint someId1 = 0; + uint someId2 = 0; + uint someId3 = 0; + + using (MemoryStream mem = new MemoryStream(subpacket.data)) + { + using (BinaryReader binReader = new BinaryReader(mem)) + { + binReader.BaseStream.Seek(0x2C, SeekOrigin.Begin); + someId1 = binReader.ReadUInt32(); + someId2 = binReader.ReadUInt32(); + someId3 = binReader.ReadUInt32(); + } + } + + Log.info(String.Format("ProcessScriptResult: Id1 = {0}, Id2 = {1}, Id3 = {2}", someId1, someId2, someId3)); + + + } + + /* + public void sendTeleportSequence(ClientConnection client, uint levelId, float x, float y, float z, float angle) + { + BasePacket reply1 = new BasePacket("./packets/move/move1.bin"); + BasePacket reply2 = new BasePacket("./packets/move/move2.bin"); + BasePacket reply3 = new BasePacket("./packets/move/move3.bin"); + BasePacket reply4 = new BasePacket("./packets/move/move4.bin"); + BasePacket reply5 = new BasePacket("./packets/move/move5.bin"); + BasePacket reply6 = new BasePacket("./packets/move/move6.bin"); + BasePacket reply7 = new BasePacket("./packets/move/move7.bin"); + BasePacket reply8 = new BasePacket("./packets/move/move8.bin"); + BasePacket reply9 = new BasePacket("./packets/move/move9.bin"); + + client.queuePacket(reply1); + client.queuePacket(reply2); + client.queuePacket(reply3); + client.queuePacket(reply4); + client.queuePacket(reply5); + client.queuePacket(reply6); + client.queuePacket(reply7); + client.queuePacket(reply8); + client.queuePacket(reply9); + + + { + CCompositePacket result; + + { + CSetMusicPacket packet; + packet.SetSourceId(PLAYER_ID); + packet.SetTargetId(PLAYER_ID); + packet.SetMusicId(zone->backgroundMusicId); + result.AddPacket(packet.ToPacketData()); + } + + { + CSetWeatherPacket packet; + packet.SetSourceId(PLAYER_ID); + packet.SetTargetId(PLAYER_ID); + packet.SetWeatherId(CSetWeatherPacket::WEATHER_CLEAR); + result.AddPacket(packet.ToPacketData()); + } + + { + CSetMapPacket packet; + packet.SetSourceId(PLAYER_ID); + packet.SetTargetId(PLAYER_ID); + packet.SetMapId(levelId); + result.AddPacket(packet.ToPacketData()); + } + + QueuePacket(0, result.ToPacketData()); + } + + QueuePacket(0, PacketData(std::begin(g_client0_moor11), std::end(g_client0_moor11))); + QueuePacket(0, PacketData(std::begin(g_client0_moor12), std::end(g_client0_moor12))); + + { + PacketData outgoingPacket(std::begin(g_client0_moor13), std::end(g_client0_moor13)); + + { + const uint32 setInitialPositionBase = 0x360; + + CSetInitialPositionPacket setInitialPosition; + setInitialPosition.SetSourceId(PLAYER_ID); + setInitialPosition.SetTargetId(PLAYER_ID); + setInitialPosition.SetX(x); + setInitialPosition.SetY(y); + setInitialPosition.SetZ(z); + setInitialPosition.SetAngle(angle); + auto setInitialPositionPacket = setInitialPosition.ToPacketData(); + + memcpy(outgoingPacket.data() + setInitialPositionBase, setInitialPositionPacket.data(), setInitialPositionPacket.size()); + } + + QueuePacket(0, outgoingPacket); + } + + QueuePacket(0, GetInventoryInfo()); + QueuePacket(0, PacketData(std::begin(g_client0_moor21), std::end(g_client0_moor21))); + //QueuePacket(0, PacketData(std::begin(g_client0_moor22), std::end(g_client0_moor22))); + + if(!m_zoneMasterCreated) + { + //Zone Master + QueuePacket(0, PacketData(std::begin(g_client0_moor23), std::end(g_client0_moor23))); + + /* + QueuePacket(0, PacketData(std::begin(g_client0_moor24), std::end(g_client0_moor24))); + QueuePacket(0, PacketData(std::begin(g_client0_moor25), std::end(g_client0_moor25))); + + QueuePacket(0, PacketData(std::begin(g_client0_moor26), std::end(g_client0_moor26))); + QueuePacket(0, PacketData(std::begin(g_client0_moor27), std::end(g_client0_moor27))); + QueuePacket(0, PacketData(std::begin(g_client0_moor28), std::end(g_client0_moor28))); + QueuePacket(0, PacketData(std::begin(g_client0_moor29), std::end(g_client0_moor29))); + + QueuePacket(0, PacketData(std::begin(g_client0_moor30), std::end(g_client0_moor30))); + QueuePacket(0, PacketData(std::begin(g_client0_moor31), std::end(g_client0_moor31))); + + QueuePacket(0, PacketData(std::begin(g_client0_moor32), std::end(g_client0_moor32))); + QueuePacket(0, PacketData(std::begin(g_client0_moor33), std::end(g_client0_moor33))); + QueuePacket(0, PacketData(std::begin(g_client0_moor34), std::end(g_client0_moor34))); + QueuePacket(0, PacketData(std::begin(g_client0_moor35), std::end(g_client0_moor35))); + QueuePacket(0, PacketData(std::begin(g_client0_moor36), std::end(g_client0_moor36))); + QueuePacket(0, PacketData(std::begin(g_client0_moor37), std::end(g_client0_moor37))); + */ + //Enables chat? + // QueuePacket(0, PacketData(std::begin(g_client0_moor38), std::end(g_client0_moor38))); + /* + { + CCompositePacket packet; + packet.AddPacket(PacketData(std::begin(g_client0_moor38), std::end(g_client0_moor38))); + QueuePacket(0, packet.ToPacketData()); + } + + // QueuePacket(0, PacketData(std::begin(g_client0_moor39), std::end(g_client0_moor39))); + + // QueuePacket(0, PacketData(std::begin(g_client0_moor40), std::end(g_client0_moor40))); + + + + m_zoneMasterCreated = true; + } + + if(zone != nullptr) + { + for(const auto& actorInfo : zone->actors) + { + SpawnNpc(actorInfo.id, actorInfo.baseModelId, actorInfo.nameStringId, + std::get<0>(actorInfo.pos), std::get<1>(actorInfo.pos), std::get<2>(actorInfo.pos), 0); + } + } + + m_curMap = levelId; + m_posX = x; + m_posY = y; + m_posZ = z; + }*/ } } diff --git a/FFXIVClassic Map Server/Program.cs b/FFXIVClassic Map Server/Program.cs index 59cf21e7..aaf6d0a1 100644 --- a/FFXIVClassic Map Server/Program.cs +++ b/FFXIVClassic Map Server/Program.cs @@ -7,6 +7,7 @@ using System.Runtime.InteropServices; using MySql.Data.MySqlClient; using System.Reflection; using FFXIVClassic_Lobby_Server.dataobjects; +using System.IO; namespace FFXIVClassic_Lobby_Server { @@ -69,7 +70,26 @@ namespace FFXIVClassic_Lobby_Server Server server = new Server(); server.startServer(); - while (true) Thread.Sleep(10000); + while (true) + { + String input = Console.ReadLine(); + String[] split = input.Split(' '); + + if (split.Length >= 3) + { + if (split[0].Equals("sendpacket")) + { + try{ + server.sendPacket("./packets/" + split[1], Int32.Parse(split[2])); + } + catch (Exception e) + { + Log.error("Could not load packet"); + } + } + } + Thread.Sleep(1000); + } } Console.WriteLine("Press any key to continue..."); diff --git a/FFXIVClassic Map Server/Server.cs b/FFXIVClassic Map Server/Server.cs index 641f57ae..c5039be4 100644 --- a/FFXIVClassic Map Server/Server.cs +++ b/FFXIVClassic Map Server/Server.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using System.Threading; using FFXIVClassic_Lobby_Server.common; using FFXIVClassic_Map_Server.dataobjects; +using FFXIVClassic_Lobby_Server.packets; namespace FFXIVClassic_Lobby_Server { @@ -19,7 +20,7 @@ namespace FFXIVClassic_Lobby_Server private Socket mServerSocket; - private List mConnectedPlayerList = new List(); + private Dictionary mConnectedPlayerList = new Dictionary(); private List mConnectionList = new List(); private PacketProcessor mProcessor; private Thread mProcessorThread; @@ -59,7 +60,7 @@ namespace FFXIVClassic_Lobby_Server Console.WriteLine("{0}:{1}", (mServerSocket.LocalEndPoint as IPEndPoint).Address, (mServerSocket.LocalEndPoint as IPEndPoint).Port); Console.ForegroundColor = ConsoleColor.Gray; - mProcessor = new PacketProcessor(mConnectionList); + mProcessor = new PacketProcessor(mConnectedPlayerList, mConnectionList); mProcessorThread = new Thread(new ThreadStart(mProcessor.update)); mProcessorThread.Start(); return true; @@ -117,16 +118,16 @@ namespace FFXIVClassic_Lobby_Server { lock (mConnectedPlayerList) { - foreach (Player p in mConnectedPlayerList) + foreach (KeyValuePair p in mConnectedPlayerList) { - if ((p.getConnection1().socket.RemoteEndPoint as IPEndPoint).Address.Equals((s.RemoteEndPoint as IPEndPoint).Address)) + if ((p.Value.getConnection1().socket.RemoteEndPoint as IPEndPoint).Address.Equals((s.RemoteEndPoint as IPEndPoint).Address)) { - return p; + return p.Value; } - if ((p.getConnection2().socket.RemoteEndPoint as IPEndPoint).Address.Equals((s.RemoteEndPoint as IPEndPoint).Address)) + if ((p.Value.getConnection2().socket.RemoteEndPoint as IPEndPoint).Address.Equals((s.RemoteEndPoint as IPEndPoint).Address)) { - return p; + return p.Value; } } } @@ -179,5 +180,10 @@ namespace FFXIVClassic_Lobby_Server #endregion + + public void sendPacket(string path, int conn) + { + mProcessor.sendPacket(path, conn); + } } } diff --git a/FFXIVClassic Map Server/bin/Debug/config.ini b/FFXIVClassic Map Server/bin/Debug/config.ini index ba5e1230..d2f74d77 100644 --- a/FFXIVClassic Map Server/bin/Debug/config.ini +++ b/FFXIVClassic Map Server/bin/Debug/config.ini @@ -1,10 +1,10 @@ [General] -server_ip=141.117.161.40 +server_ip=127.0.0.1 showtimestamp = true [Database] -worldid=1 -host="141.117.162.99" +worldid=3 +host=162.243.47.196 port=3306 database="ffxiv_server" username="root" diff --git a/FFXIVClassic Map Server/common/Utils.cs b/FFXIVClassic Map Server/common/Utils.cs index d899f6ef..e0b6db91 100644 --- a/FFXIVClassic Map Server/common/Utils.cs +++ b/FFXIVClassic Map Server/common/Utils.cs @@ -52,6 +52,7 @@ namespace FFXIVClassic_Lobby_Server.common DateTime zuluTime = currentTime.ToUniversalTime(); DateTime unixEpoch = new DateTime(1970, 1, 1); unixTimeStamp = (UInt32)(zuluTime.Subtract(unixEpoch)).TotalSeconds; + return unixTimeStamp; } diff --git a/FFXIVClassic Map Server/obj/Debug/FFXIVClassic Map Server.csproj.FileListAbsolute.txt b/FFXIVClassic Map Server/obj/Debug/FFXIVClassic Map Server.csproj.FileListAbsolute.txt index 852374ea..fc10e695 100644 --- a/FFXIVClassic Map Server/obj/Debug/FFXIVClassic Map Server.csproj.FileListAbsolute.txt +++ b/FFXIVClassic Map Server/obj/Debug/FFXIVClassic Map Server.csproj.FileListAbsolute.txt @@ -12,3 +12,17 @@ c:\users\filip\documents\visual studio 2013\Projects\FFXIVClassic Map Server\FFX c:\users\filip\documents\visual studio 2013\Projects\FFXIVClassic Map Server\FFXIVClassic Map Server\bin\Debug\Newtonsoft.Json.xml c:\users\filip\documents\visual studio 2013\Projects\FFXIVClassic Map Server\FFXIVClassic Map Server\obj\Debug\FFXIVClassic Map Server.exe c:\users\filip\documents\visual studio 2013\Projects\FFXIVClassic Map Server\FFXIVClassic Map Server\obj\Debug\FFXIVClassic Map Server.pdb +C:\Users\Filip\coding\ffxiv-classic-map-server\FFXIVClassic Map Server\bin\Debug\FFXIVClassic Map Server.exe.config +C:\Users\Filip\coding\ffxiv-classic-map-server\FFXIVClassic Map Server\obj\Debug\FFXIVClassic Map Server.csprojResolveAssemblyReference.cache +C:\Users\Filip\coding\ffxiv-classic-map-server\FFXIVClassic Map Server\bin\Debug\FFXIVClassic Map Server.exe +C:\Users\Filip\coding\ffxiv-classic-map-server\FFXIVClassic Map Server\bin\Debug\FFXIVClassic Map Server.pdb +C:\Users\Filip\coding\ffxiv-classic-map-server\FFXIVClassic Map Server\bin\Debug\Cyotek.Collections.Generic.CircularBuffer.dll +C:\Users\Filip\coding\ffxiv-classic-map-server\FFXIVClassic Map Server\bin\Debug\Dapper.dll +C:\Users\Filip\coding\ffxiv-classic-map-server\FFXIVClassic Map Server\bin\Debug\MySql.Data.dll +C:\Users\Filip\coding\ffxiv-classic-map-server\FFXIVClassic Map Server\bin\Debug\Newtonsoft.Json.dll +C:\Users\Filip\coding\ffxiv-classic-map-server\FFXIVClassic Map Server\bin\Debug\Cyotek.Collections.Generic.CircularBuffer.xml +C:\Users\Filip\coding\ffxiv-classic-map-server\FFXIVClassic Map Server\bin\Debug\Dapper.pdb +C:\Users\Filip\coding\ffxiv-classic-map-server\FFXIVClassic Map Server\bin\Debug\Dapper.xml +C:\Users\Filip\coding\ffxiv-classic-map-server\FFXIVClassic Map Server\bin\Debug\Newtonsoft.Json.xml +C:\Users\Filip\coding\ffxiv-classic-map-server\FFXIVClassic Map Server\obj\Debug\FFXIVClassic Map Server.exe +C:\Users\Filip\coding\ffxiv-classic-map-server\FFXIVClassic Map Server\obj\Debug\FFXIVClassic Map Server.pdb diff --git a/FFXIVClassic Map Server/packets/BasePacket.cs b/FFXIVClassic Map Server/packets/BasePacket.cs index c7ca383b..cf4c192f 100644 --- a/FFXIVClassic Map Server/packets/BasePacket.cs +++ b/FFXIVClassic Map Server/packets/BasePacket.cs @@ -28,6 +28,7 @@ namespace FFXIVClassic_Lobby_Server.packets public BasePacketHeader header; public byte[] data; + //Loads a sniffed packet from a file public unsafe BasePacket(String path) { byte[] bytes = File.ReadAllBytes(path); @@ -49,6 +50,7 @@ namespace FFXIVClassic_Lobby_Server.packets Array.Copy(bytes, BASEPACKET_SIZE, data, 0, packetSize - BASEPACKET_SIZE); } + //Loads a sniffed packet from a byte array public unsafe BasePacket(byte[] bytes) { if (bytes.Length < BASEPACKET_SIZE) @@ -141,6 +143,29 @@ namespace FFXIVClassic_Lobby_Server.packets return outBytes; } + //Replaces all instances of the sniffed actorID with the given one + public void replaceActorID(uint actorID) + { + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + using (BinaryReader binreader = new BinaryReader(mem)) + { + while (binreader.BaseStream.Position + 4 < data.Length) + { + uint read = binreader.ReadUInt32(); + if (read == 0x029B2941) //Original ID + { + binWriter.BaseStream.Seek(binreader.BaseStream.Position - 0x4, SeekOrigin.Begin); + binWriter.Write(actorID); + } + } + } + } + } + } + #region Utility Functions public static BasePacket createPacket(List subpackets, bool isAuthed, bool isEncrypted) {