mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-04-20 19:57:46 +00:00
More group work. Added packet operations to the world server so it can send global group info.
This commit is contained in:
parent
6c409e93a9
commit
1148619ca5
30 changed files with 1173 additions and 43 deletions
13
FFXIVClassic World Server/Actor/Group/Work/ContentWork.cs
Normal file
13
FFXIVClassic World Server/Actor/Group/Work/ContentWork.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_World_Server.Actor.Group.Work
|
||||
{
|
||||
class ContentWork
|
||||
{
|
||||
public GroupGlobalTemp _globalTemp = new GroupGlobalTemp();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_World_Server.Actor.Group.Work
|
||||
{
|
||||
class GroupGlobalSave
|
||||
{
|
||||
public ulong master;
|
||||
public ushort[] crestIcon = new ushort[4];
|
||||
public byte rank = 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_World_Server.Actor.Group.Work
|
||||
{
|
||||
class GroupGlobalTemp
|
||||
{
|
||||
public ulong owner;
|
||||
|
||||
//For content group
|
||||
public ulong director;
|
||||
|
||||
//For relation group
|
||||
public ulong host;
|
||||
public uint variableCommand;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_World_Server.Actor.Group.Work
|
||||
{
|
||||
class GroupMemberSave
|
||||
{
|
||||
//For LS
|
||||
public byte rank;
|
||||
|
||||
//For Retainers
|
||||
public byte cdIDOffset;
|
||||
public ushort placeName;
|
||||
public byte conditions;
|
||||
public byte level;
|
||||
}
|
||||
}
|
14
FFXIVClassic World Server/Actor/Group/Work/LinkshellWork.cs
Normal file
14
FFXIVClassic World Server/Actor/Group/Work/LinkshellWork.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_World_Server.Actor.Group.Work
|
||||
{
|
||||
class LinkshellWork
|
||||
{
|
||||
public GroupGlobalSave _globalSave = new GroupGlobalSave();
|
||||
public GroupMemberSave[] _memberSave = new GroupMemberSave[128];
|
||||
}
|
||||
}
|
13
FFXIVClassic World Server/Actor/Group/Work/PartyWork.cs
Normal file
13
FFXIVClassic World Server/Actor/Group/Work/PartyWork.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_World_Server.Actor.Group.Work
|
||||
{
|
||||
class PartyWork
|
||||
{
|
||||
public GroupGlobalTemp _globalTemp = new GroupGlobalTemp();
|
||||
}
|
||||
}
|
13
FFXIVClassic World Server/Actor/Group/Work/RelationWork.cs
Normal file
13
FFXIVClassic World Server/Actor/Group/Work/RelationWork.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_World_Server.Actor.Group.Work
|
||||
{
|
||||
class RelationWork
|
||||
{
|
||||
public GroupGlobalTemp _globalTemp = new GroupGlobalTemp();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
namespace FFXIVClassic_World_Server.Actor.Group.Work
|
||||
{
|
||||
class RetainerWork
|
||||
{
|
||||
public GroupMemberSave[] _memberSave = new GroupMemberSave[128];
|
||||
}
|
||||
}
|
|
@ -1,18 +1,79 @@
|
|||
using System;
|
||||
using FFXIVClassic.Common;
|
||||
using FFXIVClassic_World_Server.Packets.Send.Subpackets.Groups;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_World_Server.DataObjects.Group
|
||||
{
|
||||
class Group
|
||||
{
|
||||
public readonly ulong groupIndex;
|
||||
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 readonly ulong groupIndex;
|
||||
|
||||
public Group(ulong groupIndex)
|
||||
{
|
||||
this.groupIndex = groupIndex;
|
||||
}
|
||||
|
||||
public virtual int GetMemberCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public virtual uint GetTypeId()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public virtual string GetGroupName()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
public virtual int GetGroupLocalizedName()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public virtual List<GroupMember> BuildMemberList()
|
||||
{
|
||||
return new List<GroupMember>();
|
||||
}
|
||||
|
||||
public void SendGroupPackets(Session session)
|
||||
{
|
||||
ulong time = Utils.MilisUnixTimeStampUTC();
|
||||
List<GroupMember> members = BuildMemberList();
|
||||
|
||||
session.clientConnection.QueuePacket(GroupHeaderPacket.buildPacket(session.sessionId, session.currentZoneId, time, this), true, false);
|
||||
session.clientConnection.QueuePacket(GroupMembersBeginPacket.buildPacket(session.sessionId, session.currentZoneId, time, this), true, false);
|
||||
|
||||
int currentIndex = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (GetMemberCount() - currentIndex >= 64)
|
||||
session.clientConnection.QueuePacket(GroupMembersX64Packet.buildPacket(session.sessionId, session.currentZoneId, time, members, ref currentIndex), true, false);
|
||||
else if (GetMemberCount() - currentIndex >= 32)
|
||||
session.clientConnection.QueuePacket(GroupMembersX32Packet.buildPacket(session.sessionId, session.currentZoneId, time, members, ref currentIndex), true, false);
|
||||
else if (GetMemberCount() - currentIndex >= 16)
|
||||
session.clientConnection.QueuePacket(GroupMembersX16Packet.buildPacket(session.sessionId, session.currentZoneId, time, members, ref currentIndex), true, false);
|
||||
else if (GetMemberCount() - currentIndex > 0)
|
||||
session.clientConnection.QueuePacket(GroupMembersX08Packet.buildPacket(session.sessionId, session.currentZoneId, time, members, ref currentIndex), true, false);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
session.clientConnection.QueuePacket(GroupMembersEndPacket.buildPacket(session.sessionId, session.currentZoneId, time, this), true, false);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
using System;
|
||||
using FFXIVClassic_World_Server.Actor.Group.Work;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FFXIVClassic_World_Server.Packets.Send.Subpackets.Groups;
|
||||
|
||||
namespace FFXIVClassic_World_Server.DataObjects.Group
|
||||
{
|
||||
|
@ -10,19 +12,63 @@ namespace FFXIVClassic_World_Server.DataObjects.Group
|
|||
{
|
||||
public ulong dbId;
|
||||
public string name;
|
||||
public ushort crestId;
|
||||
public uint master;
|
||||
public ushort rank;
|
||||
|
||||
public LinkshellWork linkshellWork = new LinkshellWork();
|
||||
|
||||
public Dictionary<ulong, LinkshellMember> members = new Dictionary<ulong, LinkshellMember>();
|
||||
|
||||
public Linkshell(ulong dbId, ulong groupIndex, string name, ushort crestId, uint master, ushort rank) : base(groupIndex)
|
||||
public Linkshell(ulong dbId, ulong groupIndex, string name, ushort crestId, uint master, byte rank) : base(groupIndex)
|
||||
{
|
||||
this.dbId = dbId;
|
||||
this.name = name;
|
||||
this.crestId = crestId;
|
||||
this.master = master;
|
||||
this.rank = rank;
|
||||
linkshellWork._globalSave.crestIcon[0] = crestId;
|
||||
linkshellWork._globalSave.master = master;
|
||||
linkshellWork._globalSave.rank = rank;
|
||||
}
|
||||
|
||||
public void setMaster(uint actorId)
|
||||
{
|
||||
linkshellWork._globalSave.master = (ulong)((0xB36F92 << 8) | actorId);
|
||||
}
|
||||
|
||||
public void setCrest(ushort crestId)
|
||||
{
|
||||
linkshellWork._globalSave.crestIcon[0] = crestId;
|
||||
}
|
||||
|
||||
public void setRank(byte rank = 1)
|
||||
{
|
||||
linkshellWork._globalSave.rank = rank;
|
||||
}
|
||||
|
||||
public void setMemberRank(int index, byte rank)
|
||||
{
|
||||
if (members.Count >= index)
|
||||
return;
|
||||
linkshellWork._memberSave[index].rank = rank;
|
||||
}
|
||||
|
||||
public override int GetMemberCount()
|
||||
{
|
||||
return members.Count;
|
||||
}
|
||||
|
||||
public override string GetGroupName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public override uint GetTypeId()
|
||||
{
|
||||
return Group.CompanyGroup;
|
||||
}
|
||||
|
||||
public override List<GroupMember> BuildMemberList()
|
||||
{
|
||||
List<GroupMember> groupMembers = new List<GroupMember>();
|
||||
foreach (LinkshellMember member in members.Values)
|
||||
groupMembers.Add(new GroupMember(member.charaId, -1, 0, false, Server.GetServer().GetSession(member.charaId) != null, Server.GetServer().GetNameForId(member.charaId)));
|
||||
return groupMembers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using System;
|
||||
using FFXIVClassic_World_Server.Actor.Group.Work;
|
||||
using FFXIVClassic_World_Server.Packets.Send.Subpackets.Groups;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
@ -8,12 +10,53 @@ namespace FFXIVClassic_World_Server.DataObjects.Group
|
|||
{
|
||||
class Party : Group
|
||||
{
|
||||
public uint leader;
|
||||
public PartyWork partyGroupWork = new PartyWork();
|
||||
public List<uint> members = new List<uint>();
|
||||
|
||||
public Party(ulong groupId, uint leaderCharaId) : base(groupId)
|
||||
{
|
||||
this.leader = leaderCharaId;
|
||||
partyGroupWork._globalTemp.owner = (ulong)((0xB36F92 << 8) | leaderCharaId);
|
||||
}
|
||||
|
||||
public void SetLeader(uint actorId)
|
||||
{
|
||||
partyGroupWork._globalTemp.owner = (ulong)((0xB36F92 << 8) | actorId);
|
||||
}
|
||||
|
||||
public uint GetLeader()
|
||||
{
|
||||
return (uint)(partyGroupWork._globalTemp.owner & 0xFFFFFF);
|
||||
}
|
||||
|
||||
/*
|
||||
public override void sendWorkValues(Session session)
|
||||
{
|
||||
SynchGroupWorkValuesPacket groupWork = new SynchGroupWorkValuesPacket(groupId);
|
||||
groupWork.addProperty(this, "partyGroupWork._globalTemp.owner");
|
||||
groupWork.setTarget("/_init");
|
||||
|
||||
SubPacket test = groupWork.buildPacket(session.sessionId, session.sessionId);
|
||||
session.clientConnection.QueuePacket(test, true, false);
|
||||
}
|
||||
*/
|
||||
|
||||
public override int GetMemberCount()
|
||||
{
|
||||
return members.Count;
|
||||
}
|
||||
|
||||
public override uint GetTypeId()
|
||||
{
|
||||
return Group.PlayerPartyGroup;
|
||||
}
|
||||
|
||||
public override List<GroupMember> BuildMemberList()
|
||||
{
|
||||
List<GroupMember> groupMembers = new List<GroupMember>();
|
||||
foreach (uint charaId in members)
|
||||
groupMembers.Add(new GroupMember(charaId, -1, 0, false, Server.GetServer().GetSession(charaId) != null, Server.GetServer().GetNameForId(charaId)));
|
||||
return groupMembers;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using FFXIVClassic_World_Server.Packets.Send.Subpackets.Groups;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
@ -17,5 +18,24 @@ namespace FFXIVClassic_World_Server.DataObjects.Group
|
|||
this.charaOther = other;
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
public override int GetMemberCount()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public override uint GetTypeId()
|
||||
{
|
||||
return Group.GroupInvitationRelationGroup;
|
||||
}
|
||||
|
||||
public override List<GroupMember> BuildMemberList()
|
||||
{
|
||||
List<GroupMember> groupMembers = new List<GroupMember>();
|
||||
groupMembers.Add(new GroupMember(charaHost, -1, 0, false, Server.GetServer().GetSession(charaHost) != null, Server.GetServer().GetNameForId(charaHost)));
|
||||
groupMembers.Add(new GroupMember(charaOther, -1, 0, false, Server.GetServer().GetSession(charaOther) != null, Server.GetServer().GetNameForId(charaOther)));
|
||||
return groupMembers;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using System;
|
||||
using FFXIVClassic_World_Server.Actor.Group.Work;
|
||||
using FFXIVClassic_World_Server.Packets.Send.Subpackets.Groups;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
@ -8,6 +10,7 @@ namespace FFXIVClassic_World_Server.DataObjects.Group
|
|||
{
|
||||
class RetainerGroup : Group
|
||||
{
|
||||
public RetainerWork work = new RetainerWork();
|
||||
public uint owner;
|
||||
public Dictionary<uint, RetainerGroupMember> members = new Dictionary<uint, RetainerGroupMember>();
|
||||
|
||||
|
@ -15,5 +18,48 @@ namespace FFXIVClassic_World_Server.DataObjects.Group
|
|||
{
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public void setRetainerProperties(int index, byte cdIDOffset, ushort placeName, byte condition, byte level)
|
||||
{
|
||||
if (members.Count >= index)
|
||||
return;
|
||||
work._memberSave[index].cdIDOffset = cdIDOffset;
|
||||
work._memberSave[index].placeName = placeName;
|
||||
work._memberSave[index].conditions = condition;
|
||||
work._memberSave[index].level = level;
|
||||
}
|
||||
|
||||
/*
|
||||
public override void sendWorkValues(Session session)
|
||||
{
|
||||
SynchGroupWorkValuesPacket groupWork = new SynchGroupWorkValuesPacket(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(session.sessionId, session.sessionId);
|
||||
session.clientConnection.QueuePacket(test, true, false);
|
||||
}
|
||||
*/
|
||||
|
||||
public override int GetMemberCount()
|
||||
{
|
||||
return members.Count;
|
||||
}
|
||||
|
||||
public override uint GetTypeId()
|
||||
{
|
||||
return Group.RetainerGroup;
|
||||
}
|
||||
|
||||
public override List<GroupMember> BuildMemberList()
|
||||
{
|
||||
List<GroupMember> groupMembers = new List<GroupMember>();
|
||||
foreach (RetainerGroupMember member in members.Values)
|
||||
groupMembers.Add(new GroupMember(member.retainerId, -1, 0, false, true, member.name));
|
||||
return groupMembers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,5 +8,7 @@ namespace FFXIVClassic_World_Server.DataObjects.Group
|
|||
{
|
||||
class RetainerGroupMember
|
||||
{
|
||||
public uint retainerId;
|
||||
public string name;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,35 @@ namespace FFXIVClassic_World_Server
|
|||
return readIn;
|
||||
}
|
||||
|
||||
public static void GetAllCharaNames(Dictionary<uint, string> mIdToNameMap)
|
||||
{
|
||||
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
|
||||
{
|
||||
try
|
||||
{
|
||||
conn.Open();
|
||||
MySqlCommand cmd = new MySqlCommand("SELECT id, name FROM characters", conn);
|
||||
using (MySqlDataReader Reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (Reader.Read())
|
||||
{
|
||||
uint id = Reader.GetUInt32("id");
|
||||
string name = Reader.GetString("name");
|
||||
mIdToNameMap.Add(id, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MySqlException e)
|
||||
{
|
||||
Program.Log.Error(e.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
conn.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static uint GetCurrentZoneForSession(uint charId)
|
||||
{
|
||||
uint currentZone = 0;
|
||||
|
|
|
@ -64,6 +64,20 @@
|
|||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Actor\Group\Group.cs" />
|
||||
<Compile Include="Actor\Group\GroupInvitationRelationGroup.cs" />
|
||||
<Compile Include="Actor\Group\GroupMember.cs" />
|
||||
<Compile Include="Actor\Group\LinkshellGroup.cs" />
|
||||
<Compile Include="Actor\Group\PartyGroup.cs" />
|
||||
<Compile Include="Actor\Group\RetainerGroup.cs" />
|
||||
<Compile Include="Actor\Group\Work\ContentWork.cs" />
|
||||
<Compile Include="Actor\Group\Work\GroupGlobalSave.cs" />
|
||||
<Compile Include="Actor\Group\Work\GroupGlobalTemp.cs" />
|
||||
<Compile Include="Actor\Group\Work\GroupMemberSave.cs" />
|
||||
<Compile Include="Actor\Group\Work\LinkshellWork.cs" />
|
||||
<Compile Include="Actor\Group\Work\PartyWork.cs" />
|
||||
<Compile Include="Actor\Group\Work\RelationWork.cs" />
|
||||
<Compile Include="Actor\Group\Work\RetainerWork.cs" />
|
||||
<Compile Include="ConfigConstants.cs" />
|
||||
<Compile Include="Database.cs" />
|
||||
<Compile Include="DataObjects\ClientConnection.cs" />
|
||||
|
@ -79,6 +93,18 @@
|
|||
<Compile Include="LinkshellManager.cs" />
|
||||
<Compile Include="PacketProcessor.cs" />
|
||||
<Compile Include="Packets\Receive\HelloPacket.cs" />
|
||||
<Compile Include="Packets\Send\Subpackets\Groups\CreateNamedGroup.cs" />
|
||||
<Compile Include="Packets\Send\Subpackets\Groups\CreateNamedGroupMultiple.cs" />
|
||||
<Compile Include="Packets\Send\Subpackets\Groups\DeleteGroupPacket.cs" />
|
||||
<Compile Include="Packets\Send\Subpackets\Groups\GroupHeaderPacket.cs" />
|
||||
<Compile Include="Packets\Send\Subpackets\Groups\GroupMember.cs" />
|
||||
<Compile Include="Packets\Send\Subpackets\Groups\GroupMembersBeginPacket.cs" />
|
||||
<Compile Include="Packets\Send\Subpackets\Groups\GroupMembersEndPacket.cs" />
|
||||
<Compile Include="Packets\Send\Subpackets\Groups\GroupMembersX08Packet.cs" />
|
||||
<Compile Include="Packets\Send\Subpackets\Groups\GroupMembersX16Packet.cs" />
|
||||
<Compile Include="Packets\Send\Subpackets\Groups\GroupMembersX32Packet.cs" />
|
||||
<Compile Include="Packets\Send\Subpackets\Groups\GroupMembersX64Packet.cs" />
|
||||
<Compile Include="Packets\Send\Subpackets\Groups\SynchGroupWorkValuesPacket.cs" />
|
||||
<Compile Include="Packets\Send\_0x2Packet.cs" />
|
||||
<Compile Include="Packets\Send\_0x7Packet.cs" />
|
||||
<Compile Include="Packets\Send\_0x8PingPacket.cs" />
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
using FFXIVClassic.Common;
|
||||
using FFXIVClassic_World_Server.Actor.Group;
|
||||
using FFXIVClassic_World_Server.DataObjects.Group;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_World_Server.Packets.Send.Subpackets.Groups
|
||||
{
|
||||
class CreateNamedGroup
|
||||
{
|
||||
public const ushort OPCODE = 0x0188;
|
||||
public const uint PACKET_SIZE = 0x60;
|
||||
|
||||
public static SubPacket buildPacket(uint sessionId, 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.groupIndex);
|
||||
binWriter.Write((UInt32)group.GetTypeId());
|
||||
binWriter.Write((Int32)group.GetGroupLocalizedName());
|
||||
|
||||
binWriter.Write((UInt16)0x121C);
|
||||
|
||||
binWriter.Seek(0x20, SeekOrigin.Begin);
|
||||
|
||||
binWriter.Write(Encoding.ASCII.GetBytes(group.GetGroupName()), 0, Encoding.ASCII.GetByteCount(group.GetGroupName()) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(group.GetGroupName()));
|
||||
}
|
||||
}
|
||||
|
||||
return new SubPacket(OPCODE, sessionId, sessionId, data);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
using FFXIVClassic.Common;
|
||||
using FFXIVClassic_World_Server.Actor.Group;
|
||||
using FFXIVClassic_World_Server.DataObjects.Group;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_World_Server.Packets.Send.Subpackets.Groups
|
||||
{
|
||||
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.groupIndex);
|
||||
binWriter.Write((UInt32)group.GetTypeId());
|
||||
binWriter.Write((Int32)group.GetGroupLocalizedName());
|
||||
|
||||
binWriter.Write((UInt16)0x121C);
|
||||
|
||||
binWriter.Seek(0x20, SeekOrigin.Begin);
|
||||
|
||||
binWriter.Write(Encoding.ASCII.GetBytes(group.GetGroupName()), 0, Encoding.ASCII.GetByteCount(group.GetGroupName()) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(group.GetGroupName()));
|
||||
}
|
||||
|
||||
binWriter.Seek(0x200, SeekOrigin.Begin);
|
||||
binWriter.Write((Byte)max);
|
||||
}
|
||||
}
|
||||
|
||||
return new SubPacket(OPCODE, playerActorID, playerActorID, data);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
using FFXIVClassic.Common;
|
||||
using FFXIVClassic_World_Server.Actor.Group;
|
||||
using FFXIVClassic_World_Server.DataObjects.Group;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_World_Server.Packets.Send.Subpackets.Groups
|
||||
{
|
||||
class DeleteGroupPacket
|
||||
{
|
||||
public const ushort OPCODE = 0x0143;
|
||||
public const uint PACKET_SIZE = 0x40;
|
||||
|
||||
public static SubPacket buildPacket(uint sessionId, Group group)
|
||||
{
|
||||
return buildPacket(sessionId, group.groupIndex);
|
||||
}
|
||||
|
||||
public static SubPacket buildPacket(uint sessionId, ulong groupId)
|
||||
{
|
||||
byte[] data = new byte[PACKET_SIZE - 0x20];
|
||||
|
||||
using (MemoryStream mem = new MemoryStream(data))
|
||||
{
|
||||
using (BinaryWriter binWriter = new BinaryWriter(mem))
|
||||
{
|
||||
//Write control num ????
|
||||
binWriter.Write((UInt64)3);
|
||||
|
||||
//Write Ids
|
||||
binWriter.Write((UInt64)groupId);
|
||||
binWriter.Write((UInt64)0);
|
||||
binWriter.Write((UInt64)groupId);
|
||||
}
|
||||
}
|
||||
|
||||
return new SubPacket(OPCODE, sessionId, sessionId, data);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
using FFXIVClassic.Common;
|
||||
using FFXIVClassic_World_Server.DataObjects.Group;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_World_Server.Packets.Send.Subpackets.Groups
|
||||
{
|
||||
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.groupIndex);
|
||||
binWriter.Write((UInt64)0);
|
||||
binWriter.Write((UInt64)group.groupIndex);
|
||||
|
||||
//This seems to change depending on what the list is for
|
||||
binWriter.Write((UInt32)group.GetTypeId());
|
||||
binWriter.Seek(0x40, SeekOrigin.Begin);
|
||||
|
||||
//This is for Linkshell
|
||||
binWriter.Write((UInt32)group.GetGroupLocalizedName());
|
||||
binWriter.Write(Encoding.ASCII.GetBytes(group.GetGroupName()), 0, Encoding.ASCII.GetByteCount(group.GetGroupName()) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(group.GetGroupName()));
|
||||
|
||||
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.GetMemberCount());
|
||||
}
|
||||
}
|
||||
|
||||
return new SubPacket(OPCODE, playerActorID, playerActorID, data);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_World_Server.Packets.Send.Subpackets.Groups
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
using FFXIVClassic.Common;
|
||||
using FFXIVClassic_World_Server.DataObjects.Group;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_World_Server.Packets.Send.Subpackets.Groups
|
||||
{
|
||||
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.groupIndex);
|
||||
binWriter.Write((UInt32)group.GetMemberCount());
|
||||
}
|
||||
}
|
||||
|
||||
return new SubPacket(OPCODE, playerActorID, playerActorID, data);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
using FFXIVClassic.Common;
|
||||
using FFXIVClassic_World_Server.Actor.Group;
|
||||
using FFXIVClassic_World_Server.DataObjects.Group;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_World_Server.Packets.Send.Subpackets.Groups
|
||||
{
|
||||
class GroupMembersEndPacket
|
||||
{
|
||||
public const ushort OPCODE = 0x017E;
|
||||
public const uint PACKET_SIZE = 0x38;
|
||||
|
||||
public static SubPacket buildPacket(uint sessionId, 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.groupIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return new SubPacket(OPCODE, sessionId, sessionId, data);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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_World_Server.Packets.Send.Subpackets.Groups
|
||||
{
|
||||
class GroupMembersX08Packet
|
||||
{
|
||||
public const ushort OPCODE = 0x017F;
|
||||
public const uint PACKET_SIZE = 0x1B8;
|
||||
|
||||
public static SubPacket buildPacket(uint playerActorID, uint locationCode, ulong sequenceId, List<GroupMember> 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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_World_Server.Packets.Send.Subpackets.Groups
|
||||
{
|
||||
class GroupMembersX16Packet
|
||||
{
|
||||
public const ushort OPCODE = 0x0180;
|
||||
public const uint PACKET_SIZE = 0x330;
|
||||
|
||||
public static SubPacket buildPacket(uint playerActorID, uint locationCode, ulong sequenceId, List<GroupMember> 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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_World_Server.Packets.Send.Subpackets.Groups
|
||||
{
|
||||
class GroupMembersX32Packet
|
||||
{
|
||||
public const ushort OPCODE = 0x0181;
|
||||
public const uint PACKET_SIZE = 0x630;
|
||||
|
||||
public static SubPacket buildPacket(uint playerActorID, uint locationCode, ulong sequenceId, List<GroupMember> 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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_World_Server.Packets.Send.Subpackets.Groups
|
||||
{
|
||||
class GroupMembersX64Packet
|
||||
{
|
||||
public const ushort OPCODE = 0x0182;
|
||||
public const uint PACKET_SIZE = 0xC30;
|
||||
|
||||
public static SubPacket buildPacket(uint playerActorID, uint locationCode, ulong sequenceId, List<GroupMember> 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,211 @@
|
|||
using FFXIVClassic.Common;
|
||||
using FFXIVClassic_World_Server.Actor.Group;
|
||||
using FFXIVClassic_World_Server.DataObjects.Group;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FFXIVClassic_World_Server.Packets.Send.Subpackets.Groups
|
||||
{
|
||||
class SynchGroupWorkValuesPacket
|
||||
{
|
||||
public const ushort OPCODE = 0x017A;
|
||||
public const uint PACKET_SIZE = 0xB0;
|
||||
|
||||
private const ushort MAXBYTES = 0x98;
|
||||
|
||||
private ushort runningByteTotal = 0;
|
||||
private byte[] data = new byte[PACKET_SIZE - 0x20];
|
||||
private bool isMore = false;
|
||||
|
||||
private MemoryStream mem;
|
||||
private BinaryWriter binWriter;
|
||||
|
||||
public SynchGroupWorkValuesPacket(ulong listId)
|
||||
{
|
||||
mem = new MemoryStream(data);
|
||||
binWriter = new BinaryWriter(mem);
|
||||
binWriter.Write((UInt64)listId);
|
||||
binWriter.Seek(1, SeekOrigin.Current);
|
||||
}
|
||||
|
||||
public void closeStreams()
|
||||
{
|
||||
binWriter.Dispose();
|
||||
mem.Dispose();
|
||||
}
|
||||
|
||||
public bool addByte(uint id, byte value)
|
||||
{
|
||||
if (runningByteTotal + 6 > MAXBYTES)
|
||||
return false;
|
||||
|
||||
binWriter.Write((byte)1);
|
||||
binWriter.Write((UInt32)id);
|
||||
binWriter.Write((byte)value);
|
||||
runningByteTotal += 6;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool addShort(uint id, ushort value)
|
||||
{
|
||||
if (runningByteTotal + 7 > MAXBYTES)
|
||||
return false;
|
||||
|
||||
binWriter.Write((byte)2);
|
||||
binWriter.Write((UInt32)id);
|
||||
binWriter.Write((UInt16)value);
|
||||
runningByteTotal += 7;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool addInt(uint id, uint value)
|
||||
{
|
||||
if (runningByteTotal + 9 > MAXBYTES)
|
||||
return false;
|
||||
|
||||
binWriter.Write((byte)4);
|
||||
binWriter.Write((UInt32)id);
|
||||
binWriter.Write((UInt32)value);
|
||||
runningByteTotal += 9;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool addLong(uint id, ulong value)
|
||||
{
|
||||
if (runningByteTotal + 13 > MAXBYTES)
|
||||
return false;
|
||||
|
||||
binWriter.Write((byte)8);
|
||||
binWriter.Write((UInt32)id);
|
||||
binWriter.Write((UInt64)value);
|
||||
runningByteTotal += 13;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool addBuffer(uint id, byte[] buffer)
|
||||
{
|
||||
if (runningByteTotal + 5 + buffer.Length > MAXBYTES)
|
||||
return false;
|
||||
|
||||
binWriter.Write((byte)buffer.Length);
|
||||
binWriter.Write((UInt32)id);
|
||||
binWriter.Write(buffer);
|
||||
runningByteTotal += (ushort)(5 + buffer.Length);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void addProperty(Group group, string name)
|
||||
{
|
||||
string[] split = name.Split('.');
|
||||
int arrayIndex = 0;
|
||||
|
||||
if (!(split[0].Equals("work") || split[0].Equals("partyGroupWork")))
|
||||
return;
|
||||
|
||||
Object curObj = group;
|
||||
for (int i = 0; i < split.Length; i++)
|
||||
{
|
||||
//For arrays
|
||||
if (split[i].Contains('['))
|
||||
{
|
||||
if (split[i].LastIndexOf(']') - split[i].IndexOf('[') <= 0)
|
||||
return;
|
||||
|
||||
arrayIndex = Convert.ToInt32(split[i].Substring(split[i].IndexOf('[') + 1, split[i].Length - split[i].LastIndexOf(']')));
|
||||
|
||||
split[i] = split[i].Substring(0, split[i].IndexOf('['));
|
||||
|
||||
if (i != split.Length - 1)
|
||||
{
|
||||
curObj = curObj.GetType().GetField(split[i]).GetValue(curObj);
|
||||
curObj = ((Array)curObj).GetValue(arrayIndex);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
FieldInfo field = curObj.GetType().GetField(split[i]);
|
||||
if (field == null)
|
||||
return;
|
||||
|
||||
curObj = field.GetValue(curObj);
|
||||
if (curObj == null)
|
||||
return;
|
||||
}
|
||||
|
||||
if (curObj == null)
|
||||
return;
|
||||
else
|
||||
{
|
||||
//Array, we actually care whats inside
|
||||
if (curObj.GetType().IsArray)
|
||||
{
|
||||
if (((Array)curObj).Length <= arrayIndex)
|
||||
return;
|
||||
curObj = ((Array)curObj).GetValue(arrayIndex);
|
||||
}
|
||||
|
||||
if (curObj == null)
|
||||
return;
|
||||
|
||||
//Cast to the proper object and add to packet
|
||||
uint id = Utils.MurmurHash2(name, 0);
|
||||
if (curObj is bool)
|
||||
addByte(id, (byte)(((bool)curObj) ? 1 : 0));
|
||||
else if (curObj is byte)
|
||||
addByte(id, (byte)curObj);
|
||||
else if (curObj is ushort)
|
||||
addShort(id, (ushort)curObj);
|
||||
else if (curObj is short)
|
||||
addShort(id, (ushort)(short)curObj);
|
||||
else if (curObj is uint)
|
||||
addInt(id, (uint)curObj);
|
||||
else if (curObj is int)
|
||||
addInt(id, (uint)(int)curObj);
|
||||
else if (curObj is long)
|
||||
addLong(id, (ulong)(long)curObj);
|
||||
else if (curObj is ulong)
|
||||
addLong(id, (ulong)curObj);
|
||||
else if (curObj is float)
|
||||
addBuffer(id, BitConverter.GetBytes((float)curObj));
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void setIsMore(bool flag)
|
||||
{
|
||||
isMore = flag;
|
||||
}
|
||||
|
||||
public void setTarget(string target)
|
||||
{
|
||||
binWriter.Write((byte)(isMore ? 0x62 + target.Length : 0x82 + target.Length));
|
||||
binWriter.Write(Encoding.ASCII.GetBytes(target));
|
||||
runningByteTotal += (ushort)(1 + Encoding.ASCII.GetByteCount(target));
|
||||
|
||||
}
|
||||
|
||||
public SubPacket buildPacket(uint playerActorID, uint actorID)
|
||||
{
|
||||
binWriter.Seek(0x8, SeekOrigin.Begin);
|
||||
binWriter.Write((byte)runningByteTotal);
|
||||
|
||||
closeStreams();
|
||||
|
||||
SubPacket packet = new SubPacket(OPCODE, playerActorID, actorID, data);
|
||||
return packet;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -60,8 +60,8 @@ namespace FFXIVClassic_World_Server
|
|||
party.members.Remove(charaId);
|
||||
|
||||
//If current ldr, make a new ldr if not empty pt
|
||||
if (party.leader == charaId && party.members.Count != 0)
|
||||
party.leader = party.members[0];
|
||||
if (party.GetLeader() == charaId && party.members.Count != 0)
|
||||
party.SetLeader(party.members[0]);
|
||||
}
|
||||
return party.members.Count;
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ namespace FFXIVClassic_World_Server
|
|||
Party party = mPartyList[groupId];
|
||||
if (party.members.Contains(charaId))
|
||||
{
|
||||
party.leader = charaId;
|
||||
party.SetLeader(charaId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,14 +17,16 @@ namespace FFXIVClassic_World_Server
|
|||
public const int BACKLOG = 100;
|
||||
private static Server mSelf;
|
||||
|
||||
//Connection and Session Management
|
||||
//Connections
|
||||
private Socket mServerSocket;
|
||||
|
||||
WorldManager mWorldManager;
|
||||
PacketProcessor mPacketProcessor;
|
||||
|
||||
private List<ClientConnection> mConnectionList = new List<ClientConnection>();
|
||||
//Preloaded Maps
|
||||
private Dictionary<uint, string> mIdToNameMap = new Dictionary<uint, string>();
|
||||
|
||||
//Session Management
|
||||
private List<ClientConnection> mConnectionList = new List<ClientConnection>();
|
||||
private Dictionary<uint, Session> mZoneSessionList = new Dictionary<uint, Session>();
|
||||
private Dictionary<uint, Session> mChatSessionList = new Dictionary<uint, Session>();
|
||||
|
||||
|
@ -58,7 +60,7 @@ namespace FFXIVClassic_World_Server
|
|||
mWorldManager = new WorldManager(this);
|
||||
mWorldManager.LoadZoneServerList();
|
||||
mWorldManager.LoadZoneEntranceList();
|
||||
mWorldManager.ConnectToZoneServers();
|
||||
mWorldManager.ConnectToZoneServers();
|
||||
|
||||
IPEndPoint serverEndPoint = new System.Net.IPEndPoint(IPAddress.Parse(ConfigConstants.OPTIONS_BINDIP), int.Parse(ConfigConstants.OPTIONS_PORT));
|
||||
|
||||
|
@ -91,24 +93,28 @@ namespace FFXIVClassic_World_Server
|
|||
Console.ForegroundColor = ConsoleColor.White;
|
||||
Program.Log.Info("World Server accepting connections @ {0}:{1}", (mServerSocket.LocalEndPoint as IPEndPoint).Address, (mServerSocket.LocalEndPoint as IPEndPoint).Port);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddSession(ClientConnection connection, Session.Channel type, uint id)
|
||||
{
|
||||
Session session = new Session(id, connection, type);
|
||||
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Session.Channel.ZONE:
|
||||
//New character since world server loaded
|
||||
if (!mIdToNameMap.ContainsKey(id))
|
||||
AddNameToMap(id, session.characterName);
|
||||
|
||||
if (!mZoneSessionList.ContainsKey(id))
|
||||
mZoneSessionList.Add(id, session);
|
||||
break;
|
||||
break;
|
||||
case Session.Channel.CHAT:
|
||||
if (!mChatSessionList.ContainsKey(id))
|
||||
mChatSessionList.Add(id, session);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,7 +122,7 @@ namespace FFXIVClassic_World_Server
|
|||
{
|
||||
switch (type)
|
||||
{
|
||||
case Session.Channel.ZONE:
|
||||
case Session.Channel.ZONE:
|
||||
if (mZoneSessionList.ContainsKey(id))
|
||||
{
|
||||
mZoneSessionList[id].clientConnection.Disconnect();
|
||||
|
@ -132,7 +138,7 @@ namespace FFXIVClassic_World_Server
|
|||
mChatSessionList.Remove(id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Session GetSession(uint targetSession, Session.Channel type = Session.Channel.ZONE)
|
||||
|
@ -148,12 +154,12 @@ namespace FFXIVClassic_World_Server
|
|||
return mChatSessionList[targetSession];
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void OnReceiveSubPacketFromZone(ZoneServer zoneServer, SubPacket subpacket)
|
||||
{
|
||||
{
|
||||
uint sessionId = subpacket.header.targetId;
|
||||
|
||||
if (subpacket.gameMessage.opcode >= 0x1000)
|
||||
|
@ -207,7 +213,7 @@ namespace FFXIVClassic_World_Server
|
|||
//Group get data request
|
||||
case 0x1020:
|
||||
GetGroupPacket getGroupPacket = new GetGroupPacket(subpacket.data);
|
||||
SendGroupData(session, getGroupPacket.groupId);
|
||||
SendGroupData(session, getGroupPacket.groupId);
|
||||
break;
|
||||
//Group delete request
|
||||
case 0x1021:
|
||||
|
@ -226,7 +232,7 @@ namespace FFXIVClassic_World_Server
|
|||
break;
|
||||
//Group Add/Remove Member
|
||||
case 0x1022:
|
||||
GroupMemberChangePacket gMemberChangePacket = new GroupMemberChangePacket(subpacket.data);
|
||||
GroupMemberChangePacket gMemberChangePacket = new GroupMemberChangePacket(subpacket.data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -236,7 +242,7 @@ namespace FFXIVClassic_World_Server
|
|||
conn.QueuePacket(subpacket, true, false);
|
||||
conn.FlushQueuedSendPackets();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public WorldManager GetWorldManager()
|
||||
|
@ -307,7 +313,7 @@ namespace FFXIVClassic_World_Server
|
|||
{
|
||||
mConnectionList.Remove(conn);
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -333,7 +339,7 @@ namespace FFXIVClassic_World_Server
|
|||
{
|
||||
mPacketProcessor.ProcessPacket(conn, basePacket);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//Not all bytes consumed, transfer leftover to beginning
|
||||
|
@ -354,7 +360,7 @@ namespace FFXIVClassic_World_Server
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
lock (mConnectionList)
|
||||
{
|
||||
mConnectionList.Remove(conn);
|
||||
|
@ -365,7 +371,7 @@ namespace FFXIVClassic_World_Server
|
|||
{
|
||||
if (conn.socket != null)
|
||||
{
|
||||
|
||||
|
||||
lock (mConnectionList)
|
||||
{
|
||||
mConnectionList.Remove(conn);
|
||||
|
@ -376,12 +382,29 @@ namespace FFXIVClassic_World_Server
|
|||
|
||||
#endregion
|
||||
|
||||
public void LoadCharaNames()
|
||||
{
|
||||
Database.GetAllCharaNames(mIdToNameMap);
|
||||
}
|
||||
|
||||
public void AddNameToMap(uint charaId, string name)
|
||||
{
|
||||
mIdToNameMap.Add(charaId, name);
|
||||
}
|
||||
|
||||
public string GetNameForId(uint charaId)
|
||||
{
|
||||
if (mIdToNameMap.ContainsKey(charaId))
|
||||
return mIdToNameMap[charaId];
|
||||
return null;
|
||||
}
|
||||
|
||||
private void SendGroupData(Session session, ulong groupId)
|
||||
{
|
||||
if (mCurrentWorldGroups.ContainsKey(groupId))
|
||||
{
|
||||
Group group = mCurrentWorldGroups[groupId];
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue