mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-04-02 19:42:05 -04: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
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.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace FFXIVClassic_World_Server.DataObjects.Group
|
namespace FFXIVClassic_World_Server.DataObjects.Group
|
||||||
{
|
{
|
||||||
class 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 readonly ulong groupIndex;
|
public readonly ulong groupIndex;
|
||||||
|
|
||||||
public Group(ulong groupIndex)
|
public Group(ulong groupIndex)
|
||||||
{
|
{
|
||||||
this.groupIndex = 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.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using FFXIVClassic_World_Server.Packets.Send.Subpackets.Groups;
|
||||||
|
|
||||||
namespace FFXIVClassic_World_Server.DataObjects.Group
|
namespace FFXIVClassic_World_Server.DataObjects.Group
|
||||||
{
|
{
|
||||||
@ -10,19 +12,63 @@ namespace FFXIVClassic_World_Server.DataObjects.Group
|
|||||||
{
|
{
|
||||||
public ulong dbId;
|
public ulong dbId;
|
||||||
public string name;
|
public string name;
|
||||||
public ushort crestId;
|
|
||||||
public uint master;
|
public LinkshellWork linkshellWork = new LinkshellWork();
|
||||||
public ushort rank;
|
|
||||||
|
|
||||||
public Dictionary<ulong, LinkshellMember> members = new Dictionary<ulong, LinkshellMember>();
|
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.dbId = dbId;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.crestId = crestId;
|
linkshellWork._globalSave.crestIcon[0] = crestId;
|
||||||
this.master = master;
|
linkshellWork._globalSave.master = master;
|
||||||
this.rank = rank;
|
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.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -8,12 +10,53 @@ namespace FFXIVClassic_World_Server.DataObjects.Group
|
|||||||
{
|
{
|
||||||
class Party : Group
|
class Party : Group
|
||||||
{
|
{
|
||||||
public uint leader;
|
public PartyWork partyGroupWork = new PartyWork();
|
||||||
public List<uint> members = new List<uint>();
|
public List<uint> members = new List<uint>();
|
||||||
|
|
||||||
public Party(ulong groupId, uint leaderCharaId) : base(groupId)
|
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.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -17,5 +18,24 @@ namespace FFXIVClassic_World_Server.DataObjects.Group
|
|||||||
this.charaOther = other;
|
this.charaOther = other;
|
||||||
this.command = command;
|
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.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -8,6 +10,7 @@ namespace FFXIVClassic_World_Server.DataObjects.Group
|
|||||||
{
|
{
|
||||||
class RetainerGroup : Group
|
class RetainerGroup : Group
|
||||||
{
|
{
|
||||||
|
public RetainerWork work = new RetainerWork();
|
||||||
public uint owner;
|
public uint owner;
|
||||||
public Dictionary<uint, RetainerGroupMember> members = new Dictionary<uint, RetainerGroupMember>();
|
public Dictionary<uint, RetainerGroupMember> members = new Dictionary<uint, RetainerGroupMember>();
|
||||||
|
|
||||||
@ -15,5 +18,48 @@ namespace FFXIVClassic_World_Server.DataObjects.Group
|
|||||||
{
|
{
|
||||||
this.owner = owner;
|
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
|
class RetainerGroupMember
|
||||||
{
|
{
|
||||||
|
public uint retainerId;
|
||||||
|
public string name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,35 @@ namespace FFXIVClassic_World_Server
|
|||||||
return readIn;
|
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)
|
public static uint GetCurrentZoneForSession(uint charId)
|
||||||
{
|
{
|
||||||
uint currentZone = 0;
|
uint currentZone = 0;
|
||||||
|
@ -64,6 +64,20 @@
|
|||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<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="ConfigConstants.cs" />
|
||||||
<Compile Include="Database.cs" />
|
<Compile Include="Database.cs" />
|
||||||
<Compile Include="DataObjects\ClientConnection.cs" />
|
<Compile Include="DataObjects\ClientConnection.cs" />
|
||||||
@ -79,6 +93,18 @@
|
|||||||
<Compile Include="LinkshellManager.cs" />
|
<Compile Include="LinkshellManager.cs" />
|
||||||
<Compile Include="PacketProcessor.cs" />
|
<Compile Include="PacketProcessor.cs" />
|
||||||
<Compile Include="Packets\Receive\HelloPacket.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\_0x2Packet.cs" />
|
||||||
<Compile Include="Packets\Send\_0x7Packet.cs" />
|
<Compile Include="Packets\Send\_0x7Packet.cs" />
|
||||||
<Compile Include="Packets\Send\_0x8PingPacket.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);
|
party.members.Remove(charaId);
|
||||||
|
|
||||||
//If current ldr, make a new ldr if not empty pt
|
//If current ldr, make a new ldr if not empty pt
|
||||||
if (party.leader == charaId && party.members.Count != 0)
|
if (party.GetLeader() == charaId && party.members.Count != 0)
|
||||||
party.leader = party.members[0];
|
party.SetLeader(party.members[0]);
|
||||||
}
|
}
|
||||||
return party.members.Count;
|
return party.members.Count;
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ namespace FFXIVClassic_World_Server
|
|||||||
Party party = mPartyList[groupId];
|
Party party = mPartyList[groupId];
|
||||||
if (party.members.Contains(charaId))
|
if (party.members.Contains(charaId))
|
||||||
{
|
{
|
||||||
party.leader = charaId;
|
party.SetLeader(charaId);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,14 +17,16 @@ namespace FFXIVClassic_World_Server
|
|||||||
public const int BACKLOG = 100;
|
public const int BACKLOG = 100;
|
||||||
private static Server mSelf;
|
private static Server mSelf;
|
||||||
|
|
||||||
//Connection and Session Management
|
//Connections
|
||||||
private Socket mServerSocket;
|
private Socket mServerSocket;
|
||||||
|
|
||||||
WorldManager mWorldManager;
|
WorldManager mWorldManager;
|
||||||
PacketProcessor mPacketProcessor;
|
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> mZoneSessionList = new Dictionary<uint, Session>();
|
||||||
private Dictionary<uint, Session> mChatSessionList = new Dictionary<uint, Session>();
|
private Dictionary<uint, Session> mChatSessionList = new Dictionary<uint, Session>();
|
||||||
|
|
||||||
@ -102,13 +104,17 @@ namespace FFXIVClassic_World_Server
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case Session.Channel.ZONE:
|
case Session.Channel.ZONE:
|
||||||
|
//New character since world server loaded
|
||||||
|
if (!mIdToNameMap.ContainsKey(id))
|
||||||
|
AddNameToMap(id, session.characterName);
|
||||||
|
|
||||||
if (!mZoneSessionList.ContainsKey(id))
|
if (!mZoneSessionList.ContainsKey(id))
|
||||||
mZoneSessionList.Add(id, session);
|
mZoneSessionList.Add(id, session);
|
||||||
break;
|
break;
|
||||||
case Session.Channel.CHAT:
|
case Session.Channel.CHAT:
|
||||||
if (!mChatSessionList.ContainsKey(id))
|
if (!mChatSessionList.ContainsKey(id))
|
||||||
mChatSessionList.Add(id, session);
|
mChatSessionList.Add(id, session);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,6 +382,23 @@ namespace FFXIVClassic_World_Server
|
|||||||
|
|
||||||
#endregion
|
#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)
|
private void SendGroupData(Session session, ulong groupId)
|
||||||
{
|
{
|
||||||
if (mCurrentWorldGroups.ContainsKey(groupId))
|
if (mCurrentWorldGroups.ContainsKey(groupId))
|
||||||
|
Loading…
Reference in New Issue
Block a user