server/db/src/GuildManager.cpp

1492 lines
38 KiB
C++
Raw Normal View History

2022-03-05 12:44:06 +02:00
#include "stdafx.h"
#include "GuildManager.h"
#include "Main.h"
#include "ClientManager.h"
#include "QID.h"
#include "Config.h"
#include <math.h>
extern std::string g_stLocale;
const int GUILD_RANK_MAX_NUM = 20;
bool isEurope()
{
do
{
if (g_stLocale.compare("germany") == 0) break;
if (g_stLocale.compare("france") == 0) break;
if (g_stLocale.compare("italy") == 0) break;
if (g_stLocale.compare("spain") == 0) break;
if (g_stLocale.compare("uk") == 0) break;
if (g_stLocale.compare("turkey") == 0) break;
if (g_stLocale.compare("poland") == 0) break;
if (g_stLocale.compare("portugal") == 0) break;
if (g_stLocale.compare("greek") == 0) break;
return false;
} while (false);
return true;
}
DWORD GetGuildWarWaitStartDuration()
{
// const int GUILD_WAR_WAIT_START_DURATION = 60;
// const int GUILD_WAR_WAIT_START_DURATION = 5;
if (isEurope() == true) return 60;
else return 5;
}
DWORD GetGuildWarReserveSeconds()
{
// const int GUILD_WAR_RESERVE_SECONDS = 180;
// const int GUILD_WAR_RESERVE_SECONDS = 10;
if (isEurope() == true) return 180;
else return 10;
}
namespace
{
struct FSendPeerWar
{
FSendPeerWar(BYTE bType, BYTE bWar, DWORD GID1, DWORD GID2)
{
if (number(0, 1))
std::swap(GID1, GID2);
memset(&p, 0, sizeof(TPacketGuildWar));
p.bWar = bWar;
p.bType = bType;
p.dwGuildFrom = GID1;
p.dwGuildTo = GID2;
}
void operator() (CPeer* peer)
{
if (peer->GetChannel() == 0)
return;
peer->EncodeHeader(HEADER_DG_GUILD_WAR, 0, sizeof(TPacketGuildWar));
peer->Encode(&p, sizeof(TPacketGuildWar));
}
TPacketGuildWar p;
};
struct FSendGuildWarScore
{
FSendGuildWarScore(DWORD guild_gain, DWORD dwOppGID, int iScore, int iBetScore)
{
pck.dwGuildGainPoint = guild_gain;
pck.dwGuildOpponent = dwOppGID;
pck.lScore = iScore;
pck.lBetScore = iBetScore;
}
void operator() (CPeer* peer)
{
if (peer->GetChannel() == 0)
return;
peer->EncodeHeader(HEADER_DG_GUILD_WAR_SCORE, 0, sizeof(pck));
peer->Encode(&pck, sizeof(pck));
}
TPacketGuildWarScore pck;
};
}
CGuildManager::CGuildManager()
{
}
CGuildManager::~CGuildManager()
{
while (!m_pqOnWar.empty())
{
if (!m_pqOnWar.top().second->bEnd)
delete m_pqOnWar.top().second;
m_pqOnWar.pop();
}
}
TGuild & CGuildManager::TouchGuild(DWORD GID)
{
itertype(m_map_kGuild) it = m_map_kGuild.find(GID);
if (it != m_map_kGuild.end())
return it->second;
TGuild info;
m_map_kGuild.insert(std::map<DWORD, TGuild>::value_type(GID, info));
return m_map_kGuild[GID];
}
void CGuildManager::ParseResult(SQLResult * pRes)
{
MYSQL_ROW row;
while ((row = mysql_fetch_row(pRes->pSQLResult)))
{
DWORD GID = strtoul(row[0], NULL, 10);
TGuild & r_info = TouchGuild(GID);
strlcpy(r_info.szName, row[1], sizeof(r_info.szName));
str_to_number(r_info.ladder_point, row[2]);
str_to_number(r_info.win, row[3]);
str_to_number(r_info.draw, row[4]);
str_to_number(r_info.loss, row[5]);
str_to_number(r_info.gold, row[6]);
str_to_number(r_info.level, row[7]);
sys_log(0,
"GuildWar: %-24s ladder %-5d win %-3d draw %-3d loss %-3d",
r_info.szName,
r_info.ladder_point,
r_info.win,
r_info.draw,
r_info.loss);
}
}
void CGuildManager::Initialize()
{
char szQuery[1024];
snprintf(szQuery, sizeof(szQuery), "SELECT id, name, ladder_point, win, draw, loss, gold, level FROM guild%s", GetTablePostfix());
std::auto_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery));
if (pmsg->Get()->uiNumRows)
ParseResult(pmsg->Get());
char str[128 + 1];
if (!CConfig::instance().GetValue("POLY_POWER", str, sizeof(str)))
*str = '\0';
if (!polyPower.Analyze(str))
sys_err("cannot set power poly: %s", str);
else
sys_log(0, "POWER_POLY: %s", str);
if (!CConfig::instance().GetValue("POLY_HANDICAP", str, sizeof(str)))
*str = '\0';
if (!polyHandicap.Analyze(str))
sys_err("cannot set handicap poly: %s", str);
else
sys_log(0, "HANDICAP_POLY: %s", str);
QueryRanking();
}
void CGuildManager::Load(DWORD dwGuildID)
{
char szQuery[1024];
snprintf(szQuery, sizeof(szQuery), "SELECT id, name, ladder_point, win, draw, loss, gold, level FROM guild%s WHERE id=%u", GetTablePostfix(), dwGuildID);
std::auto_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery));
if (pmsg->Get()->uiNumRows)
ParseResult(pmsg->Get());
}
void CGuildManager::QueryRanking()
{
char szQuery[256];
snprintf(szQuery, sizeof(szQuery), "SELECT id,name,ladder_point FROM guild%s ORDER BY ladder_point DESC LIMIT 20", GetTablePostfix());
CDBManager::instance().ReturnQuery(szQuery, QID_GUILD_RANKING, 0, 0);
}
int CGuildManager::GetRanking(DWORD dwGID)
{
itertype(map_kLadderPointRankingByGID) it = map_kLadderPointRankingByGID.find(dwGID);
if (it == map_kLadderPointRankingByGID.end())
return GUILD_RANK_MAX_NUM;
return MINMAX(0, it->second, GUILD_RANK_MAX_NUM);
}
void CGuildManager::ResultRanking(MYSQL_RES * pRes)
{
if (!pRes)
return;
int iLastLadderPoint = -1;
int iRank = 0;
map_kLadderPointRankingByGID.clear();
MYSQL_ROW row;
while ((row = mysql_fetch_row(pRes)))
{
DWORD dwGID = 0; str_to_number(dwGID, row[0]);
int iLadderPoint = 0; str_to_number(iLadderPoint, row[2]);
if (iLadderPoint != iLastLadderPoint)
++iRank;
sys_log(0, "GUILD_RANK: %-24s %2d %d", row[1], iRank, iLadderPoint);
map_kLadderPointRankingByGID.insert(std::make_pair(dwGID, iRank));
}
}
void CGuildManager::Update()
{
ProcessReserveWar(); // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3>
time_t now = CClientManager::instance().GetCurrentTime();
if (!m_pqOnWar.empty())
{
// UNKNOWN_GUILD_MANAGE_UPDATE_LOG
/*
sys_log(0, "GuildManager::Update size %d now %d top %d, %s(%u) vs %s(%u)",
m_WarMap.size(),
now,
m_pqOnWar.top().first,
m_map_kGuild[m_pqOnWar.top().second->GID[0]].szName,
m_pqOnWar.top().second->GID[0],
m_map_kGuild[m_pqOnWar.top().second->GID[1]].szName,
m_pqOnWar.top().second->GID[1]);
*/
// END_OF_UNKNOWN_GUILD_MANAGE_UPDATE_LOG
while (!m_pqOnWar.empty() && (m_pqOnWar.top().first <= now || (m_pqOnWar.top().second && m_pqOnWar.top().second->bEnd)))
{
TGuildWarPQElement * e = m_pqOnWar.top().second;
m_pqOnWar.pop();
if (e)
{
if (!e->bEnd)
WarEnd(e->GID[0], e->GID[1], false);
delete e;
}
}
}
// GUILD_SKILL_COOLTIME_BUG_FIX
while (!m_pqSkill.empty() && m_pqSkill.top().first <= now)
{
const TGuildSkillUsed& s = m_pqSkill.top().second;
CClientManager::instance().SendGuildSkillUsable(s.GID, s.dwSkillVnum, true);
m_pqSkill.pop();
}
// END_OF_GUILD_SKILL_COOLTIME_BUG_FIX
while (!m_pqWaitStart.empty() && m_pqWaitStart.top().first <= now)
{
const TGuildWaitStartInfo & ws = m_pqWaitStart.top().second;
m_pqWaitStart.pop();
StartWar(ws.bType, ws.GID[0], ws.GID[1], ws.pkReserve); // insert new element to m_WarMap and m_pqOnWar
if (ws.lInitialScore)
{
UpdateScore(ws.GID[0], ws.GID[1], ws.lInitialScore, 0);
UpdateScore(ws.GID[1], ws.GID[0], ws.lInitialScore, 0);
}
TPacketGuildWar p;
p.bType = ws.bType;
p.bWar = GUILD_WAR_ON_WAR;
p.dwGuildFrom = ws.GID[0];
p.dwGuildTo = ws.GID[1];
CClientManager::instance().ForwardPacket(HEADER_DG_GUILD_WAR, &p, sizeof(p));
sys_log(0, "GuildWar: GUILD sending start of wait start war %d %d", ws.GID[0], ws.GID[1]);
}
}
#define for_all(cont, it) for (typeof((cont).begin()) it = (cont).begin(); it != (cont).end(); ++it)
void CGuildManager::OnSetup(CPeer* peer)
{
for_all(m_WarMap, it_cont)
for_all(it_cont->second, it)
{
DWORD g1 = it_cont->first;
DWORD g2 = it->first;
TGuildWarPQElement* p = it->second.pElement;
if (!p || p->bEnd)
continue;
FSendPeerWar(p->bType, GUILD_WAR_ON_WAR, g1, g2) (peer);
FSendGuildWarScore(p->GID[0], p->GID[1], p->iScore[0], p->iBetScore[0]);
FSendGuildWarScore(p->GID[1], p->GID[0], p->iScore[1], p->iBetScore[1]);
}
for_all(m_DeclareMap, it)
{
FSendPeerWar(it->bType, GUILD_WAR_SEND_DECLARE, it->dwGuildID[0], it->dwGuildID[1]) (peer);
}
for_all(m_map_kWarReserve, it)
{
it->second->OnSetup(peer);
}
}
void CGuildManager::GuildWarWin(DWORD GID)
{
itertype(m_map_kGuild) it = m_map_kGuild.find(GID);
if (it == m_map_kGuild.end())
return;
++it->second.win;
char buf[1024];
snprintf(buf, sizeof(buf), "UPDATE guild%s SET win=%d WHERE id=%u", GetTablePostfix(), it->second.win, GID);
CDBManager::instance().AsyncQuery(buf);
}
void CGuildManager::GuildWarLose(DWORD GID)
{
itertype(m_map_kGuild) it = m_map_kGuild.find(GID);
if (it == m_map_kGuild.end())
return;
++it->second.loss;
char buf[1024];
snprintf(buf, sizeof(buf), "UPDATE guild%s SET loss=%d WHERE id=%u", GetTablePostfix(), it->second.loss, GID);
CDBManager::instance().AsyncQuery(buf);
}
void CGuildManager::GuildWarDraw(DWORD GID)
{
itertype(m_map_kGuild) it = m_map_kGuild.find(GID);
if (it == m_map_kGuild.end())
return;
++it->second.draw;
char buf[1024];
snprintf(buf, sizeof(buf), "UPDATE guild%s SET draw=%d WHERE id=%u", GetTablePostfix(), it->second.draw, GID);
CDBManager::instance().AsyncQuery(buf);
}
bool CGuildManager::IsHalfWinLadderPoint(DWORD dwGuildWinner, DWORD dwGuildLoser)
{
DWORD GID1 = dwGuildWinner;
DWORD GID2 = dwGuildLoser;
if (GID1 > GID2)
std::swap(GID1, GID2);
itertype(m_mapGuildWarEndTime[GID1]) it = m_mapGuildWarEndTime[GID1].find(GID2);
if (it != m_mapGuildWarEndTime[GID1].end() &&
it->second + GUILD_WAR_LADDER_HALF_PENALTY_TIME > CClientManager::instance().GetCurrentTime())
return true;
return false;
}
void CGuildManager::ProcessDraw(DWORD dwGuildID1, DWORD dwGuildID2)
{
sys_log(0, "GuildWar: \tThe war between %d and %d is ended in draw", dwGuildID1, dwGuildID2);
GuildWarDraw(dwGuildID1);
GuildWarDraw(dwGuildID2);
ChangeLadderPoint(dwGuildID1, 0);
ChangeLadderPoint(dwGuildID2, 0);
QueryRanking();
}
void CGuildManager::ProcessWinLose(DWORD dwGuildWinner, DWORD dwGuildLoser)
{
GuildWarWin(dwGuildWinner);
GuildWarLose(dwGuildLoser);
sys_log(0, "GuildWar: \tWinner : %d Loser : %d", dwGuildWinner, dwGuildLoser);
int iPoint = GetLadderPoint(dwGuildLoser);
int gain = (int)(iPoint * 0.05);
int loss = (int)(iPoint * 0.07);
if (IsHalfWinLadderPoint(dwGuildWinner, dwGuildLoser))
gain /= 2;
sys_log(0, "GuildWar: \tgain : %d loss : %d", gain, loss);
ChangeLadderPoint(dwGuildWinner, gain);
ChangeLadderPoint(dwGuildLoser, -loss);
QueryRanking();
}
void CGuildManager::RemoveWar(DWORD GID1, DWORD GID2)
{
sys_log(0, "GuildWar: RemoveWar(%d, %d)", GID1, GID2);
if (GID1 > GID2)
std::swap(GID2, GID1);
itertype(m_WarMap[GID1]) it = m_WarMap[GID1].find(GID2);
if (it == m_WarMap[GID1].end())
{
if (m_WarMap[GID1].empty())
m_WarMap.erase(GID1);
return;
}
if (it->second.pElement)
it->second.pElement->bEnd = true;
m_mapGuildWarEndTime[GID1][GID2] = CClientManager::instance().GetCurrentTime();
m_WarMap[GID1].erase(it);
if (m_WarMap[GID1].empty())
m_WarMap.erase(GID1);
}
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>ʵ<EFBFBD><CAB5><EFBFBD> <20><><EFBFBD><EFBFBD>
//
void CGuildManager::WarEnd(DWORD GID1, DWORD GID2, bool bForceDraw)
{
if (GID1 > GID2)
std::swap(GID2, GID1);
sys_log(0, "GuildWar: WarEnd %d %d", GID1, GID2);
itertype(m_WarMap[GID1]) itWarMap = m_WarMap[GID1].find(GID2);
if (itWarMap == m_WarMap[GID1].end())
{
sys_err("GuildWar: war not exist or already ended. [1]");
return;
}
TGuildWarInfo gwi = itWarMap->second;
TGuildWarPQElement * pData = gwi.pElement;
if (!pData || pData->bEnd)
{
sys_err("GuildWar: war not exist or already ended. [2]");
return;
}
DWORD win_guild = pData->GID[0];
DWORD lose_guild = pData->GID[1];
bool bDraw = false;
if (!bForceDraw) // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ºΰ<C2BA> <20>ƴ<EFBFBD> <20><><EFBFBD><EFBFBD><ECBFA1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> üũ<C3BC>Ѵ<EFBFBD>.
{
if (pData->iScore[0] > pData->iScore[1])
{
win_guild = pData->GID[0];
lose_guild = pData->GID[1];
}
else if (pData->iScore[1] > pData->iScore[0])
{
win_guild = pData->GID[1];
lose_guild = pData->GID[0];
}
else
bDraw = true;
}
else // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>º<EFBFBD><C2BA><EFBFBD> <20><><EFBFBD><EFBFBD><ECBFA1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>º<EFBFBD>
bDraw = true;
if (bDraw)
ProcessDraw(win_guild, lose_guild);
else
ProcessWinLose(win_guild, lose_guild);
// DB <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ֱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
CClientManager::instance().for_each_peer(FSendPeerWar(0, GUILD_WAR_END, GID1, GID2));
RemoveWar(GID1, GID2);
}
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
//
void CGuildManager::RecvWarOver(DWORD dwGuildWinner, DWORD dwGuildLoser, bool bDraw, long lWarPrice)
{
sys_log(0, "GuildWar: RecvWarOver : winner %u vs %u draw? %d war_price %d", dwGuildWinner, dwGuildLoser, bDraw ? 1 : 0, lWarPrice);
DWORD GID1 = dwGuildWinner;
DWORD GID2 = dwGuildLoser;
if (GID1 > GID2)
std::swap(GID1, GID2);
itertype(m_WarMap[GID1]) it = m_WarMap[GID1].find(GID2);
if (it == m_WarMap[GID1].end())
return;
TGuildWarInfo & gw = it->second;
// Award
if (bDraw)
{
// give bet money / 2 to both guild
DepositMoney(dwGuildWinner, lWarPrice / 2);
DepositMoney(dwGuildLoser, lWarPrice / 2);
ProcessDraw(dwGuildWinner, dwGuildLoser);
}
else
{
// give bet money to winner guild
DepositMoney(dwGuildWinner, lWarPrice);
ProcessWinLose(dwGuildWinner, dwGuildLoser);
}
if (gw.pkReserve)
{
if (bDraw || !gw.pElement)
gw.pkReserve->Draw();
else if (gw.pElement->bType == GUILD_WAR_TYPE_BATTLE)
gw.pkReserve->End(gw.pElement->iBetScore[0], gw.pElement->iBetScore[1]);
}
RemoveWar(GID1, GID2);
}
void CGuildManager::RecvWarEnd(DWORD GID1, DWORD GID2)
{
sys_log(0, "GuildWar: RecvWarEnded : %u vs %u", GID1, GID2);
WarEnd(GID1, GID2, true); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>Ѿ<EFBFBD> <20>Ѵ<EFBFBD>.
}
void CGuildManager::StartWar(BYTE bType, DWORD GID1, DWORD GID2, CGuildWarReserve * pkReserve)
{
sys_log(0, "GuildWar: StartWar(%d,%d,%d)", bType, GID1, GID2);
if (GID1 > GID2)
std::swap(GID1, GID2);
TGuildWarInfo & gw = m_WarMap[GID1][GID2]; // map insert
if (bType == GUILD_WAR_TYPE_FIELD)
gw.tEndTime = CClientManager::instance().GetCurrentTime() + GUILD_WAR_DURATION;
else
gw.tEndTime = CClientManager::instance().GetCurrentTime() + 172800;
gw.pElement = new TGuildWarPQElement(bType, GID1, GID2);
gw.pkReserve = pkReserve;
m_pqOnWar.push(std::make_pair(gw.tEndTime, gw.pElement));
}
void CGuildManager::UpdateScore(DWORD dwGainGID, DWORD dwOppGID, int iScoreDelta, int iBetScoreDelta)
{
DWORD GID1 = dwGainGID;
DWORD GID2 = dwOppGID;
if (GID1 > GID2)
std::swap(GID1, GID2);
itertype(m_WarMap[GID1]) it = m_WarMap[GID1].find(GID2);
if (it != m_WarMap[GID1].end())
{
TGuildWarPQElement * p = it->second.pElement;
if (!p || p->bEnd)
{
sys_err("GuildWar: war not exist or already ended.");
return;
}
int iNewScore = 0;
int iNewBetScore = 0;
if (p->GID[0] == dwGainGID)
{
p->iScore[0] += iScoreDelta;
p->iBetScore[0] += iBetScoreDelta;
iNewScore = p->iScore[0];
iNewBetScore = p->iBetScore[0];
}
else
{
p->iScore[1] += iScoreDelta;
p->iBetScore[1] += iBetScoreDelta;
iNewScore = p->iScore[1];
iNewBetScore = p->iBetScore[1];
}
sys_log(0, "GuildWar: SendGuildWarScore guild %u wartype %u score_delta %d betscore_delta %d result %u, %u",
dwGainGID, p->bType, iScoreDelta, iBetScoreDelta, iNewScore, iNewBetScore);
CClientManager::instance().for_each_peer(FSendGuildWarScore(dwGainGID, dwOppGID, iNewScore, iNewBetScore));
}
}
void CGuildManager::AddDeclare(BYTE bType, DWORD guild_from, DWORD guild_to)
{
TGuildDeclareInfo di(bType, guild_from, guild_to);
if (m_DeclareMap.find(di) == m_DeclareMap.end())
m_DeclareMap.insert(di);
sys_log(0, "GuildWar: AddDeclare(Type:%d,from:%d,to:%d)", bType, guild_from, guild_to);
}
void CGuildManager::RemoveDeclare(DWORD guild_from, DWORD guild_to)
{
typeof(m_DeclareMap.begin()) it = m_DeclareMap.find(TGuildDeclareInfo(0, guild_from, guild_to));
if (it != m_DeclareMap.end())
m_DeclareMap.erase(it);
it = m_DeclareMap.find(TGuildDeclareInfo(0,guild_to, guild_from));
if (it != m_DeclareMap.end())
m_DeclareMap.erase(it);
sys_log(0, "GuildWar: RemoveDeclare(from:%d,to:%d)", guild_from, guild_to);
}
bool CGuildManager::TakeBetPrice(DWORD dwGuildTo, DWORD dwGuildFrom, long lWarPrice)
{
itertype(m_map_kGuild) it_from = m_map_kGuild.find(dwGuildFrom);
itertype(m_map_kGuild) it_to = m_map_kGuild.find(dwGuildTo);
if (it_from == m_map_kGuild.end() || it_to == m_map_kGuild.end())
{
sys_log(0, "TakeBetPrice: guild not exist %u %u",
dwGuildFrom, dwGuildTo);
return false;
}
if (it_from->second.gold < lWarPrice || it_to->second.gold < lWarPrice)
{
sys_log(0, "TakeBetPrice: not enough gold %u %d to %u %d",
dwGuildFrom, it_from->second.gold, dwGuildTo, it_to->second.gold);
return false;
}
it_from->second.gold -= lWarPrice;
it_to->second.gold -= lWarPrice;
MoneyChange(dwGuildFrom, it_from->second.gold);
MoneyChange(dwGuildTo, it_to->second.gold);
return true;
}
bool CGuildManager::WaitStart(TPacketGuildWar * p)
{
if (p->lWarPrice > 0)
if (!TakeBetPrice(p->dwGuildFrom, p->dwGuildTo, p->lWarPrice))
return false;
DWORD dwCurTime = CClientManager::instance().GetCurrentTime();
TGuildWaitStartInfo info(p->bType, p->dwGuildFrom, p->dwGuildTo, p->lWarPrice, p->lInitialScore, NULL);
m_pqWaitStart.push(std::make_pair(dwCurTime + GetGuildWarWaitStartDuration(), info));
sys_log(0,
"GuildWar: WaitStart g1 %d g2 %d price %d start at %u",
p->dwGuildFrom,
p->dwGuildTo,
p->lWarPrice,
dwCurTime + GetGuildWarWaitStartDuration());
return true;
}
int CGuildManager::GetLadderPoint(DWORD GID)
{
itertype(m_map_kGuild) it = m_map_kGuild.find(GID);
if (it == m_map_kGuild.end())
return 0;
return it->second.ladder_point;
}
void CGuildManager::ChangeLadderPoint(DWORD GID, int change)
{
itertype(m_map_kGuild) it = m_map_kGuild.find(GID);
if (it == m_map_kGuild.end())
return;
TGuild & r = it->second;
r.ladder_point += change;
if (r.ladder_point < 0)
r.ladder_point = 0;
char buf[1024];
snprintf(buf, sizeof(buf), "UPDATE guild%s SET ladder_point=%d WHERE id=%u", GetTablePostfix(), r.ladder_point, GID);
CDBManager::instance().AsyncQuery(buf);
sys_log(0, "GuildManager::ChangeLadderPoint %u %d", GID, r.ladder_point);
sys_log(0, "%s", buf);
// Packet <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TPacketGuildLadder p;
p.dwGuild = GID;
p.lLadderPoint = r.ladder_point;
p.lWin = r.win;
p.lDraw = r.draw;
p.lLoss = r.loss;
CClientManager::instance().ForwardPacket(HEADER_DG_GUILD_LADDER, &p, sizeof(TPacketGuildLadder));
}
void CGuildManager::UseSkill(DWORD GID, DWORD dwSkillVnum, DWORD dwCooltime)
{
// GUILD_SKILL_COOLTIME_BUG_FIX
sys_log(0, "UseSkill(gid=%d, skill=%d) CoolTime(%d:%d)", GID, dwSkillVnum, dwCooltime, CClientManager::instance().GetCurrentTime() + dwCooltime);
m_pqSkill.push(std::make_pair(CClientManager::instance().GetCurrentTime() + dwCooltime, TGuildSkillUsed(GID, dwSkillVnum)));
// END_OF_GUILD_SKILL_COOLTIME_BUG_FIX
}
void CGuildManager::MoneyChange(DWORD dwGuild, DWORD dwGold)
{
sys_log(0, "GuildManager::MoneyChange %d %d", dwGuild, dwGold);
TPacketDGGuildMoneyChange p;
p.dwGuild = dwGuild;
p.iTotalGold = dwGold;
CClientManager::instance().ForwardPacket(HEADER_DG_GUILD_MONEY_CHANGE, &p, sizeof(p));
char buf[1024];
snprintf(buf, sizeof(buf), "UPDATE guild%s SET gold=%u WHERE id = %u", GetTablePostfix(), dwGold, dwGuild);
CDBManager::instance().AsyncQuery(buf);
}
void CGuildManager::DepositMoney(DWORD dwGuild, INT iGold)
{
if (iGold <= 0)
return;
itertype(m_map_kGuild) it = m_map_kGuild.find(dwGuild);
if (it == m_map_kGuild.end())
{
sys_err("No guild by id %u", dwGuild);
return;
}
it->second.gold += iGold;
sys_log(0, "GUILD: %u Deposit %u Total %d", dwGuild, iGold, it->second.gold);
MoneyChange(dwGuild, it->second.gold);
}
void CGuildManager::WithdrawMoney(CPeer* peer, DWORD dwGuild, INT iGold)
{
itertype(m_map_kGuild) it = m_map_kGuild.find(dwGuild);
if (it == m_map_kGuild.end())
{
sys_err("No guild by id %u", dwGuild);
return;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20>÷<EFBFBD><C3B7>ش<EFBFBD>
if (it->second.gold >= iGold)
{
it->second.gold -= iGold;
sys_log(0, "GUILD: %u Withdraw %d Total %d", dwGuild, iGold, it->second.gold);
TPacketDGGuildMoneyWithdraw p;
p.dwGuild = dwGuild;
p.iChangeGold = iGold;
peer->EncodeHeader(HEADER_DG_GUILD_WITHDRAW_MONEY_GIVE, 0, sizeof(TPacketDGGuildMoneyWithdraw));
peer->Encode(&p, sizeof(TPacketDGGuildMoneyWithdraw));
}
}
void CGuildManager::WithdrawMoneyReply(DWORD dwGuild, BYTE bGiveSuccess, INT iGold)
{
itertype(m_map_kGuild) it = m_map_kGuild.find(dwGuild);
if (it == m_map_kGuild.end())
return;
sys_log(0, "GuildManager::WithdrawMoneyReply : guild %u success %d gold %d", dwGuild, bGiveSuccess, iGold);
if (!bGiveSuccess)
it->second.gold += iGold;
else
MoneyChange(dwGuild, it->second.gold);
}
//
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20>ִ<EFBFBD>)
//
const int c_aiScoreByLevel[GUILD_MAX_LEVEL+1] =
{
500, // level 0 = 500 probably error
500, // 1
1000,
2000,
3000,
4000,
6000,
8000,
10000,
12000,
15000, // 10
18000,
21000,
24000,
28000,
32000,
36000,
40000,
45000,
50000,
55000,
};
const int c_aiScoreByRanking[GUILD_RANK_MAX_NUM+1] =
{
0,
55000, // 1<><31>
50000,
45000,
40000,
36000,
32000,
28000,
24000,
21000,
18000, // 10<31><30>
15000,
12000,
10000,
8000,
6000,
4000,
3000,
2000,
1000,
500 // 20<32><30>
};
void CGuildManager::BootReserveWar()
{
const char * c_apszQuery[2] =
{
"SELECT id, guild1, guild2, UNIX_TIMESTAMP(time), type, warprice, initscore, bet_from, bet_to, power1, power2, handicap FROM guild_war_reservation WHERE started=1 AND winner=-1",
"SELECT id, guild1, guild2, UNIX_TIMESTAMP(time), type, warprice, initscore, bet_from, bet_to, power1, power2, handicap FROM guild_war_reservation WHERE started=0"
};
for (int i = 0; i < 2; ++i)
{
std::auto_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(c_apszQuery[i]));
if (pmsg->Get()->uiNumRows == 0)
continue;
MYSQL_ROW row;
while ((row = mysql_fetch_row(pmsg->Get()->pSQLResult)))
{
int col = 0;
TGuildWarReserve t;
str_to_number(t.dwID, row[col++]);
str_to_number(t.dwGuildFrom, row[col++]);
str_to_number(t.dwGuildTo, row[col++]);
str_to_number(t.dwTime, row[col++]);
str_to_number(t.bType, row[col++]);
str_to_number(t.lWarPrice, row[col++]);
str_to_number(t.lInitialScore, row[col++]);
str_to_number(t.dwBetFrom, row[col++]);
str_to_number(t.dwBetTo, row[col++]);
str_to_number(t.lPowerFrom, row[col++]);
str_to_number(t.lPowerTo, row[col++]);
str_to_number(t.lHandicap, row[col++]);
t.bStarted = 0;
CGuildWarReserve * pkReserve = new CGuildWarReserve(t);
char buf[512];
snprintf(buf, sizeof(buf), "GuildWar: BootReserveWar : step %d id %u GID1 %u GID2 %u", i, t.dwID, t.dwGuildFrom, t.dwGuildTo);
// i == 0 <20≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> DB<44><42> ƨ<><C6A8> <20><><EFBFBD>̹Ƿ<CCB9> <20><><EFBFBD>º<EFBFBD> ó<><C3B3><EFBFBD>Ѵ<EFBFBD>.
// <20>Ǵ<EFBFBD>, 5<><35> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>º<EFBFBD> ó<><C3B3><EFBFBD>Ѵ<EFBFBD>. (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>þ<EFBFBD><C3BE><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>)
//if (i == 0 || (int) t.dwTime - CClientManager::instance().GetCurrentTime() < 60 * 5)
if (i == 0 || (int) t.dwTime - CClientManager::instance().GetCurrentTime() < 0)
{
if (i == 0)
sys_log(0, "%s : DB was shutdowned while war is being.", buf);
else
sys_log(0, "%s : left time lower than 5 minutes, will be canceled", buf);
pkReserve->Draw();
delete pkReserve;
}
else
{
sys_log(0, "%s : OK", buf);
m_map_kWarReserve.insert(std::make_pair(t.dwID, pkReserve));
}
}
}
}
int GetAverageGuildMemberLevel(DWORD dwGID)
{
char szQuery[QUERY_MAX_LEN];
snprintf(szQuery, sizeof(szQuery),
"SELECT AVG(level) FROM guild_member%s, player%s AS p WHERE guild_id=%u AND guild_member%s.pid=p.id",
GetTablePostfix(), GetTablePostfix(), dwGID, GetTablePostfix());
std::auto_ptr<SQLMsg> msg(CDBManager::instance().DirectQuery(szQuery));
MYSQL_ROW row;
row = mysql_fetch_row(msg->Get()->pSQLResult);
int nAverageLevel = 0; str_to_number(nAverageLevel, row[0]);
return nAverageLevel;
}
int GetGuildMemberCount(DWORD dwGID)
{
char szQuery[QUERY_MAX_LEN];
snprintf(szQuery, sizeof(szQuery), "SELECT COUNT(*) FROM guild_member%s WHERE guild_id=%u", GetTablePostfix(), dwGID);
std::auto_ptr<SQLMsg> msg(CDBManager::instance().DirectQuery(szQuery));
MYSQL_ROW row;
row = mysql_fetch_row(msg->Get()->pSQLResult);
DWORD dwCount = 0; str_to_number(dwCount, row[0]);
return dwCount;
}
bool CGuildManager::ReserveWar(TPacketGuildWar * p)
{
DWORD GID1 = p->dwGuildFrom;
DWORD GID2 = p->dwGuildTo;
if (GID1 > GID2)
std::swap(GID1, GID2);
if (p->lWarPrice > 0)
if (!TakeBetPrice(GID1, GID2, p->lWarPrice))
return false;
TGuildWarReserve t;
memset(&t, 0, sizeof(TGuildWarReserve));
t.dwGuildFrom = GID1;
t.dwGuildTo = GID2;
t.dwTime = CClientManager::instance().GetCurrentTime() + GetGuildWarReserveSeconds();
t.bType = p->bType;
t.lWarPrice = p->lWarPrice;
t.lInitialScore = p->lInitialScore;
int lvp, rkp, alv, mc;
// <20>Ŀ<EFBFBD> <20><><EFBFBD><EFBFBD>
TGuild & k1 = TouchGuild(GID1);
lvp = c_aiScoreByLevel[MIN(GUILD_MAX_LEVEL, k1.level)];
rkp = c_aiScoreByRanking[GetRanking(GID1)];
alv = GetAverageGuildMemberLevel(GID1);
mc = GetGuildMemberCount(GID1);
polyPower.SetVar("lvp", lvp);
polyPower.SetVar("rkp", rkp);
polyPower.SetVar("alv", alv);
polyPower.SetVar("mc", mc);
t.lPowerFrom = (long) polyPower.Eval();
sys_log(0, "GuildWar: %u lvp %d rkp %d alv %d mc %d power %d", GID1, lvp, rkp, alv, mc, t.lPowerFrom);
// <20>Ŀ<EFBFBD> <20><><EFBFBD><EFBFBD>
TGuild & k2 = TouchGuild(GID2);
lvp = c_aiScoreByLevel[MIN(GUILD_MAX_LEVEL, k2.level)];
rkp = c_aiScoreByRanking[GetRanking(GID2)];
alv = GetAverageGuildMemberLevel(GID2);
mc = GetGuildMemberCount(GID2);
polyPower.SetVar("lvp", lvp);
polyPower.SetVar("rkp", rkp);
polyPower.SetVar("alv", alv);
polyPower.SetVar("mc", mc);
t.lPowerTo = (long) polyPower.Eval();
sys_log(0, "GuildWar: %u lvp %d rkp %d alv %d mc %d power %d", GID2, lvp, rkp, alv, mc, t.lPowerTo);
// <20>ڵ<EFBFBD>ĸ <20><><EFBFBD><EFBFBD>
if (t.lPowerTo > t.lPowerFrom)
{
polyHandicap.SetVar("pA", t.lPowerTo);
polyHandicap.SetVar("pB", t.lPowerFrom);
}
else
{
polyHandicap.SetVar("pA", t.lPowerFrom);
polyHandicap.SetVar("pB", t.lPowerTo);
}
t.lHandicap = (long) polyHandicap.Eval();
sys_log(0, "GuildWar: handicap %d", t.lHandicap);
// <20><><EFBFBD><EFBFBD>
char szQuery[512];
snprintf(szQuery, sizeof(szQuery),
"INSERT INTO guild_war_reservation (guild1, guild2, time, type, warprice, initscore, power1, power2, handicap) "
"VALUES(%u, %u, DATE_ADD(NOW(), INTERVAL 180 SECOND), %u, %ld, %ld, %ld, %ld, %ld)",
GID1, GID2, p->bType, p->lWarPrice, p->lInitialScore, t.lPowerFrom, t.lPowerTo, t.lHandicap);
std::auto_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery));
if (pmsg->Get()->uiAffectedRows == 0 || pmsg->Get()->uiInsertID == 0 || pmsg->Get()->uiAffectedRows == (uint32_t)-1)
{
sys_err("GuildWar: Cannot insert row");
return false;
}
t.dwID = pmsg->Get()->uiInsertID;
m_map_kWarReserve.insert(std::make_pair(t.dwID, new CGuildWarReserve(t)));
CClientManager::instance().ForwardPacket(HEADER_DG_GUILD_WAR_RESERVE_ADD, &t, sizeof(TGuildWarReserve));
return true;
}
void CGuildManager::ProcessReserveWar()
{
DWORD dwCurTime = CClientManager::instance().GetCurrentTime();
itertype(m_map_kWarReserve) it = m_map_kWarReserve.begin();
while (it != m_map_kWarReserve.end())
{
itertype(m_map_kWarReserve) it2 = it++;
CGuildWarReserve * pk = it2->second;
TGuildWarReserve & r = pk->GetDataRef();
if (!r.bStarted && r.dwTime - 1800 <= dwCurTime) // 30<33><30> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>˸<EFBFBD><CBB8><EFBFBD>.
{
int iMin = (int) ceil((int)(r.dwTime - dwCurTime) / 60.0);
TGuild & r_1 = m_map_kGuild[r.dwGuildFrom];
TGuild & r_2 = m_map_kGuild[r.dwGuildTo];
sys_log(0, "GuildWar: started GID1 %u GID2 %u %d time %d min %d", r.dwGuildFrom, r.dwGuildTo, r.bStarted, dwCurTime - r.dwTime, iMin);
if (iMin <= 0)
{
char szQuery[128];
snprintf(szQuery, sizeof(szQuery), "UPDATE guild_war_reservation SET started=1 WHERE id=%u", r.dwID);
CDBManager::instance().AsyncQuery(szQuery);
CClientManager::instance().ForwardPacket(HEADER_DG_GUILD_WAR_RESERVE_DEL, &r.dwID, sizeof(DWORD));
r.bStarted = true;
TGuildWaitStartInfo info(r.bType, r.dwGuildFrom, r.dwGuildTo, r.lWarPrice, r.lInitialScore, pk);
m_pqWaitStart.push(std::make_pair(dwCurTime + GetGuildWarWaitStartDuration(), info));
TPacketGuildWar pck;
pck.bType = r.bType;
pck.bWar = GUILD_WAR_WAIT_START;
pck.dwGuildFrom = r.dwGuildFrom;
pck.dwGuildTo = r.dwGuildTo;
pck.lWarPrice = r.lWarPrice;
pck.lInitialScore = r.lInitialScore;
CClientManager::instance().ForwardPacket(HEADER_DG_GUILD_WAR, &pck, sizeof(TPacketGuildWar));
//m_map_kWarReserve.erase(it2);
}
else
{
if (iMin != pk->GetLastNoticeMin())
{
pk->SetLastNoticeMin(iMin);
if (!g_stLocale.compare("euckr"))
CClientManager::instance().SendNotice("%s <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> %s <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> %d<><64> <20><> <20><><EFBFBD><EFBFBD> <20>˴ϴ<CBB4>!", r_1.szName, r_2.szName, iMin);
else if (!g_stLocale.compare("gb2312"))
CClientManager::instance().SendNotice("%s <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> %s <20><><EFBFBD><EFBFBD><EFBFBD>İ<EFBFBD><C4B0><EFBFBD>ս<EFBFBD><D5BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> %d<><64><EFBFBD>Ӻ<EFBFBD><D3BA><EFBFBD>ʼ!", r_1.szName, r_2.szName, iMin);
}
}
}
}
}
bool CGuildManager::Bet(DWORD dwID, const char * c_pszLogin, DWORD dwGold, DWORD dwGuild)
{
itertype(m_map_kWarReserve) it = m_map_kWarReserve.find(dwID);
char szQuery[1024];
if (it == m_map_kWarReserve.end())
{
sys_log(0, "WAR_RESERVE: Bet: cannot find reserve war by id %u", dwID);
snprintf(szQuery, sizeof(szQuery), "INSERT INTO item_award (login, vnum, socket0, given_time) VALUES('%s', %d, %u, NOW())",
c_pszLogin, ITEM_ELK_VNUM, dwGold);
CDBManager::instance().AsyncQuery(szQuery);
return false;
}
if (!it->second->Bet(c_pszLogin, dwGold, dwGuild))
{
sys_log(0, "WAR_RESERVE: Bet: cannot bet id %u, login %s, gold %u, guild %u", dwID, c_pszLogin, dwGold, dwGuild);
snprintf(szQuery, sizeof(szQuery), "INSERT INTO item_award (login, vnum, socket0, given_time) VALUES('%s', %d, %u, NOW())",
c_pszLogin, ITEM_ELK_VNUM, dwGold);
CDBManager::instance().AsyncQuery(szQuery);
return false;
}
return true;
}
void CGuildManager::CancelWar(DWORD GID1, DWORD GID2)
{
RemoveDeclare(GID1, GID2);
RemoveWar(GID1, GID2);
}
bool CGuildManager::ChangeMaster(DWORD dwGID, DWORD dwFrom, DWORD dwTo)
{
itertype(m_map_kGuild) iter = m_map_kGuild.find(dwGID);
if (iter == m_map_kGuild.end())
return false;
char szQuery[1024];
snprintf(szQuery, sizeof(szQuery), "UPDATE guild%s SET master=%u WHERE id=%u", GetTablePostfix(), dwTo, dwGID);
delete CDBManager::instance().DirectQuery(szQuery);
snprintf(szQuery, sizeof(szQuery), "UPDATE guild_member%s SET grade=1 WHERE pid=%u", GetTablePostfix(), dwTo);
delete CDBManager::instance().DirectQuery(szQuery);
snprintf(szQuery, sizeof(szQuery), "UPDATE guild_member%s SET grade=15 WHERE pid=%u", GetTablePostfix(), dwFrom);
delete CDBManager::instance().DirectQuery(szQuery);
return true;
}
//////////////////////////////////////////////////////////////////////////////////////////
// Guild War Reserve Class
//////////////////////////////////////////////////////////////////////////////////////////
CGuildWarReserve::CGuildWarReserve(const TGuildWarReserve & rTable)
{
thecore_memcpy(&m_data, &rTable, sizeof(TGuildWarReserve));
m_iLastNoticeMin = -1;
Initialize();
}
void CGuildWarReserve::Initialize()
{
char szQuery[256];
snprintf(szQuery, sizeof(szQuery), "SELECT login, guild, gold FROM guild_war_bet WHERE war_id=%u", m_data.dwID);
std::auto_ptr<SQLMsg> msgbet(CDBManager::instance().DirectQuery(szQuery));
if (msgbet->Get()->uiNumRows)
{
MYSQL_RES * res = msgbet->Get()->pSQLResult;
MYSQL_ROW row;
char szLogin[LOGIN_MAX_LEN+1];
DWORD dwGuild;
DWORD dwGold;
while ((row = mysql_fetch_row(res)))
{
dwGuild = dwGold = 0;
strlcpy(szLogin, row[0], sizeof(szLogin));
str_to_number(dwGuild, row[1]);
str_to_number(dwGold, row[2]);
mapBet.insert(std::make_pair(szLogin, std::make_pair(dwGuild, dwGold)));
}
}
}
void CGuildWarReserve::OnSetup(CPeer * peer)
{
if (m_data.bStarted) // <20>̹<EFBFBD> <20><><EFBFBD>۵<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
return;
FSendPeerWar(m_data.bType, GUILD_WAR_RESERVE, m_data.dwGuildFrom, m_data.dwGuildTo) (peer);
peer->EncodeHeader(HEADER_DG_GUILD_WAR_RESERVE_ADD, 0, sizeof(TGuildWarReserve));
peer->Encode(&m_data, sizeof(TGuildWarReserve));
TPacketGDGuildWarBet pckBet;
pckBet.dwWarID = m_data.dwID;
itertype(mapBet) it = mapBet.begin();
while (it != mapBet.end())
{
strlcpy(pckBet.szLogin, it->first.c_str(), sizeof(pckBet.szLogin));
pckBet.dwGuild = it->second.first;
pckBet.dwGold = it->second.second;
peer->EncodeHeader(HEADER_DG_GUILD_WAR_BET, 0, sizeof(TPacketGDGuildWarBet));
peer->Encode(&pckBet, sizeof(TPacketGDGuildWarBet));
++it;
}
}
bool CGuildWarReserve::Bet(const char * pszLogin, DWORD dwGold, DWORD dwGuild)
{
char szQuery[1024];
if (m_data.dwGuildFrom != dwGuild && m_data.dwGuildTo != dwGuild)
{
sys_log(0, "GuildWarReserve::Bet: invalid guild id");
return false;
}
if (m_data.bStarted)
{
sys_log(0, "GuildWarReserve::Bet: war is already started");
return false;
}
if (mapBet.find(pszLogin) != mapBet.end())
{
sys_log(0, "GuildWarReserve::Bet: failed. already bet");
return false;
}
snprintf(szQuery, sizeof(szQuery),
"INSERT INTO guild_war_bet (war_id, login, gold, guild) VALUES(%u, '%s', %u, %u)",
m_data.dwID, pszLogin, dwGold, dwGuild);
std::auto_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery));
if (pmsg->Get()->uiAffectedRows == 0 || pmsg->Get()->uiAffectedRows == (uint32_t)-1)
{
sys_log(0, "GuildWarReserve::Bet: failed. cannot insert row to guild_war_bet table");
return false;
}
if (m_data.dwGuildFrom == dwGuild)
m_data.dwBetFrom += dwGold;
else
m_data.dwBetTo += dwGold;
CClientManager::instance().ForwardPacket(HEADER_DG_GUILD_WAR_RESERVE_ADD, &m_data, sizeof(TGuildWarReserve));
snprintf(szQuery, sizeof(szQuery), "UPDATE guild_war_reservation SET bet_from=%u,bet_to=%u WHERE id=%u",
m_data.dwBetFrom, m_data.dwBetTo, m_data.dwID);
CDBManager::instance().AsyncQuery(szQuery);
sys_log(0, "GuildWarReserve::Bet: success. %s %u war_id %u bet %u : %u", pszLogin, dwGuild, m_data.dwID, m_data.dwBetFrom, m_data.dwBetTo);
mapBet.insert(std::make_pair(pszLogin, std::make_pair(dwGuild, dwGold)));
TPacketGDGuildWarBet pckBet;
pckBet.dwWarID = m_data.dwID;
strlcpy(pckBet.szLogin, pszLogin, sizeof(pckBet.szLogin));
pckBet.dwGuild = dwGuild;
pckBet.dwGold = dwGold;
CClientManager::instance().ForwardPacket(HEADER_DG_GUILD_WAR_BET, &pckBet, sizeof(TPacketGDGuildWarBet));
return true;
}
//
// <20><><EFBFBD>º<EFBFBD> ó<><C3B3>: <20><><EFBFBD>κ<EFBFBD> <20>ºΰ<C2BA> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> Ư<><C6AF> <20><>Ȳ<EFBFBD><C8B2> <20><><EFBFBD><EFBFBD><ECBFA1>
// <20><><EFBFBD>º<EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>־<EFBFBD><D6BE><EFBFBD> <20>Ѵ<EFBFBD>.
//
void CGuildWarReserve::Draw()
{
char szQuery[1024];
snprintf(szQuery, sizeof(szQuery), "UPDATE guild_war_reservation SET started=1,winner=0 WHERE id=%u", m_data.dwID);
CDBManager::instance().AsyncQuery(szQuery);
if (mapBet.empty())
return;
sys_log(0, "WAR_REWARD: Draw. war_id %u", m_data.dwID);
itertype(mapBet) it = mapBet.begin();
while (1)
{
int iLen = 0;
int iRow = 0;
iLen += snprintf(szQuery, sizeof(szQuery) - iLen, "INSERT INTO item_award (login, vnum, socket0, given_time) VALUES");
while (it != mapBet.end())
{
if (iRow == 0)
iLen += snprintf(szQuery + iLen, sizeof(szQuery) - iLen, "('%s', %d, %u, NOW())",
it->first.c_str(), ITEM_ELK_VNUM, it->second.second);
else
iLen += snprintf(szQuery + iLen, sizeof(szQuery) - iLen, ",('%s', %d, %u, NOW())",
it->first.c_str(), ITEM_ELK_VNUM, it->second.second);
it++;
if (iLen > 384)
break;
++iRow;
}
if (iRow > 0)
{
sys_log(0, "WAR_REWARD: QUERY: %s", szQuery);
CDBManager::instance().AsyncQuery(szQuery);
}
if (it == mapBet.end())
break;
}
}
void CGuildWarReserve::End(int iScoreFrom, int iScoreTo)
{
DWORD dwWinner;
sys_log(0, "WAR_REWARD: End: From %u %d To %u %d", m_data.dwGuildFrom, iScoreFrom, m_data.dwGuildTo, iScoreTo);
if (m_data.lPowerFrom > m_data.lPowerTo)
{
if (m_data.lHandicap > iScoreFrom - iScoreTo)
{
sys_log(0, "WAR_REWARD: End: failed to overcome handicap, From is strong but To won");
dwWinner = m_data.dwGuildTo;
}
else
{
sys_log(0, "WAR_REWARD: End: success to overcome handicap, From win!");
dwWinner = m_data.dwGuildFrom;
}
}
else
{
if (m_data.lHandicap > iScoreTo - iScoreFrom)
{
sys_log(0, "WAR_REWARD: End: failed to overcome handicap, To is strong but From won");
dwWinner = m_data.dwGuildFrom;
}
else
{
sys_log(0, "WAR_REWARD: End: success to overcome handicap, To win!");
dwWinner = m_data.dwGuildTo;
}
}
char szQuery[1024];
snprintf(szQuery, sizeof(szQuery), "UPDATE guild_war_reservation SET started=1,winner=%u,result1=%d,result2=%d WHERE id=%u",
dwWinner, iScoreFrom, iScoreTo, m_data.dwID);
CDBManager::instance().AsyncQuery(szQuery);
if (mapBet.empty())
return;
DWORD dwTotalBet = m_data.dwBetFrom + m_data.dwBetTo;
DWORD dwWinnerBet = 0;
if (dwWinner == m_data.dwGuildFrom)
dwWinnerBet = m_data.dwBetFrom;
else if (dwWinner == m_data.dwGuildTo)
dwWinnerBet = m_data.dwBetTo;
else
{
sys_err("WAR_REWARD: fatal error, winner does not exist!");
return;
}
if (dwWinnerBet == 0)
{
sys_err("WAR_REWARD: total bet money on winner is zero");
return;
}
sys_log(0, "WAR_REWARD: End: Total bet: %u, Winner bet: %u", dwTotalBet, dwWinnerBet);
itertype(mapBet) it = mapBet.begin();
while (1)
{
int iLen = 0;
int iRow = 0;
iLen += snprintf(szQuery, sizeof(szQuery) - iLen, "INSERT INTO item_award (login, vnum, socket0, given_time) VALUES");
while (it != mapBet.end())
{
if (it->second.first != dwWinner)
{
++it;
continue;
}
double ratio = (double) it->second.second / dwWinnerBet;
// 10% <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>й<EFBFBD>
sys_log(0, "WAR_REWARD: %s %u ratio %f", it->first.c_str(), it->second.second, ratio);
DWORD dwGold = (DWORD) (dwTotalBet * ratio * 0.9);
if (iRow == 0)
iLen += snprintf(szQuery + iLen, sizeof(szQuery) - iLen, "('%s', %d, %u, NOW())",
it->first.c_str(), ITEM_ELK_VNUM, dwGold);
else
iLen += snprintf(szQuery + iLen, sizeof(szQuery) - iLen, ",('%s', %d, %u, NOW())",
it->first.c_str(), ITEM_ELK_VNUM, dwGold);
++it;
if (iLen > 384)
break;
++iRow;
}
if (iRow > 0)
{
sys_log(0, "WAR_REWARD: query: %s", szQuery);
CDBManager::instance().AsyncQuery(szQuery);
}
if (it == mapBet.end())
break;
}
}