forked from metin2/server
292 lines
7.6 KiB
C++
292 lines
7.6 KiB
C++
#include "stdafx.h"
|
|
#include "PrivManager.h"
|
|
#include "ClientManager.h"
|
|
|
|
const int PRIV_DURATION = 60*60*12;
|
|
const int CHARACTER_GOOD_PRIV_DURATION = 2*60*60;
|
|
const int CHARACTER_BAD_PRIV_DURATION = 60*60;
|
|
|
|
CPrivManager::CPrivManager()
|
|
{
|
|
for (int type = 0; type < MAX_PRIV_NUM; ++type)
|
|
{
|
|
for (int empire = 0; empire < EMPIRE_MAX_NUM; ++empire)
|
|
m_aaPrivEmpire[type][empire] = 0;
|
|
}
|
|
}
|
|
|
|
CPrivManager::~CPrivManager()
|
|
{
|
|
}
|
|
|
|
//
|
|
// @version 05/06/07 Bang2ni - 중복적으로 보너스가 적용 된 길드에 대한 처리
|
|
//
|
|
void CPrivManager::Update()
|
|
{
|
|
time_t now = CClientManager::instance().GetCurrentTime();
|
|
|
|
while (!m_pqPrivGuild.empty() && m_pqPrivGuild.top().first <= now)
|
|
{
|
|
TPrivGuildData* p = m_pqPrivGuild.top().second;
|
|
m_pqPrivGuild.pop();
|
|
|
|
if (p->value != 0 && !p->bRemoved)
|
|
{
|
|
|
|
typeof(m_aPrivGuild[p->type].begin()) it = m_aPrivGuild[p->type].find(p->guild_id);
|
|
|
|
// ADD_GUILD_PRIV_TIME
|
|
// 길드에 중복적으로 보너스가 설정되었을 경우 map 의 value 가 갱신(수정) 되었으므로
|
|
// TPrivGuildData 의 포인터가 같을때 실제로 삭제해 주고 게임서버들에게 cast 해 준다.
|
|
if (it != m_aPrivGuild[p->type].end() && it->second == p) {
|
|
m_aPrivGuild[p->type].erase(it);
|
|
SendChangeGuildPriv(p->guild_id, p->type, 0, 0);
|
|
// END_OF_ADD_GUILD_PRIV_TIME
|
|
}
|
|
}
|
|
|
|
delete p;
|
|
}
|
|
|
|
while (!m_pqPrivEmpire.empty() && m_pqPrivEmpire.top().first <= now)
|
|
{
|
|
TPrivEmpireData* p = (m_pqPrivEmpire.top().second);
|
|
m_pqPrivEmpire.pop();
|
|
|
|
if (p->value != 0 && !p->bRemoved)
|
|
{
|
|
SendChangeEmpirePriv(p->empire, p->type, 0, 0);
|
|
m_aaPrivEmpire[p->type][p->empire] = 0;
|
|
}
|
|
|
|
delete p;
|
|
}
|
|
|
|
while (!m_pqPrivChar.empty() && m_pqPrivChar.top().first <= now)
|
|
{
|
|
TPrivCharData* p = (m_pqPrivChar.top().second);
|
|
m_pqPrivChar.pop();
|
|
|
|
if (!p->bRemoved)
|
|
{
|
|
// TODO send packet
|
|
SendChangeCharPriv(p->pid, p->type, 0);
|
|
typeof(m_aPrivChar[p->type].begin()) it = m_aPrivChar[p->type].find(p->pid);
|
|
if (it != m_aPrivChar[p->type].end())
|
|
m_aPrivChar[p->type].erase(it);
|
|
}
|
|
delete p;
|
|
}
|
|
}
|
|
|
|
void CPrivManager::AddCharPriv(DWORD pid, BYTE type, int value)
|
|
{
|
|
if (MAX_PRIV_NUM <= type)
|
|
{
|
|
SPDLOG_ERROR("PRIV_MANAGER: AddCharPriv: wrong char priv type({}) recved", type);
|
|
return;
|
|
}
|
|
|
|
typeof(m_aPrivChar[type].begin()) it = m_aPrivChar[type].find(pid);
|
|
|
|
if (it != m_aPrivChar[type].end())
|
|
return;
|
|
|
|
if (!value)
|
|
return;
|
|
|
|
time_t now = CClientManager::instance().GetCurrentTime();
|
|
TPrivCharData* p = new TPrivCharData(type, value, pid);
|
|
|
|
int iDuration = CHARACTER_BAD_PRIV_DURATION;
|
|
|
|
if (value > 0)
|
|
iDuration = CHARACTER_GOOD_PRIV_DURATION;
|
|
|
|
m_pqPrivChar.push(std::make_pair(now+iDuration, p));
|
|
m_aPrivChar[type].insert(std::make_pair(pid, p));
|
|
|
|
// TODO send packet
|
|
SPDLOG_DEBUG("AddCharPriv {} {} {}", pid, type, value);
|
|
SendChangeCharPriv(pid, type, value);
|
|
}
|
|
|
|
//
|
|
// @version 05/06/07 Bang2ni - 이미 보너스가 적용 된 길드에 보너스 설정
|
|
//
|
|
void CPrivManager::AddGuildPriv(DWORD guild_id, BYTE type, int value, time_t duration_sec)
|
|
{
|
|
if (MAX_PRIV_NUM <= type)
|
|
{
|
|
SPDLOG_ERROR("PRIV_MANAGER: AddGuildPriv: wrong guild priv type({}) recved", type);
|
|
return;
|
|
}
|
|
|
|
typeof(m_aPrivGuild[type].begin()) it = m_aPrivGuild[type].find(guild_id);
|
|
|
|
time_t now = CClientManager::instance().GetCurrentTime();
|
|
time_t end = now + duration_sec;
|
|
TPrivGuildData * p = new TPrivGuildData(type, value, guild_id, end);
|
|
m_pqPrivGuild.push(std::make_pair(end, p));
|
|
|
|
// ADD_GUILD_PRIV_TIME
|
|
// 이미 보너스가 설정되 있다면 map 의 value 를 갱신해 준다.
|
|
// 이전 value 의 포인터는 priority queue 에서 삭제될 때 해제된다.
|
|
if (it != m_aPrivGuild[type].end())
|
|
it->second = p;
|
|
else
|
|
m_aPrivGuild[type].insert(std::make_pair(guild_id, p));
|
|
|
|
SendChangeGuildPriv(guild_id, type, value, end);
|
|
// END_OF_ADD_GUILD_PRIV_TIME
|
|
|
|
SPDLOG_DEBUG("Guild Priv guild({}) type({}) value({}) duration_sec({})", guild_id, type, value, duration_sec);
|
|
}
|
|
|
|
void CPrivManager::AddEmpirePriv(BYTE empire, BYTE type, int value, time_t duration_sec)
|
|
{
|
|
if (MAX_PRIV_NUM <= type)
|
|
{
|
|
SPDLOG_ERROR("PRIV_MANAGER: AddEmpirePriv: wrong empire priv type({}) recved", type);
|
|
return;
|
|
}
|
|
|
|
if (duration_sec < 0)
|
|
duration_sec = 0;
|
|
|
|
time_t now = CClientManager::instance().GetCurrentTime();
|
|
time_t end = now+duration_sec;
|
|
|
|
// 이전 설정값 무효화
|
|
// priority_queue에 들어있는 pointer == m_aaPrivEmpire[type][empire]
|
|
{
|
|
if (m_aaPrivEmpire[type][empire])
|
|
m_aaPrivEmpire[type][empire]->bRemoved = true;
|
|
}
|
|
|
|
TPrivEmpireData * p = new TPrivEmpireData(type, value, empire, end);
|
|
m_pqPrivEmpire.push(std::make_pair(end, p));
|
|
m_aaPrivEmpire[type][empire] = p;
|
|
|
|
// ADD_EMPIRE_PRIV_TIME
|
|
SendChangeEmpirePriv(empire, type, value, end);
|
|
// END_OF_ADD_EMPIRE_PRIV_TIME
|
|
|
|
SPDLOG_DEBUG("Empire Priv empire({}) type({}) value({}) duration_sec({})", empire, type, value, duration_sec);
|
|
}
|
|
|
|
/**
|
|
* @version 05/06/08 Bang2ni - 지속시간 추가
|
|
*/
|
|
struct FSendChangeGuildPriv
|
|
{
|
|
FSendChangeGuildPriv(DWORD guild_id, BYTE type, int value, time_t end_time_sec)
|
|
{
|
|
p.guild_id = guild_id;
|
|
p.type = type;
|
|
p.value = value;
|
|
p.bLog = 1;
|
|
// ADD_GUILD_PRIV_TIME
|
|
p.end_time_sec = end_time_sec;
|
|
// END_OF_ADD_GUILD_PRIV_TIME
|
|
}
|
|
|
|
void operator() (CPeer* peer)
|
|
{
|
|
peer->EncodeHeader(HEADER_DG_CHANGE_GUILD_PRIV, 0, sizeof(TPacketDGChangeGuildPriv));
|
|
peer->Encode(&p, sizeof(TPacketDGChangeGuildPriv));
|
|
p.bLog = 0;
|
|
}
|
|
|
|
TPacketDGChangeGuildPriv p;
|
|
};
|
|
|
|
struct FSendChangeEmpirePriv
|
|
{
|
|
FSendChangeEmpirePriv(BYTE empire, BYTE type, int value, time_t end_time_sec)
|
|
{
|
|
p.empire = empire;
|
|
p.type = type;
|
|
p.value = value;
|
|
p.bLog = 1;
|
|
// ADD_EMPIRE_PRIV_TIME
|
|
p.end_time_sec = end_time_sec;
|
|
// END_OF_ADD_EMPIRE_PRIV_TIME
|
|
}
|
|
|
|
void operator ()(CPeer* peer)
|
|
{
|
|
peer->EncodeHeader(HEADER_DG_CHANGE_EMPIRE_PRIV, 0, sizeof(TPacketDGChangeEmpirePriv));
|
|
peer->Encode(&p, sizeof(TPacketDGChangeEmpirePriv));
|
|
p.bLog = 0;
|
|
}
|
|
|
|
TPacketDGChangeEmpirePriv p;
|
|
};
|
|
|
|
struct FSendChangeCharPriv
|
|
{
|
|
FSendChangeCharPriv(DWORD pid, BYTE type, int value)
|
|
{
|
|
p.pid = pid;
|
|
p.type = type;
|
|
p.value = value;
|
|
p.bLog = 1;
|
|
}
|
|
void operator()(CPeer* peer)
|
|
{
|
|
peer->EncodeHeader(HEADER_DG_CHANGE_CHARACTER_PRIV, 0, sizeof(TPacketDGChangeCharacterPriv));
|
|
peer->Encode(&p, sizeof(TPacketDGChangeCharacterPriv));
|
|
p.bLog = 0;
|
|
}
|
|
TPacketDGChangeCharacterPriv p;
|
|
};
|
|
|
|
// ADD_GUILD_PRIV_TIME
|
|
void CPrivManager::SendChangeGuildPriv(DWORD guild_id, BYTE type, int value, time_t end_time_sec)
|
|
{
|
|
CClientManager::instance().for_each_peer(FSendChangeGuildPriv(guild_id, type, value, end_time_sec));
|
|
}
|
|
// END_OF_ADD_GUILD_PRIV_TIME
|
|
|
|
// ADD_EMPIRE_PRIV_TIME
|
|
void CPrivManager::SendChangeEmpirePriv(BYTE empire, BYTE type, int value, time_t end_time_sec)
|
|
{
|
|
CClientManager::instance().for_each_peer(FSendChangeEmpirePriv(empire, type, value, end_time_sec));
|
|
}
|
|
// END_OF_ADD_EMPIRE_PRIV_TIME
|
|
|
|
void CPrivManager::SendChangeCharPriv(DWORD pid, BYTE type, int value)
|
|
{
|
|
CClientManager::instance().for_each_peer(FSendChangeCharPriv(pid, type, value));
|
|
}
|
|
|
|
void CPrivManager::SendPrivOnSetup(CPeer* peer)
|
|
{
|
|
for (int i = 1; i < MAX_PRIV_NUM; ++i)
|
|
{
|
|
for (int e = 0; e < EMPIRE_MAX_NUM; ++e)
|
|
{
|
|
// ADD_EMPIRE_PRIV_TIME
|
|
TPrivEmpireData* pPrivEmpireData = m_aaPrivEmpire[i][e];
|
|
if (pPrivEmpireData)
|
|
{
|
|
FSendChangeEmpirePriv(e, i, pPrivEmpireData->value, pPrivEmpireData->end_time_sec)(peer);
|
|
}
|
|
// END_OF_ADD_EMPIRE_PRIV_TIME
|
|
}
|
|
|
|
for (typeof(m_aPrivGuild[i].begin()) it = m_aPrivGuild[i].begin(); it != m_aPrivGuild[i].end();++it)
|
|
{
|
|
// ADD_GUILD_PRIV_TIME
|
|
FSendChangeGuildPriv(it->first, i, it->second->value, it->second->end_time_sec)(peer);
|
|
// END_OF_ADD_GUILD_PRIV_TIME
|
|
}
|
|
for (typeof(m_aPrivChar[i].begin()) it = m_aPrivChar[i].begin(); it != m_aPrivChar[i].end(); ++it)
|
|
{
|
|
FSendChangeCharPriv(it->first, i, it->second->value)(peer);
|
|
}
|
|
}
|
|
}
|