|
- #include "StdAfx.h"
- #include "LockTimeMatch.h"
- #include "..\GameServer\DataBasePacket.h"
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- #define INVALID_VALUE 0xFFFF //无效值
-
- //////////////////////////////////////////////////////////////////////////
-
- //时钟定义
- #define IDI_DISTRIBUTE_USER (IDI_MATCH_MODULE_START+100) //分配用户
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //构造函数
- CLockTimeMatch::CLockTimeMatch()
- {
- //状态变量
- m_MatchStatus = MatchStatus_Free;
-
- //比赛配置
- m_pMatchOption = NULL;
- m_pGameServiceOption = NULL;
- m_pGameServiceAttrib = NULL;
-
- //内核接口
- m_ppITableFrame = NULL;
- m_pITimerEngine = NULL;
- m_pIDataBaseEngine = NULL;
- m_pITCPNetworkEngineEvent = NULL;
-
- //服务接口
- m_pIGameServiceFrame = NULL;
- m_pIServerUserManager = NULL;
- m_pAndroidUserManager = NULL;
- }
-
- CLockTimeMatch::~CLockTimeMatch(void)
- {
- //释放资源
- SafeDeleteArray(m_ppITableFrame);
-
- //关闭定时器
- m_pITimerEngine->KillTimer(IDI_CHECK_END_MATCH);
- m_pITimerEngine->KillTimer(IDI_DISTRIBUTE_USER);
-
- //移除元素
- m_DistributeManage.RemoveAll();
- }
-
- //接口查询
- VOID* CLockTimeMatch::QueryInterface(REFGUID Guid, DWORD dwQueryVer)
- {
- QUERYINTERFACE(IGameMatchItem, Guid, dwQueryVer);
- QUERYINTERFACE(IMatchEventSink, Guid, dwQueryVer);
- QUERYINTERFACE(IServerUserItemSink, Guid, dwQueryVer);
- QUERYINTERFACE_IUNKNOWNEX(IGameMatchItem, Guid, dwQueryVer);
- return NULL;
- }
-
- //绑定桌子
- bool CLockTimeMatch::BindTableFrame(ITableFrame * pTableFrame, WORD wTableID)
- {
- if (pTableFrame == NULL || wTableID > m_pGameServiceOption->wTableCount)
- {
- ASSERT(false);
- return false;
- }
-
- //创建钩子
- CTableFrameHook * pTableFrameHook = new CTableFrameHook();
- pTableFrameHook->InitTableFrameHook(QUERY_OBJECT_PTR_INTERFACE(pTableFrame, IUnknownEx));
- pTableFrameHook->SetMatchEventSink(QUERY_OBJECT_PTR_INTERFACE(this, IUnknownEx));
-
- //设置接口
- pTableFrame->SetTableFrameHook(QUERY_OBJECT_PTR_INTERFACE(pTableFrameHook, IUnknownEx));
- m_ppITableFrame[wTableID] = pTableFrame;
-
- return true;
- }
-
- //初始化接口
- bool CLockTimeMatch::InitMatchInterface(tagMatchManagerParameter & MatchManagerParameter)
- {
- //服务配置
- m_pMatchOption = MatchManagerParameter.pGameMatchOption;
- m_pGameServiceOption = MatchManagerParameter.pGameServiceOption;
- m_pGameServiceAttrib = MatchManagerParameter.pGameServiceAttrib;
-
- //内核组件
- m_pITimerEngine = MatchManagerParameter.pITimerEngine;
- m_pIDataBaseEngine = MatchManagerParameter.pICorrespondManager;
- m_pITCPNetworkEngineEvent = MatchManagerParameter.pTCPNetworkEngine;
-
- //服务组件
- m_pIGameServiceFrame = MatchManagerParameter.pIMainServiceFrame;
- m_pIServerUserManager = MatchManagerParameter.pIServerUserManager;
- m_pAndroidUserManager = MatchManagerParameter.pIAndroidUserManager;
- m_pIServerUserItemSink = MatchManagerParameter.pIServerUserItemSink;
-
- //分组设置
- m_DistributeManage.SetDistributeRule(m_pGameServiceOption->cbDistributeRule);
-
- //创建桌子
- if (m_ppITableFrame == NULL)
- {
- m_ppITableFrame = new ITableFrame*[m_pGameServiceOption->wTableCount];
- }
-
- //开始间隔
- DWORD dwStartInterval = GetMatchStartInterval();
- if (dwStartInterval > 0)
- {
- //开始检测
- m_pITimerEngine->SetTimer(IDI_CHECK_START_MATCH, dwStartInterval * 1000L, TIMES_INFINITY, NULL);
- }
-
- return true;
- }
-
- //时间事件
- bool CLockTimeMatch::OnEventTimer(DWORD dwTimerID, WPARAM dwBindParameter)
- {
- switch (dwTimerID)
- {
- case IDI_DISTRIBUTE_USER: //分配用户
- {
- //执行分组
- PerformDistribute();
-
- return true;
- }
- case IDI_CHECK_START_MATCH: //开始比赛
- {
- //设置状态
- m_MatchStatus = MatchStatus_Playing;
-
- //发送状态
- BYTE cbMatchStatus = MS_MATCHING;
- m_pIGameServiceFrame->SendData(BG_ALL_CLIENT, MDM_GR_MATCH, SUB_GR_MATCH_STATUS, &cbMatchStatus, sizeof(cbMatchStatus));
-
- //关闭定时器
- m_pITimerEngine->KillTimer(IDI_CHECK_START_MATCH);
-
- //检测比赛结束
- m_pITimerEngine->SetTimer(IDI_CHECK_END_MATCH, 5000, TIMES_INFINITY, 0);
-
- //执行分组
- m_pITimerEngine->SetTimer(IDI_DISTRIBUTE_USER, m_pGameServiceOption->wDistributeTimeSpace * 1000, TIMES_INFINITY, NULL);
-
- //构造结构
- CMD_GR_Match_Num MatchNum;
- ZeroMemory(&MatchNum, sizeof(MatchNum));
-
- //设置变量
- MatchNum.dwWaitting = m_pIServerUserManager->GetUserItemCount();
-
- //发送消息
- m_pIGameServiceFrame->SendData(BG_ALL_CLIENT, MDM_GR_MATCH, SUB_GR_MATCH_NUM, &MatchNum, sizeof(MatchNum));
-
- return true;
- }
- case IDI_CHECK_END_MATCH: //结束比赛
- {
- //获取时间
- CTime CurTime = CTime::GetCurrentTime();
- SYSTEMTIME MatchEndTime = m_pMatchOption->MatchType.LockTime.MatchEndTime;
-
- //比赛完成
- if (CurTime.GetHour() * 3600 + CurTime.GetMinute() * 60 + CurTime.GetSecond() >=
- MatchEndTime.wHour * 3600 + MatchEndTime.wMinute * 60 + MatchEndTime.wSecond)
- {
- //关闭定时器
- m_pITimerEngine->KillTimer(IDI_CHECK_END_MATCH);
- m_pITimerEngine->KillTimer(IDI_DISTRIBUTE_USER);
-
- //设置状态
- m_MatchStatus = MatchStatus_End;
-
- //发送状态
- BYTE cbMatchStatus = MS_MATCHEND;
- m_pIGameServiceFrame->SendData(BG_ALL_CLIENT, MDM_GR_MATCH, SUB_GR_MATCH_STATUS, &cbMatchStatus, sizeof(cbMatchStatus));
-
- //解散游戏
- for (INT i = 0; i < m_pGameServiceOption->wTableCount; i++)
- {
- //获取对象
- ITableFrame * pITableFrame = m_ppITableFrame[i];
- ASSERT(pITableFrame != NULL);
- if (pITableFrame == NULL) continue;
-
- //解散游戏
- pITableFrame->DismissGame();
- }
-
- //比赛结束
- if (CurTime >= MatchEndTime)
- {
- //比赛结束
- DBR_GR_MatchOver MatchOver;
- ZeroMemory(&MatchOver, sizeof(MatchOver));
-
- //构造数据
- MatchOver.cbMatchType = MATCH_TYPE_LOCKTIME;
- MatchOver.dwMatchID = m_pMatchOption->dwMatchID;
- MatchOver.dwMatchNO = m_pMatchOption->dwMatchNO;
- MatchOver.wServerID = m_pGameServiceOption->wServerID;
- MatchOver.MatchEndTime = m_pMatchOption->MatchType.LockTime.MatchEndTime;
- MatchOver.MatchStartTime = m_pMatchOption->MatchType.LockTime.MatchStartTime;
-
- //投递请求
- m_pIDataBaseEngine->PostDataBaseRequest(0, DBR_GR_MATCH_OVER, 0, &MatchOver, sizeof(MatchOver));
-
- return true;
- }
-
- //发送结束消息
- TCHAR szMessage[128] = TEXT("今天的比赛到此结束,请您明天再来参加!");
- m_pIGameServiceFrame->SendGameMessage(szMessage, SMT_CLOSE_GAME);
-
- //比赛检测
- DWORD dwStartInterval = GetMatchStartInterval();
- if (dwStartInterval > 0)
- {
- m_pITimerEngine->SetTimer(IDI_CHECK_START_MATCH, dwStartInterval * 1000L, TIMES_INFINITY, NULL);
- }
- }
- return true;
- }
- }
- return true;
- }
-
- //数据库事件
- bool CLockTimeMatch::OnEventDataBase(WORD wRequestID, IServerUserItem * pIServerUserItem, VOID * pData, WORD wDataSize)
- {
- switch (wRequestID)
- {
- case DBO_GR_MATCH_RANK_LIST: //比赛排行
- {
- //参数校验
- ASSERT(wDataSize <= sizeof(DBO_GR_MatchRankList));
- if (wDataSize > sizeof(DBO_GR_MatchRankList)) return false;
-
- //提取数据
- DBO_GR_MatchRankList * pMatchRankList = (DBO_GR_MatchRankList*)pData;
-
- //变量定义
- bool bRewardUser = true;
- tagMatchRankInfo * pMatchRankInfo = NULL;
- IServerUserItem * pIRewardUserItem = NULL;
-
- //发放奖励
- for (WORD wIndex = 0; wIndex < pMatchRankList->wUserCount; wIndex++)
- {
- //查找玩家
- pMatchRankInfo = &pMatchRankList->MatchRankInfo[wIndex];
- pIRewardUserItem = m_pIServerUserManager->SearchUserItem(pMatchRankInfo->dwUserID);
- if (pIRewardUserItem == NULL || pIRewardUserItem->IsAndroidUser() == true) continue;
-
- //写入奖励
- WriteUserAward(pIRewardUserItem, pMatchRankInfo);
-
- //设置标识
- pIRewardUserItem->SetMatchData(&bRewardUser);
- }
-
- //在线用户
- WORD wUserIndex = 0;
- while (true)
- {
- pIRewardUserItem = m_pIServerUserManager->EnumUserItem(wUserIndex++);
- if (pIRewardUserItem == NULL) break;
- if (pIRewardUserItem->IsAndroidUser() == true) continue;
- if (pIRewardUserItem->GetMatchData() == &bRewardUser)
- {
- pIRewardUserItem->SetMatchData(NULL);
- continue;
- }
-
- //发送结束消息
- TCHAR szMessage[128] = TEXT("本次比赛到此结束,请您前往网站查看系统排名或移驾其他比赛房间参与比赛!");
- m_pIGameServiceFrame->SendGameMessage(pIRewardUserItem, szMessage, SMT_CHAT | SMT_EJECT | SMT_GLOBAL | SMT_CLOSE_GAME);
- }
-
- break;
- }
- case DBO_GR_MATCH_REWARD_RESULT: //奖励结果
- {
- //参数效验
- if (pIServerUserItem == NULL) return true;
- if (wDataSize > sizeof(DBR_GR_MatchRewardResult)) return false;
-
- //提取数据
- DBR_GR_MatchRewardResult * pMatchRewardResult = (DBR_GR_MatchRewardResult*)pData;
-
- //奖励成功
- if (pMatchRewardResult->bResultCode == true)
- {
- //构造结构
- CMD_GR_MatchGoldUpdate MatchGoldUpdate;
-
- //设置变量
- MatchGoldUpdate.lCurrGold = pMatchRewardResult->lCurrGold;
- MatchGoldUpdate.lCurrIngot = pMatchRewardResult->lCurrIngot;
- MatchGoldUpdate.dwCurrExprience = pMatchRewardResult->dwCurrExperience;
-
- //发送数据
- m_pIGameServiceFrame->SendData(pIServerUserItem, MDM_GR_MATCH, SUB_GR_MATCH_GOLDUPDATE, &MatchGoldUpdate, sizeof(MatchGoldUpdate));
- }
-
- break;
- }
- }
- return true;
- }
-
- //比赛事件
- bool CLockTimeMatch::OnEventSocketMatch(WORD wSubCmdID, VOID * pData, WORD wDataSize, IServerUserItem * pIServerUserItem, DWORD dwSocketID)
- {
- return true;
- }
- //用户积分
- bool CLockTimeMatch::OnEventUserItemScore(IServerUserItem * pIServerUserItem, BYTE cbReason)
- {
- //效验参数
- ASSERT(pIServerUserItem != NULL);
- if (pIServerUserItem == NULL) return false;
-
- //变量定义
- CMD_GR_UserScore UserScore;
- tagUserInfo * pUserInfo = pIServerUserItem->GetUserInfo();
-
- //构造数据
- UserScore.dwUserID = pUserInfo->dwUserID;
- UserScore.UserScore.dwWinCount = pUserInfo->dwWinCount;
- UserScore.UserScore.dwLostCount = pUserInfo->dwLostCount;
- UserScore.UserScore.dwDrawCount = pUserInfo->dwDrawCount;
- UserScore.UserScore.dwFleeCount = pUserInfo->dwFleeCount;
- UserScore.UserScore.dwExperience = pUserInfo->dwExperience;
- UserScore.UserScore.lLoveLiness = pUserInfo->lLoveLiness;
-
- //构造积分
- UserScore.UserScore.lGrade = pUserInfo->lGrade;
- UserScore.UserScore.lInsure = pUserInfo->lInsure;
- UserScore.UserScore.lIngot = 0;//pUserInfo->lIngot;
-
- //构造积分
- UserScore.UserScore.lScore = pUserInfo->lScore;
- UserScore.UserScore.lScore += pIServerUserItem->GetTrusteeScore();
- UserScore.UserScore.lScore += pIServerUserItem->GetFrozenedScore();
-
- //发送数据
- m_pIGameServiceFrame->SendData(BG_COMPUTER, MDM_GR_USER, SUB_GR_USER_SCORE, &UserScore, sizeof(UserScore));
-
- //变量定义
- CMD_GR_MobileUserScore MobileUserScore;
-
- //构造数据
- MobileUserScore.dwUserID = pUserInfo->dwUserID;
- MobileUserScore.UserScore.dwWinCount = pUserInfo->dwWinCount;
- MobileUserScore.UserScore.dwLostCount = pUserInfo->dwLostCount;
- MobileUserScore.UserScore.dwDrawCount = pUserInfo->dwDrawCount;
- MobileUserScore.UserScore.dwFleeCount = pUserInfo->dwFleeCount;
- MobileUserScore.UserScore.dwExperience = pUserInfo->dwExperience;
-
- //构造积分
- MobileUserScore.UserScore.lScore = pUserInfo->lScore;
- MobileUserScore.UserScore.lScore += pIServerUserItem->GetTrusteeScore();
- MobileUserScore.UserScore.lScore += pIServerUserItem->GetFrozenedScore();
-
- //发送数据
- m_pIGameServiceFrame->SendDataBatchToMobileUser(pIServerUserItem->GetTableID(), MDM_GR_USER, SUB_GR_USER_SCORE, &MobileUserScore, sizeof(MobileUserScore));
-
- //即时写分
- if ((CServerRule::IsImmediateWriteScore(m_pGameServiceOption->dwServerRule) == true) && (pIServerUserItem->IsVariation() == true))
- {
- //变量定义
- DBR_GR_WriteGameScore WriteGameScore;
- ZeroMemory(&WriteGameScore, sizeof(WriteGameScore));
-
- //用户信息
- WriteGameScore.dwUserID = pIServerUserItem->GetUserID();
- WriteGameScore.dwDBQuestID = pIServerUserItem->GetDBQuestID();
- WriteGameScore.dwClientAddr = pIServerUserItem->GetClientAddr();
- WriteGameScore.dwInoutIndex = pIServerUserItem->GetInoutIndex();
-
- //提取积分
- pIServerUserItem->DistillVariation(WriteGameScore.VariationInfo);
-
- //比赛信息
- WriteGameScore.dwMatchID = m_pMatchOption->dwMatchID;
- WriteGameScore.dwMatchNO = m_pMatchOption->dwMatchNO;
-
- //投递请求
- m_pIDataBaseEngine->PostDataBaseRequest(WriteGameScore.dwUserID, DBR_GR_WRITE_GAME_SCORE, 0L, &WriteGameScore, sizeof(WriteGameScore), TRUE);
- }
-
- return true;
- }
-
- //用户状态
- bool CLockTimeMatch::OnEventUserItemStatus(IServerUserItem * pIServerUserItem, WORD wOldTableID, WORD wOldChairID, bool bSendState)
- {
- if (m_pIServerUserItemSink != NULL)
- {
- return m_pIServerUserItemSink->OnEventUserItemStatus(pIServerUserItem, wOldTableID, wOldChairID);
- }
-
- return true;
- }
-
- //用户权限
- bool CLockTimeMatch::OnEventUserItemRight(IServerUserItem *pIServerUserItem, DWORD dwAddRight, DWORD dwRemoveRight, BYTE cbRightKind)
- {
- if (m_pIServerUserItemSink != NULL)
- {
- return m_pIServerUserItemSink->OnEventUserItemRight(pIServerUserItem, dwAddRight, dwRemoveRight, cbRightKind);
- }
-
- return true;
- }
-
- //用户登录
- bool CLockTimeMatch::OnEventUserLogon(IServerUserItem * pIServerUserItem)
- {
- //发送状态
- if (m_MatchStatus > MatchStatus_Free)
- {
- //发送状态
- BYTE cbMatchStatus = (m_MatchStatus == MatchStatus_Playing) ? MS_MATCHING : MS_MATCHEND;
- m_pIGameServiceFrame->SendData(pIServerUserItem, MDM_GR_MATCH, SUB_GR_MATCH_STATUS, &cbMatchStatus, sizeof(cbMatchStatus));
-
- //构造结构
- CMD_GR_Match_Num MatchNum;
- ZeroMemory(&MatchNum, sizeof(MatchNum));
-
- //设置变量
- MatchNum.dwWaitting = m_pIServerUserManager->GetUserItemCount();
-
- //发送消息
- m_pIGameServiceFrame->SendData(BG_ALL_CLIENT, MDM_GR_MATCH, SUB_GR_MATCH_NUM, &MatchNum, sizeof(MatchNum));
- }
-
- return true;
- }
-
- //用户登出
- bool CLockTimeMatch::OnEventUserLogout(IServerUserItem * pIServerUserItem)
- {
- //构造结构
- CMD_GR_Match_Num MatchNum;
- ZeroMemory(&MatchNum, sizeof(MatchNum));
-
- //设置变量
- MatchNum.dwWaitting = m_pIServerUserManager->GetUserItemCount();
-
- //发送消息
- m_pIGameServiceFrame->SendData(BG_ALL_CLIENT, MDM_GR_MATCH, SUB_GR_MATCH_NUM, &MatchNum, sizeof(MatchNum));
-
- return true;
- }
-
- //进入事件
- bool CLockTimeMatch::OnEventEnterMatch(DWORD dwSocketID, VOID* pData, DWORD dwUserIP, bool bIsMobile)
- {
- //判断时间
- TCHAR szDescribe[256];
- WORD wMessageType;
- if (VerifyMatchTime(szDescribe, CountArray(szDescribe), wMessageType) == false)
- {
- m_pIGameServiceFrame->SendRoomMessage(dwSocketID, szDescribe, wMessageType | SMT_GLOBAL, dwUserIP == 0);
- return true;
- }
-
- //手机用户
- if (bIsMobile == true)
- {
- //处理消息
- CMD_GR_LogonMobile * pLogonMobile = (CMD_GR_LogonMobile *)pData;
- pLogonMobile->szPassword[CountArray(pLogonMobile->szPassword) - 1] = 0;
- pLogonMobile->szMachineID[CountArray(pLogonMobile->szMachineID) - 1] = 0;
-
- //变量定义
- DBR_GR_LogonMobile LogonMobile;
- ZeroMemory(&LogonMobile, sizeof(LogonMobile));
-
- //构造数据
- LogonMobile.dwUserID = pLogonMobile->dwUserID;
- LogonMobile.dwClientAddr = dwUserIP;
- LogonMobile.dwMatchID = m_pMatchOption->dwMatchID;
- LogonMobile.dwMatchNO = m_pMatchOption->dwMatchNO;
- LogonMobile.cbDeviceType = pLogonMobile->cbDeviceType;
- LogonMobile.wBehaviorFlags = pLogonMobile->wBehaviorFlags;
- LogonMobile.wPageTableCount = pLogonMobile->wPageTableCount;
- lstrcpyn(LogonMobile.szPassword, pLogonMobile->szPassword, CountArray(LogonMobile.szPassword));
- lstrcpyn(LogonMobile.szMachineID, pLogonMobile->szMachineID, CountArray(LogonMobile.szMachineID));
-
- //投递请求
- m_pIDataBaseEngine->PostDataBaseRequest(LogonMobile.dwUserID, DBR_GR_LOGON_MOBILE, dwSocketID, &LogonMobile, sizeof(LogonMobile));
- }
- else
- {
- //处理消息
- CMD_GR_LogonUserID * pLogonUserID = (CMD_GR_LogonUserID *)pData;
- pLogonUserID->szPassword[CountArray(pLogonUserID->szPassword) - 1] = 0;
- pLogonUserID->szMachineID[CountArray(pLogonUserID->szMachineID) - 1] = 0;
-
- //变量定义
- DBR_GR_LogonUserID LogonUserID;
- ZeroMemory(&LogonUserID, sizeof(LogonUserID));
-
- //构造数据
- LogonUserID.dwClientAddr = dwUserIP;
- LogonUserID.dwUserID = pLogonUserID->dwUserID;
- LogonUserID.dwMatchID = m_pMatchOption->dwMatchID;
- LogonUserID.dwMatchNO = m_pMatchOption->dwMatchNO;
- lstrcpyn(LogonUserID.szPassword, pLogonUserID->szPassword, CountArray(LogonUserID.szPassword));
- lstrcpyn(LogonUserID.szMachineID, pLogonUserID->szMachineID, CountArray(LogonUserID.szMachineID));
-
- //投递请求
- m_pIDataBaseEngine->PostDataBaseRequest(LogonUserID.dwUserID, DBR_GR_LOGON_USERID, dwSocketID, &LogonUserID, sizeof(LogonUserID));
- }
-
- return true;
- }
-
- //用户参赛
- bool CLockTimeMatch::OnEventUserJoinMatch(IServerUserItem * pIServerUserItem, BYTE cbReason, DWORD dwSocketID)
- {
- //参数校验
- ASSERT(pIServerUserItem != NULL);
- if (pIServerUserItem == NULL) return false;
-
- //判断状态
- if (pIServerUserItem->GetUserStatus() != US_FREE || pIServerUserItem->GetTableID() != INVALID_TABLE)
- {
- return false;
- }
-
- //比赛未开始
- if (m_MatchStatus == MatchStatus_Free)
- {
- //发送消息
- m_pIGameServiceFrame->SendRoomMessage(pIServerUserItem, TEXT("比赛尚未开始,请稍后再来!"), SMT_EJECT);
-
- return true;
- }
-
- //比赛结束
- if (m_MatchStatus == MatchStatus_End)
- {
- //发送消息
- m_pIGameServiceFrame->SendRoomMessage(pIServerUserItem, TEXT("比赛已经结束,请您移驾至其他比赛房间参与比赛!"), SMT_EJECT);
- return true;
- }
-
- //加入分组
- if (InsertDistribute(pIServerUserItem) == false) return false;
-
- //发送成绩
- SendMatchUserScore(pIServerUserItem);
-
- //发送消息
- m_pIGameServiceFrame->SendRoomMessage(pIServerUserItem, TEXT("系统正在努力为您分配座位,请稍后。。。"), SMT_CHAT);
-
- return true;
- }
-
- //用户退赛
- bool CLockTimeMatch::OnEventUserQuitMatch(IServerUserItem * pIServerUserItem, BYTE cbReason, WORD *pBestRank, DWORD dwContextID)
- {
- ASSERT(pIServerUserItem != NULL);
- if (pIServerUserItem == NULL) return false;
-
- //移除分组
- m_DistributeManage.RemoveDistributeNode(pIServerUserItem);
-
- //移除同桌信息
- m_DistributeManage.RemoveUserSameTableInfo(pIServerUserItem->GetUserID());
-
- return true;
- }
-
- //游戏开始
- bool CLockTimeMatch::OnEventGameStart(ITableFrame *pITableFrame, WORD wChairCount)
- {
- //发送比赛信息
- SendTableUserMatchInfo(pITableFrame, INVALID_CHAIR);
-
- //构造数据包
- CMD_CM_SystemMessage SystemMessage;
- ZeroMemory(&SystemMessage, sizeof(SystemMessage));
-
- //变量定义
- IServerUserItem *pIServerUserItem = NULL;
- IServerUserItem *pITableUserItem = NULL;
-
- for (INT i = 0; i < pITableFrame->GetChairCount(); i++)
- {
- pIServerUserItem = pITableFrame->GetTableUserItem(i);
- ASSERT(pIServerUserItem != NULL);
- if (pIServerUserItem == NULL) continue;
-
- //构造提示消息
- TCHAR szMessage[64] = TEXT("");
- _sntprintf(szMessage, CountArray(szMessage), TEXT("本局比赛是您的第 %d 局。"), pIServerUserItem->GetUserPlayCount() + 1);
- lstrcpyn(SystemMessage.szString, szMessage, CountArray(SystemMessage.szString));
- SystemMessage.wLength = CountStringBuffer(SystemMessage.szString);
- SystemMessage.wType = SMT_CHAT;
-
- //发送提示数据
- WORD wSendSize = sizeof(SystemMessage)-sizeof(SystemMessage.szString) + SystemMessage.wLength*sizeof(TCHAR);
- pITableFrame->SendTableData(pIServerUserItem->GetChairID(), SUB_GF_SYSTEM_MESSAGE, &SystemMessage, wSendSize, MDM_GF_FRAME);
-
- //清除同桌
- ClearSameTableUser(pIServerUserItem->GetUserID());
-
- for (INT j = 0; j < pITableFrame->GetChairCount(); j++)
- {
- //获取用户
- pITableUserItem = pITableFrame->GetTableUserItem(j);
- if (pITableUserItem == NULL) continue;
- if (pITableUserItem == pIServerUserItem) continue;
-
- //插入同桌用户
- InserSameTableUser(pIServerUserItem->GetUserID(), pITableUserItem->GetUserID());
- }
- }
-
- return true;
- }
-
- //游戏结束
- bool CLockTimeMatch::OnEventGameEnd(ITableFrame *pITableFrame, WORD wChairID, IServerUserItem * pIServerUserItem, BYTE cbReason)
- {
- ASSERT(pITableFrame != NULL);
- if (pITableFrame == NULL) return false;
-
- //结束处理
- for (INT i = 0; i<pITableFrame->GetChairCount(); i++)
- {
- IServerUserItem *pIUserItem = pITableFrame->GetTableUserItem(i);
- ASSERT(pIUserItem != NULL);
- if (pIUserItem == NULL) continue;
-
- //正常结束
- if (cbReason != REMOVE_BY_ENDMATCH)
- {
- //达到淘汰线
- if (m_pMatchOption->MatchType.LockTime.lMatchCullScore>0 && pIUserItem->GetUserScore() < m_pMatchOption->MatchType.LockTime.lMatchCullScore)
- {
- //变量定义
- TCHAR szMessage[128] = TEXT("");
- _sntprintf(szMessage, CountArray(szMessage), TEXT("由于您的比赛币低于 %d,您将不能继续游戏!"), m_pMatchOption->MatchType.LockTime.lMatchCullScore);
-
- //发送消息
- m_pIGameServiceFrame->SendGameMessage(pIUserItem, szMessage, SMT_EJECT | SMT_CHAT);
-
- //构造结构
- DBR_GR_MatchEliminate MatchEliminate;
- MatchEliminate.cbMatchType = MATCH_TYPE_LOCKTIME;
- MatchEliminate.dwMatchID = m_pMatchOption->dwMatchID;
- MatchEliminate.dwMatchNO = m_pMatchOption->dwMatchNO;
- MatchEliminate.dwUserID = pIUserItem->GetUserID();
-
- //投递请求
- m_pIDataBaseEngine->PostDataBaseRequest(0, DBR_GR_MATCH_ELIMINATE, 0, &MatchEliminate, sizeof(MatchEliminate));
-
- //发送数据
- m_pIGameServiceFrame->SendData(pIUserItem, MDM_GR_MATCH, SUB_GR_MATCH_ELIMINATE, NULL, 0);
-
- continue;
- }
-
- //插入分组
- if (InsertDistribute(pIUserItem) == true)
- {
- m_pIGameServiceFrame->SendGameMessage(pIUserItem, TEXT("本局比赛结束,系统正在努力为您分配座位,请稍后..."), SMT_CHAT | SMT_TABLE_ROLL);
- }
-
- //完成局数
- if (pIUserItem->GetUserPlayCount() - pIUserItem->GetUserInfo()->dwFleeCount == m_pMatchOption->MatchType.LockTime.wMatchPlayCount)
- {
- TCHAR szMessage[128] = TEXT("");
- _sntprintf(szMessage, CountArray(szMessage), TEXT("您已完成%d局比赛,可以继续当前比赛或选择退出等待本次比赛活动结束后排名!"), m_pMatchOption->MatchType.LockTime.wMatchPlayCount);
- m_pIGameServiceFrame->SendGameMessage(pIUserItem, szMessage, SMT_CHAT | SMT_TABLE_ROLL);
- }
- }
- }
-
- return true;
- }
-
- //用户坐下
- bool CLockTimeMatch::OnActionUserSitDown(WORD wTableID, WORD wChairID, IServerUserItem * pIServerUserItem, bool bLookonUser)
- {
- return true;
- }
-
- //用户起立
- bool CLockTimeMatch::OnActionUserStandUp(WORD wTableID, WORD wChairID, IServerUserItem * pIServerUserItem, bool bLookonUser)
- {
- //移除分组
- return RemoveDistribute(pIServerUserItem);
- }
-
- //用户同意
- bool CLockTimeMatch::OnActionUserOnReady(WORD wTableID, WORD wChairID, IServerUserItem * pIServerUserItem, VOID * pData, WORD wDataSize)
- {
- return true;
- }
-
- //参赛权限
- bool CLockTimeMatch::VerifyUserEnterMatch(IServerUserItem * pIServerUserItem)
- {
- ASSERT(pIServerUserItem != NULL);
- if (pIServerUserItem == NULL) return false;
-
- //机器人不受限制
- if (pIServerUserItem->IsAndroidUser() == true)
- return true;
-
- //变量定义
- WORD wMessageType;
- TCHAR szMessage[128] = TEXT("");
-
- //结束时间已到
- if (VerifyMatchTime(szMessage, CountArray(szMessage), wMessageType) == false)
- {
- //发送消息
- m_pIGameServiceFrame->SendRoomMessage(pIServerUserItem, szMessage, wMessageType);
-
- return false;
- }
-
- //达到淘汰线
- if (m_pMatchOption->MatchType.LockTime.lMatchCullScore > 0 && pIServerUserItem->GetUserScore() < m_pMatchOption->MatchType.LockTime.lMatchCullScore)
- {
- _sntprintf(szMessage, CountArray(szMessage), TEXT("由于您的比赛币低于 %d,您将不能继续游戏!"), m_pMatchOption->MatchType.LockTime.lMatchCullScore);
-
- //发送消息
- if (pIServerUserItem->GetTableID() == INVALID_TABLE)
- {
- m_pIGameServiceFrame->SendRoomMessage(pIServerUserItem, szMessage, SMT_EJECT | SMT_CHAT);
- }
- else
- {
- m_pIGameServiceFrame->SendGameMessage(pIServerUserItem, szMessage, SMT_EJECT | SMT_CHAT);
- }
-
- return false;
- }
-
- return true;
- }
-
- //开始间隔
- DWORD CLockTimeMatch::GetMatchStartInterval()
- {
- //获取时间
- CTime CurTime = CTime::GetCurrentTime();
- CTime MatchStartTime(m_pMatchOption->MatchType.LockTime.MatchStartTime);
- CTime MatchEndTime(m_pMatchOption->MatchType.LockTime.MatchEndTime);
-
- //变量定义
- DWORD dwTimeInterval = 1;
- DWORD dwCurrStamp, dwStartStamp, dwEndStamp;
-
- //比赛未开始
- if (CurTime < MatchStartTime)
- {
- CTimeSpan TimeSpan = MatchStartTime - CurTime;
- dwTimeInterval = TimeSpan.GetTotalSeconds();
- }
-
- //比赛已结束
- if (CurTime >= MatchEndTime) dwTimeInterval = 0;
-
- //计算时间
- dwCurrStamp = CurTime.GetHour() * 3600 + CurTime.GetMinute() * 60 + CurTime.GetSecond();
- dwStartStamp = m_pMatchOption->MatchType.LockTime.MatchStartTime.wHour * 3600 + m_pMatchOption->MatchType.LockTime.MatchStartTime.wMinute * 60 + m_pMatchOption->MatchType.LockTime.MatchStartTime.wSecond;
- dwEndStamp = m_pMatchOption->MatchType.LockTime.MatchEndTime.wHour * 3600 + m_pMatchOption->MatchType.LockTime.MatchEndTime.wMinute * 60 + m_pMatchOption->MatchType.LockTime.MatchEndTime.wSecond;
-
- //比赛未开始
- if (dwCurrStamp < dwStartStamp)
- {
- dwTimeInterval = dwStartStamp - dwCurrStamp;
- }
-
- //比赛已结束
- if (dwCurrStamp >= dwEndStamp)
- {
- dwTimeInterval = 24 * 3600 - (dwCurrStamp - dwStartStamp);
- }
-
- return dwTimeInterval;
- }
-
- //分配用户
- bool CLockTimeMatch::PerformDistribute()
- {
- //状态判断
- if (m_MatchStatus != MatchStatus_Playing) return true;
-
- //人数校验
- if (m_DistributeManage.GetCount() < m_pGameServiceOption->wMinDistributeUser) return false;
-
- //分配用户
- while (true)
- {
- //变量定义
- CDistributeInfoArray DistributeInfoArray;
-
- //获取用户
- //WORD wRandCount = __max(m_pGameServiceOption->wMaxDistributeUser-m_pGameServiceOption->wMinPartakeGameUser+1,1);
- WORD wChairCount = m_pGameServiceAttrib->wChairCount/*+rand()%wRandCount*/;
- WORD wDistributeCount = m_DistributeManage.PerformDistribute(DistributeInfoArray, wChairCount);
- if (wDistributeCount < wChairCount/*m_pGameServiceOption->wMinPartakeGameUser*/) break;
-
- //寻找位置
- ITableFrame * pICurrTableFrame = NULL;
- for (WORD i = 0; i < m_pGameServiceOption->wTableCount; i++)
- {
- //获取对象
- ASSERT(m_ppITableFrame[i] != NULL);
- ITableFrame * pITableFrame = m_ppITableFrame[i];
-
- //状态判断
- if (pITableFrame->GetNullChairCount() == pITableFrame->GetChairCount())
- {
- pICurrTableFrame = pITableFrame;
- break;
- }
- }
-
- //桌子判断
- if (pICurrTableFrame == NULL) break;
-
- //玩家坐下
- bool bSitSuccess = true;
- INT_PTR nSitFailedIndex = INVALID_CHAIR;
- for (INT_PTR nIndex = 0; nIndex < DistributeInfoArray.GetCount(); nIndex++)
- {
- //变量定义
- WORD wChairID = INVALID_CHAIR;
-
- //椅子搜索
- for (WORD i = 0; i < pICurrTableFrame->GetChairCount(); i++)
- {
- if (pICurrTableFrame->GetTableUserItem(i) == NULL)
- {
- wChairID = i;
- break;
- }
- }
-
- //分配用户
- if (wChairID != INVALID_CHAIR)
- {
- //获取用户
- IServerUserItem * pIServerUserItem = DistributeInfoArray[nIndex].pIServerUserItem;
-
- //用户起立
- if (pIServerUserItem->GetTableID() != INVALID_TABLE)
- {
- WORD wTableID = pIServerUserItem->GetTableID();
- ITableFrame * pITableFrame = m_ppITableFrame[wTableID];
- pITableFrame->PerformStandUpAction(pIServerUserItem);
- }
-
- //用户坐下
- if (pICurrTableFrame->PerformSitDownAction(wChairID, pIServerUserItem) == false)
- {
- bSitSuccess = false;
- nSitFailedIndex = nIndex;
- break;
- }
- }
- }
-
- //坐下结果
- if (bSitSuccess)
- {
- //移除结点
- while (DistributeInfoArray.GetCount() > 0)
- {
- m_DistributeManage.RemoveDistributeNode((tagDistributeNode *)DistributeInfoArray[0].pPertainNode);
- DistributeInfoArray.RemoveAt(0);
- }
- }
- else
- {
- for (INT_PTR nIndex = 0; nIndex < DistributeInfoArray.GetCount(); nIndex++)
- {
- if (nSitFailedIndex == nIndex)
- {
- m_DistributeManage.RemoveDistributeNode((tagDistributeNode *)DistributeInfoArray[nIndex].pPertainNode);
- }
- else
- {
- //用户起立
- if (DistributeInfoArray[nIndex].pIServerUserItem->GetTableID() != INVALID_TABLE)
- {
- WORD wTableID = DistributeInfoArray[nIndex].pIServerUserItem->GetTableID();
- m_ppITableFrame[wTableID]->PerformStandUpAction(DistributeInfoArray[nIndex].pIServerUserItem);
- }
- }
- }
- }
- }
-
- return true;
- }
-
- //插入用户
- bool CLockTimeMatch::InsertDistribute(IServerUserItem * pIServerUserItem)
- {
- //效验参数
- ASSERT(pIServerUserItem != NULL);
- if (pIServerUserItem == NULL) return false;
-
- //比赛状态
- if (m_MatchStatus != MatchStatus_Playing) return false;
-
- //状态判断
- ASSERT(pIServerUserItem->GetUserStatus() < US_PLAYING);
- if (pIServerUserItem->GetUserStatus() >= US_PLAYING) return false;
-
- //参赛校验
- if (VerifyUserEnterMatch(pIServerUserItem) == false) return false;
-
- //变量定义
- tagDistributeInfo DistributeInfo;
- ZeroMemory(&DistributeInfo, sizeof(DistributeInfo));
-
- //设置变量
- DistributeInfo.pPertainNode = NULL;
- DistributeInfo.dwInsertStamp = (DWORD)time(NULL);
- DistributeInfo.pIServerUserItem = pIServerUserItem;
-
- //插入节点
- if (m_DistributeManage.InsertDistributeNode(DistributeInfo) == false)
- {
- return pIServerUserItem->IsAndroidUser() ? false : true;
- }
-
- return true;
- }
-
- //清除玩家
- void CLockTimeMatch::ClearSameTableUser(DWORD dwUserID)
- {
- //变量定义
- tagSameTableInfo * pSameTableInfo = m_DistributeManage.GetUserSameTableInfo(dwUserID);
- if (pSameTableInfo != NULL)
- {
- pSameTableInfo->wPlayerCount = 0;
- ZeroMemory(pSameTableInfo->wPlayerIDSet, sizeof(pSameTableInfo->wPlayerIDSet));
- }
- }
-
- //插入用户
- void CLockTimeMatch::InserSameTableUser(DWORD dwUserID, DWORD dwTableUserID)
- {
- //变量定义
- tagSameTableInfo * pSameTableInfo = m_DistributeManage.GetUserSameTableInfo(dwUserID);
- if (pSameTableInfo != NULL)
- {
- //添加用户
- pSameTableInfo->wPlayerIDSet[pSameTableInfo->wPlayerCount++] = dwTableUserID;
- }
-
- return;
- }
-
- //事件校验
- bool CLockTimeMatch::VerifyMatchTime(LPTSTR pszMessage, WORD wMaxCount, WORD & wMessageType)
- {
- //变量定义
- CTime CurTime = CTime::GetCurrentTime();
- CTime MatchStartTime(m_pMatchOption->MatchType.LockTime.MatchStartTime);
- CTime MatchEndTime(m_pMatchOption->MatchType.LockTime.MatchEndTime);
-
- //设置类型
- wMessageType = SMT_EJECT | SMT_CHAT;
-
- ////比赛未开始
- //if(CurTime<MatchStartTime)
- //{
- // wMessageType |= SMT_CLOSE_ROOM;
- // _sntprintf(pszMessage,wMaxCount,TEXT("比赛尚未开始,请您于%d年%d月%d日-%d时%d分%d秒前来参加比赛!"),MatchStartTime.GetYear(),MatchStartTime.GetMonth(),MatchStartTime.GetDay(),MatchStartTime.GetHour(),MatchStartTime.GetMinute(),MatchStartTime.GetSecond());
- // return false;
- //}
-
- //比赛已结束
- if (CurTime >= MatchEndTime)
- {
- wMessageType |= SMT_CLOSE_ROOM | SMT_CLOSE_GAME;
- _sntprintf(pszMessage, wMaxCount, TEXT("比赛已经结束,请您移驾至其他比赛房间参与比赛吧!"));
- return false;
- }
-
- ////比赛未开始
- //if(CurTime.GetHour()*3600+CurTime.GetMinute()*60+CurTime.GetSecond()<
- // m_pMatchOption->MatchType.LockTime.MatchStartTime.wHour*3600+m_pMatchOption->MatchType.LockTime.MatchStartTime.wMinute*60+m_pMatchOption->MatchType.LockTime.MatchStartTime.wSecond)
- //{
- // wMessageType |= SMT_CLOSE_ROOM|SMT_CLOSE_GAME;
- // _sntprintf(pszMessage,wMaxCount,TEXT("今天的比赛尚未开始,请您于%d时%d分%d秒前来参加比赛!"),MatchStartTime.GetHour(),MatchStartTime.GetMinute(),MatchStartTime.GetSecond());
- // return false;
- //}
-
- //比赛已结束
- if (CurTime.GetHour() * 3600 + CurTime.GetMinute() * 60 + CurTime.GetSecond() >= m_pMatchOption->MatchType.LockTime.MatchEndTime.wHour * 3600 + m_pMatchOption->MatchType.LockTime.MatchEndTime.wMinute * 60 + m_pMatchOption->MatchType.LockTime.MatchEndTime.wSecond)
- {
- wMessageType |= SMT_CLOSE_ROOM | SMT_CLOSE_GAME;
- _sntprintf(pszMessage, wMaxCount, TEXT("今天的比赛已经结束,请您于明天%d时%d分%d秒前来参加比赛!"), MatchStartTime.GetHour(), MatchStartTime.GetMinute(), MatchStartTime.GetSecond());
- return false;
- }
-
- return true;
- }
-
- //发送用户分数
- bool CLockTimeMatch::SendMatchUserScore(IServerUserItem * pIServerUserItem)
- {
- //发送数据
- CMD_GR_UserScore UserScore;
- ZeroMemory(&UserScore, sizeof(UserScore));
-
- tagUserInfo * pUserInfo = pIServerUserItem->GetUserInfo();
-
- //构造数据
- UserScore.dwUserID = pUserInfo->dwUserID;
- UserScore.UserScore.dwWinCount = pUserInfo->dwWinCount;
- UserScore.UserScore.dwLostCount = pUserInfo->dwLostCount;
- UserScore.UserScore.dwDrawCount = pUserInfo->dwDrawCount;
- UserScore.UserScore.dwFleeCount = pUserInfo->dwFleeCount;
- UserScore.UserScore.dwExperience = pUserInfo->dwExperience;
- UserScore.UserScore.lLoveLiness = pUserInfo->lLoveLiness;
-
- //构造积分
- UserScore.UserScore.lGrade = pUserInfo->lGrade;
- UserScore.UserScore.lInsure = pUserInfo->lInsure;
- UserScore.UserScore.lScore = pUserInfo->lScore;
- UserScore.UserScore.lIngot = 0;// pUserInfo->lIngot;
-
- return m_pIGameServiceFrame->SendData(BG_ALL_CLIENT, MDM_GR_USER, SUB_GR_USER_SCORE, &UserScore, sizeof(UserScore));
- }
-
- //移除玩家
- bool CLockTimeMatch::RemoveDistribute(IServerUserItem * pIServerUserItem)
- {
- //验证参数
- ASSERT(pIServerUserItem != NULL);
- if (pIServerUserItem == NULL) return false;
-
- //移除用户
- m_DistributeManage.RemoveDistributeNode(pIServerUserItem);
-
- return true;
- }
-
-
- //发送比赛信息
- void CLockTimeMatch::SendTableUserMatchInfo(ITableFrame *pITableFrame, WORD wChairID)
- {
- //验证参数
- ASSERT(pITableFrame != NULL);
- if (pITableFrame == NULL) return;
-
- //构造数据
- CMD_GR_Match_Info MatchInfo;
- ZeroMemory(&MatchInfo, sizeof(MatchInfo));
-
- //设置标题
- _sntprintf(MatchInfo.szTitle[0], CountArray(MatchInfo.szTitle[0]), TEXT("积分方式:累计积分"));
- _sntprintf(MatchInfo.szTitle[1], CountArray(MatchInfo.szTitle[1]), TEXT("游戏基数:%d"), m_pMatchOption->MatchType.LockTime.lMatchInitScore);
- _sntprintf(MatchInfo.szTitle[2], CountArray(MatchInfo.szTitle[2]), TEXT("局制名称:定时开赛"));
-
- for (WORD i = 0; i < pITableFrame->GetChairCount(); i++)
- {
- //获取用户
- if (wChairID != INVALID_CHAIR && wChairID != i) continue;
- IServerUserItem *pIServerUserItem = pITableFrame->GetTableUserItem(i);
- if (pIServerUserItem == NULL) continue;
-
- //设置局数
- MatchInfo.wGameCount = (WORD)pIServerUserItem->GetUserPlayCount() + 1;
-
- //发送数据
- if (pIServerUserItem->IsAndroidUser() == false)
- {
- pITableFrame->SendTableData(i, SUB_GR_MATCH_INFO, &MatchInfo, sizeof(MatchInfo), MDM_GF_FRAME);
- }
- }
-
- return;
- }
-
- //写入奖励
- bool CLockTimeMatch::WriteUserAward(IServerUserItem *pIServerUserItem, tagMatchRankInfo * pMatchRankInfo)
- {
- //参数效验
- ASSERT(pIServerUserItem != NULL && pMatchRankInfo != NULL);
- if (pIServerUserItem == NULL || pMatchRankInfo == NULL) return false;
-
- //变量定义
- CMD_GR_MatchResult MatchResult;
- ZeroMemory(&MatchResult, sizeof(MatchResult));
-
- //比赛奖励
- MatchResult.lGold = pMatchRankInfo->lRewardGold;
- MatchResult.dwIngot = pMatchRankInfo->dwRewardIngot;
- MatchResult.dwExperience = pMatchRankInfo->dwRewardExperience;
-
- //获奖提示
- _sntprintf(MatchResult.szDescribe, CountArray(MatchResult.szDescribe), TEXT("%s, 恭喜您在%s中获得第%d名,奖励如下:"),
- pIServerUserItem->GetNickName(), m_pMatchOption->szMatchName, pMatchRankInfo->wRankID);
-
- //更新用户信息
- tagUserInfo * pUserInfo = pIServerUserItem->GetUserInfo();
- //pUserInfo->lIngot = 0;//pMatchRankInfo->dwRewardIngot;
- pUserInfo->dwExperience += pMatchRankInfo->dwRewardExperience;
- OnEventUserItemScore(pIServerUserItem, 0);
-
- //发送数据
- if (pIServerUserItem->IsAndroidUser() == false)
- {
- m_pIGameServiceFrame->SendData(pIServerUserItem, MDM_GF_FRAME, SUB_GR_MATCH_RESULT, &MatchResult, sizeof(MatchResult));
- }
-
- //写入记录
- if (m_pIDataBaseEngine != NULL)
- {
- //变量定义
- DBR_GR_MatchReward MatchReward;
- ZeroMemory(&MatchReward, sizeof(MatchReward));
-
- //构造结构
- MatchReward.dwUserID = pIServerUserItem->GetUserID();
- MatchReward.lRewardGold = pMatchRankInfo->lRewardGold;
- MatchReward.dwRewardIngot = pMatchRankInfo->dwRewardIngot;
- MatchReward.dwRewardExperience = pMatchRankInfo->dwRewardExperience;
- MatchReward.dwClientAddr = pIServerUserItem->GetClientAddr();
-
- //投递数据
- m_pIDataBaseEngine->PostDataBaseRequest(MatchReward.dwUserID, DBR_GR_MATCH_REWARD, 0, &MatchReward, sizeof(MatchReward));
- }
-
- return true;
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
|