From cfb29b912fee3ee850584011949bb416e6077c79 Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Tue, 2 Feb 2016 00:02:06 -0500 Subject: [PATCH] Speed is now stored in the actor. Redid actor speed packet to use float. Added GameMessagePacket which can use all 20 msg packets. Added functions for lua side to call in player obj. --- .../FFXIVClassic Map Server.csproj | 1 + FFXIVClassic Map Server/actors/Actor.cs | 30 ++ FFXIVClassic Map Server/actors/area/Zone.cs | 17 + .../actors/chara/player/Player.cs | 28 +- FFXIVClassic Map Server/packets/SubPacket.cs | 11 + .../packets/send/Actor/SetActorSpeedPacket.cs | 33 +- .../packets/send/GameMessagePacket.cs | 346 ++++++++++++++++++ 7 files changed, 445 insertions(+), 21 deletions(-) create mode 100644 FFXIVClassic Map Server/packets/send/GameMessagePacket.cs diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj index a1e692a2..6b81af4d 100644 --- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj +++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj @@ -147,6 +147,7 @@ + diff --git a/FFXIVClassic Map Server/actors/Actor.cs b/FFXIVClassic Map Server/actors/Actor.cs index b56f0dfc..b71b618c 100644 --- a/FFXIVClassic Map Server/actors/Actor.cs +++ b/FFXIVClassic Map Server/actors/Actor.cs @@ -29,6 +29,7 @@ namespace FFXIVClassic_Map_Server.Actors public float positionX, positionY, positionZ, rotation; public float oldPositionX, oldPositionY, oldPositionZ, oldRotation; public ushort moveState, oldMoveState; + public float[] moveSpeeds = new float[5]; public uint zoneId; public Zone zone = null; @@ -52,6 +53,11 @@ namespace FFXIVClassic_Map_Server.Actors this.actorName = actorName; this.className = className; this.classParams = classParams; + + this.moveSpeeds[0] = SetActorSpeedPacket.DEFAULT_STOP; + this.moveSpeeds[1] = SetActorSpeedPacket.DEFAULT_WALK; + this.moveSpeeds[2] = SetActorSpeedPacket.DEFAULT_RUN; + this.moveSpeeds[3] = SetActorSpeedPacket.DEFAULT_RUN; } public SubPacket createAddActorPacket(uint playerActorId, byte val) @@ -220,6 +226,30 @@ namespace FFXIVClassic_Map_Server.Actors return classParams; } + public void changeState(ushort newState) + { + currentMainState = newState; + SubPacket changeStatePacket = SetActorStatePacket.buildPacket(actorId, actorId, newState, currentSubState); + zone.broadcastPacketAroundActor(this, changeStatePacket); + } + + public void changeSpeed(int type, float value) + { + moveSpeeds[type] = value; + SubPacket changeSpeedPacket = SetActorSpeedPacket.buildPacket(actorId, actorId, moveSpeeds[0], moveSpeeds[1], moveSpeeds[2]); + zone.broadcastPacketAroundActor(this, changeSpeedPacket); + } + + public void changeSpeed(float speedStop, float speedWalk, float speedRun) + { + moveSpeeds[0] = speedStop; + moveSpeeds[1] = speedWalk; + moveSpeeds[2] = speedRun; + moveSpeeds[3] = speedRun; + SubPacket changeSpeedPacket = SetActorSpeedPacket.buildPacket(actorId, actorId, moveSpeeds[0], moveSpeeds[1], moveSpeeds[2]); + zone.broadcastPacketAroundActor(this, changeSpeedPacket); + } + } } diff --git a/FFXIVClassic Map Server/actors/area/Zone.cs b/FFXIVClassic Map Server/actors/area/Zone.cs index c984468a..147e9cb2 100644 --- a/FFXIVClassic Map Server/actors/area/Zone.cs +++ b/FFXIVClassic Map Server/actors/area/Zone.cs @@ -289,5 +289,22 @@ namespace FFXIVClassic_Map_Server.Actors } } + public void broadcastPacketAroundActor(Actor actor, SubPacket packet) + { + if (zone != null) + { + List aroundActor = getActorsAroundActor(actor, 50); + foreach (Actor a in aroundActor) + { + if (a is Player) + { + SubPacket clonedPacket = new SubPacket(packet, actor.actorId); + Player p = (Player)a; + p.queuePacket(clonedPacket); + } + } + } + } + } } diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs index 25df3340..c909a770 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Player.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs @@ -598,7 +598,7 @@ namespace FFXIVClassic_Map_Server.Actors { playerSession.queuePacket(packet, true, false); } - + public void sendMessage(uint logType, string sender, string message) { queuePacket(SendMessagePacket.buildPacket(actorId, actorId, logType, sender, message)); @@ -614,6 +614,32 @@ namespace FFXIVClassic_Map_Server.Actors queuePacket(QuitPacket.buildPacket(actorId)); } + public void changeMusic(ushort musicId) + { + queuePacket(SetMusicPacket.buildPacket(actorId, musicId, 1)); + } + + public void sendChocoboAppearance() + { + queuePacket(SetCurrentMountChocoboPacket.buildPacket(actorId, chocoboAppearance)); + } + + public void sendGoobbueAppearance() + { + queuePacket(SetCurrentMountGoobbuePacket.buildPacket(actorId, 1)); + } + + public void sendWorldMessage(ushort worldMasterId, params object[] msgParams) + { + //queuePacket(WorldMasterPacket.buildPacket()); + } + + public void broadcastWorldMessage(ushort worldMasterId, params object[] msgParams) + { + //SubPacket worldMasterMessage = + //zone.broadcastPacketAroundActor(this, worldMasterMessage); + } + public void runEventFunction(string functionName, params object[] parameters) { List lParams = LuaUtils.createLuaParamList(parameters); diff --git a/FFXIVClassic Map Server/packets/SubPacket.cs b/FFXIVClassic Map Server/packets/SubPacket.cs index 8ef5c83d..87231156 100644 --- a/FFXIVClassic Map Server/packets/SubPacket.cs +++ b/FFXIVClassic Map Server/packets/SubPacket.cs @@ -95,6 +95,17 @@ namespace FFXIVClassic_Lobby_Server.packets header.subpacketSize = (ushort)(SUBPACKET_SIZE + GAMEMESSAGE_SIZE + data.Length); } + public SubPacket(SubPacket original, uint newTargetId) + { + this.header = new SubPacketHeader(); + this.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() { int size = Marshal.SizeOf(header); diff --git a/FFXIVClassic Map Server/packets/send/Actor/SetActorSpeedPacket.cs b/FFXIVClassic Map Server/packets/send/Actor/SetActorSpeedPacket.cs index 2fed0ebc..a1f388c7 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/SetActorSpeedPacket.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/SetActorSpeedPacket.cs @@ -13,9 +13,9 @@ namespace FFXIVClassic_Map_Server.packets.send.actor public const ushort OPCODE = 0x00D0; public const uint PACKET_SIZE = 0xA8; - public const ushort DEFAULT_STOP = 0x0000; - public const ushort DEFAULT_WALK = 0x4000; - public const ushort DEFAULT_RUN = 0x40A0; + public const float DEFAULT_STOP = 0.0f; + public const float DEFAULT_WALK = 2.0f; + public const float DEFAULT_RUN = 5.0f; public static SubPacket buildPacket(uint playerActorID, uint targetActorID) { @@ -25,20 +25,16 @@ namespace FFXIVClassic_Map_Server.packets.send.actor { using (BinaryWriter binWriter = new BinaryWriter(mem)) { - binWriter.Write((UInt16)00); - binWriter.Write((UInt16)DEFAULT_STOP); + binWriter.Write((Single)DEFAULT_STOP); binWriter.Write((UInt32)0); - binWriter.Write((UInt16)00); - binWriter.Write((UInt16)DEFAULT_WALK); + binWriter.Write((Single)DEFAULT_WALK); binWriter.Write((UInt32)1); - binWriter.Write((UInt16)00); - binWriter.Write((UInt16)DEFAULT_RUN); + binWriter.Write((Single)DEFAULT_RUN); binWriter.Write((UInt32)2); - binWriter.Write((UInt16)00); - binWriter.Write((UInt16)DEFAULT_RUN); + binWriter.Write((Single)DEFAULT_RUN); binWriter.Write((UInt32)3); binWriter.BaseStream.Seek(0x80, SeekOrigin.Begin); @@ -50,7 +46,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor return new SubPacket(OPCODE, playerActorID, targetActorID, data); } - public static SubPacket buildPacket(uint playerActorID, uint targetActorID, ushort stopSpeed, ushort walkSpeed, ushort runSpeed) + public static SubPacket buildPacket(uint playerActorID, uint targetActorID, float stopSpeed, float walkSpeed, float runSpeed) { byte[] data = new byte[PACKET_SIZE - 0x20]; @@ -58,20 +54,17 @@ namespace FFXIVClassic_Map_Server.packets.send.actor { using (BinaryWriter binWriter = new BinaryWriter(mem)) { - binWriter.Write((UInt16)00); - binWriter.Write((UInt16)stopSpeed); + binWriter.Write((Single)stopSpeed); binWriter.Write((UInt32)0); - binWriter.Write((UInt16)00); - binWriter.Write((UInt16)walkSpeed); + binWriter.Write((Single)walkSpeed); binWriter.Write((UInt32)1); binWriter.Write((UInt16)00); - binWriter.Write((UInt16)runSpeed); + binWriter.Write((Single)runSpeed); binWriter.Write((UInt32)2); - - binWriter.Write((UInt16)00); - binWriter.Write((UInt16)runSpeed); + + binWriter.Write((Single)runSpeed); binWriter.Write((UInt32)3); binWriter.BaseStream.Seek(0x90, SeekOrigin.Begin); diff --git a/FFXIVClassic Map Server/packets/send/GameMessagePacket.cs b/FFXIVClassic Map Server/packets/send/GameMessagePacket.cs new file mode 100644 index 00000000..ba05abad --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/GameMessagePacket.cs @@ -0,0 +1,346 @@ +using FFXIVClassic_Lobby_Server.packets; +using FFXIVClassic_Map_Server.lua; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.packets.send +{ + class GameMessagePacket + { + public const ushort OPCODE_GAMEMESSAGE_WITH_ACTOR1 = 0x157; + public const ushort OPCODE_GAMEMESSAGE_WITH_ACTOR2 = 0x158; + public const ushort OPCODE_GAMEMESSAGE_WITH_ACTOR3 = 0x159; + public const ushort OPCODE_GAMEMESSAGE_WITH_ACTOR4 = 0x15a; + public const ushort OPCODE_GAMEMESSAGE_WITH_ACTOR5 = 0x15b; + + public const ushort OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER1 = 0x15c; + public const ushort OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER2 = 0x15d; + public const ushort OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER3 = 0x15e; + public const ushort OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER4 = 0x15f; + public const ushort OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER5 = 0x160; + + public const ushort OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER1 = 0x161; + public const ushort OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER2 = 0x162; + public const ushort OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER3 = 0x163; + public const ushort OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER4 = 0x164; + public const ushort OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER5 = 0x165; + + public const ushort OPCODE_GAMEMESSAGE_WITHOUT_ACTOR1 = 0x166; + public const ushort OPCODE_GAMEMESSAGE_WITHOUT_ACTOR2 = 0x167; + public const ushort OPCODE_GAMEMESSAGE_WITHOUT_ACTOR3 = 0x168; + public const ushort OPCODE_GAMEMESSAGE_WITHOUT_ACTOR4 = 0x169; + public const ushort OPCODE_GAMEMESSAGE_WITHOUT_ACTOR5 = 0x16a; + + public const ushort SIZE_GAMEMESSAGE_WITH_ACTOR1 = 0x30; + public const ushort SIZE_GAMEMESSAGE_WITH_ACTOR2 = 0x38; + public const ushort SIZE_GAMEMESSAGE_WITH_ACTOR3 = 0x40; + public const ushort SIZE_GAMEMESSAGE_WITH_ACTOR4 = 0x50; + public const ushort SIZE_GAMEMESSAGE_WITH_ACTOR5 = 0x70; + + public const ushort SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER1 = 0x48; + public const ushort SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER2 = 0x58; + public const ushort SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER3 = 0x68; + public const ushort SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER4 = 0x78; + public const ushort SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER5 = 0x98; + + public const ushort SIZE_GAMEMESSAGE_WITH_DISPID_SENDER1 = 0x30; + public const ushort SIZE_GAMEMESSAGE_WITH_DISPID_SENDER2 = 0x38; + public const ushort SIZE_GAMEMESSAGE_WITH_DISPID_SENDER3 = 0x40; + public const ushort SIZE_GAMEMESSAGE_WITH_DISPID_SENDER4 = 0x50; + public const ushort SIZE_GAMEMESSAGE_WITH_DISPID_SENDER5 = 0x60; + + public const ushort SIZE_GAMEMESSAGE_WITHOUT_ACTOR1 = 0x28; + public const ushort SIZE_GAMEMESSAGE_WITHOUT_ACTOR2 = 0x38; + public const ushort SIZE_GAMEMESSAGE_WITHOUT_ACTOR3 = 0x38; + public const ushort SIZE_GAMEMESSAGE_WITHOUT_ACTOR4 = 0x48; + public const ushort SIZE_GAMEMESSAGE_WITHOUT_ACTOR5 = 0x68; + + public static SubPacket buildPacket(uint sourceId, uint targetId, uint actorId, uint textOwnerActorId, ushort textId, byte log) + { + byte[] data = new byte[SIZE_GAMEMESSAGE_WITH_ACTOR1 - 0x20]; + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + binWriter.Write((UInt32)actorId); + binWriter.Write((UInt32)textOwnerActorId); + binWriter.Write((UInt16)textId); + binWriter.Write((UInt16)log); + } + } + + return new SubPacket(OPCODE_GAMEMESSAGE_WITH_ACTOR1, sourceId, targetId, data); + } + + public static SubPacket buildPacket(uint sourceId, uint targetId, uint actorId, uint textOwnerActorId, ushort textId, byte log, List lParams) + { + int lParamsSize = findSizeOfParams(lParams); + byte[] data; + ushort opcode; + + if (lParamsSize <= 0x8) + { + data = new byte[SIZE_GAMEMESSAGE_WITH_ACTOR2 - 0x20]; + opcode = OPCODE_GAMEMESSAGE_WITH_ACTOR2; + } + else if (lParamsSize <= 0x10) + { + data = new byte[SIZE_GAMEMESSAGE_WITH_ACTOR3 - 0x20]; + opcode = OPCODE_GAMEMESSAGE_WITH_ACTOR3; + } + else if (lParamsSize <= 0x20) + { + data = new byte[SIZE_GAMEMESSAGE_WITH_ACTOR4 - 0x20]; + opcode = OPCODE_GAMEMESSAGE_WITH_ACTOR4; + } + else + { + data = new byte[SIZE_GAMEMESSAGE_WITH_ACTOR5 - 0x20]; + opcode = OPCODE_GAMEMESSAGE_WITH_ACTOR5; + } + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + binWriter.Write((UInt32)actorId); + binWriter.Write((UInt32)textOwnerActorId); + binWriter.Write((UInt16)textId); + binWriter.Write((UInt16)log); + LuaUtils.writeLuaParams(binWriter, lParams); + + if (lParamsSize <= 0x14-12) + { + binWriter.Seek(0x14, SeekOrigin.Begin); + binWriter.Write((UInt32)8); + } + } + } + + return new SubPacket(opcode, sourceId, targetId, data); + } + + public static SubPacket buildPacket(uint sourceId, uint targetId, uint textOwnerActorId, ushort textId, string sender, byte log) + { + byte[] data = new byte[SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER1 - 0x20]; + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + binWriter.Write((UInt32)textOwnerActorId); + binWriter.Write((UInt16)textId); + binWriter.Write((UInt16)log); + binWriter.Write(Encoding.ASCII.GetBytes(sender), 0, Encoding.ASCII.GetByteCount(sender) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(sender)); + } + } + + return new SubPacket(OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER1, sourceId, targetId, data); + } + + public static SubPacket buildPacket(uint sourceId, uint targetId, uint textOwnerActorId, ushort textId, string sender, byte log, List lParams) + { + int lParamsSize = findSizeOfParams(lParams); + byte[] data; + ushort opcode; + + if (lParamsSize <= 0x8) + { + data = new byte[SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER2 - 0x20]; + opcode = OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER2; + } + else if (lParamsSize <= 0x10) + { + data = new byte[SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER3 - 0x20]; + opcode = OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER3; + } + else if (lParamsSize <= 0x20) + { + data = new byte[SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER4 - 0x20]; + opcode = OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER4; + } + else + { + data = new byte[SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER5 - 0x20]; + opcode = OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER5; + } + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + binWriter.Write((UInt32)textOwnerActorId); + binWriter.Write((UInt16)textId); + binWriter.Write((UInt16)log); + binWriter.Write(Encoding.ASCII.GetBytes(sender), 0, Encoding.ASCII.GetByteCount(sender) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(sender)); + LuaUtils.writeLuaParams(binWriter, lParams); + + if (lParamsSize <= 0x14 - 12) + { + binWriter.Seek(0x30, SeekOrigin.Begin); + binWriter.Write((UInt32)8); + } + } + } + + return new SubPacket(opcode, sourceId, targetId, data); + } + + public static SubPacket buildPacket(uint sourceId, uint targetId, uint textOwnerActorId, ushort textId, uint senderDisplayNameId, byte log) + { + byte[] data = new byte[SIZE_GAMEMESSAGE_WITH_DISPID_SENDER1 - 0x20]; + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + binWriter.Write((UInt32)senderDisplayNameId); + binWriter.Write((UInt32)textOwnerActorId); + binWriter.Write((UInt16)textId); + binWriter.Write((UInt16)log); + } + } + + return new SubPacket(OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER1, sourceId, targetId, data); + } + + public static SubPacket buildPacket(uint sourceId, uint targetId, uint textOwnerActorId, ushort textId, uint senderDisplayNameId, byte log, List lParams) + { + int lParamsSize = findSizeOfParams(lParams); + byte[] data; + ushort opcode; + + if (lParamsSize <= 0x8) + { + data = new byte[SIZE_GAMEMESSAGE_WITH_DISPID_SENDER2 - 0x20]; + opcode = OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER2; + } + else if (lParamsSize <= 0x10) + { + data = new byte[SIZE_GAMEMESSAGE_WITH_DISPID_SENDER3 - 0x20]; + opcode = OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER3; + } + else if (lParamsSize <= 0x20) + { + data = new byte[SIZE_GAMEMESSAGE_WITH_DISPID_SENDER4 - 0x20]; + opcode = OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER4; + } + else + { + data = new byte[SIZE_GAMEMESSAGE_WITH_DISPID_SENDER5 - 0x20]; + opcode = OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER5; + } + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + binWriter.Write((UInt32)senderDisplayNameId); + binWriter.Write((UInt32)textOwnerActorId); + binWriter.Write((UInt16)textId); + binWriter.Write((UInt16)log); + LuaUtils.writeLuaParams(binWriter, lParams); + + if (lParamsSize <= 0x14 - 12) + { + binWriter.Seek(0x14, SeekOrigin.Begin); + binWriter.Write((UInt32)8); + } + } + } + + return new SubPacket(opcode, sourceId, targetId, data); + } + + public static SubPacket buildPacket(uint sourceId, uint targetId, uint textOwnerActorId, ushort textId, byte log) + { + byte[] data = new byte[SIZE_GAMEMESSAGE_WITHOUT_ACTOR1 - 0x20]; + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + binWriter.Write((UInt32)textOwnerActorId); + binWriter.Write((UInt16)textId); + binWriter.Write((UInt16)log); + } + } + + return new SubPacket(OPCODE_GAMEMESSAGE_WITHOUT_ACTOR1, sourceId, targetId, data); + } + + public static SubPacket buildPacket(uint sourceId, uint targetId, uint textOwnerActorId, ushort textId, byte log, List lParams) + { + int lParamsSize = findSizeOfParams(lParams); + byte[] data; + ushort opcode; + + if (lParamsSize <= 0x8) + { + data = new byte[SIZE_GAMEMESSAGE_WITHOUT_ACTOR2 - 0x20]; + opcode = OPCODE_GAMEMESSAGE_WITHOUT_ACTOR2; + } + else if (lParamsSize <= 0x10) + { + data = new byte[SIZE_GAMEMESSAGE_WITHOUT_ACTOR3 - 0x20]; + opcode = OPCODE_GAMEMESSAGE_WITHOUT_ACTOR3; + } + else if (lParamsSize <= 0x20) + { + data = new byte[SIZE_GAMEMESSAGE_WITHOUT_ACTOR4 - 0x20]; + opcode = OPCODE_GAMEMESSAGE_WITHOUT_ACTOR4; + } + else + { + data = new byte[SIZE_GAMEMESSAGE_WITHOUT_ACTOR5 - 0x20]; + opcode = OPCODE_GAMEMESSAGE_WITHOUT_ACTOR5; + } + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + binWriter.Write((UInt32)textOwnerActorId); + binWriter.Write((UInt16)textId); + binWriter.Write((UInt16)log); + LuaUtils.writeLuaParams(binWriter, lParams); + + if (lParamsSize <= 0x14 - 12) + { + binWriter.Seek(0x30, SeekOrigin.Begin); + binWriter.Write((UInt32)8); + } + } + } + + return new SubPacket(opcode, sourceId, targetId, data); + } + + private static int findSizeOfParams(List lParams) + { + int total = 0; + foreach (LuaParam l in lParams) + { + switch (l.typeID) + { + case 0: + case 1: + case 6: + total += 5; + break; + case 3: + case 4: + case 5: + total += 1; + break; + } + } + return total + 1; + } + } +}