Merge pull request #68 from rtw1x1/main
fix: Server-Side mark broadcast and packet.size
This commit is contained in:
@@ -242,6 +242,31 @@ DWORD CGuildMarkManager::SaveMark(DWORD guildID, BYTE * pbMarkImage)
|
||||
return idMark;
|
||||
}
|
||||
|
||||
// SERVER - Allocate a mark slot with default (empty) image for a new guild
|
||||
DWORD CGuildMarkManager::AllocMark(DWORD guildID)
|
||||
{
|
||||
// Check if guild already has a mark
|
||||
if (GetMarkID(guildID) != INVALID_MARK_ID)
|
||||
{
|
||||
sys_log(0, "AllocMark: guild %u already has a mark", guildID);
|
||||
return GetMarkID(guildID);
|
||||
}
|
||||
|
||||
DWORD idMark = __AllocMarkID(guildID);
|
||||
if (idMark == INVALID_MARK_ID)
|
||||
{
|
||||
sys_err("CGuildMarkManager::AllocMark: cannot alloc mark id for guild %u", guildID);
|
||||
return INVALID_MARK_ID;
|
||||
}
|
||||
|
||||
sys_log(0, "AllocMark: allocated mark id %u for guild %u", idMark, guildID);
|
||||
|
||||
// Save the index so the mark slot is persisted
|
||||
SaveMarkIndex();
|
||||
|
||||
return idMark;
|
||||
}
|
||||
|
||||
// SERVER
|
||||
void CGuildMarkManager::DeleteMark(DWORD guildID)
|
||||
{
|
||||
|
||||
@@ -45,6 +45,7 @@ class CGuildMarkManager : public singleton<CGuildMarkManager>
|
||||
// SERVER
|
||||
void CopyMarkIdx(char * pcBuf) const;
|
||||
DWORD SaveMark(DWORD guildID, BYTE * pbMarkImage);
|
||||
DWORD AllocMark(DWORD guildID); // Allocate a mark slot with default (empty) image
|
||||
void DeleteMark(DWORD guildID);
|
||||
void GetDiffBlocks(DWORD imgIdx, const uint32_t* crcList, std::map<BYTE, const SGuildMarkBlock *> & mapDiffBlocks);
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "locale_service.h"
|
||||
#include "log.h"
|
||||
#include "questmanager.h"
|
||||
#include "MarkManager.h"
|
||||
|
||||
SGuildMember::SGuildMember(LPCHARACTER ch, BYTE grade, DWORD offer_exp)
|
||||
: pid(ch->GetPlayerID()), grade(grade), is_general(0), job(ch->GetJob()), level(ch->GetLevel()), offer_exp(offer_exp), name(ch->GetName())
|
||||
@@ -113,6 +114,9 @@ CGuild::CGuild(TGuildCreateParameter & cp)
|
||||
AddMember(&p);
|
||||
*/
|
||||
RequestAddMember(cp.master, GUILD_LEADER_GRADE);
|
||||
|
||||
// Allocate a mark slot for the new guild
|
||||
CGuildMarkManager::instance().AllocMark(GetID());
|
||||
}
|
||||
|
||||
void CGuild::Initialize()
|
||||
@@ -375,25 +379,23 @@ void CGuild::SendListOneToAll(LPCHARACTER ch)
|
||||
|
||||
void CGuild::SendListOneToAll(DWORD pid)
|
||||
{
|
||||
|
||||
TPacketGCGuild pack;
|
||||
pack.header = HEADER_GC_GUILD;
|
||||
pack.size = sizeof(TPacketGCGuild);
|
||||
pack.subheader = GUILD_SUBHEADER_GC_LIST;
|
||||
|
||||
pack.size += sizeof(TGuildMemberPacketData);
|
||||
|
||||
char c[CHARACTER_NAME_MAX_LEN+1];
|
||||
memset(c, 0, sizeof(c));
|
||||
|
||||
TGuildMemberContainer::iterator cit = m_member.find(pid);
|
||||
if (cit == m_member.end())
|
||||
return;
|
||||
|
||||
TPacketGCGuild pack;
|
||||
pack.header = HEADER_GC_GUILD;
|
||||
pack.size = sizeof(TPacketGCGuild) + sizeof(TGuildMemberPacketData) + CHARACTER_NAME_MAX_LEN + 1;
|
||||
pack.subheader = GUILD_SUBHEADER_GC_LIST;
|
||||
|
||||
char szName[CHARACTER_NAME_MAX_LEN + 1];
|
||||
memset(szName, 0, sizeof(szName));
|
||||
strlcpy(szName, cit->second.name.c_str(), sizeof(szName));
|
||||
|
||||
for (TGuildMemberOnlineContainer::iterator it = m_memberOnline.begin(); it!= m_memberOnline.end(); ++it)
|
||||
{
|
||||
LPDESC d = (*it)->GetDesc();
|
||||
if (!d)
|
||||
if (!d)
|
||||
continue;
|
||||
|
||||
TGuildMemberPacketData p;
|
||||
@@ -404,12 +406,11 @@ void CGuild::SendListOneToAll(DWORD pid)
|
||||
p.level = cit->second.level;
|
||||
p.offer = cit->second.offer_exp;
|
||||
p.name_flag = 1;
|
||||
strlcpy(p.name, cit->second.name.c_str(), sizeof(p.name));
|
||||
|
||||
|
||||
TEMP_BUFFER buf;
|
||||
buf.write(&pack, sizeof(pack));
|
||||
buf.write(&p, sizeof(p));
|
||||
buf.write(szName, CHARACTER_NAME_MAX_LEN + 1);
|
||||
d->Packet(buf.read_peek(), buf.size());
|
||||
}
|
||||
}
|
||||
@@ -424,7 +425,7 @@ void CGuild::SendListPacket(LPCHARACTER ch)
|
||||
[
|
||||
...
|
||||
name_flag 1 - 이름을 보내느냐 안보내느냐
|
||||
name CHARACTER_NAME_MAX_LEN+1
|
||||
name CHARACTER_NAME_MAX_LEN+1 (only if name_flag is 1)
|
||||
] * Count
|
||||
|
||||
*/
|
||||
@@ -437,10 +438,11 @@ void CGuild::SendListPacket(LPCHARACTER ch)
|
||||
pack.size = sizeof(TPacketGCGuild);
|
||||
pack.subheader = GUILD_SUBHEADER_GC_LIST;
|
||||
|
||||
pack.size += sizeof(TGuildMemberPacketData) * m_member.size();
|
||||
// Each member: struct + name (always sent with name_flag=1)
|
||||
pack.size += (sizeof(TGuildMemberPacketData) + CHARACTER_NAME_MAX_LEN + 1) * m_member.size();
|
||||
|
||||
TEMP_BUFFER buf;
|
||||
buf.write(&pack,sizeof(pack));
|
||||
buf.write(&pack, sizeof(pack));
|
||||
|
||||
for (TGuildMemberContainer::iterator it = m_member.begin(); it != m_member.end(); ++it)
|
||||
{
|
||||
@@ -452,11 +454,16 @@ void CGuild::SendListPacket(LPCHARACTER ch)
|
||||
p.level = it->second.level;
|
||||
p.offer = it->second.offer_exp;
|
||||
p.name_flag = 1;
|
||||
strlcpy(p.name, it->second.name.c_str(), sizeof(p.name));
|
||||
buf.write(&p, sizeof(p));
|
||||
|
||||
if ( test_server )
|
||||
sys_log(0 ,"name %s job %d ", it->second.name.c_str(), it->second.job );
|
||||
// Send name separately after the struct
|
||||
char szName[CHARACTER_NAME_MAX_LEN + 1];
|
||||
memset(szName, 0, sizeof(szName));
|
||||
strlcpy(szName, it->second.name.c_str(), sizeof(szName));
|
||||
buf.write(szName, sizeof(szName));
|
||||
|
||||
if (test_server)
|
||||
sys_log(0, "name %s job %d", it->second.name.c_str(), it->second.job);
|
||||
}
|
||||
|
||||
d->Packet(buf.read_peek(), buf.size());
|
||||
@@ -470,7 +477,6 @@ void CGuild::SendListPacket(LPCHARACTER ch)
|
||||
{
|
||||
SendLoginPacket(ch, *it);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CGuild::SendLoginPacket(LPCHARACTER ch, LPCHARACTER chLogin)
|
||||
@@ -1407,7 +1413,7 @@ void CGuild::SendSkillInfoPacket(LPCHARACTER ch) const
|
||||
TPacketGCGuild pack;
|
||||
|
||||
pack.header = HEADER_GC_GUILD;
|
||||
pack.size = sizeof(pack) + 6 + GUILD_SKILL_COUNT;
|
||||
pack.size = sizeof(pack) + 5 + GUILD_SKILL_COUNT; // 1 (skill_point) + GUILD_SKILL_COUNT (abySkill) + 2 (power) + 2 (max_power)
|
||||
pack.subheader = GUILD_SUBHEADER_GC_SKILL_INFO;
|
||||
|
||||
d->BufferedPacket(&pack, sizeof(pack));
|
||||
|
||||
@@ -48,7 +48,7 @@ typedef struct SGuildMember
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct SGuildMemberPacketData
|
||||
{
|
||||
{
|
||||
uint32_t pid;
|
||||
uint8_t grade;
|
||||
uint8_t is_general;
|
||||
@@ -56,7 +56,7 @@ typedef struct SGuildMemberPacketData
|
||||
uint8_t level;
|
||||
uint32_t offer;
|
||||
uint8_t name_flag;
|
||||
char name[CHARACTER_NAME_MAX_LEN+1];
|
||||
// Note: name is sent separately after this struct if name_flag is set
|
||||
} TGuildMemberPacketData;
|
||||
|
||||
typedef struct packet_guild_sub_info
|
||||
|
||||
@@ -17,6 +17,7 @@ enum
|
||||
};
|
||||
|
||||
void LoginFailure(LPDESC d, const char * c_pszStatus);
|
||||
void BroadcastGuildMarkUpdate(DWORD dwGuildID, WORD wImgIdx);
|
||||
|
||||
|
||||
class CInputProcessor
|
||||
@@ -345,6 +346,7 @@ class CInputP2P : public CInputProcessor
|
||||
void IamAwake(LPDESC d, const char * c_pData);
|
||||
void MessengerRequestAdd(const char* c_pData);
|
||||
void MessengerResponse(const char* c_pData);
|
||||
void GuildMarkUpdate(const char * c_pData);
|
||||
|
||||
protected:
|
||||
CPacketInfoGG m_packetInfoGG;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "log.h"
|
||||
#include "horsename_manager.h"
|
||||
#include "MarkManager.h"
|
||||
#include "p2p.h"
|
||||
|
||||
static void _send_bonus_info(LPCHARACTER ch)
|
||||
{
|
||||
@@ -924,10 +925,30 @@ void CInputLogin::GuildMarkUpload(LPDESC d, const char* c_pData)
|
||||
if (*((DWORD *) p->image + iPixel) != 0x00000000)
|
||||
isEmpty = false;
|
||||
|
||||
DWORD markID = CGuildMarkManager::INVALID_MARK_ID;
|
||||
|
||||
if (isEmpty)
|
||||
rkMarkMgr.DeleteMark(p->gid);
|
||||
else
|
||||
rkMarkMgr.SaveMark(p->gid, p->image);
|
||||
markID = rkMarkMgr.SaveMark(p->gid, p->image);
|
||||
|
||||
// Broadcast mark update to all game cores via P2P, which will then broadcast to their clients
|
||||
if (markID != CGuildMarkManager::INVALID_MARK_ID)
|
||||
{
|
||||
WORD imgIdx = static_cast<WORD>(markID / CGuildMarkImage::MARK_TOTAL_COUNT);
|
||||
|
||||
// Send P2P packet to all other game cores
|
||||
TPacketGGMarkUpdate p2pPacket;
|
||||
p2pPacket.bHeader = HEADER_GG_MARK_UPDATE;
|
||||
p2pPacket.dwGuildID = p->gid;
|
||||
p2pPacket.wImgIdx = imgIdx;
|
||||
P2P_MANAGER::instance().Send(&p2pPacket, sizeof(p2pPacket));
|
||||
|
||||
// Also broadcast to clients connected to this core (mark server) using the same logic
|
||||
BroadcastGuildMarkUpdate(p->gid, imgIdx);
|
||||
|
||||
sys_log(0, "MARK_SERVER: GuildMarkUpload: Broadcast mark update for guild %u, imgIdx %u via P2P", p->gid, imgIdx);
|
||||
}
|
||||
}
|
||||
|
||||
void CInputLogin::GuildMarkIDXList(LPDESC d, const char* c_pData)
|
||||
|
||||
@@ -457,6 +457,34 @@ void CInputP2P::IamAwake(LPDESC d, const char * c_pData)
|
||||
sys_log(0, "P2P Awakeness check from %s. My P2P connection number is %d. and details...\n%s", d->GetHostName(), P2P_MANAGER::instance().GetDescCount(), hostNames.c_str());
|
||||
}
|
||||
|
||||
// Shared function to broadcast mark update to all clients on this core
|
||||
void BroadcastGuildMarkUpdate(DWORD dwGuildID, WORD wImgIdx)
|
||||
{
|
||||
TPacketGCMarkUpdate packet;
|
||||
packet.header = HEADER_GC_MARK_UPDATE;
|
||||
packet.guildID = dwGuildID;
|
||||
packet.imgIdx = wImgIdx;
|
||||
|
||||
const DESC_MANAGER::DESC_SET & c_set_desc = DESC_MANAGER::instance().GetClientSet();
|
||||
for (DESC_MANAGER::DESC_SET::const_iterator it = c_set_desc.begin(); it != c_set_desc.end(); ++it)
|
||||
{
|
||||
LPDESC pkDesc = *it;
|
||||
if (pkDesc && pkDesc->GetCharacter())
|
||||
{
|
||||
pkDesc->Packet(&packet, sizeof(packet));
|
||||
}
|
||||
}
|
||||
|
||||
sys_log(0, "BroadcastGuildMarkUpdate: guild %u, imgIdx %u, sent to %zu clients",
|
||||
dwGuildID, wImgIdx, c_set_desc.size());
|
||||
}
|
||||
|
||||
void CInputP2P::GuildMarkUpdate(const char * c_pData)
|
||||
{
|
||||
TPacketGGMarkUpdate * p = (TPacketGGMarkUpdate *) c_pData;
|
||||
BroadcastGuildMarkUpdate(p->dwGuildID, p->wImgIdx);
|
||||
}
|
||||
|
||||
int CInputP2P::Analyze(LPDESC d, BYTE bHeader, const char * c_pData)
|
||||
{
|
||||
if (test_server)
|
||||
@@ -581,6 +609,10 @@ int CInputP2P::Analyze(LPDESC d, BYTE bHeader, const char * c_pData)
|
||||
case HEADER_GG_CHECK_AWAKENESS:
|
||||
IamAwake(d, c_pData);
|
||||
break;
|
||||
|
||||
case HEADER_GG_MARK_UPDATE:
|
||||
GuildMarkUpdate(c_pData);
|
||||
break;
|
||||
}
|
||||
|
||||
return (iExtraLen);
|
||||
|
||||
@@ -212,6 +212,7 @@ enum
|
||||
|
||||
HEADER_GC_MARK_BLOCK = 100,
|
||||
HEADER_GC_MARK_IDXLIST = 102,
|
||||
HEADER_GC_MARK_UPDATE = 103,
|
||||
|
||||
HEADER_GC_TIME = 106,
|
||||
HEADER_GC_CHANGE_NAME = 107,
|
||||
@@ -314,6 +315,7 @@ enum
|
||||
HEADER_GG_MONARCH_TRANSFER = 27,
|
||||
|
||||
HEADER_GG_CHECK_AWAKENESS = 29,
|
||||
HEADER_GG_MARK_UPDATE = 30,
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
@@ -515,6 +517,13 @@ typedef struct SPacketGGBlockChat
|
||||
int32_t lBlockDuration;
|
||||
} TPacketGGBlockChat;
|
||||
|
||||
typedef struct packet_gg_mark_update
|
||||
{
|
||||
uint8_t bHeader;
|
||||
uint32_t dwGuildID;
|
||||
uint16_t wImgIdx;
|
||||
} TPacketGGMarkUpdate;
|
||||
|
||||
/* 클라이언트 측에서 보내는 패킷 */
|
||||
|
||||
typedef struct command_text
|
||||
@@ -1814,6 +1823,13 @@ typedef struct packet_mark_block
|
||||
// 뒤에 64 x 48 x 픽셀크기(4바이트) = 12288만큼 데이터 붙음
|
||||
} TPacketGCMarkBlock;
|
||||
|
||||
typedef struct packet_mark_update
|
||||
{
|
||||
uint8_t header;
|
||||
uint32_t guildID;
|
||||
uint16_t imgIdx;
|
||||
} TPacketGCMarkUpdate;
|
||||
|
||||
typedef struct command_symbol_upload
|
||||
{
|
||||
uint8_t header;
|
||||
|
||||
@@ -267,6 +267,7 @@ CPacketInfoGG::CPacketInfoGG()
|
||||
Set(HEADER_GG_MONARCH_NOTICE, sizeof(TPacketGGMonarchNotice), "MonarchNotice", false);
|
||||
Set(HEADER_GG_MONARCH_TRANSFER, sizeof(TPacketMonarchGGTransfer), "MonarchTransfer", false);
|
||||
Set(HEADER_GG_CHECK_AWAKENESS, sizeof(TPacketGGCheckAwakeness), "CheckAwakeness", false);
|
||||
Set(HEADER_GG_MARK_UPDATE, sizeof(TPacketGGMarkUpdate), "MarkUpdate", false);
|
||||
}
|
||||
|
||||
CPacketInfoGG::~CPacketInfoGG()
|
||||
|
||||
Reference in New Issue
Block a user