#include "stdafx.h" #include #include #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 #include "SGameManager.h" #include "SGame.h" //#include "Util.h" #include "SkillBase.h" #include #include #include #include "SQuestDB.h" #include "SSkillDB.h" #include "SItemDB.h" #include "SMonsterDB.h" #include "SStringDB.h" #include #include "SQuestMgr.h" #include "ErrorCode/ErrorCode.h" #include "SChatType.h" #include #include "SDebug_Util.h" #include #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 #endif #ifdef _USE_XTRAP_MODULE #include #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& questTargetList, int questCode); int getStringToInt(LPCSTR lpszName, std::map& mapInfo) { std::map::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& 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& 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& 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(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(pMsg) ); break; // 101 case TM_SC_DOUBLE_WEAPON_ATTACK_EVENT: OnDoubleAttackEvent( static_cast(pMsg) ); break; case TM_SC_CANT_ATTACK : onCantAttack( static_cast(pMsg) ); break; case TM_SC_STAT_INFO : OnStatInfo ( static_cast(pMsg) ); break; // 1000 case TM_SC_GOLD_UPDATE : OnGoldUpdate( static_cast(pMsg) ); break; // 1001 case TM_SC_LEVEL_UPDATE: OnLevelUpdate( static_cast(pMsg) ); break; // 1002 case TM_SC_EXP_UPDATE : OnExpUpdate( static_cast(pMsg) ); break; // 1003 case TM_SC_BONUS_EXP_JP: OnBonusExpUpdate( static_cast(pMsg) ); break; case TM_SC_ADD_SUMMON_INFO : OnAddSummonInfo ( static_cast(pMsg) ); break; // 301 case TM_SC_REMOVE_SUMMON_INFO : OnRemoveSummonInfo( static_cast(pMsg)); break; case TM_EQUIP_SUMMON : OnEquipSummonInfo ( static_cast(pMsg) ); break; case TM_SC_UNSUMMON : OnUnsummon ( static_cast(pMsg) ); break; case TM_SC_UNSUMMON_NOTICE : OnUnsummonNotice ( static_cast(pMsg) ); break; case TM_SC_SUMMON_EVOLUTION : OnSummonEvolution ( static_cast(pMsg) ); break; case TM_SC_TAMING_INFO : OnTamingInfo ( static_cast(pMsg) ); break; case TM_SC_MOUNT_SUMMON : OnMountSummon ( static_cast(pMsg) ); break; case TM_SC_UNMOUNT_SUMMON : OnUnMountSummon ( static_cast(pMsg) ); break; case TM_SC_SHOW_SUMMON_NAME_CHANGE : OnSummonNameChange ( static_cast(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(pMsg) ); break; //401 case TM_SC_SKILL_LIST : OnSkillList ( static_cast(pMsg) ); break; //403 //Chatting case TM_SC_CHAT_LOCAL : OnMsgChattingLocal( static_cast(pMsg) ); break; //21 case TM_SC_CHAT : OnMsgChatting ( static_cast(pMsg) ); break; //22 // 2010.05.19 HIDE_EQUIP_INFO - prodongi case TM_SC_HIDE_EQUIP_INFO: OnMsgHideEquipInfo(static_cast(pMsg)); break; //아이템 case TM_SC_WEAR_INFO : onWearInfo ( static_cast(pMsg) ); break; //202 case TM_SC_DROP_RESULT : onMsgDrop ( static_cast(pMsg) ); break; //205 case TM_SC_ITEM_DROP_INFO : onMsgDropInfo ( static_cast(pMsg) ); break; //282 case TM_SC_SKILLCARD_INFO : onMsgSkillCardInfo( static_cast(pMsg) ); break; //286 case TM_SC_ITEM_WEAR_INFO : onItemWearInfo ( static_cast(pMsg) ); break; //287 case TM_SC_INVENTORY : OnMsgInven ( static_cast(pMsg) ); break; //207 case TM_SC_OPEN_STORAGE : OnMsgOpenStorage ( static_cast(pMsg) ); break; // case TM_CS_SHOW_SOULSTONE_CRAFT_WINDOW: OnMsgOpenSoulstoneCraft( static_cast(pMsg) ); break; //260 case TM_SC_SHOW_SOULSTONE_REPAIR_WINDOW: OnMsgOpenSoulstoneRepair( static_cast(pMsg) ); break; //261 case TM_SC_MARKET : onMarket ( static_cast(pMsg) ); break; //250 case TM_SC_DESTROY_ITEM : onDestroyItem ( static_cast(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(pMsg) ); break; //255 case TM_SC_MIX_RESULT : onMixResult ( static_cast(pMsg) ); break; case TM_TRADE : onTrade ( static_cast(pMsg) ); break; //280 case TM_SC_USE_ITEM_RESULT : onUseItemResult ( static_cast(pMsg) ); break; //280 case TM_SC_TAKE_ITEM_RESULT : OnMsgTakeItemResult( static_cast(pMsg) ); break; case TM_SC_CHANGE_LOCATION : OnChangeLocation( static_cast(pMsg) ); break; //날씨 관련 case TM_SC_WEATHER_INFO : OnWeatherInfo( static_cast(pMsg) ); break; case TM_SC_GAME_TIME : OnGametime( static_cast(pMsg) ); break; //기타 case TM_SC_EMOTION : OnEmotion( static_cast(pMsg) ); break; case TM_SC_GET_CHAOS : OnGetChaos( static_cast(pMsg) ); break; //벨트 슬롯 case TM_SC_BELT_SLOT_INFO : { TS_SC_BELT_SLOT_INFO* pBeltSlotInfo = static_cast(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(pMsg) ); break; case TM_SC_STATE_RESULT : OnStateResult( static_cast(pMsg) ); break; case TM_SC_AURA : { TS_SC_AURA * pAuraMsg = static_cast(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(pMsg) ); break; case TM_SC_CHAT_RESULT : OnChatResult( static_cast(pMsg) ); break; //Cheat 관련 case TM_SC_WARP : OnWarp( static_cast(pMsg) ); break; //12 case TM_SC_STATUS_CHANGE : OnStatusChange( static_cast(pMsg) ); break; //500 // case TM_SC_HP : OnHP( static_cast(pMsg) ); break; //501 // case TM_SC_MP : OnMP( static_cast(pMsg) ); break; //502 case TM_SC_REGEN_HPMP : OnRegenHPMP( static_cast(pMsg) ); break; case TM_SC_SP : OnSP( static_cast(pMsg) ); break; //514 case TM_SC_DEAD : OnDead( pMsg ); break; // 504; 사망~ case TM_SC_STATE : OnState( static_cast(pMsg) ); break; // 505; 상태이상 case TM_SC_PROPERTY : OnProperty( static_cast(pMsg) ); break; // 507; 프로퍼티 case TM_SC_HPMP : OnHPMP( static_cast(pMsg) ); break; case TM_SC_TARGET : OnTarget( static_cast(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(pMsg) ); break; //2004 // 스킬레벨의변동이발생 case TM_SC_ADDED_SKILL_LIST: onAddedSkillList( static_cast(pMsg) ); break; //서버와의 접속이 종료 되었습니다. 메시지 수정 //2009-02-24: hunee case TM_SC_DISCONNECT_DESC : { TS_SC_DISCONNECT_DESC * desc = static_cast(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(pMsg) ); break; //3000 case TM_SC_SHOW_WINDOW : OnShowWindow( static_cast(pMsg) ); break; case TM_SC_GENERAL_MESSAGE_BOX: OnGeneralMessageBox(static_cast(pMsg)); break; /// 2011.10.26 - prodongi case TM_SC_OPEN_URL : { TS_SC_OPEN_URL* pOpen = static_cast(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(pMsg)); } break; case TM_SC_TITLE_LIST: { OnMsgTitle_List(static_cast(pMsg)); }break; case TM_SC_TITLE_CONDITION_LIST: { OnMsgTitle_ConditonList(static_cast(pMsg)); }break; case TM_SC_REMAIN_TITLE_TIME: { OnMsgTitle_RemainTime(static_cast(pMsg)); }break; case TM_SC_SET_MAIN_TITLE: { OnMsgTitle_SetMain(static_cast(pMsg)); }break; case TM_SC_SET_SUB_TITLE: { OnMsgTitle_SetSub(static_cast(pMsg)); }break; case TM_SC_BOOKMARK_TITLE: { OnMsgTitle_Bookmark(static_cast(pMsg)); }break; case TM_SC_ACHIEVE_TITLE: { OnMsgTitle_Achieve(static_cast(pMsg)); }break; case TM_SC_OPEN_TITLE: { OnMsgTitle_Open(static_cast(pMsg)); }break; case TM_SC_CHANGE_TITLE_CONDITION: { OnMsgTite_ChangeCondition(static_cast(pMsg)); }break; case TM_SC_BATTLE_ARENA_JOIN_QUEUE: OnBattleArenaJoinQueue(static_cast(pMsg)); break; case TM_SC_BATTLE_ARENA_LEAVE: OnBattleArenaLeave(static_cast(pMsg)); break; case TM_SC_BATTLE_ARENA_BATTLE_INFO: OnBattleArenaBattleInfo(static_cast(pMsg)); break; case TM_SC_BATTLE_ARENA_EXERCISE_READY_STATUS: OnBattleArenaExerciseReadyStatus(static_cast(pMsg)); break; case TM_SC_BATTLE_ARENA_BATTLE_STATUS: OnBattleArenaBattleStatus(static_cast(pMsg)); break; case TM_SC_BATTLE_ARENA_BATTLE_SCORE: OnBattleArenaBattleScore(static_cast(pMsg)); break; case TM_SC_BATTLE_ARENA_JOIN_BATTLE: OnBattleArenaJoinBattle(static_cast(pMsg)); break; case TM_SC_BATTLE_ARENA_DISCONNECT_BATTLE: OnBattleArenaDisconnectBattle(static_cast(pMsg)); break; case TM_SC_BATTLE_ARENA_RECONNECT_BATTLE: OnBattleArenaReconnectBattle(static_cast(pMsg)); break; case TM_SC_BATTLE_ARENA_RESULT: OnBattleArenaResult(static_cast(pMsg)); break; case TM_SC_BATTLE_ARENA_ABSENCE_CHECK: OnBattleArenaAbsenceCheck(static_cast(pMsg)); break; case TM_SC_BATTLE_ARENA_PENALTY_INFO: OnBattleArenaPenaltyInfo(static_cast(pMsg)); break; case TM_SC_BATTLE_ARENA_UPDATE_WAIT_USER_COUNT: OnBattleArenaUpdateWaitUserCount(static_cast(pMsg)); break; case TM_SC_DECOMPOSE_RESULT: OnDecomposeResult( static_cast(pMsg) ); break; case TM_SC_SKIN_INFO: OnChangeSkinColor( static_cast(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 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(pBuff); SkillResult skill_result; switch (pSkillResultArray->GetType()) { case SkillResult::DAMAGE: case SkillResult::MAGIC_DAMAGE: { skill_result.damage = *(reinterpret_cast(pSkillResultArray)); pSkillEvent->vSkillResult.push_back(skill_result); pBuff += sizeof(SkillResult::DamageType); break; } case SkillResult::DAMAGE_WITH_KNOCK_BACK: { skill_result.damage_kb = *(reinterpret_cast(pSkillResultArray)); pSkillEvent->vSkillResult.push_back(skill_result); pBuff += sizeof(SkillResult::DamageWithKnockBackType); break; } case SkillResult::RESULT: { skill_result.result = *(reinterpret_cast(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(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(pSkillResultArray)); pSkillEvent->vSkillResult.push_back(skill_result); pBuff += sizeof(SkillResult::AddHPMPSPType); break; } case SkillResult::RUSH: { skill_result.rush = *(reinterpret_cast(pSkillResultArray)); pSkillEvent->vSkillResult.push_back(skill_result); pBuff += sizeof(SkillResult::RushType); break; } case SkillResult::REBIRTH: { skill_result.rebirth = *(reinterpret_cast(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(pSkillResultArray)); pSkillEvent->vSkillResult.push_back(skill_result); pBuff += sizeof(SkillResult::ChainDamageType); break; } case SkillResult::CHAIN_HEAL: { skill_result.chain_heal = *(reinterpret_cast(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;jcode, _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 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& 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 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 = "

"; const char* c_szPageBreak1 = "

"; 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; nrecord_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; kcreature_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); }