#pragma once #include #include #include "ItemBase.h" #include "ItemEffect.h" #include "ItemInstance.h" #include "QuestBase.h" #include "QuestInstance.h" #include "CreatureBase.h" #include "Enc.h" #include "GameRule.h" #include "BattleArenaBase.h" #ifdef _HACK_SHIELD_ #include #endif #define _INIT(_id) { ZeroMemory( this, sizeof(*this) ); id = _id; size = sizeof( *this ); set_check_sum(); } #pragma pack( 1 ) const unsigned short TM_COMMON = 9998; const unsigned short TM_NONE = 9999; //const unsigned short TM_CS_VERSION_OLD = 50; // 2012. 8. 27 - marine 기존에 쓰던거 사용 안함.. const unsigned short TM_CS_VERSION = 51; const unsigned short TM_SC_RESULT = 0; const unsigned short TM_PUBLIC_KEY = 71; const unsigned short TM_SECRET_KEY = 72; const unsigned short TM_CS_LOGIN = 1; //1 - 61 const unsigned short TM_SC_LOGIN_RESULT = 4; //4 - 64 const unsigned short TM_TIMESYNC = 2; const unsigned short TM_SC_ENTER = 3; const unsigned short TM_CS_QUERY = 13; const unsigned short TM_CS_MOVE_REQUEST = 5; //5 - 65 const unsigned short TM_SC_MOVE_ACK = 6; //6 - 66 const unsigned short TM_CS_REGION_UPDATE = 7; //7 - 67 const unsigned short TM_SC_REGION_ACK = 11; const unsigned short TM_SC_MOVE = 8; const unsigned short TM_SC_LEAVE = 9; const unsigned short TM_SC_SET_TIME = 10; const unsigned short TM_SC_WARP = 12; const unsigned short TM_CS_ENTER_EVENT_AREA = 15; const unsigned short TM_CS_LEAVE_EVENT_AREA = 16; ///< 2011.07.06 - servantes const unsigned short TM_CS_CHAT_REQUEST = 20; const unsigned short TM_SC_CHAT_LOCAL = 21; const unsigned short TM_SC_CHAT = 22; const unsigned short TM_CS_RETURN_LOBBY = 23; ///< 캐릭터 선택 로비로 이동 const unsigned short TM_SC_CHAT_RESULT = 24; ///< 채팅 결과 const unsigned short TM_CS_REQUEST_RETURN_LOBBY = 25; const unsigned short TM_CS_REQUEST_LOGOUT = 26; const unsigned short TM_CS_LOGOUT = 27; const unsigned short TM_SC_CHANGE_NAME = 30; ///< 이름 변경 const unsigned short TM_CS_CHANGE_ALIAS = 31; /// 아레나 이름 변경 //핵쉴드 서버 연동 const unsigned short TM_SC_ANTI_HACK = 53; const unsigned short TM_CS_ANTI_HACK = 54; //nProtect const unsigned short TM_SC_GAME_GUARD_AUTH_QUERY = 55; const unsigned short TM_CS_GAME_GUARD_AUTH_ANSWER = 56; const unsigned short TM_CS_CHECK_ILLEGAL_USER = 57; ///< sonador 7.4.3 해킹 툴 감지후 종료 프로세스 구현 const unsigned short TM_SC_XTRAP_CHECK = 58; const unsigned short TM_CS_XTRAP_CHECK = 59; const unsigned short TM_CS_ATTACK_REQUEST = 100; const unsigned short TM_SC_ATTACK_EVENT = 101; const unsigned short TM_SC_CANT_ATTACK = 102; const unsigned short TM_SC_DOUBLE_WEAPON_ATTACK_EVENT = 103; const unsigned short TM_CS_CANCEL_ACTION = 150; const unsigned short TM_CS_PUTON_ITEM = 200; ///< 아이템 장비 요청 const unsigned short TM_CS_PUTOFF_ITEM = 201; ///< 아이템 장비해제 요청 const unsigned short TM_SC_WEAR_INFO = 202; ///< 아이템 장비 정보 - 첫 enter 시, 혹은 장비 변경시 방송됨 const unsigned short TM_CS_DROP_ITEM = 203; ///< 아이템 버림 요청 const unsigned short TM_CS_TAKE_ITEM = 204; ///< 아이템 줍기 요청 const unsigned short TM_SC_DROP_RESULT = 205; ///< 아이템 버림 결과 const unsigned short TM_SC_INVENTORY = 207; ///< 인벤 내용 const unsigned short TM_CS_ERASE_ITEM = 208; ///< 아이템 파기 const unsigned short TM_SC_ERASE_ITEM = 209; // 아이템파괴. const unsigned short TM_SC_TAKE_ITEM_RESULT = 210; ///< 아이텝 줍기 const unsigned short TM_SC_OPEN_STORAGE = 211; ///< 창고를 여셈~ const unsigned short TM_CS_STORAGE = 212; ///< 창고 아이템 이동 const unsigned short TM_SC_GET_CHAOS = 213; ///< 혼돈 얻음 const unsigned short TM_CS_PUTON_CARD = 214; ///< 벨트 슬롯에 아이템 장착 const unsigned short TM_CS_PUTOFF_CARD = 215; ///< 벨트 슬롯에 아이템 장착 const unsigned short TM_SC_BELT_SLOT_INFO = 216; ///< 벨트 슬롯 정보 const unsigned short TM_SC_ITEM_COOL_TIME = 217; ///< 아이템 쿨타임 const unsigned short TM_CS_CHANGE_ITEM_POSITION = 218; ///< 아이템 위치 변경 const unsigned short TM_CS_ARRANGE_ITEM = 219; ///< 인벤토리/창고 아이템 정렬 // sonador 1.9.1 인벤토리 및 창고 정렬 기능 구현 // 2010.05.19 - prodongi const unsigned short TM_CS_HIDE_EQUIP_INFO = 221; ///< 장비 숨기기 정보 변경 요청 const unsigned short TM_SC_HIDE_EQUIP_INFO = 222; ///< 장비 숨기기 정보 방송 - TM_CS_HIDE_EQUIP_INFO 처리 시 방송됨 const unsigned short TM_CS_SWAP_EQUIP = 223; // Weapon swap const unsigned short TM_SC_SKIN_INFO = 224; // 피부색 변경 const unsigned short TM_SC_NPC_TRADE_INFO = 240; ///< NPC에게 아이템을 판매/구매하였을 때 const unsigned short TM_SC_MARKET = 250; ///< 상점 아이템 리스트 const unsigned short TM_CS_BUY_ITEM = 251; ///< 아이템 구입 const unsigned short TM_CS_SELL_ITEM = 252; ///< 아이템 판매 const unsigned short TM_CS_USE_ITEM = 253; ///< 아이템 사용 const unsigned short TM_SC_DESTROY_ITEM = 254; ///< 아이템 제거 const unsigned short TM_SC_UPDATE_ITEM_COUNT = 255; ///< 아이템 제거 const unsigned short TM_CS_MIX = 256; ///< 아이템 조합 const unsigned short TM_SC_MIX_RESULT = 257; ///< 아이템 조합 결과 const unsigned short TM_CS_DONATE_ITEM = 258; ///< 기부 const unsigned short TM_CS_DONATE_REWARD = 259; ///< 기부 보상 아이템 요청 const unsigned short TM_CS_SHOW_SOULSTONE_CRAFT_WINDOW = 259; ///< 소켓 const unsigned short TM_CS_SOULSTONE_CRAFT = 260; ///< 소켓 UI에 의한 소울스톤 세공 const unsigned short TM_SC_SHOW_SOULSTONE_REPAIR_WINDOW = 261; ///< 아이템 소울스톤 영혼력 수리 UI 표시 요청 const unsigned short TM_CS_REPAIR_SOULSTONE = 262; ///< 소켓 아이템 내구도 수리 const unsigned short TM_CS_TRANSMIT_ETHEREAL_DURABILITY = 263; // 아이템수리. const unsigned short TM_CS_TRANSMIT_ETHEREAL_DURABILITY_TO_EQUIPMENT = 264; // 아이템전체수리. const unsigned short TM_CS_DECOMPOSE = 265; ///< 아이템 분해 const unsigned short TM_SC_DECOMPOSE_RESULT = 266; ///< 아이템 분해 결과 const unsigned short TM_TRADE = 280; ///< 트레이드 const unsigned short TM_CS_PUTON_ITEM_SET = 281; ///< 풀셋 아이템 장착 요청 const unsigned short TM_SC_ITEM_DROP_INFO = 282; ///< 어떤 몹이 어떤 아템 떨어트리는건지 정보 const unsigned short TM_SC_USE_ITEM_RESULT = 283; ///< 아이템 사용 결과 const unsigned short TM_CS_BIND_SKILLCARD = 284; const unsigned short TM_CS_UNBIND_SKILLCARD = 285; const unsigned short TM_SC_SKILLCARD_INFO = 286; const unsigned short TM_SC_ITEM_WEAR_INFO = 287; ///< 아이템 장비 정보 - 첫 enter 시, 혹은 장비 변경시 방송됨 const unsigned short TM_SC_ADD_SUMMON_INFO = 301; ///< 편성된 소환수 정보 추가 const unsigned short TM_SC_REMOVE_SUMMON_INFO = 302; ///< 편성된 소환수 정보 제거 const unsigned short TM_EQUIP_SUMMON = 303; ///< 소환수 편성 정보 const unsigned short TM_CS_SUMMON = 304; ///< 소환/역소환 요청 const unsigned short TM_SC_UNSUMMON = 305; ///< 역소환 통지 const unsigned short TM_SC_UNSUMMON_NOTICE = 306; ///< 역소환 알림( x시간 후에 역소환 됨 ) const unsigned short TM_SC_SUMMON_EVOLUTION = 307; ///< 크리처 진화 const unsigned short TM_SC_TAMING_INFO = 310; ///< 테이밍 정보 const unsigned short TM_SC_MOUNT_SUMMON = 320; ///< 올라 타기 const unsigned short TM_SC_UNMOUNT_SUMMON = 321; ///< 내려오기 const unsigned short TM_SC_SHOW_SUMMON_NAME_CHANGE = 322; ///< 소환수 이름 변경 UI 출력 요청 const unsigned short TM_CS_CHANGE_SUMMON_NAME = 323; ///< 변경될 소환수 이름(대상은 StructPlayer가 들고 있음) const unsigned short TM_CS_GET_SUMMON_SETUP_INFO = 324; ///< 소환수 편성 정보를 포함하는 메시지 요청(편성 창 띄우기로 사용) // sonador 10.2.1 팻 시스템 구현 const unsigned short TM_SC_UNSUMMON_PET = 350; ///< 팻 역소환 통지 const unsigned short TM_SC_ADD_PET_INFO = 351; ///< 보유 중인 펫 정보 추가 const unsigned short TM_SC_REMOVE_PET_INFO = 352; ///< 보유 중인 펫 정보 제거 const unsigned short TM_SC_SHOW_SET_PET_NAME = 353; ///< 펫 이름 설정 창 표시 const unsigned short TM_CS_SET_PET_NAME = 354; ///< 펫 이름 설정 const unsigned short TM_CS_SKILL = 400; const unsigned short TM_SC_SKILL = 401; const unsigned short TM_CS_LEARN_SKILL = 402; const unsigned short TM_SC_SKILL_LIST = 403; const unsigned short TM_CS_REQUEST_REMOVE_STATE = 408; ///<지속효과 삭제요천 메시지 const unsigned short TM_CS_JOB_LEVEL_UP = 410; //const unsigned short TM_SC_SKILL_EFFECT = 404; //const unsigned short TM_SC_SKILL_CASTING_TIME = 405; //폐기 됨 const unsigned short TM_SC_STATE_RESULT = 406; const unsigned short TM_SC_AURA = 407; /// 2011.05.12 우클릭 유도 - prodongi const unsigned short TM_SC_SKILL_LEVEL_LIST = 451; const unsigned short TM_CS_SUMMON_CARD_SKILL_LIST = 452; const unsigned short TM_SC_STATUS_CHANGE = 500; //const unsigned short TM_SC_HP = 501; //메시지 변경으로 인하여 더이상 안쓰임 //const unsigned short TM_SC_MP = 502; //메시지 변경으로 인하여 더이상 안쓰임 const unsigned short TM_CS_UPDATE = 503; ///< HP/MP 채우는거나 기타등등. 30초가량마다 한번씩 다오~ const unsigned short TM_SC_DEAD = 504; ///< 사망~ const unsigned short TM_SC_STATE = 505; ///< 상태이상 메세지 const unsigned short TM_SC_PROPERTY = 507; ///< 프로퍼티 const unsigned short TM_CS_SET_PROPERTY = 508; ///< 프로퍼티 const unsigned short TM_SC_HPMP = 509; const unsigned short TM_SC_REGEN_INFO = 510; const unsigned short TM_SC_ENERGY = 515; const unsigned short TM_SC_REGEN_HPMP = 516; const unsigned short TM_CS_TARGETING = 511; ///< 타겟의 상태 이상 정보 요청 const unsigned short TM_SC_TARGET = 512; const unsigned short TM_CS_RESURRECTION = 513; const unsigned short TM_SC_SP = 514; const unsigned short TM_CS_MONSTER_RECOGNIZE = 517; const unsigned short TM_CS_GET_REGION_INFO = 550; const unsigned short TM_SC_QUEST_LIST = 600; const unsigned short TM_SC_QUEST_STATUS = 601; const unsigned short TM_SC_QUEST_INFOMATION = 602; const unsigned short TM_CS_DROP_QUEST = 603; const unsigned short TM_CS_QUEST_INFO = 604; const unsigned short TM_CS_END_QUEST = 605; // 2011.07.12 - servantes //625~636 2012. 4. 17 - marine 호칭 관련.. const unsigned short TM_SC_TITLE_LIST = 625; // 로그인시 호칭 전체목록 const unsigned short TM_SC_TITLE_CONDITION_LIST = 626; // 진행중인 호칭 조건의 전체 목록 const unsigned short TM_SC_REMAIN_TITLE_TIME = 627; // 주호칭 쿨타임 남은 시간 const unsigned short TM_CS_SET_MAIN_TITLE = 628; // 주호칭 장착 const unsigned short TM_SC_SET_MAIN_TITLE = 629; const unsigned short TM_CS_SET_SUB_TITLE = 630; // 부호칭 장착 const unsigned short TM_SC_SET_SUB_TITLE = 631; const unsigned short TM_CS_BOOKMARK_TITLE = 632; // 즐겨찾기 const unsigned short TM_SC_BOOKMARK_TITLE = 633; const unsigned short TM_SC_ACHIEVE_TITLE = 634; // 호칭 획득 const unsigned short TM_SC_OPEN_TITLE = 635; // 호칭 열림 const unsigned short TM_SC_CHANGE_TITLE_CONDITION = 636; // 호칭관련 상태 변경 const unsigned short TM_SC_SHOW_CREATE_GUILD = 650; const unsigned short TM_SC_OPEN_GUILD_WINDOW = 651; const unsigned short TM_SC_SHOW_CREATE_ALLIANCE = 660; const unsigned short TM_CS_START_BOOTH = 700; ///< 개설 const unsigned short TM_CS_STOP_BOOTH = 701; ///< 중지 const unsigned short TM_CS_WATCH_BOOTH = 702; ///< 내용 보기 const unsigned short TM_SC_WATCH_BOOTH = 703; ///< 내용 보내주기 const unsigned short TM_CS_STOP_WATCH_BOOTH = 704; ///< 그만 보기 const unsigned short TM_CS_BUY_FROM_BOOTH = 705; ///< 물건 구입 const unsigned short TM_CS_SELL_TO_BOOTH = 706; ///< 물건 판매 const unsigned short TM_CS_GET_BOOTHS_NAME = 707; ///< 노점 이름 얻어오기 const unsigned short TM_SC_GET_BOOTHS_NAME = 708; ///< 노점 이름들 const unsigned short TM_SC_BOOTH_CLOSED = 709; ///< 노점 닫힘 알림 const unsigned short TM_SC_BOOTH_TRADE_INFO = 710; const unsigned short TM_CS_CHECK_BOOTH_STARTABLE = 711; ///< 노점 개설 가능 여부 확인(클라 UI 출력 전 확인) const unsigned short TM_CS_TURN_ON_PK_MODE = 800; ///<피케이 온 const unsigned short TM_CS_TURN_OFF_PK_MODE = 801; ///<피케이 오프 const unsigned short TM_CS_CHANGE_LOCATION = 900; ///<지역 관련 const unsigned short TM_SC_CHANGE_LOCATION = 901; ///<지역 관련 const unsigned short TM_SC_WEATHER_INFO = 902; ///<날씨 관련 const unsigned short TM_CS_GET_WEATHER_INFO = 903; ///<날씨 관련 const unsigned short TM_CS_GAME_TIME = 1100; const unsigned short TM_SC_GAME_TIME = 1101; const unsigned short TM_SC_EMOTION = 1201; const unsigned short TM_CS_EMOTION = 1202; const unsigned short TM_SC_STAT_INFO = 1000; ///< 스탯정보 const unsigned short TM_SC_GOLD_UPDATE = 1001; ///< 돈 바뀜 const unsigned short TM_SC_LEVEL_UPDATE = 1002; ///< 레벨 바뀜 const unsigned short TM_SC_EXP_UPDATE = 1003; ///< 경험치 바뀜 const unsigned short TM_SC_BONUS_EXP_JP = 1004; ///< 뽀나스 경험치 // { [sonador][3.1.3] 경매장 서버 연동 const unsigned short TM_CS_AUCTION_SEARCH = 1300; ///< 경매 물품 검색 요청 const unsigned short TM_SC_AUCTION_SEARCH = 1301; ///< 경매 물품 검색 결과 const unsigned short TM_CS_AUCTION_SELLING_LIST = 1302; ///< 자신이 등록한 경매 물품 목록 요청 const unsigned short TM_SC_AUCTION_SELLING_LIST = 1303; ///< 자신이 등록한 경매 물품 목록 결과 const unsigned short TM_CS_AUCTION_BIDDED_LIST = 1304; ///< 자신이 입찰한 경매 목록 요청 const unsigned short TM_SC_AUCTION_BIDDED_LIST = 1305; ///< 자신이 입찰한 경매 목록 결과 const unsigned short TM_CS_AUCTION_BID = 1306; ///< 경매 입찰 요청(결과는 TS_SC_RESULT로 보내고 성공시 최고 입찰가는 TS_SC_RESULT 메시지의 value로 전달함) const unsigned short TM_CS_AUCTION_INSTANT_PURCHASE = 1308; ///< 경매 물품 즉시구매 요청(결과는 TS_SC_RESULT로 보내고 페이지 갱신은 클라에서 요청 따로 보냄) const unsigned short TM_CS_AUCTION_REGISTER = 1309; ///< 경매 물품 등록 요청(결과는 TS_SC_RESULT로 보내고 그 후에 TS_SC_AUCTION_SELLING_LIST를 바로 보냄) const unsigned short TM_CS_AUCTION_CANCEL = 1310; ///< 자신이 등록한 경매 취소 요청(결과는 TS_SC_RESULT로 보내고 그 후에 TS_SC_AUCTION_SELLING_LIST를 바로 보냄) const unsigned short TM_CS_ITEM_KEEPING_LIST = 1350; ///< 자신 소유 보관 아이템 목록 요청 const unsigned short TM_SC_ITEM_KEEPING_LIST = 1351; ///< 자신 소유 보관 아이템 목록 결과 const unsigned short TM_CS_ITEM_KEEPING_TAKE = 1352; ///< 자신 소유 보관 아이템 회수 요청(결과는 TS_SC_RESULT로 보냄) // } const unsigned short TM_CS_ACCOUNT = 2000; const unsigned short TM_CS_CHARACTER_LIST = 2001; const unsigned short TM_CS_CREATE_CHARACTER = 2002; const unsigned short TM_CS_DELETE_CHARACTER = 2003; const unsigned short TM_SC_CHARACTER_LIST = 2004; const unsigned short TM_CS_CHECK_CHARACTER_NAME = 2006; // Nickname validation const unsigned short TM_SC_DIALOG = 3000; const unsigned short TM_CS_DIALOG = 3001; const unsigned short TM_CS_CONTACT = 3002; const unsigned short TM_SC_SHOW_WINDOW = 3003; const unsigned short TM_SC_GENERAL_MESSAGE_BOX = 3004; /// 2011.10.26 - prodongi // // HuntaHolic system message // // { /** * 헌터홀릭 던전의 인스턴스(방) 목록을 클라이언트에서 서버에게 요청할 때 사용됩니다. */ const unsigned short TM_CS_HUNTAHOLIC_INSTANCE_LIST = 4000; /** * 서버에서 클라이언트 요청에 따라 인스턴스(방) 목록을 보낼 때 사용됩니다. * 방 목록을 보여주는 로비 UI의 갱신에 사용되면 될 듯 합니다. */ const unsigned short TM_SC_HUNTAHOLIC_INSTANCE_LIST = 4001; /** * 현재 플레이어가 소속된 인스턴스 방의 정보가 변경될 때 (새로운 유저의 입장, 탈퇴 등) * 서버에서 클라이언트에게 변경된 방의 정보를 보낼 때 사용됩니다. 방에 진입한 상태에서 * 별도로 자신이 소속된 방의 정보만 보여주는 UI의 갱신에 사용되면 될 듯 합니다. */ const unsigned short TM_SC_HUNTAHOLIC_INSTANCE_INFO = 4002; /** * 플레이어가 새로운 방을 만드려고 할 때 새 방 만들기 요청을 서버로 보내기 위해 * 사용됩니다. */ const unsigned short TM_CS_HUNTAHOLIC_CREATE_INSTANCE = 4003; /** * 플레이어가 기존에 존재하던 방에 입장을 요청할 때 사용됩니다. */ const unsigned short TM_CS_HUNTAHOLIC_JOIN_INSTANCE = 4004; /** * 현재 플레이어가 가입해 있는 방을 나가기를 요청할 때 사용됩니다. 서버가 이 메시지를 * 받지 않는다 하더라도 로비에서 마을로 돌아가거나 접속을 종료할 때에는 자동적으로 * 현재 소속된 방에서 탈퇴됩니다. */ const unsigned short TM_CS_HUNTAHOLIC_LEAVE_INSTANCE = 4005; /** * 헌터홀릭 던전 사냥을 종료했을 때 플레이어에게 보내지는 스코어 정보입니다. 성공했든 * 실패했든 사냥 종료 당시 스코어에 대한 정보와 성공/실패 여부를 모두 포함하게 됩니다. */ const unsigned short TM_SC_HUNTAHOLIC_HUNTING_SCORE = 4006; /** * 던전내에서 사냥을 진행할 때 킬 카운트와 획득 스코어 갱신을 위해 * 몹이 죽을때 마다 방 안의 전체 멤버에게 송신됩니다. */ const unsigned short TM_SC_HUNTAHOLIC_UPDATE_SCORE = 4007; const unsigned short TM_CS_HUNTAHOLIC_LEAVE_LOBBY = 4008; ///< 헌터홀릭 로비에서 로비 입장 지점으로 귀환 const unsigned short TM_SC_HUNTAHOLIC_BEGIN_HUNTING = 4009; ///< 헌터홀릭 로비에서 던전으로 입장, 사냥 시작 ///const unsigned short TM_SC_HUNTAHOLIC_MAX_POINT_REACHED = 4010; ///< 헌터홀릭 던전 내에서 최대 획득 가능 포인트 도달 시 알림 창 띄우기용 메시지 // sonador #2.1.2.11.5 const unsigned short TM_SC_HUNTAHOLIC_MAX_POINT_ACHIEVED = 4010; //TM_SC_HUNTAHOLIC_MAX_POINT_REACHED 가 이름을 바꿈; const unsigned short TM_CS_HUNTAHOLIC_BEGIN_HUNTING = 4011; const unsigned short TM_SC_HUNTAHOLIC_BEGIN_COUNTDOWN = 4012; const unsigned short TM_CS_INSTANCE_GAME_ENTER = 4250; const unsigned short TM_CS_INSTANCE_GAME_EXIT = 4251; const unsigned short TM_CS_INSTANCE_GAME_SCORE_REQUEST = 4252; const unsigned short TM_SC_INSTANCE_GAME_SCORE_REQUEST = 4253; // servantes 2011.02.23 // 크리처 농장 관련 const unsigned short TM_CS_REQUEST_FARM_INFO = 6000; const unsigned short TM_SC_FARM_INFO = 6001; const unsigned short TM_CS_FOSTER_CREATURE = 6002; const unsigned short TM_SC_RESULT_FOSTER = 6003; const unsigned short TM_CS_RETRIEVE_CREATURE = 6004; const unsigned short TM_SC_RESULT_RETRIEVE = 6005; const unsigned short TM_CS_NURSE_CREATURE = 6006; const unsigned short TM_SC_RESULT_NURSE = 6007; const unsigned short TM_CS_REQUEST_FARM_MARKET = 6008; // 2011.06.15 - servantes // } end of HuntaHolic system message // 파티매칭 const unsigned short TM_CS_PARTYMATCH_ACTION = 7000; const unsigned short TM_SC_PARTYMATCH_LIST = 7001; const unsigned short TM_SC_PARTYMATCH_MEMBER = 7002; const unsigned short TM_CS_REPORT = 8000; const unsigned short TM_SC_OPEN_URL = 9000; ///< 캐릭터 로그인시 띄우는 팝업 URL const unsigned short TM_SC_URL_LIST = 9001; ///< 서버에 세팅된 URL //const unsigned short TM_SC_CREATE_SECURITY_NO = 9002; const unsigned short TM_SC_REQUEST_SECURITY_NO = 9004; const unsigned short TM_CS_SECURITY_NO = 9005; // const unsigned short TM_CS_CREATE_SECURITY_NO = 9006; // const unsigned short TM_CS_CHANGE_SECURITY_NO = 9007; // const unsigned short TM_CS_REQUEST_SECURITY_NO_CHANGE = 9008; // const unsigned short TM_SC_CHANGE_SECURITY_NO = 9009; //const unsigned short TM_CS_REQUEST_CLEAR_SECURITY_NO = 9010; //const unsigned short TM_SC_CLEAR_SECURITY_NO = 9011; //const unsigned short TM_CS_CLEAR_SECURITY_NO = 9012; // { 유료화 관련 const unsigned short TM_CS_OPEN_ITEM_SHOP = 10000; const unsigned short TM_SC_OPEN_ITEM_SHOP = 10001; const unsigned short TM_SC_OPEN_PAID_STORAGE = 10002; const unsigned short TM_SC_COMMERCIAL_STORAGE_INFO = 10003; ///< 캐쉬템창고에아이템이뭔가들어왔을경우전송됨 const unsigned short TM_SC_COMMERCIAL_STORAGE_LIST = 10004; ///< 캐쉬템 리스트 const unsigned short TM_CS_TAKEOUT_COMMERCIAL_ITEM = 10005; ///< 캐쉬템에서 아이템 꺼냄 // } const unsigned short TM_SC_DISCONNECT_DESC = 28; ///< 서버와의 접속이 종료되었습니다 /** * 1:1 대련 관련 패킷 추가 * 2009-01-29 : hunee * */ // Compete(필드 대련) 관련 const unsigned short TM_CS_COMPETE_REQUEST = 4500; const unsigned short TM_SC_COMPETE_REQUEST = 4501; const unsigned short TM_CS_COMPETE_ANSWER = 4502; const unsigned short TM_SC_COMPETE_ANSWER = 4503; const unsigned short TM_SC_COMPETE_COUNTDOWN = 4504; const unsigned short TM_SC_COMPETE_START = 4505; const unsigned short TM_SC_COMPETE_END = 4506; /// 2012.06.04 - prodongi // 배틀 아레나 관련 const unsigned short TM_SC_BATTLE_ARENA_PENALTY_INFO = 4700; const unsigned short TM_CS_BATTLE_ARENA_JOIN_QUEUE = 4701; const unsigned short TM_SC_BATTLE_ARENA_JOIN_QUEUE = 4702; const unsigned short TM_SC_BATTLE_ARENA_UPDATE_WAIT_USER_COUNT = 4703; const unsigned short TM_CS_BATTLE_ARENA_LEAVE = 4704; const unsigned short TM_SC_BATTLE_ARENA_LEAVE = 4705; const unsigned short TM_SC_BATTLE_ARENA_BATTLE_INFO = 4706; const unsigned short TM_CS_BATTLE_ARENA_ENTER_WHILE_COUNTDOWN = 4707; const unsigned short TM_CS_BATTLE_ARENA_EXERCISE_READY = 4708; const unsigned short TM_SC_BATTLE_ARENA_EXERCISE_READY_STATUS = 4709; const unsigned short TM_CS_BATTLE_ARENA_EXERCISE_START = 4710; const unsigned short TM_SC_BATTLE_ARENA_BATTLE_STATUS = 4711; const unsigned short TM_SC_BATTLE_ARENA_BATTLE_SCORE = 4712; const unsigned short TM_SC_BATTLE_ARENA_JOIN_BATTLE = 4713; const unsigned short TM_SC_BATTLE_ARENA_DISCONNECT_BATTLE = 4714; const unsigned short TM_SC_BATTLE_ARENA_RECONNECT_BATTLE = 4715; const unsigned short TM_SC_BATTLE_ARENA_RESULT = 4716; const unsigned short TM_CS_BATTLE_ARENA_ABSENCE_CHECK_REQUEST = 4717; const unsigned short TM_SC_BATTLE_ARENA_ABSENCE_CHECK = 4718; const unsigned short TM_CS_BATTLE_ARENA_ABSENCE_CHECK_ANSWER = 4719; /* 랭킹 시스템 관련 2009.03.24 : kappamind. */ const unsigned short TM_CS_RANKING_TOP_RECORD = 5000; const unsigned short TM_SC_RANKING_TOP_RECORD = 5001; /*****************************************************************************/ struct TS_MESSAGE { TS_MESSAGE() { size = sizeof( *this ); set_check_sum(); // TODO : 이거 서버에서는 빼도 됨 } unsigned int size; unsigned short id; unsigned char msg_check_sum; bool IsValidMessage() const { return ( msg_check_sum == get_check_sum() ); } void set_check_sum() { msg_check_sum = get_check_sum(); } protected: unsigned char get_check_sum() const { char *p = const_cast< char* >( reinterpret_cast< const char* >( &size ) ); unsigned char check_sum = 0; while( p != reinterpret_cast< const char* >( &msg_check_sum ) ) { check_sum += *p; ++p; } return check_sum; } }; struct TS_PUBLIC_KEY : TS_MESSAGE { TS_PUBLIC_KEY() _INIT( TM_PUBLIC_KEY ) size_t nKeySize; }; struct TS_SECRET_KEY : TS_MESSAGE { TS_SECRET_KEY() _INIT( TM_SECRET_KEY ) size_t nEncryptSize; }; struct TS_SC_RESULT : TS_MESSAGE { TS_SC_RESULT( unsigned short _request_msg_id, unsigned short _result, int _value ) : request_msg_id( _request_msg_id ), result( _result ), value( _value ) { size = sizeof( *this ); id = TM_SC_RESULT; set_check_sum(); } unsigned short request_msg_id; unsigned short result; int value; }; /// 헌터홀릭 인스턴스 던전 목록 송신 요청 struct TS_CS_HUNTAHOLIC_INSTANCE_LIST : TS_MESSAGE { TS_CS_HUNTAHOLIC_INSTANCE_LIST() _INIT( TM_CS_HUNTAHOLIC_INSTANCE_LIST ) int page; ///< 목록 페이지 번호 }; struct TS_HUNTAHOLIC_INSTANCE_INFO { void init() { instance_no = -1; current_member_count = 0; max_member_count = 0; require_password = false; ::memset( name, 0, sizeof( name ) ); } bool isValid() const { return instance_no > -1 ? true : false; } int instance_no; ///< 방 번호 char name[ GameRule::HUNTAHOLIC_MAX_INSTANCE_NAME_LENGTH + 1 ]; ///< 방 이름 unsigned char current_member_count; ///< 현재 참가 인원 unsigned char max_member_count; ///< 최대 참가 인원 bool require_password; ///< 비번방 여부(true: 비번방, false: 공개방) }; /// 헌터홀릭 인스턴스 던전 목록 struct TS_SC_HUNTAHOLIC_INSTANCE_LIST : TS_MESSAGE { TS_SC_HUNTAHOLIC_INSTANCE_LIST() _INIT( TM_SC_HUNTAHOLIC_INSTANCE_LIST ) int huntaholic_id; ///< 헌터홀릭 ID int page; ///< 현재 페이지 번호 int count; ///< 현재 페이지에 해당하는 인스턴스 던전 개수 int total_page; ///< 전체 인스턴스 목록의 페이지 수 // 이 뒤로 TS_HUNTAHOLIC_INSTANCE_INFO 가 count 개 만큼 이어 붙음 }; /// 헌터홀릭 인스턴스 던전 정보(현재 소속된 던전만) struct TS_SC_HUNTAHOLIC_INSTANCE_INFO : TS_MESSAGE { TS_SC_HUNTAHOLIC_INSTANCE_INFO() _INIT( TM_SC_HUNTAHOLIC_INSTANCE_INFO ) TS_HUNTAHOLIC_INSTANCE_INFO info; }; /// 헌터홀릭 인스턴스 던전 생성 요청 struct TS_CS_HUNTAHOLIC_CREATE_INSTANCE : TS_MESSAGE { TS_CS_HUNTAHOLIC_CREATE_INSTANCE() _INIT( TM_CS_HUNTAHOLIC_CREATE_INSTANCE ) char name[ GameRule::HUNTAHOLIC_MAX_INSTANCE_NAME_LENGTH + 1 ]; unsigned char max_member_count; char password[ GameRule::HUNTAHOLIC_MAX_INSTANCE_PASSWORD_LENGTH + 1 ]; }; /// 헌터홀릭 인스턴스 던전 참가 요청 struct TS_CS_HUNTAHOLIC_JOIN_INSTANCE : TS_MESSAGE { TS_CS_HUNTAHOLIC_JOIN_INSTANCE() _INIT( TM_CS_HUNTAHOLIC_JOIN_INSTANCE ) int instance_no; char password[ GameRule::HUNTAHOLIC_MAX_INSTANCE_PASSWORD_LENGTH + 1 ]; }; /// 헌터홀릭 인스턴스 던전 탈퇴 요청 struct TS_CS_HUNTAHOLIC_LEAVE_INSTANCE : TS_MESSAGE { TS_CS_HUNTAHOLIC_LEAVE_INSTANCE() _INIT( TM_CS_HUNTAHOLIC_LEAVE_INSTANCE ) }; /// 헌터홀릭 인스턴스 던전 사냥 결과 struct TS_SC_HUNTAHOLIC_HUNTING_SCORE : TS_MESSAGE { TS_SC_HUNTAHOLIC_HUNTING_SCORE() _INIT( TM_SC_HUNTAHOLIC_HUNTING_SCORE ) int huntaholic_id; ///< 헌터홀릭 ID int personal_kill_count;///< 개인 킬수 int personal_score; ///< 개인 점수 int kill_count; ///< 킬 수 int score; ///< 킬수에 따른 점수 double point_advantage; ///< 방 레벨대에 따른 점수 증폭치 double point_rate; ///< 올림방 여부에 따른 증폭치(1.0: 일반방, 1.0초과: 올림방) int gain_point; ///< 최종 계산된 획득 포인트 char is_retired; ///< 0: 성공 / 1: 사망 / 2: 실패 // sonador #2.1.2.9.3 헌터홀릭 시스템 수정(사망/실패 구분) }; /// 헌터홀릭 인스턴스 던전 사냥 중 점수 갱신 struct TS_SC_HUNTAHOLIC_UPDATE_SCORE : TS_MESSAGE { TS_SC_HUNTAHOLIC_UPDATE_SCORE() _INIT( TM_SC_HUNTAHOLIC_UPDATE_SCORE ) int kill_count; ///< 킬 수 int score; ///< 킬 수에 따른 점수 }; /// 헌터홀릭 로비에서 로비 입장 지점으로 귀환 struct TS_CS_HUNTAHOLIC_LEAVE_LOBBY : TS_MESSAGE { TS_CS_HUNTAHOLIC_LEAVE_LOBBY() _INIT( TM_CS_HUNTAHOLIC_LEAVE_LOBBY ) }; /// 헌터홀릭 로비에서 던전으로 입장, 사냥 시작 struct TS_SC_HUNTAHOLIC_BEGIN_HUNTING : TS_MESSAGE { TS_SC_HUNTAHOLIC_BEGIN_HUNTING() _INIT( TM_SC_HUNTAHOLIC_BEGIN_HUNTING ) AR_TIME begin_time; }; // sonador #2.1.2.11.5 /// 헌터홀릭 던전에서 최대 획득 가능 점수에 도달 struct TS_SC_HUNTAHOLIC_MAX_POINT_ACHIEVED : TS_MESSAGE { TS_SC_HUNTAHOLIC_MAX_POINT_ACHIEVED() _INIT( TM_SC_HUNTAHOLIC_MAX_POINT_ACHIEVED ) }; struct TS_CS_HUNTAHOLIC_BEGIN_HUNTING : TS_MESSAGE { TS_CS_HUNTAHOLIC_BEGIN_HUNTING() _INIT( TM_CS_HUNTAHOLIC_BEGIN_HUNTING ) }; struct TS_SC_HUNTAHOLIC_BEGIN_COUNTDOWN : TS_MESSAGE { TS_SC_HUNTAHOLIC_BEGIN_COUNTDOWN() _INIT( TM_SC_HUNTAHOLIC_BEGIN_COUNTDOWN ) }; // 인스턴스게임으로워프 struct TS_CS_INSTANCE_GAME_ENTER : TS_MESSAGE { enum INSTANCE_TYPE { HUNTAHOLIC_BEAR_ROAD = 0, RANKED_DEATHMATCH = 1, FREED_DEATHMATCH = 2, }; TS_CS_INSTANCE_GAME_ENTER() _INIT( TM_CS_INSTANCE_GAME_ENTER ) int instance_game_type; }; struct TS_CS_INSTANCE_GAME_EXIT : TS_MESSAGE { TS_CS_INSTANCE_GAME_EXIT() _INIT( TM_CS_INSTANCE_GAME_EXIT ) }; // 인스턴스게임의스코어요청 struct TS_CS_INSTANCE_GAME_SCORE_REQUEST : TS_MESSAGE { TS_CS_INSTANCE_GAME_SCORE_REQUEST() _INIT( TM_CS_INSTANCE_GAME_SCORE_REQUEST ) }; // 인스턴스게임의스코어전달 struct TS_SC_INSTANCE_GAME_SCORE_REQUEST : TS_MESSAGE { TS_SC_INSTANCE_GAME_SCORE_REQUEST() _INIT( TM_SC_INSTANCE_GAME_SCORE_REQUEST ) unsigned int holicpoint; unsigned int bearroad_ranking; unsigned int deathmatch_kill_count; unsigned int deathmatch_death_count; // 배틀 아레나 unsigned int battle_arena_point; unsigned int battle_arena_mvp_count; unsigned int battle_arena_record[ 3 /* _BATTLE_ARENA_TYPE */ ][ 2 /* win, lose */ ]; }; struct TS_CS_REPORT : TS_MESSAGE { TS_CS_REPORT() _INIT( TM_CS_REPORT ) unsigned short report_len; }; struct TS_SC_OPEN_URL : TS_MESSAGE { TS_SC_OPEN_URL() _INIT( TM_SC_OPEN_URL ) bool wait_for_event_scene; int width; int height; unsigned short url_len; }; struct TS_SC_URL_LIST : TS_MESSAGE { TS_SC_URL_LIST() _INIT( TM_SC_URL_LIST ) unsigned short url_list_len; // 이 뒤로 길이 url_list_len 의 문자열이 붙어감. }; struct TS_CS_VERSION : TS_MESSAGE { TS_CS_VERSION() _INIT( TM_CS_VERSION ) char szVersion[20]; }; struct TS_LOGIN : TS_MESSAGE { TS_LOGIN() _INIT( TM_CS_LOGIN ) // below is game conetents char szName[19]; unsigned char race; }; struct TS_LOGIN_RESULT : TS_MESSAGE { TS_LOGIN_RESULT() _INIT(TM_SC_LOGIN_RESULT) // 2010.05.20 - prodongi //char bIsAccepted; unsigned short result; AR_HANDLE handle; AR_UNIT x,y,z; unsigned char layer; float face_direction; int region_size; // below is game conetents int hp; int mp; int max_hp; int max_mp; int sex; int race; unsigned long skin_color; ItemBase::ItemCode faceid; ItemBase::ItemCode hairid; char szName[19]; int cell_size; int guild_id; int back_board; }; struct TS_TIMESYNC : TS_MESSAGE { TS_TIMESYNC() _INIT(TM_TIMESYNC) AR_TIME time; }; /// 특정 핸들을 요청하면, 강제 Enter Message가 날아 온다. struct TS_CS_QUERY : TS_MESSAGE { TS_CS_QUERY() _INIT(TM_CS_QUERY) AR_HANDLE handle; }; //----------------------------------------------------------------------------------------------------------------- // 아이템 정보 (기본) //----------------------------------------------------------------------------------------------------------------- struct TS_ITEM_BASE_INFO { #pragma region rnItemStruct //------------------------------------------------ // 각성 구조체 //------------------------------------------------ struct AwakenOption { DWORD nValue[ItemBase::MAX_AWAKENING_OPTION]; // 각성 타입 ( 힘, 지능, 민첩 등등.. ) int nData[ItemBase::MAX_AWAKENING_OPTION]; // 각성 값 AwakenOption() { ZeroMemory( nValue, sizeof( nValue ) ); ZeroMemory( nData , sizeof( nData ) ); } }; //------------------------------------------------ // 랜덤 옵션 //------------------------------------------------ typedef struct stRandomOption { int nType[ ItemBase::MAX_RANDOM_OPTION_NUMBER ]; // 랜덤 옵션 종류 ( 고정 증가 형, % 증가형 ) c_fixed10 stValue[ ItemBase::MAX_RANDOM_OPTION_NUMBER ]; // 랜덤 옵션 타입 ( 방어력, 마법 방어력 등등.. ) c_fixed10 stData[ ItemBase::MAX_RANDOM_OPTION_NUMBER ]; // 랜덤 옵션 값 stRandomOption() { ZeroMemory( nType, sizeof( nType ) ); ZeroMemory( stValue, sizeof( stValue ) ); ZeroMemory( stData, sizeof( stData ) ); } bool IsHaveData( void ) { if( NULL != nType[0] ) return true; else return false; } int GetAddJewelSocketCount( void ) { int nAddJewelCount( NULL ); if( false == IsHaveData() ) return nAddJewelCount; for ( int nRandomOptionIndex = 0; nRandomOptionIndex < ItemBase::MAX_RANDOM_OPTION_NUMBER; nRandomOptionIndex++ ) { const int nType( nType[nRandomOptionIndex] ); const double dbValue( stValue[nRandomOptionIndex] ); const double dbData( stData[nRandomOptionIndex] ); if( ITEM_EFFECT_PASSIVE::INC_SOCKET_COUNT_A != nType && ITEM_EFFECT_PASSIVE::INC_SOCKET_COUNT_B != nType ) continue; nAddJewelCount += dbValue; if( nAddJewelCount > ItemBase::MAX_SOCKET_NUMBER ) nAddJewelCount = ItemBase::MAX_SOCKET_NUMBER; } return nAddJewelCount; } }RANDOM_OPTION, *LPRANDOM_OPTION; #pragma endregion rnItemStruct AR_HANDLE handle; // Item Handle (Can be treated as unsigned int) ItemBase::ItemCode Code; // 아이템 코드 ItemInstance::ItemUID uid; // 고유 아이디 __int64 count; // 개수 int ethereal_durability; // 내구도 unsigned int endurance; // 내구도 unsigned char enhance; unsigned char level; // 레벨 short enhance_chance; // 강화 확률 add int Flag; // 상태 Flag int nAdditionalItemEffect; // Fraun Sky Accessories 7/12/2025 // If it's a creature card: // 0 is the creature UID // 1 is the base level // 2 is the growth level // 3 is the evolution level int socket[ ItemBase::MAX_SOCKET_NUMBER ]; AwakenOption awakenoption; RANDOM_OPTION random_option; int remain_time; // 초 단위임. 예) 1은 1초임 unsigned char elemental_effect_type; int elemental_effect_remain_time; int elemental_effect_attack_point; int elemental_effect_magic_point; ItemBase::ItemCode appearance_code; // 아이템 형상 변환 코드 int summon_id; // 크리쳐(소환수) 아이디 public: //------------------------------------------------ // 생성자 (기본) //------------------------------------------------ TS_ITEM_BASE_INFO() : count( 0 ) { ZeroMemory( socket, sizeof( socket ) ); } //------------------------------------------------ // 생성자 //------------------------------------------------ TS_ITEM_BASE_INFO( AR_HANDLE _handle, ItemBase::ItemCode _code, ItemInstance::ItemUID _uid, __int64 _count, int _endurance, int _enhance, int _level, int _Flag, int* pnSocket, int _remain_time, int _ethereal_durability, ItemBase::ItemCode _appearance_code, int _summon_id, int _additional_item_effect // Fraun Sky Accessories 7/12/2025 ) : handle( _handle ) , Code( _code ) , uid( _uid ) , count( _count ) , endurance( _endurance ) , enhance( _enhance ) , level( _level ) , Flag( _Flag ) , remain_time( _remain_time ) , ethereal_durability( ethereal_durability ) , appearance_code( _appearance_code ) , summon_id( _summon_id ) , nAdditionalItemEffect ( _additional_item_effect ) // Fraun Sky Accessories 7/12/2025 { ZeroMemory( socket, sizeof( socket ) ); if( pnSocket ) ::memcpy( socket, pnSocket, sizeof(socket) ); } }; struct TS_SC_OPEN_PAID_STORAGE : TS_MESSAGE { TS_SC_OPEN_PAID_STORAGE() _INIT(TM_SC_OPEN_PAID_STORAGE) }; struct TS_ITEM_INFO : TS_ITEM_BASE_INFO { short wear_position; // If - 1, the item is not equipped // If -2, the item is in storage // If -3, it's a cash shop item AR_HANDLE own_summon_handle; // 0 if not equipped to a summon int index; }; struct TS_ENTER : TS_MESSAGE { TS_ENTER() _INIT(TM_SC_ENTER) enum { PLAYER = 0, NPC = 1, STATIC_OBJECT = 2 }; enum //Game Obj Type { GAME_PLAYER = 0, GAME_NPC = 1, GAME_ITEM = 2, GAME_MOB = 3, GAME_SUMMON = 4, GAME_SKILL_PROP = 5, GAME_FIELD_PROP = 6, GAME_PET = 7, GAME_OBJTYPE_MAX, }; unsigned char type; AR_HANDLE handle; AR_UNIT x,y,z; unsigned char layer; // below is game conetents unsigned char ObjType; struct TS_ITEM_PICK_UP_ORDER { AR_TIME drop_time; AR_HANDLE hPlayer[ 3 ]; int nPartyID[ 3 ]; /* 먹자 방지 룰 drop_time부터 30초 이내: pickup_order.hPlayer[0] 가 0이 아닐 경우, hPlayer[0]인 사용자만 집을 수 있습니다. pickup_order.hPlayer[0] 가 0이고, pickup_order.nPartyID[0] > 0 일 경우, pickup_order.nPartyID[0]인 파티 소속원만 집을 수 있습니다. drop_time부터 40초 이내: pickup_order.hPlayer[1] 가 0이 아닐 경우, hPlayer[1]인 사용자만 집을 수 있습니다. pickup_order.hPlayer[1] 가 0이고, pickup_order.nPartyID[1] > 0 일 경우, pickup_order.nPartyID[1]인 파티 소속원만 집을 수 있습니다. drop_time부터 50초 이내: pickup_order.hPlayer[2] 가 0이 아닐 경우, hPlayer[2]인 사용자만 집을 수 있습니다. pickup_order.hPlayer[2] 가 0이고, pickup_order.nPartyID[2] > 0 일 경우, pickup_order.nPartyID[2]인 파티 소속원만 집을 수 있습니다. 50초 이후엔 아무나 집을 수 있습니다. */ }; struct ItemInfo { ENC_INT code; ///< code 가 0인것은 돈임. 액수는 cnt __int64 cnt; TS_ITEM_PICK_UP_ORDER pick_up_order; }; struct SkillInfo { AR_HANDLE caster; AR_TIME start_time; int skill_num; }; struct CreatureInfo { enum { FLAG_BATTLE_MODE = 1 << 0, FLAG_INVISIBLE = 1 << 1, }; unsigned status; float face_direction; ///< 보고있는 방향 int hp; int max_hp; int mp; int max_mp; int level; unsigned char race; unsigned long skin_color; bool is_first_enter; int energy; }; struct MonsterInfo : CreatureInfo { enum { FLAG_DEAD = 1 << 8, // 2010.07.15 - prodongi FLAG_DUNGEON_ORIGINAL_OWNER = 1 << 15, FLAG_DUNGEON_ORIGINAL_SIEGER = 1 << 17, }; // int monster_id; ENC_INT monster_id; bool is_tamed; ///< 테이밍 되었는지 여부 }; struct SummonInfo: CreatureInfo { AR_HANDLE master_handle; ENC_INT summon_code; char szName[19]; unsigned char enhance; }; struct PetInfo : CreatureInfo // sonador 10.2.1 팻 시스템 구현 { enum { FLAG_SHOVELING_SEARCH = 1 << 18, FLAG_SHOVELING_APPROACH = 1 << 19, FLAG_SHOVELING_DIG = 1 << 20, }; AR_HANDLE master_handle; ENC_INT pet_code; char szName[ 19 ]; }; struct NPCInfo: CreatureInfo { enum { FLAG_HAS_STARTABLE_QUEST = 1 << 8, FLAG_HAS_IN_PROGRESS_QUEST = 1 << 9, FLAG_HAS_FINISHABLE_QUEST = 1 << 10, }; ENC_INT npc_id; }; struct PlayerInfo: CreatureInfo { enum { FLAG_SITDOWN = 1 << 8, FLAG_BUY_BOOTH = 1 << 9, FLAG_SELL_BOOTH = 1 << 10, FLAG_PK_ON = 1 << 11, FLAG_BLOODY = 1 << 12, FLAG_DEMONIAC = 1 << 13, FLAG_GM = 1 << 14, FLAG_DUNGEON_ORIGINAL_OWNER = 1 << 15, FLAG_WALKING = 1 << 16, FLAG_DUNGEON_ORIGINAL_SIEGER = 1 << 17, // ?? FLAG_SHOVELING_SEARCH = 1 << 18, FLAG_SHOVELING_APPROACH = 1 << 19, FLAG_SHOVELING_DIG = 1 << 20, /* 1:1 대련 추가 * 2009-01-29 : hunee */ FLAG_COMPETING = 1 << 21, /// 2012.06.08 - prodongi FLAG_BATTLE_ARENA_TEAM_0 = 1 << 22, FLAG_BATTLE_ARENA_TEAM_1 = 1 << 23, }; unsigned char sex; ItemBase::ItemCode faceId; int faceTextureId; ItemBase::ItemCode hairId; int hairColorIndex; unsigned int hairColorRGB; // 2010.05.19 HIDE_EQUIP_INFO - prodongi unsigned int hideEquipFlag; char szName[19]; unsigned short job_id; AR_HANDLE ride_handle; int guild_id; int title_code; int back_board; }; struct FieldPropInfo { int prop_id; float fZOffset; float fRotateX, fRotateY, fRotateZ; float fScaleX, fScaleY, fScaleZ; bool bLockHeight; float fLockHeight; }; }; struct TS_SC_STATUS_CHANGE : TS_MESSAGE { TS_SC_STATUS_CHANGE() _INIT(TM_SC_STATUS_CHANGE) AR_HANDLE handle; unsigned status; }; struct TS_SC_STATE : TS_MESSAGE { TS_SC_STATE() _INIT( TM_SC_STATE ) AR_HANDLE handle; ///< 대상 크리쳐 unsigned short state_handle; ///< 상태이상 핸들 unsigned int state_code; ///< 상태이상 종류 unsigned short state_level; ///< 상태이상의 레벨 (0이면 풀리는 메세지임) AR_TIME end_time; ///< 끝나는 시간 (0이면 영원히) AR_TIME start_time; ///< 시작 시간 int state_value; ///< 지속효과 관련 추가값 char state_string_value[32]; }; struct TS_SC_PROPERTY : TS_MESSAGE { TS_SC_PROPERTY() _INIT(TM_SC_PROPERTY); AR_HANDLE handle; bool is_number; ///< 이게 참이라면 value 에 숫자가 들어감. 거짓이라면 문자열 값인데 메세지 끝이 '\0' 으로 끝나는 문자열이 들어감. char name[16]; __int64 value; ///< [sonador][3.4.1]소지금 한도 증가 관련 서버 메시지 변경 }; struct TS_CS_SET_PROPERTY : TS_MESSAGE { TS_CS_SET_PROPERTY() _INIT(TM_CS_SET_PROPERTY); char name[16]; }; /* struct TS_SC_HP : TS_MESSAGE { TS_SC_HP() _INIT(TM_SC_HP); AR_HANDLE handle; int hp; unsigned char hp_percentage; }; struct TS_SC_MP : TS_MESSAGE { TS_SC_MP() _INIT(TM_SC_MP); AR_HANDLE handle; short mp; }; */ struct TS_SC_HPMP : TS_MESSAGE { TS_SC_HPMP() _INIT(TM_SC_HPMP); AR_HANDLE handle; int add_hp; int hp; int max_hp; int add_mp; int mp; int max_mp; bool need_to_display; }; struct TS_SC_SP : TS_MESSAGE { TS_SC_SP() _INIT(TM_SC_SP); AR_HANDLE handle; short sp; short max_sp; }; struct TS_SC_REGEN_HPMP : TS_MESSAGE { TS_SC_REGEN_HPMP() _INIT(TM_SC_REGEN_HPMP); AR_HANDLE handle; int hp_regen; int mp_regen; int hp; int mp; }; struct TS_CS_GET_REGION_INFO : TS_MESSAGE { TS_CS_GET_REGION_INFO() _INIT( TM_CS_GET_REGION_INFO ) AR_UNIT x; AR_UNIT y; }; struct TS_CS_UPDATE : TS_MESSAGE { TS_CS_UPDATE() _INIT(TM_CS_UPDATE); AR_HANDLE handle; int ar_time; int rtc; enum { POINT_UPDATE = 0, }; }; struct TS_SC_TAMING_INFO : TS_MESSAGE { TS_SC_TAMING_INFO() _INIT(TM_SC_TAMING_INFO); enum { START = 0, ///< tamer 가 target 에게 테이밍 스킬을 걸었음 CLEAR = 1, ///< 테이밍이 초기화됨 (tamer_handle 은 0) SUCCESS = 2, ///< target 이 죽어서 tamer 에게 테이밍됨. FAILED = 3, ///< target 이 죽었지만 테이밍은 실패! }; unsigned char mode; AR_HANDLE tamer_handle; AR_HANDLE target_handle; }; struct TS_SC_MOUNT_SUMMON : TS_MESSAGE { TS_SC_MOUNT_SUMMON() _INIT(TM_SC_MOUNT_SUMMON) AR_HANDLE handle; AR_HANDLE summon_handle; AR_UNIT x, y; bool success; }; struct TS_SC_UNMOUNT_SUMMON : TS_MESSAGE { TS_SC_UNMOUNT_SUMMON() _INIT(TM_SC_UNMOUNT_SUMMON) AR_HANDLE handle; AR_HANDLE summon_handle; enum { NORMAL = 0, FALL = 1, UNSUMMON = 2, }; char flag; }; struct TS_SC_SHOW_SUMMON_NAME_CHANGE : TS_MESSAGE { TS_SC_SHOW_SUMMON_NAME_CHANGE() _INIT(TM_SC_SHOW_SUMMON_NAME_CHANGE) AR_HANDLE handle; }; struct TS_CS_CHANGE_SUMMON_NAME : TS_MESSAGE { TS_CS_CHANGE_SUMMON_NAME() _INIT(TM_CS_CHANGE_SUMMON_NAME) char szName[19]; }; struct TS_CS_GET_SUMMON_SETUP_INFO : TS_MESSAGE { TS_CS_GET_SUMMON_SETUP_INFO() _INIT(TM_CS_GET_SUMMON_SETUP_INFO) bool show_dialog; }; // sonador 10.2.1 팻 시스템 구현 struct TS_SC_UNSUMMON_PET : TS_MESSAGE { TS_SC_UNSUMMON_PET() _INIT( TM_SC_UNSUMMON_PET ) AR_HANDLE handle; }; struct TS_SC_ADD_PET_INFO : TS_MESSAGE { TS_SC_ADD_PET_INFO() _INIT( TM_SC_ADD_PET_INFO ) AR_HANDLE cage_handle; AR_HANDLE pet_handle; char name[19]; int code; }; struct TS_SC_REMOVE_PET_INFO : TS_MESSAGE { TS_SC_REMOVE_PET_INFO() _INIT( TM_SC_REMOVE_PET_INFO ) AR_HANDLE handle; }; struct TS_SC_SHOW_SET_PET_NAME : TS_MESSAGE { TS_SC_SHOW_SET_PET_NAME() _INIT( TM_SC_SHOW_SET_PET_NAME ) AR_HANDLE handle; }; struct TS_CS_SET_PET_NAME : TS_MESSAGE { TS_CS_SET_PET_NAME() _INIT( TM_CS_SET_PET_NAME ) AR_HANDLE handle; char name[19]; }; struct TS_WEAR_INFO : TS_MESSAGE { TS_WEAR_INFO() _INIT(TM_SC_WEAR_INFO) AR_HANDLE handle; /*ItemBase::ItemCode itemCode[ItemBase::MAX_ITEM_WEAR]; int itemEnhance[ItemBase::MAX_ITEM_WEAR]; int itemLevel[ItemBase::MAX_ITEM_WEAR]; unsigned char elemental_effect_type[ItemBase::MAX_ITEM_WEAR];*/ ItemBase::ItemCode itemCode[ItemBase::MAX_ITEM_SPARE_WEAR]; int itemEnhance[ItemBase::MAX_ITEM_SPARE_WEAR]; int itemLevel[ItemBase::MAX_ITEM_SPARE_WEAR]; unsigned char elemental_effect_type[ItemBase::MAX_ITEM_SPARE_WEAR]; ItemBase::ItemCode appearanceItemCode[ItemBase::MAX_ITEM_SPARE_WEAR]; //2012 .7. 24 - marine 형상변환 }; struct TS_SC_ITEM_WEAR_INFO : TS_MESSAGE { TS_SC_ITEM_WEAR_INFO() _INIT(TM_SC_ITEM_WEAR_INFO) AR_HANDLE item_handle; short wear_position; ///< -1이면 장착 안된 아이템, 소환수의 경우는 순서대로 +1000 * n (n은 슬롯 번호) AR_HANDLE target_handle; int enhance; unsigned char elemental_effect_type; ItemBase::ItemCode appearance_code; // 2012. 7. 26 - marine }; struct TS_LEAVE : TS_MESSAGE { TS_LEAVE() _INIT(TM_SC_LEAVE) AR_HANDLE handle; }; struct TS_MOVE_REQUEST : TS_MESSAGE { TS_MOVE_REQUEST() _INIT(TM_CS_MOVE_REQUEST) AR_HANDLE handle; // AR_UNIT tx,ty; AR_UNIT x,y; AR_TIME cur_time; // unsigned char tlayer; bool speed_sync; unsigned short count; struct MOVE_INFO { AR_UNIT tx,ty; }; // 이뒤에MOVE_INFO가COUNT만큼붙어서온다. }; struct TS_MOVE : TS_MESSAGE { TS_MOVE() _INIT(TM_SC_MOVE) AR_TIME start_time; AR_HANDLE handle; //AR_UNIT tx, ty, tz; unsigned char tlayer; unsigned char speed; unsigned short count; struct MOVE_INFO { AR_UNIT tx,ty; }; }; struct TS_REGION_UPDATE : TS_MESSAGE { TS_REGION_UPDATE() _INIT(TM_CS_REGION_UPDATE) AR_TIME update_time; AR_UNIT x, y, z; bool bIsStopMessage; }; struct TS_SC_WARP : TS_MESSAGE { TS_SC_WARP() _INIT(TM_SC_WARP) AR_UNIT x, y, z; unsigned char layer; }; struct TS_REGION_ACK : TS_MESSAGE { TS_REGION_ACK() _INIT(TM_SC_REGION_ACK) unsigned rx, ry; }; struct TS_MOVE_ACK : TS_MESSAGE { TS_MOVE_ACK() _INIT(TM_SC_MOVE_ACK) AR_TIME time; unsigned char speed; }; struct TS_SET_TIME : TS_MESSAGE { TS_SET_TIME() _INIT(TM_SC_SET_TIME) int gap; }; struct TS_ATTACK_REQUEST : TS_MESSAGE { TS_ATTACK_REQUEST() _INIT(TM_CS_ATTACK_REQUEST) AR_HANDLE handle; AR_HANDLE target_handle; ///< NULL 이면 공격 중지 메세지 }; struct TS_ATTACK_EVENT : TS_MESSAGE { TS_ATTACK_EVENT() _INIT(TM_SC_ATTACK_EVENT) AR_HANDLE attacker_handle; AR_HANDLE target_handle; enum { FLAG_CRITICAL = ( 1 << 3 ), FLAG_MISS = ( 1 << 2 ), FLAG_BLOCK = ( 1 << 1 ), FLAG_PERFECT_BLOCK = ( 1 << 0 ), }; unsigned short attack_speed; ///< ms unsigned short attack_delay; ///< ms enum { ATTACK_END = 1, ATTACK_AIMING = 2, ATTACK_ATTACK = 3, ATTACK_CANCEL = 4, }; char attack_action; enum { ATTACK_FLAG_BOW = ( 1 << 0 ), ATTACK_FLAG_CROSS_BOW = ( 1 << 1 ), ATTACK_FLAG_DOUBLE_WEAPON = ( 1 << 2 ), ATTACK_FLAG_DOUBLE_ATTACK = ( 1 << 3 ), }; char attack_flag; unsigned char count; // double weapon의 경우, right, left 순서 // double weapon, double attack의 경우, right, left, right, left 순서 }; struct TS_SC_CANT_ATTACK : TS_MESSAGE { TS_SC_CANT_ATTACK() _INIT(TM_SC_CANT_ATTACK) AR_HANDLE attacker_handle; AR_HANDLE target_handle; // AR_UNIT tx,ty; // AR_UNIT attack_range; int reason; }; //이도류 공격 struct TS_DOUBLE_WEAPON_ATTACK_EVENT : TS_MESSAGE { TS_DOUBLE_WEAPON_ATTACK_EVENT() _INIT(TM_SC_DOUBLE_WEAPON_ATTACK_EVENT) AR_HANDLE attacker_handle; AR_HANDLE target_handle; short right_hand_damage; short left_hand_damage; unsigned short attack_speed; ///< ms unsigned char hp_percentage; ///< HP % enum { FLAG_LEFT_HAND_CRITICAL = ( 1 << 8 ), FLAG_LEFT_HAND_MISS = ( 1 << 7 ), FLAG_LEFT_HAND_BLOCK = ( 1 << 6 ), FLAG_LEFT_HAND_PERFECT_BLOCK = ( 1 << 5 ), FLAG_RIGHT_HAND_CRITICAL = ( 1 << 4 ), FLAG_RIGHT_HAND_MISS = ( 1 << 3 ), FLAG_RIGHT_HAND_BLOCK = ( 1 << 2 ), FLAG_RIGHT_HAND_PERFECT_BLOCK = ( 1 << 1 ), }; unsigned short flag; unsigned char right_hand_elemental_damage[ CreatureElemental::COUNT ]; ///< 추가데미지 unsigned char left_hand_elemental_damage[ CreatureElemental::COUNT ]; ///< 추가데미지 }; struct TS_CS_BIND_SKILLCARD : TS_MESSAGE { TS_CS_BIND_SKILLCARD() _INIT(TM_CS_BIND_SKILLCARD) AR_HANDLE item_handle; AR_HANDLE target_handle; }; struct TS_CS_UNBIND_SKILLCARD : TS_MESSAGE { TS_CS_UNBIND_SKILLCARD() _INIT(TM_CS_UNBIND_SKILLCARD) AR_HANDLE item_handle; AR_HANDLE target_handle; }; struct TS_SC_SKILLCARD_INFO : TS_MESSAGE { TS_SC_SKILLCARD_INFO() _INIT(TM_SC_SKILLCARD_INFO) AR_HANDLE item_handle; AR_HANDLE target_handle; ///< 0 이면 장착해지 }; struct TS_CS_PUTON_ITEM : TS_MESSAGE { TS_CS_PUTON_ITEM() _INIT(TM_CS_PUTON_ITEM) unsigned char position; AR_HANDLE item_handle; AR_HANDLE target_handle; }; struct TS_CS_PUTON_ITEM_SET : TS_MESSAGE { TS_CS_PUTON_ITEM_SET() _INIT(TM_CS_PUTON_ITEM_SET) AR_HANDLE handle[ItemBase::MAX_ITEM_WEAR]; }; struct TS_CS_PUTOFF_ITEM : TS_MESSAGE { TS_CS_PUTOFF_ITEM() _INIT(TM_CS_PUTOFF_ITEM) unsigned char position; AR_HANDLE target_handle; }; struct TS_CS_DROP_ITEM : TS_MESSAGE { TS_CS_DROP_ITEM() _INIT(TM_CS_DROP_ITEM) AR_HANDLE item_handle; int count; }; struct TS_CS_TAKE_ITEM : TS_MESSAGE { TS_CS_TAKE_ITEM() _INIT(TM_CS_TAKE_ITEM) AR_HANDLE taker_handle; // sonador #2.1.2.4.3 팻 조작 UI 연동 AR_HANDLE item_handle; }; struct TS_SC_DROP_RESULT : TS_MESSAGE { TS_SC_DROP_RESULT() _INIT(TM_SC_DROP_RESULT) AR_HANDLE item_handle; bool isAccepted; }; //struct TS_CS_ERASE_ITEM : TS_MESSAGE //{ // TS_CS_ERASE_ITEM() _INIT(TM_CS_ERASE_ITEM) // // AR_HANDLE item_handle; //}; // 아이템파괴 요청. struct TS_CS_ERASE_ITEM : TS_MESSAGE { struct EraseItemInfo { AR_HANDLE item_handle; __int64 count; char is_in_storage; }; TS_CS_ERASE_ITEM() _INIT(TM_CS_ERASE_ITEM) unsigned char item_count; }; // 아이템파괴 응답. struct TS_SC_ERASE_ITEM : TS_MESSAGE { struct EraseItemInfo { AR_HANDLE item_handle; // 0 이면 파괴 실패. __int64 count; }; TS_SC_ERASE_ITEM() _INIT( TM_SC_ERASE_ITEM ) unsigned char item_count; }; struct TS_SC_INVENTORY : TS_MESSAGE { TS_SC_INVENTORY() _INIT(TM_SC_INVENTORY); unsigned short count; // 이하 TS_ITEM_INFO 가 count 만큼 붙게됨 }; struct TS_SC_TAKE_ITEM_RESULT : TS_MESSAGE { TS_SC_TAKE_ITEM_RESULT() _INIT(TM_SC_TAKE_ITEM_RESULT) AR_HANDLE item_handle; AR_HANDLE item_taker; }; struct TS_SC_OPEN_STORAGE : TS_MESSAGE { TS_SC_OPEN_STORAGE() _INIT(TM_SC_OPEN_STORAGE); int maxStorageItemCount; // 2011. 9. 15 - marine 창고 슬롯최대치 메세지 추가 }; struct TS_CS_STORAGE : TS_MESSAGE { TS_CS_STORAGE() _INIT(TM_CS_STORAGE); enum { INVENTORY_TO_STORAGE = 0, STORAGE_TO_INVENTORY = 1, GOLD_INVENTORY_TO_STORAGE = 2, GOLD_STORAGE_TO_INVENTORY = 3, CLOSE_STORAGE = 4, }; AR_HANDLE item_handle; unsigned char mode; __int64 count; ///< [sonador][3.4.1]소지금 한도 증가 관련 서버 메시지 변경 }; /// sonador 3.10.2 PC 방 혜택 관련 라크 획득 시스템 메시지 변경 struct TS_SC_GET_CHAOS : TS_MESSAGE { TS_SC_GET_CHAOS() _INIT(TM_SC_GET_CHAOS); AR_HANDLE hPlayer; AR_HANDLE hCorpse; int nChaos; enum CHAOS_BONUS_TYPE { CHAOS_BONUS_NONE = 0, CHAOS_BONUS_PCBANG = 1, CHAOS_BONUS_PREMIUM_PCBANG = 2, }; char nBonusType; unsigned char nBonusPercent; int nBonus; }; struct TS_CS_PUTON_CARD : TS_MESSAGE { TS_CS_PUTON_CARD() _INIT( TM_CS_PUTON_CARD ) unsigned char position; AR_HANDLE item_handle; }; struct TS_CS_PUTOFF_CARD : TS_MESSAGE { TS_CS_PUTOFF_CARD() _INIT( TM_CS_PUTOFF_CARD ) unsigned char position; }; struct TS_SC_BELT_SLOT_INFO : TS_MESSAGE { TS_SC_BELT_SLOT_INFO() _INIT( TM_SC_BELT_SLOT_INFO ) AR_HANDLE handle[8]; }; struct TS_SC_ITEM_COOL_TIME : TS_MESSAGE { TS_SC_ITEM_COOL_TIME() _INIT(TM_SC_ITEM_COOL_TIME); enum { // 쿨타임 그룹이 최대 20개에서 40개로 확장되었습니다 // 2009-06-12 : hunee MAX_ITEM_COOLTIME_GROUP = 40, }; AR_TIME cool_time[MAX_ITEM_COOLTIME_GROUP]; }; struct TS_CS_MIX : TS_MESSAGE { TS_CS_MIX() _INIT(TM_CS_MIX); struct MIX_INFO { AR_HANDLE handle; unsigned short count; }; MIX_INFO main_item; unsigned short count; // 이하 MIX_INFO 타입이 count 만큼 붙게 됨. }; enum MIX_TYPE { MIX_TYPE_NONE, MIX_TYPE_AWAKEN, // 각성 }; struct TS_SC_MIX_RESULT : TS_MESSAGE { TS_SC_MIX_RESULT() _INIT( TM_SC_MIX_RESULT ) // imParkth - MIX_RESULT : Type은 정해야 함 enum MIX_TYPE { MIX_TYPE_NONE, MIX_TYPE_AWAKEN, // 각성 }; unsigned count; // 이하 AR_HANDLE 이 count 만큼 붙게 됨. count 가 0 이면 조합 실패. // imParkth - TS_SC_MIX_RESULT Type 추가 unsigned char type; }; struct TS_SC_CHAT_LOCAL : TS_MESSAGE { TS_SC_CHAT_LOCAL() _INIT(TM_SC_CHAT_LOCAL); AR_HANDLE handle; unsigned char len; unsigned char type; }; struct TS_SC_CHAT : TS_MESSAGE { TS_SC_CHAT() _INIT(TM_SC_CHAT); char szSender[21]; unsigned short len; unsigned char type; }; struct TS_CS_RETURN_LOBBY : TS_MESSAGE { TS_CS_RETURN_LOBBY() _INIT(TM_CS_RETURN_LOBBY) }; struct TS_CS_CHAT_REQUEST : TS_MESSAGE { TS_CS_CHAT_REQUEST() _INIT(TM_CS_CHAT_REQUEST); char szTarget[21]; unsigned char request_id; unsigned char len; unsigned char type; }; struct TS_SC_CHAT_RESULT : TS_MESSAGE { TS_SC_CHAT_RESULT() _INIT(TM_SC_CHAT_RESULT); enum CHAT_RESULT { RESULT_DECREASE_HPMP = 0, RESULT_COOLTIME = 1, RESULT_NEED_MORE_HPMP = 2, RESULT_LEVEL_RESTRICT = 3, }; unsigned char type; unsigned char percentage; int result; int reserved; }; struct TS_SC_CHANGE_NAME : TS_MESSAGE { TS_SC_CHANGE_NAME() _INIT(TM_SC_CHANGE_NAME); AR_HANDLE handle; char name[19]; }; struct TS_CS_CHANGE_ALIAS : TS_MESSAGE { TS_CS_CHANGE_ALIAS() _INIT( TM_CS_CHANGE_ALIAS ) char alias[ 19 ]; }; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// //HackShield /// HShield.h 에서 버퍼 크기 비교 할것, 틀리면 비정상 에러 발생 됨. struct TS_SC_ANTI_HACK : TS_MESSAGE { TS_SC_ANTI_HACK() _INIT( TM_SC_ANTI_HACK ) #ifdef _HACK_SHIELD_ AHNHS_TRANS_BUFFER AhnHSReqBuffer; #endif }; struct TS_CS_ANTI_HACK : TS_MESSAGE { TS_CS_ANTI_HACK() _INIT( TM_CS_ANTI_HACK ) #ifdef _HACK_SHIELD_ AHNHS_TRANS_BUFFER AhnHSAckBuffer; #endif }; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// struct TS_SC_GAME_GUARD_AUTH_QUERY : TS_MESSAGE { TS_SC_GAME_GUARD_AUTH_QUERY() _INIT( TM_SC_GAME_GUARD_AUTH_QUERY ) unsigned int auth_data_size; // 뒤에 auth_data_size 만큼 데이터가 추가됨 }; struct TS_CS_GAME_GUARD_AUTH_ANSWER : TS_MESSAGE { TS_CS_GAME_GUARD_AUTH_ANSWER() _INIT( TM_CS_GAME_GUARD_AUTH_ANSWER ) unsigned int auth_data_size; // 뒤에 auth_data_size 만큼 데이터가 추가됨 }; /// sonador 7.4.3 해킹 툴 감지후 종료 프로세스 구현 struct TS_CS_CHECK_ILLEGAL_USER : TS_MESSAGE { TS_CS_CHECK_ILLEGAL_USER() _INIT( TM_CS_CHECK_ILLEGAL_USER ) unsigned long log_code; }; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// struct TS_SC_STAT_INFO : TS_MESSAGE { TS_SC_STAT_INFO() _INIT(TM_SC_STAT_INFO) AR_HANDLE handle; CreatureStat stat; CreatureAttribute attribute; enum { TOTAL = 0, ///< 기본 스탯 BY_ITEM = 1, ///< 아이템으로 증가된 값 }; unsigned char type; }; struct TS_SC_REGEN_INFO : TS_MESSAGE { TS_SC_REGEN_INFO() _INIT(TM_SC_REGEN_INFO) AR_HANDLE handle; short hp_regen_percentage; int hp_regen_point; short mp_regen_percentage; int mp_regen_point; }; struct TS_CS_TARGETING : TS_MESSAGE { TS_CS_TARGETING() _INIT(TM_CS_TARGETING) AR_HANDLE target; }; struct TS_CS_RESURRECTION : TS_MESSAGE { TS_CS_RESURRECTION() _INIT(TM_CS_RESURRECTION) AR_HANDLE handle; // bool use_state; // bool use_potion; // 부활과 관련하여 대련장에서 사망 후에 부활할 경우 사망 지점에서 10%의 체력만 회복하고 // 부활하는 부분을 위해 부활 관련 패킷이 아래와 같이 수정되었습니다. // 2009-01-29 : hunee enum { RESURRECT_TYPE_NORMAL = 0, ///< 일반 부활 RESURRECT_TYPE_BY_STATE = 1, ///< 버프 부활 RESURRECT_TYPE_BY_POTION = 2, ///< 대모 요정의 병 부활 RESURRECT_TYPE_BY_COMPETE = 3, ///< 대련 사망 패배 후 부활 RESURRECT_TYPE_BY_DEATHMATCH = 4, // 데스매치에서사망후부활 }; char type; }; struct TS_SC_TARGET : TS_MESSAGE { TS_SC_TARGET() _INIT(TM_SC_TARGET) AR_HANDLE target; }; /// 기공 struct TS_SC_ENERGY : TS_MESSAGE { TS_SC_ENERGY() _INIT(TM_SC_ENERGY) AR_HANDLE handle; short energy; }; struct TS_CS_SKILL : TS_MESSAGE { TS_CS_SKILL() _INIT(TM_CS_SKILL) int skill_id; AR_HANDLE caster; AR_HANDLE target; AR_UNIT x,y,z; unsigned char layer; /* enum { CASTING = 1, CANCEL = 2, }; char type; */ char skill_level; }; struct TS_CS_CANCEL_ACTION : TS_MESSAGE { TS_CS_CANCEL_ACTION() _INIT(TM_CS_CANCEL_ACTION) AR_HANDLE handle; }; //struct TS_SC_SKILL_CASTING_TIME : TS_MESSAGE //{ // TS_SC_SKILL_CASTING_TIME() _INIT(TM_SC_SKILL_CASTING_TIME) // // AR_HANDLE caster; // AR_TIME tm; //}; struct TS_SC_STATE_RESULT : TS_MESSAGE { TS_SC_STATE_RESULT() _INIT(TM_SC_STATE_RESULT) AR_HANDLE caster_handle; AR_HANDLE target_handle; int code; unsigned short level; /// result_type 종류 enum { STATE_DAMAGE_HP = 1, STATE_DAMAGE_MP = 2, STATE_DAMAGE_SP = 3, STATE_HEAL_HP = 4, STATE_HEAL_MP = 5, STATE_HEAL_SP = 6, }; unsigned short result_type; ///< 위의 enum 값 중 하나 int value; ///< enum에 해당하는 종류의 수치 int target_value; ///< 처리 후 target의 해당 수치 bool final; int total_amount; /* AR_HANDLE caster_handle; AR_HANDLE target_handle; int target_hp; int code; unsigned short level; int damage; bool final; int total_damage;*/ }; struct TS_SC_AURA : TS_MESSAGE { TS_SC_AURA() _INIT(TM_SC_AURA) AR_HANDLE caster; int skill_id; bool status; }; struct TS_SC_SKILL : TS_MESSAGE { TS_SC_SKILL() _INIT(TM_SC_SKILL) int skill_id; char skill_level; AR_HANDLE caster; AR_HANDLE target; AR_UNIT x,y,z; unsigned char layer; char type; int hp_cost; int mp_cost; int caster_hp; int caster_mp; enum { FIRE = 0, CASTING = 1, CASTING_UPDATE = 2, CANCEL = 3, REGION_FIRE = 4, ///< 지역 스킬의 fire COMPLETE = 5, }; struct CancelType { // 내용 없음 }; struct CompleteType { // 내용 없음 }; /// Casting 이거나 Casting_update일 경우 날아감. struct CastType { AR_TIME tm; // 캐스팅 타임 unsigned short nErrorCode; // 성공 여부 ( 0이면 성공 ) }; /// Region Fire일 경우에도 얘가 날아감. struct FireType { bool bMultiple; // true 실시간 연타 AR_UNIT range; // 스킬 효과 범위 unsigned char target_count; unsigned char fire_count; unsigned short count; }; union { CancelType cancel; CompleteType complete; CastType cast; FireType fire; }; // Fire나 Region Fire일 경우 추가로 뒤에 SkillResult 가 count 만큼 따라간다 }; struct TS_SC_GOLD_UPDATE : TS_MESSAGE { TS_SC_GOLD_UPDATE() _INIT(TM_SC_GOLD_UPDATE) __int64 gold; // [sonador][3.4.1]소지금 한도 증가 관련 서버 메시지 변경 int chaos; }; struct TS_SC_EXP_UPDATE : TS_MESSAGE { TS_SC_EXP_UPDATE() _INIT(TM_SC_EXP_UPDATE) AR_HANDLE handle; __int64 exp; __int64 jp; /// 2011.04.29 int -> __int64 - prodongi }; struct TS_SC_BONUS_EXP_JP : TS_MESSAGE { TS_SC_BONUS_EXP_JP() _INIT(TM_SC_BONUS_EXP_JP) AR_HANDLE handle; unsigned short count; /// 이뒤로count개만큼의BONUS_INFO가붙어서감 enum BONUS_TYPE { BONUS_PCBANG = 0, BONUS_STAMINA = 1, BONUS_PREMIUM_PCBANG = 2, BONUS_SUMMON_STAMINA = 3, ///< 오곡크래커 업데이트 2009.04.14 sfreer BOUNUS_SUPER_SAVE = 4, // 성장의물약(구슈퍼세이버) 2010.10.01 - prodongi MAX_BONUS_TYPE ///< 마지막보너스인덱스보다1 크게되므로개수로쓰면됨 }; struct BONUS_INFO { int type; ///< 보너스 종류 int rate; ///< 보너스 비율(메시지 출력용) // sonador 3.10.1 PC 방 혜택 관련 시스템 메시지 변경 //int exp; // 보너스 경험치 __int64 exp; ///< 오곡크래커 업데이트 2009.04.14 sfreer __int64 jp; ///< 보너스 JP }; }; struct TS_SC_LEVEL_UPDATE : TS_MESSAGE { TS_SC_LEVEL_UPDATE() _INIT(TM_SC_LEVEL_UPDATE) AR_HANDLE handle; int level; int job_level; }; // { [sonador][3.1.2]경매장 구현 // 경매 데이터 struct TS_AUCTION_INFO { enum AUCTION_DURATION_TYPE { DURATION_SHORTTERM = 1, ///< 마감 시한: 단기 DURATION_MIDTERM = 2, ///< 마감 시한: 중기 DURATION_LONGTERM = 3 ///< 마감 시한: 장기 }; int auction_uid; ///< 경매 번호 TS_ITEM_BASE_INFO item_info; ///< 아이템 정보 unsigned char duration_type; ///< 마감 시한 타입(AUCTION_DURATION_TYPE 값이 들어감) __int64 bidded_price; ///< 현재 입찰가 __int64 instant_purchase_price; ///< 즉시 구매가 }; // 경매 물품 검색 요청 struct TS_CS_AUCTION_SEARCH : TS_MESSAGE { TS_CS_AUCTION_SEARCH() _INIT( TM_CS_AUCTION_SEARCH ) int category_id; ///< 검색 카테고리 - 대분류 // 3.1.5 검색 카테고리 수정.sonador int sub_category_id; ///< 검색 카테고리 - 중분류 // 3.1.5 검색 카테고리 수정.sonador char keyword[31]; ///< 검색 키워드(없으면 빈 문자열이면 됨) int page_num; ///< 요청 페이지 번호 bool is_equipable; // 착용가능한장비검색여부 // 2010.08.27 - prodongi }; /// 경매 물품 검색 결과 struct TS_SC_AUCTION_SEARCH : TS_MESSAGE { TS_SC_AUCTION_SEARCH() _INIT( TM_SC_AUCTION_SEARCH ) struct SEARCHED_AUCTION_INFO : TS_AUCTION_INFO { char seller_name[31]; char flag; enum SEARCHED_AUCTION_INFO_FLAG { FLAG_IS_HIGHEST_BIDDER = 1 << 0, ///< 자신이 최고 입찰자인지 여부 FLAG_NO_OTHER_BIDDER = 1 << 1 ///< 자신이 최초 입찰자인지 여부(현재 최고 입찰가로 입찰이 가능 - 5% 높은 가격 룰 제외됨) }; }; int page_num; ///< 현재 페이지 번호 int total_page_count; ///< 전체 페이지 수 int auction_info_count; ///< 현재 페이지에 해당하는 경매 데이터 수 SEARCHED_AUCTION_INFO auction_info[ GameRule::AUCTION_INFO_COUNT_PER_PAGE ]; ///< 현재 페이지에 해당하는 경매 데이터 }; /// 자신이 등록한 경매 물품 목록 요청 struct TS_CS_AUCTION_SELLING_LIST : TS_MESSAGE { TS_CS_AUCTION_SELLING_LIST() _INIT( TM_CS_AUCTION_SELLING_LIST ) int page_num; ///< 요청 페이지 번호 }; /// 자신이 등록한 경매 물품 목록 결과 struct TS_SC_AUCTION_SELLING_LIST : TS_MESSAGE { TS_SC_AUCTION_SELLING_LIST() _INIT( TM_SC_AUCTION_SELLING_LIST ) struct REGISTERED_AUCTION_INFO : TS_AUCTION_INFO { enum REGISTERED_AUCTION_STATUS { STATUS_NO_BIDDER = 1, ///< 상태: 입찰자 없음 STATUS_BID_CALLING = 2 ///< 상태: 입찰 진행중 }; unsigned char status; ///< REGISTERED_AUCTION_STATUS 값이 들어감 }; int page_num; ///< 현재 페이지 번호 int total_page_count; ///< 전체 페이지 수 int auction_info_count; ///< 현재 페이지에 해당하는 경매 데이터 수 REGISTERED_AUCTION_INFO auction_info[ GameRule::AUCTION_INFO_COUNT_PER_PAGE ]; ///< 현재 페이지에 해당하는 경매 데이터 }; /// 자신이 입찰한 경매 목록 요청 struct TS_CS_AUCTION_BIDDED_LIST : TS_MESSAGE { TS_CS_AUCTION_BIDDED_LIST() _INIT( TM_CS_AUCTION_BIDDED_LIST ) int page_num; ///< 요청 페이지 번호 }; /// 자신이 입찰한 경매 목록 결과 struct TS_SC_AUCTION_BIDDED_LIST : TS_MESSAGE { TS_SC_AUCTION_BIDDED_LIST() _INIT( TM_SC_AUCTION_BIDDED_LIST ) struct BIDDED_AUCTION_LIST : TS_AUCTION_INFO { enum BIDDED_AUCTION_STATUS { STATUS_MINE = 1, ///< 입찰 현황: 본인 입찰 STATUS_OTHERS = 2 ///< 입찰 현황: 타인 입찰 }; unsigned char status; ///< BIDDED_AUCTION_STATUS 값이 들어감 }; int page_num; ///< 현재 페이지 번호 int total_page_count; ///< 전체 페이지 수 int auction_info_count; ///< 현재 페이지에 해당하는 경매 데이터 수 BIDDED_AUCTION_LIST auction_info[ GameRule::AUCTION_INFO_COUNT_PER_PAGE ]; ///< 현재 페이지에 해당하는 경매 데이터 }; /// 경매 입찰 요청 struct TS_CS_AUCTION_BID : TS_MESSAGE { TS_CS_AUCTION_BID() _INIT( TM_CS_AUCTION_BID ) int auction_uid; ///< 입찰 대상 경매 번호 __int64 bidding_price; ///< 입찰 요청 가격 }; /// 경매 물품 즉시구매 요청(결과는 TS_SC_RESULT로 보내고 페이지 갱신은 클라에서 요청 따로 보냄) struct TS_CS_AUCTION_INSTANT_PURCHASE : TS_MESSAGE { TS_CS_AUCTION_INSTANT_PURCHASE() _INIT( TM_CS_AUCTION_INSTANT_PURCHASE ) int auction_uid; ///< 즉시 구매 대상 경매 번호 }; /// 경매 물품 등록 요청(결과는 TS_SC_RESULT로 보내고 페이지 갱신은 클라에서 요청 따로 보냄) struct TS_CS_AUCTION_REGISTER : TS_MESSAGE { TS_CS_AUCTION_REGISTER() _INIT( TM_CS_AUCTION_REGISTER ) enum AUCTION_DURATION_TYPE { DURATION_SHORTTERM = 1, ///< 경매 기간: 단기 DURATION_MIDTERM = 2, ///< 경매 기간: 중기 DURATION_LONGTERM = 3 ///< 경매 기간: 장기 }; AR_HANDLE item_handle; ///< 경매 등록할 아이템 핸들 int item_count; ///< 경매 등록할 아이템 수량 __int64 start_price; ///< 경매 시작가 __int64 instant_purchase_price; ///< 경매 물품 즉구가 unsigned char duration_type; ///< 경매 기간 타입(AUCTION_DURATION_TYPE 값이 들어감) }; /// 자신이 등록한 경매 취소 요청(결과는 TS_SC_RESULT로 보내고 페이지 갱신은 클라에서 요청 따로 보냄) struct TS_CS_AUCTION_CANCEL : TS_MESSAGE { TS_CS_AUCTION_CANCEL() _INIT( TM_CS_AUCTION_CANCEL ) int auction_uid; ///< 취소할 경매 번호 }; /// 자신 소유 보관 아이템 목록 요청 struct TS_CS_ITEM_KEEPING_LIST : TS_MESSAGE { TS_CS_ITEM_KEEPING_LIST() _INIT( TM_CS_ITEM_KEEPING_LIST ) int page_num; ///< 요청 페이지 번호 }; /******************************************************************************************************** ************* AuctionBase.h(.\Game\Resource\AuctionBase.h) 파일 내에 선언된 KEEPING_TYPE ************ ********************************************************************************************************/ /// 아이템 보관 타입 상수 선언 enum KEEPING_TYPE { KEEPING_TYPE_UNKNOWN = 0, ///< 보관 타입 불명 KEEPING_TYPE_ITEM_BY_SUCCESSFUL_BID = 1, ///< 경매 물품 낙찰 KEEPING_TYPE_ITEM_BY_INSTANT_PURCHASE = 2, ///< 경매 물품 즉시 구매 KEEPING_TYPE_ITEM_BY_EXPIRATION = 3, ///< 경매 만료에 의한 물품 반환 KEEPING_TYPE_ITEM_BY_CANCEL = 4, ///< 경매 취소에 의한 물품 반환 KEEPING_TYPE_GOLD_BY_ITEM_SELL = 30, ///< 경매 물품 판매 대금 KEEPING_TYPE_GOLD_BY_REG_TAX = 31, ///< 경매 물품 판매 이후 등록금 환급 KEEPING_TYPE_GOLD_BY_HIGHER_BID = 32, ///< 상위 입찰에 의한 입찰금 환급 KEEPING_TYPE_GOLD_BY_CANCEL = 33, ///< 경매 취소에 의한 입찰금 환급 KEEPING_TYPE_GOLD_BY_ITEM_SOLD_OUT = 34, ///< 타인 경매 물품 즉시 구매에 의한 입찰금 환급 }; /**************************************************************************************************************** ** 아래의 TS_SC_ITEM_KEEPING_LIST::TS_ITEM_KEEPING_INFO::keeping_type 변수에 위의 값 중 하나가 들어감 ** ****************************************************************************************************************/ /// 자신 소유 보관 아이템 목록 결과 struct TS_SC_ITEM_KEEPING_LIST : TS_MESSAGE { TS_SC_ITEM_KEEPING_LIST() _INIT( TM_SC_ITEM_KEEPING_LIST ) /// 아이템 보관 데이터 struct TS_ITEM_KEEPING_INFO { int keeping_uid; ///< 아이템 보관 번호 TS_ITEM_BASE_INFO item_info; ///< 아이템 정보 int duration; ///< 보관 기간 unsigned char keeping_type; ///< 보관 타입(AuctionBase.h의 enum KEEPING_TYPE 참조) ItemBase::ItemCode related_item_code; ///< 관련 아이템 코드(보관 아이템이 돈일 경우만 사용됨) int related_item_enhance; ///< 관련 아이템 강화 레벨(보관 아이템이 돈일 경우만 사용됨) int related_item_level; ///< 관련 아이템 대장작 레벨(보관 아이템이 돈일 경우만 사용됨) }; int page_num; ///< 현재 페이지 번호 int total_page_count; ///< 전체 페이지 수 int keeping_info_count; ///< 현재 페이지에 해당하는 아이템 보관 데이터 수 TS_ITEM_KEEPING_INFO keeping_info[ GameRule::AUCTION_INFO_COUNT_PER_PAGE ]; ///< 현재 페이지에 해당하는 아이템 보관 데이터 }; /// 자신 소유 보관 아이템 회수 요청(결과는 TS_SC_RESULT로 보내고 페이지 갱신은 클라에서 요청 따로 보냄) struct TS_CS_ITEM_KEEPING_TAKE : TS_MESSAGE { TS_CS_ITEM_KEEPING_TAKE() _INIT( TM_CS_ITEM_KEEPING_TAKE ) int keeping_uid; ///< 요청 아이템 보관 번호 }; // } [sonador][3.1.3] 경매장 서버 연동 ///////////////////////////////////////////////////////////////////////////// // Things to be used in the lobby struct MODEL_INFO { enum { NUDE_HAIR = 0, NUDE_FACE = 1, NUDE_BODY = 2, NUDE_HAND = 3, NUDE_FOOT = 4, NUDE_DECO = 6, }; int sex; int race; int model_id[5]; int hair_color_index; unsigned int hair_color_rgb; unsigned int hide_equip_flag; int texture_id; int wear_info[ItemBase::MAX_ITEM_WEAR_LOGIN]; }; struct LOBBY_CHARACTER_INFO : MODEL_INFO { int level; int job; int job_level; int exp_percentage; // ( 0 ~ 100 ) int hp; int mp; int permission; bool is_banned; char name[19]; unsigned long skin_color; char szCreateTime[30]; char szDeleteTime[30]; int wear_item_enhance_info[ItemBase::MAX_ITEM_WEAR_LOGIN]; int wear_item_level_info[ItemBase::MAX_ITEM_WEAR_LOGIN]; char wear_item_elemental_type[ItemBase::MAX_ITEM_WEAR_LOGIN]; ItemBase::ItemCode wear_appearance_code[ItemBase::MAX_ITEM_WEAR_LOGIN]; }; struct TS_CS_ACCOUNT : TS_MESSAGE { TS_CS_ACCOUNT() _INIT( TM_CS_ACCOUNT ) char account[19]; char password[32]; }; struct TS_CS_CHARACTER_LIST : TS_MESSAGE { TS_CS_CHARACTER_LIST() _INIT( TM_CS_CHARACTER_LIST ) char account[ GameRule::MAX_ACCOUNT_LEN + 1 ]; // #2.1.12 }; struct TS_CS_CREATE_CHARACTER : TS_MESSAGE { TS_CS_CREATE_CHARACTER() _INIT( TM_CS_CREATE_CHARACTER ) LOBBY_CHARACTER_INFO info; }; struct TS_CS_DELETE_CHARACTER : TS_MESSAGE { TS_CS_DELETE_CHARACTER() _INIT( TM_CS_DELETE_CHARACTER ) char name[19]; char security_no[19]; }; struct TS_SC_CHARACTER_LIST : TS_MESSAGE { TS_SC_CHARACTER_LIST() _INIT( TM_SC_CHARACTER_LIST ) unsigned int current_server_time; ///< 1970년 1월 1일 0시 0분 0초로부터 몇초가 경과되었는지를 알려줌. // ( CRT 의 time() 리턴값임) unsigned short last_login_index; unsigned short count; // 이하 LOBBY_CHARACTER_INFO 가 count 만큼 붙게됨 }; struct TS_CS_CHECK_CHARACTER_NAME : TS_MESSAGE { TS_CS_CHECK_CHARACTER_NAME() _INIT( TM_CS_CHECK_CHARACTER_NAME ) char name[19]; }; /// NPC 다이얼로그 struct TS_SC_DIALOG : TS_MESSAGE { TS_SC_DIALOG() _INIT( TM_SC_DIALOG ) enum { TYPE_NPC = 0, TYPE_DUNGEON_STONE = 1, TYPE_DONATION_PROP = 2, TYPE_QUEST_INFO_AND_START = 3, TYPE_AUCTION_WINDOW = 4, // { [sonador][3.1.3]경매장 서버 연동 TYPE_HUNTAHOLIC_LOBBY = 5, // #2.1.2.11.1 TYPE_DONATION_REWARD_NOTIFY = 6, TYPE_QUEST_INFO_IN_PROGRESS = 7, TYPE_QUEST_INFO_AND_END = 8, TYPE_CREATE_FARM_WINDOW = 9, TYPE_OTHER_INSTANCE_DUNGEON_CONFIRM_WINDOW = 10, // 2011.07.13 - servantes }; int type; AR_HANDLE npc_handle; ///< NULL 일수도 있음. unsigned short title_length; unsigned short text_length; unsigned short menu_length; //TYPE_NPC // 이하 다이얼로그 정보가 text string 으로 붙게됨. 메뉴는 |문자열|트리거| 의 형식으로 붙게 된다. /* +-----------------------+ title_length : 6 | 경비병 | text_length : 20 +-----------------------+ menu_length : 41 | | | 위험하니 돌아가세요. | data : 경비병위험하니 돌아가세요.|예|on_click_yes()||아니오|on_click_no()| | | | | | [예] [아니오] | +-----------------------+ */ //TYPE_DUNGEON_STONE //title: dungeon_id|raid_guild_count|guild_name|guild_leader_name|guild_leader_level|guild_member_count|raid_record| //-- dungeon_id로 던전 정보를 뿌리고, raid_guild_count로 아래에 보여줄 레이드 신청 길드의 숫자를 파악합니다. //text: guild_name|guild_leader_name|guild_leader_level|guild_member_count|raid_record| //-- raid_guild_count만큼 위 정보가 반복됩니다. UI에 표시되어야 할 정보 중 평균 레벨만 보내지 않는데… 계산부하가 좀 커서-_-뺐습니다.; //menu: REQUEST\tREQUEST_HANDLER\tCANCEL\tCANCEL_HANDLER\tMANAGE\tMANAGE_HANDLER //-- 각각의 handler는 던전 스톤 UI 하단의 3개 버튼과 매치가 되며, handler가 없을 경우 버튼이 비 활성화 됩니다. }; /// 다이얼로그 메뉴 클릭 결과를 전송한다. 이 헤더 이후에 스트링이 따라 붙어 오게 된다. struct TS_CS_DIALOG : TS_MESSAGE { TS_CS_DIALOG() _INIT( TM_CS_DIALOG ) unsigned short trigger_length; }; /// 프랍이나 NPC 를 클릭했을때 서버로 보낸다. 결과로는 TS_SC_DIALOG 나 기타등등의 메세지가 갈 수 있다. struct TS_CS_CONTACT : TS_MESSAGE { TS_CS_CONTACT() _INIT( TM_CS_CONTACT ) AR_HANDLE handle; }; struct TS_SC_SHOW_WINDOW : TS_MESSAGE { TS_SC_SHOW_WINDOW() _INIT(TM_SC_SHOW_WINDOW) unsigned short window_length; unsigned short argument_length; unsigned short trigger_length; }; /// 2011.10.26 서버에서 받은 내용을 출력할 때, 공통으로 쓰이는 메세지 박스 - prodongi struct TS_SC_GENERAL_MESSAGE_BOX : TS_MESSAGE { TS_SC_GENERAL_MESSAGE_BOX() _INIT( TM_SC_GENERAL_MESSAGE_BOX ) unsigned short text_length; }; struct TS_SC_MARKET : TS_MESSAGE { struct ItemInfo { ItemBase::ItemCode code; __int64 price; int huntaholic_point; // #2.1.2.11.1 int arena_point; /// 2012.07.20 아레나 포인트 - prodongi }; TS_SC_MARKET() _INIT( TM_SC_MARKET ) AR_HANDLE npc_handle; unsigned short item_count; }; struct TS_CS_BUY_ITEM : TS_MESSAGE { TS_CS_BUY_ITEM() _INIT( TM_CS_BUY_ITEM ) ItemBase::ItemCode item_code; unsigned short buy_count; }; struct TS_CS_SELL_ITEM : TS_MESSAGE { TS_CS_SELL_ITEM() _INIT( TM_CS_SELL_ITEM ) AR_HANDLE handle; __int64 sell_count; }; struct TS_CS_USE_ITEM : TS_MESSAGE { TS_CS_USE_ITEM() _INIT( TM_CS_USE_ITEM ) AR_HANDLE item_handle; AR_HANDLE target_handle; ///< 혼자 쓰는거라면 0 char szParameter[32]; }; struct TS_SC_USE_ITEM_RESULT : TS_MESSAGE { TS_SC_USE_ITEM_RESULT() _INIT( TM_SC_USE_ITEM_RESULT ) AR_HANDLE item_handle; AR_HANDLE target_handle; }; struct TS_SC_DESTROY_ITEM : TS_MESSAGE { TS_SC_DESTROY_ITEM() _INIT( TM_SC_DESTROY_ITEM ) AR_HANDLE item_handle; }; struct TS_SC_UPDATE_ITEM_COUNT : TS_MESSAGE { TS_SC_UPDATE_ITEM_COUNT() _INIT( TM_SC_UPDATE_ITEM_COUNT ) AR_HANDLE item_handle; __int64 count; }; /** 트레이드 진행 순서의 예 . 트레이드 요청하는이를 A, 대상을 B 라고 한다. 1. A 가 B 의 핸들을 적어 서버에게 REQUEST_TRADE 를 보낸다. 2. B 에게는 REQUEST_TRADE 메세지가 도착한다. 3. 만약 B 가 거부하려면 서버에게 REJECT_TRADE 메세지를 보낸다. 그러면 A 에게 REJECT_TRADE 메세지가 전달됨. 4. 만약 B 가 승락하려면 서버에게 ACCEPT_TRADE 메세지를 보낸다. 그러면 A 와 B 에게 BEGIN_TRADE 메세지가 전달됨. 5. 이후 아이템이나 돈을 올려 놓으려면 서버에게 ADD_ITEM 이나 ADD_GOLD 메세지를 보낸다. 그러면 A 와 B 에게 해당 메세지가 전달됨. 6. 만약 중도에 트레이드를 취소하려면 서버에 CANCEL_TRADE 버튼을 누른다. 그러면 A 와 B 에게 CANCEL_TRADE 메세지가 전달됨. 7. 확인 버튼을 누르려면 서버에게 FREEZE_TRADE 메세지를 보낸다. 그러면 A 와 B 에게 FREEZE_TRADE 메세지가 전달됨. 8. 둘다 확인버튼을 누른 상태에서 또 둘다 CONFIRM_TRADE 메세지를 보내면 트레이드가 성사된다. A 와 B 에게 PROCESS_TRADE 가 전송되며 바뀐 인벤 데이터와 금액 데이터는 다른 메세지로 전송된다. */ struct TS_TRADE : TS_MESSAGE { TS_TRADE() _INIT( TM_TRADE ) enum { 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, ///< 아이템 삭제 MODIFY_COUNT = 11, ///< 아이템수량을바꾼다 - 2011. 10. 4 - marine }; AR_HANDLE target_player; char mode; TS_ITEM_INFO item_info; }; struct TS_CS_START_BOOTH : TS_MESSAGE { struct TS_BOOTH_OPEN_ITEM_INFO { AR_HANDLE item_handle; int cnt; __int64 gold; }; TS_CS_START_BOOTH() _INIT(TM_CS_START_BOOTH) char name[49]; char type; ///< 1이면 판매 부스. 2이면 구매 부스 unsigned short cnt; // 이하 TS_BOOTH_ITEM_OPEN_INFO들이 CNT만큼 달려서 온다. }; struct TS_CS_STOP_BOOTH : TS_MESSAGE { TS_CS_STOP_BOOTH() _INIT(TM_CS_STOP_BOOTH) }; struct TS_CS_WATCH_BOOTH : TS_MESSAGE { TS_CS_WATCH_BOOTH() _INIT(TM_CS_WATCH_BOOTH) AR_HANDLE target; ///< 보고 싶은 사용자 }; struct TS_SC_WATCH_BOOTH : TS_MESSAGE { struct TS_BOOTH_ITEM_INFO : TS_ITEM_BASE_INFO { TS_BOOTH_ITEM_INFO() { } TS_BOOTH_ITEM_INFO( const TS_BOOTH_ITEM_INFO& other ) { memcpy( this, &other, sizeof( *this ) ); } TS_BOOTH_ITEM_INFO( AR_HANDLE _handle, ItemBase::ItemCode _code, __int64 _count, __int64 _gold, int _level, int _enhance, int _endurance, int _flag, const int _socket[ ItemBase::MAX_SOCKET_NUMBER ], char _elemental_effect_type, int _elemental_effect_attack_point, int _elemental_effect_magic_point, int _ethereal_durability, ItemBase::ItemCode _appearance_code, AwakenOption _AwakenOption, RANDOM_OPTION _RandomOption, int _nSummonID, int _nAdditionalItemEffect // Fraun Sky Accessories 7/12/2025 ) { handle = _handle; uid = 0; Code = _code; endurance = _endurance; count = _count; gold = _gold; enhance = _enhance; Flag = _flag; level = _level; memcpy( socket, _socket, sizeof(socket) ); elemental_effect_type = _elemental_effect_type; elemental_effect_attack_point = _elemental_effect_attack_point; elemental_effect_magic_point = _elemental_effect_magic_point; ethereal_durability = _ethereal_durability; // bintitle appearance_code = _appearance_code; // 2012. 7. 30 - marine 형상변환 awakenoption = _AwakenOption; random_option = _RandomOption; summon_id = _nSummonID; nAdditionalItemEffect = _nAdditionalItemEffect; // Fraun Sky Accessories 7/12/2025 } __int64 gold; }; TS_SC_WATCH_BOOTH() _INIT(TM_SC_WATCH_BOOTH) AR_HANDLE target; ///< 노점을 연 사용자 char type; ///< 1이면 판매 부스. 2이면 구매 부스 unsigned short cnt; ///< 아이템 숫자 // 아래로 TS_BOOTH_ITEM_INFO가 CNT만큼 붙게 됨 }; struct TS_CS_STOP_WATCH_BOOTH : TS_MESSAGE { TS_CS_STOP_WATCH_BOOTH() _INIT(TM_CS_STOP_WATCH_BOOTH) AR_HANDLE target; ///< 보고 싶은 사용자 }; struct TS_CS_BUY_FROM_BOOTH : TS_MESSAGE { TS_CS_BUY_FROM_BOOTH() _INIT(TM_CS_BUY_FROM_BOOTH) AR_HANDLE target; ///< 노점을 연 사용자 short cnt; // 이하 TS_ITEM_BASE_INFO 가 count만큼 들어감. }; struct TS_CS_SELL_TO_BOOTH : TS_MESSAGE { TS_CS_SELL_TO_BOOTH() _INIT(TM_CS_SELL_TO_BOOTH) AR_HANDLE target; ///< 노점을 연 사용자 AR_HANDLE item_handle; ///< 검증할 필요 없음. int cnt; }; struct TS_CS_GET_BOOTHS_NAME : TS_MESSAGE { TS_CS_GET_BOOTHS_NAME() _INIT(TM_CS_GET_BOOTHS_NAME) unsigned cnt; // 이하 cnt만큼의 AR_HANDLE(플레이어 핸들) 이 달려오게 된다. }; struct TS_SC_GET_BOOTHS_NAME : TS_MESSAGE { struct TS_BOOTH_NAME { AR_HANDLE handle; char name[49]; }; unsigned cnt; // 이하 cnt만큼의 TS_BOOTH_NAME 이 달려오게 된다. }; struct TS_BOOTH_TRADE_ITEM_INFO : TS_ITEM_BASE_INFO { __int64 price; }; struct TS_SC_BOOTH_TRADE_INFO : TS_MESSAGE { TS_SC_BOOTH_TRADE_INFO() _INIT(TM_SC_BOOTH_TRADE_INFO) AR_HANDLE target; bool is_sell; ///< 판매인지 구매인지 여부. true이면 판매. false이면 구매. short cnt; // 이하 TS_BOOTH_TRADE_ITEM_INFO 가 count만큼 들어감. }; struct TS_SC_BOOTH_CLOSED : TS_MESSAGE { TS_SC_BOOTH_CLOSED() _INIT(TM_SC_BOOTH_CLOSED) AR_HANDLE target; ///< 노점을 연 사용자 }; struct TS_CS_TURN_ON_PK_MODE : TS_MESSAGE { TS_CS_TURN_ON_PK_MODE() _INIT(TM_CS_TURN_ON_PK_MODE) }; struct TS_CS_TURN_OFF_PK_MODE : TS_MESSAGE { TS_CS_TURN_OFF_PK_MODE() _INIT(TM_CS_TURN_OFF_PK_MODE) }; //----------------------------------------------------------------------------------------------------------------- // 스킬 트리 리스트 //----------------------------------------------------------------------------------------------------------------- struct TS_SC_SKILL_LIST : TS_MESSAGE { TS_SC_SKILL_LIST() _INIT( TM_SC_SKILL_LIST ); struct SkillInfo { int skill_id; unsigned char base_skill_level; unsigned char current_skill_level; AR_TIME total_cool_time; AR_TIME remain_cool_time; SkillInfo() : skill_id( NULL ) , base_skill_level( NULL ) , current_skill_level( NULL ) , total_cool_time( NULL ) , remain_cool_time( NULL ) { } }; enum ModificationType { UPDATE = 0, // 스킬이 업데이트 됨 (기존 reset = false) REFRESH = 1, // 스킬 리스트를 갱신 (기존 reset = true) }; AR_HANDLE target; // 플레이어 혹은 크리쳐 unsigned short count; unsigned char modification_type; // enum ModificationType }; //------------------------------------------------------------------------------------------------------ // 스킬을 배우거나, 스킬레벨을 올린다. //------------------------------------------------------------------------------------------------------ struct TS_CS_LEARN_SKILL : TS_MESSAGE { TS_CS_LEARN_SKILL() _INIT( TM_CS_LEARN_SKILL ) AR_HANDLE target; // 자기 자신 혹은 자신의 크리쳐 int skill_id; // 스킬 ID int origin_skill_id; // 랜덤 스킬일 경우 랜덤으로 결정되기 전의 스킬 ID short skill_level; // 배울 스킬 레벨 }; /// 잡레벨을 올린다 (1씩) struct TS_CS_JOB_LEVEL_UP : TS_MESSAGE { TS_CS_JOB_LEVEL_UP() _INIT( TM_CS_JOB_LEVEL_UP ) AR_HANDLE target; ///< 자기 자신 혹은 자신의 크리쳐 }; ////////////////////////////////////////////////////////////////////////////// /// 이하 소환수 struct TS_SC_ADD_SUMMON_INFO : TS_MESSAGE { TS_SC_ADD_SUMMON_INFO() _INIT( TM_SC_ADD_SUMMON_INFO ) AR_HANDLE card_handle; AR_HANDLE summon_handle; char name[19]; int code; // 이하 정보 필요 int level; int sp; }; struct TS_SC_REMOVE_SUMMON_INFO : TS_MESSAGE { TS_SC_REMOVE_SUMMON_INFO() _INIT( TM_SC_REMOVE_SUMMON_INFO ) AR_HANDLE card_handle; }; struct TS_EQUIP_SUMMON : TS_MESSAGE { TS_EQUIP_SUMMON() _INIT(TM_EQUIP_SUMMON) bool open_dialog; AR_HANDLE card_handle[ 6 ]; }; struct TS_CS_SUMMON : TS_MESSAGE { TS_CS_SUMMON() _INIT(TM_CS_SUMMON) unsigned char is_summon; ///< 1이면 소환, 0이면 역소환 AR_HANDLE card_handle; }; struct TS_SC_UNSUMMON : TS_MESSAGE { TS_SC_UNSUMMON() _INIT(TM_SC_UNSUMMON) AR_HANDLE summon_handle; }; struct TS_SC_UNSUMMON_NOTICE : TS_MESSAGE { TS_SC_UNSUMMON_NOTICE() _INIT(TM_SC_UNSUMMON_NOTICE) AR_HANDLE summon_handle; AR_TIME unsummon_duration; }; struct TS_SC_SUMMON_EVOLUTION : TS_MESSAGE { TS_SC_SUMMON_EVOLUTION() _INIT( TM_SC_SUMMON_EVOLUTION ) AR_HANDLE card_handle; AR_HANDLE summon_handle; char name[19]; int code; }; struct TS_SC_ITEM_DROP_INFO : TS_MESSAGE { TS_SC_ITEM_DROP_INFO() _INIT(TM_SC_ITEM_DROP_INFO) AR_HANDLE monster_handle; AR_HANDLE item_handle; }; struct TS_QUEST_REWARD { ItemBase::ItemCode nItemCode; int nQuantity; }; struct TS_SC_QUEST_LIST : TS_MESSAGE { struct TS_QUEST_INFO { QuestBase::QuestCode code; int nStartID; int nRandomValue[QuestInstance::MAX_RANDOM_VALUE]; int nStatus[QuestInstance::MAX_STATUS]; unsigned char nProgress; AR_TIME nTimeLimit; }; struct TS_PENDING_QUEST_INFO { QuestBase::QuestCode code; int nStartID; }; TS_SC_QUEST_LIST() _INIT(TM_SC_QUEST_LIST) unsigned short count_active; unsigned short count_pending; // 이하 TS_QUEST_INFO가 count만큼 붙게 됨. }; struct TS_SC_QUEST_STATUS : TS_MESSAGE { TS_SC_QUEST_STATUS() _INIT(TM_SC_QUEST_STATUS) QuestBase::QuestCode code; int nStatus[QuestInstance::MAX_STATUS]; unsigned char nProgress; AR_TIME nTimeLimit; }; struct TS_SC_QUEST_INFOMATION : TS_MESSAGE { enum QUEST_PROGRESS { IS_STARTABLE = 0, IS_IN_PROGRESS = 1, IS_FINISHABLE = 2, }; TS_SC_QUEST_INFOMATION() _INIT(TM_SC_QUEST_INFOMATION) QuestBase::QuestCode code; QUEST_PROGRESS nProgress; unsigned short trigger_length; }; struct TS_CS_DROP_QUEST : TS_MESSAGE { TS_CS_DROP_QUEST() _INIT(TM_CS_DROP_QUEST) QuestBase::QuestCode code; }; struct TS_SC_SHOW_CREATE_GUILD : TS_MESSAGE { TS_SC_SHOW_CREATE_GUILD() _INIT(TM_SC_SHOW_CREATE_GUILD) }; struct TS_SC_OPEN_GUILD_WINDOW : TS_MESSAGE { TS_SC_OPEN_GUILD_WINDOW() _INIT(TM_SC_OPEN_GUILD_WINDOW) int client_id; int account_id; int one_time_password; char raw_server_name[32]; }; struct TS_SC_SHOW_CREATE_ALLIANCE : TS_MESSAGE { TS_SC_SHOW_CREATE_ALLIANCE() _INIT(TM_SC_SHOW_CREATE_ALLIANCE) }; ////////////////////////////////////////////////////////////////////////// /// 지역 관련 struct TS_CS_CHANGE_LOCATION : TS_MESSAGE { TS_CS_CHANGE_LOCATION() _INIT( TM_CS_CHANGE_LOCATION ) AR_UNIT x; AR_UNIT y; }; struct TS_SC_CHANGE_LOCATION : TS_MESSAGE { TS_SC_CHANGE_LOCATION () _INIT( TM_SC_CHANGE_LOCATION ) int prev_location_id; int cur_location_id; }; ////////////////////////////////////////////////////////////////////////// /// 날씨 관련 struct TS_CS_GET_WEATHER_INFO : TS_MESSAGE { TS_CS_GET_WEATHER_INFO() _INIT( TM_CS_GET_WEATHER_INFO ) unsigned int region_id; }; struct TS_SC_WEATHER_INFO : TS_MESSAGE { TS_SC_WEATHER_INFO() _INIT( TM_SC_WEATHER_INFO ) enum { CLEAR = 0, CLOUDY = 1, FOGGY = 2, DRIZZLINGLY = 3, RAINY = 4, SNOWY = 5, }; unsigned int region_id; unsigned short weather_id; }; struct TS_CS_EMOTION : TS_MESSAGE { TS_CS_EMOTION() _INIT( TM_CS_EMOTION ) int emotion; }; struct TS_SC_EMOTION : TS_MESSAGE { TS_SC_EMOTION() _INIT( TM_SC_EMOTION ) AR_HANDLE handle; int emotion; }; struct TS_CS_GAME_TIME : TS_MESSAGE { TS_CS_GAME_TIME() _INIT( TM_CS_GAME_TIME ) }; struct TS_SC_GAME_TIME : TS_MESSAGE { TS_SC_GAME_TIME() _INIT( TM_SC_GAME_TIME ) AR_TIME t; unsigned __int32 game_time; }; struct TS_CS_OPEN_ITEM_SHOP : TS_MESSAGE { TS_CS_OPEN_ITEM_SHOP() _INIT( TM_CS_OPEN_ITEM_SHOP ) }; struct TS_SC_OPEN_ITEM_SHOP : TS_MESSAGE { TS_SC_OPEN_ITEM_SHOP() _INIT( TM_SC_OPEN_ITEM_SHOP ) int client_id; int account_id; int one_time_password; char raw_server_name[32]; }; ////////////////////////////////////////////////////////////////////////// /// Cash Item struct TS_SC_COMMERCIAL_STORAGE_INFO : TS_MESSAGE { TS_SC_COMMERCIAL_STORAGE_INFO() _INIT( TM_SC_COMMERCIAL_STORAGE_INFO ) unsigned short total_item_count; ///< 0보다 클경우 캐쉬템에 아이템이 존재한다고 표시해 주면 되고 unsigned short new_item_count; ///< 0보다 클경우 캐쉬템에 새로운 아이템이 도착했다고 표시해 주면 됨. }; struct TS_SC_COMMERCIAL_STORAGE_LIST : TS_MESSAGE { TS_SC_COMMERCIAL_STORAGE_LIST() _INIT( TM_SC_COMMERCIAL_STORAGE_LIST ) struct CommercialItemInfo { unsigned int commercial_item_uid; ///< cuid (캐쉬템고유번호) ItemBase::ItemCode code; ///< 아이템코드 unsigned short count; ///< 갯수 }; unsigned short count; // 이하CommercialItemInfo 가count 만큼붙음 }; struct TS_CS_TAKEOUT_COMMERCIAL_ITEM : TS_MESSAGE { TS_CS_TAKEOUT_COMMERCIAL_ITEM() _INIT( TM_CS_TAKEOUT_COMMERCIAL_ITEM ) unsigned int commercial_item_uid; ///< 꺼낼아이템cuid unsigned short count; ///< 꺼낼갯수 }; struct TS_CS_DONATE_ITEM : TS_MESSAGE { struct DonateItemInfo { AR_HANDLE handle; //unsigned short count; //2010-4-26 : hunee __int64 count; // 1종류의 아이템 65536개 기부 시 계정 블록 문제 }; TS_CS_DONATE_ITEM() _INIT( TM_CS_DONATE_ITEM ) __int64 gold; int jp; unsigned char item_count; // 이뒤로DonateItemInfo가item_count 개수만큼붙음 }; struct TS_CS_DONATE_REWARD : TS_MESSAGE { TS_CS_DONATE_REWARD() _INIT( TM_CS_DONATE_REWARD ) struct RewardInfo { unsigned char reward_type; unsigned short count; }; unsigned char reward_count; // 이 뒤로 reward_count개 만큼의 RewardInfo가 붙어서 옴 }; struct TS_CS_SOULSTONE_CRAFT : TS_MESSAGE { TS_CS_SOULSTONE_CRAFT() _INIT( TM_CS_SOULSTONE_CRAFT ); AR_HANDLE craft_item_handle; enum { MAX_SOULSTONE_NUM = 8, //4 }; AR_HANDLE soulstone_handle[ MAX_SOULSTONE_NUM ]; }; struct TS_SC_SHOW_SOULSTONE_CRAFT_WINDOW : TS_MESSAGE { TS_SC_SHOW_SOULSTONE_CRAFT_WINDOW() _INIT( TM_CS_SHOW_SOULSTONE_CRAFT_WINDOW ); }; struct TS_SC_SHOW_SOULSTONE_REPAIR_WINDOW : TS_MESSAGE { TS_SC_SHOW_SOULSTONE_REPAIR_WINDOW() _INIT( TM_SC_SHOW_SOULSTONE_REPAIR_WINDOW ); }; // sonador 1.9.1 인벤토리 및 창고 정렬 기능 구현 struct TS_CS_ARRANGE_ITEM : TS_MESSAGE { TS_CS_ARRANGE_ITEM() _INIT( TM_CS_ARRANGE_ITEM ); bool bIsStorage; }; struct TS_CS_REPAIR_SOULSTONE : TS_MESSAGE { TS_CS_REPAIR_SOULSTONE() _INIT( TM_CS_REPAIR_SOULSTONE ); enum { MAX_REPAIR_COUNT = 6, }; AR_HANDLE item_handle[ MAX_REPAIR_COUNT ]; }; struct TS_CS_REQUEST_REMOVE_STATE : TS_MESSAGE { TS_CS_REQUEST_REMOVE_STATE() _INIT(TM_CS_REQUEST_REMOVE_STATE) AR_HANDLE target; int state_code; }; struct TS_CS_CHANGE_ITEM_POSITION : TS_MESSAGE { TS_CS_CHANGE_ITEM_POSITION() _INIT(TM_CS_CHANGE_ITEM_POSITION); bool is_storage; AR_HANDLE item_handle_1; AR_HANDLE item_handle_2; }; /* struct TS_SC_CREATE_SECURITY_NO : TS_MESSAGE { TS_SC_CREATE_SECURITY_NO() _INIT( TM_SC_CREATE_SECURITY_NO ) }; */ struct TS_SC_REQUEST_SECURITY_NO : TS_MESSAGE { TS_SC_REQUEST_SECURITY_NO() _INIT( TM_SC_REQUEST_SECURITY_NO ); enum { SC_NONE, SC_OPEN_STORAGE }; int mode; // 0 - None, 1 - Storage open }; struct TS_CS_SECURITY_NO : TS_MESSAGE { TS_CS_SECURITY_NO() _INIT( TM_CS_SECURITY_NO ); int mode; // 0 - None, 1 - Storage open char security_no[19]; }; /* struct TS_CS_CREATE_SECURITY_NO : TS_MESSAGE { TS_CS_CREATE_SECURITY_NO() _INIT( TM_CS_CREATE_SECURITY_NO ); char password[19]; char security_no[19]; }; struct TS_CS_CHANGE_SECURITY_NO : TS_MESSAGE { TS_CS_CHANGE_SECURITY_NO() _INIT( TM_CS_CHANGE_SECURITY_NO ); char security_no_old[19]; char security_no[19]; }; struct TS_CS_REQUEST_SECURITY_NO_CHANGE : TS_MESSAGE { TS_CS_REQUEST_SECURITY_NO_CHANGE() _INIT( TM_CS_REQUEST_SECURITY_NO_CHANGE ); }; struct TS_SC_CHANGE_SECURITY_NO : TS_MESSAGE { TS_SC_CHANGE_SECURITY_NO() _INIT( TM_SC_CHANGE_SECURITY_NO ); }; struct TS_CS_REQUEST_CLEAR_SECURITY_NO : TS_MESSAGE { TS_CS_REQUEST_CLEAR_SECURITY_NO() _INIT( TM_CS_REQUEST_CLEAR_SECURITY_NO ); }; struct TS_SC_CLEAR_SECURITY_NO : TS_MESSAGE { TS_SC_CLEAR_SECURITY_NO() _INIT( TM_SC_CLEAR_SECURITY_NO ); bool clearable; }; struct TS_CS_CLEAR_SECURITY_NO : TS_MESSAGE { TS_CS_CLEAR_SECURITY_NO() _INIT( TM_CS_CLEAR_SECURITY_NO ); char password[19]; char security_no[19]; }; */ struct TS_SC_NPC_TRADE_INFO : TS_MESSAGE { TS_SC_NPC_TRADE_INFO() _INIT( TM_SC_NPC_TRADE_INFO ) bool is_sell; ItemBase::ItemCode code; __int64 count; __int64 price; int huntaholic_point; // #2.1.2.11.1 int arena_point; AR_HANDLE target; }; struct TS_CS_CHECK_BOOTH_STARTABLE : TS_MESSAGE { TS_CS_CHECK_BOOTH_STARTABLE() _INIT( TM_CS_CHECK_BOOTH_STARTABLE ) }; struct TS_CS_REQUEST_RETURN_LOBBY : TS_MESSAGE { TS_CS_REQUEST_RETURN_LOBBY() _INIT( TM_CS_REQUEST_RETURN_LOBBY ) }; struct TS_CS_REQUEST_LOGOUT : TS_MESSAGE { TS_CS_REQUEST_LOGOUT() _INIT( TM_CS_REQUEST_LOGOUT ) }; struct TS_CS_LOGOUT : TS_MESSAGE { TS_CS_LOGOUT() _INIT( TM_CS_LOGOUT ) }; /** 1:1 대련 관련 패킷 추가 * 2009-01-29 : hunee */ /// 대련 타입 enum _COMPETE_TYPE { COMPETE_TYPE_VS_PLAYER = 0, COMPETE_TYPE_VS_PARTY = 1, COMPETE_TYPE_VS_GUILD = 2, COMPETE_TYPE_VS_ALLIANCE = 3 }; /// 대련 요청에 따른 응답 타입(클라이언트의 응답 메시지 및 CompeteManager에 응답 처리 시 사용됨) enum _COMPETE_ANSWER_TYPE { COMPETE_ANSWER_TYPE_ACCEPT = 0, ///< 수락 COMPETE_ANSWER_TYPE_REJECT_BY_USER = 1, ///< 거절 COMPETE_ANSWER_TYPE_REJECT_BY_OPTION = 2, ///< 자동거절(옵션) COMPETE_ANSWER_TYPE_REJECT_BY_TIMEOUT = 3 ///< 시간 초과에 따른 취소(신청받은 플레이어에게 보내질 경우 신청 수락/확인창이 닫히는 것으로 처리) // 일정 횟수 이상 연속 거절당함으로 인한 신청 불가 처리는 신청하는 플레이어의 클라이언트에서 처리함(서버에 요청이 올 일이 없으므로 불필요) }; /// 대련 종료 타입 enum _COMPETE_END_TYPE { COMPETE_END_BY_DEATH = 0, ///< 사망으로 인한 종료 COMPETE_END_BY_LOGOUT = 1, ///< 로그아웃으로 인한 종료 COMPETE_END_BY_RINGOUT = 2, ///< 장외로 인한 종료 COMPETE_END_BY_TIMEOUT = 3, ///< 시간 초과로 인한 종료 COMPETE_END_BY_INTERRUPT = 4, ///< 몬스터 또는 PK 플레이어의 방해로 인한 종료 COMPETE_END_BY_ENTERING_SAFETY_ZONE = 5, ///< 대련 불가 지역 진입으로 인한 종료 }; /// 플레이어가 타 플레이어에게 대련 요청 struct TS_CS_COMPETE_REQUEST : TS_MESSAGE { TS_CS_COMPETE_REQUEST() _INIT( TM_CS_COMPETE_REQUEST ) unsigned char compete_type; ///< _COMPETE_TYPE 값이 사용됨 char requestee[ 31 ]; ///< 도전 받은 플레이어 이름(개인/파티전은 플레이어/파티장 이름, 길드/연합전은 길드/연합의 이름이 사용됨) }; /** * 클라이언트 요청 메시지 ID (TS_SC_RESULT::request_msg_id) = TM_CS_COMPETE_REQUEST(= 4500) * 결과값(TS_SC_RESULT::result) * RESULT_NOT_EXIST 대련을 요청 받아야 할 대상 플레이어를 찾을 수 없는 경우 * RESULT_WAITING_COMPETE_REQUEST_ANSWER 대련을 요청한 플레이어가 전에 다른 플레이어에게 대련을 요청해 두었으며, 해당 응답이 아직 오지 않아서 타 플레이어에게 대련을 요청할 수 없는 경우 * RESULT_TARGET_WAITING_COMPETE_REQUEST_ANSWER 대련을 요청 받은 플레이어가 다른 플레이어로에게 대련을 요청하여 응답을 기다리고 있거나 응답을 해야 하는 상태인 경우 * RESULT_ALREADY_IN_COMPETE 대련을 요청한 플레이어가 이미 다른 진행 중인 대련에 참가 중인 경우 * RESULT_TARGET_ALREADY_IN_COMPETE 대련을 요청 받은 플레이어가 이미 다른 진행 중인 대련에 참가 중인 경우 * RESULT_NOT_IN_COMPETIBLE_PLACE 대련을 요청한 플레이어가 대련 불가 지역에 있는 경우 * RESULT_TARGET_NOT_IN_COMPETIBLE_PLACE 대련을 요청 받은 플레이어가 대련 불가 지역에 있는 경우 * RESULT_SUCCESS 성공적으로 대련 요청이 이루어진 경우 */ /// 대련 요청받은 플레이어에게 요청 전달 struct TS_SC_COMPETE_REQUEST : TS_MESSAGE { TS_SC_COMPETE_REQUEST() _INIT( TM_SC_COMPETE_REQUEST ) unsigned char compete_type; ///< _COMPETE_TYPE 값이 사용됨 char requester[ 31 ]; ///< 도전자 이름(개인/파티전은 플레이어/파티장 이름, 길드/연합전은 길드/연합의 이름이 사용됨) }; /// 대련 요청받은 플레이어가 응답 struct TS_CS_COMPETE_ANSWER : TS_MESSAGE { TS_CS_COMPETE_ANSWER() _INIT( TM_CS_COMPETE_ANSWER ) unsigned char compete_type; ///< _COMPETE_TYPE 값이 사용됨 unsigned char answer_type; ///< _COMPETE_ANSWER_TYPE 값이 사용됨 }; /** * 클라이언트 요청 메시지 ID (TS_SC_RESULT::request_msg_id) = TM_CS_COMPETE_ANSWER(= 4502) * 결과값(TS_SC_RESULT::result) * RESULT_NOT_IN_COMPETE 최초에 대련 요청했던 플레이어의 대련 정보가 초기화되어 정상적으로 수락 또는 거부가 이루어지지 않은 경우 * RESULT_NOT_EXIST 서버 내부적으로 사용하는 대련 신청 정보가 알 수 없는 이유로 삭제되었거나 대련을 요청한 플레이어를 찾을 수 없어서(로그아웃 등?) 수락 또는 거부가 처리되지 않은 경우 * RESULT_ALREADY_IN_COMPETE 신청 받았던 대련이 이미 시작되어 진행 중인 경우(수락 메시지를 연속 2번 이상 보낼 경우 발생 가능) * RESULT_TARGET_ALREADY_IN_COMPETE 대련을 수락 또는 거절한 플레이어가 신청 받은 대련이 아닌 다른 대련에 참가되어 있는 경우(수락/거부 버튼을 누르기 전에 다른 대련으로 딸려 들어간 상태, 버그나 네트워크 렉으로 인해 기존의 신청이 취소되지 않은 상태에서 다른 대련이 진행되는 경우에 발생 가능) * RESULT_ALREADY_IN_COMPETE 최초에 대련을 요청했던 플레이어가 다른 대련에 참가 중인 경우(위의 경우와 동일하지만 대련에 진입한 플레이어가 신청 받은 플레이어인지 신청한 플레이어인지만 다름) * RESULT_TARGET_NOT_IN_COMPETIBLE_PLACE 대련을 수락 또는 거절한 플레이어가 대련이 불가능한 지역에 진입해 있는 경우(신청 시 체크하지만 신청 받은 이후 대련 불가 지역으로 진입하여 수락 버튼을 누르는 경우에 해당) * RESULT_NOT_IN_COMPETIBLE_PLACE 최초에 대련을 요청했던 플레이어가 대련이 불가능한 지역에 진입해 있는 경우 */ /// 최초 대련 요청에 대한 결과 전달(수락/거부/자동거부) struct TS_SC_COMPETE_ANSWER : TS_MESSAGE { TS_SC_COMPETE_ANSWER() _INIT( TM_SC_COMPETE_ANSWER ) unsigned char compete_type; ///< _COMPETE_TYPE 값이 사용됨 unsigned char answer_type; ///< _COMPETE_ANSWER_TYPE 값이 사용됨 char requestee[ 31 ]; ///< 도전 받은 플레이어 이름(개인/파티전은 플레이어/파티장 이름, 길드/연합전은 길드/연합의 이름이 사용됨) }; /// 대련 시작 전 카운트 다운 개시 struct TS_SC_COMPETE_COUNTDOWN : TS_MESSAGE { TS_SC_COMPETE_COUNTDOWN() _INIT( TM_SC_COMPETE_COUNTDOWN ) unsigned char compete_type; ///< _COMPETE_TYPE 값이 사용됨 char competitor[ 31 ]; ///< 상대방 플레이어 이름(개인/파티전은 플레이어/파티장 이름, 길드/연합전은 길드/연합의 이름이 사용됨) AR_HANDLE handle_competitor; ///< 상대방플레이어핸들(1:1 PVP에서만 사용됨) }; /// 대련 시작 struct TS_SC_COMPETE_START : TS_MESSAGE { TS_SC_COMPETE_START() _INIT( TM_SC_COMPETE_START ) unsigned char compete_type; ///< _COMPETE_TYPE 값이 사용됨 char competitor[ 31 ]; ///< 상대방 플레이어 이름(개인/파티전은 플레이어/파티장 이름, 길드/연합전은 길드/연합의 이름이 사용됨) }; /// 대련 종료(결과 방송) struct TS_SC_COMPETE_END : TS_MESSAGE { TS_SC_COMPETE_END() _INIT( TM_SC_COMPETE_END ) unsigned char compete_type; ///< _COMPETE_TYPE 값이 사용됨 unsigned char end_type; ///< _COMPETE_END_TYPE 값이 사용됨 char winner[ 31 ]; ///< 승자 이름(개인/파티전은 플레이어/파티장 이름, 길드/연합전은 길드/연합의 이름이 사용됨) char loser[ 31 ]; ///< 패자 이름(개인/파티전은 플레이어/파티장 이름, 길드/연합전은 길드/연합의 이름이 사용됨) }; /** 1:1 대련 관련 패킷 추가 */ /// 랭킹 시스템 추가 enum _RANKING_TYPE { RANKING_TYPE_DONATION = 0, ///< 기부 포인트 랭킹 RANKING_TYPE_MAX_INDEX ///< 기부 타입 최대 수 }; /// 랭킹 타입별 상위 랭킹 차트와 자신의 랭크 요청 struct TS_CS_RANKING_TOP_RECORD : TS_MESSAGE { TS_CS_RANKING_TOP_RECORD() _INIT( TM_CS_RANKING_TOP_RECORD ) unsigned char ranking_type; ///< _RANKING_TYPE 값이 사용됨 }; /// 랭킹 타입별 상위 랭킹 차트와 요청자의 랭크 struct TS_SC_RANKING_TOP_RECORD : TS_MESSAGE { TS_SC_RANKING_TOP_RECORD() _INIT( TM_SC_RANKING_TOP_RECORD ) unsigned char ranking_type; ///< _RANKING_TYPE 값이 사용됨 unsigned short requester_rank; ///< 요청자 랭크(0이면 랭킹 미등록) __int64 requester_score; ///< 요청자 점수 struct RANKING_RECORD { unsigned short rank; char ranker_name[ 31 ]; __int64 score; }; unsigned short record_count; RANKING_RECORD ranking_record[ 10 ]; ///< 이 뒤로 RANKING_RECORD 가 record_count 개 만큼 이어 붙음 }; /// /// 서버와의 접속이 종료되었습니다 struct TS_SC_DISCONNECT_DESC : TS_MESSAGE { TS_SC_DISCONNECT_DESC() _INIT( TM_SC_DISCONNECT_DESC ) enum _DISCONNECT_TYPE { // { TS_AG_KICK_CLIENT::_KICK_TYPE DISCONNECT_TYPE_ANOTHER_LOGIN = 0, ///< 다른 유저의 접속으로 인한 접속 종료 DISCONNECT_TYPE_DUPLICATED_LOGIN = 1, ///< 인증 서버에서 게임 서버 로그인 처리 시 중복된 로그인 감지로 인한 접속 종료(내부 오류 또는 해킹에 의한 발생) DISCONNECT_TYPE_BILLING_EXPIRED = 2, ///< 결재 정보 만료로 인한 접속 종료 DISCONNECT_TYPE_GAME_ADDICTION = 3, ///< 게임 중독 방지로 인한 접속 종료 // } TS_AG_KICK_CLIENT::_KICK_TYPE DISCONNECT_TYPE_DB_ERROR = 100, ///< DB 오류로 인한 예외 처리로 인한 접속 종료 DISCONNECT_TYPE_ANTI_HACK = 101, ///< 게임 보안 솔루션 오류로 인한 접속 종료 DISCONNECT_TYPE_SCRIPT = 102, ///< 스크립트 명령어(SCRIPT_Kick)으로 인한 접속 종료 }; char desc_id; }; const int XTRAP_SETINFO_PACKETBUFF_SIZE = 128; struct TS_SC_XTRAP_CHECK : TS_MESSAGE { TS_SC_XTRAP_CHECK() _INIT( TM_SC_XTRAP_CHECK ) unsigned char pCheckBuffer[ XTRAP_SETINFO_PACKETBUFF_SIZE ]; }; struct TS_CS_XTRAP_CHECK : TS_MESSAGE { TS_CS_XTRAP_CHECK() _INIT( TM_CS_XTRAP_CHECK ) unsigned char pCheckBuffer[ XTRAP_SETINFO_PACKETBUFF_SIZE ]; }; struct TS_CS_ENTER_EVENT_AREA : TS_MESSAGE { TS_CS_ENTER_EVENT_AREA() _INIT( TM_CS_ENTER_EVENT_AREA ) int event_area_id; ///< 진입한 이벤트 영역의 ID int area_index; ///< 이벤트 영역을 구성하는 폴리곤들 중 몇 번째 폴리곤인지를 0-based index로 표현 }; // 2011.07.06 - servantes / TS_CS_LEAVE_EVENT_AREA add struct TS_CS_LEAVE_EVENT_AREA : TS_MESSAGE { TS_CS_LEAVE_EVENT_AREA() _INIT( TM_CS_LEAVE_EVENT_AREA ) int event_area_id; int area_index; }; // 서버에 퀘스트가 끝났다고 알린다 // 2011.07.12 - servantes struct TS_CS_END_QUEST : TS_MESSAGE { TS_CS_END_QUEST() _INIT( TM_CS_END_QUEST ) QuestBase::QuestCode code; unsigned char nOptionalReward; }; struct TS_CS_QUEST_INFO : TS_MESSAGE { TS_CS_QUEST_INFO() _INIT( TM_CS_QUEST_INFO ) QuestBase::QuestCode code; }; struct TS_CS_MONSTER_RECOGNIZE : TS_MESSAGE { TS_CS_MONSTER_RECOGNIZE() _INIT( TM_CS_MONSTER_RECOGNIZE ) AR_HANDLE recognizer_handle; AR_HANDLE handle; }; ////////////////////////////////////////////////////////////////////////// const unsigned short TM_SC_ADDED_SKILL_LIST = 404; //------------------------------------------------------------------------------------------------------ // A change in skill level occurs //------------------------------------------------------------------------------------------------------ struct TS_SC_ADDED_SKILL_LIST : TS_MESSAGE { TS_SC_ADDED_SKILL_LIST() _INIT( TM_SC_ADDED_SKILL_LIST ); struct AddedSkillInfo { int skill_id; bool restricted_to_type; char added_skill_level; AddedSkillInfo() : skill_id( NULL ) , restricted_to_type( false ) , added_skill_level( NULL ) { } }; AR_HANDLE target; unsigned short count; }; const unsigned short TM_SC_HAIR_INFO = 220; // Broadcast hair information – occurs on first enter, or when dyeing/changing hairstyle struct TS_SC_HAIR_INFO : TS_MESSAGE { TS_SC_HAIR_INFO() _INIT( TM_SC_HAIR_INFO ) AR_HANDLE hPlayer; int nHairID; int nHairColorIndex; unsigned int nHairColorRGB; }; // 길드 아이콘을 업데이트 하기위한 OTP 인증. const unsigned short TM_SC_UPDATE_GUILD_ICON = 652; struct TS_SC_UPDATE_GUILD_ICON : TS_MESSAGE { TS_SC_UPDATE_GUILD_ICON() _INIT( TM_SC_UPDATE_GUILD_ICON ) int client_id; int account_id; int one_time_password; char raw_server_name[32]; }; // 2010.05.19 HIDE_EQUIP_INFO - prodongi struct TS_CS_HIDE_EQUIP_INFO : TS_MESSAGE { TS_CS_HIDE_EQUIP_INFO() _INIT( TM_CS_HIDE_EQUIP_INFO ) unsigned int nHideEquipFlag; }; struct TS_SC_HIDE_EQUIP_INFO : TS_MESSAGE { TS_SC_HIDE_EQUIP_INFO() _INIT( TM_SC_HIDE_EQUIP_INFO ) AR_HANDLE hPlayer; unsigned int nHideEquipFlag; }; // Weapon swap struct TS_CS_SWAP_EQUIP : TS_MESSAGE { TS_CS_SWAP_EQUIP() _INIT( TM_CS_SWAP_EQUIP ) }; // 아이템수리. struct TS_CS_TRANSMIT_ETHEREAL_DURABILITY : TS_MESSAGE { TS_CS_TRANSMIT_ETHEREAL_DURABILITY() _INIT( TM_CS_TRANSMIT_ETHEREAL_DURABILITY ); AR_HANDLE handle; //int amount; }; // 아이템전체수리. struct TS_CS_TRANSMIT_ETHEREAL_DURABILITY_TO_EQUIPMENT : TS_MESSAGE { TS_CS_TRANSMIT_ETHEREAL_DURABILITY_TO_EQUIPMENT() _INIT( TM_CS_TRANSMIT_ETHEREAL_DURABILITY_TO_EQUIPMENT ); float percent; char target; }; // servantes 2011.02.23 // 크리처 농장 정보 요청 struct TS_CS_REQUEST_FARM_INFO : TS_MESSAGE { TS_CS_REQUEST_FARM_INFO() _INIT( TM_CS_REQUEST_FARM_INFO ) }; // 크리처 농장 정보 반환 struct TS_SC_FARM_INFO : TS_MESSAGE { TS_SC_FARM_INFO() _INIT( TM_SC_FARM_INFO ) char creature_count; struct SUMMON_INFO { int index; // 농장슬롯 int level; int type; char name[19]; int duration; // 맡기는 기간 int elasped_time; // 경과 시간 int refresh_time; // 돌보기 할 수 있는 시점까지 남은 시간 char using_cash; char using_cracker; TS_ITEM_BASE_INFO card_info; // 크리처 카드의 아이템 정보 }; // 이후 creature_count 만큼 SUMMON_INFO 구조체가 따라옴. }; // 크리처 맡기기 요청 struct TS_CS_FOSTER_CREATURE : TS_MESSAGE { TS_CS_FOSTER_CREATURE() _INIT( TM_CS_FOSTER_CREATURE ) AR_HANDLE creature_card_handle; int ticket_info_count; int cracker_info_count; struct TICKET_INFO { AR_HANDLE ticket_handle; int ticket_count; }; struct CRACKER_INFO { AR_HANDLE cracker_handle; int cracker_count; }; // 이후 TICKET_INFO, CRACKER_INFO 순서로 관련 정보들이 ticket_info_count, cracker_info_count만큼 따라옴 }; // 크리처 맡기기 결과 struct TS_SC_RESULT_FOSTER : TS_MESSAGE { TS_SC_RESULT_FOSTER() _INIT( TM_SC_RESULT_FOSTER ) char result; }; // 크리처 꺼내기 요청 struct TS_CS_RETRIEVE_CREATURE : TS_MESSAGE { TS_CS_RETRIEVE_CREATURE() _INIT( TM_CS_RETRIEVE_CREATURE ) AR_HANDLE creature_card_handle; }; // 크리처 꺼내기 결과 struct TS_SC_RESULT_RETRIEVE : TS_MESSAGE { TS_SC_RESULT_RETRIEVE() _INIT( TM_SC_RESULT_RETRIEVE ) char result; }; // 크리처 돌보기 요청 struct TS_CS_NURSE_CREATURE : TS_MESSAGE { TS_CS_NURSE_CREATURE() _INIT( TM_CS_NURSE_CREATURE ) AR_HANDLE creature_card_handle; }; // 크리처 돌보기 결과 struct TS_SC_RESULT_NURSE : TS_MESSAGE { TS_SC_RESULT_NURSE() _INIT( TM_SC_RESULT_NURSE ) char result; enum Result { FAILED = 0, // 무언가 잘못된 정보를 보냈으므로 요청을 무시. NO_REWARD = 1, // 돌보기를 하였으나 크리처가 보상을 주지는 않음 REWARDED = 2, // 돌보기 결과 크리처가 보상을 줌 }; }; // 마켓 열기 struct TS_CS_REQUEST_FARM_MARKET : TS_MESSAGE { TS_CS_REQUEST_FARM_MARKET() _INIT( TM_CS_REQUEST_FARM_MARKET ) }; // 크리처 농장 패킷 끝 struct TS_SC_SKILL_LEVEL_LIST : TS_MESSAGE { TS_SC_SKILL_LEVEL_LIST() _INIT( TM_SC_SKILL_LEVEL_LIST ) struct SkillLevelInfo { int skill_id; unsigned char skill_level; SkillLevelInfo() : skill_id( NULL ) , skill_level( NULL ) { } }; unsigned short count; }; struct TS_CS_SUMMON_CARD_SKILL_LIST : TS_MESSAGE { TS_CS_SUMMON_CARD_SKILL_LIST() _INIT( TM_CS_SUMMON_CARD_SKILL_LIST ) AR_HANDLE item_handle; }; struct TS_SC_TITLE_LIST : TS_MESSAGE { struct TS_TITLE_INFO { int code; int status; }; TS_SC_TITLE_LIST() _INIT( TM_SC_TITLE_LIST ) unsigned short count; // 이하TS_TITLE_INFO가count만큼붙는다. }; struct TS_SC_TITLE_CONDITION_LIST : TS_MESSAGE { struct TS_TITLE_CONDITION_INFO { int type; __int64 count; }; TS_SC_TITLE_CONDITION_LIST() _INIT( TM_SC_TITLE_CONDITION_LIST ) unsigned short count; // 이하TS_TITLE_CONDITION_INFO가count만큼붙는다. }; struct TS_SC_REMAIN_TITLE_TIME : TS_MESSAGE { TS_SC_REMAIN_TITLE_TIME() _INIT( TM_SC_REMAIN_TITLE_TIME ) AR_TIME remain_title_time; }; struct TS_CS_SET_MAIN_TITLE : TS_MESSAGE { TS_CS_SET_MAIN_TITLE() _INIT( TM_CS_SET_MAIN_TITLE ) int code; }; struct TS_SC_SET_MAIN_TITLE : TS_MESSAGE { TS_SC_SET_MAIN_TITLE() _INIT( TM_SC_SET_MAIN_TITLE ) int handle; int code; }; struct TS_CS_SET_SUB_TITLE : TS_MESSAGE { TS_CS_SET_SUB_TITLE() _INIT( TM_CS_SET_SUB_TITLE ) int index; int code; }; struct TS_SC_SET_SUB_TITLE : TS_MESSAGE { TS_SC_SET_SUB_TITLE() _INIT( TM_SC_SET_SUB_TITLE ) int index; int code; }; struct TS_CS_BOOKMARK_TITLE : TS_MESSAGE { TS_CS_BOOKMARK_TITLE() _INIT( TM_CS_BOOKMARK_TITLE ) int code; }; struct TS_SC_BOOKMARK_TITLE : TS_MESSAGE { TS_SC_BOOKMARK_TITLE() _INIT( TM_SC_BOOKMARK_TITLE ) int code; bool bookmarked; }; struct TS_SC_ACHIEVE_TITLE : TS_MESSAGE { TS_SC_ACHIEVE_TITLE() _INIT( TM_SC_ACHIEVE_TITLE ) int code; }; struct TS_SC_OPEN_TITLE : TS_MESSAGE { TS_SC_OPEN_TITLE() _INIT( TM_SC_OPEN_TITLE ) int code; }; struct TS_SC_CHANGE_TITLE_CONDITION : TS_MESSAGE { TS_SC_CHANGE_TITLE_CONDITION() _INIT( TM_SC_CHANGE_TITLE_CONDITION ) int condition_id; __int64 count; }; struct TS_SC_BATTLE_ARENA_PENALTY_INFO : TS_MESSAGE { TS_SC_BATTLE_ARENA_PENALTY_INFO() _INIT( TM_SC_BATTLE_ARENA_PENALTY_INFO ) AR_TIME nBlockTime; int nPenaltyCount; AR_TIME nPenaltyCountDecTime; }; struct TS_CS_BATTLE_ARENA_JOIN_QUEUE : TS_MESSAGE { TS_CS_BATTLE_ARENA_JOIN_QUEUE() _INIT( TM_CS_BATTLE_ARENA_JOIN_QUEUE ) int nArenaID; }; struct TS_SC_BATTLE_ARENA_JOIN_QUEUE : TS_MESSAGE { TS_SC_BATTLE_ARENA_JOIN_QUEUE() _INIT( TM_SC_BATTLE_ARENA_JOIN_QUEUE ) int nArenaID; /* // 아레나 유저 등급 구분 enum _BATTLE_GRADE { BG_INVALID = -1, BG_ROOKIE = 0, BG_GROW = 1, BG_MAJOR = 2, MAX_BATTLE_GRADE, }; */ _BATTLE_GRADE eGrade; }; struct TS_SC_BATTLE_ARENA_UPDATE_WAIT_USER_COUNT : TS_MESSAGE { TS_SC_BATTLE_ARENA_UPDATE_WAIT_USER_COUNT() _INIT( TM_SC_BATTLE_ARENA_UPDATE_WAIT_USER_COUNT ) int nWaitUserCount; }; struct TS_CS_BATTLE_ARENA_LEAVE : TS_MESSAGE { TS_CS_BATTLE_ARENA_LEAVE() _INIT( TM_CS_BATTLE_ARENA_LEAVE ) }; struct TS_SC_BATTLE_ARENA_LEAVE : TS_MESSAGE { TS_SC_BATTLE_ARENA_LEAVE() _INIT( TM_SC_BATTLE_ARENA_LEAVE ) /* // 아레나 이탈 유형 코드 enum _ARENA_LEAVE_TYPE { ALT_UNKNOWN = 0, ALT_USER_REQUEST = 1, // 대기열/경기 이탈 두 경우 모두 사용됨 ALT_GAME_OVER = 2, // 경기 이탈 시에만 사용됨 ALT_PARTICIPATING_SPECIAL_PARTY = 3, // 대기열 이탈 시에만 사용됨 ALT_FAILED_TO_JOIN_BATTLE = 4, // 대기열 이탈 시에만 사용됨 ALT_FAILED_TO_START_BATTLE = 5, // 대기열 이탈 시에만 사용됨(경기 시작 실패) ALT_DISCONNECT = 6, // 대기열 이탈 시에만 사용됨(대기열에 있다가 접속 끊긴 경우) }; */ _ARENA_LEAVE_TYPE eLeaveType; char szName[ 19 ]; }; struct TS_SC_BATTLE_ARENA_BATTLE_INFO : TS_MESSAGE { TS_SC_BATTLE_ARENA_BATTLE_INFO() _INIT( TM_SC_BATTLE_ARENA_BATTLE_INFO ) int nArenaID; // 패킷 수신자 개인 종속적인 내용 AR_TIME nForceEnterTime; // 경기 종속적인 내용(점수는 별도의 패킷이 있으므로 제외) AR_TIME nStartTime; _BATTLE_GRADE eGrade; AR_TIME nEndTime; unsigned char nPlayerCountPerTeam[ 2 ]; struct PlayerInfo { AR_HANDLE handle; // handle == 0 이면 오프라인 유저 int nJobID; char szName[ 19 ]; // 기존에 AR_HANDLE과 묶인 이름 정보가 있더라도 가명에 의해 다른 이름이 지정될 수 있음 }; // 이 뒤로 PlayerInfo가 nPlayerCountPerTeam[ 0 ] + nPlayerCountPerTeam[ 1 ]개 만큼 붙음 }; struct TS_CS_BATTLE_ARENA_ENTER_WHILE_COUNTDOWN : TS_MESSAGE { TS_CS_BATTLE_ARENA_ENTER_WHILE_COUNTDOWN() _INIT( TM_CS_BATTLE_ARENA_ENTER_WHILE_COUNTDOWN ) }; struct TS_CS_BATTLE_ARENA_EXERCISE_READY : TS_MESSAGE { TS_CS_BATTLE_ARENA_EXERCISE_READY() _INIT( TM_CS_BATTLE_ARENA_EXERCISE_READY ) bool bReady; }; struct TS_SC_BATTLE_ARENA_EXERCISE_READY_STATUS : TS_MESSAGE { TS_SC_BATTLE_ARENA_EXERCISE_READY_STATUS() _INIT( TM_SC_BATTLE_ARENA_EXERCISE_READY_STATUS ) int nReadyState; }; struct TS_CS_BATTLE_ARENA_EXERCISE_START : TS_MESSAGE { TS_CS_BATTLE_ARENA_EXERCISE_START() _INIT( TM_CS_BATTLE_ARENA_EXERCISE_START ) }; struct TS_SC_BATTLE_ARENA_BATTLE_STATUS : TS_MESSAGE { TS_SC_BATTLE_ARENA_BATTLE_STATUS() _INIT( TM_SC_BATTLE_ARENA_BATTLE_STATUS ) int nStatus; /* enum _PROP_STATE { PS_NOT_EXIST = 0, PS_NEUTRAL = 1, PS_OWNED_BY_TEAM_0 = 2, PS_OWNED_BY_TEAM_1 = 3, }; */ _PROP_STATE GetPropState( int nPropIndex ) const { assert( nPropIndex >= 0 && nPropIndex < 9 ); return static_cast< _PROP_STATE >( ( nStatus >> ( nPropIndex * 2 ) ) & 0x3 ); } bool IsActivatedBingoLine( int nLineIndex ) { assert( nLineIndex >= 0 && nLineIndex < 8 ); return ( ( nStatus >> 24 ) & ( 1 << nLineIndex ) ) != 0; } // 경기 타입에 따라 nStatus의 의미가 달라짐 // 클래식 - 이 패킷 자체를 사용하지 않음 // 슬래터 - 슬래터 프랍 소속 상태(GetPropState( 0 )으로 얻을 수 있음) // 빙고 - 3x3 프랍의 소속 정보 및 빙고 달성 정보 // 1. 뒤에서부터 2 비트( ( nStatus >> ( nPropIndex * 2 ) ) & 0x3 )씩 잘라서 각 프랍의 소속 상태로 사용(0: 프랍 없음, 1: 중립, 2: 연합군, 3: 마녀군) // 총 9개의 프랍이 있으므로 32비트 중 18비트가 사용됨 // * GetPropState을 사용해 각 프랍별 상태를 확인할 수 있음 // 2. 최상위의 8비트( int nActivatedLineFlag = (nStatus >> 24) & 0xFF )를 이번 nStatus 변경으로 인해 달성된 빙고 라인이 어느 것인지 표현 // 0---1---2 // | | | // 3---4---5 // | | | // 6---7---8 // 위와 같이 각 빙고 프랍에 대해 0 ~ 8 까지 Index가 지정되어 있을 때 // 0 - 1 - 2 (가로줄 1)이 달성되었으면 최하위 0번째 비트가 On ( nActivatedLineFlag & ( 1 << 0 ) ) != 0 // 3 - 4 - 5 (가로줄 2)가 달성되었으면 최하위 1번째 비트가 On ( nActivatedLineFlag & ( 1 << 1 ) ) != 0 // 6 - 7 - 8 (가로줄 3)이 달성되었으면 최하위 2번째 비트가 On ( nActivatedLineFlag & ( 1 << 2 ) ) != 0 // 0 - 3 - 6 (세로줄 1)이 달성되었으면 최하위 3번째 비트가 On ( nActivatedLineFlag & ( 1 << 3 ) ) != 0 // 1 - 4 - 7 (세로줄 2)가 달성되었으면 최하위 4번째 비트가 On ( nActivatedLineFlag & ( 1 << 4 ) ) != 0 // 2 - 5 - 8 (세로줄 3)이 달성되었으면 최하위 5번째 비트가 On ( nActivatedLineFlag & ( 1 << 5 ) ) != 0 // 0 - 4 - 8 (대각선 1)이 달성되었으면 최하위 6번째 비트가 On ( nActivatedLineFlag & ( 1 << 6 ) ) != 0 // 2 - 4 - 6 (대각선 2)가 달성되었으면 최하위 7번째 비트가 On ( nActivatedLineFlag & ( 1 << 7 ) ) != 0 // * 빙고에 참여된 프랍은 사라져야 하기 때문에 ( ( nStatus >> nPropIdx * 2 ) & 0x3 ) 값이 0이 아니었다가 0이 됨(빙고라는 걸 방송하는 시점에는 0이 된 상태로 방송됨) // * >> (Bit right shift) 연산을 nStatus 에 할 때, signed 변수이기 때문에 만일 최상위 비트가 On 되어있었을 경우(int 값으로는 음수)에는 // 왼쪽에서부터 1이 채워져 들어오게 되므로 Shift 연산 후의 결과가 음수가 됨. 따라서 Shift 연산 후에는 반드시 & (Bitwise AND) 연산자를 통해 얻고자 하는 값만 잘라내야 함 // * IsActivatedBingoLine 함수로 특정 라인이 빙고 상태가 됐는지 확인 가능 }; struct TS_SC_BATTLE_ARENA_BATTLE_SCORE : TS_MESSAGE { TS_SC_BATTLE_ARENA_BATTLE_SCORE() _INIT( TM_SC_BATTLE_ARENA_BATTLE_SCORE ) struct TeamScore { short nTotalKillCount; // 각 팀별 킬 수 총합 short nTotalDeathCount; // 각 팀별 데스 수 총합 short nScore; // 각 팀별 현재 점수 }; struct PlayerScore { char szName[ 19 ]; short nKillCount; short nDeathCount; short nPropActivateCount; int nTotalGainAP; }; TeamScore aTeamScore[ 2 /* GameRule::BATTLE_ARENA_MAX_TEAM_COUNT */ ]; unsigned char nPlayerScoreCount; // 이 뒤로 PlayerScore가 nPlayerScoreCount개 만큼 붙음 }; struct TS_SC_BATTLE_ARENA_JOIN_BATTLE : TS_MESSAGE { TS_SC_BATTLE_ARENA_JOIN_BATTLE() _INIT( TM_SC_BATTLE_ARENA_JOIN_BATTLE ) int nTeamNo; AR_HANDLE handle; int nJobID; char szName[ 19 ]; }; struct TS_SC_BATTLE_ARENA_DISCONNECT_BATTLE : TS_MESSAGE { TS_SC_BATTLE_ARENA_DISCONNECT_BATTLE() _INIT( TM_SC_BATTLE_ARENA_DISCONNECT_BATTLE ) AR_HANDLE handle; }; struct TS_SC_BATTLE_ARENA_RECONNECT_BATTLE : TS_MESSAGE { TS_SC_BATTLE_ARENA_RECONNECT_BATTLE() _INIT( TM_SC_BATTLE_ARENA_RECONNECT_BATTLE ) // 유저가 로그아웃되었다가 다시 접속될 경우 서버에서 AR_HANDLE값이 재부여되기 때문에 // 클라이언트에서는 기존의 AR_HANDLE 값을 사용하면 안되고 이 패킷으로 받은 값으로 갱신해서 사용해야 함 // 이 경우 어떤 유저가 재접속했는지는 szName을 기준으로 처리해야 함 char szName[ 19 ]; AR_HANDLE newHandle; }; struct TS_SC_BATTLE_ARENA_RESULT : TS_MESSAGE { TS_SC_BATTLE_ARENA_RESULT() _INIT( TM_SC_BATTLE_ARENA_RESULT ) /* // 아레나 경기 종료 타입 enum _ARENA_END_TYPE { AET_UNKNOWN = 0, AET_ONE_TEAM_NO_MEMBER = 1, // 한 팀의 멤버가 모두 이탈하여 경기 종료(종료 유형이지만 보상이 없다는 내용도 포함) AET_MAX_SCORE_REACHED = 2, // 목표 점수 도달로 경기 종료 AET_TIME_OVER = 3, // 시간 초과로 경기 종료 }; // 아레나 경기 보상 타입 enum _ARENA_REWARD_TYPE { ART_UNKNOWN = 0, ART_FULL_REWARD = 1, // 값 없음(지정 안하면 이거) ART_HALF_REWARD_BY_FEW_MEMBER = 2, // 한 팀의 멤버 수가 팀 최대 인원의 50% 미만이어서 보상이 절반으로 감소 ART_NO_REWARD_BY_NO_MEMBER = 3, // 한 팀의 멤버가 모두 이탈해서 경기가 중단되어 보상 없음 ART_NO_REWARD_BY_MIN_TIME = 4, // 최소 경기 시간 미달로 인해 보상 없음 ART_NO_REWARD_BY_EXERCISE = 5, // 연습 경기는 보상 없음 }; */ _ARENA_END_TYPE eEndType; _ARENA_REWARD_TYPE eRewardType; int nWinnerTeamNo; // 0: 연합군, 1:마녀군 unsigned char nMVPCount; // 이 뒤로 char[ 19 ] 가 nMVPCount 만큼 붙음 }; struct TS_CS_BATTLE_ARENA_ABSENCE_CHECK_REQUEST : TS_MESSAGE { TS_CS_BATTLE_ARENA_ABSENCE_CHECK_REQUEST() _INIT( TM_CS_BATTLE_ARENA_ABSENCE_CHECK_REQUEST ) AR_HANDLE hCheckTarget; }; struct TS_SC_BATTLE_ARENA_ABSENCE_CHECK : TS_MESSAGE { TS_SC_BATTLE_ARENA_ABSENCE_CHECK() _INIT( TM_SC_BATTLE_ARENA_ABSENCE_CHECK ) AR_TIME nLimitTime; }; struct TS_CS_BATTLE_ARENA_ABSENCE_CHECK_ANSWER : TS_MESSAGE { TS_CS_BATTLE_ARENA_ABSENCE_CHECK_ANSWER() _INIT( TM_CS_BATTLE_ARENA_ABSENCE_CHECK_ANSWER ) bool bSuccess; }; //struct TS_CS_DECOMPOSE : TS_MESSAGE //{ // TS_CS_DECOMPOSE() _INIT( TM_CS_DECOMPOSE ) // // UINT m_nCount; //}; //gmpbigsun(20130409) : 분해 -중첩수량 추가 struct TS_CS_DECOMPOSE : TS_MESSAGE { TS_CS_DECOMPOSE() _INIT( TM_CS_DECOMPOSE ) struct DECOMPOSE_INFO { DECOMPOSE_INFO( AR_HANDLE _handle = 0, unsigned int _count = 0) : handle( _handle ), count( _count ) {} AR_HANDLE handle; unsigned int count; }; unsigned int count; // 이하DECOMPOSE_INFO 가count 만큼붙게됨. }; struct TS_SC_DECOMPOSE_RESULT : TS_MESSAGE { TS_SC_DECOMPOSE_RESULT() _INIT( TM_SC_DECOMPOSE_RESULT ) UINT m_nTotalCount; }; struct TS_SC_SKIN_INFO : TS_MESSAGE { TS_SC_SKIN_INFO() _INIT( TM_SC_SKIN_INFO ) AR_HANDLE hPlayer; DWORD dwSkinColor; }; /////////////////////////////////////////////////////////////////// // 파티매치 메시지 #define PARTYMATCH_MEMBER_MAX 10 #define PARTYMATCH_ROOM_MAX 100 #define PARTYMATCH_ROOM_PAGE 10 #define PARTYMATCH_ROOM_TITLE 32 struct STRUCT_PARTYMATCH_ROOM { int nRoom; // Room 이 0이면 방이 없는것 int nParty; short nArea; short nLevel; short nMember; short nMaxMember; char szText[PARTYMATCH_ROOM_TITLE]; }; struct STRUCT_PARTYMATCH_MEMBER { int nMode; // 맴버 표시정보. 현재로서는 0x80000000 | (nLevel<<16) | nJobID; //short nLevel; //short nJobID; AR_HANDLE nMember; char szName[20]; }; struct TS_CS_PARTYMATCH_ACTION : TS_MESSAGE { TS_CS_PARTYMATCH_ACTION() _INIT( TM_CS_PARTYMATCH_ACTION ) int nAction; // 0:목록요청 1:맴버요청 2:방만들기 3:방없애기 4:초대요청 int nPage; // 목록요청에만 사용. AR_HANDLE nMaster; // Apply 에만 사용. STRUCT_PARTYMATCH_ROOM stRoom; }; struct TS_SC_PARTYMATCH_LIST : TS_MESSAGE { TS_SC_PARTYMATCH_LIST() _INIT( TM_SC_PARTYMATCH_LIST ) int nPage; int nRoomTotal; STRUCT_PARTYMATCH_ROOM pRoom[PARTYMATCH_ROOM_PAGE]; }; struct TS_SC_PARTYMATCH_MEMBER : TS_MESSAGE { int nRoom; AR_HANDLE nMaster; // master ID 아래에 pMeber중 하나가 이와 같은 값이다. STRUCT_PARTYMATCH_MEMBER pMember[PARTYMATCH_MEMBER_MAX]; }; #pragma pack() void PendMessage( struct IStreamSocketConnection *pConn, const TS_MESSAGE * pMessage ); void PendMessage( struct IStreamSocketConnection *pConn, void *pBuffer, unsigned size );