From df6e16103ce978f31fa41da5e81a1bceb5b1952e Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Sun, 4 Dec 2016 09:52:57 -0500 Subject: [PATCH] Manually added the group packets and dataobjects into dev branch because the working_on_groups branch is so old it probably will break stuff. --- .../FFXIVClassic Map Server.csproj | 19 +++ .../actors/group/ContentWork.cs | 13 ++ FFXIVClassic Map Server/actors/group/Group.cs | 141 ++++++++++++++++++ .../actors/group/GroupGlobalSave.cs | 14 ++ .../actors/group/GroupGlobalTemp.cs | 20 +++ .../actors/group/GroupMemberSave.cs | 20 +++ .../actors/group/LinkshellWork.cs | 14 ++ .../actors/group/PartyWork.cs | 13 ++ .../actors/group/RelationWork.cs | 13 ++ .../actors/group/RetainerWork.cs | 13 ++ .../packets/send/groups/CreateNamedGroup.cs | 41 +++++ .../send/groups/CreateNamedGroupMultiple.cs | 55 +++++++ .../packets/send/groups/GroupHeaderPacket.cs | 62 ++++++++ .../packets/send/groups/GroupMember.cs | 24 +++ .../send/groups/GroupMembersBeginPacket.cs | 38 +++++ .../send/groups/GroupMembersEndPacket.cs | 38 +++++ .../send/groups/GroupMembersX08Packet.cs | 54 +++++++ .../send/groups/GroupMembersX16Packet.cs | 51 +++++++ .../send/groups/GroupMembersX32Packet.cs | 51 +++++++ .../send/groups/GroupMembersX64Packet.cs | 51 +++++++ 20 files changed, 745 insertions(+) create mode 100644 FFXIVClassic Map Server/actors/group/ContentWork.cs create mode 100644 FFXIVClassic Map Server/actors/group/Group.cs create mode 100644 FFXIVClassic Map Server/actors/group/GroupGlobalSave.cs create mode 100644 FFXIVClassic Map Server/actors/group/GroupGlobalTemp.cs create mode 100644 FFXIVClassic Map Server/actors/group/GroupMemberSave.cs create mode 100644 FFXIVClassic Map Server/actors/group/LinkshellWork.cs create mode 100644 FFXIVClassic Map Server/actors/group/PartyWork.cs create mode 100644 FFXIVClassic Map Server/actors/group/RelationWork.cs create mode 100644 FFXIVClassic Map Server/actors/group/RetainerWork.cs create mode 100644 FFXIVClassic Map Server/packets/send/groups/CreateNamedGroup.cs create mode 100644 FFXIVClassic Map Server/packets/send/groups/CreateNamedGroupMultiple.cs create mode 100644 FFXIVClassic Map Server/packets/send/groups/GroupHeaderPacket.cs create mode 100644 FFXIVClassic Map Server/packets/send/groups/GroupMember.cs create mode 100644 FFXIVClassic Map Server/packets/send/groups/GroupMembersBeginPacket.cs create mode 100644 FFXIVClassic Map Server/packets/send/groups/GroupMembersEndPacket.cs create mode 100644 FFXIVClassic Map Server/packets/send/groups/GroupMembersX08Packet.cs create mode 100644 FFXIVClassic Map Server/packets/send/groups/GroupMembersX16Packet.cs create mode 100644 FFXIVClassic Map Server/packets/send/groups/GroupMembersX32Packet.cs create mode 100644 FFXIVClassic Map Server/packets/send/groups/GroupMembersX64Packet.cs diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj index c645651e..ea355218 100644 --- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj +++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj @@ -81,6 +81,7 @@ + @@ -89,8 +90,16 @@ + + + + + + + + @@ -188,10 +197,20 @@ + + + + + + + + + + diff --git a/FFXIVClassic Map Server/actors/group/ContentWork.cs b/FFXIVClassic Map Server/actors/group/ContentWork.cs new file mode 100644 index 00000000..a8a3ccd7 --- /dev/null +++ b/FFXIVClassic Map Server/actors/group/ContentWork.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.actors.group +{ + class ContentWork + { + public GroupGlobalTemp _globalTemp = new GroupGlobalTemp(); + } +} diff --git a/FFXIVClassic Map Server/actors/group/Group.cs b/FFXIVClassic Map Server/actors/group/Group.cs new file mode 100644 index 00000000..2446fd8a --- /dev/null +++ b/FFXIVClassic Map Server/actors/group/Group.cs @@ -0,0 +1,141 @@ +using FFXIVClassic_Lobby_Server.common; +using FFXIVClassic_Lobby_Server.packets; +using FFXIVClassic_Map_Server.Actors; +using FFXIVClassic_Map_Server.packets.send.actor; +using FFXIVClassic_Map_Server.packets.send.group; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.actors.group +{ + class Group + { + public const uint PlayerPartyGroup = 10001; + public const uint CompanyGroup = 20001; + + public const uint GroupInvitationRelationGroup = 50001; + public const uint TradeRelationGroup = 50002; + public const uint BazaarBuyItemRelationGroup = 50009; + + public const uint RetainerGroup = 80001; + + public ulong groupId; + public uint groupTypeId; + public int localizedNamed = -1; + public string groupName = ""; + + public PartyWork partyGroupWork; //For party group types + public Object work; //For the rest + + public List members = new List(); + + public Group(ulong id, uint typeId, object work) + { + groupId = id; + groupTypeId = typeId; + + if (work is PartyWork) + partyGroupWork = (PartyWork)work; + else + this.work = work; + } + + public Group(ulong id, uint typeId, int nameId, object work) + { + groupId = id; + groupTypeId = typeId; + localizedNamed = nameId; + + if (work is PartyWork) + partyGroupWork = (PartyWork)work; + else + this.work = (PartyWork)work; + } + + public Group(ulong id, uint typeId, string name, object work) + { + groupId = id; + groupTypeId = typeId; + groupName = name; + localizedNamed = -1; + + if (work is PartyWork) + partyGroupWork = (PartyWork)work; + else + this.work = work; + } + + public void add(Actor actor) + { + GroupMember member = new GroupMember(actor.actorId, (int)actor.displayNameId, 0, false, true, actor.customDisplayName); + members.Add(member); + } + + public void sendMemberPackets(Player toPlayer) + { + ulong time = Utils.MilisUnixTimeStampUTC(); + + toPlayer.queuePacket(GroupHeaderPacket.buildPacket(toPlayer.actorId, toPlayer.zoneId, time, this)); + toPlayer.queuePacket(GroupMembersBeginPacket.buildPacket(toPlayer.actorId, toPlayer.zoneId, time, this)); + + int currentIndex = 0; + + while (true) + { + if (members.Count - currentIndex >= 64) + toPlayer.queuePacket(GroupMembersX64Packet.buildPacket(toPlayer.actorId, toPlayer.zoneId, time, members, ref currentIndex)); + else if (members.Count - currentIndex >= 32) + toPlayer.queuePacket(GroupMembersX32Packet.buildPacket(toPlayer.actorId, toPlayer.zoneId, time, members, ref currentIndex)); + else if (members.Count - currentIndex >= 16) + toPlayer.queuePacket(GroupMembersX16Packet.buildPacket(toPlayer.actorId, toPlayer.zoneId, time, members, ref currentIndex)); + else if (members.Count - currentIndex > 0) + toPlayer.queuePacket(GroupMembersX08Packet.buildPacket(toPlayer.actorId, toPlayer.zoneId, time, members, ref currentIndex)); + else + break; + } + + + toPlayer.queuePacket(GroupMembersEndPacket.buildPacket(toPlayer.actorId, toPlayer.zoneId, time, this)); + + } + + public void sendWorkValues(Player player) + { + if (groupTypeId == PlayerPartyGroup) + { + SetGroupWorkValuesPacket groupWork = new SetGroupWorkValuesPacket(groupId); + groupWork.addProperty(this, "partyGroupWork._globalTemp.owner"); + groupWork.setTarget("/_init"); + + SubPacket test = groupWork.buildPacket(player.actorId, player.actorId); + player.queuePacket(test); + } + else if (groupTypeId == GroupInvitationRelationGroup) + { + SetGroupWorkValuesPacket groupWork = new SetGroupWorkValuesPacket(groupId); + groupWork.addProperty(this, "work._globalTemp.host"); + groupWork.addProperty(this, "work._globalTemp.variableCommand"); + groupWork.setTarget("/_init"); + + SubPacket test = groupWork.buildPacket(player.actorId, player.actorId); + test.debugPrintSubPacket(); + player.queuePacket(test); + } + else if (groupTypeId == RetainerGroup) + { + SetGroupWorkValuesPacket groupWork = new SetGroupWorkValuesPacket(groupId); + groupWork.addProperty(this, "work._memberSave[0].cdIDOffset"); + groupWork.addProperty(this, "work._memberSave[0].placeName"); + groupWork.addProperty(this, "work._memberSave[0].conditions"); + groupWork.addProperty(this, "work._memberSave[0].level"); + groupWork.setTarget("/_init"); + + SubPacket test = groupWork.buildPacket(player.actorId, player.actorId); + player.queuePacket(test); + } + } + } +} diff --git a/FFXIVClassic Map Server/actors/group/GroupGlobalSave.cs b/FFXIVClassic Map Server/actors/group/GroupGlobalSave.cs new file mode 100644 index 00000000..1231f117 --- /dev/null +++ b/FFXIVClassic Map Server/actors/group/GroupGlobalSave.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.actors.group +{ + class GroupGlobalSave + { + public ulong master; + public byte[] crestIcon = new byte[4]; + } +} diff --git a/FFXIVClassic Map Server/actors/group/GroupGlobalTemp.cs b/FFXIVClassic Map Server/actors/group/GroupGlobalTemp.cs new file mode 100644 index 00000000..2a831dce --- /dev/null +++ b/FFXIVClassic Map Server/actors/group/GroupGlobalTemp.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.actors.group +{ + class GroupGlobalTemp + { + public ulong owner; + + //For content group + public ulong director; + + //For relation group + public ulong host; + public uint variableCommand; + } +} diff --git a/FFXIVClassic Map Server/actors/group/GroupMemberSave.cs b/FFXIVClassic Map Server/actors/group/GroupMemberSave.cs new file mode 100644 index 00000000..4b6160a0 --- /dev/null +++ b/FFXIVClassic Map Server/actors/group/GroupMemberSave.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.actors.group +{ + class GroupMemberSave + { + //For LS + public byte rank; + + //For Retainers + public byte cdIDOffset; + public ushort placeName; + public byte conditions; + public byte level; + } +} diff --git a/FFXIVClassic Map Server/actors/group/LinkshellWork.cs b/FFXIVClassic Map Server/actors/group/LinkshellWork.cs new file mode 100644 index 00000000..d2e5d6ce --- /dev/null +++ b/FFXIVClassic Map Server/actors/group/LinkshellWork.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.actors.group +{ + class LinkshellWork + { + public GroupGlobalSave _globalSave = new GroupGlobalSave(); + public GroupMemberSave[] _memberSave = new GroupMemberSave[128]; + } +} diff --git a/FFXIVClassic Map Server/actors/group/PartyWork.cs b/FFXIVClassic Map Server/actors/group/PartyWork.cs new file mode 100644 index 00000000..c45a89a4 --- /dev/null +++ b/FFXIVClassic Map Server/actors/group/PartyWork.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.actors.group +{ + class PartyWork + { + public GroupGlobalTemp _globalTemp = new GroupGlobalTemp(); + } +} diff --git a/FFXIVClassic Map Server/actors/group/RelationWork.cs b/FFXIVClassic Map Server/actors/group/RelationWork.cs new file mode 100644 index 00000000..e0094492 --- /dev/null +++ b/FFXIVClassic Map Server/actors/group/RelationWork.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.actors.group +{ + class RelationWork + { + public GroupGlobalTemp _globalTemp = new GroupGlobalTemp(); + } +} diff --git a/FFXIVClassic Map Server/actors/group/RetainerWork.cs b/FFXIVClassic Map Server/actors/group/RetainerWork.cs new file mode 100644 index 00000000..49e1c7df --- /dev/null +++ b/FFXIVClassic Map Server/actors/group/RetainerWork.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.actors.group +{ + class RetainerWork + { + public GroupMemberSave[] _memberSave = new GroupMemberSave[128]; + } +} diff --git a/FFXIVClassic Map Server/packets/send/groups/CreateNamedGroup.cs b/FFXIVClassic Map Server/packets/send/groups/CreateNamedGroup.cs new file mode 100644 index 00000000..eaeb6279 --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/groups/CreateNamedGroup.cs @@ -0,0 +1,41 @@ +using FFXIVClassic.Common; +using FFXIVClassic_Map_Server.actors.group; +using FFXIVClassic_Map_Server.dataobjects; +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.group +{ + class CreateNamedGroup + { + public const ushort OPCODE = 0x0188; + public const uint PACKET_SIZE = 0x60; + + public static SubPacket buildPacket(uint playerActorID, Group group) + { + byte[] data = new byte[PACKET_SIZE - 0x20]; + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + binWriter.Write((UInt64)group.groupId); + binWriter.Write((UInt32)group.groupTypeId); + binWriter.Write((Int32)group.localizedNamed); + + binWriter.Write((UInt16)0x121C); + + binWriter.Seek(0x20, SeekOrigin.Begin); + + binWriter.Write(Encoding.ASCII.GetBytes(group.groupName), 0, Encoding.ASCII.GetByteCount(group.groupName) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(group.groupName)); + } + } + + return new SubPacket(OPCODE, playerActorID, playerActorID, data); + } + } +} diff --git a/FFXIVClassic Map Server/packets/send/groups/CreateNamedGroupMultiple.cs b/FFXIVClassic Map Server/packets/send/groups/CreateNamedGroupMultiple.cs new file mode 100644 index 00000000..2946f653 --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/groups/CreateNamedGroupMultiple.cs @@ -0,0 +1,55 @@ +using FFXIVClassic.Common; +using FFXIVClassic_Map_Server.actors.group; +using FFXIVClassic_Map_Server.dataobjects; +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.group +{ + class CreateNamedGroupMultiple + { + public const ushort OPCODE = 0x0189; + public const uint PACKET_SIZE = 0x228; + + public static SubPacket buildPacket(uint playerActorID, Group[] groups, ref int offset) + { + byte[] data = new byte[PACKET_SIZE - 0x20]; + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + int max = 8; + if (groups.Length - offset <= 8) + max = groups.Length - offset; + + for (int i = 0; i < max; i++) + { + binWriter.Seek(i * 0x40, SeekOrigin.Begin); + + Group group = groups[offset+i]; + + binWriter.Write((UInt64)group.groupId); + binWriter.Write((UInt32)group.groupTypeId); + binWriter.Write((Int32)group.localizedNamed); + + binWriter.Write((UInt16)0x121C); + + binWriter.Seek(0x20, SeekOrigin.Begin); + + binWriter.Write(Encoding.ASCII.GetBytes(group.groupName), 0, Encoding.ASCII.GetByteCount(group.groupName) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(group.groupName)); + } + + binWriter.Seek(0x200, SeekOrigin.Begin); + binWriter.Write((Byte)max); + } + } + + return new SubPacket(OPCODE, playerActorID, playerActorID, data); + } + } +} diff --git a/FFXIVClassic Map Server/packets/send/groups/GroupHeaderPacket.cs b/FFXIVClassic Map Server/packets/send/groups/GroupHeaderPacket.cs new file mode 100644 index 00000000..2a04dca6 --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/groups/GroupHeaderPacket.cs @@ -0,0 +1,62 @@ +using FFXIVClassic_Lobby_Server.packets; +using FFXIVClassic_Map_Server.actors.group; +using FFXIVClassic_Map_Server.dataobjects; +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.group +{ + class GroupHeaderPacket + { + public const uint TYPEID_RETAINER = 0x13881; + public const uint TYPEID_PARTY = 0x2711; + public const uint TYPEID_LINKSHELL = 0x4E22; + + public const ushort OPCODE = 0x017C; + public const uint PACKET_SIZE = 0x98; + + public static SubPacket buildPacket(uint playerActorID, uint locationCode, ulong sequenceId, Group group) + { + byte[] data = new byte[PACKET_SIZE - 0x20]; + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + //Write list header + binWriter.Write((UInt64)locationCode); + binWriter.Write((UInt64)sequenceId); + + //Write list id + binWriter.Write((UInt64)3); + binWriter.Write((UInt64)group.groupId); + binWriter.Write((UInt64)0); + binWriter.Write((UInt64)group.groupId); + + //This seems to change depending on what the list is for + binWriter.Write((UInt32)group.groupTypeId); + binWriter.Seek(0x40, SeekOrigin.Begin); + + //This is for Linkshell + binWriter.Write((UInt32)group.localizedNamed); + binWriter.Write(Encoding.ASCII.GetBytes(group.groupName), 0, Encoding.ASCII.GetByteCount(group.groupName) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(group.groupName)); + + binWriter.Seek(0x64, SeekOrigin.Begin); + + binWriter.Write((UInt32)0x6D); + binWriter.Write((UInt32)0x6D); + binWriter.Write((UInt32)0x6D); + binWriter.Write((UInt32)0x6D); + + binWriter.Write((UInt32)group.members.Count); + } + } + + return new SubPacket(OPCODE, playerActorID, playerActorID, data); + } + } +} diff --git a/FFXIVClassic Map Server/packets/send/groups/GroupMember.cs b/FFXIVClassic Map Server/packets/send/groups/GroupMember.cs new file mode 100644 index 00000000..1a00c38f --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/groups/GroupMember.cs @@ -0,0 +1,24 @@ +using FFXIVClassic.Common; + +namespace FFXIVClassic_Map_Server.packets.send.group +{ + class GroupMember + { + public uint actorId; + public int localizedName; + public uint unknown2; + public bool flag1; + public bool isOnline; + public string name; + + public GroupMember(uint actorId, int localizedName, uint unknown2, bool flag1, bool isOnline, string name) + { + this.actorId = actorId; + this.localizedName = localizedName; + this.unknown2 = unknown2; + this.flag1 = flag1; + this.isOnline = isOnline; + this.name = name; + } + } +} diff --git a/FFXIVClassic Map Server/packets/send/groups/GroupMembersBeginPacket.cs b/FFXIVClassic Map Server/packets/send/groups/GroupMembersBeginPacket.cs new file mode 100644 index 00000000..981dd031 --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/groups/GroupMembersBeginPacket.cs @@ -0,0 +1,38 @@ +using FFXIVClassic.Common; +using FFXIVClassic_Map_Server.actors.group; +using FFXIVClassic_Map_Server.dataobjects; +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.group +{ + class GroupMembersBeginPacket + { + public const ushort OPCODE = 0x017D; + public const uint PACKET_SIZE = 0x40; + + public static SubPacket buildPacket(uint playerActorID, uint locationCode, ulong sequenceId, Group group) + { + byte[] data = new byte[PACKET_SIZE - 0x20]; + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + //Write List Header + binWriter.Write((UInt64)locationCode); + binWriter.Write((UInt64)sequenceId); + //Write List Info + binWriter.Write((UInt64)group.groupId); + binWriter.Write((UInt32)group.members.Count); + } + } + + return new SubPacket(OPCODE, playerActorID, playerActorID, data); + } + } +} diff --git a/FFXIVClassic Map Server/packets/send/groups/GroupMembersEndPacket.cs b/FFXIVClassic Map Server/packets/send/groups/GroupMembersEndPacket.cs new file mode 100644 index 00000000..fdf24e21 --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/groups/GroupMembersEndPacket.cs @@ -0,0 +1,38 @@ +using FFXIVClassic.Common; +using FFXIVClassic_Map_Server.actors.group; +using FFXIVClassic_Map_Server.dataobjects; +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.group +{ + class GroupMembersEndPacket + { + public const ushort OPCODE = 0x017E; + public const uint PACKET_SIZE = 0x38; + + public static SubPacket buildPacket(uint playerActorID, uint locationCode, ulong sequenceId, Group group) + { + byte[] data = new byte[PACKET_SIZE - 0x20]; + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + //Write List Header + binWriter.Write((UInt64)locationCode); + binWriter.Write((UInt64)sequenceId); + //Write List Info + binWriter.Write((UInt64)group.groupId); + } + } + + return new SubPacket(OPCODE, playerActorID, playerActorID, data); + } + + } +} diff --git a/FFXIVClassic Map Server/packets/send/groups/GroupMembersX08Packet.cs b/FFXIVClassic Map Server/packets/send/groups/GroupMembersX08Packet.cs new file mode 100644 index 00000000..e5272adb --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/groups/GroupMembersX08Packet.cs @@ -0,0 +1,54 @@ +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.send.group +{ + class GroupMembersX08Packet + { + public const ushort OPCODE = 0x017F; + public const uint PACKET_SIZE = 0x1B8; + + public static SubPacket buildPacket(uint playerActorID, uint locationCode, ulong sequenceId, List entries, ref int offset) + { + byte[] data = new byte[PACKET_SIZE - 0x20]; + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + //Write List Header + binWriter.Write((UInt64)locationCode); + binWriter.Write((UInt64)sequenceId); + //Write Entries + int max = 8; + if (entries.Count-offset < 8) + max = entries.Count - offset; + for (int i = 0; i < max; i++) + { + binWriter.Seek(0x10 + (0x30 * i), SeekOrigin.Begin); + + GroupMember entry = entries[i]; + binWriter.Write((UInt32)entry.actorId); + binWriter.Write((Int32)entry.localizedName); + binWriter.Write((UInt32)entry.unknown2); + binWriter.Write((Byte)(entry.flag1? 1 : 0)); + binWriter.Write((Byte)(entry.isOnline? 1 : 0)); + binWriter.Write(Encoding.ASCII.GetBytes(entry.name), 0, Encoding.ASCII.GetByteCount(entry.name) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(entry.name)); + + offset++; + } + //Write Count + binWriter.Seek(0x10 + (0x30 * 8), SeekOrigin.Begin); + binWriter.Write(max); + } + } + + return new SubPacket(OPCODE, playerActorID, playerActorID, data); + } + } +} diff --git a/FFXIVClassic Map Server/packets/send/groups/GroupMembersX16Packet.cs b/FFXIVClassic Map Server/packets/send/groups/GroupMembersX16Packet.cs new file mode 100644 index 00000000..e2b1ca13 --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/groups/GroupMembersX16Packet.cs @@ -0,0 +1,51 @@ +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.send.group +{ + class GroupMembersX16Packet + { + public const ushort OPCODE = 0x0180; + public const uint PACKET_SIZE = 0x330; + + public static SubPacket buildPacket(uint playerActorID, uint locationCode, ulong sequenceId, List entries, ref int offset) + { + byte[] data = new byte[PACKET_SIZE - 0x20]; + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + //Write List Header + binWriter.Write((UInt64)locationCode); + binWriter.Write((UInt64)sequenceId); + //Write Entries + int max = 16; + if (entries.Count-offset < 16) + max = entries.Count - offset; + for (int i = 0; i < max; i++) + { + binWriter.Seek(0x10 + (0x30 * i), SeekOrigin.Begin); + + GroupMember entry = entries[i]; + binWriter.Write((UInt32)entry.actorId); + binWriter.Write((Int32)entry.localizedName); + binWriter.Write((UInt32)entry.unknown2); + binWriter.Write((Byte)(entry.flag1? 1 : 0)); + binWriter.Write((Byte)(entry.isOnline? 1 : 0)); + binWriter.Write(Encoding.ASCII.GetBytes(entry.name), 0, Encoding.ASCII.GetByteCount(entry.name) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(entry.name)); + + offset++; + } + } + } + + return new SubPacket(OPCODE, playerActorID, playerActorID, data); + } + } +} diff --git a/FFXIVClassic Map Server/packets/send/groups/GroupMembersX32Packet.cs b/FFXIVClassic Map Server/packets/send/groups/GroupMembersX32Packet.cs new file mode 100644 index 00000000..923e5019 --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/groups/GroupMembersX32Packet.cs @@ -0,0 +1,51 @@ +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.send.group +{ + class GroupMembersX32Packet + { + public const ushort OPCODE = 0x0181; + public const uint PACKET_SIZE = 0x630; + + public static SubPacket buildPacket(uint playerActorID, uint locationCode, ulong sequenceId, List entries, ref int offset) + { + byte[] data = new byte[PACKET_SIZE - 0x20]; + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + //Write List Header + binWriter.Write((UInt64)locationCode); + binWriter.Write((UInt64)sequenceId); + //Write Entries + int max = 32; + if (entries.Count-offset < 32) + max = entries.Count - offset; + for (int i = 0; i < max; i++) + { + binWriter.Seek(0x10 + (0x30 * i), SeekOrigin.Begin); + + GroupMember entry = entries[i]; + binWriter.Write((UInt32)entry.actorId); + binWriter.Write((Int32)entry.localizedName); + binWriter.Write((UInt32)entry.unknown2); + binWriter.Write((Byte)(entry.flag1? 1 : 0)); + binWriter.Write((Byte)(entry.isOnline? 1 : 0)); + binWriter.Write(Encoding.ASCII.GetBytes(entry.name), 0, Encoding.ASCII.GetByteCount(entry.name) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(entry.name)); + + offset++; + } + } + } + + return new SubPacket(OPCODE, playerActorID, playerActorID, data); + } + } +} diff --git a/FFXIVClassic Map Server/packets/send/groups/GroupMembersX64Packet.cs b/FFXIVClassic Map Server/packets/send/groups/GroupMembersX64Packet.cs new file mode 100644 index 00000000..05535081 --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/groups/GroupMembersX64Packet.cs @@ -0,0 +1,51 @@ +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.send.group +{ + class GroupMembersX64Packet + { + public const ushort OPCODE = 0x0182; + public const uint PACKET_SIZE = 0xC30; + + public static SubPacket buildPacket(uint playerActorID, uint locationCode, ulong sequenceId, List entries, ref int offset) + { + byte[] data = new byte[PACKET_SIZE - 0x20]; + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + //Write List Header + binWriter.Write((UInt64)locationCode); + binWriter.Write((UInt64)sequenceId); + //Write Entries + int max = 64; + if (entries.Count - offset < 64) + max = entries.Count - offset; + for (int i = 0; i < max; i++) + { + binWriter.Seek(0x10 + (0x30 * i), SeekOrigin.Begin); + + GroupMember entry = entries[i]; + binWriter.Write((UInt32)entry.actorId); + binWriter.Write((Int32)entry.localizedName); + binWriter.Write((UInt32)entry.unknown2); + binWriter.Write((Byte)(entry.flag1? 1 : 0)); + binWriter.Write((Byte)(entry.isOnline? 1 : 0)); + binWriter.Write(Encoding.ASCII.GetBytes(entry.name), 0, Encoding.ASCII.GetByteCount(entry.name) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(entry.name)); + + offset++; + } + } + } + + return new SubPacket(OPCODE, playerActorID, playerActorID, data); + } + } +}