1558 lines
39 KiB
C++
1558 lines
39 KiB
C++
#include "stdafx.h"
|
|
#include "Map.h"
|
|
#include "KnightsManager.h"
|
|
#include "../shared/tstring.h"
|
|
#include "DBAgent.h"
|
|
#include "User.h"
|
|
|
|
// TODO: Move this to the CUser class.
|
|
void CKnightsManager::PacketProcess(CUser *pUser, Packet & pkt)
|
|
{
|
|
if (pUser == nullptr)
|
|
return;
|
|
|
|
uint8 opcode = pkt.read<uint8>();
|
|
|
|
if (pUser->isDead()
|
|
|| pUser->isTrading()
|
|
|| pUser->isMerchanting()
|
|
|| pUser->isStoreOpen()
|
|
|| pUser->isSellingMerchant()
|
|
|| pUser->isBuyingMerchant()
|
|
|| pUser->isMining()
|
|
|| pUser->m_bMerchantStatex)
|
|
return;
|
|
|
|
switch (opcode)
|
|
{
|
|
case KNIGHTS_CREATE:
|
|
CreateKnights(pUser, pkt);
|
|
break;
|
|
case KNIGHTS_JOIN:
|
|
JoinKnights(pUser, pkt);
|
|
break;
|
|
case KNIGHTS_WITHDRAW:
|
|
WithdrawKnights(pUser, pkt);
|
|
break;
|
|
case KNIGHTS_REMOVE:
|
|
case KNIGHTS_ADMIT:
|
|
case KNIGHTS_REJECT:
|
|
case KNIGHTS_CHIEF:
|
|
case KNIGHTS_VICECHIEF:
|
|
case KNIGHTS_OFFICER:
|
|
case KNIGHTS_PUNISH:
|
|
ModifyKnightsMember(pUser, pkt, opcode);
|
|
break;
|
|
case KNIGHTS_HANDOVER_VICECHIEF_LIST:
|
|
ModifyKnightsLeader(pUser, pkt, opcode);
|
|
break;
|
|
case KNIGHTS_HANDOVER_REQ:
|
|
ModifyKnightsLeader(pUser, pkt, opcode);
|
|
break;
|
|
case KNIGHTS_HANDOVER:
|
|
ModifyKnightsLeader(pUser, pkt, opcode);
|
|
break;
|
|
case KNIGHTS_POINT_METHOD:
|
|
ModifyKnightsPointMethod(pUser, pkt);
|
|
break;
|
|
case KNIGHTS_DESTROY:
|
|
DestroyKnights(pUser);
|
|
break;
|
|
case KNIGHTS_ALLLIST_REQ:
|
|
AllKnightsList(pUser, pkt);
|
|
break;
|
|
case KNIGHTS_MEMBER_REQ:
|
|
AllKnightsMember(pUser);
|
|
break;
|
|
case KNIGHTS_CURRENT_REQ:
|
|
CurrentKnightsMember(pUser, pkt);
|
|
break;
|
|
case KNIGHTS_JOIN_REQ:
|
|
JoinKnightsReq(pUser, pkt);
|
|
break;
|
|
case KNIGHTS_MARK_REGISTER:
|
|
RegisterClanSymbol(pUser, pkt);
|
|
break;
|
|
case KNIGHTS_MARK_VERSION_REQ:
|
|
RequestClanSymbolVersion(pUser, pkt);
|
|
break;
|
|
case KNIGHTS_MARK_REGION_REQ:
|
|
RequestClanSymbols(pUser, pkt);
|
|
break;
|
|
case KNIGHTS_MARK_REQ:
|
|
GetClanSymbol(pUser, pkt.read<uint16>());
|
|
break;
|
|
case KNIGHTS_ALLY_CREATE:
|
|
KnightsAllianceCreate(pUser, pkt);
|
|
break;
|
|
case KNIGHTS_ALLY_REQ:
|
|
KnightsAllianceRequest(pUser, pkt);
|
|
break;
|
|
case KNIGHTS_ALLY_INSERT:
|
|
KnightsAllianceInsert(pUser, pkt);
|
|
break;
|
|
case KNIGHTS_ALLY_REMOVE:
|
|
KnightsAllianceRemove(pUser, pkt);
|
|
break;
|
|
case KNIGHTS_ALLY_PUNISH:
|
|
KnightsAlliancePunish(pUser, pkt);
|
|
break;
|
|
case KNIGHTS_ALLY_LIST:
|
|
KnightsAllianceList(pUser, pkt);
|
|
break;
|
|
case KNIGHTS_TOP10:
|
|
ListTop10Clans(pUser);
|
|
break;
|
|
case KNIGHTS_POINT_REQ:
|
|
DonateNPReq(pUser, pkt);
|
|
break;
|
|
case KNIGHTS_DONATE_POINTS:
|
|
DonateNP(pUser, pkt);
|
|
break;
|
|
case KNIGHTS_DONATION_LIST:
|
|
DonationList(pUser, pkt);
|
|
break;
|
|
case KNIGHTS_NOTICE:
|
|
UpdateClanNotice(pUser,pkt);
|
|
break;
|
|
case KNIGHTS_MEMO:
|
|
UpdateKnightMemo(pUser,pkt);
|
|
break;
|
|
default:
|
|
TRACE("Unhandled clan system opcode: %X\n", opcode);
|
|
}
|
|
}
|
|
|
|
void CKnightsManager::CreateKnights(CUser* pUser, Packet & pkt)
|
|
{
|
|
if (pUser == nullptr)
|
|
return;
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS, uint8(KNIGHTS_CREATE));
|
|
std::string idname;
|
|
uint8 ret_value = 0;
|
|
pkt >> idname;
|
|
|
|
if (idname.empty() || idname.size() > MAX_ID_SIZE
|
|
|| !IsAvailableName(idname.c_str())
|
|
|| !g_pMain->WordGuardSystem(idname,idname.length()))
|
|
ret_value = 3;
|
|
else if (pUser->GetClanID() != 0)
|
|
ret_value = 5;
|
|
else if (g_pMain->m_nServerGroup == 2)
|
|
ret_value = 8;
|
|
else if (!pUser->GetMap()->canUpdateClan())
|
|
ret_value = 9;
|
|
else if (pUser->GetLevel() < CLAN_LEVEL_REQUIREMENT)
|
|
ret_value = 2;
|
|
else if (!pUser->hasCoins(CLAN_COIN_REQUIREMENT))
|
|
ret_value = 4;
|
|
|
|
if (ret_value == 0)
|
|
{
|
|
uint16 knightindex = GetKnightsIndex(pUser->m_bNation);
|
|
if (knightindex >= 0)
|
|
{
|
|
result << uint8(g_pMain->RoyalG1 ? ClanTypeRoyal1 : ClanTypeTraining)
|
|
<< knightindex << pUser->GetNation()
|
|
<< idname << pUser->GetName();
|
|
g_pMain->AddDatabaseRequest(result, pUser);
|
|
return;
|
|
}
|
|
ret_value = 6;
|
|
}
|
|
|
|
result << ret_value;
|
|
pUser->Send(&result);
|
|
}
|
|
|
|
bool CKnightsManager::IsAvailableName( const char *strname)
|
|
{
|
|
foreach_stlmap (itr, g_pMain->m_KnightsArray)
|
|
if (STRCASECMP(itr->second->GetName().c_str(), strname) == 0)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
int CKnightsManager::GetKnightsIndex( int nation )
|
|
{
|
|
Guard lock(g_pMain->m_KnightsArray.m_lock);
|
|
|
|
int knightindex = 0;
|
|
if (nation == ELMORAD) knightindex = 15000;
|
|
|
|
foreach_stlmap (itr, g_pMain->m_KnightsArray)
|
|
{
|
|
if (itr->second != nullptr &&
|
|
knightindex < itr->second->GetID())
|
|
{
|
|
if (nation == KARUS && itr->second->GetID() >= 15000)
|
|
continue;
|
|
|
|
knightindex = itr->second->GetID();
|
|
}
|
|
}
|
|
|
|
knightindex++;
|
|
if ((nation == KARUS && (knightindex >= 15000 || knightindex < 0))
|
|
|| nation == ELMORAD && (knightindex < 15000 || knightindex > 30000)
|
|
|| g_pMain->GetClanPtr(knightindex))
|
|
return -1;
|
|
|
|
return knightindex;
|
|
}
|
|
|
|
void CKnightsManager::JoinKnights(CUser *pUser, Packet & pkt)
|
|
{
|
|
if (pUser == nullptr)
|
|
return;
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS);
|
|
uint8 bResult = 0;
|
|
|
|
do
|
|
{
|
|
if (!pUser->GetMap()->canUpdateClan())
|
|
bResult = 12;
|
|
else if (!pUser->isClanLeader() && !pUser->isClanAssistant())
|
|
bResult = 6;
|
|
|
|
if (bResult != 0)
|
|
break;
|
|
|
|
uint16 sClanID = pUser->GetClanID();
|
|
CKnights *pKnights = g_pMain->GetClanPtr(sClanID);
|
|
if (pKnights == nullptr)
|
|
{
|
|
bResult = 7;
|
|
break;
|
|
}
|
|
|
|
CUser *pTUser = g_pMain->GetUserPtr(pkt.read<uint16>());
|
|
if (pTUser == nullptr)
|
|
bResult = 2;
|
|
else if (pTUser->isDead())
|
|
bResult = 3;
|
|
else if (pTUser->GetNation() != pUser->GetNation())
|
|
bResult = 4;
|
|
else if (pTUser->GetClanID() > 0)
|
|
bResult = 5;
|
|
|
|
if (bResult != 0)
|
|
break;
|
|
|
|
result << uint8(KNIGHTS_JOIN_REQ) << uint8(1)
|
|
<< pUser->GetSocketID() << sClanID << pKnights->m_strName;
|
|
pTUser->Send(&result);
|
|
|
|
pTUser->AchieveType4(10);
|
|
|
|
return;
|
|
} while (0);
|
|
|
|
|
|
result << uint8(KNIGHTS_JOIN) << bResult;
|
|
pUser->Send(&result);
|
|
}
|
|
|
|
void CKnightsManager::JoinKnightsReq(CUser *pUser, Packet & pkt)
|
|
{
|
|
if (pUser == nullptr)
|
|
return;
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS, uint8(KNIGHTS_JOIN));
|
|
uint8 bFlag, bResult = 0;
|
|
uint16 sid, sClanID;
|
|
pkt >> bFlag >> sid >> sClanID;
|
|
CUser *pTUser = g_pMain->GetUserPtr(sid);
|
|
if (pTUser == nullptr)
|
|
bResult = 2;
|
|
else if (bFlag == 0)
|
|
bResult = 11;
|
|
else
|
|
{
|
|
CKnights *pKnights = g_pMain->GetClanPtr(sClanID);
|
|
if (pKnights == nullptr)
|
|
bResult = 7;
|
|
else if (pKnights->m_sMembers >= MAX_CLAN_USERS)
|
|
bResult = 8;
|
|
}
|
|
|
|
if (bResult != 0)
|
|
{
|
|
result << bResult;
|
|
pUser->Send(&result);
|
|
}
|
|
else
|
|
{
|
|
result << sClanID;
|
|
g_pMain->AddDatabaseRequest(result, pUser);
|
|
}
|
|
}
|
|
|
|
void CKnightsManager::WithdrawKnights(CUser *pUser, Packet & pkt)
|
|
{
|
|
if (pUser == nullptr)
|
|
return;
|
|
|
|
CKnights * pKinghts = g_pMain->GetClanPtr(pUser->m_bKnights);
|
|
Packet result(WIZ_KNIGHTS_PROCESS);
|
|
uint8 bResult = 0;
|
|
do
|
|
{
|
|
if (!pUser->isInClan())
|
|
bResult = 10;
|
|
else if (pUser->isClanLeader() && !pUser->GetMap()->canUpdateClan())
|
|
bResult = 12;
|
|
|
|
if (bResult != 0)
|
|
break;
|
|
|
|
result << uint8(pUser->isClanLeader() ? KNIGHTS_DESTROY : KNIGHTS_WITHDRAW)
|
|
<< pUser->GetClanID();
|
|
|
|
if (pUser->isClanLeader())
|
|
ReqKnightsAllianceRemove(pUser, pkt);
|
|
|
|
g_pMain->AddDatabaseRequest(result, pUser);
|
|
return;
|
|
} while (0);
|
|
result << bResult;
|
|
pUser->Send(&result);
|
|
}
|
|
|
|
void CKnightsManager::DestroyKnights( CUser* pUser )
|
|
{
|
|
if (pUser == nullptr)
|
|
return;
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS, uint8(KNIGHTS_DESTROY));
|
|
uint8 bResult = 1;
|
|
if (!pUser->isClanLeader() || !pUser->isInClan())
|
|
bResult = 0;
|
|
else if (!pUser->GetMap()->canUpdateClan())
|
|
bResult = 12;
|
|
|
|
if (bResult == 1)
|
|
{
|
|
result << pUser->GetClanID();
|
|
g_pMain->AddDatabaseRequest(result, pUser);
|
|
}
|
|
else
|
|
{
|
|
result << bResult;
|
|
pUser->Send(&result);
|
|
}
|
|
}
|
|
|
|
void CKnightsManager::ModifyKnightsLeader(CUser *pUser, Packet & pkt, uint8 opcode)
|
|
{
|
|
if (pUser == nullptr)
|
|
return;
|
|
|
|
CKnights* pKnights = g_pMain->GetClanPtr(pUser->GetClanID());
|
|
|
|
if (pKnights == nullptr)
|
|
return;
|
|
|
|
uint8 isClanLeader = pUser->isClanLeader() ? 1 : 2;
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS);
|
|
|
|
if (opcode == KNIGHTS_HANDOVER_VICECHIEF_LIST)
|
|
{
|
|
uint16 ViceChiefCount = 0;
|
|
|
|
if (g_pMain->GetUserPtr(pKnights->m_strViceChief_1, TYPE_CHARACTER))
|
|
ViceChiefCount++;
|
|
|
|
if (g_pMain->GetUserPtr(pKnights->m_strViceChief_2, TYPE_CHARACTER))
|
|
ViceChiefCount++;
|
|
|
|
if (g_pMain->GetUserPtr(pKnights->m_strViceChief_3, TYPE_CHARACTER))
|
|
ViceChiefCount++;
|
|
|
|
result << opcode << isClanLeader << ViceChiefCount << pKnights->m_strViceChief_1 << pKnights->m_strViceChief_2 << pKnights->m_strViceChief_3;
|
|
pUser->Send(&result);
|
|
}
|
|
else if (opcode == KNIGHTS_HANDOVER_REQ)
|
|
{
|
|
if (isClanLeader)
|
|
{
|
|
std::string strUserID;
|
|
pkt >> strUserID;
|
|
|
|
CUser *pTUser = g_pMain->GetUserPtr(strUserID, TYPE_CHARACTER);
|
|
|
|
if (pTUser == nullptr)
|
|
return;
|
|
|
|
pKnights->m_strChief = strUserID;
|
|
|
|
if (pKnights->m_strViceChief_1 == strUserID) pKnights->m_strViceChief_1 = "";
|
|
else if (pKnights->m_strViceChief_2 == strUserID) pKnights->m_strViceChief_2 = "";
|
|
else if (pKnights->m_strViceChief_3 == strUserID) pKnights->m_strViceChief_3 = "";
|
|
else return;
|
|
g_DBAgent.UpdateKnights((uint8)KNIGHTS_HANDOVER, strUserID, pUser->GetClanID(), 0);
|
|
|
|
result << (uint8)KNIGHTS_HANDOVER << pUser->GetName() << strUserID;
|
|
pUser->Send(&result);
|
|
pUser->ChangeFame(TRAINEE);
|
|
g_DBAgent.UpdateUser(pUser->GetName(),UPDATE_PACKET_SAVE,pUser);
|
|
AllKnightsMember(pUser);
|
|
|
|
result.clear();
|
|
result << (uint8)KNIGHTS_HANDOVER << strUserID << pUser->GetName();
|
|
pTUser->Send(&result);
|
|
pTUser->ChangeFame(CHIEF);
|
|
g_DBAgent.UpdateUser(pTUser->GetName(),UPDATE_PACKET_SAVE,pTUser);
|
|
AllKnightsMember(pTUser);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CKnightsManager::ModifyKnightsMember(CUser *pUser, Packet & pkt, uint8 opcode)
|
|
{
|
|
if (pUser == nullptr)
|
|
return;
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS, opcode);
|
|
uint8 bResult = 1, bRemoveFlag = 0;
|
|
std::string strUserID;
|
|
|
|
pkt >> strUserID;
|
|
if (pUser->GetName() == strUserID)
|
|
return;
|
|
|
|
do
|
|
{
|
|
if (strUserID.empty() || strUserID.size() > MAX_ID_SIZE)
|
|
bResult = 2;
|
|
else if (!pUser->GetMap()->canUpdateClan())
|
|
bResult = 12;
|
|
else if (STRCASECMP(strUserID.c_str(), pUser->GetName().c_str()) == 0)
|
|
bResult = 9;
|
|
else if (((opcode == KNIGHTS_ADMIT || opcode == KNIGHTS_REJECT) && pUser->GetFame() < OFFICER)
|
|
|| (opcode == KNIGHTS_PUNISH && pUser->GetFame() < VICECHIEF))
|
|
bResult = 0;
|
|
else if (opcode != KNIGHTS_ADMIT && opcode != KNIGHTS_REJECT && opcode != KNIGHTS_PUNISH
|
|
&& !pUser->isClanLeader())
|
|
bResult = 6;
|
|
CKnights *pKnight = g_pMain->GetClanPtr(pUser->GetClanID());
|
|
if (pKnight->m_strViceChief_1 == "")
|
|
bResult = 1;
|
|
else if (pKnight->m_strViceChief_2 == "")
|
|
bResult = 1;
|
|
else if (pKnight->m_strViceChief_3 == "")
|
|
bResult = 1;
|
|
else if (opcode == KNIGHTS_VICECHIEF) bResult = 0;
|
|
|
|
if (bResult != 1)
|
|
break;
|
|
|
|
CUser *pTUser = g_pMain->GetUserPtr(strUserID, TYPE_CHARACTER);
|
|
if (pTUser == nullptr)
|
|
{
|
|
if (opcode != KNIGHTS_REMOVE)
|
|
bResult = 2;
|
|
}
|
|
else
|
|
{
|
|
if (pUser->GetNation() != pTUser->GetNation())
|
|
bResult = 4;
|
|
else if (pUser->GetClanID() != pTUser->GetClanID())
|
|
bResult = 5;
|
|
|
|
if (bResult == 1 && opcode == KNIGHTS_VICECHIEF)
|
|
{
|
|
if (pTUser->isClanAssistant())
|
|
bResult = 8;
|
|
else if (!g_pMain->GetClanPtr(pUser->GetClanID()))
|
|
bResult = 7;
|
|
}
|
|
|
|
bRemoveFlag = 1;
|
|
}
|
|
|
|
if (bResult != 1)
|
|
break;
|
|
|
|
result << pUser->GetClanID() << strUserID << bRemoveFlag;
|
|
g_pMain->AddDatabaseRequest(result, pUser);
|
|
return;
|
|
} while (0);
|
|
|
|
result << bResult;
|
|
pUser->Send(&result);
|
|
}
|
|
|
|
|
|
void CKnightsManager::ModifyKnightsPointMethod(CUser *pUser, Packet & pkt)
|
|
{
|
|
if (pUser == nullptr && !pUser->isClanLeader())
|
|
return;
|
|
|
|
CKnights *pKnights = g_pMain->GetClanPtr(pUser->GetClanID());
|
|
|
|
if (pKnights == nullptr)
|
|
return;
|
|
|
|
uint8 subCode = 0;
|
|
pkt >> subCode;
|
|
|
|
uint8 bResult = 1;
|
|
|
|
if (pKnights->m_byFlag >= ClanTypeAccredited5)
|
|
pKnights->m_sClanPointMethod = subCode != 0 ? subCode - 1 : pKnights->m_sClanPointMethod;
|
|
else
|
|
bResult = 2;
|
|
|
|
g_DBAgent.UpdateKnights((uint8)KNIGHTS_POINT_METHOD, pUser->GetName(), pUser->GetClanID(), pKnights->GetClanPointMethod());
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS, (uint8)KNIGHTS_POINT_METHOD);
|
|
result << bResult << pKnights->GetClanPointMethod();
|
|
pUser->Send(&result);
|
|
}
|
|
|
|
void CKnightsManager::AllKnightsList(CUser *pUser, Packet & pkt)
|
|
{
|
|
if (pUser == nullptr)
|
|
return;
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS, uint8(KNIGHTS_ALLLIST_REQ));
|
|
uint16 sPage = pkt.read<uint16>(), start = sPage * 10, count = 0;
|
|
result << uint8(1) << sPage << count;
|
|
|
|
foreach_stlmap (itr, g_pMain->m_KnightsArray)
|
|
{
|
|
CKnights* pKnights = itr->second;
|
|
if (pKnights == nullptr
|
|
|| !pKnights->isPromoted()
|
|
|| pKnights->m_byNation != pUser->GetNation()
|
|
|| count++ < start)
|
|
continue;
|
|
|
|
result << uint16(pKnights->m_sIndex) << pKnights->m_strName
|
|
<< uint16(pKnights->m_sMembers) << pKnights->m_strChief
|
|
<< uint32(pKnights->m_nPoints);
|
|
if (count >= start + 10)
|
|
break;
|
|
}
|
|
|
|
count -= start;
|
|
result.put(4, count);
|
|
pUser->Send(&result);
|
|
}
|
|
|
|
void CKnightsManager::AllKnightsMember(CUser *pUser)
|
|
{
|
|
if (pUser == nullptr)
|
|
return;
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS, uint8(KNIGHTS_MEMBER_REQ));
|
|
uint8 bResult = 1;
|
|
|
|
if (!pUser->isInClan())
|
|
bResult = 2;
|
|
else if (g_pMain->GetClanPtr(pUser->GetClanID()) == nullptr)
|
|
bResult = 7;
|
|
|
|
result << bResult;
|
|
if (bResult == 1)
|
|
{
|
|
CKnights* pKnights = g_pMain->GetClanPtr(pUser->GetClanID());
|
|
|
|
uint16 pktSize = 0, count = 0;
|
|
result << pktSize << count << uint16(MAX_CLAN_USERS) << pKnights->m_strClanNotice << count; // placeholders
|
|
pktSize = (uint16)result.size();
|
|
count = g_pMain->GetKnightsAllMembers(pUser->GetClanID(), result, pktSize, pUser->isClanLeader());
|
|
if (count > MAX_CLAN_USERS)
|
|
return;
|
|
|
|
pktSize = ((uint16)result.size() - pktSize) + 6;
|
|
result.put(2, pktSize);
|
|
result.put(4, count);
|
|
result.put(10+pKnights->m_strClanNotice.size(), count);
|
|
}
|
|
pUser->Send(&result);
|
|
}
|
|
|
|
void CKnightsManager::CurrentKnightsMember(CUser *pUser, Packet & pkt)
|
|
{
|
|
if (pUser == nullptr)
|
|
return;
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS, uint8(KNIGHTS_CURRENT_REQ));
|
|
CKnights *pKnights = nullptr;
|
|
if (!pUser->isInClan()
|
|
|| (pKnights = g_pMain->GetClanPtr(pUser->GetClanID())) == nullptr)
|
|
{
|
|
result << uint8(0); // failed
|
|
result << "is this error still used?";
|
|
pUser->Send(&result);
|
|
return;
|
|
}
|
|
|
|
uint16 page = pkt.read<uint16>();
|
|
uint16 start = page * 10;
|
|
uint16 count = 0;
|
|
|
|
result << uint8(1) // success
|
|
<< pKnights->m_strChief
|
|
<< page;
|
|
|
|
size_t pos = result.wpos();
|
|
result << count; // placeholder
|
|
|
|
foreach_array (i, pKnights->m_arKnightsUser)
|
|
{
|
|
_KNIGHTS_USER *p = &pKnights->m_arKnightsUser[i];
|
|
if (!p->byUsed
|
|
|| count++ < start)
|
|
continue;
|
|
|
|
CUser *pTUser = p->pSession;
|
|
result << pUser->GetName() << pUser->GetFame() << pUser->GetLevel() << pUser->GetClass() << uint32(0);
|
|
count++;
|
|
if (count >= start + 10)
|
|
break;
|
|
}
|
|
|
|
count -= start;
|
|
result.put(pos, count);
|
|
pUser->Send(&result);
|
|
}
|
|
|
|
void CKnightsManager::RecvUpdateKnights(CUser *pUser, Packet & pkt, uint8 command)
|
|
{
|
|
if (pUser == nullptr)
|
|
return;
|
|
|
|
uint16 sClanID = pkt.read<uint16>();
|
|
CKnights *pKnights = g_pMain->GetClanPtr(sClanID);
|
|
if (pKnights == nullptr)
|
|
return;
|
|
|
|
if (command == KNIGHTS_JOIN)
|
|
{
|
|
std::string noticeText;
|
|
g_pMain->GetServerResource(IDS_KNIGHTS_JOIN, ¬iceText, pUser->GetName().c_str());
|
|
pKnights->AddUser(pUser);
|
|
pKnights->SendChat("%s", noticeText.c_str());
|
|
|
|
}
|
|
else if (command == KNIGHTS_WITHDRAW || command == KNIGHTS_REMOVE)
|
|
{
|
|
pKnights->RemoveUser(pUser);
|
|
}
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS, command);
|
|
result << uint8(1) << pUser->GetSocketID() << pUser->GetClanID() << pUser->GetFame();
|
|
|
|
CKnights *aKnights = g_pMain->GetClanPtr(pKnights->GetAllianceID());
|
|
|
|
if (command == KNIGHTS_JOIN)
|
|
{
|
|
result << pKnights->m_byFlag
|
|
<< pKnights->GetAllianceID()
|
|
<< pKnights->GetCapeID(aKnights)
|
|
<< pKnights->m_bCapeR << pKnights->m_bCapeG << pKnights->m_bCapeB << uint8(0)
|
|
<< int16(pKnights->m_sMarkVersion)
|
|
<< pKnights->m_strName << pKnights->m_byGrade << pKnights->m_byRanking;
|
|
}
|
|
|
|
pUser->SendToRegion(&result,nullptr,pUser->GetEventRoom());
|
|
}
|
|
|
|
void CKnightsManager::RecvModifyFame(CUser *pUser, Packet & pkt, uint8 command)
|
|
{
|
|
if (pUser == nullptr)
|
|
return;
|
|
|
|
std::string clanNotice;
|
|
std::string strUserID;
|
|
uint16 sClanID;
|
|
|
|
pkt >> sClanID >> strUserID;
|
|
|
|
CUser *pTUser = g_pMain->GetUserPtr(strUserID, TYPE_CHARACTER);
|
|
CKnights *pKnights = g_pMain->GetClanPtr(sClanID);
|
|
|
|
switch (command)
|
|
{
|
|
case KNIGHTS_REMOVE:
|
|
if (pTUser != nullptr)
|
|
pKnights->RemoveUser(pTUser);
|
|
else
|
|
pKnights->RemoveUser(strUserID);
|
|
|
|
g_pMain->GetServerResource(IDS_KNIGHTS_REMOVE, &clanNotice, pTUser == nullptr ? strUserID.c_str() : pTUser->GetName().c_str());
|
|
break;
|
|
case KNIGHTS_ADMIT:
|
|
if (pTUser != nullptr)
|
|
pTUser->m_bFame = KNIGHT;
|
|
break;
|
|
case KNIGHTS_REJECT:
|
|
if (pTUser != nullptr)
|
|
{
|
|
pTUser->SetClanID(0);
|
|
pTUser->m_bFame = 0;
|
|
|
|
RemoveKnightsUser(sClanID, pTUser->GetName());
|
|
}
|
|
break;
|
|
case KNIGHTS_CHIEF:
|
|
if (pTUser != nullptr)
|
|
{
|
|
pTUser->m_bFame = CHIEF;
|
|
g_pMain->GetServerResource(IDS_KNIGHTS_CHIEF, &clanNotice, pTUser->GetName().c_str());
|
|
}
|
|
break;
|
|
case KNIGHTS_VICECHIEF:
|
|
if (pTUser != nullptr)
|
|
{
|
|
pTUser->m_bFame = VICECHIEF;
|
|
g_pMain->GetServerResource(IDS_KNIGHTS_VICECHIEF, &clanNotice, pTUser->GetName().c_str());
|
|
}
|
|
break;
|
|
case KNIGHTS_OFFICER:
|
|
if (pTUser != nullptr)
|
|
pTUser->m_bFame = OFFICER;
|
|
break;
|
|
case KNIGHTS_PUNISH:
|
|
if (pTUser != nullptr)
|
|
pTUser->m_bFame = PUNISH;
|
|
break;
|
|
}
|
|
|
|
if (pTUser != nullptr)
|
|
pTUser->SendClanUserStatusUpdate(command == KNIGHTS_REMOVE);
|
|
|
|
if (clanNotice.empty())
|
|
return;
|
|
|
|
// Construct the clan system chat packet
|
|
Packet result;
|
|
ChatPacket::Construct(&result, KNIGHTS_CHAT, &clanNotice);
|
|
|
|
// If we've been removed from a clan, tell the user as well (since they're no longer in the clan)
|
|
if (command == KNIGHTS_REMOVE && pTUser != nullptr)
|
|
pTUser->Send(&result);
|
|
|
|
// Otherwise, since we're actually in the clan, we don't need to be explicitly told what happened.
|
|
if (pKnights != nullptr)
|
|
pKnights->Send(&result);
|
|
}
|
|
|
|
bool CKnightsManager::AddKnightsUser(int index, std::string & strUserID)
|
|
{
|
|
CKnights *pKnights = g_pMain->GetClanPtr(index);
|
|
return (pKnights == nullptr ? false : pKnights->AddUser(strUserID));
|
|
}
|
|
|
|
bool CKnightsManager::RemoveKnightsUser(int index, std::string & strUserID)
|
|
{
|
|
CKnights *pKnights = g_pMain->GetClanPtr(index);
|
|
return (pKnights == nullptr ? false : pKnights->RemoveUser(strUserID));
|
|
}
|
|
|
|
void CKnightsManager::UpdateKnightsGrade(uint16 sClanID, uint8 byFlag)
|
|
{
|
|
CKnights * pClan = g_pMain->GetClanPtr(sClanID);
|
|
if (pClan == nullptr)
|
|
return;
|
|
|
|
if (byFlag == ClanTypeTraining)
|
|
pClan->m_sCape = -1;
|
|
else if (byFlag == ClanTypePromoted)
|
|
pClan->m_sCape = 0;
|
|
|
|
pClan->m_byFlag = byFlag;
|
|
pClan->SendUpdate();
|
|
|
|
// Update the database server
|
|
Packet result(WIZ_KNIGHTS_PROCESS, uint8(KNIGHTS_UPDATE_GRADE));
|
|
result << sClanID << byFlag << pClan->m_sCape;
|
|
g_pMain->AddDatabaseRequest(result);
|
|
}
|
|
|
|
void CKnightsManager::UpdateClanPoint(uint16 sClanID, int32 nChangeAmount)
|
|
{
|
|
CKnights * pClan = g_pMain->GetClanPtr(sClanID);
|
|
if (pClan == nullptr)
|
|
return;
|
|
|
|
if (nChangeAmount > 0)
|
|
{
|
|
if (pClan->m_nClanPointFund + nChangeAmount > LOYALTY_MAX)
|
|
pClan->m_nClanPointFund = LOYALTY_MAX;
|
|
else
|
|
pClan->m_nClanPointFund += nChangeAmount;
|
|
}
|
|
else
|
|
{
|
|
uint32 pChangeAmount = -nChangeAmount;
|
|
|
|
if (pChangeAmount > pClan->m_nClanPointFund)
|
|
pClan->m_nClanPointFund = 0;
|
|
else
|
|
pClan->m_nClanPointFund -= pChangeAmount;
|
|
}
|
|
|
|
pClan->UpdateClanFund();
|
|
}
|
|
|
|
void CKnightsManager::LoadUserDonatedNP(int index, std::string & strUserID, uint32 nDonatedNP, bool bIsKillReward)
|
|
{
|
|
|
|
CKnights *pKnights = g_pMain->GetClanPtr(index);
|
|
if (pKnights == nullptr)
|
|
return;
|
|
|
|
std::string Name = "", myName = strUserID;
|
|
STRTOUPPER(myName);
|
|
|
|
for (int i = 0; i < MAX_CLAN_USERS; i++)
|
|
{
|
|
if (pKnights->m_arKnightsUser[i].byUsed == 0)
|
|
continue;
|
|
|
|
Name = pKnights->m_arKnightsUser[i].strUserName;
|
|
STRTOUPPER(Name);
|
|
if(Name != myName)
|
|
continue;
|
|
|
|
pKnights->m_arKnightsUser[i].nDonatedNP = nDonatedNP;
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void CKnightsManager::AddUserDonatedNPinGame(int index, CUser * pUser, uint32 nDonatedNP, bool bIsKillReward)
|
|
{
|
|
CKnights *pKnights = g_pMain->GetClanPtr(index);
|
|
if (pKnights == nullptr || pUser == nullptr)
|
|
return;
|
|
|
|
pKnights->m_nClanPointFund += nDonatedNP;
|
|
|
|
foreach_array(i,pKnights->m_arKnightsUser)
|
|
{
|
|
_KNIGHTS_USER *p = &pKnights->m_arKnightsUser[i];
|
|
if (!p->byUsed || p->pSession == nullptr)
|
|
continue;
|
|
|
|
if (p->pSession->GetID() == pUser->GetID())
|
|
{
|
|
pKnights->m_arKnightsUser[i].nDonatedNP += nDonatedNP;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
pUser->AchieveType4(5);
|
|
}
|
|
|
|
void CKnightsManager::RecvKnightsAllList(Packet & pkt)
|
|
{
|
|
Packet result(WIZ_KNIGHTS_PROCESS, uint8(KNIGHTS_ALLLIST_REQ));
|
|
uint8 count = pkt.read<uint8>(), send_count = 0;
|
|
result << send_count; // placeholder for count
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
uint32 nPoints; uint16 sClanID; uint8 bRank;
|
|
pkt >> sClanID >> nPoints >> bRank;
|
|
|
|
CKnights *pKnights = g_pMain->GetClanPtr(sClanID);
|
|
if (pKnights == nullptr)
|
|
continue;
|
|
|
|
if (pKnights->m_nPoints != nPoints
|
|
|| pKnights->m_byRanking != bRank)
|
|
{
|
|
pKnights->m_nPoints = nPoints;
|
|
pKnights->m_byRanking = bRank;
|
|
pKnights->m_byGrade = g_pMain->GetKnightsGrade(nPoints);
|
|
|
|
result << sClanID << pKnights->m_byGrade << pKnights->m_byRanking;
|
|
send_count++;
|
|
}
|
|
}
|
|
|
|
result.put(1, send_count);
|
|
g_pMain->Send_All(&result);
|
|
}
|
|
|
|
void CKnightsManager::RegisterClanSymbol(CUser* pUser, Packet & pkt)
|
|
{
|
|
if (pUser == nullptr || !pUser->isInClan())
|
|
return;
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS, uint8(KNIGHTS_MARK_REGISTER));
|
|
CKnights *pKnights = nullptr;
|
|
char clanSymbol[MAX_KNIGHTS_MARK];
|
|
uint16 sFailCode = 1, sSymbolSize = pkt.read<uint16>();
|
|
|
|
// Are they even a clan leader?
|
|
if (!pUser->isClanLeader())
|
|
sFailCode = 11;
|
|
// Invalid zone (only in home zones)
|
|
else if (pUser->GetZoneID() != pUser->GetNation())
|
|
sFailCode = 12;
|
|
// Invalid symbol size (or invalid packet)
|
|
else if (sSymbolSize == 0
|
|
|| sSymbolSize > MAX_KNIGHTS_MARK
|
|
|| pkt.size() < sSymbolSize)
|
|
sFailCode = 13;
|
|
// User doesn't have enough coins
|
|
else if (pUser->m_iGold < CLAN_SYMBOL_COST)
|
|
sFailCode = 14;
|
|
// Clan doesn't exist
|
|
else if ((pKnights = g_pMain->GetClanPtr(pUser->GetClanID())) == nullptr)
|
|
sFailCode = 20;
|
|
// Clan not promoted
|
|
else if (!pKnights->isPromoted())
|
|
sFailCode = 11;
|
|
|
|
// Uh oh, did we error?
|
|
if (sFailCode != 1)
|
|
{
|
|
result << sFailCode;
|
|
pUser->Send(&result);
|
|
return;
|
|
}
|
|
|
|
// Read the clan symbol from the packet
|
|
pkt.read(clanSymbol, sSymbolSize);
|
|
|
|
// Nope? Let's update the clan symbol.
|
|
result << pUser->GetClanID() << sSymbolSize;
|
|
result.append(clanSymbol, sSymbolSize);
|
|
g_pMain->AddDatabaseRequest(result, pUser);
|
|
}
|
|
|
|
void CKnightsManager::RequestClanSymbolVersion(CUser* pUser, Packet & pkt)
|
|
{
|
|
if (pUser == nullptr
|
|
|| !pUser->isInClan())
|
|
return;
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS, uint8(KNIGHTS_MARK_VERSION_REQ));
|
|
int16 sFailCode = 1;
|
|
|
|
CKnights *pKnights = g_pMain->GetClanPtr(pUser->GetClanID());
|
|
if (pKnights == nullptr || !pKnights->isPromoted() || !pUser->isClanLeader())
|
|
sFailCode = 11;
|
|
else if (pUser->GetZoneID() != pUser->GetNation())
|
|
sFailCode = 12;
|
|
|
|
result << sFailCode;
|
|
|
|
if (sFailCode == 1)
|
|
result << uint16(pKnights->m_sMarkVersion);
|
|
|
|
pUser->Send(&result);
|
|
}
|
|
|
|
/**
|
|
* The clan member (leader only?) tells groups of users to update the clan symbols
|
|
* they have for this clan. This is a horrible, horrible idea.
|
|
**/
|
|
void CKnightsManager::RequestClanSymbols(CUser* pUser, Packet & pkt)
|
|
{
|
|
// Should we force them to be a clan leader too?
|
|
// Need to check if *any* clan member can trigger this, or if it's just leaders.
|
|
if (pUser == nullptr
|
|
|| !pUser->isInClan())
|
|
return;
|
|
|
|
uint16 sCount = pkt.read<uint16>();
|
|
if (sCount > 100)
|
|
sCount = 100;
|
|
|
|
for (int i = 0; i < sCount; i++)
|
|
{
|
|
uint16 sid = pkt.read<uint16>();
|
|
CUser *pTUser = g_pMain->GetUserPtr(sid);
|
|
if (pTUser == nullptr
|
|
|| !pTUser->isInGame())
|
|
continue;
|
|
|
|
// This is really quite scary that users can send directly to specific players like this.
|
|
// Quite possibly we should replace this with a completely server-side implementation.
|
|
GetClanSymbol(pTUser, pUser->GetClanID());
|
|
}
|
|
}
|
|
|
|
void CKnightsManager::GetClanSymbol(CUser* pUser, uint16 sClanID)
|
|
{
|
|
if (pUser == nullptr)
|
|
return;
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS);
|
|
CKnights *pKnights = g_pMain->GetClanPtr(sClanID);
|
|
|
|
// Dose that clan exist?
|
|
if (pKnights == nullptr
|
|
// Are they promoted?
|
|
|| !pKnights->isPromoted()
|
|
// Is their symbol version set?
|
|
|| pKnights->m_sMarkVersion == 0
|
|
// The clan symbol is more than 0 bytes, right?
|
|
|| pKnights->m_sMarkLen <= 0)
|
|
return;
|
|
|
|
result << uint8(KNIGHTS_MARK_REQ) << uint16(1); // success
|
|
result << uint16(pKnights->m_byNation) << sClanID
|
|
<< uint16(pKnights->m_sMarkVersion) << uint16(pKnights->m_sMarkLen);
|
|
result.append(pKnights->m_Image, pKnights->m_sMarkLen);
|
|
pUser->SendCompressed(&result);
|
|
}
|
|
|
|
/**
|
|
* @brief Performs CSW/Delos checks to determine whether an alliance
|
|
* can be made with the specified clan.
|
|
*
|
|
* @param pMainClan The clan seeking to form an alliance.
|
|
* @param pTargetClan Target clan an alliance is being formed with.
|
|
*
|
|
* @return true if it succeeds, false if it fails.
|
|
*/
|
|
bool CKnightsManager::CheckAlliance(CKnights * pMainClan, CKnights * pTargetClan)
|
|
{
|
|
_KNIGHTS_ALLIANCE * pMainAlliance = g_pMain->GetAlliancePtr(pMainClan->GetAllianceID()) ,
|
|
* pTargetAlliance = g_pMain->GetAlliancePtr(pTargetClan->GetAllianceID());
|
|
if(pMainAlliance == pTargetAlliance && (pMainAlliance != nullptr || pTargetAlliance != nullptr))
|
|
return true;
|
|
else
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
void CKnightsManager::KnightsAllianceCreate(CUser* pUser, Packet & pkt)
|
|
{
|
|
if (pUser == nullptr || pUser->isDead())
|
|
return;
|
|
Packet result(WIZ_KNIGHTS_PROCESS, uint8(KNIGHTS_ALLY_CREATE));
|
|
CKnights * pKnights = g_pMain->GetClanPtr(pUser->m_bKnights);
|
|
|
|
if(pKnights->m_byFlag > 1 && pKnights->m_strChief == pUser->GetName())
|
|
{
|
|
result << uint8(1) << pUser->m_bKnights;
|
|
g_pMain->AddDatabaseRequest(result, pUser);
|
|
pUser->Send(&result);
|
|
}
|
|
}
|
|
void CKnightsManager::KnightsAllianceInsert(CUser* pUser, Packet & pkt)
|
|
{
|
|
if (pUser == nullptr)
|
|
return;
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS);
|
|
result.SByte();
|
|
uint8 bResult = 0;
|
|
|
|
do
|
|
{
|
|
if (!pUser->isClanLeader() && !pUser->isClanAssistant())
|
|
bResult = 6;
|
|
|
|
if (bResult != 0)
|
|
break;
|
|
|
|
uint16 sClanID = pUser->GetClanID();
|
|
CKnights *pKnights = g_pMain->GetClanPtr(sClanID);
|
|
_KNIGHTS_ALLIANCE * pAlliance = g_pMain->GetAlliancePtr(pUser->m_bKnights);
|
|
if (pAlliance == nullptr)
|
|
{
|
|
CKnights * pTknights = g_pMain->GetClanPtr(pUser->m_bKnights);
|
|
|
|
if(pTknights != nullptr && pKnights->m_byFlag > 1 && pKnights->m_strChief == pUser->GetName())
|
|
{
|
|
result<< uint8(KNIGHTS_ALLY_CREATE) << uint8(1) << pUser->m_bKnights;
|
|
g_pMain->AddDatabaseRequest(result, pUser);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pKnights == nullptr)
|
|
{
|
|
bResult = 7;
|
|
break;
|
|
}
|
|
|
|
CUser *pTUser = g_pMain->GetUserPtr(pkt.read<uint16>());
|
|
if (pTUser == nullptr)
|
|
bResult = 2;
|
|
else if (pTUser->isDead())
|
|
bResult = 3;
|
|
else if (pTUser->GetNation() != pUser->GetNation()
|
|
|| pTUser->isInTempleEventZone()
|
|
|| pTUser->isInPKZone()
|
|
|| pTUser->GetMap()->isWarZone()
|
|
|| !pUser->isClanLeader() || !pTUser->isClanLeader())
|
|
bResult = 4;
|
|
|
|
if (bResult != 0)
|
|
break;
|
|
|
|
|
|
uint16 sTUserClanID = pTUser->GetClanID();
|
|
CKnights *pTUserKnights = g_pMain->GetClanPtr(sTUserClanID);
|
|
|
|
result << uint8(KNIGHTS_ALLY_REQ);
|
|
|
|
result << uint8(1) << pKnights->GetName();
|
|
pTUser->Send(&result);
|
|
return;
|
|
}
|
|
}
|
|
while (0);
|
|
|
|
|
|
result << uint8(KNIGHTS_JOIN) << bResult;
|
|
pUser->Send(&result);
|
|
}
|
|
|
|
void CKnightsManager::KnightsAllianceRequest(CUser* pUser, Packet & pkt)
|
|
{
|
|
if (pUser == nullptr || pUser->isDead())
|
|
return;
|
|
|
|
uint8 flag;
|
|
uint16 TargetClanLeaderID;
|
|
|
|
pkt >> flag >> TargetClanLeaderID;
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS);
|
|
uint8 Hata = 0;
|
|
|
|
CUser * pTargetUser = g_pMain->GetUserPtr(TargetClanLeaderID);
|
|
if (pTargetUser == nullptr)
|
|
{
|
|
Hata = 2;
|
|
goto FinalResult;
|
|
}
|
|
else
|
|
{
|
|
CKnights * pKnights = g_pMain->GetClanPtr(pTargetUser->m_bKnights);
|
|
if(pKnights == nullptr && !pUser->isInGame() && !pTargetUser->isInGame())
|
|
{
|
|
Hata = 2;
|
|
goto FinalResult;
|
|
}
|
|
|
|
CKnights * pTargetKnights = g_pMain->GetClanPtr(pUser->m_bKnights);
|
|
_KNIGHTS_ALLIANCE * pAlliance = g_pMain->GetAlliancePtr(pTargetUser->m_bKnights);
|
|
if (pTargetKnights != nullptr || pKnights != nullptr)
|
|
{
|
|
if (pTargetUser->isDead())
|
|
{
|
|
Hata = 3;
|
|
goto FinalResult;
|
|
}
|
|
else if (pTargetUser->GetNation() != pUser->GetNation())
|
|
{
|
|
Hata = 4;
|
|
goto FinalResult;
|
|
}
|
|
else if (!pTargetUser->GetClanID())
|
|
{
|
|
Hata = 5;
|
|
goto FinalResult;
|
|
}
|
|
if(pAlliance != nullptr)
|
|
{
|
|
CKnights * pKnights1 = g_pMain->GetClanPtr(pAlliance->sSubAllianceKnights),
|
|
* pKnights2 = g_pMain->GetClanPtr(pAlliance->sMercenaryClan_1),
|
|
* pKnights3 = g_pMain->GetClanPtr(pAlliance->sMercenaryClan_2);
|
|
|
|
if (pKnights->m_byFlag > 1 &&
|
|
!pTargetKnights->isInAlliance() &&
|
|
pKnights->m_strChief == pTargetUser->GetName() &&
|
|
pAlliance != nullptr &&
|
|
pAlliance->sMainAllianceKnights == pKnights->GetAllianceID() &&
|
|
pAlliance->sMercenaryClan_1 != pTargetKnights->m_sIndex &&
|
|
pAlliance->sMercenaryClan_2 != pTargetKnights->m_sIndex &&
|
|
pAlliance->sSubAllianceKnights != pTargetKnights->m_sIndex)
|
|
{
|
|
uint16 MainCap = pKnights->m_sCape;
|
|
result << uint8(KNIGHTS_ALLY_INSERT) << uint8(1) << pTargetUser->m_bKnights << pUser->m_bKnights << MainCap;
|
|
g_pMain->AddDatabaseRequest(result, pTargetUser);
|
|
std::string noticeText;
|
|
g_pMain->GetServerResource(IDS_INSERT_KNIGHTS_ALLIANCE, ¬iceText, pTargetKnights->GetName().c_str());
|
|
pKnights->SendChatAlliance("%s", noticeText.c_str());
|
|
if(pKnights1 != nullptr)
|
|
pKnights1->SendChatAlliance("%s", noticeText.c_str());
|
|
if(pKnights2 != nullptr)
|
|
pKnights2->SendChatAlliance("%s", noticeText.c_str());
|
|
if(pKnights3 != nullptr)
|
|
pKnights3->SendChatAlliance("%s", noticeText.c_str());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
FinalResult:
|
|
{
|
|
result << uint8(KNIGHTS_JOIN) << Hata;
|
|
pUser->Send(&result);
|
|
}
|
|
}
|
|
|
|
void CKnightsManager::KnightsAllianceRemove(CUser* pUser, Packet & pkt)
|
|
{
|
|
if (pUser == nullptr || pUser->isDead())
|
|
return;
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS, uint8(KNIGHTS_ALLY_REMOVE));
|
|
CKnights *pKnights = g_pMain->GetClanPtr(pUser->GetClanID()),
|
|
*pTKnights = g_pMain->GetClanPtr(pKnights->m_sAlliance);
|
|
_KNIGHTS_ALLIANCE *pAlliance = g_pMain->GetAlliancePtr(pKnights->m_sAlliance);
|
|
|
|
if (pAlliance == nullptr)
|
|
{
|
|
KnightsAllianceCreate(pUser,pkt);
|
|
g_pMain->ReloadKnightAndUserRanks();
|
|
pAlliance = g_pMain->GetAlliancePtr(pUser->GetClanID());
|
|
}
|
|
else
|
|
{
|
|
CKnights *pKnights1 = g_pMain->GetClanPtr(pAlliance->sMercenaryClan_1),
|
|
*pKnights2 = g_pMain->GetClanPtr(pAlliance->sMercenaryClan_2),
|
|
*pKnights3 = g_pMain->GetClanPtr(pAlliance->sSubAllianceKnights);
|
|
|
|
if ((pKnights->m_strChief == pUser->GetName()
|
|
|| pTKnights->m_strChief == pUser->GetName())
|
|
&& !pTKnights->isInAlliance()
|
|
&& pAlliance != nullptr
|
|
&& pAlliance->sMainAllianceKnights != pUser->GetClanID()
|
|
|| pAlliance->sMercenaryClan_1 == pKnights->m_sIndex
|
|
|| pAlliance->sMercenaryClan_2 == pKnights->m_sIndex
|
|
|| pAlliance->sSubAllianceKnights == pKnights->m_sIndex)
|
|
{
|
|
|
|
result << uint8(1) << pKnights->m_sAlliance << pUser->GetClanID() << uint16(-1);
|
|
g_pMain->AddDatabaseRequest(result, pUser);
|
|
pUser->SendToRegion(&result);
|
|
|
|
std::string noticeText;
|
|
g_pMain->GetServerResource(IDS_REMOVE_KNIGHTS_ALLIANCE, ¬iceText, pKnights->GetName().c_str());
|
|
pTKnights->SendChatAlliance("%s", noticeText.c_str());
|
|
if (pKnights1 != nullptr)
|
|
pKnights1->SendChatAlliance("%s", noticeText.c_str());
|
|
if (pKnights2 != nullptr)
|
|
pKnights2->SendChatAlliance("%s", noticeText.c_str());
|
|
if (pKnights3 != nullptr)
|
|
pKnights3->SendChatAlliance("%s", noticeText.c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
void CKnightsManager::KnightsAlliancePunish(CUser* pUser, Packet & pkt) {
|
|
|
|
|
|
if (pUser == nullptr
|
|
|| pUser->isDead())
|
|
return;
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS, uint8(KNIGHTS_ALLY_PUNISH)); // knights ban
|
|
uint16 TargetClanID = pkt.read<uint16>(),MainCapeID;
|
|
CKnights *pTargetKnights = g_pMain->GetClanPtr(TargetClanID) , *pKnights = g_pMain->GetClanPtr(pUser->m_bKnights);
|
|
_KNIGHTS_ALLIANCE * pAlliance = g_pMain->GetAlliancePtr(pUser->m_bKnights);
|
|
|
|
if( pAlliance != nullptr && pTargetKnights != nullptr && pKnights != nullptr)
|
|
{
|
|
CKnights * pKnights1 = g_pMain->GetClanPtr(pAlliance->sSubAllianceKnights),
|
|
* pKnights2 = g_pMain->GetClanPtr(pAlliance->sMercenaryClan_1),
|
|
* pKnights3 = g_pMain->GetClanPtr(pAlliance->sMercenaryClan_2);
|
|
|
|
CUser *pTargetUser = nullptr;
|
|
|
|
if (pTargetKnights != nullptr && !pTargetKnights->m_strChief.empty())
|
|
pTargetUser = g_pMain->GetUserPtr(pTargetKnights->m_strChief, TYPE_CHARACTER);
|
|
|
|
if (pAlliance->sMainAllianceKnights == pKnights->GetID())
|
|
MainCapeID = pKnights->m_sCape;
|
|
else
|
|
MainCapeID = pTargetKnights->m_sCape;
|
|
|
|
if (pKnights->m_byFlag > 1 &&
|
|
pKnights->m_strChief == pUser->GetName() &&
|
|
pAlliance != nullptr &&
|
|
pTargetKnights->isInAlliance() &&
|
|
pAlliance->sMainAllianceKnights == pKnights->GetAllianceID() ||
|
|
pAlliance->sMercenaryClan_1 == pTargetKnights->m_sIndex ||
|
|
pAlliance->sMercenaryClan_2 == pTargetKnights->m_sIndex ||
|
|
pAlliance->sSubAllianceKnights == pTargetKnights->m_sIndex)
|
|
{
|
|
|
|
if (pTargetUser != nullptr)
|
|
{
|
|
result << uint8(1) << pUser->m_bKnights << pTargetUser->m_bKnights << MainCapeID;
|
|
g_pMain->AddDatabaseRequest(result, pUser);
|
|
std::string noticeText;
|
|
g_pMain->GetServerResource(IDS_PUNISH_KNIGHTS_ALLIANCE, ¬iceText, pTargetKnights->GetName().c_str());
|
|
pKnights->SendChatAlliance("%s", noticeText.c_str());
|
|
if(pKnights1 != nullptr)
|
|
pKnights1->SendChatAlliance("%s", noticeText.c_str());
|
|
if(pKnights2 != nullptr)
|
|
pKnights2->SendChatAlliance("%s", noticeText.c_str());
|
|
if(pKnights3 != nullptr)
|
|
pKnights3->SendChatAlliance("%s", noticeText.c_str());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* @brief Handles the client packet responsible for displaying
|
|
* all clans that are part of the user's clan's alliance.
|
|
*
|
|
* @param pUser The user.
|
|
* @param pkt The packet.
|
|
*/
|
|
void CKnightsManager::KnightsAllianceList(CUser* pUser, Packet & pkt)
|
|
{
|
|
if (pUser == nullptr || !pUser->isInGame() || !pUser->isInClan())
|
|
return;
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS, uint8(KNIGHTS_ALLY_LIST));
|
|
_KNIGHTS_ALLIANCE * pAlliance;
|
|
CKnights * pClan = g_pMain->GetClanPtr(pUser->GetClanID());
|
|
|
|
if (pClan == nullptr || !pClan->isInAlliance() || (pAlliance = g_pMain->GetAlliancePtr(pClan->GetAllianceID())) == nullptr)
|
|
{
|
|
result << uint8(0);
|
|
pUser->Send(&result);
|
|
return;
|
|
}
|
|
|
|
uint16 clans[] =
|
|
{
|
|
pAlliance->sMainAllianceKnights, pAlliance->sSubAllianceKnights,
|
|
pAlliance->sMercenaryClan_1, pAlliance->sMercenaryClan_2
|
|
};
|
|
|
|
size_t wpos = result.wpos();
|
|
uint8 clanCount = 0;
|
|
result << clanCount << std::string("Valentine,ByTerry"); // Ally announcement
|
|
|
|
result.SByte();
|
|
|
|
foreach_array(i, clans)
|
|
{
|
|
uint16 sClanID = clans[i];
|
|
CKnights * pTmp = g_pMain->GetClanPtr(sClanID);
|
|
|
|
if (pTmp == nullptr)
|
|
continue;
|
|
|
|
result << pTmp->GetID() << pTmp->GetName() << pTmp->isInAlliance() << pUser->isInGame() << pUser->GetFame() << pTmp->m_strChief;
|
|
|
|
clanCount++;
|
|
}
|
|
|
|
if (clanCount == 0)
|
|
return;
|
|
|
|
result.put(wpos, clanCount);
|
|
pUser->Send(&result);
|
|
}
|
|
|
|
void CKnightsManager::ListTop10Clans(CUser *pUser)
|
|
{
|
|
Packet result(WIZ_KNIGHTS_PROCESS, uint8(KNIGHTS_TOP10));
|
|
result << uint16(0);
|
|
|
|
// List top 5 clans of each nation
|
|
for (int nation = KARUS_ARRAY; nation <= ELMORAD_ARRAY; nation++)
|
|
{
|
|
uint16 i = 1;
|
|
foreach_stlmap (itr, g_pMain->m_KnightsRatingArray[nation])
|
|
{
|
|
if (i > 5)
|
|
break;
|
|
|
|
CKnights *pKnights = g_pMain->GetClanPtr(itr->second->sClanID);
|
|
|
|
if (pKnights == nullptr)
|
|
{
|
|
result << int16(-1) // Clan ID
|
|
<< "" // Clan name (2 byte length)
|
|
<< int16(-1) // Symbol version
|
|
<< int16(i-1); // Rank (0 - 4)
|
|
}
|
|
else
|
|
{
|
|
if (pKnights->m_byNation == nation + 1)
|
|
result << pKnights->m_sIndex << pKnights->m_strName << pKnights->m_sMarkVersion << int16(i-1);
|
|
else
|
|
continue;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
}
|
|
|
|
pUser->Send(&result);
|
|
}
|
|
/**
|
|
* @brief Handles the clan NP info packet from the client.
|
|
* It is designed to tell the user how many points are
|
|
* currently stored, and how much they can donate.
|
|
*
|
|
* @param pUser The user.
|
|
* @param pkt The packet.
|
|
*/
|
|
void CKnightsManager::DonateNPReq(CUser * pUser, Packet & pkt)
|
|
{
|
|
if (pUser == nullptr
|
|
|| !pUser->isInClan())
|
|
return;
|
|
|
|
CKnights * pKnights = g_pMain->GetClanPtr(pUser->GetClanID());
|
|
if (pKnights == nullptr)
|
|
return;
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS, uint8(KNIGHTS_POINT_REQ));
|
|
result << uint8(1)
|
|
<< uint32(pUser->GetLoyalty())
|
|
<< uint32(pKnights->m_nClanPointFund); // note: amount shown is in NP form
|
|
pUser->Send(&result);
|
|
}
|
|
|
|
/**
|
|
* @brief Handles the clan NP donations packet from the client.
|
|
*
|
|
* @param pUser The user.
|
|
* @param pkt The packet.
|
|
*/
|
|
void CKnightsManager::DonateNP(CUser *pUser, Packet & pkt)
|
|
{
|
|
// Ensure the user's valid and in a clan.
|
|
if (pUser == nullptr
|
|
|| !pUser->isInClan()
|
|
// Ensure users don't try to donate NP when their NP is at or below the minimum.
|
|
|| pUser->GetLoyalty() < MIN_NP_TO_DONATE)
|
|
return;
|
|
|
|
// Ensure the clan exists and the clan is at least Accredited.
|
|
CKnights * pKnights = g_pMain->GetClanPtr(pUser->GetClanID());
|
|
if (pKnights == nullptr
|
|
|| pKnights->m_byFlag < ClanTypeAccredited5)
|
|
return;
|
|
|
|
// Pass the packet straight to the database thread for further processing.
|
|
ReqDonateNP(pUser,pkt);
|
|
}
|
|
|
|
/**
|
|
* @brief Handles the clan NP donations list packet from the client.
|
|
* i.e. the "save cont" button's "accumulation status" list.
|
|
*
|
|
* @param pUser The user.
|
|
* @param pkt The packet.
|
|
*/
|
|
|
|
void CKnightsManager::UpdateClanNotice(CUser * pUser,Packet & pkt)
|
|
{
|
|
if (pUser == nullptr
|
|
|| !pUser->isInClan())
|
|
return;
|
|
|
|
// Ensure the clan exists and the clan is at least Accredited.
|
|
CKnights * pKnights = g_pMain->GetClanPtr(pUser->GetClanID());
|
|
if (pKnights == nullptr
|
|
|| !pUser->isClanLeader())
|
|
return;
|
|
|
|
std::string Notice;
|
|
|
|
pkt >> Notice;
|
|
|
|
pKnights->UpdateClanNotice( Notice );
|
|
}
|
|
|
|
void CKnightsManager::DonationList(CUser *pUser, Packet & pkt)
|
|
{
|
|
// Ensure the user's valid and in a clan.
|
|
if (pUser == nullptr
|
|
|| !pUser->isInClan())
|
|
return;
|
|
|
|
// Ensure the clan exists and the clan is at least Accredited.
|
|
CKnights * pKnights = g_pMain->GetClanPtr(pUser->GetClanID());
|
|
if (pKnights == nullptr
|
|
|| pKnights->m_byFlag < ClanTypeAccredited5)
|
|
return;
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS, uint8(KNIGHTS_DONATION_LIST));
|
|
uint8 count = 0;
|
|
size_t wpos = result.wpos();
|
|
result << count;
|
|
|
|
for (int i = 0; i < MAX_CLAN_USERS; i++)
|
|
{
|
|
_KNIGHTS_USER * p = &pKnights->m_arKnightsUser[i];
|
|
if (!p->byUsed)
|
|
continue;
|
|
|
|
result << p->strUserName << p->nDonatedNP;
|
|
count++;
|
|
}
|
|
|
|
result.put(wpos, count);
|
|
pUser->Send(&result);
|
|
}
|
|
|
|
|
|
void CKnightsManager::UpdateKnightMemo(CUser * pUser, Packet & pkt)
|
|
{
|
|
uint8 command = pkt.read<uint8>();
|
|
|
|
Packet result(WIZ_KNIGHTS_PROCESS);
|
|
|
|
if(pUser == nullptr)
|
|
return;
|
|
|
|
CKnights* pKnights = g_pMain->GetClanPtr(pUser->GetClanID());
|
|
|
|
if(pKnights == nullptr)
|
|
return;
|
|
|
|
std::string myName = pUser->GetName();
|
|
std::string Name = "";
|
|
|
|
_KNIGHTS_USER * p = nullptr;
|
|
foreach_array (i, pKnights->m_arKnightsUser)
|
|
{
|
|
p = &pKnights->m_arKnightsUser[i];
|
|
if (!p->byUsed)
|
|
continue;
|
|
|
|
Name = p->strUserName;
|
|
STRTOUPPER(Name);
|
|
if(Name != myName)
|
|
continue;
|
|
|
|
break;
|
|
}
|
|
|
|
if(p == nullptr || p->strUserMemo.size() > 20)
|
|
return;
|
|
|
|
pkt >> p->strUserMemo;
|
|
|
|
if(p->strUserMemo.size() > 20 || p->strUserMemo.size() == 0)
|
|
return;
|
|
|
|
pUser->m_strMemo = p->strUserMemo;
|
|
|
|
result.DByte();
|
|
result << uint8(0x58) << uint8(0x03) << uint8(0x01) << p->strUserMemo;
|
|
|
|
g_pMain->Send_KnightsMember(pUser->GetClanID(),&result);
|
|
|
|
} |