Advertisement
Guest User

MMatchServer_Stage.cpp

a guest
Mar 5th, 2016
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 113.21 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "MMatrix.h"
  3. #include "MMatchServer.h"
  4. #include "MSharedCommandTable.h"
  5. #include "MErrorTable.h"
  6. #include "MBlobArray.h"
  7. #include "MObject.h"
  8. #include "MMatchObject.h"
  9. #include "MMatchItem.h"
  10. #include "MAgentObject.h"
  11. #include "MMatchNotify.h"
  12. #include "Msg.h"
  13. #include "MMatchObjCache.h"
  14. #include "MMatchStage.h"
  15. #include "MMatchTransDataType.h"
  16. #include "MMatchFormula.h"
  17. #include "MMatchConfig.h"
  18. #include "MCommandCommunicator.h"
  19. #include "MMatchShop.h"
  20. #include "MMatchTransDataType.h"
  21. #include "MDebug.h"
  22. #include "MMatchAuth.h"
  23. #include "MMatchStatus.h"
  24. #include "MAsyncDBJob.h"
  25. #include "MVoteDiscussImpl.h"
  26. #include "MUtil.h"
  27. #include "MMatchGameType.h"
  28. #include "MMatchRuleBaseQuest.h"
  29. #include "MMatchRuleQuest.h"
  30. #include "MMatchRuleBerserker.h"
  31. #include "MMatchRuleDuel.h"
  32. #include "MCrashDump.h"
  33.  
  34. #include "MAsyncDBJob_InsertGamePlayerLog.h"
  35.  
  36. static bool StageShowInfo(MMatchServer* pServer, const MUID& uidPlayer, const MUID& uidStage, char* pszChat);
  37.  
  38.  
  39. MMatchStage* MMatchServer::FindStage(const MUID& uidStage)
  40. {
  41. MMatchStageMap::iterator i = m_StageMap.find(uidStage);
  42. if(i==m_StageMap.end()) return NULL;
  43.  
  44. MMatchStage* pStage = (*i).second;
  45. return pStage;
  46. }
  47.  
  48. bool MMatchServer::StageAdd(MMatchChannel* pChannel, const char* pszStageName, bool bPrivate, const char* pszStagePassword, MUID* pAllocUID, bool bIsAllowNullChannel)
  49. {
  50. // Ŭ·£ÀüÀº pChannelÀÌ NULLÀÌ´Ù.
  51.  
  52. MUID uidStage = m_StageMap.UseUID();
  53.  
  54. MMatchStage* pStage= new MMatchStage;
  55. if (pChannel && !pChannel->AddStage(pStage)) {
  56. delete pStage;
  57. return false;
  58. }
  59.  
  60.  
  61. MMATCH_GAMETYPE GameType = MMATCH_GAMETYPE_DEFAULT;
  62. bool bIsCheckTicket = false;
  63. DWORD dwTicketID = 0;
  64.  
  65. if ( (NULL != pChannel) && MGetServerConfig()->IsUseTicket()) {
  66. bIsCheckTicket = (pChannel != 0) && pChannel->IsUseTicket() && pChannel->IsTicketChannel();
  67. dwTicketID = pChannel->GetTicketItemID();
  68.  
  69. // ƼÄÏ ¼­¹ö¿¡¼­ »ç¼³ ä³ÎÀº ¹«Á¶°Ç ƼÄÏ °Ë»ç - ƼÄÏÀº Ŭ·£Àü ƼÄÏ°ú µ¿ÀÏÇÏ´Ù.
  70. if ( pChannel->GetChannelType() == MCHANNEL_TYPE_USER) {
  71. bIsCheckTicket = true;
  72. dwTicketID = GetChannelMap()->GetClanChannelTicketInfo().m_dwTicketItemID;
  73. }
  74. }
  75.  
  76. if (!pStage->Create( uidStage, pszStageName, bPrivate, pszStagePassword, bIsAllowNullChannel, GameType, bIsCheckTicket, dwTicketID) ) {
  77. if (pChannel) {
  78. pChannel->RemoveStage(pStage);
  79. }
  80.  
  81. delete pStage;
  82. return false;
  83. }
  84.  
  85. m_StageMap.Insert(uidStage, pStage);
  86.  
  87. *pAllocUID = uidStage;
  88.  
  89. return true;
  90. }
  91.  
  92.  
  93. bool MMatchServer::StageRemove(const MUID& uidStage, MMatchStageMap::iterator* pNextItor)
  94. {
  95. MMatchStageMap::iterator i = m_StageMap.find(uidStage);
  96. if(i==m_StageMap.end()) {
  97. return false;
  98. }
  99.  
  100. MMatchStage* pStage = (*i).second;
  101.  
  102. MMatchChannel* pChannel = FindChannel(pStage->GetOwnerChannel());
  103. if (pChannel) {
  104. pChannel->RemoveStage(pStage);
  105. }
  106.  
  107. pStage->Destroy();
  108. delete pStage;
  109.  
  110. MMatchStageMap::iterator itorTemp = m_StageMap.erase(i);
  111. if (pNextItor) *pNextItor = itorTemp;
  112.  
  113. return true;
  114. }
  115.  
  116.  
  117. bool MMatchServer::StageJoin(const MUID& uidPlayer, const MUID& uidStage)
  118. {
  119. MMatchObject* pObj = GetObject(uidPlayer);
  120. if (!IsEnabledObject(pObj)) return false;
  121.  
  122. if (pObj->GetStageUID() != MUID(0,0))
  123. StageLeave(pObj->GetUID());//, pObj->GetStageUID());
  124.  
  125. MMatchChannel* pChannel = FindChannel(pObj->GetChannelUID());
  126. if (pChannel == NULL) return false;
  127. if (pChannel->GetChannelType() == MCHANNEL_TYPE_DUELTOURNAMENT) return false;
  128.  
  129. MMatchStage* pStage = FindStage(uidStage);
  130. if (pStage == NULL) return false;
  131.  
  132. int ret = ValidateStageJoin(uidPlayer, uidStage);
  133. if (ret != MOK) {
  134. RouteResponseToListener(pObj, MC_MATCH_RESPONSE_STAGE_JOIN, ret);
  135. return false;
  136. }
  137. pObj->OnStageJoin();
  138.  
  139. // Cache Add
  140. MMatchObjectCacheBuilder CacheBuilder;
  141. CacheBuilder.AddObject(pObj);
  142. MCommand* pCmdCacheAdd = CacheBuilder.GetResultCmd(MATCHCACHEMODE_ADD, this);
  143. RouteToStage(pStage->GetUID(), pCmdCacheAdd);
  144.  
  145. // Join
  146. pStage->AddObject(uidPlayer, pObj);
  147. // ÀÓ½ÃÄÚµå... À߸øµÈ Ŭ·£ID ¿Â´Ù¸é üũÇÏ¿© Àâ±âÀ§ÇÔ...20090224 by kammir
  148. if(pObj->GetCharInfo()->m_ClanInfo.GetClanID() >= 9000000)
  149. LOG(LOG_FILE, "[UpdateCharClanInfo()] %s's ClanID:%d.", pObj->GetAccountName(), pObj->GetCharInfo()->m_ClanInfo.GetClanID());
  150.  
  151. pObj->SetStageUID(uidStage);
  152. pObj->SetStageState(MOSS_NONREADY);
  153. pObj->SetTeam(pStage->GetRecommandedTeam());
  154.  
  155. // Cast Join
  156. MCommand* pNew = new MCommand(m_CommandManager.GetCommandDescByID(MC_MATCH_STAGE_JOIN), MUID(0,0), m_This);
  157. pNew->AddParameter(new MCommandParameterUID(uidPlayer));
  158. pNew->AddParameter(new MCommandParameterUID(pStage->GetUID()));
  159. pNew->AddParameter(new MCommandParameterUInt(pStage->GetIndex()+1));
  160. pNew->AddParameter(new MCommandParameterString((char*)pStage->GetName()));
  161.  
  162. if (pStage->GetState() == STAGE_STATE_STANDBY) RouteToStage(pStage->GetUID(), pNew);
  163. else RouteToListener(pObj, pNew);
  164.  
  165. // Cache Update
  166. CacheBuilder.Reset();
  167. for (MUIDRefCache::iterator i=pStage->GetObjBegin(); i!=pStage->GetObjEnd(); i++) {
  168. MUID uidObj = (MUID)(*i).first;
  169. MMatchObject* pScanObj = (MMatchObject*)GetObject(uidObj);
  170. if (pScanObj) {
  171. CacheBuilder.AddObject(pScanObj);
  172. } else {
  173. LOG(LOG_PROG, "MMatchServer::StageJoin - Invalid ObjectMUID(%u:%u) exist in Stage(%s)\n",
  174. uidObj.High, uidObj.Low, pStage->GetName());
  175. pStage->RemoveObject(uidObj);
  176. return false;
  177. }
  178. }
  179. MCommand* pCmdCacheUpdate = CacheBuilder.GetResultCmd(MATCHCACHEMODE_UPDATE, this);
  180. RouteToListener(pObj, pCmdCacheUpdate);
  181.  
  182.  
  183. // Cast Master(¹æÀå)
  184. MUID uidMaster = pStage->GetMasterUID();
  185. MCommand* pMasterCmd = CreateCommand(MC_MATCH_STAGE_MASTER, MUID(0,0));
  186. pMasterCmd->AddParameter(new MCommandParameterUID(uidStage));
  187. pMasterCmd->AddParameter(new MCommandParameterUID(uidMaster));
  188. RouteToListener(pObj, pMasterCmd);
  189.  
  190. #ifdef _QUEST_ITEM
  191. if (MGetServerConfig()->GetServerMode() == MSM_CLAN)
  192. {
  193. const MSTAGE_SETTING_NODE* pNode = pStage->GetStageSetting()->GetStageSetting();
  194. if( 0 == pNode )
  195. {
  196. mlog( "MMatchServer::StageJoin - ½ºÅ×ÀÌÁö ¼ÂÆà ³ëµå ã±â ½ÇÆÐ.\n" );
  197. return false;
  198. }
  199.  
  200. if (MGetGameTypeMgr()->IsQuestDerived(pNode->nGameType))
  201. {
  202. MMatchRuleBaseQuest* pRuleQuest = reinterpret_cast< MMatchRuleBaseQuest* >( pStage->GetRule() );
  203. if( 0 == pRuleQuest )
  204. {
  205. mlog( "MMatchServer::StageJoin - Æ÷ÀÎÅÍ Çüº¯È¯ ½ÇÆÐ.\n" );
  206. return false;
  207. }
  208.  
  209. pRuleQuest->OnChangeCondition();
  210. //pRuleQuest->OnResponseQL_ToStage( pObj->GetStageUID() );
  211. // µ¿È¯¾¾²²¼­ óÀ½ ½ºÅ×ÀÌÁö Á¶Àνô ÀÌÀü¿¡ ¼³Á¤ÀÌ Äù½ºÆ®·Î µÇÀ־
  212. // óÀ½ Á¶ÀÎÇÑ À¯Àú´Â Äù½ºÆ® ŸÀÔÀÎÁö ¾Ë¼ö°¡ ¾ø±â¿¡,
  213. // Ŭ¶óÀ̾ðÆ®°¡ ½ºÅ×ÀÌÁö ŸÀÔÀÌ Äù½ºÆ®ÀÎÁö¸¦ ÀνÄÇÏ´Â ½ÃÁ¡¿¡¼­
  214. // ÀÌ Á¤º¸¸¦ ¿äûÀ» ÇÏ´Â ¹æÇâÀ¸·Î ¼öÁ¤ÇÔ. - 05/04/14 by Ãß±³¼º.
  215. // pStage->GetRule()->OnResponseSacrificeSlotInfoToStage( uidPlayer );
  216. }
  217. }
  218. #endif
  219.  
  220. // Cast Character Setting
  221. StageTeam(uidPlayer, uidStage, pObj->GetTeam());
  222. StagePlayerState(uidPlayer, uidStage, pObj->GetStageState());
  223. // ¹æ¼Û °ü°èÀÚ¸é ¹æÀå±ÇÇÑÀ» ÀÚµ¿À¸·Î »©¾Ñ´Â´Ù. - ¿Â°ÔÀÓ³Ý ºñºñºò ¿äû
  224. if (MMUG_EVENTMASTER == pObj->GetAccountInfo()->m_nUGrade) {
  225. OnEventChangeMaster(pObj->GetUID());
  226. }
  227. return true;
  228. }
  229.  
  230. bool MMatchServer::StageLeave(const MUID& uidPlayer)
  231. {
  232. MMatchObject* pObj = GetObject( uidPlayer );
  233.  
  234. if( !IsEnabledObject(pObj) ) return false;
  235. // MMatchStage* pStage = FindStage(uidStage);
  236.  
  237. //if(pObj->GetStageUID()!=uidStage)
  238. // mlog(" stage leave hack %s (%d, %d) ignore\n", pObj->GetName(), uidPlayer.High, uidPlayer.Low);
  239.  
  240. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  241. if (pStage == NULL) return false;
  242.  
  243. bool bLeaverMaster = false;
  244. if (uidPlayer == pStage->GetMasterUID()) bLeaverMaster = true;
  245.  
  246. #ifdef _QUEST_ITEM
  247. if (MGetServerConfig()->GetServerMode() == MSM_CLAN)
  248. {
  249. const MSTAGE_SETTING_NODE* pNode = pStage->GetStageSetting()->GetStageSetting();
  250. if( 0 != pNode )
  251. {
  252. if (MGetGameTypeMgr()->IsQuestDerived(pNode->nGameType))
  253. {
  254. MMatchRuleBaseQuest* pRuleQuest = reinterpret_cast< MMatchRuleBaseQuest* >( pStage->GetRule() );
  255. if(pRuleQuest)
  256. {
  257. pRuleQuest->PreProcessLeaveStage( uidPlayer );
  258. } else {
  259. LOG(LOG_PROG, "StageLeave:: MMatchRule to MMatchRuleBaseQuest FAILED \n");
  260. }
  261. }
  262. }
  263. }
  264. #endif
  265.  
  266. MCommand* pNew = new MCommand(m_CommandManager.GetCommandDescByID(MC_MATCH_STAGE_LEAVE), MUID(0,0), m_This);
  267. pNew->AddParameter(new MCommandParameterUID(uidPlayer));
  268. // pNew->AddParameter(new MCommandParameterUID(pStage->GetUID()));
  269. RouteToStage(pStage->GetUID(), pNew);
  270.  
  271. pStage->RemoveObject(uidPlayer);
  272.  
  273. //MMatchObject* pObj = GetObject(uidPlayer);
  274. //if (pObj)
  275. {
  276. MMatchObjectCacheBuilder CacheBuilder;
  277. CacheBuilder.AddObject(pObj);
  278. MCommand* pCmdCache = CacheBuilder.GetResultCmd(MATCHCACHEMODE_REMOVE, this);
  279. RouteToStage(pStage->GetUID(), pCmdCache);
  280. }
  281.  
  282. // cast Master
  283. if (bLeaverMaster) StageMaster(pStage->GetUID());
  284.  
  285. #ifdef _QUEST_ITEM
  286. // À¯Àú°¡ ½ºÅ×ÀÌÁö¿¡¼­ ³ª°£ÈÄ¿¡ QLÀ» ´Ù½Ã °è»êÇØ Áà¾ß ÇÔ.
  287. if (MGetServerConfig()->GetServerMode() == MSM_CLAN)
  288. {
  289. const MSTAGE_SETTING_NODE* pNode = pStage->GetStageSetting()->GetStageSetting();
  290. if( 0 == pNode )
  291. {
  292. mlog( "MMatchServer::StageLeave - ½ºÅ×ÀÌÁö ¼ÂÆà ³ëµå ã±â ½ÇÆÐ.\n" );
  293. return false;
  294. }
  295.  
  296. if (MGetGameTypeMgr()->IsQuestDerived(pNode->nGameType))
  297. {
  298. MMatchRuleBaseQuest* pRuleQuest = reinterpret_cast< MMatchRuleBaseQuest* >( pStage->GetRule() );
  299. if( 0 == pRuleQuest )
  300. {
  301. mlog( "MMatchServer::StageLeave - Æ÷ÀÎÅÍ Çüº¯È¯ ½ÇÆÐ.\n" );
  302. return false;
  303. }
  304.  
  305. if( STAGE_STATE_STANDBY == pStage->GetState() )
  306. pRuleQuest->OnChangeCondition();
  307. //pRuleQuest->OnResponseQL_ToStage( uidStage );
  308. }
  309. }
  310. #endif
  311.  
  312. // Custom: Ladder Rejoin
  313. if (pStage->GetStageType() != MST_NORMAL)
  314. {
  315. MCommand* pNew = CreateCommand(MC_MATCH_NOTIFY_LADDER_REJOIN, uidPlayer);
  316. RouteToListener(pObj, pNew);
  317. }
  318.  
  319. return true;
  320. }
  321.  
  322.  
  323.  
  324. DWORD StageEnterBattleExceptionHandler( PEXCEPTION_POINTERS ExceptionInfo )
  325. {
  326. char szStageDumpFileName[ _MAX_DIR ]= {0,};
  327. SYSTEMTIME SystemTime;
  328. GetLocalTime( &SystemTime );
  329. sprintf( szStageDumpFileName, "Log/StageDump_%d-%d-%d_%d-%d-%d.dmp"
  330. , SystemTime.wYear
  331. , SystemTime.wMonth
  332. , SystemTime.wDay
  333. , SystemTime.wHour
  334. , SystemTime.wMinute
  335. , SystemTime.wSecond );
  336.  
  337. return CrashExceptionDump( ExceptionInfo, szStageDumpFileName, true );
  338. }
  339.  
  340.  
  341.  
  342. bool ExceptionTraceStageEnterBattle( MMatchObject* pObj, MMatchStage* pStage )
  343. {
  344. if( NULL == pObj )
  345. {
  346. return false;
  347. }
  348.  
  349. if( NULL == pStage )
  350. {
  351. return false;
  352. }
  353.  
  354. __try
  355. {
  356. pStage->EnterBattle(pObj);
  357. }
  358. __except( StageEnterBattleExceptionHandler(GetExceptionInformation()) )
  359. {
  360. /* mlog( "\nexception : stage enter battle =====================\n" );
  361.  
  362.  
  363. MMatchObject* pMaster = MGetMatchServer()->GetObject( pStage->GetMasterUID() );
  364. if( NULL != pMaster )
  365. {
  366. if( NULL != pMaster->GetCharInfo() )
  367. {
  368. mlog( "stage master cid : %d\n", pMaster->GetCharInfo()->m_nCID );
  369. }
  370. }
  371. else
  372. {
  373. mlog( "stage master hass problem.\n" );
  374. }
  375.  
  376.  
  377. if( NULL != pObj->GetCharInfo() )
  378. {
  379. mlog( "cmd sender cid : %d\n", pObj->GetCharInfo()->m_nCID );
  380. }
  381. else
  382. {
  383. mlog( "cmd send char info null point.\n" );
  384. }
  385.  
  386.  
  387. MMatchStageSetting* pStageSetting = pStage->GetStageSetting();
  388. if( NULL != pStageSetting )
  389. {
  390. mlog( "stage state : %d\n", pStage->GetStageSetting()->GetStageState() );
  391.  
  392. const MSTAGE_SETTING_NODE* pExStageSettingNode = pStageSetting->GetStageSetting();
  393. if( NULL != pExStageSettingNode )
  394. {
  395. mlog( "stage name : %s\n", pExStageSettingNode->szMapName );
  396. mlog( "stage game type : %d\n", pExStageSettingNode->nGameType );
  397. mlog( "stage max player : %d\n", pExStageSettingNode->nMaxPlayers );
  398. mlog( "stage current player : %d\n", pStage->GetPlayers() );
  399. mlog( "stage force entry enable : %d\n", pExStageSettingNode->bForcedEntryEnabled );
  400. mlog( "stage rule pointer : %x\n", pStage->GetRule() );
  401. }
  402. }
  403.  
  404. MUIDRefCache::iterator itStage, endStage;
  405. endStage = pStage->GetObjEnd();
  406. itStage = pStage->GetObjBegin();
  407. MMatchObject* pObj = NULL;
  408. for( ; endStage != itStage; ++itStage )
  409. {
  410. pObj = MGetMatchServer()->GetObject( itStage->first );
  411. if( NULL == pObj )
  412. {
  413. mlog( "!!!!stage can't find player!!!!\n" );
  414. continue;
  415. }
  416.  
  417. mlog( "stage player name : %s\n", pObj->GetName() );
  418. }
  419.  
  420. mlog( "=====================\n\n" );
  421. */
  422. return false;
  423. }
  424.  
  425. return true;
  426. }
  427.  
  428.  
  429.  
  430. bool MMatchServer::StageEnterBattle(const MUID& uidPlayer, const MUID& uidStage)
  431. {
  432. MMatchObject* pObj = GetObject(uidPlayer);
  433. if (!IsEnabledObject(pObj)) return false;
  434. // MMatchStage* pStage = FindStage(uidStage);
  435.  
  436. if(pObj->GetStageUID()!=uidStage)
  437. mlog(" stage enter battle hack %s (%d, %d) ignore\n", pObj->GetName(), uidPlayer.High, uidPlayer.Low);
  438.  
  439. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  440. if (pStage == NULL) return false;
  441.  
  442. pObj->SetPlace(MMP_BATTLE);
  443.  
  444. MCommand* pNew = CreateCommand(MC_MATCH_STAGE_ENTERBATTLE, MUID(0,0));
  445. //pNew->AddParameter(new MCommandParameterUID(uidPlayer));
  446. //pNew->AddParameter(new MCommandParameterUID(uidStage));
  447.  
  448. unsigned char nParam = MCEP_NORMAL;
  449. if (pObj->IsForcedEntried()) nParam = MCEP_FORCED;
  450. pNew->AddParameter(new MCommandParameterUChar(nParam));
  451.  
  452. void* pPeerArray = MMakeBlobArray(sizeof(MTD_PeerListNode), 1);
  453. MTD_PeerListNode* pNode = (MTD_PeerListNode*)MGetBlobArrayElement(pPeerArray, 0);
  454. memset(pNode, 0, sizeof(MTD_PeerListNode));
  455.  
  456. pNode->uidChar = pObj->GetUID();
  457. // pNode->dwIP = pObj->GetIP();
  458. // pNode->nPort = pObj->GetPort();
  459. // Custom: Don't distribute IP/Port in Clan Wars
  460. //if (pStage->GetStageSetting() != NULL && pStage->GetStageSetting()->IsTeamWinThePoint())
  461. //{
  462. // // unconnectable, force relay
  463. // pNode->dwIP = 0;
  464. // pNode->nPort = 0;
  465. //}
  466. if (IsAdminGrade(pObj)) /*|| pObj->GetAccountInfo()->m_nUGrade == MMUG_EVENTTEAM) && pObj->GetForcedNATOption() == true)*/
  467. {
  468. // There is a possibility that the GMs receive the non-staff user's IP and attempts to connect..?
  469. pNode->dwIP = 0;
  470. pNode->nPort = 0;
  471. }
  472. else
  473. {
  474. pNode->dwIP = pObj->GetIP();
  475. pNode->nPort = pObj->GetPort();
  476. }
  477.  
  478. CopyCharInfoForTrans(&pNode->CharInfo, pObj->GetCharInfo(), pObj);
  479. //¹öÇÁÁ¤º¸ÀÓ½ÃÁÖ¼® CopyCharBuffInfoForTrans(&pNode->CharBuffInfo, pObj->GetCharInfo(), pObj);
  480.  
  481. pNode->ExtendInfo.nPlayerFlags = pObj->GetPlayerFlags();
  482. if (pStage->GetStageSetting()->IsTeamPlay()) pNode->ExtendInfo.nTeam = (char)pObj->GetTeam();
  483. else pNode->ExtendInfo.nTeam = 0;
  484.  
  485. pNew->AddParameter(new MCommandParameterBlob(pPeerArray, MGetBlobArraySize(pPeerArray)));
  486. MEraseBlobArray(pPeerArray);
  487.  
  488. RouteToStage(uidStage, pNew);
  489.  
  490. // ¹èƲ ½ÃÀ۽𣠼¼ÆÃ
  491. pObj->GetCharInfo()->m_nBattleStartTime = MMatchServer::GetInstance()->GetGlobalClockCount();
  492. pObj->GetCharInfo()->m_nBattleStartXP = pObj->GetCharInfo()->m_nXP;
  493.  
  494. // ¶ó¿ìÆà ÈÄ¿¡ ³Ö¾î¾ß ÇÑ´Ù.
  495. return ExceptionTraceStageEnterBattle( pObj, pStage );
  496. }
  497.  
  498. bool MMatchServer::StageLeaveBattle(const MUID& uidPlayer, bool bGameFinishLeaveBattle, bool bForcedLeave)
  499. {
  500. MMatchObject* pObj = GetObject(uidPlayer);
  501. if (!IsEnabledObject(pObj)) return false;
  502. if (pObj->GetPlace() != MMP_BATTLE) { return false; }
  503.  
  504. // MMatchStage* pStage = FindStage(uidStage);
  505.  
  506. //if(pObj->GetStageUID()!=uidStage)
  507. // mlog(" stage leave battle hack %s (%d, %d) ignore\n", pObj->GetName(), uidPlayer.High, uidPlayer.Low);
  508.  
  509. const MUID uidStage = pObj->GetStageUID();
  510.  
  511. MMatchStage* pStage = FindStage(uidStage);
  512. if (pStage == NULL)
  513. { // Ŭ·£Àü½Ã ÇÑÁ·ÀÌ ´Ù³ª°¡¸é ½ºÅ×ÀÌÁö°¡ ¾ø¾îÁö¹Ç·Î ¿©±â¼­ agent¸¦ ²÷¾îÁØ´Ù.
  514. if (pObj->GetRelayPeer()) {
  515. MAgentObject* pAgent = GetAgent(pObj->GetAgentUID());
  516. if (pAgent) {
  517. MCommand* pCmd = CreateCommand(MC_AGENT_PEER_UNBIND, pAgent->GetCommListener());
  518. pCmd->AddParameter(new MCmdParamUID(uidPlayer));
  519. Post(pCmd);
  520. }
  521. }
  522.  
  523. UpdateCharDBCachingData(pObj); ///< XP, BP, KillCount, DeathCount ij½³ ¾÷µ¥ÀÌÆ®
  524. UpdateCharItemDBCachingData(pObj); ///< Character Item¿¡¼­ ¾÷µ¥ÀÌÆ®°¡ ÇÊ¿äÇÑ °Íµé ¾÷µ¥ÀÌÆ®
  525. //CheckSpendableItemCounts(pObj); ///< Ç×»ó UpdateCharItemDBCachingData µÚ¿¡ ÀÖ¾î¾ß ÇÕ´Ï´Ù.
  526.  
  527. ProcessCharPlayInfo(pObj); ///< ij¸¯ÅÍ Ç÷¹ÀÌÇÑ Á¤º¸ ¾÷µ¥ÀÌÆ®
  528. return false;
  529. }
  530. else
  531. {
  532. // Ç÷¹ÀÌ Á÷ÈÄ ´ë±â½Ç¿¡¼­ °æÇèÄ¡, ½Â/ÆÐ, ½Â·ü, ¹Ù¿îƼ°¡ ¹Ý¿µµÇÁö ¾Ê½À´Ï´Ù. - by kammir 2008.09.19
  533. // LeaveBattle°¡ µÇ¸é¼­ ij¸¯ÅÍ µ¥ÀÌÅ͸¦ ¾÷µ¥ÀÌÆ® ÇØÁØ´Ù.
  534. MMatchObjectCacheBuilder CacheBuilder;
  535. CacheBuilder.Reset();
  536. for (MUIDRefCache::iterator i=pStage->GetObjBegin(); i!=pStage->GetObjEnd(); i++) {
  537. MMatchObject* pScanObj = (MMatchObject*)(*i).second;
  538. CacheBuilder.AddObject(pScanObj);
  539. }
  540. MCommand* pCmdCacheUpdate = CacheBuilder.GetResultCmd(MATCHCACHEMODE_UPDATE, this);
  541. RouteToListener(pObj, pCmdCacheUpdate);
  542. }
  543.  
  544. pStage->LeaveBattle(pObj);
  545. pObj->SetPlace(MMP_STAGE);
  546.  
  547.  
  548. // ·¹º§¿¡ ¾È¸Â´Â Àåºñ¾ÆÀÌÅÛ Ã¼Å©
  549. #define LEGAL_ITEMLEVEL_DIFF 3
  550. bool bIsCorrect = true;
  551. for (int i = 0; i < MMCIP_END; i++) {
  552. if (CorrectEquipmentByLevel(pObj, MMatchCharItemParts(i), LEGAL_ITEMLEVEL_DIFF)) {
  553. bIsCorrect = false;
  554. }
  555. }
  556.  
  557. if (!bIsCorrect) {
  558. MCommand* pNewCmd = CreateCommand(MC_MATCH_RESPONSE_RESULT, MUID(0,0));
  559. pNewCmd->AddParameter(new MCommandParameterInt(MERR_TAKEOFF_ITEM_BY_LEVELDOWN));
  560. RouteToListener(pObj, pNewCmd);
  561. }
  562.  
  563. CheckExpiredItems(pObj); //< ±â°£ ¸¸·á ¾ÆÀÌÅÛÀÌ ÀÖ´ÂÁö üũ
  564.  
  565. if (pObj->GetRelayPeer()) {
  566. MAgentObject* pAgent = GetAgent(pObj->GetAgentUID());
  567. if (pAgent) {
  568. MCommand* pCmd = CreateCommand(MC_AGENT_PEER_UNBIND, pAgent->GetCommListener());
  569. pCmd->AddParameter(new MCmdParamUID(uidPlayer));
  570. Post(pCmd);
  571. }
  572. }
  573.  
  574. // ij¸¯ÅÍ Ç÷¹ÀÌÇÑ Á¤º¸ ¾÷µ¥ÀÌÆ®
  575. ProcessCharPlayInfo(pObj);
  576.  
  577. //=======================================================================================================================================
  578.  
  579. bool bIsLeaveAllBattle = true;
  580.  
  581. for (MUIDRefCache::iterator i=pStage->GetObjBegin(); i!=pStage->GetObjEnd(); i++) {
  582. MUID uidObj = (MUID)(*i).first;
  583. MMatchObject* pAllObj = (MMatchObject*)GetObject(uidObj);
  584. if(NULL == pAllObj) continue;
  585. if(MMP_STAGE != pAllObj->GetPlace()) {
  586. bIsLeaveAllBattle = false;
  587. break;
  588. }
  589. }
  590.  
  591.  
  592. if(pStage->IsRelayMap())
  593. {
  594. if(bGameFinishLeaveBattle)
  595. { // ¸±·¹À̸Ê, ¹èƲ Á¾·á·Î ½ºÅ×ÀÌÁö·Î ³ª¿ÔÀ»¶§
  596. if(!pStage->m_bIsLastRelayMap)
  597. { // ´ÙÀ½¸ÊÀÌ ÀÖ´Ù¸é ¹Ù·Î ´ÙÀ½ ¸Ê½ÃÀÛ Ã³¸®
  598.  
  599. if( !bForcedLeave )
  600. {
  601. pObj->SetStageState(MOSS_READY);
  602. }
  603.  
  604. if( bIsLeaveAllBattle )
  605. {
  606. OnStageRelayStart(uidStage);
  607. }
  608.  
  609. MCommand* pNew = CreateCommand(MC_MATCH_STAGE_LEAVEBATTLE_TO_CLIENT, MUID(0,0));
  610. pNew->AddParameter(new MCommandParameterUID(uidPlayer));
  611. pNew->AddParameter(new MCommandParameterBool(true));
  612. RouteToStage(uidStage, pNew);
  613. }
  614. }
  615. else
  616. { ///< ¸ÞÀÎ ¸Þ´º·Î ½ºÅ×ÀÌÁö¿¡ ³ª¿È
  617. MCommand* pNew = CreateCommand(MC_MATCH_STAGE_LEAVEBATTLE_TO_CLIENT, MUID(0,0));
  618. pNew->AddParameter(new MCommandParameterUID(uidPlayer));
  619. pNew->AddParameter(new MCommandParameterBool(false));
  620. RouteToStage(uidStage, pNew);
  621.  
  622. if(bIsLeaveAllBattle)
  623. { ///< ¸ðµÎ ½ºÅ×ÀÌÁö¿¡ ÀÖ´Ù¸é ¸±·¹ÀÌ¸Ê ¼¼ÆÃÀ» ´Ù½Ã ÇØÁØ´Ù.
  624. pStage->m_bIsLastRelayMap = true;//¸±·¹À̸ÊÀ» ³¡³½´Ù
  625. pStage->GetStageSetting()->SetMapName(MMATCH_MAPNAME_RELAYMAP);
  626. pStage->SetRelayMapCurrList(pStage->GetRelayMapList());
  627. pStage->m_RelayMapRepeatCountRemained = pStage->GetRelayMapRepeatCount();
  628. }
  629. }
  630. }
  631. else
  632. {
  633. MCommand* pNew = CreateCommand(MC_MATCH_STAGE_LEAVEBATTLE_TO_CLIENT, MUID(0,0));
  634. pNew->AddParameter(new MCommandParameterUID(uidPlayer));
  635. pNew->AddParameter(new MCommandParameterBool(false));
  636. RouteToStage(uidStage, pNew);
  637. }
  638.  
  639. //=======================================================================================================================================
  640.  
  641. // ¹æ¿¡¼­ ³ª°¡¸é noready»óÅ·Πº¯°æµÈ´Ù.
  642. // º¯°æµÈ Á¤º¸¸¦ ½ºÅ×ÀÌÁöÀÇ ¸ðµç Ŭ¶óÀ̾ðÆ®·Î º¸³»ÁÜ. - by SungE 2007-06-04
  643. StagePlayerState( uidPlayer, pStage->GetUID(), pObj->GetStageState() );
  644.  
  645. UpdateCharDBCachingData(pObj); ///< XP, BP, KillCount, DeathCount ij½³ ¾÷µ¥ÀÌÆ®
  646. UpdateCharItemDBCachingData(pObj); ///< Character Item¿¡¼­ ¾÷µ¥ÀÌÆ®°¡ ÇÊ¿äÇÑ °Íµé ¾÷µ¥ÀÌÆ®
  647. //CheckSpendableItemCounts(pObj); ///< Ç×»ó UpdateCharItemDBCachingData µÚ¿¡ ÀÖ¾î¾ß ÇÕ´Ï´Ù.
  648.  
  649. return true;
  650. }
  651.  
  652. bool MMatchServer::StageChat(const MUID& uidPlayer, const MUID& uidStage, char* pszChat)
  653. {
  654. MMatchStage* pStage = FindStage(uidStage);
  655. if (pStage == NULL) return false;
  656. MMatchObject* pObj = (MMatchObject*)GetObject(uidPlayer);
  657. if ((pObj == NULL) || (pObj->GetCharInfo() == NULL)) return false;
  658. int nGrade = pObj->GetAccountInfo()->m_nUGrade;
  659. if (nGrade == MMUG_CHAT_LIMITED) return false;
  660.  
  661.  
  662. // InsertChatDBLog(uidPlayer, pszChat);
  663.  
  664. ///< È«±âÁÖ(2009.08.04)
  665. ///< ÇöÀç ÇØ´ç »ç¿ëÀÚ°¡ ÀÖ´Â Stage¿Í º¸³»¿Â StageÀÇ UID°¡ ´Ù¸¦ °æ¿ì!
  666. ///< ´Ù¸¥ Stageµé¿¡°Ôµµ Msg¸¦ º¸³¾ ¼ö ÀÖ´Â ¹®Á¦°¡ ÀÖÀ½ (ÇØÅ· ÇÁ·Î±×·¥ »ç¿ë½Ã)
  667. if( uidStage != pObj->GetStageUID() )
  668. {
  669. //LOG(LOG_FILE,"MMatchServer::StageChat - Different Stage(S:%d, P:%d)", uidStage, pObj->GetStageUID());
  670. return false;
  671. }
  672. // Admin Logs
  673. if (IsAdminGrade(pObj) && MGetServerConfig()->IsUseAdminLog() == true)
  674. {
  675. m_MatchDBMgr.CreateAdminLog(pObj->GetAccountInfo()->m_nAID, pObj->GetCharInfo()->m_szName, pszChat, "Stage Chat");
  676. }
  677.  
  678. MCommand* pCmd = new MCommand(m_CommandManager.GetCommandDescByID(MC_MATCH_STAGE_CHAT), MUID(0,0), m_This);
  679. pCmd->AddParameter(new MCommandParameterUID(uidPlayer));
  680. pCmd->AddParameter(new MCommandParameterUID(uidStage));
  681. pCmd->AddParameter(new MCommandParameterString(pszChat));
  682.  
  683. /*if( uidStage == pObj->GetStageUID() )
  684. {
  685. LOG(LOG_PROG, "[Stage] | %s : %s ", pObj->GetName(), pszChat);
  686. }
  687. */
  688. RouteToStage(uidStage, pCmd);
  689. return true;
  690. }
  691.  
  692. bool MMatchServer::StageTeam(const MUID& uidPlayer, const MUID& uidStage, MMatchTeam nTeam)
  693. {
  694. MMatchStage* pStage = FindStage(uidStage);
  695. if (pStage == NULL) return false;
  696.  
  697. pStage->PlayerTeam(uidPlayer, nTeam);
  698.  
  699. MCommand* pCmd = CreateCommand(MC_MATCH_STAGE_TEAM, MUID(0,0));
  700. pCmd->AddParameter(new MCommandParameterUID(uidPlayer));
  701. pCmd->AddParameter(new MCommandParameterUID(uidStage));
  702. pCmd->AddParameter(new MCommandParameterUInt(nTeam));
  703.  
  704. RouteToStageWaitRoom(uidStage, pCmd);
  705. return true;
  706. }
  707.  
  708. bool MMatchServer::StagePlayerState(const MUID& uidPlayer, const MUID& uidStage, MMatchObjectStageState nStageState)
  709. {
  710. MMatchObject* pObj = GetObject(uidPlayer);
  711. if (!IsEnabledObject(pObj)) return false;
  712. // MMatchStage* pStage = FindStage(uidStage);
  713. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  714. if (pStage == NULL) return false;
  715.  
  716. pStage->PlayerState(uidPlayer, nStageState);
  717.  
  718. MCommand* pCmd = CreateCommand(MC_MATCH_STAGE_PLAYER_STATE, MUID(0,0));
  719. pCmd->AddParameter(new MCommandParameterUID(uidPlayer));
  720. pCmd->AddParameter(new MCommandParameterUID(uidStage));
  721. pCmd->AddParameter(new MCommandParameterInt(nStageState));
  722. RouteToStage(uidStage, pCmd);
  723. return true;
  724. }
  725.  
  726. bool MMatchServer::StageMaster(const MUID& uidStage)
  727. {
  728. MMatchStage* pStage = FindStage(uidStage);
  729. if (pStage == NULL) return false;
  730.  
  731. MUID uidMaster = pStage->GetMasterUID();
  732.  
  733. MCommand* pCmd = CreateCommand(MC_MATCH_STAGE_MASTER, MUID(0,0));
  734. pCmd->AddParameter(new MCommandParameterUID(uidStage));
  735. pCmd->AddParameter(new MCommandParameterUID(uidMaster));
  736. RouteToStage(uidStage, pCmd);
  737.  
  738. return true;
  739. }
  740.  
  741. void MMatchServer::StageLaunch(const MUID& uidStage)
  742. {
  743. MMatchStage* pStage = FindStage(uidStage);
  744. if (pStage == NULL) return;
  745.  
  746. ReserveAgent(pStage);
  747. if (MGetGameTypeMgr()->IsQuestDerived(pStage->GetStageSetting()->GetGameType()))
  748. {
  749. if (pStage->m_pRule)
  750. {
  751. pStage->m_pRule->OnQuestStageLaunch();
  752. }
  753. }
  754.  
  755. MCommand* pCmd = CreateCommand(MC_MATCH_STAGE_LAUNCH, MUID(0,0));
  756. pCmd->AddParameter(new MCmdParamUID(uidStage));
  757. pCmd->AddParameter(new MCmdParamStr( const_cast<char*>(pStage->GetMapName()) ));
  758. RouteToStage(uidStage, pCmd);
  759. }
  760.  
  761. void MMatchServer::StageRelayLaunch(const MUID& uidStage)
  762. {
  763. MMatchStage* pStage = FindStage(uidStage);
  764. if (pStage == NULL) return;
  765.  
  766. ReserveAgent(pStage);
  767.  
  768. for (MUIDRefCache::iterator i=pStage->GetObjBegin(); i!=pStage->GetObjEnd(); i++) {
  769. MUID uidObj = (MUID)(*i).first;
  770. MMatchObject* pObj = (MMatchObject*)GetObject(uidObj);
  771. if (pObj) {
  772. if( pObj->GetStageState() == MOSS_READY) {
  773. MCommand* pCmd = CreateCommand(MC_MATCH_STAGE_RELAY_LAUNCH, MUID(0,0));
  774. pCmd->AddParameter(new MCmdParamUID(uidStage));
  775. pCmd->AddParameter(new MCmdParamStr(const_cast<char*>(pStage->GetMapName())));
  776. pCmd->AddParameter(new MCmdParamBool(false));
  777. RouteToListener(pObj, pCmd);
  778. } else {
  779. MCommand* pCmd = CreateCommand(MC_MATCH_STAGE_RELAY_LAUNCH, MUID(0,0));
  780. pCmd->AddParameter(new MCmdParamUID(uidStage));
  781. pCmd->AddParameter(new MCmdParamStr(const_cast<char*>(pStage->GetMapName())));
  782. pCmd->AddParameter(new MCmdParamBool(true));
  783. RouteToListener(pObj, pCmd);
  784. }
  785. } else {
  786. LOG(LOG_PROG, "WARNING(StageRelayLaunch) : Not Existing Obj(%u:%u)\n", uidObj.High, uidObj.Low);
  787. i=pStage->RemoveObject(uidObj);
  788. LogObjectCommandHistory(uidObj);
  789. }
  790. }
  791. }
  792.  
  793. void MMatchServer::StageFinishGame(const MUID& uidStage)
  794. {
  795. MMatchStage* pStage = FindStage(uidStage);
  796. if (pStage == NULL) return;
  797.  
  798. bool bIsRelayMapUnFinish = true;
  799.  
  800. if(pStage->IsRelayMap())
  801. { // ¸±·¹ÀÌ ¸ÊÀ϶§¿¡´Â ¹èƲÀ» ´Ù½Ã ½ÃÀÛÇØÁØ´Ù.
  802. if((int)pStage->m_vecRelayMapsRemained.size() <= 0)
  803. { // ³²Àº ¸ÊÀÌ ¾øÀ»¶§
  804. int nRepeatCount = (int)pStage->m_RelayMapRepeatCountRemained - 1;
  805. if(nRepeatCount < 0)
  806. {
  807. bIsRelayMapUnFinish = false;
  808.  
  809. pStage->m_bIsLastRelayMap = true;//¸±·¹À̸ÊÀ» ³¡³½´Ù
  810. nRepeatCount = 0;
  811. pStage->GetStageSetting()->SetMapName(MMATCH_MAPNAME_RELAYMAP); //"RelayMap" ¼¼ÆÃ
  812. }
  813. pStage->m_RelayMapRepeatCountRemained = (RELAY_MAP_REPEAT_COUNT)nRepeatCount;
  814. pStage->SetRelayMapCurrList(pStage->GetRelayMapList());
  815. }
  816.  
  817. if(!pStage->m_bIsLastRelayMap) {
  818. // óÀ½ ½ÃÀÛ½Ã, Flag¸¦ On½ÃÄÑÁØ´Ù.
  819. if( pStage->IsStartRelayMap() == false ) {
  820. pStage->SetIsStartRelayMap(true);
  821. }
  822.  
  823. if((int)pStage->m_vecRelayMapsRemained.size() > 0) { // ´ÙÀ½¸ÊÀÌ ÀÖ´Ù¸é
  824. int nRelayMapIndex = 0;
  825.  
  826. if(pStage->GetRelayMapType() == RELAY_MAP_TURN) { //< ³²Àº °ÍÁß¿¡¼­ ù ¹ø°ºÎÅÍ ½ÃÀÛ(°¡µ¶¼º)
  827. nRelayMapIndex = 0;
  828. } else if(pStage->GetRelayMapType() == RELAY_MAP_RANDOM) {
  829. nRelayMapIndex = rand() % (int)pStage->m_vecRelayMapsRemained.size();
  830. }
  831.  
  832. if(nRelayMapIndex >= MAX_RELAYMAP_LIST_COUNT) { //< ¸Ê ±¸¼ºÀÌ 20°³
  833. mlog("StageFinishGame RelayMap Fail RelayMapList MIsCorrect MaxCount[%d] \n", (int)nRelayMapIndex);
  834. return;
  835. }
  836.  
  837. char* szMapName = (char*)MGetMapDescMgr()->GetMapName(pStage->m_vecRelayMapsRemained[nRelayMapIndex].nMapID);
  838. if (!szMapName)
  839. {
  840. mlog("RelayMapBattleStart Fail MapID[%d] \n", (int)pStage->m_vecRelayMapsRemained[nRelayMapIndex].nMapID);
  841. return;
  842. }
  843.  
  844. pStage->GetStageSetting()->SetMapName(szMapName);
  845.  
  846. // ½ÇÇàÇÑ ¸±·¹À̸ÊÀº »èÁ¦ÇØÁØ´Ù.
  847. vector<RelayMap>::iterator itor = pStage->m_vecRelayMapsRemained.begin();
  848. for(int i=0 ; nRelayMapIndex > i ; ++itor, ++i);// ÇØ´ç À妽º±îÁö À̵¿
  849. pStage->m_vecRelayMapsRemained.erase(itor);
  850. }
  851. else {
  852. mlog("MMatchServer::StageFinishGame::IsRelayMap() - m_vecRelayMapsRemained.size() == 0\n");
  853. }
  854. } else {
  855. pStage->SetIsStartRelayMap(false);
  856. bIsRelayMapUnFinish = false; // ¸±·¹ÀÌ¸Ê ÁøÇàÀÌ ³¡³µÀ½
  857. }
  858. }
  859.  
  860. MCommand* pCmd = CreateCommand(MC_MATCH_STAGE_FINISH_GAME, MUID(0,0));
  861. pCmd->AddParameter(new MCommandParameterUID(uidStage));
  862. pCmd->AddParameter(new MCommandParameterBool(bIsRelayMapUnFinish));
  863. RouteToStage(uidStage, pCmd);
  864.  
  865. return;
  866. }
  867.  
  868. MCommand* MMatchServer::CreateCmdResponseStageSetting(const MUID& uidStage)
  869. {
  870. MMatchStage* pStage = FindStage(uidStage);
  871. if (pStage == NULL) return NULL;
  872.  
  873. MCommand* pCmd = CreateCommand(MC_MATCH_RESPONSE_STAGESETTING, MUID(0,0));
  874. pCmd->AddParameter(new MCommandParameterUID(pStage->GetUID()));
  875.  
  876. MMatchStageSetting* pSetting = pStage->GetStageSetting();
  877.  
  878. // Param 1 : Stage Settings
  879. void* pStageSettingArray = MMakeBlobArray(sizeof(MSTAGE_SETTING_NODE), 1);
  880. MSTAGE_SETTING_NODE* pNode = (MSTAGE_SETTING_NODE*)MGetBlobArrayElement(pStageSettingArray, 0);
  881. CopyMemory(pNode, pSetting->GetStageSetting(), sizeof(MSTAGE_SETTING_NODE));
  882. pCmd->AddParameter(new MCommandParameterBlob(pStageSettingArray, MGetBlobArraySize(pStageSettingArray)));
  883. MEraseBlobArray(pStageSettingArray);
  884.  
  885. // Param 2 : Char Settings
  886. int nCharCount = (int)pStage->GetObjCount();
  887. void* pCharArray = MMakeBlobArray(sizeof(MSTAGE_CHAR_SETTING_NODE), nCharCount);
  888. int nIndex=0;
  889. for (MUIDRefCache::iterator itor=pStage->GetObjBegin(); itor!=pStage->GetObjEnd(); itor++) {
  890. MSTAGE_CHAR_SETTING_NODE* pCharNode = (MSTAGE_CHAR_SETTING_NODE*)MGetBlobArrayElement(pCharArray, nIndex++);
  891. MMatchObject* pObj = (MMatchObject*)(*itor).second;
  892. pCharNode->uidChar = pObj->GetUID();
  893. pCharNode->nTeam = pObj->GetTeam();
  894. pCharNode->nState = pObj->GetStageState();
  895. }
  896. pCmd->AddParameter(new MCommandParameterBlob(pCharArray, MGetBlobArraySize(pCharArray)));
  897. MEraseBlobArray(pCharArray);
  898.  
  899. // Param 3 : Stage State
  900. pCmd->AddParameter(new MCommandParameterInt((int)pStage->GetState()));
  901.  
  902. // Param 4 : Stage Master
  903. pCmd->AddParameter(new MCommandParameterUID(pStage->GetMasterUID()));
  904.  
  905. return pCmd;
  906. }
  907.  
  908. void MMatchServer::OnStageCreate(const MUID& uidChar, char* pszStageName, bool bPrivate, char* pszStagePassword)
  909. {
  910. MMatchObject* pObj = GetObject(uidChar);
  911. if (pObj == NULL) return;
  912.  
  913. MMatchChannel* pChannel = FindChannel(pObj->GetChannelUID());
  914. if (pChannel == NULL) return;
  915. if (strstr(pChannel->GetName(), "Event") && !IsAdminGrade(pObj))
  916. {
  917. RouteResponseToListener(pObj, MC_MATCH_RESPONSE_STAGE_CREATE, MERR_CANNOT_STAFF_ONLY);
  918. return;
  919. }
  920.  
  921. if ((MGetServerConfig()->GetServerMode() == MSM_CLAN) && (pChannel->GetChannelType() == MCHANNEL_TYPE_CLAN)
  922. && (pChannel->GetChannelType() == MCHANNEL_TYPE_DUELTOURNAMENT)) {
  923. return;
  924. }
  925.  
  926. MUID uidStage;
  927.  
  928. if (!StageAdd(pChannel, pszStageName, bPrivate, pszStagePassword, &uidStage))
  929. {
  930. RouteResponseToListener(pObj, MC_MATCH_RESPONSE_STAGE_CREATE, MERR_CANNOT_CREATE_STAGE);
  931. return;
  932. }
  933. StageJoin(uidChar, uidStage);
  934.  
  935. MMatchStage* pStage = FindStage(uidStage);
  936. if (pStage)
  937. pStage->SetFirstMasterName(pObj->GetCharInfo()->m_szName);
  938. }
  939.  
  940.  
  941. //void MMatchServer::OnStageJoin(const MUID& uidChar, const MUID& uidStage)
  942. //{
  943. // MMatchObject* pObj = GetObject(uidChar);
  944. // if (pObj == NULL) return;
  945. //
  946. // MMatchStage* pStage = NULL;
  947. //
  948. // if (uidStage == MUID(0,0)) {
  949. // return;
  950. // } else {
  951. // pStage = FindStage(uidStage);
  952. // }
  953. //
  954. // if (pStage == NULL) {
  955. // RouteResponseToListener(pObj, MC_MATCH_RESPONSE_STAGE_JOIN, MERR_STAGE_NOT_EXIST);
  956. // return;
  957. // }
  958. //
  959. // if ((IsAdminGrade(pObj) == false) && pStage->IsPrivate())
  960. // {
  961. // RouteResponseToListener(pObj, MC_MATCH_RESPONSE_STAGE_JOIN, MERR_CANNOT_JOIN_STAGE_BY_PASSWORD);
  962. // return;
  963. // }
  964. //
  965. // StageJoin(uidChar, pStage->GetUID());
  966. //}
  967.  
  968. void MMatchServer::OnPrivateStageJoin(const MUID& uidPlayer, const MUID& uidStage, char* pszPassword)
  969. {
  970. if (strlen(pszPassword) > STAGEPASSWD_LENGTH) return;
  971.  
  972. MMatchStage* pStage = NULL;
  973.  
  974. if (uidStage == MUID(0,0))
  975. {
  976. return;
  977. }
  978. else
  979. {
  980. pStage = FindStage(uidStage);
  981. }
  982.  
  983. if (pStage == NULL)
  984. {
  985. MMatchObject* pObj = GetObject(uidPlayer);
  986. if (pObj != NULL)
  987. {
  988. RouteResponseToListener(pObj, MC_MATCH_RESPONSE_STAGE_JOIN, MERR_STAGE_NOT_EXIST);
  989. }
  990.  
  991. return;
  992. }
  993.  
  994. // ¿µÀÚ³ª °³¹ßÀÚ¸é ¹«½Ã..
  995.  
  996. bool bSkipPassword = false;
  997.  
  998. MMatchObject* pObj = GetObject(uidPlayer);
  999.  
  1000. if ((pObj == NULL) || (pObj->GetCharInfo() == NULL))
  1001. return;
  1002.  
  1003. MMatchUserGradeID ugid = pObj->GetAccountInfo()->m_nUGrade;
  1004.  
  1005. if (ugid == MMUG_DEVELOPER || ugid == MMUG_ADMIN || ugid == MMUG_GM || ugid == MMUG_HEADGM || ugid == MMUG_EVENTMASTER)
  1006. bSkipPassword = true;
  1007.  
  1008. // ºñ¹Ð¹æÀÌ ¾Æ´Ï°Å³ª Æнº¿öµå°¡ Ʋ¸®¸é Æнº¿öµå°¡ Ʋ·È´Ù°í ÀÀ´äÇÑ´Ù.
  1009. if(bSkipPassword==false) {
  1010. if ((!pStage->IsPrivate()) || (strcmp(pStage->GetPassword(), pszPassword)))
  1011. {
  1012. MMatchObject* pObj = GetObject(uidPlayer);
  1013. if (pObj != NULL)
  1014. {
  1015. RouteResponseToListener(pObj, MC_MATCH_RESPONSE_STAGE_JOIN, MERR_CANNOT_JOIN_STAGE_BY_PASSWORD);
  1016. }
  1017.  
  1018. return;
  1019. }
  1020. }
  1021.  
  1022. StageJoin(uidPlayer, pStage->GetUID());
  1023. }
  1024.  
  1025. void MMatchServer::OnStageFollow(const MUID& uidPlayer, const char* pszTargetName, bool bSpectate)
  1026. {
  1027. MMatchObject* pPlayerObj = GetObject(uidPlayer);
  1028. if (pPlayerObj == NULL) return;
  1029.  
  1030. MMatchObject* pTargetObj = GetPlayerByName(pszTargetName);
  1031. if (pTargetObj == NULL) return;
  1032.  
  1033. // ÀÚ±â ÀÚ½ÅÀ» µû¶ó °¡·Á°í ÇßÀ»°æ¿ì °Ë»ç.
  1034. if (pPlayerObj->GetUID() == pTargetObj->GetUID()) return;
  1035.  
  1036. // ½ºÅ×ÀÌÆ®°¡ À߸øµÇ¾î ÀÖ´ÂÁö °Ë»ç.
  1037. if (!pPlayerObj->CheckEnableAction(MMatchObject::MMOA_STAGE_FOLLOW)) return;
  1038.  
  1039.  
  1040. // ¼­·Î ´Ù¸¥ ä³ÎÀÎÁö °Ë»ç.
  1041. if (pPlayerObj->GetChannelUID() != pTargetObj->GetChannelUID()) {
  1042.  
  1043. #ifdef _VOTESETTING
  1044. RouteResponseToListener( pPlayerObj, MC_MATCH_RESPONSE_STAGE_FOLLOW, MERR_CANNOT_FOLLOW );
  1045. #endif
  1046. return;
  1047. }
  1048.  
  1049. if ((IsAdminGrade(pTargetObj) == true)) {
  1050. NotifyMessage(pPlayerObj->GetUID(), MATCHNOTIFY_GENERAL_USER_NOTFOUND);
  1051. return;
  1052. }
  1053.  
  1054. MMatchStage* pStage = FindStage(pTargetObj->GetStageUID());
  1055. if (pStage == NULL) return;
  1056.  
  1057. // Ŭ·£Àü°ÔÀÓÀº µû¶ó°¥ ¼ö ¾øÀ½
  1058. if (pStage->GetStageType() != MST_NORMAL) return;
  1059.  
  1060. if (pStage->IsPrivate()==false) {
  1061. if ((pStage->GetStageSetting()->GetForcedEntry()==false) && pStage->GetState() != STAGE_STATE_STANDBY) {
  1062. // Deny Join
  1063.  
  1064. #ifdef _VOTESETTING
  1065. RouteResponseToListener( pPlayerObj, MC_MATCH_RESPONSE_STAGE_FOLLOW, MERR_CANNOT_FOLLOW );
  1066. #endif
  1067. } else { //spectate mode
  1068. StageJoin(uidPlayer, pTargetObj->GetStageUID());
  1069. if (bSpectate)
  1070. StageTeam(uidPlayer, pTargetObj->GetStageUID(), MMT_SPECTATOR);
  1071. }
  1072. }
  1073. else {
  1074. // µû¶ó°¡·Á´Â ¹æÀÌ ºñ¹Ð¹øÈ£¸¦ ÇÊ¿ä·Î ÇÒ°æ¿ì´Â µû¶ó°¥¼ö ¾øÀ½.
  1075. //RouteResponseToListener( pPlayerObj, MC_MATCH_RESPONSE_STAGE_FOLLOW, MERR_CANNOT_FOLLOW_BY_PASSWORD );
  1076.  
  1077. // ÇØ´ç¹æÀÌ ºñ¹Ð¹æÀÌ¸é ºñ¹Ð¹øÈ£¸¦ ¿ä±¸ÇÑ´Ù.
  1078. MCommand* pNew = new MCommand(m_CommandManager.GetCommandDescByID(MC_MATCH_STAGE_REQUIRE_PASSWORD), MUID(0,0), m_This);
  1079. pNew->AddParameter(new MCommandParameterUID(pStage->GetUID()));
  1080. pNew->AddParameter(new MCommandParameterString((char*)pStage->GetName()));
  1081. RouteToListener(pPlayerObj, pNew);
  1082. }
  1083. }
  1084.  
  1085. void MMatchServer::OnStageLeave(const MUID& uidPlayer)//, const MUID& uidStage)
  1086. {
  1087. MMatchObject* pObj = GetObject( uidPlayer );
  1088. if( !IsEnabledObject(pObj) ) return;
  1089. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  1090. if (pStage == NULL) return;
  1091.  
  1092. if( !IsEnabledObject(GetObject(uidPlayer)) )
  1093. {
  1094. return;
  1095. }
  1096.  
  1097. StageLeave(uidPlayer);// , uidStage);
  1098. }
  1099.  
  1100. void MMatchServer::OnStageRequestPlayerList(const MUID& uidPlayer, const MUID& uidStage)
  1101. {
  1102. MMatchObject* pObj = GetObject(uidPlayer);
  1103. if (pObj == NULL) return;
  1104.  
  1105. // MMatchStage* pStage = FindStage(uidStage);
  1106. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  1107. if (pStage == NULL) return;
  1108.  
  1109. // ¹æÀοø ¸ñ·Ï
  1110. MMatchObjectCacheBuilder CacheBuilder;
  1111. CacheBuilder.Reset();
  1112. for (MUIDRefCache::iterator i=pStage->GetObjBegin(); i!=pStage->GetObjEnd(); i++) {
  1113. MMatchObject* pScanObj = (MMatchObject*)(*i).second;
  1114. CacheBuilder.AddObject(pScanObj);
  1115. }
  1116. MCommand* pCmdCacheUpdate = CacheBuilder.GetResultCmd(MATCHCACHEMODE_UPDATE, this);
  1117. RouteToListener(pObj, pCmdCacheUpdate);
  1118.  
  1119. // Cast Master(¹æÀå)
  1120. MUID uidMaster = pStage->GetMasterUID();
  1121. MCommand* pMasterCmd = CreateCommand(MC_MATCH_STAGE_MASTER, MUID(0,0));
  1122. pMasterCmd->AddParameter(new MCommandParameterUID(uidStage));
  1123. pMasterCmd->AddParameter(new MCommandParameterUID(uidMaster));
  1124. RouteToListener(pObj, pMasterCmd);
  1125.  
  1126. // Cast Character Setting
  1127. StageTeam(uidPlayer, uidStage, pObj->GetTeam());
  1128. StagePlayerState(uidPlayer, uidStage, pObj->GetStageState());
  1129. }
  1130.  
  1131. void MMatchServer::OnStageEnterBattle(const MUID& uidPlayer, const MUID& uidStage)
  1132. {
  1133. MMatchStage* pStage = FindStage(uidStage);
  1134. if (pStage == NULL) return;
  1135.  
  1136. StageEnterBattle(uidPlayer, uidStage);
  1137. }
  1138.  
  1139. void MMatchServer::OnStageLeaveBattle(const MUID& uidPlayer, bool bGameFinishLeaveBattle)//, const MUID& uidStage)
  1140. {
  1141. if( !IsEnabledObject(GetObject(uidPlayer)) )
  1142. {
  1143. return;
  1144. }
  1145.  
  1146. StageLeaveBattle(uidPlayer, bGameFinishLeaveBattle, false);//, uidStage);
  1147. }
  1148.  
  1149.  
  1150. #include "CMLexicalAnalyzer.h"
  1151. // °­Åð ÀÓ½ÃÄÚµå
  1152. bool StageKick(MMatchServer* pServer, const MUID& uidPlayer, const MUID& uidStage, char* pszChat)
  1153. {
  1154. MMatchObject* pChar = pServer->GetObject(uidPlayer);
  1155. if (pChar == NULL) return false;
  1156. MMatchStage* pStage = pServer->FindStage(uidStage);
  1157. if (pStage == NULL) return false;
  1158. if (uidPlayer != pStage->GetMasterUID()) return false;
  1159.  
  1160. bool bResult = false;
  1161. CMLexicalAnalyzer lex;
  1162. lex.Create(pszChat);
  1163.  
  1164. if (lex.GetCount() >= 1) {
  1165. char* pszCmd = lex.GetByStr(0);
  1166. if (pszCmd) {
  1167. if (stricmp(pszCmd, "/kick") == 0) {
  1168. if (lex.GetCount() >= 2) {
  1169. char* pszTarget = lex.GetByStr(1);
  1170. if (pszTarget) {
  1171. for (MUIDRefCache::iterator itor = pStage->GetObjBegin();
  1172. itor != pStage->GetObjEnd(); ++itor)
  1173. {
  1174. MMatchObject* pTarget = (MMatchObject*)((*itor).second);
  1175. if (stricmp(pszTarget, pTarget->GetName()) == 0) {
  1176. if (pTarget->GetPlace() != MMP_BATTLE) {
  1177. pServer->StageLeave(pTarget->GetUID());//, uidStage);
  1178. bResult = true;
  1179. }
  1180. break;
  1181. }
  1182. }
  1183. }
  1184. }
  1185. } // Kick
  1186. }
  1187. }
  1188.  
  1189. lex.Destroy();
  1190. return bResult;
  1191. }
  1192.  
  1193. // ¹æÀåÈ®ÀÎ ÀÓ½ÃÄÚµå
  1194. bool StageShowInfo(MMatchServer* pServer, const MUID& uidPlayer, const MUID& uidStage, char* pszChat)
  1195. {
  1196. MMatchObject* pChar = pServer->GetObject(uidPlayer);
  1197. if (pChar == NULL) return false;
  1198. MMatchStage* pStage = pServer->FindStage(uidStage);
  1199. if (pStage == NULL) return false;
  1200. if (uidPlayer != pStage->GetMasterUID()) return false;
  1201.  
  1202. bool bResult = false;
  1203. CMLexicalAnalyzer lex;
  1204. lex.Create(pszChat);
  1205.  
  1206. if (lex.GetCount() >= 1) {
  1207. char* pszCmd = lex.GetByStr(0);
  1208. if (pszCmd) {
  1209. if (stricmp(pszCmd, "/showinfo") == 0) {
  1210. char szMsg[256]="";
  1211. sprintf(szMsg, "FirstMaster : (%s)", pStage->GetFirstMasterName());
  1212. pServer->Announce(pChar, szMsg);
  1213. bResult = true;
  1214. } // ShowInfo
  1215. }
  1216. }
  1217.  
  1218. lex.Destroy();
  1219. return bResult;
  1220. }
  1221. void MMatchServer::OnStageChat(const MUID& uidPlayer, const MUID& uidStage, char* pszChat)
  1222. {
  1223. // RAONHAJE : °­Åð ÀÓ½ÃÄÚµå
  1224. if (pszChat[0] == '/') {
  1225. if (StageKick(this, uidPlayer, uidStage, pszChat))
  1226. return;
  1227. if (StageShowInfo(this, uidPlayer, uidStage, pszChat))
  1228. return;
  1229. }
  1230.  
  1231. StageChat(uidPlayer, uidStage, pszChat);
  1232. }
  1233.  
  1234. void MMatchServer::OnStageStart(const MUID& uidPlayer, const MUID& uidStage, int nCountdown)
  1235. {
  1236. MMatchStage* pStage = FindStage(uidStage);
  1237. if (pStage == NULL) return;
  1238. if (pStage->GetMasterUID() != uidPlayer) return;
  1239.  
  1240.  
  1241. if (pStage->StartGame(MGetServerConfig()->IsUseResourceCRC32CacheCheck()) == true) {
  1242. StageRelayMapBattleStart(uidPlayer, uidStage);
  1243.  
  1244. MCommand* pNew = new MCommand(m_CommandManager.GetCommandDescByID(MC_MATCH_STAGE_START), MUID(0,0), m_This);
  1245. pNew->AddParameter(new MCommandParameterUID(uidPlayer));
  1246. pNew->AddParameter(new MCommandParameterUID(uidStage));
  1247. pNew->AddParameter(new MCommandParameterInt(min(nCountdown,3)));
  1248. RouteToStage(uidStage, pNew);
  1249.  
  1250. // µðºñ¿¡ ·Î±×¸¦ ³²±ä´Ù.
  1251. SaveGameLog(uidStage);
  1252. }
  1253. }
  1254.  
  1255. void MMatchServer::OnStageRelayStart(const MUID& uidStage)
  1256. {
  1257. MMatchStage* pStage = FindStage(uidStage);
  1258. if (pStage == NULL) return;
  1259.  
  1260. if (pStage->StartRelayGame(MGetServerConfig()->IsUseResourceCRC32CacheCheck()) == true) {
  1261. // µðºñ¿¡ ·Î±×¸¦ ³²±ä´Ù.
  1262. SaveGameLog(uidStage);
  1263. }
  1264. }
  1265.  
  1266. void MMatchServer::OnStartStageList(const MUID& uidComm)
  1267. {
  1268. MMatchObject* pObj = GetPlayerByCommUID(uidComm);
  1269. if (pObj == NULL) return;
  1270.  
  1271. pObj->SetStageListTransfer(true);
  1272. }
  1273.  
  1274. void MMatchServer::OnStopStageList(const MUID& uidComm)
  1275. {
  1276. MMatchObject* pObj = GetPlayerByCommUID(uidComm);
  1277. if (pObj == NULL) return;
  1278.  
  1279. pObj->SetStageListTransfer(false);
  1280. }
  1281.  
  1282. void MMatchServer::OnStagePlayerState(const MUID& uidPlayer, const MUID& uidStage, MMatchObjectStageState nStageState)
  1283. {
  1284. StagePlayerState(uidPlayer, uidStage, nStageState);
  1285. }
  1286.  
  1287.  
  1288. void MMatchServer::OnStageTeam(const MUID& uidPlayer, const MUID& uidStage, MMatchTeam nTeam)
  1289. {
  1290. MMatchStage* pStage = FindStage(uidStage);
  1291. if (pStage == NULL) return;
  1292.  
  1293. MMatchObject* pChar = GetObject(uidPlayer);
  1294. if (pChar == NULL) return;
  1295.  
  1296. StageTeam(uidPlayer, uidStage, nTeam);
  1297. }
  1298.  
  1299. void MMatchServer::OnStageMap(const MUID& uidStage, char* pszMapName)
  1300. {
  1301. MMatchStage* pStage = FindStage(uidStage);
  1302. if (pStage == NULL) return;
  1303. if (pStage->GetState() != STAGE_STATE_STANDBY) return; // ´ë±â»óÅ¿¡¼­¸¸ ¹Ù²Ü¼ö ÀÖ´Ù
  1304. if (strlen(pszMapName) < 2) return;
  1305.  
  1306. pStage->SetMapName( pszMapName );
  1307. pStage->SetIsRelayMap(strcmp(MMATCH_MAPNAME_RELAYMAP, pszMapName) == 0);
  1308.  
  1309. MCommand* pNew = new MCommand(m_CommandManager.GetCommandDescByID(MC_MATCH_STAGE_MAP), MUID(0,0), m_This);
  1310. pNew->AddParameter(new MCommandParameterUID(uidStage));
  1311. pNew->AddParameter(new MCommandParameterString(pStage->GetMapName()));
  1312.  
  1313. if ( MGetGameTypeMgr()->IsQuestDerived( pStage->GetStageSetting()->GetGameType()))
  1314. {
  1315. MMatchRuleBaseQuest* pQuest = reinterpret_cast< MMatchRuleBaseQuest* >( pStage->GetRule() );
  1316. pQuest->RefreshStageGameInfo();
  1317. }
  1318.  
  1319. RouteToStage(uidStage, pNew);
  1320. }
  1321.  
  1322. void MMatchServer::StageRelayMapBattleStart(const MUID& uidPlayer, const MUID& uidStage)
  1323. {// ¸±·¹ÀÌ¸Ê ¼±ÅÃÇÏ°í °ÔÀÓ ½ÃÀÛ ¹öÆ° ´©¸£¸é ´ÙÀ½À» ¼öÇàÇÑ´Ù
  1324. MMatchStage* pStage = FindStage(uidStage);
  1325. if (pStage == NULL) return;
  1326. if (pStage->GetMasterUID() != uidPlayer) return;
  1327. if(!pStage->IsRelayMap()) return;
  1328.  
  1329. // °ÔÀÓ Ã³À½½ÃÀ۽à ÃʱâÈ­ ÇØÁÖ±â
  1330. pStage->InitCurrRelayMap();
  1331.  
  1332. if (pStage->m_vecRelayMapsRemained.empty()) return;
  1333.  
  1334. if((int)pStage->m_vecRelayMapsRemained.size() > MAX_RELAYMAP_LIST_COUNT)
  1335. {// ¸Ê ±¸¼ºÀÌ 20°³ ÃÊ°úÇÏ¸é ¿¡·¯
  1336. mlog("RelayMapBattleStart Fail RelayMapList MIsCorrect OverCount[%d] \n", (int)pStage->m_vecRelayMapsRemained.size());
  1337. return;
  1338. }
  1339.  
  1340. if (pStage->m_vecRelayMapsRemained.size() != pStage->GetRelayMapListCount())
  1341. {
  1342. mlog("m_vecRelayMapsRemained[%d] != GetRelayMapListCount[%d]\n", (int)pStage->m_vecRelayMapsRemained.size(), pStage->GetRelayMapListCount());
  1343. return;
  1344. }
  1345.  
  1346. // óÀ½ ½ÇÇàÇÒ ¸ÊÀ» Á¤ÇÑ´Ù
  1347. int nRelayMapIndex = 0;
  1348. if(pStage->GetRelayMapType() == RELAY_MAP_TURN )
  1349. nRelayMapIndex = 0; // ³²Àº°ÍÁß¿¡¼­ óÀ½¹ø° ºÎÅÍ ½ÃÀÛ(°¡µ¶¼º)
  1350. else if(pStage->GetRelayMapType() == RELAY_MAP_RANDOM)
  1351. nRelayMapIndex = rand() % int(pStage->m_vecRelayMapsRemained.size());
  1352.  
  1353. if(MMATCH_MAP_RELAYMAP == pStage->m_vecRelayMapsRemained[nRelayMapIndex].nMapID)
  1354. {
  1355. mlog("RelayMapBattleStart Fail Type[%d], RoundCount[Curr:%d][%d], ListCount[Curr:%d][%d] \n",
  1356. pStage->GetRelayMapType(), pStage->m_RelayMapRepeatCountRemained, pStage->GetRelayMapRepeatCount(), (int)pStage->m_vecRelayMapsRemained.size(), pStage->GetRelayMapListCount());
  1357. return;
  1358. }
  1359.  
  1360. char* szMapName = (char*)MGetMapDescMgr()->GetMapName(pStage->m_vecRelayMapsRemained[nRelayMapIndex].nMapID);
  1361. if (!szMapName)
  1362. {
  1363. mlog("RelayMapBattleStart Fail MapID[%d] \n", (int)pStage->m_vecRelayMapsRemained[nRelayMapIndex].nMapID);
  1364. return;
  1365. }
  1366.  
  1367. pStage->GetStageSetting()->SetMapName(szMapName);
  1368.  
  1369. // ½ÇÇàÇÑ ¸±·¹À̸ÊÀº »èÁ¦ÇØÁØ´Ù.
  1370. vector<RelayMap>::iterator itor = pStage->m_vecRelayMapsRemained.begin();
  1371. for(int i=0 ; nRelayMapIndex > i ; ++itor, ++i);// ÇØ´ç À妽º±îÁö À̵¿
  1372. pStage->m_vecRelayMapsRemained.erase(itor);
  1373. }
  1374.  
  1375. void MMatchServer::OnStageRelayMapElementUpdate(const MUID& uidStage, int nType, int nRepeatCount)
  1376. {
  1377. MMatchStage* pStage = FindStage(uidStage);
  1378. pStage->SetRelayMapType((RELAY_MAP_TYPE)nType);
  1379. pStage->SetRelayMapRepeatCount((RELAY_MAP_REPEAT_COUNT)nRepeatCount);
  1380.  
  1381. MCommand* pNew = new MCommand(m_CommandManager.GetCommandDescByID(MC_MATCH_STAGE_RELAY_MAP_ELEMENT_UPDATE), MUID(0,0), m_This);
  1382. pNew->AddParameter(new MCommandParameterUID(uidStage));
  1383. pNew->AddParameter(new MCommandParameterInt((int)pStage->GetRelayMapType()));
  1384. pNew->AddParameter(new MCommandParameterInt((int)pStage->GetRelayMapRepeatCount()));
  1385. RouteToStage(uidStage, pNew);
  1386. }
  1387.  
  1388. void MMatchServer::OnStageRelayMapListUpdate(const MUID& uidStage, int nRelayMapType, int nRelayMapRepeatCount, void* pRelayMapListBlob)
  1389. {
  1390. MMatchStage* pStage = FindStage(uidStage);
  1391. if (pStage == NULL) return;
  1392. if(!pStage->IsRelayMap()) return;
  1393. if (pStage->GetState() != STAGE_STATE_STANDBY) return; // ´ë±â»óÅ¿¡¼­¸¸ ¹Ù²Ü¼ö ÀÖ´Ù
  1394.  
  1395. // ¸±·¹ÀÌ¸Ê Á¤º¸¸¦ ¼­¹öÂÊ ½ºÅ×ÀÌÁö¸¦ °»½Å
  1396. RelayMap relayMapList[MAX_RELAYMAP_LIST_COUNT];
  1397. for (int i = 0; i < MAX_RELAYMAP_LIST_COUNT; i++)
  1398. relayMapList[i].nMapID = -1;
  1399. int nRelayMapListCount = MGetBlobArrayCount(pRelayMapListBlob);
  1400. if(nRelayMapListCount > MAX_RELAYMAP_LIST_COUNT)
  1401. nRelayMapListCount = MAX_RELAYMAP_LIST_COUNT;
  1402. for (int i = 0; i < nRelayMapListCount; i++)
  1403. {
  1404. MTD_RelayMap* pRelayMap = (MTD_RelayMap*)MGetBlobArrayElement(pRelayMapListBlob, i);
  1405. if(!MGetMapDescMgr()->MIsCorrectMap(pRelayMap->nMapID))
  1406. {
  1407. mlog("OnStageRelayMapListUpdate Fail MIsCorrectMap ID[%d] \n", (int)pRelayMap->nMapID);
  1408. break;
  1409. }
  1410. relayMapList[i].nMapID = pRelayMap->nMapID;
  1411. }
  1412.  
  1413. pStage->SetRelayMapType((RELAY_MAP_TYPE)nRelayMapType);
  1414. pStage->SetRelayMapRepeatCount((RELAY_MAP_REPEAT_COUNT)nRelayMapRepeatCount);
  1415. pStage->SetRelayMapList(relayMapList);
  1416. pStage->InitCurrRelayMap();
  1417.  
  1418.  
  1419. // ºí·° ¸¸µé±â, ¸Ê¸®½ºÆ® ¼¼ÆÃ
  1420. void* pRelayMapListBlob = MMakeBlobArray(sizeof(MTD_RelayMap), pStage->GetRelayMapListCount());
  1421. RelayMap RelayMapList[MAX_RELAYMAP_LIST_COUNT];
  1422. memcpy(RelayMapList, pStage->GetRelayMapList(), sizeof(RelayMap)*MAX_RELAYMAP_LIST_COUNT);
  1423. for (int i = 0; i < pStage->GetRelayMapListCount(); i++)
  1424. {
  1425. MTD_RelayMap* pRelayMapList = (MTD_RelayMap*)MGetBlobArrayElement(pRelayMapListBlob, i);
  1426. pRelayMapList->nMapID = RelayMapList[i].nMapID;
  1427. }
  1428.  
  1429. // ¹æÀåÀÌ º¸³½ ¸±·¹ÀÌ¸Ê Á¤º¸¸¦ ¹æ¿øµé¿¡°Ô º¸³¿
  1430. MCommand* pNew = new MCommand(m_CommandManager.GetCommandDescByID(MC_MATCH_STAGE_RELAY_MAP_INFO_UPDATE), MUID(0,0), m_This);
  1431. pNew->AddParameter(new MCommandParameterUID(uidStage));
  1432. pNew->AddParameter(new MCommandParameterInt((int)pStage->GetRelayMapType()));
  1433. pNew->AddParameter(new MCommandParameterInt((int)pStage->GetRelayMapRepeatCount()));
  1434. pNew->AddParameter(new MCommandParameterBlob(pRelayMapListBlob, MGetBlobArraySize(pRelayMapListBlob)));
  1435. RouteToStage(uidStage, pNew);
  1436. }
  1437. void MMatchServer::OnStageRelayMapListInfo(const MUID& uidStage, const MUID& uidChar)
  1438. {
  1439. MMatchStage* pStage = FindStage(uidStage);
  1440. if(pStage == NULL) return;
  1441. if(!pStage->IsRelayMap()) return;
  1442. MMatchObject* pObj = GetObject(uidChar);
  1443. if (pObj == NULL) return;
  1444. // ´ë±â»óÅÂÀ϶§ ¹æÀåÀº ó¸® ¾ÈÇØÁÜ(¸±·¹ÀÌ¸Ê ÀÛ¼ºÁßÀϼöµµ ÀÖÀ½)
  1445. if(pStage->GetState() == STAGE_STATE_STANDBY && pStage->GetMasterUID() == uidChar) return;
  1446.  
  1447. // ºí·° ¸¸µé±â, ¸Ê¸®½ºÆ® ¼¼ÆÃ
  1448. void* pRelayMapListBlob = MMakeBlobArray(sizeof(MTD_RelayMap), pStage->GetRelayMapListCount());
  1449. RelayMap RelayMapList[MAX_RELAYMAP_LIST_COUNT];
  1450. memcpy(RelayMapList, pStage->GetRelayMapList(), sizeof(RelayMap)*MAX_RELAYMAP_LIST_COUNT);
  1451. for (int i = 0; i < pStage->GetRelayMapListCount(); i++)
  1452. {
  1453. MTD_RelayMap* pRelayMapList = (MTD_RelayMap*)MGetBlobArrayElement(pRelayMapListBlob, i);
  1454. pRelayMapList->nMapID = RelayMapList[i].nMapID;
  1455. }
  1456. MCommand* pNew = new MCommand(m_CommandManager.GetCommandDescByID(MC_MATCH_STAGE_RELAY_MAP_INFO_UPDATE), MUID(0,0), m_This);
  1457. pNew->AddParameter(new MCommandParameterUID(uidStage));
  1458. pNew->AddParameter(new MCommandParameterInt((int)pStage->GetRelayMapType()));
  1459. pNew->AddParameter(new MCommandParameterInt((int)pStage->GetRelayMapRepeatCount()));
  1460. pNew->AddParameter(new MCommandParameterBlob(pRelayMapListBlob, MGetBlobArraySize(pRelayMapListBlob)));
  1461. MEraseBlobArray(pRelayMapListBlob);
  1462.  
  1463. RouteToListener(pObj, pNew); // ¹æÀåÀÌ ¸±·¹ÀÌ¸Ê ¼³Á¤Áß¿¡ ¾÷µ¥ÀÌÆ®µÈ ¼³Á¤À¸·Î º¯°æ µÉ¼ö°¡ ÀÖÀ½
  1464. }
  1465.  
  1466. void MMatchServer::OnStageSetting(const MUID& uidPlayer, const MUID& uidStage, void* pStageBlob, int nStageCount)
  1467. {
  1468. MMatchStage* pStage = FindStage(uidStage);
  1469. if (pStage == NULL) return;
  1470. if (pStage->GetState() != STAGE_STATE_STANDBY) return; // ´ë±â»óÅ¿¡¼­¸¸ ¹Ù²Ü¼ö ÀÖ´Ù
  1471. if (nStageCount <= 0) return;
  1472.  
  1473. // validate
  1474. MMatchObject* pObj = GetObject(uidPlayer);
  1475. if (!IsEnabledObject(pObj)) {
  1476. mlog(" stage setting invalid object (%d, %d) ignore\n", uidPlayer.High, uidPlayer.Low);
  1477. return;
  1478. }
  1479.  
  1480. if( pObj->GetStageUID()!=uidStage || nStageCount!=1 ||
  1481. MGetBlobArraySize(pStageBlob) != (sizeof(MSTAGE_SETTING_NODE)+sizeof(int)*2) )
  1482. {
  1483. mlog(" stage setting hack %s (%d, %d) ignore\n", pObj->GetName(), uidPlayer.High, uidPlayer.Low);
  1484. LogObjectCommandHistory( uidPlayer );
  1485. return;
  1486. }
  1487.  
  1488. // ¹æÀåÀ̰ųª ¿î¿µÀÚ°¡ ¾Æ´Ñµ¥ ¼¼ÆÃÀ» ¹Ù²Ù¸é ±×³É ¸®ÅÏ
  1489. if (pStage->GetMasterUID() != uidPlayer)
  1490. {
  1491. MMatchObject* pObjMaster = GetObject(uidPlayer);
  1492. if (!IsAdminGrade(pObjMaster)) return;
  1493. }
  1494.  
  1495.  
  1496. MSTAGE_SETTING_NODE* pNode = (MSTAGE_SETTING_NODE*)MGetBlobArrayElement(pStageBlob, 0);
  1497.  
  1498. // let's refactor
  1499. if( (pNode->nGameType < MMATCH_GAMETYPE_DEATHMATCH_SOLO) || (pNode->nGameType >= MMATCH_GAMETYPE_MAX)) {
  1500. mlog(" stage setting game mode hack %s (%d, %d) ignore\n", pObj->GetName(), uidPlayer.High, uidPlayer.Low);
  1501. LogObjectCommandHistory( uidPlayer );
  1502.  
  1503. // µðºñ¿¡ ³²±âÀÚ.
  1504. // pObj->SetInvalidStageSettingDisconnectWaitInfo();
  1505. pObj->DisconnectHacker( MMHT_INVALIDSTAGESETTING );
  1506.  
  1507. return;
  1508. }
  1509.  
  1510. // ¼­¹ÙÀ̹úÀÌ ºñÈ°¼º ¼¼ÆÃÀε¥ ¼­¹ÙÀ̹ú ¿äû½Ã
  1511. if( MGetServerConfig()->IsEnabledSurvivalMode()==false && pNode->nGameType==MMATCH_GAMETYPE_SURVIVAL) {
  1512. mlog(" stage setting game mode hack %s (%d, %d) ignore\n", pObj->GetName(), uidPlayer.High, uidPlayer.Low);
  1513. LogObjectCommandHistory( uidPlayer );
  1514. pObj->DisconnectHacker( MMHT_INVALIDSTAGESETTING );
  1515. return;
  1516. }
  1517.  
  1518. // ±âº»ÀûÀ¸·Î ÃÖ´ë ÀοøÀÌ STAGE_BASIC_MAX_PLAYERCOUNTÀÌ ³ÑÀ¸¸é STAGE_BASIC_MAX_PLAYERCOUNT·Î ¸ÂÃçÁÜ.
  1519. // ³²Àº ÀÛ¾÷À» ÁøÇàÇϸéÀº °¢ °ÔÀÓ¿¡ ¸Â´Â ÀοøÀ¸·Î ¼ÂÆÃÀ» ÇÔ. - by SungE 2007-05-14
  1520. if( STAGE_MAX_PLAYERCOUNT < pNode->nMaxPlayers )
  1521. pNode->nMaxPlayers = STAGE_MAX_PLAYERCOUNT;
  1522.  
  1523. // ÀÌ ÀÌ»óÀÇ ¶ó¿îµå ¼ÂÆÃÀº ºÒ°¡´É ÇÏ´Ù. ¹«Á¶°Ç º¸Á¤ÇÑ´Ù. - By SungE 2007-11-07
  1524. if( STAGE__MAX_ROUND < pNode->nRoundMax )
  1525. pNode->nRoundMax = STAGE__MAX_ROUND;
  1526.  
  1527. MMatchStageSetting* pSetting = pStage->GetStageSetting();
  1528. MMatchChannel* pChannel = FindChannel(pStage->GetOwnerChannel());
  1529.  
  1530. bool bCheckChannelRule = true;
  1531.  
  1532. if (QuestTestServer())
  1533. {
  1534. if (MGetGameTypeMgr()->IsQuestDerived(pNode->nGameType))
  1535. {
  1536. bCheckChannelRule = false;
  1537. }
  1538. }
  1539.  
  1540. if ((pChannel) && (bCheckChannelRule))
  1541. {
  1542. // ¼¼ÆÃÇÒ ¼ö ÀÖ´Â ¸Ê, °ÔÀÓŸÀÔÀÎÁö üũ
  1543. MChannelRule* pRule = MGetChannelRuleMgr()->GetRule(pChannel->GetRuleType());
  1544. if (pRule)
  1545. {
  1546. if (!pRule->CheckGameType(pNode->nGameType))
  1547. {
  1548. pNode->nGameType = MMATCH_GAMETYPE_DEATHMATCH_SOLO;
  1549. }
  1550.  
  1551. bool bDuelMode = false;
  1552. bool bCTFMode = false;
  1553. if ( pNode->nGameType == MMATCH_GAMETYPE_DUEL)
  1554. bDuelMode = true;
  1555.  
  1556. if ( pNode->nGameType == MMATCH_GAMETYPE_CTF)
  1557. bCTFMode = true;
  1558.  
  1559.  
  1560. if (!pRule->CheckCTFMap(pNode->nMapIndex) && bCTFMode)
  1561. {
  1562. strcpy(pNode->szMapName, MGetMapDescMgr()->GetMapName(MMATCH_MAP_MANSION));
  1563. pNode->nMapIndex = 0;
  1564. }
  1565. if (!pRule->CheckMap(pNode->nMapIndex, bDuelMode) && !bCTFMode)
  1566. {
  1567. strcpy(pNode->szMapName, MGetMapDescMgr()->GetMapName(MMATCH_MAP_MANSION));
  1568. pNode->nMapIndex = 0;
  1569. }
  1570. else if(!bCTFMode)
  1571. {
  1572. strcpy(pNode->szMapName, pSetting->GetMapName());
  1573. pNode->nMapIndex = pSetting->GetMapIndex();
  1574. }
  1575. }
  1576. }
  1577.  
  1578. MMATCH_GAMETYPE nLastGameType = pSetting->GetGameType();
  1579.  
  1580. // Custom: removed late join setting on quest.
  1581. if (MGetGameTypeMgr()->IsQuestDerived(pNode->nGameType))
  1582. {
  1583. pNode->nMaxPlayers = STAGE_QUEST_MAX_PLAYER;
  1584. pNode->nLimitTime = STAGESETTING_LIMITTIME_UNLIMITED;
  1585.  
  1586. }
  1587.  
  1588. if (!MGetGameTypeMgr()->IsTeamGame(pNode->nGameType))
  1589. {
  1590. pNode->bAutoTeamBalancing = true;
  1591. }
  1592.  
  1593. // ¸±·¹ÀÌ¸Ê ¼¼ÆÃ
  1594. pStage->SetIsRelayMap(strcmp(MMATCH_MAPNAME_RELAYMAP, pNode->szMapName) == 0);
  1595. pStage->SetIsStartRelayMap(false);
  1596.  
  1597. if(!pStage->IsRelayMap())
  1598. { // ¸±·¹À̸ÊÀÌ ¾Æ´Ï¸é ±âº»À¸·Î ÃʱâÈ­ ÇØÁØ´Ù.
  1599. pNode->bIsRelayMap = pStage->IsRelayMap();
  1600. pNode->bIsStartRelayMap = pStage->IsStartRelayMap();
  1601. for (int i=0; i<MAX_RELAYMAP_LIST_COUNT; ++i)
  1602. pNode->MapList[i].nMapID = -1;
  1603. pNode->nRelayMapListCount = 0;
  1604. pNode->nRelayMapType = RELAY_MAP_TURN;
  1605. pNode->nRelayMapRepeatCount = RELAY_MAP_3REPEAT;
  1606. }
  1607.  
  1608. if(pNode->bAntiLead) {
  1609. pSetting->SetAntiLead(true);
  1610. } else {
  1611. pSetting->SetAntiLead(true);
  1612. }
  1613.  
  1614.  
  1615. pSetting->UpdateStageSetting(pNode);
  1616. pStage->ChangeRule(pNode->nGameType);
  1617.  
  1618.  
  1619. MCommand* pCmd = CreateCmdResponseStageSetting(uidStage);
  1620. RouteToStage(uidStage, pCmd);
  1621.  
  1622.  
  1623. // °ÔÀÓ ¸ðµå°¡ º¯°æµÇ¾úÀ»°æ¿ì
  1624. if (nLastGameType != pSetting->GetGameType())
  1625. {
  1626. char szNewMap[ MAPNAME_LENGTH ] = {0};
  1627.  
  1628. if (MGetGameTypeMgr()->IsQuestDerived( nLastGameType ) == false &&
  1629. MGetGameTypeMgr()->IsQuestDerived( pSetting->GetGameType() ) == true)
  1630. {
  1631. // OnStageMap(uidStage, GetQuest()->GetSurvivalMapInfo(MSURVIVAL_MAP(0))->szName);
  1632. // OnStageMap(uidStage, pSetting->GetMapName());
  1633. OnStageMap(uidStage, MMATCH_DEFAULT_STAGESETTING_MAPNAME);
  1634.  
  1635. MMatchRuleBaseQuest* pQuest = reinterpret_cast< MMatchRuleBaseQuest* >( pStage->GetRule());
  1636. pQuest->RefreshStageGameInfo();
  1637. }
  1638. else if ( (nLastGameType != MMATCH_GAMETYPE_DUEL) && ( pSetting->GetGameType() == MMATCH_GAMETYPE_DUEL))
  1639. {
  1640. strcpy( szNewMap, MGetMapDescMgr()->GetMapName( MMATCH_MAP_HALL));
  1641. OnStageMap(uidStage, szNewMap);
  1642. }
  1643. else if ( ((nLastGameType == MMATCH_GAMETYPE_QUEST) || (nLastGameType == MMATCH_GAMETYPE_SURVIVAL) || (nLastGameType == MMATCH_GAMETYPE_DUEL)) &&
  1644. ((pSetting->GetGameType() != MMATCH_GAMETYPE_QUEST) && (pSetting->GetGameType() != MMATCH_GAMETYPE_SURVIVAL) && ( pSetting->GetGameType() != MMATCH_GAMETYPE_DUEL)))
  1645. {
  1646. strcpy( szNewMap, MGetMapDescMgr()->GetMapName( MMATCH_MAP_MANSION));
  1647. OnStageMap(uidStage, szNewMap);
  1648. }
  1649. }
  1650. }
  1651.  
  1652. void MMatchServer::OnRequestStageSetting(const MUID& uidComm, const MUID& uidStage)
  1653. {
  1654. MMatchStage* pStage = FindStage(uidStage);
  1655. if (pStage == NULL) return;
  1656.  
  1657. MCommand* pCmd = CreateCmdResponseStageSetting(uidStage);
  1658. pCmd->m_Receiver = uidComm;
  1659. Post(pCmd);
  1660.  
  1661. // ¸Ê ¼±ÅÃÀÌ ¸±·¹À̸ÊÀ̸é ó¸®ÇØÁØ´Ù.
  1662. OnStageRelayMapListInfo(uidStage, uidComm);
  1663.  
  1664. MMatchObject* pChar = GetObject(uidComm);
  1665. if (pChar && (MMUG_EVENTMASTER == pChar->GetAccountInfo()->m_nUGrade)) {
  1666. // À̺¥Æ® ¸¶½ºÅÍ¿¡°Ô óÀ½ ¹æ¸¸µé¾ú´ø »ç¶÷À» ¾Ë·ÁÁØ´Ù
  1667. StageShowInfo(this, uidComm, uidStage, "/showinfo");
  1668. }
  1669. }
  1670.  
  1671. void MMatchServer::OnRequestPeerList(const MUID& uidChar, const MUID& uidStage)
  1672. {
  1673. ResponsePeerList(uidChar, uidStage);
  1674. }
  1675.  
  1676. void MMatchServer::OnRequestGameInfo(const MUID& uidChar, const MUID& uidStage)
  1677. {
  1678. ResponseGameInfo(uidChar, uidStage);
  1679. }
  1680.  
  1681. void MMatchServer::ResponseGameInfo(const MUID& uidChar, const MUID& uidStage)
  1682. {
  1683. MMatchStage* pStage = FindStage(uidStage); if (pStage == NULL) return;
  1684. MMatchObject* pObj = GetObject(uidChar); if (pObj == NULL) return;
  1685. if (pStage->GetRule() == NULL) return;
  1686.  
  1687. MCommand* pNew = CreateCommand(MC_MATCH_RESPONSE_GAME_INFO, MUID(0,0));
  1688. pNew->AddParameter(new MCommandParameterUID(pStage->GetUID()));
  1689.  
  1690. // °ÔÀÓÁ¤º¸
  1691. void* pGameInfoArray = MMakeBlobArray(sizeof(MTD_GameInfo), 1);
  1692. MTD_GameInfo* pGameItem = (MTD_GameInfo*)MGetBlobArrayElement(pGameInfoArray, 0);
  1693. memset(pGameItem, 0, sizeof(MTD_GameInfo));
  1694.  
  1695. if (pStage->GetStageSetting()->IsTeamPlay())
  1696. {
  1697. pGameItem->nRedTeamScore = static_cast<char>(pStage->GetTeamScore(MMT_RED));
  1698. pGameItem->nBlueTeamScore = static_cast<char>(pStage->GetTeamScore(MMT_BLUE));
  1699.  
  1700. pGameItem->nRedTeamKills = static_cast<short>(pStage->GetTeamKills(MMT_RED));
  1701. pGameItem->nBlueTeamKills = static_cast<short>(pStage->GetTeamKills(MMT_BLUE));
  1702. }
  1703.  
  1704. pNew->AddParameter(new MCommandParameterBlob(pGameInfoArray, MGetBlobArraySize(pGameInfoArray)));
  1705. MEraseBlobArray(pGameInfoArray);
  1706.  
  1707. // ·êÁ¤º¸
  1708. void* pRuleInfoArray = NULL;
  1709. if (pStage->GetRule())
  1710. pRuleInfoArray = pStage->GetRule()->CreateRuleInfoBlob();
  1711. if (pRuleInfoArray == NULL)
  1712. pRuleInfoArray = MMakeBlobArray(0, 0);
  1713. pNew->AddParameter(new MCommandParameterBlob(pRuleInfoArray, MGetBlobArraySize(pRuleInfoArray)));
  1714. MEraseBlobArray(pRuleInfoArray);
  1715.  
  1716. // Battle¿¡ µé¾î°£ »ç¶÷¸¸ List¸¦ ¸¸µç´Ù.
  1717. int nPlayerCount = pStage->GetObjInBattleCount();
  1718.  
  1719. void* pPlayerItemArray = MMakeBlobArray(sizeof(MTD_GameInfoPlayerItem), nPlayerCount);
  1720. int nIndex=0;
  1721. for (MUIDRefCache::iterator itor=pStage->GetObjBegin(); itor!=pStage->GetObjEnd(); itor++)
  1722. {
  1723. MMatchObject* pObj = (MMatchObject*)(*itor).second;
  1724. if (pObj->GetEnterBattle() == false) continue;
  1725.  
  1726. MTD_GameInfoPlayerItem* pPlayerItem = (MTD_GameInfoPlayerItem*)MGetBlobArrayElement(pPlayerItemArray, nIndex++);
  1727. pPlayerItem->uidPlayer = pObj->GetUID();
  1728. pPlayerItem->bAlive = pObj->CheckAlive();
  1729. pPlayerItem->nKillCount = pObj->GetAllRoundKillCount();
  1730. pPlayerItem->nDeathCount = pObj->GetAllRoundDeathCount();
  1731. }
  1732. pNew->AddParameter(new MCommandParameterBlob(pPlayerItemArray, MGetBlobArraySize(pPlayerItemArray)));
  1733. MEraseBlobArray(pPlayerItemArray);
  1734.  
  1735. RouteToListener(pObj, pNew);
  1736. }
  1737.  
  1738. void MMatchServer::OnMatchLoadingComplete(const MUID& uidPlayer, int nPercent)
  1739. {
  1740. MMatchObject* pObj = GetObject(uidPlayer);
  1741. if (pObj == NULL) return;
  1742.  
  1743. MCommand* pCmd = CreateCommand(MC_MATCH_LOADING_COMPLETE, MUID(0,0));
  1744. pCmd->AddParameter(new MCmdParamUID(uidPlayer));
  1745. pCmd->AddParameter(new MCmdParamInt(nPercent));
  1746. RouteToStage(pObj->GetStageUID(), pCmd);
  1747. }
  1748.  
  1749.  
  1750. void MMatchServer::OnGameRoundState(const MUID& uidStage, int nState, int nRound)
  1751. {
  1752. MMatchStage* pStage = FindStage(uidStage);
  1753. if (pStage == NULL) return;
  1754.  
  1755. pStage->RoundStateFromClient(uidStage, nState, nRound);
  1756. }
  1757.  
  1758.  
  1759. void MMatchServer::OnDuelSetObserver(const MUID& uidChar)
  1760. {
  1761. MMatchObject* pObj = GetObject(uidChar);
  1762. if (pObj == NULL) return;
  1763.  
  1764. MCommand* pCmd = CreateCommand(MC_MATCH_SET_OBSERVER, MUID(0,0));
  1765. pCmd->AddParameter(new MCmdParamUID(uidChar));
  1766. RouteToBattle(pObj->GetStageUID(), pCmd);
  1767. }
  1768.  
  1769. void MMatchServer::OnRequestSpawn(const MUID& uidChar, const MVector& pos, const MVector& dir)
  1770. {
  1771. MMatchObject* pObj = GetObject(uidChar);
  1772. if (pObj == NULL) return;
  1773.  
  1774. // Do Not Spawn when AdminHiding
  1775. if (IsAdminGrade(pObj) && pObj->CheckPlayerFlags(MTD_PlayerFlags_AdminHide)) return;
  1776. if (pObj->GetTeam() == MMT_SPECTATOR) return;
  1777.  
  1778.  
  1779. // ¸¶Áö¸· Á×¾ú´ø ½Ã°£°ú »õ·Î ¸®½ºÆùÀ» ¿äûÇÑ ½Ã°£ »çÀÌ¿¡ 2ÃÊ ÀÌ»óÀÇ ½Ã°£ÀÌ ÀÖ¾ú´ÂÁö °Ë»çÇÑ´Ù.
  1780. DWORD dwTime = timeGetTime() - pObj->GetLastSpawnTime();
  1781. if ( dwTime < RESPAWN_DELAYTIME_AFTER_DYING_MIN) return;
  1782. pObj->SetLastSpawnTime(timeGetTime());
  1783.  
  1784. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  1785. if (pStage == NULL) return;
  1786. if ( (pStage->GetRule()->GetRoundState() != MMATCH_ROUNDSTATE_PREPARE) && (!pObj->IsEnabledRespawnDeathTime(GetTickTime())) )
  1787. {
  1788. if(pStage->GetRule()->GetGameType() != MMATCH_GAMETYPE_INFECTION ){
  1789. return;
  1790. }
  1791. }
  1792.  
  1793. MMatchRule* pRule = pStage->GetRule(); // ÀÌ·± ½ÄÀÇ ÄÚµå´Â ¸¶À½¿¡ ¾ÈµéÁö¸¸ -_-; °ÔÀÓŸÀÔ º¸°í ¿¹¿Üó¸®.
  1794. MMATCH_GAMETYPE gameType = pRule->GetGameType(); // ´Ù¸¥ ¹æ¹ý ÀÖ³ª¿ä.
  1795. if (gameType == MMATCH_GAMETYPE_DUEL)
  1796. {
  1797. MMatchRuleDuel* pDuel = (MMatchRuleDuel*)pRule; // RTTI ¾È½á¼­ dynamic cast´Â Æнº.. ¿¹¿Ü󸮵µ Â¥Áõ³ª°í -,.-
  1798. if (uidChar != pDuel->uidChampion && uidChar != pDuel->uidChallenger)
  1799. {
  1800. OnDuelSetObserver(uidChar);
  1801. return;
  1802. }
  1803. }
  1804.  
  1805. pObj->ResetCustomItemUseCount();
  1806. pObj->SetAlive(true);
  1807.  
  1808. MCommand* pCmd = CreateCommand(MC_MATCH_GAME_RESPONSE_SPAWN, MUID(0,0));
  1809. pCmd->AddParameter(new MCmdParamUID(uidChar));
  1810. pCmd->AddParameter(new MCmdParamShortVector(pos.x, pos.y, pos.z));
  1811. pCmd->AddParameter(new MCmdParamShortVector(DirElementToShort(dir.x), DirElementToShort(dir.y), DirElementToShort(dir.z)));
  1812. RouteToBattle(pObj->GetStageUID(), pCmd);
  1813. }
  1814.  
  1815. void MMatchServer::OnGameRequestTimeSync(const MUID& uidComm, unsigned long nLocalTimeStamp)
  1816. {
  1817. MMatchObject* pObj = GetPlayerByCommUID(uidComm);
  1818. if (pObj == NULL) return;
  1819.  
  1820. MMatchTimeSyncInfo* pSync = pObj->GetSyncInfo();
  1821. pSync->Update(GetGlobalClockCount());
  1822.  
  1823. MCommand* pCmd = CreateCommand(MC_MATCH_GAME_RESPONSE_TIMESYNC, MUID(0,0));
  1824. pCmd->AddParameter(new MCmdParamUInt(nLocalTimeStamp));
  1825. pCmd->AddParameter(new MCmdParamUInt(GetGlobalClockCount()));
  1826. RouteToListener(pObj, pCmd);
  1827. }
  1828.  
  1829. void MMatchServer::OnGameReportTimeSync(const MUID& uidComm, unsigned long nLocalTimeStamp, unsigned int nDataChecksum)
  1830. {
  1831. MMatchObject* pObj = GetPlayerByCommUID(uidComm);
  1832. if (pObj == NULL) return;
  1833.  
  1834. pObj->UpdateTickLastPacketRecved(); // Last Packet Timestamp
  1835.  
  1836. if (pObj->GetEnterBattle() == false)
  1837. return;
  1838.  
  1839. //// SpeedHack Test ////
  1840. MMatchTimeSyncInfo* pSync = pObj->GetSyncInfo();
  1841. int nSyncDiff = nLocalTimeStamp - pSync->GetLastSyncClock();
  1842. float fError = static_cast<float>(nSyncDiff) / static_cast<float>(MATCH_CYCLE_CHECK_SPEEDHACK);
  1843. if (fError > 2.f) {
  1844. pSync->AddFoulCount();
  1845. if (pSync->GetFoulCount() >= 3) { // 3¿¬¼Ó ½ºÇǵåÇÙ °ËÃâ - 3Áø¾Æ¿ô
  1846.  
  1847. #ifndef _DEBUG // µð¹ö±×ÇÒ¶§´Â »©³õ¾ÒÀ½
  1848. NotifyMessage(pObj->GetUID(), MATCHNOTIFY_GAME_SPEEDHACK);
  1849. StageLeave(pObj->GetUID());//, pObj->GetStageUID());
  1850. Disconnect(pObj->GetUID());
  1851. #endif
  1852. mlog("SPEEDHACK : User='%s', SyncRatio=%f (TimeDiff=%d) \n",
  1853. pObj->GetName(), fError, nSyncDiff);
  1854. pSync->ResetFoulCount();
  1855. }
  1856. } else {
  1857. pSync->ResetFoulCount();
  1858. }
  1859. pSync->Update(GetGlobalClockCount());
  1860.  
  1861. //// MemoryHack Test ////
  1862. if (nDataChecksum > 0) { // ¼­¹ö°¡ Client MemoryChecksum ¸ð¸£¹Ç·Î ÀÏ´Ü Å¬¶óÀ̾ðÆ®°¡ ½Å°íÇÏ´ÂÀǹ̷Π»ç¿ëÇÑ´Ù.
  1863. NotifyMessage(pObj->GetUID(), MATCHNOTIFY_GAME_MEMORYHACK);
  1864. StageLeave(pObj->GetUID());//, pObj->GetStageUID());
  1865. Disconnect(pObj->GetUID());
  1866. mlog("MEMORYHACK : User='%s', MemoryChecksum=%u \n", pObj->GetName(), nDataChecksum);
  1867. }
  1868. }
  1869.  
  1870. void MMatchServer::OnUpdateFinishedRound(const MUID& uidStage, const MUID& uidChar,
  1871. void* pPeerInfo, void* pKillInfo)
  1872. {
  1873.  
  1874. }
  1875.  
  1876. void MMatchServer::OnRequestForcedEntry(const MUID& uidStage, const MUID& uidChar)
  1877. {
  1878. MMatchStage* pStage = FindStage(uidStage);
  1879. if (pStage == NULL) return;
  1880. MMatchObject* pObj = GetObject(uidChar);
  1881. if (pObj == NULL) return;
  1882.  
  1883. pObj->SetForcedEntry(true);
  1884.  
  1885. //Late Join Quest
  1886. if (MGetGameTypeMgr()->IsQuestDerived(pStage->GetStageSetting()->GetGameType()))
  1887. {
  1888. if (pStage->m_pRule)
  1889. {
  1890. MUID uidChar = pObj->GetUID();
  1891. pStage->m_pRule->OnQuestEnterBattle(uidChar);
  1892. }
  1893. }
  1894. RouteResponseToListener(pObj, MC_MATCH_STAGE_RESPONSE_FORCED_ENTRY, MOK);
  1895. }
  1896.  
  1897. void MMatchServer::OnRequestSuicide(const MUID& uidPlayer)
  1898. {
  1899. MMatchObject* pObj = GetObject(uidPlayer);
  1900. if (pObj == NULL) return;
  1901. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  1902. if (pStage == NULL) return;
  1903.  
  1904. pStage->ReserveSuicide( uidPlayer, MGetMatchServer()->GetGlobalClockCount() );
  1905.  
  1906. // OnGameKill(uidPlayer, uidPlayer);
  1907.  
  1908. //MCommand* pNew = CreateCommand(MC_MATCH_RESPONSE_SUICIDE, MUID(0,0));
  1909. //int nResult = MOK;
  1910. //pNew->AddParameter(new MCommandParameterInt(nResult));
  1911. //pNew->AddParameter(new MCommandParameterUID(uidPlayer));
  1912. //RouteToBattle(pObj->GetStageUID(), pNew);
  1913. }
  1914.  
  1915. void MMatchServer::OnRequestObtainWorldItem(const MUID& uidPlayer, const int nItemUID)
  1916. {
  1917. MMatchObject* pObj = GetObject(uidPlayer);
  1918. if (pObj == NULL) return;
  1919. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  1920. if (pStage == NULL) return;
  1921.  
  1922. pStage->ObtainWorldItem(pObj, nItemUID);
  1923. }
  1924.  
  1925. void MMatchServer::OnRequestFlagCap(const MUID& uidPlayer, const int nItemID)
  1926. {
  1927. MMatchObject* pObj = GetObject(uidPlayer);
  1928. if (pObj == NULL) return;
  1929. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  1930. if (pStage == NULL) return;
  1931.  
  1932. if(pStage->GetStageSetting())
  1933. {
  1934. if(pStage->GetStageSetting()->GetGameType() == MMATCH_GAMETYPE_CTF)
  1935. {
  1936. MMatchRuleTeamCTF* pRule = (MMatchRuleTeamCTF*)pStage->GetRule();
  1937. if(pRule)
  1938. {
  1939. pRule->OnObtainWorldItem( pObj, nItemID, NULL );
  1940. }
  1941. }
  1942. }
  1943. }
  1944.  
  1945. void MMatchServer::OnRequestSpawnWorldItem(const MUID& uidPlayer, const int nItemID, const float x, const float y, const float z, float fDropDelayTime)
  1946. {
  1947. MMatchObject* pObj = GetObject(uidPlayer);
  1948. if (pObj == NULL) return;
  1949. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  1950. if (pStage == NULL) return;
  1951.  
  1952. if( !pObj->IsHaveCustomItem() )
  1953. return;
  1954.  
  1955. /*
  1956. Âø¿ëÇÏ°í ÀÖ´Â ÂÊÀ» ¾Ë ¼ö ¾øÀ¸¹Ç·Î µÎÂÊÀÇ ÇÕÀ¸·Î ÃÖ´ë »ç¿ëÇÒ ¼ö ÀÖ´Â ¼ö·®À» ±¸ÇÑÈÄ
  1957. ±× Çѵµ ¾È¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ÇÑ´Ù.
  1958. */
  1959. if( pObj->IncreaseCustomItemUseCount() )
  1960. {
  1961. pStage->RequestSpawnWorldItem(pObj, nItemID, x, y, z, fDropDelayTime);
  1962. }
  1963. }
  1964.  
  1965. void MMatchServer::OnNotifyThrowTrapItem(const MUID& uidPlayer, const int nItemID)
  1966. {
  1967. MMatchObject* pObj = GetObject(uidPlayer);
  1968. if (pObj == NULL) return;
  1969. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  1970. if (pStage == NULL) return;
  1971.  
  1972. if (!pObj->IsEquipCustomItem(nItemID))
  1973. return;
  1974.  
  1975. pStage->OnNotifyThrowTrapItem(uidPlayer, nItemID);
  1976. }
  1977.  
  1978. void MMatchServer::OnNotifyActivatedTrapItem(const MUID& uidPlayer, const int nItemID, const MVector3& pos)
  1979. {
  1980. MMatchObject* pObj = GetObject(uidPlayer);
  1981. if (pObj == NULL) return;
  1982. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  1983. if (pStage == NULL) return;
  1984.  
  1985. pStage->OnNotifyActivatedTrapItem(uidPlayer, nItemID, pos);
  1986. }
  1987.  
  1988. float MMatchServer::GetDuelVictoryMultiflier(int nVictorty)
  1989. {
  1990. return 1.0f;
  1991. }
  1992.  
  1993. float MMatchServer::GetDuelPlayersMultiflier(int nPlayerCount)
  1994. {
  1995. return 1.0f;
  1996. }
  1997.  
  1998. void MMatchServer::CalcExpOnGameKill(MMatchStage* pStage, MMatchObject* pAttacker, MMatchObject* pVictim,
  1999. int* poutAttackerExp, int* poutVictimExp)
  2000. {
  2001. bool bSuicide = false; // ÀÚ»ì
  2002. if (pAttacker == pVictim) bSuicide = true;
  2003.  
  2004. MMATCH_GAMETYPE nGameType = pStage->GetStageSetting()->GetGameType();
  2005. float fGameExpRatio = MGetGameTypeMgr()->GetInfo(nGameType)->fGameExpRatio;
  2006.  
  2007. // °ÔÀÓŸÀÔÀÌ TrainingÀÌ¸é ¹Ù·Î 0¸®ÅÏ
  2008. if (nGameType == MMATCH_GAMETYPE_TRAINING)
  2009. {
  2010. *poutAttackerExp = 0;
  2011. *poutVictimExp = 0;
  2012. return;
  2013. }
  2014. // °ÔÀÓŸÀÔÀÌ ¹ö¼­Ä¿ÀÏ °æ¿ì
  2015. else if (nGameType == MMATCH_GAMETYPE_BERSERKER)
  2016. {
  2017. MMatchRuleBerserker* pRuleBerserker = (MMatchRuleBerserker*)pStage->GetRule();
  2018.  
  2019. if (pRuleBerserker->GetBerserker() == pAttacker->GetUID())
  2020. {
  2021. if (pAttacker != pVictim)
  2022. {
  2023. // ¹ö¼­Ä¿´Â °æÇèÄ¡¸¦ 80%¸¸ ȹµæÇÑ´Ù.
  2024. fGameExpRatio = fGameExpRatio * 0.8f;
  2025. }
  2026. else
  2027. {
  2028. // ¹ö¼­Ä¿´Â ÀÚ»ì ¶Ç´Â ÇÇ°¡ ÁÙ¾î Á״°æ¿ì ¼Õ½Ç °æÇèÄ¡´Â ¾øµµ·Ï ÇÑ´Ù.
  2029. fGameExpRatio = 0.0f;
  2030. }
  2031. }
  2032. }
  2033. else if (nGameType == MMATCH_GAMETYPE_DUEL)
  2034. {
  2035. MMatchRuleDuel* pRuleDuel = (MMatchRuleDuel*)pStage->GetRule();
  2036. if (pVictim->GetUID() == pRuleDuel->uidChallenger)
  2037. {
  2038. fGameExpRatio *= GetDuelVictoryMultiflier(pRuleDuel->GetVictory());
  2039. }
  2040. else
  2041. {
  2042. fGameExpRatio *= GetDuelVictoryMultiflier(pRuleDuel->GetVictory()) * GetDuelPlayersMultiflier(pStage->GetPlayers());
  2043.  
  2044. }
  2045. // if (pRuleDuel->GetVictory() <= 1)
  2046. // {
  2047. // fGameExpRatio = fGameExpRatio * GetDuelPlayersMultiflier(pStage->GetPlayers()) * GetDuelVictoryMultiflier()
  2048. // }
  2049. }
  2050. else if (nGameType == MMATCH_GAMETYPE_CTF)
  2051. {
  2052. MMatchRuleTeamCTF* pRuleCTF = (MMatchRuleTeamCTF*)pStage->GetRule();
  2053. if (pAttacker != pVictim)
  2054. {
  2055. // ¹ö¼­Ä¿´Â °æÇèÄ¡¸¦ 80%¸¸ ȹµæÇÑ´Ù.
  2056. if(!(pAttacker->GetTeam() == pVictim->GetTeam()) && (pVictim->GetUID() == pRuleCTF->GetBlueCarrier() || pVictim->GetUID() == pRuleCTF->GetRedCarrier()))
  2057. fGameExpRatio = fGameExpRatio * 2;
  2058. }
  2059. else
  2060. {
  2061. // ¹ö¼­Ä¿´Â ÀÚ»ì ¶Ç´Â ÇÇ°¡ ÁÙ¾î Á״°æ¿ì ¼Õ½Ç °æÇèÄ¡´Â ¾øµµ·Ï ÇÑ´Ù.
  2062. fGameExpRatio = 0.0f;
  2063. }
  2064. }
  2065.  
  2066. // ¸Ê, °ÔÀÓŸÀÔ¿¡ ´ëÇÑ °æÇèÄ¡ ºñÀ² Àû¿ë
  2067. int nMapIndex = pStage->GetStageSetting()->GetMapIndex();
  2068. if ((nMapIndex >=0) && (nMapIndex < MMATCH_MAP_COUNT))
  2069. {
  2070. float fMapExpRatio = MGetMapDescMgr()->GetExpRatio(nMapIndex);
  2071. fGameExpRatio = fGameExpRatio * fMapExpRatio;
  2072. }
  2073.  
  2074. int nAttackerLevel = pAttacker->GetCharInfo()->m_nLevel;
  2075. int nVictimLevel = pVictim->GetCharInfo()->m_nLevel;
  2076.  
  2077. // °æÇèÄ¡ °è»ê
  2078. int nAttackerExp = (int)(MMatchFormula::GetGettingExp(nAttackerLevel, nVictimLevel) * fGameExpRatio);
  2079. int nVictimExp = (int)(MMatchFormula::CalcPanaltyEXP(nAttackerLevel, nVictimLevel) * fGameExpRatio);
  2080.  
  2081.  
  2082. // Ŭ·£ÀüÀÏ °æ¿ì´Â ȹµæ °æÇèÄ¡°¡ 1.5¹è, ¼Õ½Ç°æÇèÄ¡ ¾øÀ½
  2083. if ((MGetServerConfig()->GetServerMode() == MSM_CLAN) && (pStage->GetStageType() == MST_LADDER))
  2084. {
  2085. nAttackerExp = (int)((float)nAttackerExp * 1.5f);
  2086. nVictimExp = 0;
  2087. }
  2088.  
  2089. // °í¼öä³Î, ÃÊ°í¼öä³ÎÀÏ °æ¿ì¿¡´Â °æÄ¡´Ù¿î ¾øÀ½(ÀÚ»ìÁ¦¿Ü)
  2090. MMatchChannel* pOwnerChannel = FindChannel(pStage->GetOwnerChannel());
  2091.  
  2092. if ((pOwnerChannel) && (!bSuicide))
  2093. {
  2094. if ((pOwnerChannel->GetRuleType() == MCHANNEL_RULE_MASTERY) ||
  2095. (pOwnerChannel->GetRuleType() == MCHANNEL_RULE_ELITE) ||
  2096. (pOwnerChannel->GetRuleType() == MCHANNEL_RULE_CHAMPION))
  2097. {
  2098. nVictimExp=0;
  2099. }
  2100. }
  2101.  
  2102. // Á×Àº»ç¶÷ÀÌ ¿î¿µÀÚ, °³¹ßÀÚÀÏ °æ¿ì °æÇèÄ¡ µÎ¹è
  2103. if ((pVictim->GetAccountInfo()->m_nUGrade == MMUG_ADMIN) ||
  2104. (pVictim->GetAccountInfo()->m_nUGrade == MMUG_DEVELOPER) ||
  2105. (pVictim->GetAccountInfo()->m_nUGrade == MMUG_GM) ||
  2106. (pVictim->GetAccountInfo()->m_nUGrade == MMUG_HEADGM))
  2107. {
  2108. nAttackerExp = nAttackerExp * 2;
  2109. }
  2110. // Á×Àλç¶÷ÀÌ ¿î¿µÀÚ, °³¹ßÀÚÀÏ °æ¿ì °æÄ¡´Ù¿î ¾øÀ½
  2111. if ((!bSuicide) &&
  2112. ((pAttacker->GetAccountInfo()->m_nUGrade == MMUG_ADMIN) ||
  2113. (pAttacker->GetAccountInfo()->m_nUGrade == MMUG_DEVELOPER) ||
  2114. (pAttacker->GetAccountInfo()->m_nUGrade == MMUG_GM) ||
  2115. (pAttacker->GetAccountInfo()->m_nUGrade == MMUG_HEADGM)))
  2116. {
  2117. nVictimExp = 0;
  2118. }
  2119.  
  2120. // ÀÚ»ìÀÏ °æ¿ì °æÇèÄ¡ ¼Õ½ÇÀÌ µÎ¹è
  2121. if (bSuicide)
  2122. {
  2123. nVictimExp = (int)(MMatchFormula::GetSuicidePanaltyEXP(nVictimLevel) * fGameExpRatio);
  2124. nAttackerExp = 0;
  2125. }
  2126.  
  2127. // ÆÀųÀΰæ¿ì °æÇèÄ¡ Á¦·Î
  2128. if ((pStage->GetStageSetting()->IsTeamPlay()) && (pAttacker->GetTeam() == pVictim->GetTeam()))
  2129. {
  2130. nAttackerExp = 0;
  2131. }
  2132.  
  2133.  
  2134. // ÆÀÀüÀÏ °æ¿ì °æÇèÄ¡ ¹èºÐ
  2135. if (pStage->IsApplyTeamBonus())
  2136. {
  2137. int nTeamBonus = 0;
  2138. if (pStage->GetRule() != NULL)
  2139. {
  2140. int nNewAttackerExp = nAttackerExp;
  2141. pStage->GetRule()->CalcTeamBonus(pAttacker, pVictim, nAttackerExp, &nNewAttackerExp, &nTeamBonus);
  2142. nAttackerExp = nNewAttackerExp;
  2143. }
  2144.  
  2145. // ÆÀ °æÇèÄ¡ Àû¸³
  2146. pStage->AddTeamBonus(nTeamBonus, MMatchTeam(pAttacker->GetTeam()));
  2147. }
  2148.  
  2149. // xp º¸³Ê½º Àû¿ë(³Ý¸¶ºí PC¹æ, °æÇèÄ¡ ¹ÝÁö)
  2150. int nAttackerExpBonus = 0;
  2151. if (nAttackerExp != 0)
  2152. {
  2153. //const float ta = float(atoi("15")) / 100.0f;
  2154. //mlog( "test float : %f\n", ta * 100.0f );
  2155.  
  2156. //MMatchItemBonusType nBonusType = GetStageBonusType(pStage->GetStageSetting());
  2157. //const double dAttackerExp = static_cast< double >( nAttackerExp );
  2158. //const double dXPBonusRatio = static_cast< double >( MMatchFormula::CalcXPBonusRatio(pAttacker, nBonusType) );
  2159. //const double dAttackerExpBouns = dAttackerExp * dXPBonusRatio;
  2160. //const double dSumAttackerExp = dAttackerExp + dAttackerExpBouns;
  2161. //
  2162. //
  2163. //nAttackerExpBonus = static_cast< int >( dAttackerExpBouns + 0.00001);
  2164.  
  2165. MMatchItemBonusType nBonusType = GetStageBonusType(pStage->GetStageSetting());
  2166. const float fAttackerExpBonusRatio = MMatchFormula::CalcXPBonusRatio(pAttacker, nBonusType);
  2167. //ºÎµ¿¼Ò¼öÁ¡ ¿ÀÂ÷¶§¹®¿¡ °è»ê¿¡ ¿µÇâÀ» ÁÖÁö ¾Ê´Â ¹üÀ§¿¡¼­ º¸Á¤À» ÇØÁØ´Ù.
  2168. // ¸¸¾à À̺κп¡¼­ ´Ù½Ã ¹®Á¦°¡ ¹ß»ýÇÑ´Ù¸é º¸Á¤ÀÌ ¾Æ´Ñ º£À̽ººÎÅÍ ¼öÁ¤ ÀÛ¾÷À» ÇØ Áà¾ß ÇÑ´Ù.
  2169. nAttackerExpBonus = (int)(nAttackerExp * (fAttackerExpBonusRatio + 0.00001f));
  2170. }
  2171.  
  2172. *poutAttackerExp = nAttackerExp + nAttackerExpBonus;
  2173.  
  2174. *poutVictimExp = nVictimExp;
  2175. }
  2176.  
  2177.  
  2178. const int MMatchServer::CalcBPonGameKill( MMatchStage* pStage, MMatchObject* pAttacker, const int nAttackerLevel, const int nVictimLevel )
  2179. {
  2180. if( (0 == pStage) || (0 == pAttacker) )
  2181. return -1;
  2182.  
  2183. const int nAddedBP = static_cast< int >( MMatchFormula::GetGettingBounty(nAttackerLevel, nVictimLevel) );
  2184. const float fBPBonusRatio = MMatchFormula::CalcBPBounsRatio( pAttacker, GetStageBonusType(pStage->GetStageSetting()) );
  2185. const int nBPBonus = static_cast< int >( nAddedBP * fBPBonusRatio );
  2186.  
  2187. return nAddedBP + nBPBonus;
  2188. }
  2189.  
  2190.  
  2191.  
  2192.  
  2193. void MMatchServer::ProcessPlayerXPBP(MMatchStage* pStage, MMatchObject* pPlayer, int nAddedXP, int nAddedBP)
  2194. {
  2195. if (pStage == NULL) return;
  2196. if (!IsEnabledObject(pPlayer)) return;
  2197.  
  2198. /*
  2199. °æÇèÄ¡ °è»ê
  2200. ij¸¯ÅÍ¿¡ °æÇèÄ¡ Àû¿ë
  2201. ·¹º§ °è»ê
  2202. DBij½Ì ¾÷µ¥ÀÌÆ®
  2203. ·¹º§¾÷,´Ù¿î ¸Þ¼¼Áö Àü¼Û
  2204. */
  2205.  
  2206. MUID uidStage = pPlayer->GetStageUID();
  2207. int nPlayerLevel = pPlayer->GetCharInfo()->m_nLevel;
  2208.  
  2209. // ij¸¯ÅÍ XP ¾÷µ¥ÀÌÆ®
  2210. pPlayer->GetCharInfo()->IncXP(nAddedXP);
  2211.  
  2212. // ·¹º§ °è»ê
  2213. int nNewPlayerLevel = -1;
  2214.  
  2215. if ((pPlayer->GetCharInfo()->m_nLevel < MAX_LEVEL) &&
  2216. (pPlayer->GetCharInfo()->m_nXP >= MMatchFormula::GetNeedExp(nPlayerLevel)))
  2217. {
  2218. nNewPlayerLevel = MMatchFormula::GetLevelFromExp(pPlayer->GetCharInfo()->m_nXP);
  2219. if (nNewPlayerLevel != pPlayer->GetCharInfo()->m_nLevel) pPlayer->GetCharInfo()->m_nLevel = nNewPlayerLevel;
  2220.  
  2221. }
  2222.  
  2223. // ¹Ù¿îƼ Ãß°¡ÇØÁØ´Ù
  2224. pPlayer->GetCharInfo()->IncBP(nAddedBP);
  2225.  
  2226.  
  2227. // DB ij½³ ¾÷µ¥ÀÌÆ®
  2228. if (pPlayer->GetCharInfo()->GetDBCachingData()->IsRequestUpdate()) {
  2229. UpdateCharDBCachingData(pPlayer); ///< XP, BP, KillCount, DeathCount ij½³ ¾÷µ¥ÀÌÆ®
  2230. }
  2231.  
  2232. // ¸¸¾à ·¹º§ÀÌ ¹Ù²î¸é µû·Î ·¹º§¾÷ÇÑ´Ù.
  2233. if ((nNewPlayerLevel >= 0) && (nNewPlayerLevel != nPlayerLevel))
  2234. {
  2235. // ·¹º§ÀÌ ¹Ù²î¸é ¹Ù·Î ij½³ ¾÷µ¥ÀÌÆ®ÇÑ´Ù
  2236. UpdateCharDBCachingData(pPlayer);
  2237.  
  2238. pPlayer->GetCharInfo()->m_nLevel = nNewPlayerLevel;
  2239. if (!m_MatchDBMgr.UpdateCharLevel(pPlayer->GetCharInfo()->m_nCID,
  2240. nNewPlayerLevel,
  2241. pPlayer->GetCharInfo()->m_nBP,
  2242. pPlayer->GetCharInfo()->m_nTotalKillCount,
  2243. pPlayer->GetCharInfo()->m_nTotalDeathCount,
  2244. pPlayer->GetCharInfo()->m_nTotalPlayTimeSec,
  2245. true))
  2246. {
  2247. mlog("DB UpdateCharLevel Error : %s\n", pPlayer->GetCharInfo()->m_szName);
  2248. }
  2249. }
  2250.  
  2251. // ·¹º§¾÷, ·¹º§ ´Ù¿î ¸Þ¼¼Áö º¸³»±â
  2252. if (nNewPlayerLevel > 0)
  2253. {
  2254. if (nNewPlayerLevel > nPlayerLevel)
  2255. {
  2256. MCommand* pCmd = CreateCommand(MC_MATCH_GAME_LEVEL_UP, MUID(0,0));
  2257. pCmd->AddParameter(new MCommandParameterUID(pPlayer->GetUID()));
  2258. pCmd->AddParameter(new MCommandParameterInt(nNewPlayerLevel));
  2259. RouteToBattle(uidStage, pCmd);
  2260. }
  2261. else if (nNewPlayerLevel < nPlayerLevel)
  2262. {
  2263. MCommand* pCmd = CreateCommand(MC_MATCH_GAME_LEVEL_DOWN, MUID(0,0));
  2264. pCmd->AddParameter(new MCommandParameterUID(pPlayer->GetUID()));
  2265. pCmd->AddParameter(new MCommandParameterInt(nNewPlayerLevel));
  2266. RouteToBattle(uidStage, pCmd);
  2267. }
  2268. }
  2269. }
  2270.  
  2271. //ECoin VIP
  2272. //--------------------------------------------------------------------
  2273. void MMatchServer::AddCoins(MMatchObject* pObject, int quantity){
  2274.  
  2275. if (!IsEnabledObject(pObject)) return;
  2276. if (quantity <= 0)
  2277. {
  2278. _ASSERT(0);
  2279. return;
  2280. }
  2281.  
  2282. if (!m_MatchDBMgr.AddCoins(pObject->GetAccountInfo()->m_nAID,quantity))
  2283. {
  2284. mlog("DB UpdateAccECoins Error : %s\n", pObject->GetCharInfo()->m_szName);
  2285. }
  2286. }
  2287. //--------------------------------------------------------------------
  2288. // ÆÀ º¸³Ê½º Àû¿ë
  2289. void MMatchServer::ApplyObjectTeamBonus(MMatchObject* pObject, int nAddedExp)
  2290. {
  2291. if (!IsEnabledObject(pObject)) return;
  2292. if (nAddedExp <= 0)
  2293. {
  2294. //_ASSERT(0);
  2295. return;
  2296. }
  2297.  
  2298. bool bIsLevelUp = false;
  2299.  
  2300. // º¸³Ê½º Àû¿ë
  2301. if (nAddedExp != 0)
  2302. {
  2303. int nExpBonus = (int)(nAddedExp * MMatchFormula::CalcXPBonusRatio(pObject, MIBT_TEAM));
  2304. nAddedExp += nExpBonus;
  2305. }
  2306.  
  2307.  
  2308.  
  2309.  
  2310. // ij¸¯ÅÍ XP ¾÷µ¥ÀÌÆ®
  2311. pObject->GetCharInfo()->IncXP(nAddedExp);
  2312.  
  2313. // ·¹º§ °è»ê
  2314. int nNewLevel = -1;
  2315. int nCurrLevel = pObject->GetCharInfo()->m_nLevel;
  2316.  
  2317. if (nNewLevel > nCurrLevel) bIsLevelUp = true;
  2318.  
  2319.  
  2320. if ((pObject->GetCharInfo()->m_nLevel < MAX_LEVEL) &&
  2321. (pObject->GetCharInfo()->m_nXP >= MMatchFormula::GetNeedExp(nCurrLevel)))
  2322. {
  2323. nNewLevel = MMatchFormula::GetLevelFromExp(pObject->GetCharInfo()->m_nXP);
  2324. if (nNewLevel != nCurrLevel) pObject->GetCharInfo()->m_nLevel = nNewLevel;
  2325.  
  2326. }
  2327.  
  2328. // DB ij½³ ¾÷µ¥ÀÌÆ®
  2329. if (pObject->GetCharInfo()->GetDBCachingData()->IsRequestUpdate())
  2330. {
  2331. UpdateCharDBCachingData(pObject);
  2332. }
  2333.  
  2334. // ¸¸¾à ·¹º§ÀÌ ¹Ù²î¸é ¹Ù·Î ·¹º§¾÷ÇÑ´Ù.
  2335. if ((nNewLevel >= 0) && (nNewLevel != nCurrLevel))
  2336. {
  2337. // ·¹º§ÀÌ ¹Ù²î¸é ¹Ù·Î ij½³ ¾÷µ¥ÀÌÆ®ÇÑ´Ù
  2338. UpdateCharDBCachingData(pObject);
  2339.  
  2340. pObject->GetCharInfo()->m_nLevel = nNewLevel;
  2341. nCurrLevel = nNewLevel;
  2342.  
  2343. if (!m_MatchDBMgr.UpdateCharLevel(pObject->GetCharInfo()->m_nCID,
  2344. nNewLevel,
  2345. pObject->GetCharInfo()->m_nBP,
  2346. pObject->GetCharInfo()->m_nTotalKillCount,
  2347. pObject->GetCharInfo()->m_nTotalDeathCount,
  2348. pObject->GetCharInfo()->m_nTotalPlayTimeSec,
  2349. bIsLevelUp
  2350. ))
  2351. {
  2352. mlog("DB UpdateCharLevel Error : %s\n", pObject->GetCharInfo()->m_szName);
  2353. }
  2354. }
  2355.  
  2356.  
  2357. MUID uidStage = pObject->GetStageUID();
  2358.  
  2359. unsigned long int nExpArg;
  2360. __int64 nChrExp;
  2361. int nPercent;
  2362.  
  2363. nChrExp = pObject->GetCharInfo()->m_nXP;
  2364. nPercent = MMatchFormula::GetLevelPercent(nChrExp, nCurrLevel);
  2365. // »óÀ§ 2¹ÙÀÌÆ®´Â °æÇèÄ¡, ÇÏÀ§ 2¹ÙÀÌÆ®´Â °æÇèÄ¡ÀÇ ÆÛ¼¾Æ®ÀÌ´Ù.
  2366. nExpArg = MakeExpTransData(nAddedExp, nPercent);
  2367.  
  2368.  
  2369. MCommand* pCmd = CreateCommand(MC_MATCH_GAME_TEAMBONUS, MUID(0,0));
  2370. pCmd->AddParameter(new MCommandParameterUID(pObject->GetUID()));
  2371. pCmd->AddParameter(new MCommandParameterUInt(nExpArg));
  2372. RouteToBattle(uidStage, pCmd);
  2373.  
  2374.  
  2375. // ·¹º§¾÷ ¸Þ¼¼Áö º¸³»±â
  2376. if ((nNewLevel >= 0) && (nNewLevel > nCurrLevel))
  2377. {
  2378. MCommand* pCmd = CreateCommand(MC_MATCH_GAME_LEVEL_UP, MUID(0,0));
  2379. pCmd->AddParameter(new MCommandParameterUID(pObject->GetUID()));
  2380. pCmd->AddParameter(new MCommandParameterInt(nNewLevel));
  2381. RouteToBattle(uidStage, pCmd);
  2382. }
  2383. }
  2384.  
  2385. // Ç÷¹ÀÌ Áß Ä³¸¯ÅÍ Á¤º¸ ¾÷µ¥ÀÌÆ®
  2386. void MMatchServer::ProcessCharPlayInfo(MMatchObject* pPlayer)
  2387. {
  2388. if (!IsEnabledObject(pPlayer)) return;
  2389.  
  2390. /*
  2391. ¿øÇÒ¶§¸¶´Ù ij¸¯ÅÍ Á¤º¸¸¦ ¾÷µ¥ÀÌÆ® Àû¿ë
  2392. °æÇèÄ¡ °è»ê
  2393. ij¸¯ÅÍ¿¡ °æÇèÄ¡ Àû¿ë
  2394. ·¹º§ °è»ê
  2395. ·¹º§¾÷,´Ù¿î ¸Þ¼¼Áö Àü¼Û
  2396. ¹Ù¿îƼ Ãß°¡ÇØÁØ´Ù
  2397. Á¢¼Ó½Ã°£, °ÔÀÓ ÁøÇà½Ã°£, Ç÷¹ÀÌ ½Ã°£
  2398. */
  2399.  
  2400. MUID uidStage = pPlayer->GetStageUID();
  2401. int nPlayerLevel = pPlayer->GetCharInfo()->m_nLevel;
  2402.  
  2403. // ·¹º§ °è»ê
  2404. int nNewPlayerLevel = -1;
  2405.  
  2406. if ((pPlayer->GetCharInfo()->m_nLevel < MAX_LEVEL) &&
  2407. (pPlayer->GetCharInfo()->m_nXP >= MMatchFormula::GetNeedExp(nPlayerLevel)))
  2408. {
  2409. nNewPlayerLevel = MMatchFormula::GetLevelFromExp(pPlayer->GetCharInfo()->m_nXP);
  2410. if (nNewPlayerLevel != pPlayer->GetCharInfo()->m_nLevel) pPlayer->GetCharInfo()->m_nLevel = nNewPlayerLevel;
  2411.  
  2412. }
  2413. // ¸¸¾à ·¹º§ÀÌ ¹Ù²î¸é µû·Î ·¹º§¾÷ÇÑ´Ù.
  2414. if ((nNewPlayerLevel >= 0) && (nNewPlayerLevel != nPlayerLevel))
  2415. pPlayer->GetCharInfo()->m_nLevel = nNewPlayerLevel;
  2416.  
  2417. // Á¢¼Ó½Ã°£, °ÔÀÓ ÁøÇà½Ã°£, Ç÷¹ÀÌ ½Ã°£
  2418. unsigned long int nNowTime = MMatchServer::GetInstance()->GetGlobalClockCount();
  2419. unsigned long int nBattlePlayingTimeSec = 0;
  2420. if(pPlayer->GetCharInfo()->m_nBattleStartTime != 0)
  2421. {
  2422. nBattlePlayingTimeSec = MGetTimeDistance(pPlayer->GetCharInfo()->m_nBattleStartTime, nNowTime) / 1000; // ¹èƲÀ» ÁøÇàÇÑ ½Ã°£
  2423.  
  2424. /*
  2425. // ¾Æ¹« 󸮵µ ÇÏÁö ¾Ê´Âµ¥, ¿Ö ·Î±×´Â ³²±â´Â°Ç°¡¿ä? ÀÏ´Ü ÁÖ¼® ó¸®ÇÕ´Ï´Ù. - carrot318
  2426. if(nBattlePlayingTimeSec > 60*60)
  2427. {// ÀÌ»óÀûÀ¸·Î °ªÀÌ ¼¼ÆÃµÅ¸é ·Î±×¸¦ ³²±ä´Ù.
  2428. CTime theTime = CTime::GetCurrentTime();
  2429. CString szTime = theTime.Format( "[%c] " );
  2430.  
  2431. // °ÔÀÓ ¸ðµå
  2432. char buf[64]={0,};
  2433. MMatchStage* pStage = FindStage(uidStage);
  2434.  
  2435. if( pStage != NULL )
  2436. {
  2437. switch((int)pStage->GetStageSetting()->GetGameType())
  2438. {
  2439. case MMATCH_GAMETYPE_DEATHMATCH_SOLO: {sprintf(buf, "DEATHMATCH_SOLO"); } break; ///< °³ÀÎ µ¥¾²¸ÅÄ¡
  2440. case MMATCH_GAMETYPE_DEATHMATCH_TEAM: {sprintf(buf, "DEATHMATCH_TEAM"); } break; ///< ÆÀ µ¥¾²¸ÅÄ¡
  2441. case MMATCH_GAMETYPE_GLADIATOR_SOLO: {sprintf(buf, "GLADIATOR_SOLO"); } break; ///< °³ÀÎ ±Û·¡µð¿¡ÀÌÅÍ
  2442. case MMATCH_GAMETYPE_GLADIATOR_TEAM: {sprintf(buf, "GLADIATOR_TEAM"); } break; ///< ÆÀ ±Û·¡µð¿¡ÀÌÅÍ
  2443. case MMATCH_GAMETYPE_ASSASSINATE: {sprintf(buf, "ASSASSINATE"); } break; ///< º¸½ºÀü
  2444. case MMATCH_GAMETYPE_TRAINING: {sprintf(buf, "TRAINING"); } break; ///< ¿¬½À
  2445.  
  2446. case MMATCH_GAMETYPE_SURVIVAL: {sprintf(buf, "SURVIVAL"); } break; ///< ¼­¹ÙÀ̹ú
  2447. case MMATCH_GAMETYPE_QUEST: {sprintf(buf, "QUEST"); } break; ///< Äù½ºÆ®
  2448.  
  2449. case MMATCH_GAMETYPE_BERSERKER: {sprintf(buf, "BERSERKER"); } break;
  2450. case MMATCH_GAMETYPE_DEATHMATCH_TEAM2: {sprintf(buf, "DEATHMATCH_TEAM2"); } break;
  2451. case MMATCH_GAMETYPE_DUEL: {sprintf(buf, "DUEL"); } break;
  2452. default: {sprintf(buf, "don't know"); } break;
  2453. }
  2454. mlog("%s BattlePlayT Error GameMode:%s, CID:%d, Name:%s, ServerCurrT:%u, BattleStartT:%u, PlayT:%d, PlayerConnectT:%u \n"
  2455. , szTime, buf, pPlayer->GetCharInfo()->m_nCID, pPlayer->GetCharInfo()->m_szName, nNowTime, pPlayer->GetCharInfo()->m_nBattleStartTime, nBattlePlayingTimeSec, pPlayer->GetCharInfo()->m_nConnTime);
  2456. }
  2457. }
  2458. */
  2459. //pPlayer->GetCharInfo()->m_nBattleStartTime = 0;
  2460. }
  2461. unsigned long int nLoginTotalTimeSec = MGetTimeDistance(pPlayer->GetCharInfo()->m_nConnTime, nNowTime) / 1000; // °ÔÀÓÀ» ÁøÇàÇÑ ½Ã°£
  2462.  
  2463. // ÀÌ»óÀûÀ¸·Î °æÇèÄ¡°¡ ȹµæÇßÀ¸¸é ·Î±×¸¦ ³²°ÜÁØ´Ù.
  2464. // ¾Æ¹« 󸮵µ ÇÏÁö ¾Ê´Âµ¥, ¿Ö ·Î±×´Â ³²±â´Â°Ç°¡¿ä? ÀÏ´Ü ÁÖ¼® ó¸®ÇÕ´Ï´Ù. - carrot318
  2465. /*
  2466. long int nBattleEXPGained = pPlayer->GetCharInfo()->m_nXP - pPlayer->GetCharInfo()->m_nBattleStartXP;
  2467. if(nBattleEXPGained < -150000 || 150000 < nBattleEXPGained)
  2468. {
  2469. CTime theTime = CTime::GetCurrentTime();
  2470. CString szTime = theTime.Format( "[%c] " );
  2471. mlog("%s BattleXPGained Error CID:%d, Name:%s, StartXP:%d, EXPGained:%d \n", szTime, pPlayer->GetCharInfo()->m_nCID, pPlayer->GetCharInfo()->m_szName, pPlayer->GetCharInfo()->m_nBattleStartXP, nBattleEXPGained);
  2472. }
  2473. */
  2474.  
  2475. #ifdef LOCALE_NHNUSA
  2476. if (!m_MatchDBMgr.UpdateCharPlayInfo(pPlayer->GetAccountInfo()->m_nAID
  2477. , pPlayer->GetCharInfo()->m_nCID
  2478. , pPlayer->GetCharInfo()->m_nXP
  2479. , pPlayer->GetCharInfo()->m_nLevel
  2480. , nBattlePlayingTimeSec // ¹èƲ ½Ã°£
  2481. , nLoginTotalTimeSec // ÃÑ°ÔÀÓÀ» ÁøÇàÇÑ ½Ã°£
  2482. , pPlayer->GetCharInfo()->m_nTotalKillCount
  2483. , pPlayer->GetCharInfo()->m_nTotalDeathCount
  2484. , pPlayer->GetCharInfo()->m_nBP
  2485. , false))
  2486. {
  2487. mlog("DB UpdateCharPlayInfo Error : %s\n", pPlayer->GetCharInfo()->m_szName);
  2488. }
  2489. #endif
  2490.  
  2491. }
  2492.  
  2493. void MMatchServer::PostGameDeadOnGameKill(MUID& uidStage, MMatchObject* pAttacker, MMatchObject* pVictim,
  2494. int nAddedAttackerExp, int nSubedVictimExp)
  2495. {
  2496. unsigned long int nAttackerArg = 0;
  2497. unsigned long int nVictimArg =0;
  2498.  
  2499. int nRealAttackerLevel = pAttacker->GetCharInfo()->m_nLevel;
  2500. int nRealVictimLevel = pVictim->GetCharInfo()->m_nLevel;
  2501.  
  2502. __int64 nChrExp;
  2503. int nPercent;
  2504.  
  2505. nChrExp = pAttacker->GetCharInfo()->m_nXP;
  2506. nPercent = MMatchFormula::GetLevelPercent(nChrExp, nRealAttackerLevel);
  2507. nAttackerArg = MakeExpTransData(nAddedAttackerExp, nPercent);
  2508.  
  2509. nChrExp = pVictim->GetCharInfo()->m_nXP;
  2510. nPercent = MMatchFormula::GetLevelPercent(nChrExp, nRealVictimLevel);
  2511. nVictimArg = MakeExpTransData(nSubedVictimExp, nPercent);
  2512.  
  2513. MCommand* pCmd = CreateCommand(MC_MATCH_GAME_DEAD, MUID(0,0));
  2514. pCmd->AddParameter(new MCommandParameterUID(pAttacker->GetUID()));
  2515. pCmd->AddParameter(new MCommandParameterUInt(nAttackerArg));
  2516. pCmd->AddParameter(new MCommandParameterUID(pVictim->GetUID()));
  2517. pCmd->AddParameter(new MCommandParameterUInt(nVictimArg));
  2518. RouteToBattle(uidStage, pCmd);
  2519. }
  2520.  
  2521. void MMatchServer::StageList(const MUID& uidPlayer, int nStageStartIndex, bool bCacheUpdate)
  2522. {
  2523. MMatchObject* pChar = GetObject(uidPlayer);
  2524. if (pChar == NULL) return;
  2525. MMatchChannel* pChannel = FindChannel(pChar->GetChannelUID());
  2526. if (pChannel == NULL) return;
  2527.  
  2528. // Ŭ·£¼­¹öÀε¥ Ŭ·£Ã¤³ÎÀÏ °æ¿ì¿¡´Â ¹æ ¸®½ºÆ®´ë½Å ´ë±âÁß Å¬·£ ¸®½ºÆ®¸¦ º¸³½´Ù.
  2529. if ((MGetServerConfig()->GetServerMode() == MSM_CLAN) && (pChannel->GetChannelType() == MCHANNEL_TYPE_CLAN))
  2530. {
  2531. StandbyClanList(uidPlayer, nStageStartIndex, bCacheUpdate);
  2532. return;
  2533. }
  2534.  
  2535.  
  2536. MCommand* pNew = new MCommand(m_CommandManager.GetCommandDescByID(MC_MATCH_STAGE_LIST), MUID(0,0), m_This);
  2537.  
  2538. int nPrevStageCount = -1, nNextStageCount = -1;
  2539. int nNextStageIndex = pChannel->GetMaxPlayers()-1;
  2540.  
  2541.  
  2542. // 2008.09.16
  2543. int nRealStageStartIndex = nStageStartIndex;
  2544. int nStageCount = 0;
  2545. for(int i = 0; i < pChannel->GetMaxPlayers(); i++)
  2546. {
  2547. // ¹æÀÌ ºñ¿öÀÕÀ¸¸é 󸮾ÈÇÑ´Ù
  2548. if (pChannel->IsEmptyStage(i)) continue;
  2549. // ¹æÀÌ ÀÖÀ¸¸é ó¸®
  2550. if(nStageCount < nStageStartIndex) // ¾Õ¿¡ ÅÇ¿¡ ó¸®µÈ ¹æµé < ÇöÀç ÅÇ¿¡¼­ ½ÃÀÛÇÒ ¹æ Index
  2551. nStageCount++;
  2552. else
  2553. {
  2554. nRealStageStartIndex = i;
  2555. break;
  2556. }
  2557. }
  2558.  
  2559. int nRealStageCount = 0;
  2560. for (int i = /*nStageStartIndex*/nRealStageStartIndex; i < pChannel->GetMaxPlayers(); i++)
  2561. {
  2562. if (pChannel->IsEmptyStage(i)) continue;
  2563.  
  2564. MMatchStage* pStage = pChannel->GetStage(i);
  2565. if ((pStage == NULL) || (pStage->GetState() == STAGE_STATE_CLOSE)) continue;
  2566.  
  2567. nRealStageCount++;
  2568. if (nRealStageCount >= TRANS_STAGELIST_NODE_COUNT)
  2569. {
  2570. nNextStageIndex = i;
  2571. break;
  2572. }
  2573. }
  2574.  
  2575. if (!bCacheUpdate)
  2576. {
  2577. nPrevStageCount = pChannel->GetPrevStageCount(nStageStartIndex);
  2578. nNextStageCount = pChannel->GetNextStageCount(nNextStageIndex);
  2579. }
  2580.  
  2581. pNew->AddParameter(new MCommandParameterChar((char)nPrevStageCount));
  2582. pNew->AddParameter(new MCommandParameterChar((char)nNextStageCount));
  2583.  
  2584.  
  2585. void* pStageArray = MMakeBlobArray(sizeof(MTD_StageListNode), nRealStageCount);
  2586. int nArrayIndex=0;
  2587.  
  2588. for (int i = /*nStageStartIndex*/nRealStageStartIndex; i < pChannel->GetMaxPlayers(); i++)
  2589. {
  2590. if (pChannel->IsEmptyStage(i)) continue;
  2591. MMatchStage* pStage = pChannel->GetStage(i);
  2592. if ((pStage == NULL) || (pStage->GetState() == STAGE_STATE_CLOSE)) continue;
  2593.  
  2594. if( pStage->GetState() < STAGE_STATE_STANDBY || pStage->GetState() > STAGE_STATE_COUNT )
  2595. {
  2596. /* Å©·¡½¬·Î ÀÎÇØ ¹æ¾îÄÚµå Ãß°¡. ³ªÁß¿¡ pChannel->m_pStages ¹è¿­ÀÌ ¾Æ´Ñ ¸ÊÀ̳ª ´Ù¸¥°É·Î ¸®ÆåÅ丵ÇÊ¿ä*/
  2597. LOG(LOG_FILE, "there is unavailable stages in %s channel. No:%d \n", pChannel->GetName(), i);
  2598. continue;
  2599. }
  2600.  
  2601.  
  2602. if (nArrayIndex >= nRealStageCount) break;
  2603.  
  2604. MTD_StageListNode* pNode = (MTD_StageListNode*)MGetBlobArrayElement(pStageArray, nArrayIndex++);
  2605. pNode->uidStage = pStage->GetUID();
  2606. strcpy(pNode->szStageName, pStage->GetName());
  2607. pNode->nNo = (unsigned char)(pStage->GetIndex() + 1); // »ç¿ëÀÚ¿¡°Ô º¸¿©ÁÖ´Â À妽º´Â 1ºÎÅÍ ½ÃÀÛÇÑ´Ù
  2608. pNode->nPlayers = (char)pStage->GetPlayers();
  2609. pNode->nMaxPlayers = pStage->GetStageSetting()->GetMaxPlayers();
  2610. pNode->nState = pStage->GetState();
  2611. pNode->nGameType = pStage->GetStageSetting()->GetGameType();
  2612.  
  2613. // ¸±·¹ÀÌ¸é ·Îºñ ¹æ¸®½ºÆ® ¹è³Ê¸¦ ¸±·¹À̸ÊÀ¸·Î À¯ÁöÇØÁØ´Ù.
  2614. if(pStage->IsRelayMap()) pNode->nMapIndex = MMATCH_MAP_RELAYMAP;
  2615. else pNode->nMapIndex = pStage->GetStageSetting()->GetMapIndex();
  2616.  
  2617. pNode->nSettingFlag = 0;
  2618. // ³­ÀÔ
  2619. if (pStage->GetStageSetting()->GetForcedEntry())
  2620. {
  2621. pNode->nSettingFlag |= MSTAGENODE_FLAG_FORCEDENTRY_ENABLED;
  2622. }
  2623. // ºñ¹Ð¹æ
  2624. if (pStage->IsPrivate())
  2625. {
  2626. pNode->nSettingFlag |= MSTAGENODE_FLAG_PRIVATE;
  2627. }
  2628. // ·¹º§Á¦ÇÑ
  2629. pNode->nLimitLevel = pStage->GetStageSetting()->GetLimitLevel();
  2630. pNode->nMasterLevel = 0;
  2631.  
  2632. if (pNode->nLimitLevel != 0)
  2633. {
  2634. pNode->nSettingFlag |= MSTAGENODE_FLAG_LIMITLEVEL;
  2635.  
  2636. ;
  2637. MMatchObject* pMaster = GetObject(pStage->GetMasterUID());
  2638. if (pMaster)
  2639. {
  2640. if (pMaster->GetCharInfo())
  2641. {
  2642. pNode->nMasterLevel = pMaster->GetCharInfo()->m_nLevel;
  2643. }
  2644. }
  2645. }
  2646. }
  2647.  
  2648. pNew->AddParameter(new MCommandParameterBlob(pStageArray, MGetBlobArraySize(pStageArray)));
  2649. MEraseBlobArray(pStageArray);
  2650.  
  2651. RouteToListener(pChar, pNew);
  2652. }
  2653.  
  2654.  
  2655. void MMatchServer::OnStageRequestStageList(const MUID& uidPlayer, const MUID& uidChannel, const int nStageCursor)
  2656. {
  2657. MMatchObject* pObj = GetObject(uidPlayer);
  2658. if (pObj == NULL) return;
  2659. MMatchChannel* pChannel = FindChannel(uidChannel);
  2660. if (pChannel == NULL) return;
  2661.  
  2662. pObj->SetStageCursor(nStageCursor);
  2663. StageList(pObj->GetUID(), nStageCursor, false);
  2664. }
  2665.  
  2666.  
  2667. void MMatchServer::OnRequestQuickJoin(const MUID& uidPlayer, void* pQuickJoinBlob)
  2668. {
  2669. MTD_QuickJoinParam* pNode = (MTD_QuickJoinParam*)MGetBlobArrayElement(pQuickJoinBlob, 0);
  2670. ResponseQuickJoin(uidPlayer, pNode);
  2671. }
  2672.  
  2673. void MMatchServer::ResponseQuickJoin(const MUID& uidPlayer, MTD_QuickJoinParam* pQuickJoinParam)
  2674. {
  2675. if (pQuickJoinParam == NULL) return;
  2676.  
  2677. MMatchObject* pObj = GetObject(uidPlayer);
  2678. if (!IsEnabledObject(pObj)) return;
  2679. MMatchChannel* pChannel = FindChannel(pObj->GetChannelUID());
  2680. if (pChannel == NULL) return;
  2681.  
  2682. list<MUID> recommended_stage_list;
  2683. MUID uidRecommendedStage = MUID(0,0);
  2684. int nQuickJoinResult = MOK;
  2685.  
  2686.  
  2687. for (int i = 0; i < pChannel->GetMaxStages(); i++)
  2688. {
  2689. if (pChannel->IsEmptyStage(i)) continue;
  2690. MMatchStage* pStage = pChannel->GetStage(i);
  2691. if ((pStage == NULL) || (pStage->GetState() == STAGE_STATE_CLOSE)) continue;
  2692.  
  2693. int ret = ValidateStageJoin(pObj->GetUID(), pStage->GetUID());
  2694. if (ret == MOK)
  2695. {
  2696. if (pStage->IsPrivate()) continue;
  2697.  
  2698. int nMapIndex = pStage->GetStageSetting()->GetMapIndex();
  2699. int nGameType = pStage->GetStageSetting()->GetGameType();
  2700.  
  2701. if (!CheckBitSet(pQuickJoinParam->nMapEnum, nMapIndex)) continue;
  2702. if (!CheckBitSet(pQuickJoinParam->nModeEnum, nGameType)) continue;
  2703.  
  2704. //if (((1 << nMapIndex) & (pQuickJoinParam->nMapEnum)) == 0) continue;
  2705. //if (((1 << nGameType) & (pQuickJoinParam->nModeEnum)) == 0) continue;
  2706.  
  2707. recommended_stage_list.push_back(pStage->GetUID());
  2708. }
  2709. }
  2710.  
  2711. if (!recommended_stage_list.empty())
  2712. {
  2713. int nSize=(int)recommended_stage_list.size();
  2714. int nIndex = rand() % nSize;
  2715.  
  2716. int nCnt = 0;
  2717. for (list<MUID>::iterator itor = recommended_stage_list.begin(); itor != recommended_stage_list.end(); ++itor)
  2718. {
  2719. if (nIndex == nCnt)
  2720. {
  2721. uidRecommendedStage = (*itor);
  2722. break;
  2723. }
  2724. nCnt++;
  2725. }
  2726. }
  2727. else
  2728. {
  2729. nQuickJoinResult = MERR_CANNOT_NO_STAGE;
  2730. }
  2731.  
  2732. MCommand* pCmd = CreateCommand(MC_MATCH_STAGE_RESPONSE_QUICKJOIN, MUID(0,0));
  2733. pCmd->AddParameter(new MCommandParameterInt(nQuickJoinResult));
  2734. pCmd->AddParameter(new MCommandParameterUID(uidRecommendedStage));
  2735. RouteToListener(pObj, pCmd);
  2736. }
  2737.  
  2738. static int __cdecl _int_sortfunc(const void* a, const void* b)
  2739. {
  2740. return *((int*)a) - *((int*)b);
  2741. }
  2742.  
  2743.  
  2744. int MMatchServer::GetLadderTeamIDFromDB(const int nTeamTableIndex, const int* pnMemberCIDArray, const int nMemberCount)
  2745. {
  2746. if ((nMemberCount <= 0) || (nTeamTableIndex != nMemberCount))
  2747. {
  2748. //_ASSERT(0);
  2749. return 0;
  2750. }
  2751.  
  2752. // cid ¿À¸§Â÷¼øÀ¸·Î ¼ÒÆà - db»ó¿¡ ¼ÒÆÃµÇ¾î µé¾î°¡ÀÖ´Ù.
  2753. int* pnSortedCIDs = new int[nMemberCount];
  2754. for (int i = 0; i < nMemberCount; i++)
  2755. {
  2756. pnSortedCIDs[i] = pnMemberCIDArray[i];
  2757. }
  2758. qsort(pnSortedCIDs, nMemberCount, sizeof(int), _int_sortfunc);
  2759.  
  2760. int nTID = 0;
  2761. if (pnSortedCIDs[0] != 0)
  2762. {
  2763. if (!m_MatchDBMgr.GetLadderTeamID(nTeamTableIndex, pnSortedCIDs, nMemberCount, &nTID))
  2764. {
  2765. nTID = 0;
  2766. }
  2767. }
  2768.  
  2769.  
  2770. delete[] pnSortedCIDs;
  2771.  
  2772. return nTID;
  2773. }
  2774.  
  2775. void MMatchServer::SaveLadderTeamPointToDB(const int nTeamTableIndex, const int nWinnerTeamID, const int nLoserTeamID, const bool bIsDrawGame)
  2776. {
  2777. // Æ÷ÀÎÆ® °è»ê - ¾×¼Ç¸®±× Àü¿ë
  2778. int nWinnerPoint = 0, nLoserPoint = 0, nDrawPoint = 0;
  2779.  
  2780. nLoserPoint = -1;
  2781. switch (nTeamTableIndex)
  2782. {
  2783. case 2: // 2´ë2
  2784. {
  2785. nWinnerPoint = 4;
  2786. nDrawPoint = 1;
  2787. }
  2788. break;
  2789. case 3:
  2790. {
  2791. nWinnerPoint = 6;
  2792. nDrawPoint = 1;
  2793. }
  2794. break;
  2795. case 4:
  2796. {
  2797. nWinnerPoint = 10;
  2798. nDrawPoint = 2;
  2799. }
  2800. break;
  2801. }
  2802.  
  2803. if (!m_MatchDBMgr.LadderTeamWinTheGame(nTeamTableIndex, nWinnerTeamID, nLoserTeamID, bIsDrawGame,
  2804. nWinnerPoint, nLoserPoint, nDrawPoint))
  2805. {
  2806. mlog("DB Query(SaveLadderTeamPointToDB) Failed\n");
  2807. }
  2808. }
  2809. //-------------------------------------------------------------------------------------------
  2810. //MUTE
  2811. //-------------------------------------------------------------------------------------------
  2812. void MMatchServer::Mute(const MUID& uidAdmin, const char* pszTargetName)
  2813. {
  2814. MMatchObject* pObj = GetObject(uidAdmin);
  2815. if( 0 == pObj )
  2816. return;
  2817.  
  2818. if (!IsEnabledObject(pObj)) return;
  2819.  
  2820. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  2821. if (pStage == NULL) return;
  2822.  
  2823. if (!IsAdminGrade(pObj))
  2824. {
  2825. return;
  2826. }
  2827.  
  2828. MMatchObject* pTargetObj = GetPlayerByName(pszTargetName);
  2829. if (pTargetObj == NULL) return;
  2830.  
  2831. pTargetObj->GetAccountInfo()->m_nUGrade = MMUG_CHAT_LIMITED;
  2832.  
  2833. if (m_MatchDBMgr.Mute(pTargetObj->GetAccountInfo()->m_nAID, true)) {
  2834. MMatchObjectCacheBuilder CacheBuilder;
  2835. CacheBuilder.AddObject(pTargetObj);
  2836. MCommand* pCmdCacheUpdate = CacheBuilder.GetResultCmd(MATCHCACHEMODE_REPLACE, this);
  2837. RouteToStage(pStage->GetUID(), pCmdCacheUpdate);
  2838.  
  2839. MCommand* pCmdUIUpdate = CreateCommand(MC_MUTE, MUID(0,0));
  2840. pCmdUIUpdate->AddParameter(new MCommandParameterUID(pTargetObj->GetUID()));
  2841. pCmdUIUpdate->AddParameter(new MCommandParameterBool(false));
  2842. RouteToStage(pStage->GetUID(), pCmdUIUpdate);
  2843.  
  2844. }
  2845. }
  2846. //-------------------------------------------------------------------------------------------
  2847. //FREEZE
  2848. //-------------------------------------------------------------------------------------------
  2849. void MMatchServer::Freeze(const MUID& uidAdmin, const char* pszTargetName)
  2850. {
  2851. MMatchObject* pObj = GetObject(uidAdmin);
  2852. if( 0 == pObj )
  2853. return;
  2854.  
  2855. if (!IsEnabledObject(pObj)) return;
  2856.  
  2857. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  2858. if (pStage == NULL) return;
  2859.  
  2860. // °ü¸®ÀÚ ±ÇÇÑÀ» °¡Áø »ç¶÷ÀÌ ¾Æ´Ï¸é ¿¬°áÀ» ²÷´Â´Ù.
  2861. if (!IsAdminGrade(pObj))
  2862. {
  2863. return;
  2864. }
  2865.  
  2866. MMatchObject* pTargetObj = GetPlayerByName(pszTargetName);
  2867. if (pTargetObj == NULL) return; // ¾îµå¹Î ´ë»óÀ¸·Î ¯ºÒ°¡
  2868.  
  2869. pTargetObj->GetAccountInfo()->m_nUGrade = MMUG_FREEZE;
  2870.  
  2871. if (m_MatchDBMgr.Freeze(pTargetObj->GetAccountInfo()->m_nAID, true)) {
  2872. MMatchObjectCacheBuilder CacheBuilder;
  2873. CacheBuilder.AddObject(pTargetObj);
  2874. MCommand* pCmdCacheUpdate = CacheBuilder.GetResultCmd(MATCHCACHEMODE_REPLACE, this);
  2875. RouteToStage(pStage->GetUID(), pCmdCacheUpdate);
  2876.  
  2877. MCommand* pCmdUIUpdate = CreateCommand(MC_FREEZE, MUID(0,0));
  2878. pCmdUIUpdate->AddParameter(new MCommandParameterUID(pTargetObj->GetUID()));
  2879. pCmdUIUpdate->AddParameter(new MCommandParameterBool(false));
  2880. RouteToStage(pStage->GetUID(), pCmdUIUpdate);
  2881.  
  2882. }
  2883. }
  2884. //-------------------------------------------------------------------------------------------
  2885. //BAN
  2886. //-------------------------------------------------------------------------------------------
  2887. void MMatchServer::Ban(const MUID& uidAdmin, const char* pszTargetName)
  2888. {
  2889. MMatchObject* pObj = GetObject(uidAdmin);
  2890. if( 0 == pObj )
  2891. return;
  2892.  
  2893. if (!IsEnabledObject(pObj)) return;
  2894.  
  2895. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  2896. if (pStage == NULL) return;
  2897.  
  2898. // °ü¸®ÀÚ ±ÇÇÑÀ» °¡Áø »ç¶÷ÀÌ ¾Æ´Ï¸é ¿¬°áÀ» ²÷´Â´Ù.
  2899. if (!IsAdminGrade(pObj))
  2900. {
  2901. return;
  2902. }
  2903.  
  2904. MMatchObject* pTargetObj = GetPlayerByName(pszTargetName);
  2905. if (pTargetObj == NULL) return; // ¾îµå¹Î ´ë»óÀ¸·Î ¯ºÒ°¡
  2906.  
  2907. pTargetObj->GetAccountInfo()->m_nUGrade = MMUG_BLOCKED;
  2908.  
  2909. if (m_MatchDBMgr.Ban(pTargetObj->GetAccountInfo()->m_nAID, true)) {
  2910. MMatchObjectCacheBuilder CacheBuilder;
  2911. CacheBuilder.AddObject(pTargetObj);
  2912. MCommand* pCmdCacheUpdate = CacheBuilder.GetResultCmd(MATCHCACHEMODE_REPLACE, this);
  2913. RouteToStage(pStage->GetUID(), pCmdCacheUpdate);
  2914.  
  2915. MCommand* pCmdUIUpdate = CreateCommand(MC_BAN, MUID(0,0));
  2916. pCmdUIUpdate->AddParameter(new MCommandParameterUID(pTargetObj->GetUID()));
  2917. pCmdUIUpdate->AddParameter(new MCommandParameterBool(false));
  2918. RouteToStage(pStage->GetUID(), pCmdUIUpdate);
  2919. }
  2920. }
  2921. //-------------------------------------------------------------------------------------------
  2922. //UNBAN
  2923. //-------------------------------------------------------------------------------------------
  2924. void MMatchServer::Unban(const MUID& uidAdmin, const char* pszTargetName)
  2925. {
  2926. MMatchObject* pObj = GetObject(uidAdmin);
  2927. if( 0 == pObj )
  2928. return;
  2929.  
  2930. if (!IsEnabledObject(pObj)) return;
  2931.  
  2932. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  2933. if (pStage == NULL) return;
  2934.  
  2935. // °ü¸®ÀÚ ±ÇÇÑÀ» °¡Áø »ç¶÷ÀÌ ¾Æ´Ï¸é ¿¬°áÀ» ²÷´Â´Ù.
  2936. if (!IsAdminGrade(pObj))
  2937. {
  2938. return;
  2939. }
  2940.  
  2941. MMatchObject* pTargetObj = GetPlayerByName(pszTargetName);
  2942. if (pTargetObj == NULL) return; // ¾îµå¹Î ´ë»óÀ¸·Î ¯ºÒ°¡
  2943.  
  2944. pTargetObj->GetAccountInfo()->m_nUGrade = MMUG_FREE;
  2945.  
  2946. if (m_MatchDBMgr.Unban(pTargetObj->GetAccountInfo()->m_nAID, true)) {
  2947. MMatchObjectCacheBuilder CacheBuilder;
  2948. CacheBuilder.AddObject(pTargetObj);
  2949. MCommand* pCmdCacheUpdate = CacheBuilder.GetResultCmd(MATCHCACHEMODE_REPLACE, this);
  2950. RouteToStage(pStage->GetUID(), pCmdCacheUpdate);
  2951.  
  2952. MCommand* pCmdUIUpdate = CreateCommand(MC_UNBAN, MUID(0,0));
  2953. pCmdUIUpdate->AddParameter(new MCommandParameterUID(pTargetObj->GetUID()));
  2954. pCmdUIUpdate->AddParameter(new MCommandParameterBool(false));
  2955. RouteToStage(pStage->GetUID(), pCmdUIUpdate);
  2956. }
  2957. }
  2958. //-------------------------------------------------------------------------------------------
  2959.  
  2960. void MMatchServer::OnVoteCallVote(const MUID& uidPlayer, const char* pszDiscuss, const char* pszArg)
  2961. {
  2962. MMatchObject* pObj = GetObject(uidPlayer);
  2963. if (pObj == NULL) return;
  2964.  
  2965. // ¿î¿µÀÚ°¡ °­ÅðÅõÇ¥ÇÏ¸é °­Á¦·Î °­Åð
  2966. if (IsAdminGrade(pObj)) {
  2967. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  2968. if (pStage)
  2969. pStage->KickBanPlayer(pszArg, false);
  2970. return;
  2971. }
  2972.  
  2973. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  2974. if (pStage == NULL) return;
  2975. char szMsg[256];
  2976. // ¿î¿µÀÚ°¡ °°ÀÌ °ÔÀÓÁßÀ̸é ÅõÇ¥ ºÒ°¡´É
  2977. for (MUIDRefCache::iterator itor = pStage->GetObjBegin(); itor != pStage->GetObjEnd(); itor++) {
  2978. MUID uidObj = (MUID)(*itor).first;
  2979. MMatchObject* pPlayer = (MMatchObject*)GetObject(uidObj);
  2980. if ((pPlayer) && (IsAdminGrade(pPlayer)))
  2981. {
  2982. sprintf(szMsg, "%s%d", MTOK_ANNOUNCE_PARAMSTR, MERR_CANNOT_VOTE);
  2983. Announce(uidPlayer, szMsg);
  2984.  
  2985. return;
  2986. }
  2987. }
  2988.  
  2989.  
  2990. if( pObj->WasCallVote() )
  2991. {
  2992. sprintf(szMsg, "%s%d", MTOK_ANNOUNCE_PARAMSTR, MERR_CANNOT_VOTE);
  2993. Announce(uidPlayer, szMsg);
  2994.  
  2995. return;
  2996. }
  2997.  
  2998. // ÅõÇ¥¸¦ Çß´Ù´Â°É Ç¥½ÃÇسõÀ½.
  2999. pObj->SetVoteState( true );
  3000.  
  3001. if (pStage->GetStageType() == MST_LADDER)
  3002. {
  3003. sprintf(szMsg, "%s%d", MTOK_ANNOUNCE_PARAMSTR, MERR_CANNOT_VOTE_LADERGAME);
  3004. Announce(uidPlayer, szMsg);
  3005.  
  3006. return;
  3007. }
  3008.  
  3009. if (pStage->GetRule() && pStage->GetRule()->GetGameType() == MMATCH_GAMETYPE_DUELTOURNAMENT)
  3010. {
  3011. sprintf(szMsg, "%s%d", MTOK_ANNOUNCE_PARAMSTR, MERR_CANNOT_VOTE);
  3012. Announce(uidPlayer, szMsg);
  3013.  
  3014. return;
  3015. }
  3016. #ifdef _VOTESETTING
  3017. // ¹æ ¼³Á¤Áß ÅõÇ¥±â´ÉÀ» °Ë»çÇÔ.
  3018. if( !pStage->GetStageSetting()->bVoteEnabled ) {
  3019. VoteAbort( uidPlayer );
  3020. return;
  3021. }
  3022.  
  3023. // À̹ø °ÔÀÓ¿¡¼­ ÅõÇ¥¸¦ °ÇÀÇÇß´ÂÁö °Ë»ç.
  3024. if( pStage->WasCallVote() ) {
  3025. VoteAbort( uidPlayer );
  3026. return;
  3027. }
  3028. else {
  3029. pStage->SetVoteState( true );
  3030. }
  3031. #endif
  3032.  
  3033. if (pStage->GetVoteMgr()->GetDiscuss())
  3034. {
  3035. sprintf(szMsg, "%s%d", MTOK_ANNOUNCE_PARAMSTR, MERR_VOTE_ALREADY_START);
  3036. Announce(uidPlayer, szMsg);
  3037.  
  3038. return;
  3039. }
  3040.  
  3041. MVoteDiscuss* pDiscuss = MVoteDiscussBuilder::Build(uidPlayer, pStage->GetUID(), pszDiscuss, pszArg);
  3042. if (pDiscuss == NULL) return;
  3043.  
  3044. if (pStage->GetVoteMgr()->CallVote(pDiscuss)) {
  3045. pDiscuss->Vote(uidPlayer, MVOTE_YES); // ¹ßÀÇÀÚ ¹«Á¶°Ç Âù¼º
  3046.  
  3047. MCommand* pCmd = CreateCommand(MC_MATCH_NOTIFY_CALLVOTE, MUID(0,0));
  3048. pCmd->AddParameter(new MCmdParamStr(pszDiscuss));
  3049. pCmd->AddParameter(new MCmdParamStr(pszArg));
  3050. RouteToStage(pStage->GetUID(), pCmd);
  3051. return;
  3052. }
  3053. else
  3054. {
  3055. sprintf(szMsg, "%s%d", MTOK_ANNOUNCE_PARAMSTR, MERR_VOTE_FAILED);
  3056. Announce(uidPlayer, szMsg);
  3057.  
  3058. return;
  3059. }
  3060. }
  3061.  
  3062. void MMatchServer::OnVoteYes(const MUID& uidPlayer)
  3063. {
  3064. MMatchObject* pObj = GetObject(uidPlayer);
  3065. if (pObj == NULL) return;
  3066.  
  3067. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  3068. if (pStage == NULL) return;
  3069.  
  3070. MVoteDiscuss* pDiscuss = pStage->GetVoteMgr()->GetDiscuss();
  3071. if (pDiscuss == NULL) return;
  3072.  
  3073. pDiscuss->Vote(uidPlayer, MVOTE_YES);
  3074. }
  3075.  
  3076. void MMatchServer::OnVoteNo(const MUID& uidPlayer)
  3077. {
  3078. MMatchObject* pObj = GetObject(uidPlayer);
  3079. if (pObj == NULL) return;
  3080.  
  3081. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  3082. if (pStage == NULL) return;
  3083.  
  3084. MVoteDiscuss* pDiscuss = pStage->GetVoteMgr()->GetDiscuss();
  3085. if (pDiscuss == NULL) return;
  3086.  
  3087. pDiscuss->Vote(uidPlayer, MVOTE_NO);
  3088. }
  3089.  
  3090. void MMatchServer::VoteAbort( const MUID& uidPlayer )
  3091. {
  3092. #ifndef MERR_CANNOT_VOTE
  3093. #define MERR_CANNOT_VOTE 120000
  3094. #endif
  3095.  
  3096. MMatchObject* pObj = GetObject( uidPlayer );
  3097. if( 0 == pObj )
  3098. return;
  3099.  
  3100. MCommand* pCmd = CreateCommand( MC_MATCH_VOTE_RESPONSE, MUID(0, 0) );
  3101. if( 0 == pCmd )
  3102. return;
  3103.  
  3104. pCmd->AddParameter( new MCommandParameterInt(MERR_CANNOT_VOTE) );
  3105. RouteToListener( pObj, pCmd );
  3106. }
  3107.  
  3108.  
  3109.  
  3110. void MMatchServer::OnEventChangeMaster(const MUID& uidAdmin)
  3111. {
  3112. MMatchObject* pObj = GetObject(uidAdmin);
  3113. if( 0 == pObj )
  3114. return;
  3115.  
  3116. if (!IsEnabledObject(pObj)) return;
  3117.  
  3118. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  3119. if (pStage == NULL) return;
  3120.  
  3121. // °ü¸®ÀÚ ±ÇÇÑÀ» °¡Áø »ç¶÷ÀÌ ¾Æ´Ï¸é ¿¬°áÀ» ²÷´Â´Ù.
  3122. if (!IsAdminGrade(pObj))
  3123. {
  3124. // DisconnectObject(uidAdmin);
  3125. return;
  3126. }
  3127.  
  3128. if (pStage->GetMasterUID() == uidAdmin)
  3129. return;
  3130.  
  3131. pStage->SetMasterUID(uidAdmin);
  3132. StageMaster(pStage->GetUID());
  3133. }
  3134.  
  3135. void MMatchServer::OnEventChangePassword(const MUID& uidAdmin, const char* pszPassword)
  3136. {
  3137. MMatchObject* pObj = GetObject(uidAdmin);
  3138. if( 0 == pObj )
  3139. return;
  3140.  
  3141. if (!IsEnabledObject(pObj)) return;
  3142.  
  3143. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  3144. if (pStage == NULL) return;
  3145.  
  3146. // °ü¸®ÀÚ ±ÇÇÑÀ» °¡Áø »ç¶÷ÀÌ ¾Æ´Ï¸é ¿¬°áÀ» ²÷´Â´Ù.
  3147. if (!IsAdminGrade(pObj))
  3148. {
  3149. // DisconnectObject(uidAdmin);
  3150. return;
  3151. }
  3152.  
  3153. pStage->SetPassword(pszPassword);
  3154. pStage->SetPrivate(true);
  3155. }
  3156.  
  3157. void MMatchServer::OnEventRequestJjang(const MUID& uidAdmin, const char* pszTargetName)
  3158. {
  3159. MMatchObject* pObj = GetObject(uidAdmin);
  3160. if( 0 == pObj )
  3161. return;
  3162.  
  3163. if (!IsEnabledObject(pObj)) return;
  3164.  
  3165. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  3166. if (pStage == NULL) return;
  3167.  
  3168. // °ü¸®ÀÚ ±ÇÇÑÀ» °¡Áø »ç¶÷ÀÌ ¾Æ´Ï¸é ¹«½Ã
  3169. if (!IsAdminGrade(pObj))
  3170. {
  3171. return;
  3172. }
  3173.  
  3174. MMatchObject* pTargetObj = GetPlayerByName(pszTargetName);
  3175. if (pTargetObj == NULL) return;
  3176. if (IsAdminGrade(pTargetObj)) return; // ¾îµå¹Î ´ë»óÀ¸·Î ¯ºÒ°¡
  3177. if (MMUG_STAR == pTargetObj->GetAccountInfo()->m_nUGrade) return; // ÀÌ¹Ì Â¯
  3178.  
  3179. pTargetObj->GetAccountInfo()->m_nUGrade = MMUG_STAR;
  3180.  
  3181. if (m_MatchDBMgr.EventJjangUpdate(pTargetObj->GetAccountInfo()->m_nAID, true)) {
  3182. MMatchObjectCacheBuilder CacheBuilder;
  3183. CacheBuilder.AddObject(pTargetObj);
  3184. MCommand* pCmdCacheUpdate = CacheBuilder.GetResultCmd(MATCHCACHEMODE_REPLACE, this);
  3185. RouteToStage(pStage->GetUID(), pCmdCacheUpdate);
  3186.  
  3187. MCommand* pCmdUIUpdate = CreateCommand(MC_EVENT_UPDATE_JJANG, MUID(0,0));
  3188. pCmdUIUpdate->AddParameter(new MCommandParameterUID(pTargetObj->GetUID()));
  3189. pCmdUIUpdate->AddParameter(new MCommandParameterBool(true));
  3190. RouteToStage(pStage->GetUID(), pCmdUIUpdate);
  3191. }
  3192. }
  3193.  
  3194. void MMatchServer::OnEventRemoveJjang(const MUID& uidAdmin, const char* pszTargetName)
  3195. {
  3196. MMatchObject* pObj = GetObject(uidAdmin);
  3197. if( 0 == pObj )
  3198. return;
  3199.  
  3200. if (!IsEnabledObject(pObj)) return;
  3201.  
  3202. MMatchStage* pStage = FindStage(pObj->GetStageUID());
  3203. if (pStage == NULL) return;
  3204.  
  3205. // °ü¸®ÀÚ ±ÇÇÑÀ» °¡Áø »ç¶÷ÀÌ ¾Æ´Ï¸é ¿¬°áÀ» ²÷´Â´Ù.
  3206. if (!IsAdminGrade(pObj))
  3207. {
  3208. return;
  3209. }
  3210.  
  3211. MMatchObject* pTargetObj = GetPlayerByName(pszTargetName);
  3212. if (pTargetObj == NULL) return; // ¾îµå¹Î ´ë»óÀ¸·Î ¯ºÒ°¡
  3213.  
  3214. pTargetObj->GetAccountInfo()->m_nUGrade = MMUG_FREE;
  3215.  
  3216. if (m_MatchDBMgr.EventJjangUpdate(pTargetObj->GetAccountInfo()->m_nAID, false)) {
  3217. MMatchObjectCacheBuilder CacheBuilder;
  3218. CacheBuilder.AddObject(pTargetObj);
  3219. MCommand* pCmdCacheUpdate = CacheBuilder.GetResultCmd(MATCHCACHEMODE_REPLACE, this);
  3220. RouteToStage(pStage->GetUID(), pCmdCacheUpdate);
  3221.  
  3222. MCommand* pCmdUIUpdate = CreateCommand(MC_EVENT_UPDATE_JJANG, MUID(0,0));
  3223. pCmdUIUpdate->AddParameter(new MCommandParameterUID(pTargetObj->GetUID()));
  3224. pCmdUIUpdate->AddParameter(new MCommandParameterBool(false));
  3225. RouteToStage(pStage->GetUID(), pCmdUIUpdate);
  3226. }
  3227. }
  3228.  
  3229.  
  3230. void MMatchServer::OnStageGo(const MUID& uidPlayer, unsigned int nRoomNo)
  3231. {
  3232. MMatchObject* pChar = GetObject(uidPlayer);
  3233. if( 0 == pChar ) return;
  3234. if (!IsEnabledObject(pChar)) return;
  3235. if (pChar->GetPlace() != MMP_LOBBY) return;
  3236. MMatchChannel* pChannel = FindChannel(pChar->GetChannelUID());
  3237. if (pChannel == NULL) return;
  3238.  
  3239. MMatchStage* pStage = pChannel->GetStage(nRoomNo-1);
  3240. if (pStage) {
  3241. MCommand* pNew = CreateCommand(MC_MATCH_REQUEST_STAGE_JOIN, GetUID());
  3242. pNew->SetSenderUID(uidPlayer); // Ç÷¹À̾ º¸³½ ¸Þ½ÃÁöÀÎ °Íó·³ À§Àå
  3243. pNew->AddParameter(new MCommandParameterUID(uidPlayer));
  3244. pNew->AddParameter(new MCommandParameterUID(pStage->GetUID()));
  3245. Post(pNew);
  3246. }
  3247. }
  3248.  
  3249.  
  3250.  
  3251. void MMatchServer::OnDuelQueueInfo(const MUID& uidStage, const MTD_DuelQueueInfo& QueueInfo)
  3252. {
  3253. MCommand* pCmd = CreateCommand(MC_MATCH_DUEL_QUEUEINFO, MUID(0,0));
  3254. pCmd->AddParameter(new MCmdParamBlob(&QueueInfo, sizeof(MTD_DuelQueueInfo)));
  3255. RouteToBattle(uidStage, pCmd);
  3256. }
  3257.  
  3258.  
  3259. void MMatchServer::OnQuestSendPing(const MUID& uidStage, unsigned long int t)
  3260. {
  3261. MCommand* pCmd = CreateCommand(MC_QUEST_PING, MUID(0,0));
  3262. pCmd->AddParameter(new MCommandParameterUInt(t));
  3263. RouteToBattle(uidStage, pCmd);
  3264. }
  3265.  
  3266. void MMatchServer::SaveGameLog(const MUID& uidStage)
  3267. {
  3268. MMatchStage* pStage = FindStage(uidStage);
  3269. if (pStage == NULL) return;
  3270.  
  3271. int nMapID = pStage->GetStageSetting()->GetMapIndex();
  3272. int nGameType = (int)pStage->GetStageSetting()->GetGameType();
  3273.  
  3274.  
  3275.  
  3276. // test ¸ÊµîÀº ·Î±× ³²±âÁö ¾Ê´Â´Ù.
  3277. if ( (MGetMapDescMgr()->MIsCorrectMap(nMapID)) && (MGetGameTypeMgr()->IsCorrectGameType(nGameType)) )
  3278. {
  3279. if (pStage->GetStageType() != MST_LADDER)
  3280. {
  3281. MMatchObject* pMaster = GetObject(pStage->GetMasterUID());
  3282.  
  3283. MAsyncDBJob_InsertGameLog* pJob = new MAsyncDBJob_InsertGameLog(uidStage);
  3284. pJob->Input(pMaster == NULL ? 0 : pMaster->GetCharInfo()->m_nCID,
  3285. MGetMapDescMgr()->GetMapName(nMapID),
  3286. MGetGameTypeMgr()->GetInfo(MMATCH_GAMETYPE(nGameType))->szGameTypeStr);
  3287.  
  3288. PostAsyncJob(pJob);
  3289. }
  3290. }
  3291.  
  3292. }
  3293.  
  3294. void MMatchServer::SaveGamePlayerLog(MMatchObject* pObj, unsigned int nStageID)
  3295. {
  3296. if( pObj == NULL ) return;
  3297. if( nStageID == 0 ) return;
  3298. if( pObj->GetCharInfo() == NULL ) return;
  3299.  
  3300.  
  3301. }
  3302.  
  3303.  
  3304. void MMatchServer::OnPeerChat(const MUID& uidChar, const int nTeam, const char* szMessage)
  3305. {
  3306. MMatchObject* pObject = GetObject(uidChar);
  3307. if (!pObject) return;
  3308.  
  3309. MMatchStage* pStage = FindStage(pObject->GetStageUID());
  3310. if (!pStage || pStage->GetState() < STAGE_STATE_COUNTDOWN) return;
  3311. /*
  3312. * TODO: FILTER AND LOG CHAT.
  3313. */
  3314. MCommand* pCmd = CreateCommand(MC_PEER_CHAT, MUID());
  3315. pCmd->AddParameter(new MCommandParameterInt(nTeam));
  3316. pCmd->AddParameter(new MCommandParameterString(szMessage));
  3317. pCmd->AddParameter(new MCommandParameterUID(uidChar));
  3318. RouteToStage(pStage->GetUID(), pCmd);
  3319. }
  3320. void MMatchServer::OnAdminSBTest(const MUID& uidComm, char* pszTargetName)
  3321. {
  3322. MMatchObject* pObj = GetPlayerByCommUID( uidComm );
  3323.  
  3324. if( pObj == NULL ) return;
  3325. if( pObj->GetCharInfo() == NULL ) return;
  3326. if( pObj->GetStageUID().IsInvalid() ) return;
  3327.  
  3328. MMatchObject* pTargetObj = GetPlayerByName( pszTargetName );
  3329.  
  3330. if( pTargetObj == NULL ) return;
  3331. if( pTargetObj->GetCharInfo() == NULL ) return;
  3332. if( pTargetObj->GetStageUID().IsInvalid() ) return;
  3333.  
  3334. if( pObj->GetStageUID() != pTargetObj->GetStageUID() )
  3335. return;
  3336.  
  3337.  
  3338. if( IsAdminGrade(pObj) == false && pObj->GetAccountInfo()->m_nUGrade != MMUG_ADMIN ) //Which admins have access 26/10/2015
  3339. return;
  3340.  
  3341. if( pObj->GetPlace() != MMP_BATTLE || pTargetObj->GetPlace() != MMP_BATTLE )
  3342. return;
  3343.  
  3344. MCommand* pCmd = CreateCommand(MC_ADMIN_SBTEST, MUID(0,0));
  3345. pCmd->AddParameter(new MCmdParamUID(pObj->GetUID()));
  3346. pCmd->AddParameter(new MCmdParamStr(pTargetObj->GetName()));
  3347. RouteToListener(pTargetObj, pCmd);
  3348.  
  3349. char szBuf[128];
  3350. sprintf( szBuf, "Tested SB for '%s'.", pszTargetName );
  3351.  
  3352. Announce( pObj, szBuf );
  3353. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement