Files
Leviathan/Client/Game/game/Main/SGameVM.cpp
T
2026-06-01 12:46:52 +02:00

4624 lines
156 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "stdafx.h"
#include <network/IConnection.h>
#include <toolkit/IQueue.h>
#include "SGameVM.h"
#include "K3DTypes.h"
#include "KObject.h"
#include "SGameObject.h"
#include "GameDefine.h"
#include "SSkillDB.h"
#include "SNetMessage.h"
#include "SNetMessageBill.h"
#include "SGameMessage.h"
//#include "SGameMessageUI.h"
#include <WindowsX.h>
#include "SGameManager.h"
#include "SGame.h"
//#include "Util.h"
#include "SkillBase.h"
#include <toolkit/nsl.h>
#include <toolkit/nsluni.h>
#include <toolkit/nslreg.h>
#include "SQuestDB.h"
#include "SSkillDB.h"
#include "SItemDB.h"
#include "SMonsterDB.h"
#include "SStringDB.h"
#include <toolkit/XStringUtil.h>
#include "SQuestMgr.h"
#include "ErrorCode/ErrorCode.h"
#include "SChatType.h"
#include <toolkit/XEnv.h>
#include "SDebug_Util.h"
#include <toolkit/bits_scramble.h>
#include "SUISysMsgDefine.h"
#include "CInput.h"
#include "SLog.h"
// 2010.04.22 - prodongi
#include "SSelectedAvatarInfo.h"
/// 2010.11.10 - prodongi
#include "SGameLobbyDefine.h"
#include "KTextRender.h"
#include "ElementParser\\SElementParser.h" /// 2012.05.11 - prodongi
#ifdef _HACK_SHIELD_
#include <hack_shield/HShield.h>
#endif
#ifdef _USE_XTRAP_MODULE
#include <xtrap/090628_513_Xtrap_C_Interface.h>
#endif
#ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL 0x020A
#define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam))
#define WM_LMOUSE_CLICK S_USER+100
#define WM_RMOUSE_CLICK S_USER+101
#endif
extern HWND g_hWnd;
extern bool g_bUserCamMode;
/// 2010.11.10 - prodongi
//#ifdef _DEV
//extern bool g_bDebugMode;
//#endif
extern FILE* g_pFLog;
extern std::string g_strModulePath; // sonador 7.0.13 친구 추가 오류 수정( 멀티바이트 문자열 관련 오류 )
//서버와의 접속이 종료 되었습니다. 메시지 수정
//2009-02-24: hunee
char g_disconnectId = -1;
namespace
{
const int c_Belt_Slot_Cnt = 8;
}
std::string ParseQuestText( const char *szQuestString, int nQuestCode );
void ParseScriptText( std::string & strText );
/// 2011.08.19 퀘스트 목표 텍스트 리스트를 뽑는다 - prodongi
void extractQuestTarget(std::vector<std::string>& questTargetList, int questCode);
int getStringToInt(LPCSTR lpszName, std::map<std::string, int>& mapInfo)
{
std::map<std::string, int>::iterator it = mapInfo.find( std::string ( lpszName ) );
if( it == mapInfo.end() )
return (-1);
return it->second;
}
// multibyte to multibyte string vector
void MsgSplit( const char* szMsg, std::vector<std::string>& vecText, const wchar_t* lpDelimiter, bool bProcSpecialCharacter=false )
{
/*
//유니 코드 변환 후 split
int nMsgLen = strlen(szMsg);
std::vector< std::wstring > toklist;
DWORD CodePage = GetCodePageFromLang((LANGID)GetSystemDefaultLangID()); //이것을 삭제할때는 위의 #include "CInput.h"도 삭제할 것
wchar_t* pwtempCmpStr= new wchar_t[nMsgLen+1];
memset( pwtempCmpStr, 0, sizeof(wchar_t)*(nMsgLen+1) );
MultiByteToWideChar(CodePage, 0, szMsg, strlen(szMsg), pwtempCmpStr, nMsgLen+1);
toklist = nsl::split( pwtempCmpStr, lpDelimiter, bProcSpecialCharacter );
delete [] pwtempCmpStr;
#ifdef _DEBUG
int nCount = toklist.size();
#endif
char szBuf[1024];
for( unsigned int i(0); toklist.size()>i; i++ )
{
memset( szBuf, 0, sizeof(szBuf) );
WideCharToMultiByte( CodePage, 0, toklist[i].c_str(), toklist[i].length(), szBuf, 1024, 0, 0 );
vecText.push_back( szBuf );
}
*/
/// 2011.11.23 - prodongi
std::vector< std::wstring > toklist;
std::wstring wstr;
safeM2W(szMsg, lpDelimiter, wstr);
/*
//유코드 변환 과정에서 윈도우 로컬 관련 문제점을 iconv로 수정
//2009-06-24: hunee
std::vector< std::wstring > toklist;
std::wstring wstr = nsl::uni::conv(szMsg);
*/
toklist = nsl::split(wstr.c_str(), lpDelimiter, bProcSpecialCharacter);
#ifdef _DEBUG
int nCount = toklist.size();
#endif
for( unsigned int i(0); toklist.size()>i; i++ )
{
std::string buff = nsl::uni::conv(toklist[i].c_str());
vecText.push_back(buff.c_str());
}
toklist.clear();
}
// sonador 7.0.13 친구 추가 오류 수정( 멀티바이트 문자열 관련 오류 )
// unicode to unicode string vector
void MsgSplit( const wchar_t* szMsg, std::vector<std::wstring>& vecText, const wchar_t* lpDelimiter, bool bProcSpecialCharacter=false )
{
vecText = nsl::split( szMsg, lpDelimiter, bProcSpecialCharacter );
}
// multibyte to multibyte string vector
void MsgSplit_Ex( const char* szMsg, std::vector<std::string>& vecText, const wchar_t* lpDelimiter, bool bProcSpecialCharacter=false )
{
/// 2011.11.23 - prodongi
std::vector< std::wstring > toklist;
std::wstring wstr;
safeM2W(szMsg, lpDelimiter, wstr);
/*
//유코드 변환 과정에서 윈도우 로컬 관련 문제점을 iconv로 수정
//2009-06-24: hunee
std::vector< std::wstring > toklist;
std::wstring wstr = nsl::uni::conv(szMsg);
*/
toklist = nsl::split_Ex(wstr.c_str(), lpDelimiter, bProcSpecialCharacter);
#ifdef _DEBUG
int nCount = toklist.size();
#endif
for( unsigned int i(0); toklist.size()>i; i++ )
{
std::string buff = nsl::uni::conv(toklist[i].c_str());
vecText.push_back(buff.c_str());
}
toklist.clear();
}
SGameVM::SGameVM()
{
Init();
}
SGameVM::~SGameVM()
{
Destroy();
}
void SGameVM::Init()
{
m_dwAttackTime = 0;
m_pGameManager = NULL;
m_dwTime = 0;
struct PROPERTY_INFO
{
int dwFlag;
std::string sName;
};
PROPERTY_INFO PROPERTY_ARRAY[] =
{
{SMSG_PROPERTY::PROPERTY_HP, "hp" },
{SMSG_PROPERTY::PROPERTY_MP, "mp" },
{SMSG_PROPERTY::PROPERTY_MAX_HP, "max_hp" },
{SMSG_PROPERTY::PROPERTY_MAX_MP, "max_mp" },
{SMSG_PROPERTY::PROPERTY_LOGIN, "login" },
{SMSG_PROPERTY::PROPERTY_ACCOUNT, "account" },
{SMSG_PROPERTY::PROPERTY_NAME, "name" },
{SMSG_PROPERTY::PROPERTY_GOLD, "gold" },
{SMSG_PROPERTY::PROPERTY_EXP, "exp" },
{SMSG_PROPERTY::PROPERTY_JP, "jp" },
{SMSG_PROPERTY::PROPERTY_JOB_LEVEL, "job_level" },
{SMSG_PROPERTY::PROPERTY_JOB, "job" },
{SMSG_PROPERTY::PROPERTY_JOB_0, "job_0" },
{SMSG_PROPERTY::PROPERTY_JLV_0, "jlv_0" },
{SMSG_PROPERTY::PROPERTY_JOB_1, "job_1" },
{SMSG_PROPERTY::PROPERTY_JLV_1, "jlv_1" },
{SMSG_PROPERTY::PROPERTY_JOB_2, "job_2" },
{SMSG_PROPERTY::PROPERTY_JLV_2, "jlv_2" },
{SMSG_PROPERTY::PROPERTY_LEVEL, "level" },
{SMSG_PROPERTY::PROPERTY_WEIGHT, "weight" },
{SMSG_PROPERTY::PROPERTY_STR, "str" },
{SMSG_PROPERTY::PROPERTY_AGI, "agi" },
{SMSG_PROPERTY::PROPERTY_DEX, "dex" },
{SMSG_PROPERTY::PROPERTY_INT, "int" },
{SMSG_PROPERTY::PROPERTY_LUCK, "luck" },
{SMSG_PROPERTY::PROPERTY_VITAL, "vital" },
{SMSG_PROPERTY::PROPERTY_MENTAL, "mental" },
{SMSG_PROPERTY::PROPERTY_PERMISSION, "permission" },
{SMSG_PROPERTY::PROPERTY_PK_COUNT, "pk_count" },
{SMSG_PROPERTY::PROPERTY_DK_COUNT, "dk_count" },
{SMSG_PROPERTY::PROPERTY_RACE, "race" },
{SMSG_PROPERTY::PROPERTY_CHARISMA, "charisma" },
{SMSG_PROPERTY::PROPERTY_MORAL, "immoral" },
{SMSG_PROPERTY::PROPERTY_LOGIN_TIME, "login_time" },
{SMSG_PROPERTY::PROPERTY_SEX, "sex" },
{SMSG_PROPERTY::PROPERTY_X, "x" },
{SMSG_PROPERTY::PROPERTY_Y, "y" },
{SMSG_PROPERTY::PROPERTY_SPEED, "speed" },
{SMSG_PROPERTY::PROPERTY_SP, "sp" },
{SMSG_PROPERTY::PROPERTY_STORAGE_GOLD, "storage_gold"},
{SMSG_PROPERTY::PROPERTY_STAMINA, "stamina" },
{SMSG_PROPERTY::PROPERTY_CHAOS, "chaos" },
{SMSG_PROPERTY::PROPERTY_MAX_CHAOS, "max_chaos" },
{SMSG_PROPERTY::PROPERTY_MAX_STAMINA, "max_stamina"},
{SMSG_PROPERTY::PROPERTY_CHANNEL, "channel" },
{SMSG_PROPERTY::PROPERTY_STAMINA_REGEN_RATE, "stamina_regen" },
{SMSG_PROPERTY::PROPERTY_PLAYTIME, "playtime" },
{SMSG_PROPERTY::PROPERTY_PLAYTIME_LIMIT1, "playtime_limit1" },
{SMSG_PROPERTY::PROPERTY_PLAYTIME_LIMIT2, "playtime_limit2" },
{SMSG_PROPERTY::PROPERTY_HUNTAHOLIC_ENT, "huntaholic_ent" },
{SMSG_PROPERTY::PROPERTY_ETHEREAL_STONE_DURABILITY, "ethereal_stone" }, // 에테리얼스톤. bintitle. 2010.08.25.
{SMSG_PROPERTY::PROPERTY_HUNTAHOLICPOINT, "huntaholicpoint" }, // 헌터홀릭포인트. bintitle. 2010.09.03.
{SMSG_PROPERTY::PROPERTY_TP, "tp" }, /// 2011.03.28 특성 포인트 - prodongi
{SMSG_PROPERTY::PROPERTY_AP, "ap" }, /// 2012.06.08 아레나 포이트 - prodongi
{SMSG_PROPERTY::PROPERTY_ALIAS, "alias" }, /// 2012.07.20 아레나 별칭 - prodongi
{SMSG_PROPERTY::PROPERTY_CLIENT_INFO, "client_info"},
{SMSG_PROPERTY::PROPERTY_QUICK_SLOT, "quick_slot"},
{SMSG_PROPERTY::PROPERTY_CURRENT_KEY, "current_key"},
{SMSG_PROPERTY::PROPERTY_SAVED_KEY, "saved_key"},
};
int nCount = _countof(PROPERTY_ARRAY);
for(int i = 0; i < nCount; ++i)
MAP_PROPERTY.insert( std::make_pair( PROPERTY_ARRAY[i].sName, PROPERTY_ARRAY[i].dwFlag) );
m_hNetStr.add( 9998, "TM_COMMON" );
m_hNetStr.add( 9999, "TM_NONE" );
m_hNetStr.add( 51, "TM_CS_VERSION" ); // 2012. 8. 27 - marine 아이디 변경
m_hNetStr.add( 0, "TM_SC_RESULT" );
m_hNetStr.add( 1, "TM_CS_LOGIN" );
m_hNetStr.add( 4, "TM_SC_LOGIN_RESULT" );
m_hNetStr.add( 2, "TM_TIMESYNC" );
m_hNetStr.add( 3, "TM_SC_ENTER" );
m_hNetStr.add( 13, "TM_CS_QUERY" );
m_hNetStr.add( 5, "TM_CS_MOVE_REQUEST" );
m_hNetStr.add( 6, "TM_SC_MOVE_ACK" );
m_hNetStr.add( 7, "TM_CS_REGION_UPDATE" );
m_hNetStr.add( 11, "TM_SC_REGION_ACK" );
m_hNetStr.add( 8, "TM_SC_MOVE" );
m_hNetStr.add( 9, "TM_SC_LEAVE" );
m_hNetStr.add( 10, "TM_SC_SET_TIME" );
m_hNetStr.add( 12, "TM_SC_WARP" );
m_hNetStr.add( 15, "TM_CS_ENTER_EVENT_AREA");
m_hNetStr.add( 16, "TM_CS_LEAVE_EVENT_AREA");
m_hNetStr.add( 20, "TM_CS_CHAT_REQUEST" );
m_hNetStr.add( 21, "TM_SC_CHAT_LOCAL" );
m_hNetStr.add( 22, "TM_SC_CHAT" );
m_hNetStr.add( 23, "TM_CS_RETURN_LOBBY" ); //캐릭터 선택 로비로 이동
m_hNetStr.add( 24, "TM_SC_CHAT_RESULT" ); //채팅 결과
m_hNetStr.add( 25, "TM_CS_REQUEST_RETURN_LOBBY");
m_hNetStr.add( 26, "TM_CS_REQUEST_LOGOUT" );
m_hNetStr.add( 27, "TM_CS_LOGOUT" );
m_hNetStr.add( 30, "TM_SC_CHANGE_NAME" ); //이름 변경
m_hNetStr.add( 31, "TM_CS_CHANGE_ALIAS" );
m_hNetStr.add( 53, "TM_SC_ANTI_HACK" ); //핵쉴드
m_hNetStr.add( 54, "TM_CS_ANTI_HACK" ); //핵쉴드
m_hNetStr.add( 55, "TM_SC_GAME_GUARD_AUTH_QUERY");
m_hNetStr.add( 56, "TM_CS_GAME_GUARD_AUTH_ANSWER");
m_hNetStr.add( 57, "TM_CS_CHECK_ILLEGAL_USER");
m_hNetStr.add( 58, "TM_SC_XTRAP_CHECK" ); //XTrap
m_hNetStr.add( 59, "TM_CS_XTRAP_CHECK" ); //XTrap
m_hNetStr.add( 100, "TM_CS_ATTACK_REQUEST" );
m_hNetStr.add( 101, "TM_SC_ATTACK_EVENT" );
m_hNetStr.add( 102, "TM_SC_CANT_ATTACK" );
m_hNetStr.add( 103, "TM_SC_DOUBLE_WEAPON_ATTACK_EVENT");
m_hNetStr.add( 150, "TM_CS_CANCEL_ACTION" );
m_hNetStr.add( 200, "TM_CS_PUTON_ITEM" ); // 아이템 장비 요청
m_hNetStr.add( 201, "TM_CS_PUTOFF_ITEM" ); // 아이템 장비해제 요청
m_hNetStr.add( 202, "TM_SC_WEAR_INFO" ); // 아이템 장비 정보 - 첫 enter 시, 혹은 장비 변경시 방송됨
m_hNetStr.add( 203, "TM_CS_DROP_ITEM" ); // 아이템 버림 요청
m_hNetStr.add( 204, "TM_CS_TAKE_ITEM" ); // 아이템 줍기 요청
m_hNetStr.add( 205, "TM_SC_DROP_RESULT" ); // 아이템 버림 결과
m_hNetStr.add( 207, "TM_SC_INVENTORY" ); // 인벤 내용
m_hNetStr.add( 208, "TM_CS_ERASE_ITEM" ); // 아이템 파기
m_hNetStr.add( 210, "TM_SC_TAKE_ITEM_RESULT"); // 아이텝 줍기
m_hNetStr.add( 211, "TM_SC_OPEN_STORAGE" ); // 창고를 여셈~
m_hNetStr.add( 212, "TM_CS_STORAGE" ); // 창고 아이템 이동
m_hNetStr.add( 213, "TM_SC_GET_CHAOS" ); // 혼돈 얻음
m_hNetStr.add( 214, "TM_CS_PUTON_CARD" ); // 벨트 슬롯에 아이템 장착
m_hNetStr.add( 215, "TM_CS_PUTOFF_CARD" ); // 벨트 슬롯에 아이템 장착
m_hNetStr.add( 216, "TM_SC_BELT_SLOT_INFO" ); // 벨트 슬롯 정보
m_hNetStr.add( 217, "TM_SC_ITEM_COOL_TIME" ); // 아이템 쿨타임
m_hNetStr.add( 218, "TM_CS_CHANGE_ITEM_POSITION" );
m_hNetStr.add( 219, "TM_CS_ARRANGE_ITEM" );
// 2010.05.19 HIDE_EQUIP_INFO - prodongi
m_hNetStr.add( 221, "TM_CS_HIDE_EQUIP_INFO" ); // 장비 숨기기 정보 변경 요청
m_hNetStr.add( 222, "TM_SC_HIDE_EQUIP_INFO" ); // 장비 숨기기 정보 방송
m_hNetStr.add( 223, "TM_CS_SWAP_EQUIP" );
m_hNetStr.add( 224, "TM_SC_SKIN_INFO" ); // 피부색 변경
m_hNetStr.add( 240, "TM_SC_NPC_TRADE_INFO" );
m_hNetStr.add( 250, "TM_SC_MARKET" ); // 상점 아이템 리스트
m_hNetStr.add( 251, "TM_CS_BUY_ITEM" ); // 아이템 구입
m_hNetStr.add( 252, "TM_CS_SELL_ITEM" ); // 아이템 판매
m_hNetStr.add( 253, "TM_CS_USE_ITEM" ); // 아이템 사용
m_hNetStr.add( 254, "TM_SC_DESTROY_ITEM" ); // 아이템 제거
m_hNetStr.add( 255, "TM_SC_UPDATE_ITEM_COUNT"); // 아이템 제거
m_hNetStr.add( 256, "TM_CS_MIX" ); // 아이템 조합
m_hNetStr.add( 257, "TM_SC_MIX_RESULT" ); // 아이템 조합 결과
m_hNetStr.add( 263, "TM_CS_TRANSMIT_ETHEREAL_DURABILITY"); /// 아이템 수리
m_hNetStr.add( 264, "TM_CS_TRANSMIT_ETHEREAL_DURABILITY_TO_EQUIPMENT"); /// 아이템 전체 수리
m_hNetStr.add( 280, "TM_TRADE" ); // 트레이드
m_hNetStr.add( 281, "TM_CS_PUTON_ITEM_SET" ); // 풀셋 아이템 장착 요청
m_hNetStr.add( 282, "TM_SC_ITEM_DROP_INFO" ); // 어떤 몹이 어떤 아템 떨어트리는건지 정보
m_hNetStr.add( 283, "TM_SC_USE_ITEM_RESULT" ); // 아이템 사용 결과
m_hNetStr.add( 284, "TM_CS_BIND_SKILLCARD" );
m_hNetStr.add( 285, "TM_CS_UNBIND_SKILLCARD" );
m_hNetStr.add( 286, "TM_SC_SKILLCARD_INFO" );
m_hNetStr.add( 287, "TM_SC_ITEM_WEAR_INFO" ); // 아이템 장비 정보 - 첫 enter 시, 혹은 장비 변경시 방송됨
m_hNetStr.add( 301, "TM_SC_ADD_SUMMON_INFO" ); // 편성된 소환수 정보 추가
m_hNetStr.add( 302, "TM_SC_REMOVE_SUMMON_INFO"); // 편성된 소환수 정보 제거
m_hNetStr.add( 303, "TM_EQUIP_SUMMON" ); // 소환수 편성 정보
m_hNetStr.add( 304, "TM_CS_SUMMON" ); // 소환/역소환 요청
m_hNetStr.add( 305, "TM_SC_UNSUMMON" ); // 역소환 통지
m_hNetStr.add( 306, "TM_SC_UNSUMMON_NOTICE" ); // 역소환 알림( x시간 후에 역소환 됨 )
m_hNetStr.add( 307, "TM_SC_SUMMON_EVOLUTION" ); // 크리처 진화
m_hNetStr.add( 310, "TM_SC_TAMING_INFO" ); // 테이밍 정보
m_hNetStr.add( 320, "TM_SC_MOUNT_SUMMON" ); // 올라 타기
m_hNetStr.add( 321, "TM_SC_UNMOUNT_SUMMON" ); // 내려오기
m_hNetStr.add( 322, "TM_SC_SHOW_SUMMON_NAME_CHANGE" );
m_hNetStr.add( 323, "TM_CS_CHANGE_SUMMON_NAME" );
m_hNetStr.add( 324, "TM_CS_GET_SUMMON_SETUP_INFO" );
m_hNetStr.add( 350, "TM_SC_UNSUMMON_PET" );
m_hNetStr.add( 351, "TM_SC_ADD_PET_INFO" );
m_hNetStr.add( 352, "TM_SC_REMOVE_PET_INFO" );
m_hNetStr.add( 353, "TM_SC_SHOW_SET_PET_NAME" );
m_hNetStr.add( 354, "TM_CS_SET_PET_NAME" );
m_hNetStr.add( 400, "TM_CS_SKILL" );
m_hNetStr.add( 401, "TM_SC_SKILL" );
m_hNetStr.add( 402, "TM_CS_LEARN_SKILL" );
m_hNetStr.add( 403, "TM_SC_SKILL_LIST" );
m_hNetStr.add( 408, "" );
m_hNetStr.add( 410, "TM_CS_JOB_LEVEL_UP" );
m_hNetStr.add( 406, "TM_STATE_DAMAGE" );
m_hNetStr.add( 407, "TM_SC_AURA" );
m_hNetStr.add(451, "TM_SC_SKILL_LEVEL_LIST");
m_hNetStr.add(452, "TM_CS_SUMMON_CARD_SKILL_LIST");
m_hNetStr.add( 500, "TM_SC_STATUS_CHANGE" );
m_hNetStr.add( 503, "TM_CS_UPDATE" ); // HP/MP 채우는거나 기타등등. 30초가량마다 한번씩 다오~
m_hNetStr.add( 504, "TM_SC_DEAD" ); // 사망~
m_hNetStr.add( 505, "TM_SC_STATE" ); // 상태이상 메세지
m_hNetStr.add( 507, "TM_SC_PROPERTY" ); // 프로퍼티
m_hNetStr.add( 508, "TM_CS_SET_PROPERTY" ); // 프로퍼티
m_hNetStr.add( 509, "TM_SC_HPMP" );
m_hNetStr.add( 510, "TM_SC_REGEN_INFO" );
m_hNetStr.add( 515, "TM_SC_ENERGY" );
m_hNetStr.add( 516, "TM_SC_REGEN_HPMP" );
m_hNetStr.add( 511, "TM_CS_TARGETING" ); // 타겟의 상태 이상 정보 요청
m_hNetStr.add( 512, "TM_SC_TARGET" );
m_hNetStr.add( 513, "TM_CS_RESURRECTION" );
m_hNetStr.add( 514, "TM_SC_SP" );
m_hNetStr.add( 517, "TM_CS_MONSTER_RECOGNIZE" );
m_hNetStr.add( 550, "TM_CS_GET_REGION_INFO" );
m_hNetStr.add( 600, "TM_SC_QUEST_LIST" );
m_hNetStr.add( 601, "TM_SC_QUEST_STATUS" );
m_hNetStr.add( 602, "TM_SC_QUEST_INFOMATION" );
m_hNetStr.add( 603, "TM_CS_DROP_QUEST" );
m_hNetStr.add( 604, "TM_CS_QUEST_INFO" );
m_hNetStr.add( 605, "TM_CS_END_QUEST" );
m_hNetStr.add( 625, "TM_SC_TITLE_LIST" );
m_hNetStr.add( 626, "TM_SC_TITLE_CONDITION_LIST" );
m_hNetStr.add( 627, "TM_SC_REMAIN_TITLE_TIME" );
m_hNetStr.add( 628, "TM_CS_SET_MAIN_TITLE" );
m_hNetStr.add( 629, "TM_SC_SET_MAIN_TITLE" );
m_hNetStr.add( 630, "TM_CS_SET_SUB_TITLE" );
m_hNetStr.add( 631, "TM_SC_SET_SUB_TITLE" );
m_hNetStr.add( 632, "TM_CS_BOOKMARK_TITLE" );
m_hNetStr.add( 633, "TM_SC_BOOKMARK_TITLE" );
m_hNetStr.add( 634, "TM_SC_ACHIEVE_TITLE" );
m_hNetStr.add( 635, "TM_SC_OPEN_TITLE" );
m_hNetStr.add( 636, "TM_SC_CHANGE_TITLE_CONDITION" );
m_hNetStr.add( 650, "TM_SC_SHOW_CREATE_GUILD");
m_hNetStr.add( 651, "TM_SC_OPEN_GUILD_WINDOW");
m_hNetStr.add( 700, "TM_CS_START_BOOTH" ); // 개설
m_hNetStr.add( 701, "TM_CS_STOP_BOOTH" ); // 중지
m_hNetStr.add( 702, "TM_CS_WATCH_BOOTH" ); // 내용 보기
m_hNetStr.add( 703, "TM_SC_WATCH_BOOTH" ); // 내용 보내주기
m_hNetStr.add( 704, "TM_CS_STOP_WATCH_BOOTH" ); // 그만 보기
m_hNetStr.add( 705, "TM_CS_BUY_FROM_BOOTH" ); // 물건 구입
m_hNetStr.add( 706, "TM_CS_SELL_TO_BOOTH" ); // 물건 판매
m_hNetStr.add( 707, "TM_CS_GET_BOOTHS_NAME" ); // 노점 이름 얻어오기
m_hNetStr.add( 708, "TM_SC_GET_BOOTHS_NAME" ); // 노점 이름들
m_hNetStr.add( 709, "TM_SC_BOOTH_CLOSED" ); // 노점 닫힘 알림
m_hNetStr.add( 710, "TM_SC_BOOTH_TRADE_INFO" );
m_hNetStr.add( 711, "TM_CS_CHECK_BOOTH_STARTABLE" );
m_hNetStr.add( 800, "TM_CS_TURN_ON_PK_MODE" ); //피케이 온
m_hNetStr.add( 801, "TM_CS_TURN_OFF_PK_MODE" ); //피케이 오프
m_hNetStr.add( 900, "TM_CS_CHANGE_LOCATION" ); //지역 관련
m_hNetStr.add( 901, "TM_SC_CHANGE_LOCATION" ); //지역 관련
m_hNetStr.add( 902, "TM_SC_WEATHER_INFO" ); //날씨 관련
m_hNetStr.add( 903, "TM_CS_GET_WEATHER_INFO" ); //날씨 관련
m_hNetStr.add( 1100, "TM_CS_GAME_TIME");
m_hNetStr.add( 1101, "TM_SC_GAME_TIME");
m_hNetStr.add( 1201, "TM_SC_EMOTION");
m_hNetStr.add( 1202, "TM_CS_EMOTION");
m_hNetStr.add( 1000, "TM_SC_STAT_INFO" ); // 스탯정보
m_hNetStr.add( 1001, "TM_SC_GOLD_UPDATE" ); // 돈 바뀜
m_hNetStr.add( 1002, "TM_SC_LEVEL_UPDATE" ); // 레벨 바뀜
m_hNetStr.add( 1003, "TM_SC_EXP_UPDATE" ); // 경험치 바뀜
m_hNetStr.add( 1300, "TM_CS_AUCTION_SEARCH" );
m_hNetStr.add( 1301, "TM_SC_AUCTION_SEARCH" );
m_hNetStr.add( 1302, "TM_CS_AUCTION_SELLING_LIST" );
m_hNetStr.add( 1303, "TM_SC_AUCTION_SELLING_LIST" );
m_hNetStr.add( 1304, "TM_CS_AUCTION_BIDDED_LIST" );
m_hNetStr.add( 1305, "TM_SC_AUCTION_BIDDED_LIST" );
m_hNetStr.add( 1306, "TM_CS_AUCTION_BID" );
m_hNetStr.add( 1308, "TM_CS_AUCTION_INSTANT_PURCHASE" );
m_hNetStr.add( 1309, "TM_CS_AUCTION_REGISTER" );
m_hNetStr.add( 1310, "TM_CS_AUCTION_CANCEL" );
m_hNetStr.add( 1350, "TM_CS_ITEM_KEEPING_LIST" );
m_hNetStr.add( 1351, "TM_SC_ITEM_KEEPING_LIST" );
m_hNetStr.add( 1352, "TM_CS_ITEM_KEEPING_TAKE" );
m_hNetStr.add( 2000, "TM_CS_ACCOUNT" );
m_hNetStr.add( 2001, "TM_CS_CHARACTER_LIST" );
m_hNetStr.add( 2002, "TM_CS_CREATE_CHARACTER" );
m_hNetStr.add( 2003, "TM_CS_DELETE_CHARACTER" );
m_hNetStr.add( 2004, "TM_SC_CHARACTER_LIST" );
m_hNetStr.add( 2006, "TM_CS_CHECK_CHARACTER_NAME"); // 캐릭터 생성 이름 검사
m_hNetStr.add( 3000, "TM_SC_DIALOG");
m_hNetStr.add( 3001, "TM_CS_DIALOG");
m_hNetStr.add( 3002, "TM_CS_CONTACT");
m_hNetStr.add( 3003, "TM_SC_SHOW_WINDOW");
m_hNetStr.add( 3004, "TM_SC_GENERAL_MESSAGE_BOX");
m_hNetStr.add( 4000, "TM_CS_HUNTAHOLIC_INSTANCE_LIST" );
m_hNetStr.add( 4001, "TM_SC_HUNTAHOLIC_INSTANCE_LIST" );
m_hNetStr.add( 4002, "TM_SC_HUNTAHOLIC_INSTANCE_INFO" );
m_hNetStr.add( 4003, "TM_CS_HUNTAHOLIC_CREATE_INSTANCE" );
m_hNetStr.add( 4004, "TM_CS_HUNTAHOLIC_JOIN_INSTANCE" );
m_hNetStr.add( 4005, "TM_CS_HUNTAHOLIC_LEAVE_INSTANCE" );
m_hNetStr.add( 4006, "TM_SC_HUNTAHOLIC_HUNTING_SCORE" );
m_hNetStr.add( 4007, "TM_SC_HUNTAHOLIC_UPDATE_SCORE" );
m_hNetStr.add( 4008, "TM_CS_HUNTAHOLIC_LEAVE_LOBBY" );
m_hNetStr.add( 4009, "TM_SC_HUNTAHOLIC_BEGIN_HUNTING" );
m_hNetStr.add( 4010, "TM_SC_HUNTAHOLIC_MAX_POINT_ACHIEVED" );
m_hNetStr.add( 4011, "TM_CS_HUNTAHOLIC_BEGIN_HUNTING" );
m_hNetStr.add( 4012, "TM_SC_HUNTAHOLIC_BEGIN_COUNTDOWN" );
m_hNetStr.add( 4250, "TM_CS_INSTANCE_GAME_ENTER" );
m_hNetStr.add( 4251, "TM_CS_INSTANCE_GAME_EXIT" );
m_hNetStr.add( 4252, "TM_CS_INSTANCE_GAME_SCORE_REQUEST" );
m_hNetStr.add( 4253, "TM_SC_INSTANCE_GAME_SCORE_REQUEST" );
m_hNetStr.add( 6000, "TM_CS_REQUEST_FARM_INFO" );
m_hNetStr.add( 6001, "TM_SC_FARM_INFO" );
m_hNetStr.add( 6002, "TM_CS_FOSTER_CREATURE" );
m_hNetStr.add( 6003, "TM_SC_RESULT_FOSTER" );
m_hNetStr.add( 6004, "TM_CS_RETRIEVE_CREATURE" );
m_hNetStr.add( 6005, "TM_SC_RESULT_RETRIEVE" );
m_hNetStr.add( 6006, "TM_CS_NURSE_CREATURE" );
m_hNetStr.add( 6007, "TM_SC_RESULT_NURSE" );
m_hNetStr.add( 6008, "TM_CS_REQUEST_FARM_MARKET" );
m_hNetStr.add( 8000, "TM_CS_REPORT");
m_hNetStr.add( 9000, "TM_SC_OPEN_URL" );
m_hNetStr.add( 9001, "TM_SC_URL_LIST" );
//m_hNetStr.add( TM_SC_CREATE_SECURITY_NO, "TM_SC_CREATE_SECURITY_NO" );
m_hNetStr.add( TM_SC_REQUEST_SECURITY_NO, "TM_SC_REQUEST_SECURITY_NO" ); // 9002
m_hNetStr.add( TM_CS_SECURITY_NO, "TM_CS_SECURITY_NO" ); // 9005
//m_hNetStr.add( TM_CS_CREATE_SECURITY_NO, "TM_CS_CREATE_SECURITY_NO" );
//m_hNetStr.add( TM_CS_CHANGE_SECURITY_NO, "TM_CS_CHANGE_SECURITY_NO" );
//m_hNetStr.add( TM_CS_REQUEST_SECURITY_NO_CHANGE, "TM_CS_REQUEST_SECURITY_NO_CHANGE" );
//m_hNetStr.add( TM_SC_CHANGE_SECURITY_NO, "TM_SC_CHANGE_SECURITY_NO" );
//m_hNetStr.add( TM_CS_REQUEST_CLEAR_SECURITY_NO, "TM_CS_REQUEST_CLEAR_SECURITY_NO" );
//m_hNetStr.add( TM_SC_CLEAR_SECURITY_NO, "TM_SC_CLEAR_SECURITY_NO" );
//m_hNetStr.add( TM_CS_CLEAR_SECURITY_NO, "TM_CS_CLEAR_SECURITY_NO" );
m_hNetStr.add( 10000, "TM_CS_OPEN_ITEM_SHOP" );
m_hNetStr.add( 10001, "TM_SC_OPEN_ITEM_SHOP" );
m_hNetStr.add( 10002, "TM_SC_OPEN_PAID_STORAGE" );
m_hNetStr.add( 10003, "TM_SC_COMMERCIAL_STORAGE_INFO"); //캐쉬템창고에아이템이뭔가들어왔을경우전송됨
m_hNetStr.add( 10004, "TM_SC_COMMERCIAL_STORAGE_LIST"); //캐쉬템 리스트
m_hNetStr.add( 10005, "TM_CS_TAKEOUT_COMMERCIAL_ITEM"); //캐쉬템에서 아이템 꺼냄
// }
m_hNetStr.add( 28,"TM_SC_DISCONNECT_DESC" );
//1:1 대전
//2009-01-30 : hunee
m_hNetStr.add( TM_SC_COMPETE_REQUEST, "TM_SC_COMPETE_REQUEST" );
m_hNetStr.add( TM_SC_COMPETE_ANSWER, "TM_SC_COMPETE_ANSWER" );
m_hNetStr.add( TM_SC_COMPETE_COUNTDOWN, "TM_SC_COMPETE_COUNTDOWN" );
m_hNetStr.add( TM_SC_COMPETE_START, "TM_SC_COMPETE_START" );
m_hNetStr.add( TM_SC_COMPETE_END, "TM_SC_COMPETE_END" );
// 랭킹시스템
m_hNetStr.add( TM_CS_RANKING_TOP_RECORD, "TM_CS_RANKING_TOP_RECORD" );
m_hNetStr.add( TM_SC_RANKING_TOP_RECORD, "TM_SC_RANKING_TOP_RECORD" );
m_hNetStr.add( TM_SC_BATTLE_ARENA_PENALTY_INFO, "TM_SC_BATTLE_ARENA_PENALTY_INFO");
m_hNetStr.add( TM_CS_BATTLE_ARENA_JOIN_QUEUE, "TM_CS_BATTLE_ARENA_JOIN_QUEUE");
m_hNetStr.add( TM_SC_BATTLE_ARENA_JOIN_QUEUE , "TM_SC_BATTLE_ARENA_JOIN_QUEUE");
m_hNetStr.add( TM_SC_BATTLE_ARENA_UPDATE_WAIT_USER_COUNT , "TM_SC_BATTLE_ARENA_UPDATE_WAIT_USER_COUNT");
m_hNetStr.add( TM_CS_BATTLE_ARENA_LEAVE , "TM_CS_BATTLE_ARENA_LEAVE");
m_hNetStr.add( TM_SC_BATTLE_ARENA_LEAVE , "TM_SC_BATTLE_ARENA_LEAVE");
m_hNetStr.add( TM_SC_BATTLE_ARENA_BATTLE_INFO, "TM_SC_BATTLE_ARENA_BATTLE_INFO");
m_hNetStr.add( TM_CS_BATTLE_ARENA_ENTER_WHILE_COUNTDOWN, "TM_CS_BATTLE_ARENA_ENTER_WHILE_COUNTDOWN");
m_hNetStr.add( TM_CS_BATTLE_ARENA_EXERCISE_READY, "TM_CS_BATTLE_ARENA_EXERCISE_READY");
m_hNetStr.add( TM_SC_BATTLE_ARENA_EXERCISE_READY_STATUS, "TM_SC_BATTLE_ARENA_EXERCISE_READY_STATUS");
m_hNetStr.add( TM_CS_BATTLE_ARENA_EXERCISE_START, "TM_CS_BATTLE_ARENA_EXERCISE_START");
m_hNetStr.add( TM_SC_BATTLE_ARENA_BATTLE_STATUS, "TM_SC_BATTLE_ARENA_BATTLE_STATUS");
m_hNetStr.add( TM_SC_BATTLE_ARENA_BATTLE_SCORE, "TM_SC_BATTLE_ARENA_BATTLE_SCORE");
m_hNetStr.add( TM_SC_BATTLE_ARENA_JOIN_BATTLE, "TM_SC_BATTLE_ARENA_JOIN_BATTLE");
m_hNetStr.add( TM_SC_BATTLE_ARENA_DISCONNECT_BATTLE, "TM_SC_BATTLE_ARENA_DISCONNECT_BATTLE");
m_hNetStr.add( TM_SC_BATTLE_ARENA_RECONNECT_BATTLE, "TM_SC_BATTLE_ARENA_RECONNECT_BATTLE");
m_hNetStr.add( TM_SC_BATTLE_ARENA_RESULT, "TM_SC_BATTLE_ARENA_RESULT");
m_hNetStr.add( TM_CS_BATTLE_ARENA_ABSENCE_CHECK_REQUEST, "TM_CS_BATTLE_ARENA_ABSENCE_CHECK_REQUEST");
m_hNetStr.add( TM_SC_BATTLE_ARENA_ABSENCE_CHECK, "TM_SC_BATTLE_ARENA_ABSENCE_CHECK");
m_hNetStr.add( TM_CS_BATTLE_ARENA_ABSENCE_CHECK_ANSWER, "TM_CS_BATTLE_ARENA_ABSENCE_CHECK_ANSWER");
m_hNetStr.add( TM_CS_DECOMPOSE, "TM_CS_DECOMPOSE" );
m_hNetStr.add( TM_SC_DECOMPOSE_RESULT, "TM_CS_DECOMPOSE_RESULT" );
}
void SGameVM::Destroy()
{
if( !m_vDelList.empty() )
{
for( unsigned int i(0); m_vDelList.size()>i; i++ )
{
delete m_vDelList[i];
}
m_vDelList.clear();
}
if( !m_QueueGame.empty() )
{
while( 1 )
{
if( m_QueueGame.empty() ) break;
SGameMessage* pMsg = m_QueueGame.front();
delete pMsg;
m_QueueGame.pop();
}
}
if( !m_ReQueueGame.empty() )
{
while( 1 )
{
if( m_ReQueueGame.empty() ) break;
SGameMessage* pMsg = m_ReQueueGame.front();
delete pMsg;
m_ReQueueGame.pop();
}
}
if( !m_QueueNet.empty() )
{
while( 1 )
{
if( m_QueueNet.empty() ) break;
TS_MESSAGE* pMsg = m_QueueNet.front();
delete pMsg;
m_QueueNet.pop();
}
}
if( !m_vSafeKeepingList.empty() )
{
_oprint( "SafeKeepingList : %d\n", (int)m_vSafeKeepingList.size() );
//보관용
std::vector< SGameMessage* >::iterator it = m_vSafeKeepingList.begin();
while( it != m_vSafeKeepingList.end() )
{
delete (*it);
it = m_vSafeKeepingList.erase( it );
}
}
}
// Receive network message
bool SGameVM::onReadEvent( struct IStreamSocketConnection * pConn, struct IQueue* pRecvQueue )
{
// Fraun performance tweak
//char buf[1*1024];
//char buf[4*1024];
char buf[65536];
int nLen = pConn->Read( buf, sizeof(buf) );
if( nLen < 0 || nLen > sizeof( buf ) )
{
//Connection Closed
return false;
}
pRecvQueue->Write( buf, nLen );
while( pRecvQueue->Size() >= sizeof( TS_MESSAGE ) )
{
TS_MESSAGE* pMsg = (TS_MESSAGE*)pRecvQueue->GetBuf();
if( pMsg->size > pRecvQueue->Size() ) return true;
#ifdef _DEV
if( (GetKeyState(20) & 0x01) )
{
std::string strMsg;
if( m_hNetStr.lookup( pMsg->id, strMsg ) )
{
_oprint( "onReadEvent %s [%d]\n", strMsg.c_str(), pMsg->id );
}
}
#endif
// Some result comes from the server
switch( pMsg->id )
{
case TM_SECRET_KEY: // 72
{
TS_SECRET_KEY* pKeyMsg = static_cast< TS_SECRET_KEY* >( pMsg );
SMSG_SECRET_KEY* pSecret = new SMSG_SECRET_KEY;
pSecret->nEncryptSize = pKeyMsg->nEncryptSize;
pSecret->pEncryptData = new unsigned char[pSecret->nEncryptSize];
memcpy( pSecret->pEncryptData, (pKeyMsg+1), pSecret->nEncryptSize );
m_QueueGame.push( pSecret );
}
break;
case TM_AC_ACCOUNT_INFO: // 10014
{
TS_AC_ACCOUNT_INFO* pAccountInfoMsg = static_cast< TS_AC_ACCOUNT_INFO* >( pMsg );
SMSG_ACCOUNT_INFO* pAccountInfo = new SMSG_ACCOUNT_INFO;
pAccountInfo->strAccount = pAccountInfoMsg->account;
pAccountInfo->user_no = pAccountInfoMsg->user_no;
m_QueueGame.push( pAccountInfo );
}
break;
case TM_SC_RESULT : OnResult( static_cast<TS_SC_RESULT*>(pMsg) ); break; // 0
case TM_TIMESYNC : onMsgTimeSync( static_cast< TS_TIMESYNC* >(pMsg) ); break; // 2
case TM_SC_ENTER : onMsgEnter( static_cast< TS_ENTER* >(pMsg) ); break; // 3
case TM_SC_WATCH_BOOTH : onMsgWatchBooth( static_cast< TS_SC_WATCH_BOOTH* >(pMsg) ); break; // 703
case TM_SC_GET_BOOTHS_NAME : onBoothName( static_cast< TS_SC_GET_BOOTHS_NAME* >(pMsg) ) ; break; // 708
case TM_SC_BOOTH_CLOSED : onMsgBoothClopsed( static_cast< TS_SC_BOOTH_CLOSED* >(pMsg) ); break; // 709
case TM_SC_BOOTH_TRADE_INFO : onBoothTradeInfo( static_cast< TS_SC_BOOTH_TRADE_INFO* >(pMsg) ) ; break; // 710
case TM_SC_LOGIN_RESULT : onMsgLogin( static_cast< TS_LOGIN_RESULT* >(pMsg) ); break; // 4
case TM_SC_MOVE : onMsgMove( static_cast< TS_MOVE* >(pMsg) ); break; // 8
case TM_SC_LEAVE : onMsgLeave( static_cast< TS_LEAVE* >(pMsg) ); break; // 9
case TM_SC_REGION_ACK : onMsgRegionAck( static_cast< TS_REGION_ACK* >(pMsg) ); break; // 11
case TM_SC_SET_TIME : SetArTimeAdjust(GetArTimeAdjust() + static_cast< TS_SET_TIME* >( pMsg )->gap ); break; // 10
case TM_SC_HAIR_INFO : onMsgHairInfo( static_cast< TS_SC_HAIR_INFO* > (pMsg)); break; // 220
case TM_SC_CHANGE_NAME :
{
TS_SC_CHANGE_NAME* pChangeName = static_cast< TS_SC_CHANGE_NAME* >(pMsg);
SMSG_CHANGE_NAME * pGameChangeName = new SMSG_CHANGE_NAME;
pGameChangeName->handle = pChangeName->handle;
pGameChangeName->m_name = pChangeName->name;
m_QueueGame.push( pGameChangeName );
}
break;
case TM_SC_ANTI_HACK :
{
#ifdef _HACK_SHIELD_
TS_SC_ANTI_HACK* pAnti_Hack = static_cast< TS_SC_ANTI_HACK* >(pMsg);
TS_CS_ANTI_HACK byAckMsg;
DWORD dwRet = _AhnHS_MakeResponse( pAnti_Hack->AhnHSReqBuffer.byBuffer, pAnti_Hack->AhnHSReqBuffer.nLength, &byAckMsg.AhnHSAckBuffer );
if( dwRet != ERROR_SUCCESS )
{
}
else
{
m_pGameManager->PendMessage( &byAckMsg );
}
#endif
}
break;
case TM_SC_GAME_GUARD_AUTH_QUERY:
{
if( m_pGameManager )
{
if( m_pGameManager->GameGuardReceiveFromServer( pMsg ) == false )
{
if( g_pFLog )
{
fprintf( g_pFLog, "%s\n", "if( sizeof( TS_SC_GAME_GUARD_AUTH_QUERY ) != sizeof( GG_AUTH_DATA ) )" );
fflush( g_pFLog );
}
}
}
}
break;
case TM_SC_ATTACK_EVENT: onAttackEvent( static_cast<TS_ATTACK_EVENT*>(pMsg) ); break; // 101
case TM_SC_DOUBLE_WEAPON_ATTACK_EVENT: OnDoubleAttackEvent( static_cast<TS_DOUBLE_WEAPON_ATTACK_EVENT*>(pMsg) ); break;
case TM_SC_CANT_ATTACK : onCantAttack( static_cast<TS_SC_CANT_ATTACK*>(pMsg) ); break;
case TM_SC_STAT_INFO : OnStatInfo ( static_cast<TS_SC_STAT_INFO*>(pMsg) ); break; // 1000
case TM_SC_GOLD_UPDATE : OnGoldUpdate( static_cast<TS_SC_GOLD_UPDATE*>(pMsg) ); break; // 1001
case TM_SC_LEVEL_UPDATE: OnLevelUpdate( static_cast<TS_SC_LEVEL_UPDATE*>(pMsg) ); break; // 1002
case TM_SC_EXP_UPDATE : OnExpUpdate( static_cast<TS_SC_EXP_UPDATE*>(pMsg) ); break; // 1003
case TM_SC_BONUS_EXP_JP: OnBonusExpUpdate( static_cast<TS_SC_BONUS_EXP_JP*>(pMsg) ); break;
case TM_SC_ADD_SUMMON_INFO : OnAddSummonInfo ( static_cast<TS_SC_ADD_SUMMON_INFO*>(pMsg) ); break; // 301
case TM_SC_REMOVE_SUMMON_INFO : OnRemoveSummonInfo( static_cast<TS_SC_REMOVE_SUMMON_INFO*>(pMsg)); break;
case TM_EQUIP_SUMMON : OnEquipSummonInfo ( static_cast<TS_EQUIP_SUMMON*>(pMsg) ); break;
case TM_SC_UNSUMMON : OnUnsummon ( static_cast<TS_SC_UNSUMMON*>(pMsg) ); break;
case TM_SC_UNSUMMON_NOTICE : OnUnsummonNotice ( static_cast<TS_SC_UNSUMMON_NOTICE*>(pMsg) ); break;
case TM_SC_SUMMON_EVOLUTION : OnSummonEvolution ( static_cast<TS_SC_SUMMON_EVOLUTION*>(pMsg) ); break;
case TM_SC_TAMING_INFO : OnTamingInfo ( static_cast<TS_SC_TAMING_INFO*>(pMsg) ); break;
case TM_SC_MOUNT_SUMMON : OnMountSummon ( static_cast<TS_SC_MOUNT_SUMMON*>(pMsg) ); break;
case TM_SC_UNMOUNT_SUMMON : OnUnMountSummon ( static_cast<TS_SC_UNMOUNT_SUMMON*>(pMsg) ); break;
case TM_SC_SHOW_SUMMON_NAME_CHANGE : OnSummonNameChange ( static_cast<TS_SC_SHOW_SUMMON_NAME_CHANGE*>(pMsg) ); break;
// sonador 10.2.1 팻 시스템 구현
// pet
case TM_SC_UNSUMMON_PET : OnUnsummonPet ( static_cast< TS_SC_UNSUMMON_PET* >( pMsg ) ); break;
case TM_SC_ADD_PET_INFO : OnAddPetInfo ( static_cast< TS_SC_ADD_PET_INFO* >( pMsg ) ); break;
case TM_SC_REMOVE_PET_INFO : OnRemovePetInfo ( static_cast< TS_SC_REMOVE_PET_INFO* >( pMsg ) ); break;
case TM_SC_SHOW_SET_PET_NAME: OnShowSetPetName ( static_cast< TS_SC_SHOW_SET_PET_NAME* >( pMsg ) ); break;
// quest
case TM_SC_QUEST_LIST : OnQuestList( static_cast< TS_SC_QUEST_LIST* >( pMsg ) ); break;
case TM_SC_QUEST_STATUS : OnQuestStatus( static_cast< TS_SC_QUEST_STATUS* >( pMsg ) ); break;
// guild
case TM_SC_SHOW_CREATE_GUILD : OnShowCreateGuild( static_cast< TS_SC_SHOW_CREATE_GUILD* >( pMsg ) ); break;
// guild alliance
case TM_SC_SHOW_CREATE_ALLIANCE : OnShowCreateAlliance( static_cast< TS_SC_SHOW_CREATE_ALLIANCE*>(pMsg) ); break;
case TM_SC_SKILL : OnSkillEvent ( static_cast<TS_SC_SKILL*>(pMsg) ); break; //401
case TM_SC_SKILL_LIST : OnSkillList ( static_cast<TS_SC_SKILL_LIST*>(pMsg) ); break; //403
//Chatting
case TM_SC_CHAT_LOCAL : OnMsgChattingLocal( static_cast<TS_SC_CHAT_LOCAL*>(pMsg) ); break; //21
case TM_SC_CHAT : OnMsgChatting ( static_cast<TS_SC_CHAT*>(pMsg) ); break; //22
// 2010.05.19 HIDE_EQUIP_INFO - prodongi
case TM_SC_HIDE_EQUIP_INFO: OnMsgHideEquipInfo(static_cast<TS_SC_HIDE_EQUIP_INFO*>(pMsg)); break;
//아이템
case TM_SC_WEAR_INFO : onWearInfo ( static_cast<TS_WEAR_INFO*>(pMsg) ); break; //202
case TM_SC_DROP_RESULT : onMsgDrop ( static_cast<TS_SC_DROP_RESULT*>(pMsg) ); break; //205
case TM_SC_ITEM_DROP_INFO : onMsgDropInfo ( static_cast<TS_SC_ITEM_DROP_INFO*>(pMsg) ); break; //282
case TM_SC_SKILLCARD_INFO : onMsgSkillCardInfo( static_cast<TS_SC_SKILLCARD_INFO*>(pMsg) ); break; //286
case TM_SC_ITEM_WEAR_INFO : onItemWearInfo ( static_cast<TS_SC_ITEM_WEAR_INFO*>(pMsg) ); break; //287
case TM_SC_INVENTORY : OnMsgInven ( static_cast<TS_SC_INVENTORY*>(pMsg) ); break; //207
case TM_SC_OPEN_STORAGE : OnMsgOpenStorage ( static_cast<TS_SC_OPEN_STORAGE*>(pMsg) ); break; //
case TM_CS_SHOW_SOULSTONE_CRAFT_WINDOW: OnMsgOpenSoulstoneCraft( static_cast<TS_SC_SHOW_SOULSTONE_CRAFT_WINDOW*>(pMsg) ); break; //260
case TM_SC_SHOW_SOULSTONE_REPAIR_WINDOW: OnMsgOpenSoulstoneRepair( static_cast<TS_SC_SHOW_SOULSTONE_REPAIR_WINDOW*>(pMsg) ); break; //261
case TM_SC_MARKET : onMarket ( static_cast<TS_SC_MARKET*>(pMsg) ); break; //250
case TM_SC_DESTROY_ITEM : onDestroyItem ( static_cast<TS_SC_DESTROY_ITEM*>(pMsg) ); break; //254
case TM_SC_ERASE_ITEM : onEraseItem( static_cast< TS_SC_ERASE_ITEM * >( pMsg ) ); break; // 263. br // 아이템파괴.
case TM_SC_UPDATE_ITEM_COUNT : onUpdateItemCount( static_cast<TS_SC_UPDATE_ITEM_COUNT*>(pMsg) ); break; //255
case TM_SC_MIX_RESULT : onMixResult ( static_cast<TS_SC_MIX_RESULT*>(pMsg) ); break;
case TM_TRADE : onTrade ( static_cast<TS_TRADE*>(pMsg) ); break; //280
case TM_SC_USE_ITEM_RESULT : onUseItemResult ( static_cast<TS_SC_USE_ITEM_RESULT*>(pMsg) ); break; //280
case TM_SC_TAKE_ITEM_RESULT : OnMsgTakeItemResult( static_cast<TS_SC_TAKE_ITEM_RESULT*>(pMsg) ); break;
case TM_SC_CHANGE_LOCATION : OnChangeLocation( static_cast<TS_SC_CHANGE_LOCATION*>(pMsg) ); break;
//날씨 관련
case TM_SC_WEATHER_INFO : OnWeatherInfo( static_cast<TS_SC_WEATHER_INFO*>(pMsg) ); break;
case TM_SC_GAME_TIME : OnGametime( static_cast<TS_SC_GAME_TIME*>(pMsg) ); break;
//기타
case TM_SC_EMOTION : OnEmotion( static_cast<TS_SC_EMOTION*>(pMsg) ); break;
case TM_SC_GET_CHAOS : OnGetChaos( static_cast<TS_SC_GET_CHAOS*>(pMsg) ); break;
//벨트 슬롯
case TM_SC_BELT_SLOT_INFO :
{
TS_SC_BELT_SLOT_INFO* pBeltSlotInfo = static_cast<TS_SC_BELT_SLOT_INFO*>(pMsg);
SMSG_BELT_SLOT_INFO * pNewBeltSlotInfo = new SMSG_BELT_SLOT_INFO;
for( unsigned short i(0); c_Belt_Slot_Cnt>i; i++ )
pNewBeltSlotInfo->handle[i] = pBeltSlotInfo->handle[i];
m_QueueGame.push( pNewBeltSlotInfo );
}
break;
case TM_SC_ENERGY : OnEnergy( static_cast<TS_SC_ENERGY*>(pMsg) ); break;
case TM_SC_STATE_RESULT : OnStateResult( static_cast<TS_SC_STATE_RESULT*>(pMsg) ); break;
case TM_SC_AURA :
{
TS_SC_AURA * pAuraMsg = static_cast<TS_SC_AURA*>(pMsg);
SMSG_AURA * pNewAuraMsg = new SMSG_AURA;
pNewAuraMsg->caster = pAuraMsg->caster;
pNewAuraMsg->skill_id = pAuraMsg->skill_id;
pNewAuraMsg->status = pAuraMsg->status;
m_QueueGame.push( pNewAuraMsg );
}
break;
case TM_SC_ITEM_COOL_TIME : OnItemCoolTime( static_cast<TS_SC_ITEM_COOL_TIME*>(pMsg) ); break;
case TM_SC_CHAT_RESULT : OnChatResult( static_cast<TS_SC_CHAT_RESULT*>(pMsg) ); break;
//Cheat 관련
case TM_SC_WARP : OnWarp( static_cast<TS_SC_WARP*>(pMsg) ); break; //12
case TM_SC_STATUS_CHANGE : OnStatusChange( static_cast<TS_SC_STATUS_CHANGE*>(pMsg) ); break; //500
// case TM_SC_HP : OnHP( static_cast<TS_SC_HP*>(pMsg) ); break; //501
// case TM_SC_MP : OnMP( static_cast<TS_SC_MP*>(pMsg) ); break; //502
case TM_SC_REGEN_HPMP : OnRegenHPMP( static_cast<TS_SC_REGEN_HPMP*>(pMsg) ); break;
case TM_SC_SP : OnSP( static_cast<TS_SC_SP*>(pMsg) ); break; //514
case TM_SC_DEAD : OnDead( pMsg ); break; // 504; 사망~
case TM_SC_STATE : OnState( static_cast<TS_SC_STATE*>(pMsg) ); break; // 505; 상태이상
case TM_SC_PROPERTY : OnProperty( static_cast<TS_SC_PROPERTY*>(pMsg) ); break; // 507; 프로퍼티
case TM_SC_HPMP : OnHPMP( static_cast<TS_SC_HPMP*>(pMsg) ); break;
case TM_SC_TARGET : OnTarget( static_cast<TS_SC_TARGET*>(pMsg) ); break;
// { [sonador][3.1.2] 경매장 구현
case TM_SC_AUCTION_SEARCH : OnMsgResultAuctionSearch( static_cast< TS_SC_AUCTION_SEARCH* >( pMsg ) ); break; // 경매장 검색에 대한 서버로 부터의 결과 메시지 처리
case TM_SC_AUCTION_SELLING_LIST : OnMsgResultAuctionSellingList( static_cast< TS_SC_AUCTION_SELLING_LIST* >( pMsg ) ); break; // 경매장에 자신이 등록한 물품 요청에 대한 결과 메시지 처리
case TM_SC_AUCTION_BIDDED_LIST : OnMsgResultAuctionBiddedList( static_cast< TS_SC_AUCTION_BIDDED_LIST* >( pMsg ) ); break; // 경매장에 자신이 등록한 물품 요청에 대한 결과 메시지 처리
case TM_SC_ITEM_KEEPING_LIST : OnMsgResultAuctionItemKeepingList( static_cast< TS_SC_ITEM_KEEPING_LIST* >( pMsg ) ); break; // 경매장에 자신의 보관된 물품 요청에 대한 결과 메시지 처리
// }
// #2.1.2.11.1 {
case TM_SC_HUNTAHOLIC_INSTANCE_LIST: OnMsgHuntaHolicInstanceList( static_cast< TS_SC_HUNTAHOLIC_INSTANCE_LIST* >( pMsg ) ); break;
case TM_SC_HUNTAHOLIC_INSTANCE_INFO: OnMsgHuntaHolicInstanceInfo( static_cast< TS_SC_HUNTAHOLIC_INSTANCE_INFO* >( pMsg ) ); break;
case TM_SC_HUNTAHOLIC_HUNTING_SCORE: OnMsgHuntaHolicHuntingScore( static_cast< TS_SC_HUNTAHOLIC_HUNTING_SCORE* >( pMsg ) ); break;
case TM_SC_HUNTAHOLIC_UPDATE_SCORE: OnMsgHuntaHolicUpdateScroe ( static_cast< TS_SC_HUNTAHOLIC_UPDATE_SCORE* >( pMsg ) ); break;
case TM_SC_HUNTAHOLIC_BEGIN_HUNTING: OnMsgHuntaHolicBeginHunting( static_cast< TS_SC_HUNTAHOLIC_BEGIN_HUNTING* >( pMsg ) ); break;
case TM_SC_HUNTAHOLIC_MAX_POINT_ACHIEVED: OnMsgHuntaHolicMaxPointReached( static_cast< TS_SC_HUNTAHOLIC_MAX_POINT_ACHIEVED* >( pMsg ) ); break; // sonador #2.1.2.11.5
//인스턴스게임추가
// sfreer 2009.11.04
case TM_SC_HUNTAHOLIC_BEGIN_COUNTDOWN : OnMsgHuntaHolicBeginCountDown( static_cast< TS_SC_HUNTAHOLIC_BEGIN_COUNTDOWN* >( pMsg ) ); break;
case TM_SC_INSTANCE_GAME_SCORE_REQUEST : OnMsgInstanceGameScoreRequest( static_cast< TS_SC_INSTANCE_GAME_SCORE_REQUEST* >( pMsg ) ); break;
// #2.1.2.11.1 }
// 1:1 대련
// 2009-01-30:hunee
case TM_SC_COMPETE_REQUEST : OnMsgCompeteRequest( static_cast< TS_SC_COMPETE_REQUEST* >( pMsg ) ); break;
case TM_SC_COMPETE_ANSWER : OnMsgCompeteAnswer( static_cast< TS_SC_COMPETE_ANSWER* >( pMsg ) ); break;
case TM_SC_COMPETE_COUNTDOWN : OnMsgCompeteCountdown( static_cast< TS_SC_COMPETE_COUNTDOWN* >( pMsg ) ); break;
case TM_SC_COMPETE_START : OnMsgCompeteStart( static_cast< TS_SC_COMPETE_START* >( pMsg ) ); break;
case TM_SC_COMPETE_END : OnMsgCompeteEnd( static_cast< TS_SC_COMPETE_END* >( pMsg ) ); break;
case TM_SC_RANKING_TOP_RECORD : OnMsgRanking(static_cast< TS_SC_RANKING_TOP_RECORD* >( pMsg ) ); break;
// Login과 캐랙터 선택/생성 관련
case TM_SC_CHARACTER_LIST: onMsgCharacterList( static_cast<TS_SC_CHARACTER_LIST*>(pMsg) ); break; //2004
// 스킬레벨의변동이발생
case TM_SC_ADDED_SKILL_LIST: onAddedSkillList( static_cast<TS_SC_ADDED_SKILL_LIST*>(pMsg) ); break;
//서버와의 접속이 종료 되었습니다. 메시지 수정
//2009-02-24: hunee
case TM_SC_DISCONNECT_DESC :
{
TS_SC_DISCONNECT_DESC * desc = static_cast<TS_SC_DISCONNECT_DESC *>(pMsg);
g_disconnectId = desc->desc_id;
//100: db
//101: gameguard
//102: script kick
//char *txt = GetStringDB().GetString( 797 );;
std::string txt;
txt = GetStringDB().GetString( 797 );
switch(g_disconnectId)
{
case 100:
txt += "(100)";
break;
case 101:
txt += "(101)";
break;
case 102:
txt += "(102)";
break;
}
char descid[80];
sprintf(descid, "DISCONNECT ID=%d", g_disconnectId);
MessageBox( g_hWnd, txt.c_str(), descid, MB_OK);
#ifdef _DEV
GetLog().OutputFile(LOGFILE_NAME);
#endif
exit(0);
}
break;
case TM_SC_DIALOG : OnDialog( static_cast<TS_SC_DIALOG*>(pMsg) ); break; //3000
case TM_SC_SHOW_WINDOW : OnShowWindow( static_cast<TS_SC_SHOW_WINDOW*>(pMsg) ); break;
case TM_SC_GENERAL_MESSAGE_BOX: OnGeneralMessageBox(static_cast<TS_SC_GENERAL_MESSAGE_BOX*>(pMsg)); break; /// 2011.10.26 - prodongi
case TM_SC_OPEN_URL :
{
TS_SC_OPEN_URL* pOpen = static_cast<TS_SC_OPEN_URL*>(pMsg);
SMSG_OPEN_URL * pOpenURL = new SMSG_OPEN_URL;
pOpenURL->wait_for_event_scene = pOpen->wait_for_event_scene;
pOpenURL->width = pOpen->width;
pOpenURL->height = pOpen->height;
// 전체 문자열
int nEntireLength = (pOpen->url_len);
const char* pEntire = (const char*)(pOpen + 1); // 주의! : NULL문자를 포함하지 않으므로 이 자체를 문자열로 사용할 수 없음!
pOpenURL->m_strURL = std::string( pEntire, pEntire + nEntireLength );
_oprint( "TS_SC_OPEN_URL : %s\n", pOpenURL->m_strURL.c_str() );
m_QueueGame.push( pOpenURL );
}
break;
case TM_SC_URL_LIST :
{
if( ENV().IsExist( "not_use_url" ) )
break;
TS_SC_URL_LIST* pURL = static_cast<TS_SC_URL_LIST*>(pMsg);
int nEntireLength = (pURL->url_list_len);
const char* pEntire = (const char*)(pURL + 1); // 주의! : NULL문자를 포함하지 않으므로 이 자체를 문자열로 사용할 수 없음!
std::string strAll = std::string( pEntire, pEntire + nEntireLength );
_oprint( "URL_LIST\t[ %s ]\n", strAll.c_str() );
std::vector< std::string > vString;
MsgSplit( strAll.c_str(), vString, L"|\r\n" );
int nLoop = (int)vString.size()/2;
int n=0;
for( int i(0); nLoop>i; i++ )
{
std::string strKey = vString[n++].c_str();
std::string strValue = vString[n++].c_str();
_oprint( "Key [%s] Value [%s]\n", strKey.c_str(), strValue.c_str() );
if( strKey == "web_download_port" )
{
ENV().Set( strKey.c_str(), atoi(strValue.c_str()) );
}
else
{
// _oprint( "Old Value [%s]\t", ENV().GetString( strKey.c_str() ).c_str() );
ENV().Set( strKey.c_str(), strValue.c_str() );
// _oprint( "SetKey Value [%s]\n", ENV().GetString( strKey.c_str() ).c_str() );
}
}
vString.clear();
}
break;
case TM_AC_RESULT :
{
TS_AC_RESULT* pAcResult = static_cast<TS_AC_RESULT*>(pMsg);
SMSG_AC_RESULT * pResult = new SMSG_AC_RESULT;
pResult->result = pAcResult->result;
pResult->request_msg_id = pAcResult->request_msg_id;
pResult->value = pAcResult->value;
m_QueueGame.push( pResult );
}
break;
/// 2011.05.20 - prodongi
case TM_AC_RESULT_WITH_STRING:
{
TS_AC_RESULT_WITH_STRING* result = static_cast<TS_AC_RESULT_WITH_STRING*>(pMsg);
SMSG_AC_RESULT_WITH_STRING* msg = new SMSG_AC_RESULT_WITH_STRING;
msg->result = result->result;
msg->request_msg_id = result->request_msg_id;
msg->value = result->value;
if (0 < result->strSize)
{
msg->str = new char[result->strSize+1];
memcpy((void*)msg->str, (void*)((BYTE*)pMsg + sizeof (TS_AC_RESULT_WITH_STRING)), result->strSize);
msg->str[result->strSize] = 0x00;
}
m_QueueGame.push(msg);
}
break;
case TM_AC_SERVER_LIST :
{
TS_AC_SERVER_LIST* pAcServerList = static_cast<TS_AC_SERVER_LIST*>(pMsg);
SMSG_AC_SERVER_LIST * pServerList = new SMSG_AC_SERVER_LIST;
pServerList->last_login_server_idx = pAcServerList->last_login_server_idx;
pServerList->count = pAcServerList->count;
if( pAcServerList->count )
{
pServerList->m_pServerInfo = new TS_SERVER_INFO[pAcServerList->count];
TS_SERVER_INFO* pServerInfo = (TS_SERVER_INFO*)(pAcServerList+1);
for( int i(0); pAcServerList->count>i; i++ )
{
memcpy( &pServerList->m_pServerInfo[i], &pServerInfo[i], sizeof(pServerList->m_pServerInfo[i]) );
}
}
m_QueueGame.push( pServerList );
}
break;
case TM_AC_SELECT_SERVER :
{
TS_AC_SELECT_SERVER* pAcSelectServer = static_cast<TS_AC_SELECT_SERVER*>(pMsg);
SMSG_AC_SELECT_SERVER * pSelectServer = new SMSG_AC_SELECT_SERVER;
pSelectServer->one_time_key_en_len = pAcSelectServer->one_time_key_en_len;
::memcpy( pSelectServer->one_time_key, pAcSelectServer->one_time_key, sizeof( pSelectServer->one_time_key ) );
pSelectServer->result = pAcSelectServer->result;
pSelectServer->pending_time = pAcSelectServer->pending_time;
m_QueueGame.push( pSelectServer );
}
break;
case TM_AC_UPDATE_PENDING_TIME:
{
TS_AC_UPDATE_PENDING_TIME* pAcUpdatePendingTime = static_cast<TS_AC_UPDATE_PENDING_TIME*>(pMsg);
SMSG_AC_UPDATE_PENDING_TIME * pUpdatePendingTime = new SMSG_AC_UPDATE_PENDING_TIME;
pUpdatePendingTime->pending_time = pAcUpdatePendingTime->pending_time;
m_QueueGame.push( pUpdatePendingTime );
}
break;
case TM_SC_OPEN_ITEM_SHOP:
{
TS_SC_OPEN_ITEM_SHOP *pPwMsg = static_cast<TS_SC_OPEN_ITEM_SHOP*>(pMsg);
SMSG_SEND_DATA *pOpenMsg = new SMSG_SEND_DATA( pPwMsg->one_time_password, "open_item_shop", pPwMsg->client_id, pPwMsg->account_id, pPwMsg->raw_server_name );
m_QueueGame.push( pOpenMsg );
}
break;
case TM_SC_OPEN_GUILD_WINDOW: // 폐기됨. TS_SC_UPDATE_GUILD_ICON 로 대체 되었다.
{
TS_SC_OPEN_GUILD_WINDOW *pPwMsg = static_cast<TS_SC_OPEN_GUILD_WINDOW*>(pMsg);
SMSG_SEND_DATA *pOpenMsg = new SMSG_SEND_DATA( pPwMsg->one_time_password, "open_guil_web", pPwMsg->client_id, pPwMsg->account_id, pPwMsg->raw_server_name );
m_QueueGame.push( pOpenMsg );
}
break;
case TM_SC_UPDATE_GUILD_ICON : // 길드 아이콘을 업데이트 하기위한 OTP 인증.
{
TS_SC_OPEN_GUILD_WINDOW *pPwMsg = static_cast<TS_SC_OPEN_GUILD_WINDOW*>(pMsg);
SMSG_SEND_DATA *pOpenMsg = new SMSG_SEND_DATA( pPwMsg->one_time_password, "open_guil_web", pPwMsg->client_id, pPwMsg->account_id, pPwMsg->raw_server_name );
m_QueueGame.push( pOpenMsg );
// OTP 정보 전달.
TS_SC_OPEN_GUILD_WINDOW * pOTP = new TS_SC_OPEN_GUILD_WINDOW();
memcpy( pOTP, pPwMsg, sizeof( *pOTP ) );
SIMSG_UI_SEND_DATA * pData = new SIMSG_UI_SEND_DATA();
pData->m_nTarget = SIMSG_TOGGLE_UIWINDOW::_UIWINDOW_TYPE::UIWINDOW_GUILD_SUB_MANAGE;
pData->m_strString = "OTP_CONFIRM";
pData->m_pData = (void *)pOTP;
m_QueueGame.push( pData );
//::MessageBox( NULL, "open_guil_web", "", MB_OK );
}
break;
// case TM_SC_OPEN_PAID_STORAGE:
case TM_SC_COMMERCIAL_STORAGE_INFO:
{
TS_SC_COMMERCIAL_STORAGE_INFO *pStorageInfo = static_cast<TS_SC_COMMERCIAL_STORAGE_INFO*>(pMsg);
SMSG_COMMERCIAL_STORAGE_INFO * pNewStorageInfo = new SMSG_COMMERCIAL_STORAGE_INFO;
pNewStorageInfo->new_item_count = pStorageInfo->new_item_count ;
pNewStorageInfo->total_item_count = pStorageInfo->total_item_count;
m_QueueGame.push( pNewStorageInfo );
}
break;
case TM_SC_COMMERCIAL_STORAGE_LIST:
{
TS_SC_COMMERCIAL_STORAGE_LIST *pPwMsg = static_cast<TS_SC_COMMERCIAL_STORAGE_LIST*>(pMsg);
SMSG_COMMERCIAL_STORAGE_LIST* pCommercialStorageList = new SMSG_COMMERCIAL_STORAGE_LIST;
pCommercialStorageList->count = pPwMsg->count;
if( pPwMsg->count > 0 )
{
TS_SC_COMMERCIAL_STORAGE_LIST::CommercialItemInfo *pInfo = reinterpret_cast< TS_SC_COMMERCIAL_STORAGE_LIST::CommercialItemInfo * >( pPwMsg + 1 );
for( int n(0); pPwMsg->count>n; ++n, pInfo++ )
{
TS_SC_COMMERCIAL_STORAGE_LIST::CommercialItemInfo item;
item.code = pInfo->code;
item.count = pInfo->count;
item.commercial_item_uid = pInfo->commercial_item_uid;
pCommercialStorageList->vItemList.push_back(item);
}
}
m_QueueGame.push( pCommercialStorageList );
}
break;
/*
case TM_SC_CREATE_SECURITY_NO:
{
TS_SC_CREATE_SECURITY_NO* pSCMsg = static_cast<TS_SC_CREATE_SECURITY_NO*>(pMsg);
SMSG_SC_CREATE_SECURITY_NO* pGameMsg = new SMSG_SC_CREATE_SECURITY_NO;
m_QueueGame.push( pGameMsg );
}
break;
*/
case TM_SC_REQUEST_SECURITY_NO:
{
TS_SC_REQUEST_SECURITY_NO* pSCMsg = static_cast<TS_SC_REQUEST_SECURITY_NO*>(pMsg);
SMSG_REQUEST_SECURITY_NO* pGameMsg = new SMSG_REQUEST_SECURITY_NO;
pGameMsg->mode = pSCMsg->mode;
m_QueueGame.push( pGameMsg );
}
break;
case TM_SC_NPC_TRADE_INFO:
{
TS_SC_NPC_TRADE_INFO* pNpcTradeMsg = static_cast<TS_SC_NPC_TRADE_INFO*>(pMsg);
SMSG_NPC_TRADE_INFO* pGameMsg = new SMSG_NPC_TRADE_INFO;
*pGameMsg = *pNpcTradeMsg;
m_QueueGame.push( pGameMsg );
}
break;
case TM_SC_XTRAP_CHECK: OnMsgXTrapCheck ( static_cast< TS_SC_XTRAP_CHECK* >(pMsg) ); break;
case TM_SC_FARM_INFO:
{
OnMsgCreatureFarmInfo( static_cast< TS_SC_FARM_INFO* >(pMsg) ); break; // 2011.02.23 - servantes
}
case TM_SC_RESULT_FOSTER:
{
OnMsgAssignResult( static_cast< TS_SC_RESULT_FOSTER* >(pMsg) );
break;
}
case TM_SC_RESULT_NURSE: // 2011.03.04 - servantes
{
OnMsgNurseResult( static_cast< TS_SC_RESULT_NURSE* >(pMsg) );
break;
}
case TM_SC_RESULT_RETRIEVE: // 2011.03.04 - servantes
{
OnMsgRegainResult( static_cast< TS_SC_RESULT_RETRIEVE* >(pMsg) );
break;
}
/// 2011.05.12 - prodongi
case TM_SC_SKILL_LEVEL_LIST:
{
OnMsgSkillLevelList(static_cast<TS_SC_SKILL_LEVEL_LIST*>(pMsg));
}
break;
case TM_SC_TITLE_LIST:
{
OnMsgTitle_List(static_cast<TS_SC_TITLE_LIST*>(pMsg));
}break;
case TM_SC_TITLE_CONDITION_LIST:
{
OnMsgTitle_ConditonList(static_cast<TS_SC_TITLE_CONDITION_LIST*>(pMsg));
}break;
case TM_SC_REMAIN_TITLE_TIME:
{
OnMsgTitle_RemainTime(static_cast<TS_SC_REMAIN_TITLE_TIME*>(pMsg));
}break;
case TM_SC_SET_MAIN_TITLE:
{
OnMsgTitle_SetMain(static_cast<TS_SC_SET_MAIN_TITLE*>(pMsg));
}break;
case TM_SC_SET_SUB_TITLE:
{
OnMsgTitle_SetSub(static_cast<TS_SC_SET_SUB_TITLE*>(pMsg));
}break;
case TM_SC_BOOKMARK_TITLE:
{
OnMsgTitle_Bookmark(static_cast<TS_SC_BOOKMARK_TITLE*>(pMsg));
}break;
case TM_SC_ACHIEVE_TITLE:
{
OnMsgTitle_Achieve(static_cast<TS_SC_ACHIEVE_TITLE*>(pMsg));
}break;
case TM_SC_OPEN_TITLE:
{
OnMsgTitle_Open(static_cast<TS_SC_OPEN_TITLE*>(pMsg));
}break;
case TM_SC_CHANGE_TITLE_CONDITION:
{
OnMsgTite_ChangeCondition(static_cast<TS_SC_CHANGE_TITLE_CONDITION*>(pMsg));
}break;
case TM_SC_BATTLE_ARENA_JOIN_QUEUE: OnBattleArenaJoinQueue(static_cast<TS_SC_BATTLE_ARENA_JOIN_QUEUE*>(pMsg)); break;
case TM_SC_BATTLE_ARENA_LEAVE: OnBattleArenaLeave(static_cast<TS_SC_BATTLE_ARENA_LEAVE*>(pMsg)); break;
case TM_SC_BATTLE_ARENA_BATTLE_INFO: OnBattleArenaBattleInfo(static_cast<TS_SC_BATTLE_ARENA_BATTLE_INFO*>(pMsg)); break;
case TM_SC_BATTLE_ARENA_EXERCISE_READY_STATUS: OnBattleArenaExerciseReadyStatus(static_cast<TS_SC_BATTLE_ARENA_EXERCISE_READY_STATUS*>(pMsg)); break;
case TM_SC_BATTLE_ARENA_BATTLE_STATUS: OnBattleArenaBattleStatus(static_cast<TS_SC_BATTLE_ARENA_BATTLE_STATUS*>(pMsg)); break;
case TM_SC_BATTLE_ARENA_BATTLE_SCORE: OnBattleArenaBattleScore(static_cast<TS_SC_BATTLE_ARENA_BATTLE_SCORE*>(pMsg)); break;
case TM_SC_BATTLE_ARENA_JOIN_BATTLE: OnBattleArenaJoinBattle(static_cast<TS_SC_BATTLE_ARENA_JOIN_BATTLE*>(pMsg)); break;
case TM_SC_BATTLE_ARENA_DISCONNECT_BATTLE: OnBattleArenaDisconnectBattle(static_cast<TS_SC_BATTLE_ARENA_DISCONNECT_BATTLE*>(pMsg)); break;
case TM_SC_BATTLE_ARENA_RECONNECT_BATTLE: OnBattleArenaReconnectBattle(static_cast<TS_SC_BATTLE_ARENA_RECONNECT_BATTLE*>(pMsg)); break;
case TM_SC_BATTLE_ARENA_RESULT: OnBattleArenaResult(static_cast<TS_SC_BATTLE_ARENA_RESULT*>(pMsg)); break;
case TM_SC_BATTLE_ARENA_ABSENCE_CHECK: OnBattleArenaAbsenceCheck(static_cast<TS_SC_BATTLE_ARENA_ABSENCE_CHECK*>(pMsg)); break;
case TM_SC_BATTLE_ARENA_PENALTY_INFO: OnBattleArenaPenaltyInfo(static_cast<TS_SC_BATTLE_ARENA_PENALTY_INFO*>(pMsg)); break;
case TM_SC_BATTLE_ARENA_UPDATE_WAIT_USER_COUNT: OnBattleArenaUpdateWaitUserCount(static_cast<TS_SC_BATTLE_ARENA_UPDATE_WAIT_USER_COUNT*>(pMsg)); break;
case TM_SC_DECOMPOSE_RESULT: OnDecomposeResult( static_cast<TS_SC_DECOMPOSE_RESULT*>(pMsg) ); break;
case TM_SC_SKIN_INFO: OnChangeSkinColor( static_cast<TS_SC_SKIN_INFO*>(pMsg) ); break;
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
// Upload Server
case TM_UC_LOGIN_RESULT : OnUploadServerLogin( static_cast< TS_UC_LOGIN_RESULT * >( pMsg ) ); break;
case TM_UC_UPLOAD : OnUploadServerGuildIconUpload( static_cast< TS_UC_UPLOAD * >( pMsg ) ); break;
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
case TM_SC_PARTYMATCH_LIST : OnPartyMatchList ( static_cast< TS_SC_PARTYMATCH_LIST * >( pMsg ) ); break;
case TM_SC_PARTYMATCH_MEMBER : OnPartyMatchMember( static_cast< TS_SC_PARTYMATCH_MEMBER * >( pMsg ) ); break;
default : _oprint( "Unprocessed message: %d\n", pMsg->id ); break;
}
pRecvQueue->Read( NULL, pMsg->size );
}
return true;
}
// XTRAP 확인요청이 들어오면 처리해서 바로 보낸다.
void SGameVM::OnMsgXTrapCheck( struct TS_SC_XTRAP_CHECK* pMsg )
{
#ifdef _USE_XTRAP_MODULE
TS_CS_XTRAP_CHECK msg;
XTrap_CS_Step2(pMsg->pCheckBuffer, msg.pCheckBuffer, XTRAP_PROTECT_PE | XTRAP_PROTECT_TEXT | XTRAP_PROTECT_EXCEPT_VIRUS);
m_pGameManager->PendMessage(&msg);
#endif
}
void SGameVM::onMsgBoothClopsed( struct TS_SC_BOOTH_CLOSED* pMsg )
{
m_QueueGame.push( new SMSG_BOOTH_CLOSED( pMsg->target ) );
}
void SGameVM::onMsgWatchBooth ( struct TS_SC_WATCH_BOOTH* pMsg )
{
SMSG_BOOTH_INFO *pGameMsg = new SMSG_BOOTH_INFO;
pGameMsg->bIsWatch = true;
pGameMsg->bIsSell = ( pMsg->type == 1 );
pGameMsg->hTarget = pMsg->target;
TS_SC_WATCH_BOOTH::TS_BOOTH_ITEM_INFO *pInfo = reinterpret_cast< TS_SC_WATCH_BOOTH::TS_BOOTH_ITEM_INFO * >( pMsg + 1 );
for( size_t idx = 0; idx < pMsg->cnt; ++idx, ++pInfo )
{
pGameMsg->vList.push_back( *pInfo );
}
m_QueueGame.push( pGameMsg );
}
void SGameVM::onBoothTradeInfo( struct TS_SC_BOOTH_TRADE_INFO* pMsg )
{
SMSG_BOOTH_TRADE_INFO *pGameMsg = new SMSG_BOOTH_TRADE_INFO;
pGameMsg->hTarget = pMsg->target;
pGameMsg->bIsSell = pMsg->is_sell;
TS_BOOTH_TRADE_ITEM_INFO *pInfo = reinterpret_cast< TS_BOOTH_TRADE_ITEM_INFO * >( pMsg + 1 );
for( int idx = 0; idx < pMsg->cnt; ++idx, ++pInfo )
{
pGameMsg->vList.push_back( *pInfo );
}
m_QueueGame.push( pGameMsg );
}
void SGameVM::onBoothName( TS_SC_GET_BOOTHS_NAME* pMsg )
{
TS_SC_GET_BOOTHS_NAME::TS_BOOTH_NAME *pBoothName = reinterpret_cast< TS_SC_GET_BOOTHS_NAME::TS_BOOTH_NAME * >( pMsg + 1 );
SMSG_BOOTH_NAME *pNameMsg = new SMSG_BOOTH_NAME;
for( size_t idx = 0; idx < pMsg->cnt; ++idx, ++pBoothName )
{
pNameMsg->vBoothName.push_back( *pBoothName );
}
m_QueueGame.push( pNameMsg );
}
void SGameVM::OnState ( struct TS_SC_STATE* pMsg )
{
// _oprint( "OnState : 상태 이상~\n" );
SMSG_STATE * pState = new SMSG_STATE;
pState->handle = pMsg->handle;
pState->state_handle = pMsg->state_handle;
pState->state_code = pMsg->state_code;
pState->state_level = pMsg->state_level;
pState->end_time = pMsg->end_time;
pState->start_time = pMsg->start_time;
if ( pMsg->state_code == 9006 )
pState->state_value = pMsg->state_value - 100;// -100 >> 혹시 수치가 잘못들어오거나 하면 바로 서버로 문의. 서버와 맞춘거임..
else
pState->state_value = pMsg->state_value;
/// 2011.07.28 redmine #16797 소환수 이름에서 강화 레벨을 구한다 - prodongi
std::vector<std::string> stringList;
MsgSplit(pMsg->state_string_value, stringList, L"|");
if (0 < stringList.size()) pState->state_string_value = stringList[0];
if (1 < stringList.size()) pState->disguiseEnhance = atoi(stringList[1].c_str());
stringList.clear();
if( pState->end_time == (AR_TIME)(-1) )
{ //토글형 스킬 임
pState->isToggle = true;
}
m_QueueGame.push( pState );
}
void SGameVM::OnStatusChange( TS_SC_STATUS_CHANGE* pMsg )
{
SMSG_STATUS_CHANGE * pStatusChange = new SMSG_STATUS_CHANGE;
pStatusChange->handle = pMsg->handle;
pStatusChange->status = pMsg->status;
m_QueueGame.push( pStatusChange );
}
/*
void SGameVM::OnHP ( struct TS_SC_HP* pMsg )
{
//여기가 0 일때만 죽는다.
_oprint( " OnHP : %d %u\n", pMsg->hp, pMsg->handle );
SMSG_HP * pHP = new SMSG_HP;
pHP->handle = pMsg->handle;
pHP->hp = pMsg->hp;
pHP->hp_percentage = pMsg->hp_percentage;
m_QueueGame.push( pHP );
}
void SGameVM::OnMP ( struct TS_SC_MP* pMsg )
{
SMSG_MP * pMP = new SMSG_MP;
pMP->handle = pMsg->handle;
pMP->mp = pMsg->mp;
m_QueueGame.push( pMP );
}
*/
void SGameVM::OnRegenHPMP( struct TS_SC_REGEN_HPMP* pMsg )
{
SMSG_REGEN_HPMP* pRegenHpMp = new SMSG_REGEN_HPMP;
pRegenHpMp->handle = pMsg->handle;
pRegenHpMp->hp = pMsg->hp;
pRegenHpMp->mp = pMsg->mp;
pRegenHpMp->hp_regen = pMsg->hp_regen;
pRegenHpMp->mp_regen = pMsg->mp_regen;
m_QueueGame.push( pRegenHpMp );
}
void SGameVM::OnSP( struct TS_SC_SP* pMsg )
{
SMSG_SP* pSP = new SMSG_SP;
pSP->handle = pMsg->handle;
pSP->sp = pMsg->sp;
pSP->max_sp = pMsg->max_sp;
m_QueueGame.push( pSP );
}
void SGameVM::OnResult( TS_SC_RESULT* pMsg )
{
SMSG_RESULT * pResultMsg = new SMSG_RESULT;
pResultMsg->request_msg_id = pMsg->request_msg_id;
pResultMsg->result = pMsg->result;
pResultMsg->value = pMsg->value;
switch( pMsg->request_msg_id )
{
case TM_CS_ATTACK_REQUEST : _oprint( "Attack Request result %s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_SKILL : _oprint( "스킬 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_MOVE_REQUEST : _oprint( "이동 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_PUTON_ITEM : _oprint( "아이템 장착 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_PUTOFF_ITEM : _oprint( "아이템 해제 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_DROP_ITEM : _oprint( "아이템 버리기요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_TAKE_ITEM : _oprint( "아이템 줍기 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_ERASE_ITEM :
{
_oprint( "아이템 삭제 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
}
case TM_CS_STORAGE : _oprint( "창고 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_BUY_ITEM : _oprint( "아이템 사기 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_SELL_ITEM : _oprint( "아이템 팔기 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_USE_ITEM : _oprint( "아이템 사용 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_MIX : _oprint( "조합 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_PUTON_ITEM_SET : _oprint( "셋트장착 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_BIND_SKILLCARD : _oprint( "카드장착 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_UNBIND_SKILLCARD : _oprint( "카드해제 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_LEARN_SKILL : _oprint( "스킬배우기 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_JOB_LEVEL_UP : _oprint( "잡레벨업 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_UPDATE : _oprint( "갱신 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_SET_PROPERTY : _oprint( "프로퍼티 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_CONTACT : _oprint( "연결 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_RETURN_LOBBY : _oprint( "로비 이동 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_START_BOOTH : _oprint( "노점 개설 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
// { [sonador][3.1.3] synchronize with server message
case TM_CS_AUCTION_BID : _oprint( "경매 입찰 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_AUCTION_INSTANT_PURCHASE : _oprint( "경매 즉구 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_AUCTION_REGISTER : _oprint( "경매 등록 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_AUCTION_CANCEL : _oprint( "경매 취소 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
// }
case TM_CS_ARRANGE_ITEM : _oprint( "아이템 정렬 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break; // sonador 1.9.1 인벤토리 및 창고 정렬 기능 구현
case TM_CS_TAKEOUT_COMMERCIAL_ITEM : _oprint( "캐쉬 아이템 빼오기 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_CHECK_BOOTH_STARTABLE: _oprint( "노점 개설 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_REQUEST_RETURN_LOBBY: _oprint( "Lobby로 이동 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_REQUEST_LOGOUT: _oprint( "로그아웃 요청결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result ); break;
case TM_CS_COMPETE_REQUEST: _oprint( "대련 요청 결과-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result); break;
case TM_CS_DONATE_REWARD: _oprint( "모럴 포인트 부족-%s[%d]\n", GetErrorStr(pMsg->result), pMsg->result); break;
case TM_CS_INSTANCE_GAME_ENTER: _oprint( "Failed to enter instance game %s[%d]\n", GetErrorStr(pMsg->result), pMsg->result); break;
case TM_CS_HUNTAHOLIC_CREATE_INSTANCE : _oprint( "Room creation failed: not enough Bearload plays %s[%d]\n", GetErrorStr(pMsg->result), pMsg->result); break;
case TM_CS_HUNTAHOLIC_JOIN_INSTANCE : _oprint( "Failed to enter due to insufficient Bearload play count %s[%d]\n", GetErrorStr(pMsg->result), pMsg->result); break;
/// 2011.05.12 우클릭 유도 - prodongi
case TM_CS_SUMMON_CARD_SKILL_LIST: _oprint("TM_CS_SUMMON_CARD_SKILL_LIST Request Result: %s[%d]\n", GetErrorStr(pMsg->result), pMsg->result); break;
default : _oprint( "Result of MSG ID: %d - %s[%d]\n", pMsg->request_msg_id, GetErrorStr(pMsg->result), pMsg->result ); break;
}
m_QueueGame.push( pResultMsg );
}
void SGameVM::onMsgMove( TS_MOVE* pMsg )
{
SMSG_MOVE * pMoveMsg = new SMSG_MOVE;
pMoveMsg->handle = pMsg->handle;
pMoveMsg->speed = pMsg->speed;
// pMoveMsg->pos_target = K3DVector( pMsg->tx, pMsg->ty, pMsg->tz );
if( pMsg->count > 0 )
{
char * pBuff = (char *)(pMsg+1);
TS_MOVE::MOVE_INFO* pMoveinfo = (reinterpret_cast< TS_MOVE::MOVE_INFO* >( pBuff ));
for( int i(0); i < pMsg->count; i++ )
{
//_oprint( "%u onMsgMove %d %f %f\n", pMoveMsg->handle, pMoveMsg->speed, pMoveinfo[i].tx, pMoveinfo[i].ty );
pMoveMsg->m_vecMoveInfo.push_back( ArPosition( pMoveinfo[i].tx, pMoveinfo[i].ty, 0 ) );
}
pMoveMsg->pos_target = K3DVector( pMoveMsg->m_vecMoveInfo.back().x, pMoveMsg->m_vecMoveInfo.back().y, pMoveMsg->m_vecMoveInfo.back().z );
#ifdef _DEV
//int lcount = pMsg->count - 1;
//_oprint( "%u onMsgMove %d %f %f\n", pMoveMsg->handle, pMoveMsg->speed, pMoveinfo[lcount].tx, pMoveinfo[lcount].ty );
#endif
}
m_QueueGame.push( pMoveMsg );
}
void SGameVM::onMsgMoveAck( TS_MOVE_ACK* pMsg )
{
// _oprint( "이동 응답\n" );
SMSG_MOVE_ACK * pMoveAckMsg = new SMSG_MOVE_ACK;
pMoveAckMsg->time = pMsg->time;
pMoveAckMsg->speed = pMsg->speed;
m_QueueGame.push( pMoveAckMsg );
}
void SGameVM::onMsgRegionAck( TS_REGION_ACK* pMsg )
{
SMSG_REGION_ACK * pRegionAckMsg = new SMSG_REGION_ACK;
pRegionAckMsg->rx = pMsg->rx;
pRegionAckMsg->ry = pMsg->ry;
m_QueueGame.push( pRegionAckMsg );
}
void SGameVM::onMsgLeave( TS_LEAVE * pMsg )
{
// _oprint( "Msg Leave \n" );
SMSG_LEAVE * pLeaveMsg = new SMSG_LEAVE;
pLeaveMsg->handle = pMsg->handle;
m_QueueGame.push( pLeaveMsg );
}
void SGameVM::onMsgEnter( TS_ENTER * pMsg )
{
SMSG_ENTER entermsg;
entermsg.handle = pMsg->handle;
entermsg.type = pMsg->type;
entermsg.x = pMsg->x;
entermsg.y = pMsg->y;
entermsg.z = pMsg->z;
entermsg.layer = pMsg->layer;
entermsg.ObjType = pMsg->ObjType;
char * pEnterMsg = NULL;
assert( sizeof(SMSG_ENTER::CreatureInfo) == sizeof(TS_ENTER::CreatureInfo) );
assert( sizeof(SMSG_ENTER::PlayerInfo) == sizeof(TS_ENTER::PlayerInfo) );
assert( sizeof(SMSG_ENTER::NPCInfo) == sizeof(TS_ENTER::NPCInfo) );
assert( sizeof(SMSG_ENTER::MonsterInfo) == sizeof(TS_ENTER::MonsterInfo) );
assert( sizeof(SMSG_ENTER::ItemInfo) == sizeof(TS_ENTER::ItemInfo) );
assert( sizeof(SMSG_ENTER::SummonInfo) == sizeof(TS_ENTER::SummonInfo) );
assert( sizeof(SMSG_ENTER::SkillInfo) == sizeof(TS_ENTER::SkillInfo) );
assert( sizeof(SMSG_ENTER::FieldPropInfo) == sizeof(TS_ENTER::FieldPropInfo) );
// Fraun performance tweak
switch (entermsg.ObjType)
{
case TS_ENTER::GAME_PLAYER:
{
pEnterMsg = new char[sizeof(SMSG_ENTER) + sizeof(SMSG_ENTER::PlayerInfo)];
memcpy(pEnterMsg, &entermsg, sizeof(SMSG_ENTER));
TS_ENTER::PlayerInfo* pContent = (TS_ENTER::PlayerInfo*)(pMsg + 1);
memcpy(&pEnterMsg[sizeof(SMSG_ENTER)], pContent, sizeof(SMSG_ENTER::PlayerInfo));
if (!IsValidSex(pContent->sex) || !IsValidRace(pContent->race))
{
assert(pContent->sex);
assert(pContent->race);
_oprint("Enter : Name[%s] Sex[%d] Race[%d]\n", pContent->szName, pContent->sex, pContent->race);
SAFE_DELETE(pEnterMsg);
return;
}
break;
}
case TS_ENTER::GAME_NPC:
{
pEnterMsg = new char[sizeof(SMSG_ENTER) + sizeof(SMSG_ENTER::NPCInfo)];
memcpy(pEnterMsg, &entermsg, sizeof(SMSG_ENTER));
TS_ENTER::NPCInfo* pContent = (TS_ENTER::NPCInfo*)(pMsg + 1);
memcpy(&pEnterMsg[sizeof(SMSG_ENTER)], pContent, sizeof(SMSG_ENTER::NPCInfo));
break;
}
case TS_ENTER::GAME_ITEM:
{
pEnterMsg = new char[sizeof(SMSG_ENTER) + sizeof(SMSG_ENTER::ItemInfo)];
memcpy(pEnterMsg, &entermsg, sizeof(SMSG_ENTER));
TS_ENTER::ItemInfo* pContent = (TS_ENTER::ItemInfo*)(pMsg + 1);
memcpy(&pEnterMsg[sizeof(SMSG_ENTER)], pContent, sizeof(SMSG_ENTER::ItemInfo));
break;
}
case TS_ENTER::GAME_MOB:
{
pEnterMsg = new char[sizeof(SMSG_ENTER) + sizeof(SMSG_ENTER::MonsterInfo)];
memcpy(pEnterMsg, &entermsg, sizeof(SMSG_ENTER));
TS_ENTER::MonsterInfo* pContent = (TS_ENTER::MonsterInfo*)(pMsg + 1);
memcpy(&pEnterMsg[sizeof(SMSG_ENTER)], pContent, sizeof(SMSG_ENTER::MonsterInfo));
break;
}
case TS_ENTER::GAME_SUMMON:
{
pEnterMsg = new char[sizeof(SMSG_ENTER) + sizeof(SMSG_ENTER::SummonInfo)];
memcpy(pEnterMsg, &entermsg, sizeof(SMSG_ENTER));
TS_ENTER::SummonInfo* pContent = (TS_ENTER::SummonInfo*)(pMsg + 1);
memcpy(&pEnterMsg[sizeof(SMSG_ENTER)], pContent, sizeof(SMSG_ENTER::SummonInfo));
break;
}
case TS_ENTER::GAME_SKILL_PROP:
{
pEnterMsg = new char[sizeof(SMSG_ENTER) + sizeof(SMSG_ENTER::SkillInfo)];
memcpy(pEnterMsg, &entermsg, sizeof(SMSG_ENTER));
TS_ENTER::SkillInfo* pContent = (TS_ENTER::SkillInfo*)(pMsg + 1);
memcpy(&pEnterMsg[sizeof(SMSG_ENTER)], pContent, sizeof(SMSG_ENTER::SkillInfo));
break;
}
case TS_ENTER::GAME_FIELD_PROP:
{
pEnterMsg = new char[sizeof(SMSG_ENTER) + sizeof(SMSG_ENTER::FieldPropInfo)];
memcpy(pEnterMsg, &entermsg, sizeof(SMSG_ENTER));
TS_ENTER::FieldPropInfo* pContent = (TS_ENTER::FieldPropInfo*)(pMsg + 1);
memcpy(&pEnterMsg[sizeof(SMSG_ENTER)], pContent, sizeof(SMSG_ENTER::FieldPropInfo));
break;
}
case TS_ENTER::GAME_PET:
{
pEnterMsg = new char[sizeof(SMSG_ENTER) + sizeof(SMSG_ENTER::PetInfo)];
memcpy(pEnterMsg, &entermsg, sizeof(SMSG_ENTER));
TS_ENTER::PetInfo* pContent = (TS_ENTER::PetInfo*)(pMsg + 1);
memcpy(&pEnterMsg[sizeof(SMSG_ENTER)], pContent, sizeof(SMSG_ENTER::PetInfo));
break;
}
}
if( pEnterMsg )
{
m_QueueGame.push( (SMSG_ENTER*)pEnterMsg );
}
}
void SGameVM::onMsgLogin( TS_LOGIN_RESULT * pMsg )
{
_oprint( "Login Msg : %u\n", pMsg->handle );
// 2010.06.11 테스트 - prodongi
//pMsg->result = RESULT_DB_ERROR;
// 2010.05.20 - prodongi
//if( pMsg->bIsAccepted == false || pMsg->bIsAccepted == 0 )
if( pMsg->result != RESULT_SUCCESS )
{
// 2010.06.11 - prodongi
/*
#ifndef _RELEASE
MessageBox( 0, "Login Fail!", "Rappelz-Login Error", MB_OK|MB_ICONERROR );
#endif
SetWindowText( g_hWnd, "Login Fail" );
_oprint( "Login Fail!\n" );
// // bintitle. 2010.06.10.
// 비정상 좌표 로그인 처리.
bool bError = false;
int nErrString = 0;
// 에러 상태 검사.
switch( pMsg->result )
{
case RESULT_DB_ERROR: bError = true; nErrString = 0; break; // 1번 스트링 출력 팝업 창 띄운 후 확인 버튼 클릭 시 클라이언트 종료
case RESULT_NOT_ACTABLE_HERE: bError = true; nErrString = 1; break; // 2번 스트링 출력 팝업 창 띄운 후 확인 버튼 클릭 시 클라이언트 종료
case RESULT_NOT_EXIST: bError = true; nErrString = 2; break; // 3번 스트링 출력 팝업 창 띄운 후 확인 버튼 클릭 시 클라이언트 종료
default:
}
// 로그인 에러 발생. 로딩화면 에러출력.
if( bError )
{
// TEST 용.
char arrStr[][128] = { "DB_ERROR", "NOT_ACTABLE_HERE", "NOT_EXIST" }; // string db 필요.
MessageBox( 0, arrStr[ nErrString ], "Rappelz-Login Error", MB_OK );
m_pGameManager->GameExit();
exit(0);
}
*/
int nErrString;
switch( pMsg->result )
{
case RESULT_DB_ERROR: nErrString = 146; break; // 1번 스트링 출력 팝업 창 띄운 후 확인 버튼 클릭 시 클라이언트 종료
case RESULT_NOT_ACTABLE_HERE: nErrString = 147; break; // 2번 스트링 출력 팝업 창 띄운 후 확인 버튼 클릭 시 클라이언트 종료
case RESULT_NOT_EXIST: nErrString = 147; break; // 3번 스트링 출력 팝업 창 띄운 후 확인 버튼 클릭 시 클라이언트 종료
default: nErrString = 0;
}
m_pGameManager->InterfaceMsg(&SIMSG_REQ_OPEN_MSGBOX(SIMSG_REQ_OPEN_MSGBOX::MSGBOX_LOGIN_ERR, S(nErrString)));
return;
}
SMSG_LOGIN * pLoginMsg = new SMSG_LOGIN;
// 2010.05.20 - prodongi
//pLoginMsg->bIsAccepted = pMsg->result;
pLoginMsg->result = pMsg->result;
pLoginMsg->handle = pMsg->handle;
pLoginMsg->x = pMsg->x;
pLoginMsg->y = pMsg->y;
pLoginMsg->z = pMsg->z;
pLoginMsg->layer = pMsg->layer;
pLoginMsg->face_direction = pMsg->face_direction;
pLoginMsg->region_size = pMsg->region_size;
pLoginMsg->hp = pMsg->hp;
pLoginMsg->mp = pMsg->mp;
pLoginMsg->max_hp = pMsg->max_hp;
pLoginMsg->max_mp = pMsg->max_mp;
pLoginMsg->sex = pMsg->sex;
pLoginMsg->skin_color = pMsg->skin_color;
pLoginMsg->race = pMsg->race;
pLoginMsg->faceid = pMsg->faceid;
pLoginMsg->hairid = pMsg->hairid;
memcpy( pLoginMsg->szName, pMsg->szName, sizeof(pMsg->szName) );
pLoginMsg->cell_size = pMsg->cell_size;
pLoginMsg->guild_id = pMsg->guild_id;
pLoginMsg->back_board = pMsg->back_board;
//pLoginMsg->hairColorIndex = pMsg->hair_color_index;
// 2010.04.22 - prodongi
pLoginMsg->hairColorIndex = GetSelectedAvatarInfo().m_hairColorIndex;
pLoginMsg->hairColorRGB = GetSelectedAvatarInfo().m_hairColorRgb;
// 2010.05.20 - prodongi
pLoginMsg->hideEquipInfo = GetSelectedAvatarInfo().m_hideEquipInfo;
m_hLocal = pMsg->handle;
m_QueueGame.push( pLoginMsg );
}
void SGameVM::onMsgHairInfo( struct TS_SC_HAIR_INFO* pMsg)
{
SMSG_HAIR_INFO* pHairInfoMsg = new SMSG_HAIR_INFO;
pHairInfoMsg->hPlayer = pMsg->hPlayer;
pHairInfoMsg->nHairID = pMsg->nHairID;
pHairInfoMsg->nHairColorIndex = pMsg->nHairColorIndex;
pHairInfoMsg->nHairColorRGB = pMsg->nHairColorRGB;
m_QueueGame.push( pHairInfoMsg );
}
void SGameVM::onMsgCharacterList( struct TS_SC_CHARACTER_LIST* pMsg )
{
SMSG_CHARLIST* pCharListMsg = new SMSG_CHARLIST;
pCharListMsg->current_server_time = pMsg->current_server_time; //시간
pCharListMsg->last_login_index = pMsg->last_login_index; //마지막 캐릭터 인덱스
pCharListMsg->nCharCount = pMsg->count;
pCharListMsg->pCharInfo = new LOBBY_CHARACTER_INFO[ pMsg->count ];
::memcpy( pCharListMsg->pCharInfo, ((BYTE*)pMsg) + sizeof(TS_SC_CHARACTER_LIST), sizeof(LOBBY_CHARACTER_INFO) * pMsg->count );
m_QueueGame.push( pCharListMsg );
}
void SGameVM::onMsgTimeSync( TS_TIMESYNC * pMsg )
{
STMSG_TIMESYNC * pTimeSyncMsg = new STMSG_TIMESYNC;
pTimeSyncMsg->time = pMsg->time;
m_QueueGame.push( pTimeSyncMsg );
}
void SGameVM::OnDoubleAttackEvent( TS_DOUBLE_WEAPON_ATTACK_EVENT * pMsg )
{
SMSG_ATTACK_DOUBLE * pAttackDouble = new SMSG_ATTACK_DOUBLE;
pAttackDouble->attacker_handle = pMsg->attacker_handle;
pAttackDouble->target_handle = pMsg->target_handle;
pAttackDouble->right_hand_damage = pMsg->right_hand_damage;
pAttackDouble->left_hand_damage = pMsg->left_hand_damage;
pAttackDouble->hp_percentage = pMsg->hp_percentage;
pAttackDouble->attack_speed = pMsg->attack_speed;
//추가 데미지 추가
pAttackDouble->flag = pMsg->flag;
for( int i(0); CreatureElemental::ElementalType::COUNT>i; i++ )
pAttackDouble->right_hand_elemental_damage[i] = pMsg->right_hand_elemental_damage[i];
for( int i(0); CreatureElemental::ElementalType::COUNT>i; i++ )
pAttackDouble->left_hand_elemental_damage[i] = pMsg->left_hand_elemental_damage[i];
m_QueueGame.push( pAttackDouble );
}
void SGameVM::onAttackEvent( TS_ATTACK_EVENT * pMsg )
{
SMSG_ATTACK * pAttackMsg = new SMSG_ATTACK;
pAttackMsg->attacker_handle = pMsg->attacker_handle;
pAttackMsg->target_handle = pMsg->target_handle;
pAttackMsg->attack_speed = pMsg->attack_speed;
pAttackMsg->attack_delay = pMsg->attack_delay;
pAttackMsg->attack_action = pMsg->attack_action;
pAttackMsg->attack_flag = pMsg->attack_flag;
pAttackMsg->count = pMsg->count;
if( pAttackMsg->attack_action == TS_ATTACK_EVENT::ATTACK_END ||
pAttackMsg->attack_action == TS_ATTACK_EVENT::ATTACK_CANCEL )
{
if( pAttackMsg->target_handle == 0 )
pAttackMsg->target_handle = pAttackMsg->attacker_handle;
}
if( pMsg->count > 0 )
{
char * pBuff = (char *)(pMsg+1);
ATTACK_INFO * pAttackInfo = (reinterpret_cast< ATTACK_INFO* >( pBuff ));
for( int i(0); i < pMsg->count; i++ )
{
pAttackMsg->m_vAttackInfoList.push_back( pAttackInfo[i] );
}
}
m_QueueGame.push( pAttackMsg );
}
void SGameVM::onCantAttack( TS_SC_CANT_ATTACK* pMsg )
{
SMSG_CANT_ATTACK * pCantAttack = new SMSG_CANT_ATTACK;
pCantAttack->attacker_handle = pMsg->attacker_handle;
pCantAttack->target_handle = pMsg->target_handle;
pCantAttack->reason = pMsg->reason;
m_QueueGame.push( pCantAttack );
}
void SGameVM::OnGoldUpdate ( struct TS_SC_GOLD_UPDATE* pMsg)
{
SMSG_GOLD_UPDATE * pGoldUpdate = new SMSG_GOLD_UPDATE;
pGoldUpdate->gold = money_t( pMsg->gold );
pGoldUpdate->chaos = pMsg->chaos;
m_QueueGame.push( pGoldUpdate );
}
void SGameVM::OnLevelUpdate ( struct TS_SC_LEVEL_UPDATE* pMsg)
{
_oprint( "!!!! SGameVM::OnLevelUpdate [handle:%u],[lv:%d],[jl:%d]\n", pMsg->handle, pMsg->level, pMsg->job_level );
SMSG_LEVEL_UPDATE * pLevelUpdate = new SMSG_LEVEL_UPDATE;
pLevelUpdate->handle = pMsg->handle;
pLevelUpdate->level = pMsg->level;
pLevelUpdate->job_level = pMsg->job_level;
m_QueueGame.push( pLevelUpdate );
}
void SGameVM::OnExpUpdate ( struct TS_SC_EXP_UPDATE* pMsg)
{
SMSG_EXP_UPDATE * pExpUpdate = new SMSG_EXP_UPDATE;
pExpUpdate->handle = pMsg->handle;
pExpUpdate->exp = pMsg->exp;
pExpUpdate->jp = pMsg->jp;
m_QueueGame.push( pExpUpdate );
}
void SGameVM::OnBonusExpUpdate( struct TS_SC_BONUS_EXP_JP* pMsg )
{
SMSG_BONUS_EXP_JP* pBonusExpjp = new SMSG_BONUS_EXP_JP;
char * pBuff = (char *)(pMsg+1);
for( int i(0); pMsg->count > i; ++i )
{
TS_SC_BONUS_EXP_JP::BONUS_INFO* pBonusInfo = reinterpret_cast< TS_SC_BONUS_EXP_JP::BONUS_INFO * >(pBuff);
pBonusExpjp->m_vBonusInfo.push_back( *pBonusInfo );
pBuff += sizeof( TS_SC_BONUS_EXP_JP::BONUS_INFO );
}
m_QueueGame.push( pBonusExpjp );
}
void SGameVM::OnStatInfo ( TS_SC_STAT_INFO* pMsg )
{
SMSG_STAT_INFO * pStatMsg = new SMSG_STAT_INFO;
pStatMsg->handle = pMsg->handle;
memcpy( &pStatMsg->stat , &pMsg->stat , sizeof(pStatMsg->stat ) );
memcpy( &pStatMsg->attribute, &pMsg->attribute, sizeof(pStatMsg->attribute) );
pStatMsg->type = pMsg->type;
m_QueueGame.push( pStatMsg );
}
void SGameVM::OnAddSummonInfo ( struct TS_SC_ADD_SUMMON_INFO* pMsg )
{
SMSG_ADD_SUMMON_INFO * pAddSummonInfo = new SMSG_ADD_SUMMON_INFO;
pAddSummonInfo->card_handle = pMsg->card_handle;
pAddSummonInfo->summon_handle = pMsg->summon_handle;
memcpy( pAddSummonInfo->name, pMsg->name, sizeof(pMsg->name) );
pAddSummonInfo->code = pMsg->code;
// 이하 정보 필요
pAddSummonInfo->level = pMsg->level;
pAddSummonInfo->sp = pMsg->sp;
m_QueueGame.push( pAddSummonInfo );
}
void SGameVM::OnRemoveSummonInfo( struct TS_SC_REMOVE_SUMMON_INFO* pMsg)
{
SMSG_REMOVE_SUMMON_INFO * pRemoveSummonInfo = new SMSG_REMOVE_SUMMON_INFO;
pRemoveSummonInfo->card_handle = pMsg->card_handle;
m_QueueGame.push( pRemoveSummonInfo );
}
void SGameVM::OnEquipSummonInfo ( struct TS_EQUIP_SUMMON* pMsg )
{
SMSG_EQUIP_SUMMON * pEquipSummon = new SMSG_EQUIP_SUMMON;
for( int i(0); 6>i; i++ )
pEquipSummon->card_handle[i] = pMsg->card_handle[ i ];
pEquipSummon->open_dialog = pMsg->open_dialog;
m_QueueGame.push( pEquipSummon );
}
void SGameVM::OnUnsummon ( struct TS_SC_UNSUMMON* pMsg )
{
SMSG_UNSUMMON * pUnSummon = new SMSG_UNSUMMON;
pUnSummon->summon_handle = pMsg->summon_handle;
m_QueueGame.push( pUnSummon );
}
void SGameVM::OnUnsummonNotice ( struct TS_SC_UNSUMMON_NOTICE* pMsg )
{
SMSG_UNSUMMON_NOTICE * pUnSummonNotice = new SMSG_UNSUMMON_NOTICE;
pUnSummonNotice->summon_handle = pMsg->summon_handle;
pUnSummonNotice->unsummon_duration = pMsg->unsummon_duration;
m_QueueGame.push( pUnSummonNotice );
}
void SGameVM::OnSummonEvolution( struct TS_SC_SUMMON_EVOLUTION* pMsg )
{
SMSG_SUMMON_EVOLUTION* pSummonEvolution = new SMSG_SUMMON_EVOLUTION;
pSummonEvolution->card_handle = pMsg->card_handle;
pSummonEvolution->summon_handle = pMsg->summon_handle;
memcpy( pSummonEvolution->name, pMsg->name, sizeof(pMsg->name) );
pSummonEvolution->code = pMsg->code;
m_QueueGame.push( pSummonEvolution );
}
void SGameVM::OnTamingInfo ( struct TS_SC_TAMING_INFO* pMsg )
{
SMSG_TAMING_INFO * pTamingInfo = new SMSG_TAMING_INFO;
pTamingInfo->mode = pMsg->mode;
pTamingInfo->tamer_handle = pMsg->tamer_handle;
pTamingInfo->target_handle = pMsg->target_handle;
m_QueueGame.push( pTamingInfo );
}
void SGameVM::OnMountSummon( struct TS_SC_MOUNT_SUMMON* pMsg )
{
SMSG_MOUNT_SUMMON* pMountSummon = new SMSG_MOUNT_SUMMON;
pMountSummon->handle = pMsg->handle;
pMountSummon->summon_handle = pMsg->summon_handle;
pMountSummon->x = pMsg->x;
pMountSummon->y = pMsg->y;
pMountSummon->success = pMsg->success; //성공/실패
m_QueueGame.push( pMountSummon );
}
void SGameVM::OnUnMountSummon( struct TS_SC_UNMOUNT_SUMMON* pMsg )
{
SMSG_UNMOUNT_SUMMON* pUnMountSummon = new SMSG_UNMOUNT_SUMMON;
pUnMountSummon->handle = pMsg->handle;
pUnMountSummon->summon_handle = pMsg->summon_handle;
pUnMountSummon->flag = pMsg->flag; //낙마
m_QueueGame.push( pUnMountSummon );
}
void SGameVM::OnSummonNameChange( struct TS_SC_SHOW_SUMMON_NAME_CHANGE* pMsg )
{
SMSG_SUMMON_NAME_CHANGE* pSummonNameChange = new SMSG_SUMMON_NAME_CHANGE;
pSummonNameChange->summon_handle = pMsg->handle;
m_QueueGame.push( pSummonNameChange );
}
// sonador 10.2.1 팻 시스템 구현
void SGameVM::OnUnsummonPet( struct TS_SC_UNSUMMON_PET* pMsg )
{
SMSG_UNSUMMON_PET* pUnsummonPet = new SMSG_UNSUMMON_PET;
pUnsummonPet->pet_handle = pMsg->handle;
m_QueueGame.push( pUnsummonPet );
}
void SGameVM::OnAddPetInfo( struct TS_SC_ADD_PET_INFO* pMsg )
{
SMSG_ADD_PET_INFO* pAddPetInfo = new SMSG_ADD_PET_INFO;
pAddPetInfo->cage_handle = pMsg->cage_handle;
pAddPetInfo->pet_handle = pMsg->pet_handle;
pAddPetInfo->code = pMsg->code;
::memcpy( pAddPetInfo->name, pMsg->name, sizeof( pMsg->name ) );
m_QueueGame.push( pAddPetInfo );
}
void SGameVM::OnRemovePetInfo( struct TS_SC_REMOVE_PET_INFO* pMsg )
{
SMSG_REMOVE_PET_INFO* pRemovePetInfo = new SMSG_REMOVE_PET_INFO;
pRemovePetInfo->pet_handle = pMsg->handle;
m_QueueGame.push( pRemovePetInfo );
}
void SGameVM::OnShowSetPetName( struct TS_SC_SHOW_SET_PET_NAME* pMsg )
{
SMSG_SHOW_SET_PET_NAME* pShowSetPetName = new SMSG_SHOW_SET_PET_NAME;
pShowSetPetName->pet_handle = pMsg->handle;
m_QueueGame.push( pShowSetPetName );
}
void SGameVM::OnSkillEvent ( TS_SC_SKILL* pMsg )
{
SMSG_SKILL_EVENT * pSkillEvent = new SMSG_SKILL_EVENT;
pSkillEvent->skill_id = pMsg->skill_id ;
pSkillEvent->skill_level = pMsg->skill_level;
pSkillEvent->caster = pMsg->caster ;
pSkillEvent->target = pMsg->target ;
pSkillEvent->x = pMsg->x ;
pSkillEvent->y = pMsg->y ;
pSkillEvent->z = pMsg->z ;
pSkillEvent->layer = pMsg->layer ;
pSkillEvent->status_type = pMsg->type ;
pSkillEvent->hp_cost = pMsg->hp_cost;
pSkillEvent->mp_cost = pMsg->mp_cost;
pSkillEvent->caster_hp = pMsg->caster_hp;
pSkillEvent->caster_mp = pMsg->caster_mp;
//_oprint( "냥냥 스킬 썼당~~ state : %d, count : %d\n", pMsg->type, pMsg->count );
// Fraun performance tweak
switch (pSkillEvent->status_type)
{
case TS_SC_SKILL::FIRE:
case TS_SC_SKILL::REGION_FIRE:
{
pSkillEvent->fire.bMultiple = pMsg->fire.bMultiple;
pSkillEvent->fire.count = pMsg->fire.count;
pSkillEvent->fire.range = pMsg->fire.range;
pSkillEvent->fire.target_count = pMsg->fire.target_count;
pSkillEvent->fire.fire_count = pMsg->fire.fire_count;
if (pMsg->fire.count > 0)
{
char* pBuff = (char*)(pMsg + 1);
for (int i(0); pMsg->fire.count > i; i++)
{
SkillResult* pSkillResultArray = reinterpret_cast<SkillResult*>(pBuff);
SkillResult skill_result;
switch (pSkillResultArray->GetType())
{
case SkillResult::DAMAGE:
case SkillResult::MAGIC_DAMAGE:
{
skill_result.damage = *(reinterpret_cast<SkillResult::DamageType*>(pSkillResultArray));
pSkillEvent->vSkillResult.push_back(skill_result);
pBuff += sizeof(SkillResult::DamageType);
break;
}
case SkillResult::DAMAGE_WITH_KNOCK_BACK:
{
skill_result.damage_kb = *(reinterpret_cast<SkillResult::DamageWithKnockBackType*>(pSkillResultArray));
pSkillEvent->vSkillResult.push_back(skill_result);
pBuff += sizeof(SkillResult::DamageWithKnockBackType);
break;
}
case SkillResult::RESULT:
{
skill_result.result = *(reinterpret_cast<SkillResult::ResultType*>(pSkillResultArray));
pSkillEvent->vSkillResult.push_back(skill_result);
pBuff += sizeof(SkillResult::ResultType);
break;
}
case SkillResult::ADD_HP:
case SkillResult::ADD_MP:
{
skill_result.add_hp = *(reinterpret_cast<SkillResult::AddHPType*>(pSkillResultArray));
pSkillEvent->vSkillResult.push_back(skill_result);
pBuff += sizeof(SkillResult::AddHPType);
break;
}
case SkillResult::ADD_HP_MP_SP:
{
skill_result.add_hp_mp_sp = *(reinterpret_cast<SkillResult::AddHPMPSPType*>(pSkillResultArray));
pSkillEvent->vSkillResult.push_back(skill_result);
pBuff += sizeof(SkillResult::AddHPMPSPType);
break;
}
case SkillResult::RUSH:
{
skill_result.rush = *(reinterpret_cast<SkillResult::RushType*>(pSkillResultArray));
pSkillEvent->vSkillResult.push_back(skill_result);
pBuff += sizeof(SkillResult::RushType);
break;
}
case SkillResult::REBIRTH:
{
skill_result.rebirth = *(reinterpret_cast<SkillResult::RebirthType*>(pSkillResultArray));
pSkillEvent->vSkillResult.push_back(skill_result);
pBuff += sizeof(SkillResult::RebirthType);
break;
}
case SkillResult::CHAIN_DAMAGE:
case SkillResult::CHAIN_MAGIC_DAMAGE:
{
skill_result.chain_damage = *(reinterpret_cast<SkillResult::ChainDamageType*>(pSkillResultArray));
pSkillEvent->vSkillResult.push_back(skill_result);
pBuff += sizeof(SkillResult::ChainDamageType);
break;
}
case SkillResult::CHAIN_HEAL:
{
skill_result.chain_heal = *(reinterpret_cast<SkillResult::ChainHealType*>(pSkillResultArray));
pSkillEvent->vSkillResult.push_back(skill_result);
pBuff += sizeof(SkillResult::ChainHealType);
break;
}
}
}
}
else
{
_oprint("Check required: The skill has no damage.\n");
}
break;
}
case TS_SC_SKILL::CASTING:
{
_oprint("SGameVM-OnSkillEvent::CAST\n");
pSkillEvent->cast.nErrorCode = pMsg->cast.nErrorCode;
pSkillEvent->cast.tm = pMsg->cast.tm;
if (pMsg->cast.nErrorCode != 0)
{
_oprint("Casting Failed :: Error_Code : [%d] %s\n", pMsg->cast.nErrorCode, GetErrorStr(pMsg->cast.nErrorCode));
}
break;
}
case TS_SC_SKILL::CANCEL:
{
_oprint("SGameVM-OnSkillEvent::Cancel\n");
// If it's a casting cancel, a target is not needed.
// If the target has logged out or died, the object will be searched by the target handle.
// Since the stored data has already been deleted, this causes a problem!!!
pSkillEvent->target = pMsg->caster;
_oprint("Skill cancel\n");
break;
}
case TS_SC_SKILL::CASTING_UPDATE:
{
_oprint("SGameVM-OnSkillEvent::CASTING_UPDATE\n");
pSkillEvent->cast.nErrorCode = pMsg->cast.nErrorCode;
pSkillEvent->cast.tm = pMsg->cast.tm; //변화된 Max 값임.
break;
}
case TS_SC_SKILL::COMPLETE:
{
_oprint("SGameVM-OnSkillEvent::COMPLETE\n");
pSkillEvent->target = pMsg->caster;
break;
}
}
m_QueueGame.push( pSkillEvent );
}
void SGameVM::OnSkillList ( struct TS_SC_SKILL_LIST* pMsg )
{
_oprint( "OnSkillList : %d\n", pMsg->count );
assert( sizeof(SMSG_SKILL_LIST::SkillInfo) == sizeof(TS_SC_SKILL_LIST::SkillInfo) );
if( pMsg->count > 0 )
{
SMSG_SKILL_LIST * pSkillList = new SMSG_SKILL_LIST;
pSkillList->dwTime = m_dwTime;
pSkillList->count = pMsg->count;
pSkillList->target = pMsg->target;
pSkillList->modification_type = pMsg->modification_type; /// 2011.07.04 - prodongi
TS_SC_SKILL_LIST::SkillInfo * pSource = (TS_SC_SKILL_LIST::SkillInfo *)(pMsg+1);
pSkillList->pSkillInfo = new SMSG_SKILL_LIST::SkillInfo[pMsg->count];
for( int i(0); pMsg->count>i; i++ )
{
pSkillList->pSkillInfo[i].remain_cool_time = pSource->remain_cool_time;
pSkillList->pSkillInfo[i].skill_id = pSource->skill_id;
pSkillList->pSkillInfo[i].base_skill_level = pSource->base_skill_level;
pSkillList->pSkillInfo[i].total_cool_time = pSource->total_cool_time;
pSkillList->pSkillInfo[i].current_skill_level = pSource->current_skill_level;
/// 2011.05.04 쿨타임이 증가 했을 때 - prodongi
if (pSource->total_cool_time < pSource->remain_cool_time)
{
pSkillList->pSkillInfo[i].total_cool_time = pSource->remain_cool_time;
}
pSource++;
}
m_QueueGame.push( pSkillList );
}
else
{
SMSG_SKILL_LIST * pSkillList = new SMSG_SKILL_LIST;
pSkillList->dwTime = m_dwTime;
pSkillList->count = pMsg->count;
pSkillList->target = pMsg->target;
pSkillList->modification_type = pMsg->modification_type; /// 2011.07.04 - prodongi
m_QueueGame.push( pSkillList );
}
}
void SGameVM::OnMsgChattingLocal( TS_SC_CHAT_LOCAL* pMsg )
{
SMSG_CHATTING * chatmsg = new SMSG_CHATTING;
chatmsg->handle = pMsg->handle;
chatmsg->len = pMsg->len; //채팅 크기
chatmsg->nChatType = CHAT_NORMAL;
chatmsg->strText = (char *)(pMsg+1);
chatmsg->szSender = "Local";
// 2009.3.26 by 정동섭
// 채팅창에 #@숫자@# 식으로 치면 스트링테이블에서 해당 스트링을 꺼내오던 문제 해결 - 그냥 #@숫자@#패턴 무시
std::vector< std::string > storage;
while( nsl::regex::match( "#@([0-9]*)@#", chatmsg->strText.c_str(), &storage ) )
{
CStringUtil::ReplacePhrase( chatmsg->strText, storage[0], "" );
storage.clear();
}
#ifdef _EUROPE_TEST_
//UTF8 -> UNICODE 변환
//UNICODE -> ANSI 변환
const int BUFFER_MAX = 256;
char szText[BUFFER_MAX];
wchar_t wszBuffer[BUFFER_MAX];
MultiByteToWideChar( CP_UTF8, 0, chatmsg->strText.c_str(), -1, wszBuffer, BUFFER_MAX );
WideCharToMultiByte( 949, 0, wszBuffer, -1, szText, BUFFER_MAX, NULL, NULL );
chatmsg->strText = szText;
#endif
_performance_print( "MSG_CHATING : strlen %s --- %d\n", chatmsg->strText.c_str(), strlen(chatmsg->strText.c_str()) );
_performance_print( "MSG_CHATING : _mbstrlen %s --- %d\n", chatmsg->strText.c_str(), _mbstrlen(chatmsg->strText.c_str()) );
m_QueueGame.push( chatmsg );
}
#ifdef _DEV
char const* chatTypeToString(int type)
{
switch (type)
{
case CHAT_NORMAL: return "CHAT_NORMAL";
case CHAT_YELL: return "CHAT_YELL";
case CHAT_ADV: return "CHAT_ADV";
case CHAT_WHISPER: return "CHAT_WHISPER";
case CHAT_GLOBAL: return "CHAT_GLOBAL";
case CHAT_EMOTION: return "CHAT_EMOTION";
case CHAT_GM: return "CHAT_GM";
case CHAT_GM_WHISPER: return "CHAT_GM_WHISPER";
case CHAT_PARTY: return "CHAT_PARTY";
case CHAT_GUILD: return "CHAT_GUILD";
case CHAT_ATTACKTEAM: return "CHAT_ATTACKTEAM";
case CHAT_FRIEND: return "CHAT_FRIEND";
case CHAT_NOTICE: return "CHAT_NOTICE";
case CHAT_ANNOUNCE: return "CHAT_ANNOUNCE";
case CHAT_CENTER_NOTICE: return "CHAT_CENTER_NOTICE";
case CHAT_EXP: return "CHAT_EXP";
case CHAT_DAMAGE: return "CHAT_DAMAGE";
case CHAT_ITEM: return "CHAT_ITEM";
case CHAT_BATTLE: return "CHAT_BATTLE";
case CHAT_SUMMON: return "CHAT_SUMMON";
case CHAT_ETC: return "CHAT_ETC";
case CHAT_COMMUNITY: return "CHAT_COMMUNITY";
case CHAT_DEBUG: return "CHAT_DEBUG";
case CHAT_EXT_DAMAGE: return "CHAT_EXT_DAMAGE";
case CHAT_COMMAND: return "CHAT_COMMAND";
case CHAT_PARTY_SYSTEM: return "CHAT_PARTY_SYSTEM";
case CHAT_GUILD_SYSTEM: return "CHAT_GUILD_SYSTEM";
case CHAT_QUEST_SYSTEM: return "CHAT_QUEST_SYSTEM";
case CHAT_RAID_SYSTEM: return "CHAT_RAID_SYSTEM";
case CHAT_FRIEND_SYSTEM: return "CHAT_FRIEND_SYSTEM";
case CHAT_ALLIANCE_SYSTEM: return "CHAT_ALLIANCE_SYSTEM";
case CHAT_HUNTAHOLIC_SYSTEM:return "CHAT_HUNTAHOLIC_SYSTEM";
case CHAT_SYSTEM: return "CHAT_SYSTEM";
default: return "";
}
}
#endif
void SGameVM::OnMsgChatting ( TS_SC_CHAT* pMsg )
{
SMSG_CHATTING * chatmsg = new SMSG_CHATTING;
chatmsg->szSender = pMsg->szSender;
chatmsg->handle = 0;
chatmsg->len = pMsg->len; //채팅 크기
chatmsg->nChatType = pMsg->type; //채팅 타입
chatmsg->strText = (char *)(pMsg+1);
#ifdef _DEV
/// 2011.10.20 디버깅 때문에 - prodongi
// 로그가 너무 많이 떠서 일단 주석 처리
//_oprint("Recv Chat : %s | %s | %s\n", chatmsg->szSender.c_str(), chatTypeToString(chatmsg->nChatType), chatmsg->strText.c_str());
#endif
#ifdef _EUROPE_TEST_
//UTF8 -> UNICODE 변환
//UNICODE -> ANSI 변환
const int BUFFER_MAX = 256;
char szText[BUFFER_MAX];
wchar_t wszBuffer[BUFFER_MAX];
MultiByteToWideChar( CP_UTF8, 0, chatmsg->strText.c_str(), -1, wszBuffer, BUFFER_MAX );
WideCharToMultiByte( 949, 0, wszBuffer, -1, szText, BUFFER_MAX, NULL, NULL );
chatmsg->strText = szText;
SetWindowTextW( g_hWnd, wszBuffer );
#endif
if( stricmp( pMsg->szSender, "@SCRIPT" ) == 0 ||
stricmp( pMsg->szSender, "@NOTICE" ) == 0 ||
stricmp( pMsg->szSender, "@ANNOUNCE" ) == 0 || /// 2011.07.18
stricmp( pMsg->szSender, "@SYSTEM" ) == 0 ||
stricmp( pMsg->szSender, "@GUILD" ) == 0 ||
stricmp( pMsg->szSender, "@PARTY" ) == 0 ||
stricmp( pMsg->szSender, "@RAID" ) == 0 ||
stricmp( pMsg->szSender, "@COMMON" ) == 0 ||
stricmp( pMsg->szSender, "@FRIEND" ) == 0 ||
stricmp( pMsg->szSender, "@HUNTAHOLIC" ) == 0 ||
stricmp( pMsg->szSender, "@DUNGEON" ) == 0 )
{
#ifdef _TEMP_DEBUG_FRIEND
if( stricmp( pMsg->szSender, "@FRIEND" ) == 0 )
{
SetFileAttributes( CStringUtil::StringFormat( "friend_log_for_debug.txt", g_strModulePath.c_str() ).c_str(), FILE_ATTRIBUTE_NORMAL );
FILE* pF = fopen( CStringUtil::StringFormat( "friend_log_for_debug.txt", g_strModulePath.c_str() ).c_str(), "at" );
if( pF )
{
fprintf( pF, "%s\n", chatmsg->strText.c_str() );
fclose( pF );
}
}
#endif
ParseScriptText( chatmsg->strText );
}
m_QueueGame.push( chatmsg );
}
// 2010.05.19 HIDE_EQUIP_INFO - prodongi
void SGameVM::OnMsgHideEquipInfo(TS_SC_HIDE_EQUIP_INFO* pMsg)
{
_oprint( "--OnMsgHideEquipInfo\n" );
SMSG_HIDE_EQUIP_INFO* hideEquipInfo = new SMSG_HIDE_EQUIP_INFO;
hideEquipInfo->hPlayer = pMsg->hPlayer;
hideEquipInfo->nHideEquipFlag = pMsg->nHideEquipFlag;
m_QueueGame.push(hideEquipInfo);
}
//static AR_HANDLE lastHandle = 0xffffffff;
//static AR_TIME lastTime = 0;
void SGameVM::onWearInfo( TS_WEAR_INFO* pMsg )
{
/*
AR_TIME time = GetSafeTickCount();
if (time < lastTime + 500) //500 tick 안에 wearInfo 들어 오면 무시
{
if (lastHandle == pMsg->handle)
return;
}
//
lastHandle = pMsg->handle;
lastTime = time;
*/
//
_oprint( "--onWearInfo\n" );
SMSG_ITEM_WEAR * pItemWearMsg = new SMSG_ITEM_WEAR;
pItemWearMsg->handle = pMsg->handle;
for( int i(0); ItemBase::MAX_ITEM_SPARE_WEAR>i; i++ )
{
pItemWearMsg->nItemCode[i] = pMsg->itemCode[i];
pItemWearMsg->nItemEnhance[i] = pMsg->itemEnhance[i];
pItemWearMsg->nItemLevel[i] = pMsg->itemLevel[i];
pItemWearMsg->elemental_effect_type[i] = pMsg->elemental_effect_type[i];
pItemWearMsg->nAppearanceItemCode[i] = pMsg->appearanceItemCode[i]; // 2012. 7. 24 - marine 형상변환
}
m_QueueGame.push( pItemWearMsg );
}
void SGameVM::OnMsgInven( TS_SC_INVENTORY* pMsg )
{
_oprint( "--OnMsgInven\n" );
TS_ITEM_INFO * pItemInfo = (TS_ITEM_INFO *)(pMsg+1);
SMSG_ITEM_INVEN * pItemInvenMsg = new SMSG_ITEM_INVEN;
pItemInvenMsg->nItemCnt = pMsg->count;
pItemInvenMsg->handle = pItemInfo->handle;
if( pMsg->count > 0 )
{
pItemInvenMsg->pItemInfo = new TS_ITEM_INFO[pMsg->count];
for( unsigned short i(0); pMsg->count>i; i++ )
{
memcpy( &pItemInvenMsg->pItemInfo[i], pItemInfo, sizeof(pItemInvenMsg->pItemInfo[i]) );
pItemInfo++;
}
}
m_QueueGame.push( pItemInvenMsg );
}
void SGameVM::OnMsgOpenStorage ( struct TS_SC_OPEN_STORAGE* pMsg )
{
_oprint( "창고 열어\n" );
SMSG_OPEN_STORAGE * pOpenStorage = new SMSG_OPEN_STORAGE;
pOpenStorage->maxStorageItemCount = pMsg->maxStorageItemCount;
// pMsg;
m_QueueGame.push( pOpenStorage );
}
void SGameVM::OnMsgOpenSoulstoneCraft ( struct TS_SC_SHOW_SOULSTONE_CRAFT_WINDOW* pMsg )
{
_oprint( "보석 장착 열어\n" );
SMSG_OPEN_JEWEL_EQUIP * pOpenJewelEquip = new SMSG_OPEN_JEWEL_EQUIP;
m_QueueGame.push( pOpenJewelEquip );
}
void SGameVM::OnMsgOpenSoulstoneRepair( struct TS_SC_SHOW_SOULSTONE_REPAIR_WINDOW* pMsg )
{
_oprint( "보석 내구도 수리열어\n" );
SMSG_OPEN_SOUL_REPAIR * pOpenSoulRepair = new SMSG_OPEN_SOUL_REPAIR;
m_QueueGame.push( pOpenSoulRepair );
}
void SGameVM::onMsgDrop( TS_SC_DROP_RESULT* pMsg )
{
// if( pMsg->isAccepted == false ) return;
SMSG_ITEM_DROP * pItemDrop = new SMSG_ITEM_DROP;
pItemDrop->item_handle = pMsg->item_handle;
pItemDrop->isAccepted = pMsg->isAccepted;
m_QueueGame.push( pItemDrop );
}
//몬스터가 죽을때 보여줄 아이템 정보
void SGameVM::onMsgDropInfo ( struct TS_SC_ITEM_DROP_INFO* pMsg )
{
// _oprint( "onMsgDropInfo : 몬스터가 죽을때 보여줄 아이템 정보\n" );
SMSG_ITEM_DROP_INFO * pItemDropInfo = new SMSG_ITEM_DROP_INFO;
pItemDropInfo->item_handle = pMsg->item_handle;
pItemDropInfo->monster_handle = pMsg->monster_handle;
m_QueueGame.push( pItemDropInfo );
}
void SGameVM::onMsgSkillCardInfo( TS_SC_SKILLCARD_INFO* pMsg )
{
SMSG_SKILLCARD_INFO * pSkillCardInfo = new SMSG_SKILLCARD_INFO;
pSkillCardInfo->item_handle = pMsg->item_handle;
pSkillCardInfo->target_handle = pMsg->target_handle;
m_QueueGame.push( pSkillCardInfo );
}
void SGameVM::onItemWearInfo ( TS_SC_ITEM_WEAR_INFO* pMsg )
{
SMSG_ITEM_WEAR_INFO * pItemWearInfo = new SMSG_ITEM_WEAR_INFO;
pItemWearInfo->item_handle = pMsg->item_handle;
pItemWearInfo->wear_position = pMsg->wear_position;
pItemWearInfo->target_handle = pMsg->target_handle;
pItemWearInfo->elemental_effect_type = pMsg->elemental_effect_type;
pItemWearInfo->appearance_code = pMsg->appearance_code;
m_QueueGame.push( pItemWearInfo );
}
//Cheating
void SGameVM::OnWarp( TS_SC_WARP* pMsg )
{
// _oprint( "OnWarp\n" );
SCMSG_WARP * pWarpMsg = new SCMSG_WARP;
pWarpMsg->x = pMsg->x;
pWarpMsg->y = pMsg->y;
pWarpMsg->z = pMsg->z;
pWarpMsg->layer = pMsg->layer;
m_QueueGame.push( pWarpMsg );
/*
SMSG_INSTANCE_GAME_SCORE *pScoreMsg = new SMSG_INSTANCE_GAME_SCORE( pMsg->holicpoint, pMsg->bearroad_ranking, pMsg->deathmatch_kill_count, pMsg->deathmatch_death_count );
m_QueueGame.push( pScoreMsg);
*/
if (m_pGameManager)
//m_pGameManager->UpdateLoadingProgress(0.0f);
m_pGameManager->InitLoadingBar();
}
void SGameVM::onMarket ( struct TS_SC_MARKET* pMsg )
{
SMSG_MARKET * pMarketMsg = new SMSG_MARKET;
pMarketMsg->npc_handle = pMsg->npc_handle;
pMarketMsg->item_count = pMsg->item_count;
if( pMarketMsg->item_count )
{
TS_SC_MARKET::ItemInfo * pItemInfo = (TS_SC_MARKET::ItemInfo *)(pMsg+1);
pMarketMsg->pItemInfo = new SMSG_MARKET::ItemInfo[pMarketMsg->item_count];
memcpy( pMarketMsg->pItemInfo, pItemInfo, sizeof(TS_SC_MARKET::ItemInfo)*pMarketMsg->item_count );
}
m_QueueGame.push( pMarketMsg );
}
void SGameVM::onEraseItem( struct TS_SC_ERASE_ITEM* pMsg )
{
SMSG_ERASE_ITEM * pItem = new SMSG_ERASE_ITEM;
pItem->item_count = pMsg->item_count;
int cnt = pItem->item_count;
if( cnt )
{
TS_SC_ERASE_ITEM::EraseItemInfo * pItemInfo = reinterpret_cast< TS_SC_ERASE_ITEM::EraseItemInfo * >( pMsg + 1 );
pItem->pItemInfo = new SMSG_ERASE_ITEM::EraseItemInfo[ cnt ];
memcpy( pItem->pItemInfo, pItemInfo, sizeof( TS_SC_ERASE_ITEM::EraseItemInfo ) * cnt );
}
m_QueueGame.push( pItem );
}
void SGameVM::onDestroyItem ( struct TS_SC_DESTROY_ITEM* pMsg )
{
SMSG_ITEM_DESTROY * pItemDestroy = new SMSG_ITEM_DESTROY;
pItemDestroy->item_handle = pMsg->item_handle;
m_QueueGame.push( pItemDestroy );
}
void SGameVM::onUpdateItemCount( struct TS_SC_UPDATE_ITEM_COUNT* pMsg )
{
SMSG_UPDATE_ITEM_COUNT * pUpdateItemCount = new SMSG_UPDATE_ITEM_COUNT;
pUpdateItemCount->item_handle = pMsg->item_handle;
pUpdateItemCount->count = count_t( pMsg->count );
m_QueueGame.push( pUpdateItemCount );
}
void SGameVM::onMixResult ( struct TS_SC_MIX_RESULT* pMsg )
{
SMSG_MIX_RESULT * pMixResult = new SMSG_MIX_RESULT;
pMixResult->count = pMsg->count;
pMixResult->type = pMsg->type;
if( pMsg->count )
{
pMixResult->pArHandle = new AR_HANDLE[pMsg->count];
AR_HANDLE * pHandle = (AR_HANDLE *)(pMsg+1);
memcpy( pMixResult->pArHandle, pHandle, sizeof(AR_HANDLE)*pMsg->count );
}
m_QueueGame.push( pMixResult );
}
#ifndef NDEBUG
const char * pTrade[] = {
"REQUEST_TRADE",// = 0, // 트레이드 요청을 시작한다
"ACCEPT_TRADE",// = 1, // 트레이드 요청을 수락한다
"BEGIN_TRADE",// = 2, // 트레이드 시작
"CANCEL_TRADE",// = 3, // 트레이드 취소
"REJECT_TRADE",// = 4, // 트레이드 거부
"ADD_ITEM",// = 5, // 아이템을 올린다.
"ADD_GOLD",// = 6, // 돈을 올린다. 돈을 올릴때는 item_info 를 모두 0 으로 채우고 count 만 액수로 설정한다.
"FREEZE_TRADE",// = 7, // 확인버튼을 누른다.
"CONFIRM_TRADE",// = 8, // 최종결정 버튼을 누른다.
"PROCESS_TRADE",// = 9, // 거래 완료
"REMOVE_ITEM", // = 10, // 아이템 회수
};
#endif
void SGameVM::onTrade ( struct TS_TRADE* pMsg )
{
SMSG_TRADE * pTradeMsg = new SMSG_TRADE;
pTradeMsg->target_player = pMsg->target_player;
pTradeMsg->mode = pMsg->mode;
pTradeMsg->bIncoming = true;
#ifndef NDEBUG
_oprint( "onTrade Mode : %s %d\n", pTrade[pTradeMsg->mode], pTradeMsg->mode );
#endif
memcpy( &pTradeMsg->item_info, &pMsg->item_info, sizeof(pTradeMsg->item_info) );
m_QueueGame.push( pTradeMsg );
}
void SGameVM::onUseItemResult ( struct TS_SC_USE_ITEM_RESULT* pMsg )
{
SMSG_USE_ITEM_RESULT * pUseItemResult = new SMSG_USE_ITEM_RESULT;
pUseItemResult->item_handle = pMsg->item_handle;
pUseItemResult->target_handle = pMsg->target_handle;
m_QueueGame.push( pUseItemResult );
}
void SGameVM::OnMsgTakeItemResult( struct TS_SC_TAKE_ITEM_RESULT* pMsg )
{
SMSG_TAKE_ITEM_RESULT* pTakeItemResult = new SMSG_TAKE_ITEM_RESULT;
pTakeItemResult->item_taker = pMsg->item_taker;
pTakeItemResult->item_handle = pMsg->item_handle;
m_QueueGame.push( pTakeItemResult );
}
//아직 서버에 메세지 없다.
//안 쓴데... - -;;;
void SGameVM::OnDead ( struct TS_MESSAGE* pMsg )
{
//SMSG_DEAD * pDeadMsg = new SMSG_DEAD;
//m_QueueGame.push( pDeadMsg );
}
void SGameVM::OnProperty ( struct TS_SC_PROPERTY* pMsg )
{
//if( SMSG_PROPERTY::PROPERTY_JOB_LEVEL == getStringToInt( pMsg->name, MAP_PROPERTY ) ||
// SMSG_PROPERTY::PROPERTY_LEVEL == getStringToInt( pMsg->name, MAP_PROPERTY ) )
// _oprint( "!!!!! SGameVM::OnProperty : %s %d \n", pMsg->name, getStringToInt( pMsg->name, MAP_PROPERTY ) );
std::string strValue;
if( pMsg->is_number )
strValue = CStringUtil::StringFormat( "%I64d", pMsg->value ).c_str();
else
strValue = (const char*)(pMsg + 1);
if( ::_stricmp(pMsg->name, "huntaholic_ent") == 0 )
{
SDEBUGLOG("%s %s",pMsg->name, strValue.c_str());
}
m_QueueGame.push( new SMSG_PROPERTY( pMsg->handle, getStringToInt( pMsg->name, MAP_PROPERTY ), strValue.c_str() ) );
}
void SGameVM::OnHPMP ( struct TS_SC_HPMP* pMsg )
{
SMSG_HPMP * pHPMP = new SMSG_HPMP;
pHPMP->handle = pMsg->handle;
pHPMP->add_hp = pMsg->add_hp;
pHPMP->hp = pMsg->hp ;
pHPMP->max_hp = pMsg->max_hp;
pHPMP->add_mp = pMsg->add_mp;
pHPMP->mp = pMsg->mp ;
pHPMP->max_mp = pMsg->max_mp;
pHPMP->need_to_display = pMsg->need_to_display;
m_QueueGame.push( pHPMP );
}
void SGameVM::OnTarget( struct TS_SC_TARGET* pMsg )
{
SMSG_TARGET * pTarget = new SMSG_TARGET;
pTarget->target = pMsg->target;
m_QueueGame.push( pTarget );
}
// { [sonador][3.1.2] 경매장 구현
void SGameVM::OnMsgResultAuctionSearch( struct TS_SC_AUCTION_SEARCH* pMsg )
{
SIMSG_RES_AUCTION_SEARCH* pGameMsg = new SIMSG_RES_AUCTION_SEARCH;
pGameMsg->page_num = pMsg->page_num;
pGameMsg->total_page_count = pMsg->total_page_count;
pGameMsg->auction_info_count = pMsg->auction_info_count;
::memcpy( pGameMsg->auction_info, pMsg->auction_info, sizeof( pMsg->auction_info ) );
m_QueueGame.push( pGameMsg );
}
void SGameVM::OnMsgResultAuctionSellingList( struct TS_SC_AUCTION_SELLING_LIST *pMsg )
{
SIMSG_RES_AUCTION_SELLING_LIST* pGameMsg = new SIMSG_RES_AUCTION_SELLING_LIST;
pGameMsg->page_num = pMsg->page_num; // 현재 페이지 번호
pGameMsg->total_page_count = pMsg->total_page_count; // 전체 페이지 수
pGameMsg->auction_info_count = pMsg->auction_info_count; // 현재 페이지에 해당하는 경매 데이터 수
::memcpy( pGameMsg->auction_info, pMsg->auction_info, sizeof( pMsg->auction_info ) );
m_QueueGame.push( pGameMsg );
}
//! 입찰 물품 목록 요청 결과 처리
void SGameVM::OnMsgResultAuctionBiddedList( struct TS_SC_AUCTION_BIDDED_LIST* pMsg )
{
SIMSG_RES_AUCTION_BIDDED_LIST* pGameMsg = new SIMSG_RES_AUCTION_BIDDED_LIST;
pGameMsg->page_num = pMsg->page_num; // 현재 페이지 번호
pGameMsg->total_page_count = pMsg->total_page_count; // 전체 페이지 수
pGameMsg->auction_info_count = pMsg->auction_info_count; // 현재 페이지에 해당하는 경매 데이터 수
::memcpy( pGameMsg->auction_info, pMsg->auction_info, sizeof( pMsg->auction_info ) );
m_QueueGame.push( pGameMsg );
}
void SGameVM::OnMsgResultAuctionItemKeepingList( struct TS_SC_ITEM_KEEPING_LIST* pMsg )
{
SIMSG_RES_AUCTION_ITEM_KEEPING_LIST* pGameMsg = new SIMSG_RES_AUCTION_ITEM_KEEPING_LIST;
pGameMsg->page_num = pMsg->page_num;
pGameMsg->total_page_count = pMsg->total_page_count; // 전체 페이지 수
pGameMsg->keeping_info_count = pMsg->keeping_info_count; // 현재 페이지에 해당하는 아이템 보관 데이터 수
::memcpy( pGameMsg->keeping_info, pMsg->keeping_info, sizeof( pMsg->keeping_info ) );
m_QueueGame.push( pGameMsg );
}
// } [sonador][3.1.2] 경매장 구현
// #2.1.2.11.1 {
void SGameVM::OnMsgHuntaHolicInstanceList( struct TS_SC_HUNTAHOLIC_INSTANCE_LIST* pMsg )
{
SMSG_HUNTAHOLIC_INSTANCE_LIST* pGameMsg = new SMSG_HUNTAHOLIC_INSTANCE_LIST;
pGameMsg->huntaholic_id = pMsg->huntaholic_id;
pGameMsg->page = pMsg->page;
pGameMsg->count = pMsg->count;
pGameMsg->total_page = pMsg->total_page;
if( pGameMsg->count > 0 )
{
TS_HUNTAHOLIC_INSTANCE_INFO* pMsgInstanceInfo = (TS_HUNTAHOLIC_INSTANCE_INFO*)( pMsg + 1 );
pGameMsg->instance_info = new TS_HUNTAHOLIC_INSTANCE_INFO[ pGameMsg->count ];
::memcpy( pGameMsg->instance_info, pMsgInstanceInfo, sizeof( TS_HUNTAHOLIC_INSTANCE_INFO ) * pGameMsg->count );
}
m_QueueGame.push( pGameMsg );
}
void SGameVM::OnMsgHuntaHolicInstanceInfo( struct TS_SC_HUNTAHOLIC_INSTANCE_INFO* pMsg )
{
SMSG_HUNTAHOLIC_INSTANCE_INFO* pGameMsg = new SMSG_HUNTAHOLIC_INSTANCE_INFO;
pGameMsg->info = pMsg->info;
m_QueueGame.push( pGameMsg );
}
void SGameVM::OnMsgHuntaHolicHuntingScore( struct TS_SC_HUNTAHOLIC_HUNTING_SCORE* pMsg )
{
SMSG_HUNTAHOLIC_HUNTING_SCORE* pGameMsg = new SMSG_HUNTAHOLIC_HUNTING_SCORE;
pGameMsg->huntaholic_id = pMsg->huntaholic_id;
pGameMsg->personal_kill_count = pMsg->personal_kill_count;
pGameMsg->personal_score = pMsg->personal_score;
pGameMsg->kill_count = pMsg->kill_count;
pGameMsg->score = pMsg->score;
pGameMsg->point_advantage = pMsg->point_advantage;
pGameMsg->point_rate = pMsg->point_rate;
pGameMsg->gain_point = pMsg->gain_point;
pGameMsg->is_retired = pMsg->is_retired;
m_QueueGame.push( pGameMsg );
}
void SGameVM::OnMsgHuntaHolicUpdateScroe( struct TS_SC_HUNTAHOLIC_UPDATE_SCORE* pMsg )
{
SMSG_HUNTAHOLIC_UPDATE_SCORE* pGameMsg = new SMSG_HUNTAHOLIC_UPDATE_SCORE;
pGameMsg->kill_count = pMsg->kill_count;
pGameMsg->score = pMsg->score;
m_QueueGame.push( pGameMsg );
}
void SGameVM::OnMsgHuntaHolicBeginHunting( struct TS_SC_HUNTAHOLIC_BEGIN_HUNTING* pMsg )
{
SMSG_HUNTAHOLIC_BEGIN_HUNTING* pGameMsg = new SMSG_HUNTAHOLIC_BEGIN_HUNTING;
pGameMsg->begin_time = pMsg->begin_time;
m_QueueGame.push( pGameMsg );
SMSG_CHATTING * chatmsg = new SMSG_CHATTING;
chatmsg->handle = 0;
chatmsg->nChatType = CHAT_NOTICE;
chatmsg->szSender = "@NOTICE";//"notice";
chatmsg->strText = S( 9235 );
chatmsg->nNoticeOnly = 0;
m_QueueGame.push( chatmsg );
}
// sonador #2.1.2.11.5
void SGameVM::OnMsgHuntaHolicMaxPointReached( struct TS_SC_HUNTAHOLIC_MAX_POINT_ACHIEVED* pMsg )
{
m_QueueGame.push( new SGameMessage( MSG_HUNTAHOLIC_MAX_POINT_ACHIEVED ) );
}
void SGameVM::OnMsgHuntaHolicBeginCountDown( struct TS_SC_HUNTAHOLIC_BEGIN_COUNTDOWN* pMsg )
{
m_QueueGame.push( new SMSG_HUNTAHOLIC_BEGIN_COUNTDOWN() );
}
void SGameVM::OnMsgInstanceGameScoreRequest( struct TS_SC_INSTANCE_GAME_SCORE_REQUEST* pMsg )
{
SMSG_INSTANCE_GAME_SCORE *pScoreMsg = new SMSG_INSTANCE_GAME_SCORE( pMsg->holicpoint, pMsg->bearroad_ranking, pMsg->deathmatch_kill_count, pMsg->deathmatch_death_count );
/// 2012.06.13 - prodongi
pScoreMsg->battle_arena_point = pMsg->battle_arena_point;
pScoreMsg->battle_arena_mvp_count = pMsg->battle_arena_mvp_count;
memcpy(pScoreMsg->battle_arena_record, pMsg->battle_arena_record, sizeof (pScoreMsg->battle_arena_record));
m_QueueGame.push( pScoreMsg);
}
// #2.1.2.11.1 }
void SGameVM::OnQuestStatus( TS_SC_QUEST_STATUS* pMsg )
{
if( SQuestMgr::GetInstance().IsAddQuest(pMsg->code) )
{
SMSG_QUEST_UPDATA* pQData = new SMSG_QUEST_UPDATA;
pQData->nQuestID = pMsg->code;
pQData->nProgress = pMsg->nProgress;
::memcpy( pQData->nStatus, pMsg->nStatus, sizeof(pQData->nStatus) );
QuestBase *pBase = GetQuestDB().GetQuestData( pMsg->code );
if( pBase ) pQData->strOldQuest = ParseQuestText( GetStringDB().GetQuestString( pBase->nStatusTextId ), pMsg->code );
m_QueueGame.push( pQData );
}
SQuestMgr::GetInstance().ChangeStatus( pMsg->code, pMsg->nStatus, pMsg->nProgress );
SIMSG_UI_SEND_DATA *pData;
pData = new SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_QUEST_LIST, "quest_status_updated" );
m_QueueGame.push( pData );
pData = new SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_QUEST_INFO, "quest_status_updated" );
m_QueueGame.push( pData );
}
void SGameVM::OnShowCreateGuild( TS_SC_SHOW_CREATE_GUILD* pMsg )
{
SMSG_SHOW_CREATE_GUILD * pGuild = new SMSG_SHOW_CREATE_GUILD;
m_QueueGame.push( pGuild );
}
void SGameVM::OnShowCreateAlliance( TS_SC_SHOW_CREATE_ALLIANCE* pMsg )
{
SMSG_SHOW_CREATE_ALLIANCE* pGAlliance = new SMSG_SHOW_CREATE_ALLIANCE;
m_QueueGame.push( pGAlliance );
}
void SGameVM::OnQuestList( TS_SC_QUEST_LIST* pMsg )
{
TS_SC_QUEST_LIST::TS_QUEST_INFO *pInfo = reinterpret_cast< TS_SC_QUEST_LIST::TS_QUEST_INFO * >( pMsg+1 );
SQuestMgr::GetInstance().saveData(); /// 2011.09.28 - prodongi
SQuestMgr::GetInstance().Clear();
for( int i = 0; i < pMsg->count_active; ++i )
{
SQuestMgr::GetInstance().InsertQuest( pInfo->code, pInfo->nStatus, pInfo->nRandomValue, pInfo->nStartID, pInfo->nTimeLimit, pInfo->nProgress );
++pInfo;
}
//int ddd = pMsg->count_active*sizeof(TS_SC_QUEST_LIST::TS_QUEST_INFO);
TS_SC_QUEST_LIST::TS_PENDING_QUEST_INFO *pInfo2 = reinterpret_cast< TS_SC_QUEST_LIST::TS_PENDING_QUEST_INFO * >(pInfo);
//( pMsg+(ddd+1 ));
for( int i = 0; i < pMsg->count_pending; ++i )
{
int _nStatus[ QuestInstance::MAX_STATUS ];
int _nRandomValue[ QuestInstance::MAX_RANDOM_VALUE ];
for(int j=0;j<QuestInstance::MAX_STATUS;j++)
_nStatus[j] = 0;
for(int k=0;k<QuestInstance::MAX_RANDOM_VALUE;k++)
_nRandomValue[k] = 0;
SQuestMgr::GetInstance().InsertQuest( pInfo2->code, _nStatus, _nRandomValue, pInfo2->nStartID, 0, 0, true);
//( pInfo->code, pInfo->nStatus, pInfo->nRandomValue, pInfo->nStartID, pInfo->nTimeLimit, pInfo->nProgress );
++pInfo2;
}
SQuestMgr::GetInstance().restoreData(); /// 2011.09.28 - prodongi
SIMSG_UI_SEND_DATA *pData;
pData = new SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_QUEST_LIST, "quest_list_updated" );
m_QueueGame.push( pData );
pData = new SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_MINIMAP, "quest_list_updated" );
m_QueueGame.push( pData );
pData = new SIMSG_UI_SEND_DATA( SIMSG_TOGGLE_UIWINDOW::UIWINDOW_WORLDMAP, "quest_list_updated" );
m_QueueGame.push( pData );
}
void ParseScriptText( std::string & strText )
{
/*
// { sonador 7.0.13 친구 추가 오류 수정( 멀티바이트 문자열 관련 오류 )
int nCodePage = GetCodePageFromLang( GetSystemDefaultLangID() );
wchar_t szwBuffer[ 1024 ] = { 0, };
MultiByteToWideChar( nCodePage, 0, strText.c_str(), strText.length(), szwBuffer, 1024 );
std::wstring wstrText = szwBuffer;
std::vector< std::wstring > vWideList;
MsgSplit( wstrText.c_str(), vWideList, L"\v" );
if( vWideList.size() < 1 ) return;
if( nsl::regex::match( L"@[0-9]+", vWideList[0].c_str() ) )
{
::memset( szwBuffer, 0, sizeof( szwBuffer ) );
const char* szString = GetStringDB().GetString( ::_wtoi(vWideList[0].c_str()+1) );
MultiByteToWideChar( nCodePage, 0, szString, ::strlen( szString ), szwBuffer, 1024 );
wstrText = szwBuffer;
}
else
{
wstrText = vWideList[0].c_str();
}
for( size_t i = 1; i + 1< vWideList.size(); i+= 2 )
{
if( nsl::regex::match( L"@[0-9]+", vWideList[i+1].c_str() ) )
{
::memset( szwBuffer, 0, sizeof( szwBuffer ) );
const char* szString = GetStringDB().GetString( ::_wtoi( vWideList[i+1].c_str() + 1 ) );
MultiByteToWideChar( nCodePage, 0, szString, ::strlen( szString ), szwBuffer, 1024 );
vWideList[i+1] = szwBuffer;
}
XStringUtil::Replace( wstrText, vWideList[i], vWideList[i+1] );
}
char szBuffer[ 1024 ] = { 0, };
WideCharToMultiByte( nCodePage, 0, wstrText.c_str(), wstrText.length(), szBuffer, 1024, 0, 0 );
strText = szBuffer;
// }
*/
//유코드 변환 과정에서 윈도우 로컬 관련 문제점을 iconv로 수정
//2009-06-24: hunee
std::vector< std::wstring > vWideList;
std::wstring wstrText = nsl::uni::conv(strText.c_str());
MsgSplit(wstrText.c_str(), vWideList, L"\v" );
if( vWideList.size() < 1 )
return;
if( vWideList[0].compare( L"PROMOTE" ) == 0 ) // 2011.11.02 : servantes
INT K=0;
if( nsl::regex::match( L"@[0-9]+", vWideList[0].c_str() ) )
{
wstrText.clear();
/// vWideList[0] 안에 L"|"로 여러개 나누어져 있을 수 있으므로 vWideList[0]로 파싱을 따로 해줘야 된다.
std::vector<std::wstring> firstStringList;
MsgSplit(vWideList[0].c_str(), firstStringList, L"|");
size_t len = firstStringList.size();
std::wstring wtemp;
for (size_t i = 0; i < len; ++i)
{
wchar_t const* w = firstStringList[i].c_str();
if (w[0] == L'@')
{
wtemp = nsl::uni::conv(S(::_wtoi(w+1)));
wstrText += wtemp;
}
else
{
wstrText += w;
}
if (i < len-1)
wstrText += L"|";
}
firstStringList.clear();
}
else
{
wstrText = vWideList[0].c_str();
}
for( size_t i = 1; i + 1< vWideList.size(); i+= 2 )
{
if( nsl::regex::match( L"@[0-9]+", vWideList[i+1].c_str() ) )
{
const char* szString = GetStringDB().GetString( ::_wtoi( vWideList[i+1].c_str() + 1 ) );
std::wstring wstrBuffer = nsl::uni::conv(szString);
vWideList[i+1] = wstrBuffer.c_str();
}
if( vWideList[i].compare( L"#@price@#" ) == 0 )
{
std::string strPriceComma = CStringUtil::GetCommaNumberString( ::_wtoi64( vWideList[i+1].c_str() ) );
std::string wstrBuffer = CStringUtil::StringFormat("<#ffffff>%s<#fafa01>", strPriceComma.c_str() );
vWideList[i+1] = nsl::uni::conv( wstrBuffer.c_str() );
}
XStringUtil::Replace( wstrText, vWideList[i], vWideList[i+1] );
}
std::string str = nsl::uni::conv(wstrText.c_str());
strText = str;
vWideList.clear();
}
inline int get_quest_value( QuestBase *pQuest, const char *value )
{
int nIndex = 0;
if( value && value[0] && value[0] == 'r' )
{
int nIndex = atoi( &value[1] ) - 1;
assert( nIndex >=0 && nIndex <= QuestInstance::MAX_RANDOM_VALUE );
return SQuestMgr::GetInstance().GetQuestRandomValue( pQuest->nCode, nIndex );
}
else
{
int nIndex = atoi( value ) - 1;
assert( nIndex >=0 && nIndex <= QuestBase::MAX_VALUE_NUMBER );
return pQuest->nValue[nIndex];
}
}
bool eval( int nQuestCode, const char *szExpression )
{
std::string expression = szExpression;
// r(인덱스) (부등호) (숫자) [ (and|or) ... ]
std::string pattern = "r([\\d]+) *([!<>=]+) *(\\d+) *([(and)|(or)]*)"; // 빈공백은 무시됨
bool bPrevEval = false;
std::string strPrevOp;
std::vector< std::string > vList;
while( nsl::regex::match( pattern.c_str(), expression.c_str(), &vList ) )
{
bool bEval = false;
int nIndex = atoi( vList[1].c_str() ) - 1;
int nValue = atoi( vList[3].c_str() );
int nCurVal = SQuestMgr::GetInstance().GetQuestRandomValue( nQuestCode, nIndex );
if( strcmp( vList[2].c_str(), "<" ) == 0 ) bEval = ( nCurVal < nValue );
else if( strcmp( vList[2].c_str(), ">" ) == 0 ) bEval = ( nCurVal > nValue );
else if( strcmp( vList[2].c_str(), "<=" ) == 0 ) bEval = ( nCurVal <= nValue );
else if( strcmp( vList[2].c_str(), ">=" ) == 0 ) bEval = ( nCurVal >= nValue );
else if( strcmp( vList[2].c_str(), "==" ) == 0 ) bEval = ( nCurVal == nValue );
else if( strcmp( vList[2].c_str(), "!=" ) == 0 ) bEval = ( nCurVal != nValue );
else if( strcmp( vList[2].c_str(), "<>" ) == 0 ) bEval = ( nCurVal != nValue );
else if( strcmp( vList[2].c_str(), "><" ) == 0 ) bEval = ( nCurVal != nValue );
if( strPrevOp.empty() )
{
bPrevEval = bEval;
}
else
{
if( stricmp( strPrevOp.c_str(), "and" ) == 0 ) bPrevEval = ( bPrevEval && bEval );
else if( stricmp( strPrevOp.c_str(), "or" ) == 0 ) bPrevEval = ( bPrevEval || bEval );
}
strPrevOp = vList[4];
nsl::replace( &expression, vList[0].c_str(), "" );
vList.clear();
}
return bPrevEval;
}
/// 몹 이름을 치환 할 때, 쉽게 하기 위해서 addMobNameDiff를 추가함(몹 이름이 중복되는 경우에 문제가 될 수 있음,,)
std::string _ParseQuestText( const char *szQuestString, int nQuestCode, bool addMobNameDiff)
{
QuestBase *pQuest = GetQuestDB().GetQuestData( nQuestCode );
if( !pQuest ) return szQuestString;
// (조건문)"문자열"
std::string pattern = "\\(([\\d\\w ><=]+)\\)\"([^(^)^\".]*)\"";
std::string strText = szQuestString;
std::vector< std::string > vList;
while( nsl::regex::match( pattern.c_str(), strText.c_str(), &vList ) )
{
// vList[0] : 바꿔야할것
// vList[1] : 조건문
// vList[2] : 바꿀 대상
bool bIsTrue = true;
// 조건문을 평가함.
bIsTrue = eval( nQuestCode, vList[1].c_str() );
// 조건문이 참이면 해당 문자열을 표시하고 거짓이면 표시하지 않음.
if( bIsTrue ) nsl::replace( &strText, vList[0].c_str(), vList[2].c_str() );
else nsl::replace( &strText, vList[0].c_str(), "" );
vList.clear();
}
cElementQuestParser parser;
parser.setQuest(pQuest);
return parser.parsing(strText.c_str(), addMobNameDiff);
}
std::string ParserTitleText( const char* sz, int id )
{
cElementTitleParser parser;
parser.setConditionTypeID( id );
return parser.parsing( sz, false );
}
std::string ParseQuestText( const char *szQuestString, int nQuestCode )
{
return _ParseQuestText(szQuestString, nQuestCode, false);
}
std::string ParseQuestTextAddMobDiff( const char *szQuestString, int nQuestCode )
{
return _ParseQuestText(szQuestString, nQuestCode, true);
}
void SGameVM::OnShowWindow ( struct TS_SC_SHOW_WINDOW* pMsg )
{
SMSG_SCRIPT_SHOW_WINDOW * pScriptShowWindow = new SMSG_SCRIPT_SHOW_WINDOW;
// 전체 문자열
int nEntireLength = (pMsg->window_length + pMsg->argument_length + pMsg->trigger_length);
const char* pEntire = (const char*)(pMsg + 1); // 주의! : NULL문자를 포함하지 않으므로 이 자체를 문자열로 사용할 수 없음!
pScriptShowWindow->strWindow = std::string( pEntire, pEntire + nEntireLength );
pScriptShowWindow->strTrigger = std::string( pEntire, pEntire + nEntireLength );
pScriptShowWindow->strArgument = std::string( pEntire, pEntire + nEntireLength );
pScriptShowWindow->strWindow.erase( pMsg->window_length, pScriptShowWindow->strWindow.length() );
pScriptShowWindow->strArgument.erase( 0, pMsg->window_length );
pScriptShowWindow->strArgument.erase( pMsg->argument_length, pScriptShowWindow->strArgument.length() );
pScriptShowWindow->strTrigger.erase( 0, pMsg->window_length + pMsg->argument_length );
ParseScriptText(pScriptShowWindow->strArgument); /// 2011.10.26 - prodongi
m_QueueGame.push( pScriptShowWindow );
}
/// 2011.10.26 - prodongi
void SGameVM::OnGeneralMessageBox(TS_SC_GENERAL_MESSAGE_BOX* pMsg)
{
SMSG_GENERAL_MESSAGE_BOX* msg = new SMSG_GENERAL_MESSAGE_BOX;
char* text = new char[pMsg->text_length + 1];
memcpy(text, (byte*)pMsg + sizeof (TS_SC_GENERAL_MESSAGE_BOX), pMsg->text_length);
text[pMsg->text_length] = 0x00;
msg->m_text = text;
ParseScriptText(msg->m_text);
delete[] text;
m_QueueGame.push(msg);
}
/// 2011.08.19 ParseQuestStringElement함수에서 갖고 옴 - prodongi
void extractQuestTarget(std::vector<std::string>& questTargetList, int questCode)
{
questTargetList.clear();
QuestBase *quest = GetQuestDB().GetQuestData(questCode);
if (!quest)
{
_oprint("failed extraction quest Target Quest data %d\n", questCode);
return ;
}
std::string questString = GetStringDB().GetQuestString(quest->nStatusTextId);
std::vector<std::string> storage;
std::string strFrom, strTo;
while( nsl::regex::match( "#@m_name:([r0-9]*)@#", questString.c_str(), &storage ) )
{
strFrom = storage[0];
strTo= storage[1];
ENC_INT code = bits_scramble< int, 3 > ( get_quest_value( quest, strTo.c_str() ) );
int nTextID = GetMonsterDB().GetTextID( code );
if( nTextID == -1 )
break;
strTo = S(nTextID);
questTargetList.push_back(strTo);
CStringUtil::ReplacePhrase(questString, strFrom, strTo);
storage.clear();
}
while( nsl::regex::match( "#@m_location:([r0-9]*)@#", questString.c_str(), &storage ) )
{
strFrom = storage[0];
strTo= storage[1];
ENC_INT code = bits_scramble< int, 3 > ( get_quest_value( quest, strTo.c_str() ) );
// { 몬스터 지역 이름 얻어옴
_MONSTER_INFO_FILE *pPtr = GetMonsterDB().GetMonsterData( code );
if( pPtr == NULL )
{
//무엇인가로 표시 ㅡ,.ㅡ
strTo = GetStringDB().GetString( 88 );
}
else
{
// 변경 적용 되기 전까지 주석처리.
strTo = GetStringDB().GetString( pPtr->respawn_name_id );
}
questTargetList.push_back(strTo);
CStringUtil::ReplacePhrase(questString, strFrom, strTo);
storage.clear();
}
while( nsl::regex::match( "#@i_name:([r0-9]*)@#", questString.c_str(), &storage ) )
{
strFrom = storage[0];
strTo= storage[1];
int nIndex = get_quest_value( quest, strTo.c_str() );
strTo = GetStringDB().GetString( GetItemDB().GetItemData( nIndex )->nNameId );
questTargetList.push_back(strTo);
CStringUtil::ReplacePhrase(questString, strFrom, strTo);
storage.clear();
}
while( nsl::regex::match( "#@s_name:([r0-9]*)@#", questString.c_str(), &storage ) )
{
strFrom = storage[0];
strTo= storage[1];
// { 인덱스 얻어옴
int nIndex = get_quest_value( quest, strTo.c_str() );
SkillBase *pBase = GetSkillDB().GetSkillData( nIndex );
if( pBase ) strTo = GetStringDB().GetString( pBase->GetNameID() );
questTargetList.push_back(strTo);
CStringUtil::ReplacePhrase(questString, strFrom, strTo);
storage.clear();
}
while( nsl::regex::match( "#@t_name:([r0-9]*)@#", questString.c_str(), &storage ) )
{
strFrom = storage[0];
strTo= storage[1];
int nIndex = get_quest_value( quest, strTo.c_str() );
if (0 < nIndex) strTo = GetStringDB().GetString( nIndex );
questTargetList.push_back(strTo);
CStringUtil::ReplacePhrase(questString, strFrom, strTo);
storage.clear();
}
}
void SGameVM::OnDialog ( struct TS_SC_DIALOG* pMsg )
{
SMSG_NPC_DIALOG* pDialogMsg = new SMSG_NPC_DIALOG;
bool bIsQuestDialog = false;
pDialogMsg->npc_handle = pMsg->npc_handle;
pDialogMsg->nDialogType = pMsg->type;
// 전체 문자열
int nEntireLength = (pMsg->title_length + pMsg->text_length + pMsg->menu_length);
const char* pEntire = (const char*)(pMsg + 1); // 주의! : NULL문자를 포함하지 않으므로 이 자체를 문자열로 사용할 수 없음!
std::string strEntireString( pEntire, pEntire + nEntireLength );
// 타이틀 문자열
{
pDialogMsg->strTitle.assign( strEntireString, 0, pMsg->title_length );
ParseScriptText( pDialogMsg->strTitle );
}
// 텍스트 문자열
{
const char* c_szPageBreak0 = "<P>";
const char* c_szPageBreak1 = "<p>";
std::string strText;
strText.assign( strEntireString, pMsg->title_length, pMsg->text_length );
// 퀘스트 문자열인지..?
const char *pszQuestHeader = "QUEST|";
if( strnicmp( strText.c_str(), pszQuestHeader, strlen(pszQuestHeader) ) == 0 )
{
bIsQuestDialog = true;
std::vector< std::string > vToken;
MsgSplit( strText.c_str(), vToken, L"|" );
pDialogMsg->nQuestCode = atoi( vToken[1].c_str() );
pDialogMsg->nQuestTextID = atoi( vToken[2].c_str() );
strText = GetStringDB().GetString( pDialogMsg->nQuestTextID );
// 퀘스트 문자열 고치기
strText = ParseQuestText( strText.c_str(), pDialogMsg->nQuestCode );
vToken.clear();
}
else
{
// 호라이즌 교역상이 엘빈으로 테스트 @90400102
if (strText[0]=='@' && strText[1]!=NULL)
{ std::vector< std::string > vToken;
MsgSplit( strText.c_str(), vToken, L"@" );
pDialogMsg->nQuestTextID = atoi(vToken[0].c_str());
}
ParseScriptText( strText );
}
if (pDialogMsg->nQuestTextID)
{
char temp[256];
sprintf(temp,"V%8.8d.mp3",pDialogMsg->nQuestTextID);
m_pGameManager->StartSound( temp );
// V90408102.mp3 파일이 second 에 있어야 테스트가 된다.
}
XStringUtil::TranslateKoreanPostfix( strText );
CStringUtil::ReplacePhrase( strText, std::string(c_szPageBreak0), std::string(c_szPageBreak1) );
CStringUtil::GetTextLinesFromString( strText, pDialogMsg->vtTexts, c_szPageBreak1 );
}
// 메뉴 문자열
{
std::string strMenus;
strMenus.assign( strEntireString, (pMsg->title_length + pMsg->text_length), pMsg->menu_length );
STRING_VECTOR vtMenuData;
CStringUtil::GetTextLinesFromString( strMenus, vtMenuData, "\t" );
// Fraun performance tweak
switch (pDialogMsg->nDialogType)
{
case TS_SC_DIALOG::TYPE_NPC:
case TS_SC_DIALOG::TYPE_QUEST_INFO_AND_START:
case TS_SC_DIALOG::TYPE_OTHER_INSTANCE_DUNGEON_CONFIRM_WINDOW:
{
while (!vtMenuData.empty())
{
std::string strMenu, strTrigger;
if (!vtMenuData.empty()) { strMenu = vtMenuData[0]; vtMenuData.erase(vtMenuData.begin()); }
if (!vtMenuData.empty()) { strTrigger = vtMenuData[0]; vtMenuData.erase(vtMenuData.begin()); }
std::vector< std::string > vToken;
MsgSplit(strMenu.c_str(), vToken, L"|");
int nButtonType = SMSG_NPC_DIALOG::BUTTON_NORMAL;
if (vToken[0] == "QUEST")
{
char* YELLOW = "<#DDDD77>";
char* ORANGE = "<#FFAA33>";
char* GREEN = "<#AAAAFF>";
char* pszColor = YELLOW;
nButtonType = SMSG_NPC_DIALOG::BUTTON_QUEST_INPROGRESS;
//진행 할 수 있는 퀘스트
if (atoi(vToken[2].c_str()) == TS_SC_QUEST_INFOMATION::IS_STARTABLE)
{
pszColor = ORANGE;
nButtonType = SMSG_NPC_DIALOG::BUTTON_QUEST_STARTABLE;
}
//완료 할 수 있는 퀘스트
else if (atoi(vToken[2].c_str()) == TS_SC_QUEST_INFOMATION::IS_FINISHABLE)
{
pszColor = GREEN;
nButtonType = SMSG_NPC_DIALOG::BUTTON_QUEST_FINISHABLE;
}
XStringUtil::Format(strMenu, "%s%s", pszColor, GetStringDB().GetString(atoi(vToken[1].c_str())));
}
else
{
ParseScriptText(strMenu);
}
if (bIsQuestDialog)
{
if (strMenu == "START") strMenu = GetStringDB().GetString(19);
else if (strMenu == "REJECT") strMenu = GetStringDB().GetString(20);
else if (strMenu == "OK") strMenu = GetStringDB().GetString(11);
else if (strMenu == "END") strMenu = GetStringDB().GetString(10);
else if (strMenu == "REWARD")
{
m_QueueGame.push(new SIMSG_UI_SEND_DATA(SIMSG_TOGGLE_UIWINDOW::UIWINDOW_QUEST_REWARD, number_t(::_atoi64(strTrigger.c_str())), "select_reward"));
m_QueueGame.push(new SIMSG_SHOW_UIWINDOW(SIMSG_TOGGLE_UIWINDOW::UIWINDOW_QUEST_REWARD, true));
strMenu = GetStringDB().GetString(11);
strTrigger = "";
}
}
if (strMenu != "NULL") pDialogMsg->vtMenus.push_back(SMSG_NPC_DIALOG::DLGMENU(strMenu.c_str(), strTrigger.c_str(), nButtonType));
vToken.clear();
}
break;
}
case TS_SC_DIALOG::TYPE_DUNGEON_STONE:
{
int nMenuCnt = vtMenuData.size() / 2;
assert(nMenuCnt == 3 && "Menu Count Invalid");
for (size_t n(0); vtMenuData.size() > n; n += 2)
{
pDialogMsg->vtMenus.push_back(SMSG_NPC_DIALOG::DLGMENU(vtMenuData[n].c_str(), vtMenuData[n + 1].c_str(), SMSG_NPC_DIALOG::BUTTON_DUNGEON_STONE));
}
break;
}
case TS_SC_DIALOG::TYPE_DONATION_PROP:
{
int nMenuCnt = vtMenuData.size() / 2;
assert(nMenuCnt == 2 && "Menu Count Invalid");
for (size_t n(0); vtMenuData.size() > n; n += 2)
{
pDialogMsg->vtMenus.push_back(SMSG_NPC_DIALOG::DLGMENU(vtMenuData[n].c_str(), vtMenuData[n + 1].c_str(), SMSG_NPC_DIALOG::BUTTON_DONATION_PROP));
}
break;
}
case TS_SC_DIALOG::TYPE_QUEST_INFO_IN_PROGRESS:
{
//진행중인 퀘스트 내용이 표시될 UI 열기
std::string strMenu, strTrigger;
strMenu = GetStringDB().GetString(19);
strTrigger = "";
int nButtonType = SMSG_NPC_DIALOG::BUTTON_NORMAL;
pDialogMsg->vtMenus.push_back(SMSG_NPC_DIALOG::DLGMENU(strMenu.c_str(), strTrigger.c_str(), nButtonType));
break;
}
case TS_SC_DIALOG::TYPE_QUEST_INFO_AND_END:
{
// Open quest reward selection and completion UI”
break;
}
}
}
m_QueueGame.push( pDialogMsg );
}
void SGameVM::OnChangeLocation( struct TS_SC_CHANGE_LOCATION* pMsg )
{
SMSG_CHANGE_LOCATION* pChangeLocation = new SMSG_CHANGE_LOCATION;
pChangeLocation->cur_location_id = pMsg->cur_location_id;
pChangeLocation->prev_location_id = pMsg->prev_location_id;
m_QueueGame.push( pChangeLocation );
}
//날씨 관련 정보 받기
void SGameVM::OnWeatherInfo( struct TS_SC_WEATHER_INFO* pMsg )
{
SMSG_WEATHER_INFO* pWeatherInfo = new SMSG_WEATHER_INFO;
pWeatherInfo->region_id = pMsg->region_id;
pWeatherInfo->weather_id = pMsg->weather_id;
m_QueueGame.push( pWeatherInfo );
}
void SGameVM::OnGametime( struct TS_SC_GAME_TIME* pMsg )
{
SMSG_GAME_TIME* pGameTime = new SMSG_GAME_TIME;
pGameTime->t = pMsg->t;
pGameTime->game_time = pMsg->game_time;
m_QueueGame.push( pGameTime );
}
void SGameVM::OnEmotion( struct TS_SC_EMOTION* pMsg )
{
SMSG_EMOTION* pEmotion = new SMSG_EMOTION;
pEmotion->handle = pMsg->handle;
pEmotion->emotion = pMsg->emotion;
m_QueueGame.push( pEmotion );
}
void SGameVM::OnGetChaos( struct TS_SC_GET_CHAOS* pMsg )
{
SMSG_GET_CHAOS* pChaos = new SMSG_GET_CHAOS;
pChaos->hPlayer = pMsg->hPlayer;
pChaos->hCorpse = pMsg->hCorpse;
pChaos->nChaos = pMsg->nChaos;
pChaos->nBonusType = pMsg->nBonusType; // sonador 3.10.2 PC 방 혜택 관련 라크 획득 시스템 메시지 변경
pChaos->nBonusPercent = pMsg->nBonusPercent; //
pChaos->nBonus = pMsg->nBonus;
m_QueueGame.push( pChaos );
}
void SGameVM::OnEnergy( struct TS_SC_ENERGY* pMsg )
{
SMSG_ENERGY* pEnergy = new SMSG_ENERGY;
pEnergy->handle = pMsg->handle;
pEnergy->energy = pMsg->energy;
m_QueueGame.push( pEnergy );
}
//1:1 대련
// 2009-01-30 : hunee
void SGameVM::OnMsgCompeteRequest( struct TS_SC_COMPETE_REQUEST* pMsg)
{
SMSG_SC_COMPETE_REQUEST * pCompeteRequest = new SMSG_SC_COMPETE_REQUEST;
pCompeteRequest->compete_type = pMsg->compete_type;
strcpy(pCompeteRequest->requester, pMsg->requester);
m_QueueGame.push( pCompeteRequest );
}
void SGameVM::OnMsgCompeteAnswer( struct TS_SC_COMPETE_ANSWER* pMsg)
{
SMSG_SC_COMPETE_ANSWER * pCompeteAnswer = new SMSG_SC_COMPETE_ANSWER;
pCompeteAnswer->compete_type = pMsg->compete_type;
pCompeteAnswer->answer_type = pMsg->answer_type;
strcpy(pCompeteAnswer->requestee, pMsg->requestee);
m_QueueGame.push( pCompeteAnswer );
}
void SGameVM::OnMsgCompeteCountdown( struct TS_SC_COMPETE_COUNTDOWN* pMsg)
{
SMSG_SC_COMPETE_COUNTDOWN * pCompeteCountdown = new SMSG_SC_COMPETE_COUNTDOWN;
pCompeteCountdown->compete_type = pMsg->compete_type;
pCompeteCountdown->handle_competitor = pMsg->handle_competitor; // 상대방플레이어핸들(1:1 PVP에서만 사용됨)
strcpy(pCompeteCountdown->competitor, pMsg->competitor);
m_QueueGame.push( pCompeteCountdown );
}
void SGameVM::OnMsgCompeteStart( struct TS_SC_COMPETE_START* pMsg)
{
SMSG_SC_COMPETE_START * pCompeteStart = new SMSG_SC_COMPETE_START;
pCompeteStart->compete_type = pMsg->compete_type;
strcpy(pCompeteStart->competitor, pMsg->competitor);
m_QueueGame.push( pCompeteStart );
}
void SGameVM::OnMsgCompeteEnd( struct TS_SC_COMPETE_END* pMsg)
{
SMSG_SC_COMPETE_END * pCompeteEnd = new SMSG_SC_COMPETE_END;
pCompeteEnd->compete_type = pMsg->compete_type;
pCompeteEnd->end_type = pMsg->end_type;
strcpy(pCompeteEnd->winner, pMsg->winner);
strcpy(pCompeteEnd->loser, pMsg->loser);
m_QueueGame.push( pCompeteEnd );
}
// 기부 랭킹 받아오기
void SGameVM::OnMsgRanking( struct TS_SC_RANKING_TOP_RECORD* pMsg )
{
SMSG_SC_RANKING_TOP_RECORD * pRankingRecord = new SMSG_SC_RANKING_TOP_RECORD;
pRankingRecord->ranking_type = pMsg->ranking_type;
pRankingRecord->requester_rank = pMsg->requester_rank;
pRankingRecord->requester_score = ( pMsg->requester_score ) / 10000;
pRankingRecord->record_count = pMsg->record_count;
for (int n=0; n<pMsg->record_count; n++)
{
pRankingRecord->ranking_record[n].rank = pMsg->ranking_record[n].rank;
strcpy(pRankingRecord->ranking_record[n].ranker_name, pMsg->ranking_record[n].ranker_name);
pRankingRecord->ranking_record[n].score = ( pMsg->ranking_record[n].score ) / 10000;
}
m_QueueGame.push( pRankingRecord );
}
void SGameVM::OnItemCoolTime( struct TS_SC_ITEM_COOL_TIME* pMsg )
{
//쿨타입 그룹 ID 사용
SMSG_ITEM_COOL_TIME* pItemCoolTime = new SMSG_ITEM_COOL_TIME;
memcpy( pItemCoolTime->cool_time, pMsg->cool_time, sizeof( pMsg->cool_time ) );
//#ifndef NDEBUG
// _oprint( "OnItemCoolTime : " );
// for( int i(0); TS_SC_ITEM_COOL_TIME::MAX_ITEM_COOLTIME_GROUP>i; i++ )
// {
// _oprint( "[%d] ", pItemCoolTime->cool_time[i] );
// }
// _oprint( "\n" );
//#endif
m_QueueGame.push( pItemCoolTime );
}
void SGameVM::OnChatResult( struct TS_SC_CHAT_RESULT* pMsg )
{
SMSG_CHAT_RESULT* pChatResult = new SMSG_CHAT_RESULT;
pChatResult->type = pMsg->type;
pChatResult->percentage = pMsg->percentage;
pChatResult->result = pMsg->result;
pChatResult->reserved = pMsg->reserved;
m_QueueGame.push( pChatResult );
}
void SGameVM::OnStateResult( struct TS_SC_STATE_RESULT* pMsg )
{
SMSG_STATE_RESULT* pStateDamage = new SMSG_STATE_RESULT;
pStateDamage->caster_handle = pMsg->caster_handle;
pStateDamage->target_handle = pMsg->target_handle;
pStateDamage->code = pMsg->code;
pStateDamage->level = pMsg->level;
pStateDamage->result_type = pMsg->result_type;
pStateDamage->value = pMsg->value;
pStateDamage->target_value = pMsg->target_value;
pStateDamage->final = pMsg->final;
pStateDamage->total_amount = pMsg->total_amount;
m_QueueGame.push( pStateDamage );
}
void SGameVM::onHotkey( GameHotKeystrcut & HotKey )
{
//등록된 핫키를 찾아서 날리자~
// _oprint( " S:%d A:%d C:%d Key:%d\n", (int)bShift, (int)bAlt, (int)bControl, Virtual_Key );
SIMSG_HOTKEY_EX key;
key.bUp = HotKey.bUp;
key.bAlt = HotKey.bAlt;
key.bCtrlShift = ( HotKey.bShift && HotKey.bCtrl );
key.bShift = HotKey.bShift;
key.bCtrl = HotKey.bCtrl;
key.bTab = HotKey.bTab;
key.wParam = HotKey.Virtual_Key;
ProcMsgAtStatic( &key);
}
// 스킬레벨의변동이발생
// 2010.3.9 : hunee
void SGameVM::onAddedSkillList( struct TS_SC_ADDED_SKILL_LIST* pMsg )
{
_oprint( "OnAddedSkillList : %d\n", pMsg->count );
assert( sizeof(SMSG_ADDED_SKILL_LIST::AddedSkillInfo) == sizeof(TS_SC_ADDED_SKILL_LIST::AddedSkillInfo) );
if( pMsg->count > 0 )
{
SMSG_ADDED_SKILL_LIST * pAddedSkillList = new SMSG_ADDED_SKILL_LIST;
pAddedSkillList->count = pMsg->count;
pAddedSkillList->target = pMsg->target;
TS_SC_ADDED_SKILL_LIST::AddedSkillInfo * pSource = (TS_SC_ADDED_SKILL_LIST::AddedSkillInfo *)(pMsg+1);
pAddedSkillList->pAddedSkillInfo = new SMSG_ADDED_SKILL_LIST::AddedSkillInfo[pMsg->count];
for( int i(0); pMsg->count>i; i++ )
{
pAddedSkillList->pAddedSkillInfo[i].skill_id = pSource->skill_id;
pAddedSkillList->pAddedSkillInfo[i].restricted_to_type = pSource->restricted_to_type;
pAddedSkillList->pAddedSkillInfo[i].added_skill_level = pSource->added_skill_level;
pSource++;
}
m_QueueGame.push( pAddedSkillList );
}
else
{
SMSG_ADDED_SKILL_LIST * pAddedSkillList = new SMSG_ADDED_SKILL_LIST;
pAddedSkillList->count = pMsg->count;
pAddedSkillList->target = pMsg->target;
m_QueueGame.push( pAddedSkillList );
}
}
//윈도우 메세지 받기
LRESULT CALLBACK SGameVM::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 메뉴의 선택 영역을 구문 분석합니다.
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_CLOSE:
{
OutputDebugString("press X button!!\n");
// m_pGameManager->StartSound( "ui_button_click.wav" );
// m_pGameManager->ProcMsgAtStatic( &SIMSG_REQ_OPEN_MSGBOX( SIMSG_REQ_OPEN_MSGBOX::MSGBOX_EXITGAME, SYS_MSG_SERVER_EXITGAME ) );
SMSG_GAME_OUT* msg = new SMSG_GAME_OUT;
msg->character_select = false;
m_QueueGame.push( msg );
}
// _oprint( "ProcMsgAtStatic( &STMSG_REQ_CLOSE() );\n" );
// ProcMsgAtStatic( &STMSG_REQ_CLOSE() );
break;
case WM_SYSKEYDOWN :
{
_oprint( "WM_SYSKEYDOWN : %d %d\n", wParam, LOWORD(wParam) );
if( wParam == VK_F4)
{
return TRUE;
}
}
break;
case WM_SYSKEYUP :
{
}
break;
case WM_IME_NOTIFY:
{
switch( wParam )
{
case IMN_SETCONVERSIONMODE: /*_oprint( "IMN_SETCONVERSIONMODE\n" ); break;*/
case IMN_SETOPENSTATUS:
{
SIMSG_IME_NOTIFY ImeNotifyMsg;
ImeNotifyMsg.lParam = lParam;
ImeNotifyMsg.wParam = wParam;
ImeNotifyMsg.nMsg = message;
ProcMsgAtStatic( &ImeNotifyMsg );
// _oprint( "IMN_SETOPENSTATUS\n" );
}
break;
}
}
break;
case WM_KEYDOWN :
{
/// 2010.11.10 - prodongi
//#ifdef _DEV
if (g_UserInfo.isMonkeyTail())
{
extern bool g_bDebugMode;
if( g_bUserCamMode && g_bDebugMode )
{
SIMSG_KEYDOWN KeyDownMsg;
KeyDownMsg.lParam = lParam;
KeyDownMsg.wParam = wParam;
KeyDownMsg.nMsg = message;
ProcMsgAtStatic( &KeyDownMsg );
}
}
//#endif
}
break; // Record key presses
case WM_KEYUP :
{
SIMSG_KEYUP KeyUpMsg;
KeyUpMsg.lParam = lParam;
KeyUpMsg.wParam = wParam;
KeyUpMsg.nMsg = message;
ProcMsgAtStatic( &KeyUpMsg );
}
break; // Perform commands when keys are released
//case WM_SETCURSOR:
// {
// SIMSG_SETCURSOR SetCursorMsg;
// SetCursorMsg.nMsg = message;
// SetCursorMsg.wParam = wParam;
// SetCursorMsg.lParam = lParam;
// ProcMsgAtStatic( &SetCursorMsg );
// }
// break;
case WM_MOUSEMOVE :
{
SIMSG_MOUSEMOVE MouseMove;
MouseMove.nMsg = message;
MouseMove.wParam = wParam;
MouseMove.lParam = lParam;
ProcMsgAtStatic( &MouseMove );
}
break;
case WM_MOUSEWHEEL:
{
SIMSG_MOUSEWHEEL MouseWheel;
MouseWheel.nMsg = message;
MouseWheel.wParam = wParam;
MouseWheel.lParam = lParam;
ProcMsgAtStatic( &MouseWheel );
}
break;
case WM_MBUTTONDOWN:
{
SIMSG_MBUTTONDOWN mbuttonMsg;
mbuttonMsg.nMsg = message;
mbuttonMsg.wParam = wParam;
mbuttonMsg.lParam = lParam;
ProcMsgAtStatic( &mbuttonMsg );
}
break;
case WM_RBUTTONDBLCLK:
{
SIMSG_RBUTTONDBLCLK RbuttonDblclk;
RbuttonDblclk.nMsg = message;
RbuttonDblclk.wParam = wParam;
RbuttonDblclk.lParam = lParam;
ProcMsgAtStatic( &RbuttonDblclk );
}
break;
case WM_RBUTTONDOWN:
{
SIMSG_RBUTTONDOWN RbuttonDown;
RbuttonDown.nMsg = message;
RbuttonDown.wParam = wParam;
RbuttonDown.lParam = lParam;
ProcMsgAtStatic( &RbuttonDown );
if (!m_bLPress && !m_bRPress)
{
SetCapture(hWnd);
m_ptOldPoint.x = GET_X_LPARAM(lParam);
m_ptOldPoint.y = GET_Y_LPARAM(lParam);
}
m_bRPress = TRUE;
}
break;
case WM_RBUTTONUP:
{
SIMSG_RBUTTONUP RbuttonUp;
RbuttonUp.nMsg = message;
RbuttonUp.wParam = wParam;
RbuttonUp.lParam = lParam;
ProcMsgAtStatic( &RbuttonUp );
if (m_bRPress && !m_bLPress)
ReleaseCapture();
m_bRPress = FALSE;
}
break;
case WM_LBUTTONDBLCLK:
{
SIMSG_LBUTTONDBLCLK LbuttonDblclk;
LbuttonDblclk.nMsg = message;
LbuttonDblclk.wParam = wParam;
LbuttonDblclk.lParam = lParam;
ProcMsgAtStatic( &LbuttonDblclk );
}
break;
case WM_LBUTTONDOWN:
{
SIMSG_LBUTTONDOWN LbuttonDown;
LbuttonDown.nMsg = message;
LbuttonDown.wParam = wParam;
LbuttonDown.lParam = lParam;
ProcMsgAtStatic( &LbuttonDown );
if (!m_bLPress && !m_bRPress)
{
SetCapture(hWnd);
m_ptOldPoint.x = GET_X_LPARAM(lParam);
m_ptOldPoint.y = GET_Y_LPARAM(lParam);
}
m_bLPress = TRUE;
}
break;
case WM_LBUTTONUP:
{
SIMSG_LBUTTONUP LbuttonUp;
LbuttonUp.nMsg = message;
LbuttonUp.wParam = wParam;
LbuttonUp.lParam = lParam;
ProcMsgAtStatic( &LbuttonUp );
if (!m_bRPress && m_bLPress)
ReleaseCapture();
m_bLPress = FALSE;
}
break;
}
return 0;
}
void SGameVM::ProcMsgAtStatic( SGameMessage* pMsg )
{
if( m_pGameManager )
{
m_pGameManager->ProcMsgAtStatic( pMsg );
}
}
void SGameVM::ProcDel()
{
if( !m_vDelList.empty() )
{
//지울 것들
std::vector< SGameMessage* >::iterator it = m_vDelList.begin();
while( it != m_vDelList.end() )
{
if( (*it)->bUse )
{
delete (*it);
it = m_vDelList.erase( it );
}
else
it++;
}
}
if( !m_vSafeKeepingList.empty() )
{
//보관용
std::vector< SGameMessage* >::iterator it = m_vSafeKeepingList.begin();
while( it != m_vSafeKeepingList.end() )
{
if( (*it)->bUse )
{
delete (*it);
it = m_vSafeKeepingList.erase( it );
}
else
it++;
}
}
}
void SGameVM::AddSafeKeeping( struct SGameMessage* pMsg )
{
m_vSafeKeepingList.push_back( pMsg );
}
void SGameVM::AddRecycle( SGameMessage* pMsg )
{
// _oprint( "AddRecycle Msg : %d\n", pMsg->nType );
switch( pMsg->nType )
{
// case IMSG_SETCURSOR :
case IMSG_KEYUP :
case IMSG_KEYDOWN :
case IMSG_MOUSEMOVE :
case IMSG_MOUSEWHEEL :
case IMSG_LBUTTONUP :
case IMSG_LBUTTONDOWN :
case IMSG_LBUTTONDBLCLK :
case IMSG_MBUTTONUP :
case IMSG_MBUTTONDOWN :
case IMSG_MBUTTONDBLCLK :
case IMSG_RBUTTONUP :
case IMSG_RBUTTONDOWN :
case IMSG_RBUTTONDBLCLK :
pMsg->bUse = true;
}
m_ReQueueGame.push(pMsg);
}
void SGameVM::Process( DWORD dwTime )
{
m_dwTime = dwTime;
}
void SGameVM::AddDelMsg( SGameMessage* pMsg )
{
m_vDelList.push_back( pMsg );
}
SGameMessage* SGameVM::GetGameMsg()
{
if( IsProcGameMsg() )
{
if( !m_ReQueueGame.empty() ) //리사이클이 있으면, 무조건 먼저 처리, 순서 문제 해결
{
SGameMessage* pGameMsg = m_ReQueueGame.front();
m_ReQueueGame.pop();
pGameMsg->nUseCnt++;
// assert( pGameMsg->nUseCnt < 5000 && "Recycle Msg MAX : BERSERK 불러 주세요~" );
return pGameMsg;
}
SGameMessage* pGameMsg = m_QueueGame.front();
m_QueueGame.pop();
return pGameMsg;
}
return NULL;
}
TS_MESSAGE* SGameVM::GetNetMsg()
{
if( ISProcNetMsg() )
{
TS_MESSAGE* pNetMsg = m_QueueNet.front();
m_QueueNet.pop();
return pNetMsg;
}
return NULL;
}
void *SGameVM::Perform( KID id, KArg& msg )
{
return (void*)0;
}
/// 2010.10.06 - prodongi
void SGameVM::lookUpNetStr(unsigned short id, std::string& str)
{
if (!m_hNetStr.lookup(id, str))
{
str = "unknown net message string";
}
}
// servantes 2011.02.23
void SGameVM::OnMsgCreatureFarmInfo( struct TS_SC_FARM_INFO* pMsg )
{
SMSG_CREATURE_FARM_INFO* pFMsg = new SMSG_CREATURE_FARM_INFO;
pFMsg->creature_count = pMsg->creature_count;
if(pFMsg->creature_count)
{
pFMsg->pInfoList = new SMSG_CREATURE_FARM_INFO::SMSG_SUMMON_INFO[ pFMsg->creature_count ];
::memcpy( pFMsg->pInfoList, ((BYTE*)pMsg) + sizeof(TS_SC_FARM_INFO), sizeof(SMSG_CREATURE_FARM_INFO::SMSG_SUMMON_INFO) * pMsg->creature_count );
// for(int k=0; k<pFMsg->creature_count; k++)
// {
// pFMsg->pInfoList[ k ] = pMsg->
// }
}
m_QueueGame.push( pFMsg );
}
void SGameVM::OnMsgTitle_List( struct TS_SC_TITLE_LIST* pMsg )
{
SMSG_TITLE_LIST* pMessage = new SMSG_TITLE_LIST;
pMessage->count = pMsg->count;
if( pMessage->count )
{
pMessage->pListInfo = new SMSG_TITLE_LIST::TS_TITLE_INFO[ pMessage->count ];
::memcpy( pMessage->pListInfo, ((BYTE*)pMsg) + sizeof(TS_SC_TITLE_LIST), sizeof(SMSG_TITLE_LIST::TS_TITLE_INFO) *pMsg->count );
}
m_QueueGame.push( pMessage );
}
void SGameVM::OnMsgTitle_ConditonList( struct TS_SC_TITLE_CONDITION_LIST* pMsg )
{
SMSG_TITLE_CONDITION_LIST* pMessage = new SMSG_TITLE_CONDITION_LIST;
pMessage->count = pMsg->count;
if( pMessage->count )
{
pMessage->pListInfo = new SMSG_TITLE_CONDITION_LIST::TS_TITLE_CONDITION_INFO[ pMessage->count ];
::memcpy( (BYTE*)pMessage->pListInfo, (BYTE*)pMsg + sizeof(TS_SC_TITLE_CONDITION_LIST), sizeof(SMSG_TITLE_CONDITION_LIST::TS_TITLE_CONDITION_INFO) *pMsg->count );
}
m_QueueGame.push( pMessage );
}
void SGameVM::OnMsgTitle_RemainTime( struct TS_SC_REMAIN_TITLE_TIME* pMsg )
{
SMSG_TITLE_REMAIN_TIME* pMessage = new SMSG_TITLE_REMAIN_TIME;
pMessage->remain_title_time = pMsg->remain_title_time;
m_QueueGame.push( pMessage );
}
void SGameVM::OnMsgTitle_SetMain( struct TS_SC_SET_MAIN_TITLE* pMsg )
{
SMSG_TITLE_SET_MAIN_TITLE* pMessage = new SMSG_TITLE_SET_MAIN_TITLE;
pMessage->code = pMsg->code;
pMessage->handle = pMsg->handle;
m_QueueGame.push( pMessage );
}
void SGameVM::OnMsgTitle_SetSub( struct TS_SC_SET_SUB_TITLE* pMsg )
{
SMSG_TITLE_SET_SUB_TITLE* pMessage = new SMSG_TITLE_SET_SUB_TITLE;
pMessage->index = pMsg->index;
pMessage->code = pMsg->code;
m_QueueGame.push( pMessage );
}
void SGameVM::OnMsgTitle_Bookmark( struct TS_SC_BOOKMARK_TITLE* pMsg )
{
SMSG_TITLE_BOOKMARK_TITLE* pMessage = new SMSG_TITLE_BOOKMARK_TITLE;
pMessage->code = pMsg->code;
pMessage->bookmarked = pMsg->bookmarked;
m_QueueGame.push( pMessage );
}
void SGameVM::OnMsgTitle_Achieve( struct TS_SC_ACHIEVE_TITLE* pMsg )
{
SMSG_TITLE_ACHIEVE_TITLE* pMessage = new SMSG_TITLE_ACHIEVE_TITLE;
pMessage->code = pMsg->code;
m_QueueGame.push( pMessage );
}
void SGameVM::OnMsgTitle_Open( struct TS_SC_OPEN_TITLE* pMsg )
{
SMSG_TITLE_OPEN_TITLE* pMessage = new SMSG_TITLE_OPEN_TITLE;
pMessage->code = pMsg->code;
m_QueueGame.push( pMessage );
}
void SGameVM::OnMsgTite_ChangeCondition( struct TS_SC_CHANGE_TITLE_CONDITION* pMsg )
{
SMSG_TITLE_CHANGE_CONDITION* pMessage = new SMSG_TITLE_CHANGE_CONDITION;
pMessage->condition_id = pMsg->condition_id;
pMessage->count = pMsg->count;
m_QueueGame.push( pMessage );
}
void SGameVM::OnMsgAssignResult( struct TS_SC_RESULT_FOSTER* pMsg ) //2011.03.02 - servantes
{
SMSG_RESULT_FOSTER* pFMsg = new SMSG_RESULT_FOSTER;
pFMsg->result = pMsg->result;
m_QueueGame.push( pFMsg );
}
void SGameVM::OnMsgNurseResult( struct TS_SC_RESULT_NURSE* pMsg ) //2011.03.04 - servantes
{
SMSG_RESULT_NURSE* pRMsg = new SMSG_RESULT_NURSE;
pRMsg->result = pMsg->result;
m_QueueGame.push( pRMsg );
}
void SGameVM::OnMsgRegainResult( struct TS_SC_RESULT_RETRIEVE* pMsg ) //2011.03.07 - servantes
{
SMSG_RESULT_REGAIN* pRMsg = new SMSG_RESULT_REGAIN;
pRMsg->result = pMsg->result;
m_QueueGame.push( pRMsg );
}
/// 2011.05.12 우클릭 유도 - prodongi
void SGameVM::OnMsgSkillLevelList(struct TS_SC_SKILL_LEVEL_LIST* pMsg)
{
SMSG_SKILL_LEVEL_LIST* msg = new SMSG_SKILL_LEVEL_LIST;
msg->count = pMsg->count;
if (0 < msg->count)
{
msg->list = new SMSG_SKILL_LEVEL_LIST::SkillLevelInfo[msg->count];
memcpy((void*)msg->list, (void*)((LPBYTE)pMsg + sizeof (TS_SC_SKILL_LEVEL_LIST)), sizeof (SMSG_SKILL_LEVEL_LIST::SkillLevelInfo) * msg->count);
}
m_QueueGame.push(msg);
}
void SGameVM::OnBattleArenaJoinQueue(TS_SC_BATTLE_ARENA_JOIN_QUEUE* msg)
{
SMSG_BATTLE_ARENA_JOIN_QUEUE* _msg = new SMSG_BATTLE_ARENA_JOIN_QUEUE;
_msg->arenaId = msg->nArenaID;
_msg->grade = msg->eGrade;
m_QueueGame.push(_msg);
}
void SGameVM::OnBattleArenaLeave(TS_SC_BATTLE_ARENA_LEAVE* msg)
{
SMSG_BATTLE_ARENA_LEAVE* _msg = new SMSG_BATTLE_ARENA_LEAVE;
_msg->leaveType = msg->eLeaveType;
strcpy(_msg->name, msg->szName);
m_QueueGame.push(_msg);
}
void SGameVM::OnBattleArenaBattleInfo(TS_SC_BATTLE_ARENA_BATTLE_INFO* msg)
{
SMSG_BATTLE_ARENA_BATTLE_INFO* _msg = new SMSG_BATTLE_ARENA_BATTLE_INFO;
_msg->arenaId = msg->nArenaID;
_msg->forceEnterTime = msg->nForceEnterTime;
_msg->grade = msg->eGrade;
_msg->endTime = msg->nEndTime;
_msg->startTime = msg->nStartTime;
size_t sizePlayerInfo = sizeof (TS_SC_BATTLE_ARENA_BATTLE_INFO::PlayerInfo);
byte* b_msg = (byte*)msg + sizeof (TS_SC_BATTLE_ARENA_BATTLE_INFO);
for (int i = 0; i < SMSG_BATTLE_ARENA_BATTLE_INFO::MAX_TEAM_NUM; ++i)
{
int count = msg->nPlayerCountPerTeam[i];
_msg->playerCountPerTeam[i] = count;
if (0 < count)
{
_msg->playerInfo[i] = new SMSG_BATTLE_ARENA_BATTLE_INFO::sPlayerInfo[count];
memcpy(_msg->playerInfo[i], b_msg, count * sizePlayerInfo);
b_msg += count * sizePlayerInfo;
}
}
m_QueueGame.push(_msg);
}
void SGameVM::OnBattleArenaExerciseReadyStatus(struct TS_SC_BATTLE_ARENA_EXERCISE_READY_STATUS* msg)
{
SMSG_BATTLE_ARENA_EXERCISE_READY_STATUS* _msg = new SMSG_BATTLE_ARENA_EXERCISE_READY_STATUS;
_msg->readyState = msg->nReadyState;
m_QueueGame.push(_msg);
}
void SGameVM::OnBattleArenaBattleStatus(struct TS_SC_BATTLE_ARENA_BATTLE_STATUS* msg)
{
SMSG_BATTLE_ARENA_BATTLE_STATUS* _msg = new SMSG_BATTLE_ARENA_BATTLE_STATUS;
_msg->status = msg->nStatus;
m_QueueGame.push(_msg);
}
void SGameVM::OnBattleArenaBattleScore(struct TS_SC_BATTLE_ARENA_BATTLE_SCORE* msg)
{
SMSG_BATTLE_ARENA_BATTLE_SCORE* _msg = new SMSG_BATTLE_ARENA_BATTLE_SCORE;
memcpy(_msg->teamScore, msg->aTeamScore, 2 * sizeof (TS_SC_BATTLE_ARENA_BATTLE_SCORE::TeamScore));
_msg->playerScoreCount = msg->nPlayerScoreCount;
int count = _msg->playerScoreCount;
if (0 < count)
{
_msg->playerScore = new SMSG_BATTLE_ARENA_BATTLE_SCORE::sPlayerScore[count];
memcpy(_msg->playerScore, (byte*)msg + sizeof (TS_SC_BATTLE_ARENA_BATTLE_SCORE), count * sizeof (TS_SC_BATTLE_ARENA_BATTLE_SCORE::PlayerScore));
}
m_QueueGame.push(_msg);
}
void SGameVM::OnBattleArenaJoinBattle(struct TS_SC_BATTLE_ARENA_JOIN_BATTLE* msg)
{
SMSG_BATTLE_ARENA_JOIN_BATTLE* _msg = new SMSG_BATTLE_ARENA_JOIN_BATTLE;
_msg->teamNo = msg->nTeamNo;
_msg->handle = msg->handle;
_msg->jobID = msg->nJobID;
strcpy(_msg->name, msg->szName);
m_QueueGame.push(_msg);
}
void SGameVM::OnBattleArenaDisconnectBattle(struct TS_SC_BATTLE_ARENA_DISCONNECT_BATTLE* msg)
{
SMSG_BATTLE_ARENA_DISCONNECT_BATTLE* _msg = new SMSG_BATTLE_ARENA_DISCONNECT_BATTLE;
_msg->handle = msg->handle;
m_QueueGame.push(_msg);
}
void SGameVM::OnBattleArenaReconnectBattle(struct TS_SC_BATTLE_ARENA_RECONNECT_BATTLE* msg)
{
SMSG_BATTLE_ARENA_RECONNECT_BATTLE* _msg = new SMSG_BATTLE_ARENA_RECONNECT_BATTLE;
_msg->newHandle = msg->newHandle;
strcpy(_msg->name, msg->szName);
m_QueueGame.push(_msg);
}
void SGameVM::OnBattleArenaResult(struct TS_SC_BATTLE_ARENA_RESULT* msg)
{
SMSG_BATTLE_ARENA_RESULT* _msg = new SMSG_BATTLE_ARENA_RESULT;
_msg->endType = msg->eEndType;
_msg->rewardType = msg->eRewardType;
_msg->winnerTeamNo = msg->nWinnerTeamNo;
_msg->mvpCount = msg->nMVPCount;
if (0 < _msg->mvpCount)
{
_msg->mvp = new SMSG_BATTLE_ARENA_RESULT::sMvp[msg->nMVPCount];
memcpy((void*)_msg->mvp, (byte*)msg + sizeof (TS_SC_BATTLE_ARENA_RESULT), msg->nMVPCount * sizeof (SMSG_BATTLE_ARENA_RESULT::sMvp));
}
m_QueueGame.push(_msg);
}
void SGameVM::OnBattleArenaAbsenceCheck(struct TS_SC_BATTLE_ARENA_ABSENCE_CHECK* msg)
{
SMSG_BATTLE_ARENA_ABSENCE_CHECK* _msg = new SMSG_BATTLE_ARENA_ABSENCE_CHECK;
_msg->limitTime = msg->nLimitTime;
m_QueueGame.push(_msg);
}
void SGameVM::OnBattleArenaPenaltyInfo(struct TS_SC_BATTLE_ARENA_PENALTY_INFO* msg)
{
SMSG_BATTLE_ARENA_PENALTY_INFO* _msg = new SMSG_BATTLE_ARENA_PENALTY_INFO;
_msg->blockTime = msg->nBlockTime;
_msg->penaltyCount = msg->nPenaltyCount;
_msg->penaltyCountTime = msg->nPenaltyCountDecTime;
m_QueueGame.push(_msg);
}
void SGameVM::OnBattleArenaUpdateWaitUserCount(struct TS_SC_BATTLE_ARENA_UPDATE_WAIT_USER_COUNT* msg)
{
SMSG_BATTLE_ARENA_UPDATE_WAIT_USER_COUNT* _msg = new SMSG_BATTLE_ARENA_UPDATE_WAIT_USER_COUNT;
_msg->waitUserCount = msg->nWaitUserCount;
m_QueueGame.push(_msg);
}
//-----------------------------------------------------------------------------------------------------------------
// 분해 결과
//-----------------------------------------------------------------------------------------------------------------
void SGameVM::OnDecomposeResult( struct TS_SC_DECOMPOSE_RESULT* pMsg )
{
if( NULL == pMsg )
return;
SMSG_DECOMPOSE_RESULT* pDecomposeResult( new SMSG_DECOMPOSE_RESULT() );
if( NULL == pDecomposeResult )
{
SDEBUGLOG( "[GameVM] Decompose Result Alloc Failed" );
assert( NULL );
return;
}
SMSG_DECOMPOSE_RESULT::PDECOMPOSE_INFO pItemInfo( (SMSG_DECOMPOSE_RESULT::PDECOMPOSE_INFO)(pMsg+1) );
for( UINT nCount = 0; nCount < pMsg->m_nTotalCount; nCount++ )
{
SMSG_DECOMPOSE_RESULT::DECOMPOSE_INFO stItemInfo;
memcpy( &stItemInfo, pItemInfo, sizeof(stItemInfo) );
pDecomposeResult->m_vecItemInfo.push_back( stItemInfo );
pItemInfo++;
}
m_QueueGame.push( pDecomposeResult );
}
//-----------------------------------------------------------------------------------------------------------------
// 피부색 변경
//-----------------------------------------------------------------------------------------------------------------
void SGameVM::OnChangeSkinColor( struct TS_SC_SKIN_INFO* pMsg )
{
if( NULL == pMsg )
return;
SMSG_CHANGE_SKIN_COLOR* pChangeSkinColorInfo( new SMSG_CHANGE_SKIN_COLOR() );
if( NULL == pChangeSkinColorInfo )
{
SDEBUGLOG( "[GameVM] Change Skin Color Alloc Failed" );
assert( NULL );
return;
}
pChangeSkinColorInfo->hPlayer = pMsg->hPlayer;
pChangeSkinColorInfo->dwSkinColor = pMsg->dwSkinColor;
m_QueueGame.push( pChangeSkinColorInfo );
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
// Upload Server
//
void SGameVM::OnUploadServerLogin( struct TS_UC_LOGIN_RESULT * pMsg )
{
SIMSG_UPLOADSERVER_RESULT * pResult = new SIMSG_UPLOADSERVER_RESULT( SIMSG_TOGGLE_UIWINDOW::_UIWINDOW_TYPE::UIWINDOW_GUILD_SUB_MANAGE,
SIMSG_UPLOADSERVER_RESULT::UPLOADSERVER_LOGIN_RESULT, pMsg->result );
m_QueueGame.push( pResult);
}
void SGameVM::OnUploadServerGuildIconUpload( struct TS_UC_UPLOAD * pMsg )
{
SIMSG_UPLOADSERVER_RESULT * pResult = new SIMSG_UPLOADSERVER_RESULT( SIMSG_TOGGLE_UIWINDOW::_UIWINDOW_TYPE::UIWINDOW_GUILD_SUB_MANAGE,
SIMSG_UPLOADSERVER_RESULT::UPLOADSERVER_GUILDICON_UPLOAD_RESULT, pMsg->result );
m_QueueGame.push( pResult);
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
void SGameVM::OnPartyMatchList ( struct TS_SC_PARTYMATCH_LIST * pMsg )
{
SMSG_PARTYMATCH_LIST* _msg = new SMSG_PARTYMATCH_LIST;
//
_msg->nPage = pMsg->nPage;
_msg->nRoomTotal = pMsg->nRoomTotal;
memcpy(_msg->pRoom, pMsg->pRoom, sizeof(STRUCT_PARTYMATCH_ROOM)*PARTYMATCH_ROOM_PAGE);
//
m_QueueGame.push(_msg);
}
void SGameVM::OnPartyMatchMember( struct TS_SC_PARTYMATCH_MEMBER * pMsg)
{
SMSG_PARTYMATCH_MEMBER* _msg = new SMSG_PARTYMATCH_MEMBER;
//
_msg->nRoom = pMsg->nRoom;
_msg->nMaster = pMsg->nMaster;
memcpy(_msg->pMember, pMsg->pMember, sizeof(STRUCT_PARTYMATCH_MEMBER)*PARTYMATCH_MEMBER_MAX);
//
m_QueueGame.push(_msg);
}