static void __proc_login_notice(char *login, int on_time, int off_time) { //{ check player's name LPDESC desc = DESC_MANAGER::instance().FindByLoginName(login); if (NULL==desc) return; LPCHARACTER ch = desc->GetCharacter(); if (NULL==ch) return; //} check player's name char on_time_string[64]; char off_time_string[64]; __sec_to_timestring(on_time, on_time_string, sizeof(on_time_string)); __sec_to_timestring(off_time, off_time_string, sizeof(off_time_string)); if (0==on_time) { ch->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("당신의 누적 오프라인 시간은 %s입니다."), off_time_string); ch->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("당신의 누적 온라인 시간은 0이 되었습니다. 100% 효과를 얻으실 수 있습니다.")); return; } else { ch->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("당신의 누적 오프라인 시간은 %s이며, 누적 온라인 시간은 %s입니다."), off_time_string, on_time_string); } }
void CObject::EncodeInsertPacket(LPENTITY entity) { LPDESC d; if (!(d = entity->GetDesc())) return; sys_log(0, "ObjectInsertPacket vid %u vnum %u rot %f %f %f", m_dwVID, m_data.dwVnum, m_data.xRot, m_data.yRot, m_data.zRot); TPacketGCCharacterAdd pack; memset(&pack, 0, sizeof(TPacketGCCharacterAdd)); pack.header = HEADER_GC_CHARACTER_ADD; pack.dwVID = m_dwVID; pack.bType = CHAR_TYPE_BUILDING; pack.angle = m_data.zRot; pack.x = GetX(); pack.y = GetY(); pack.z = GetZ(); pack.wRaceNum = m_data.dwVnum; // 빌딩 회전 정보(벽일때는 문 위치)를 변환 pack.dwAffectFlag[0] = unsigned(m_data.xRot); pack.dwAffectFlag[1] = unsigned(m_data.yRot); if (GetLand()) { // pack.dwGuild = GetLand()->GetOwner(); } d->Packet(&pack, sizeof(pack)); }
void DESC_MANAGER::DestroyClosed() { DESC_SET::iterator i = m_set_pkDesc.begin(); while (i != m_set_pkDesc.end()) { LPDESC d = *i; DESC_SET::iterator ci = i; ++i; if (d->IsPhase(PHASE_CLOSE)) { if (d->GetType() == DESC_TYPE_CONNECTOR) { LPCLIENT_DESC client_desc = (LPCLIENT_DESC)d; if (client_desc->IsRetryWhenClosed()) { client_desc->Reset(); continue; } } DestroyDesc(d, false); m_set_pkDesc.erase(ci); } } }
bool operator () (LPDESC d) { if (d->GetCharacter() && !strcmp(d->GetCharacter()->GetName(), m_name)) return true; return false; }
void CPVPManager::Insert(LPCHARACTER pkChr, LPCHARACTER pkVictim) { if (pkChr->IsDead() || pkVictim->IsDead()) return; CPVP kPVP(pkChr->GetPlayerID(), pkVictim->GetPlayerID()); CPVP * pkPVP; if ((pkPVP = Find(kPVP.m_dwCRC))) { // 복수할 수 있으면 바로 싸움! if (pkPVP->Agree(pkChr->GetPlayerID())) { pkVictim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s님과의 대결 시작!"), pkChr->GetName()); pkChr->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s님과의 대결 시작!"), pkVictim->GetName()); } return; } pkPVP = M2_NEW CPVP(kPVP); pkPVP->SetVID(pkChr->GetPlayerID(), pkChr->GetVID()); pkPVP->SetVID(pkVictim->GetPlayerID(), pkVictim->GetVID()); m_map_pkPVP.insert(map<DWORD, CPVP *>::value_type(pkPVP->m_dwCRC, pkPVP)); m_map_pkPVPSetByID[pkChr->GetPlayerID()].insert(pkPVP); m_map_pkPVPSetByID[pkVictim->GetPlayerID()].insert(pkPVP); pkPVP->Packet(); char msg[CHAT_MAX_LEN + 1]; snprintf(msg, sizeof(msg), LC_TEXT("%s님이 대결신청을 했습니다. 승낙하려면 대결동의를 하세요."), pkChr->GetName()); pkVictim->ChatPacket(CHAT_TYPE_INFO, msg); pkChr->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s에게 대결신청을 했습니다."), pkVictim->GetName()); // NOTIFY_PVP_MESSAGE LPDESC pkVictimDesc = pkVictim->GetDesc(); if (pkVictimDesc) { TPacketGCWhisper pack; int len = MIN(CHAT_MAX_LEN, strlen(msg) + 1); pack.bHeader = HEADER_GC_WHISPER; pack.wSize = sizeof(TPacketGCWhisper) + len; pack.bType = WHISPER_TYPE_SYSTEM; strlcpy(pack.szNameFrom, pkChr->GetName(), sizeof(pack.szNameFrom)); TEMP_BUFFER buf; buf.write(&pack, sizeof(TPacketGCWhisper)); buf.write(msg, len); pkVictimDesc->Packet(buf.read_peek(), buf.size()); } // END_OF_NOTIFY_PVP_MESSAGE }
void operator() (LPDESC d) { if (d->GetCharacter()) { ++iTotalCount; ++aiEmpireUserCount[d->GetEmpire()]; } }
void CInputProcessor::Handshake(LPDESC d, const char * c_pData) { TPacketCGHandshake * p = (TPacketCGHandshake *) c_pData; if (d->GetHandshake() != p->dwHandshake) { sys_err("Invalid Handshake on %d", d->GetSocket()); d->SetPhase(PHASE_CLOSE); } else { if (d->IsPhase(PHASE_HANDSHAKE)) { if (d->HandshakeProcess(p->dwTime, p->lDelta, false)) { #ifdef _IMPROVED_PACKET_ENCRYPTION_ d->SendKeyAgreement(); #else if (g_bAuthServer) d->SetPhase(PHASE_AUTH); else d->SetPhase(PHASE_LOGIN); #endif // #ifdef _IMPROVED_PACKET_ENCRYPTION_ } } else d->HandshakeProcess(p->dwTime, p->lDelta, true); } }
void CPVP::Packet(bool bDelete) { if (!m_players[0].dwVID || !m_players[1].dwVID) { if (bDelete) sys_err("null vid when removing %u %u", m_players[0].dwVID, m_players[0].dwVID); return; } TPacketGCPVP pack; pack.bHeader = HEADER_GC_PVP; if (bDelete) { pack.bMode = PVP_MODE_NONE; pack.dwVIDSrc = m_players[0].dwVID; pack.dwVIDDst = m_players[1].dwVID; } else if (IsFight()) { pack.bMode = PVP_MODE_FIGHT; pack.dwVIDSrc = m_players[0].dwVID; pack.dwVIDDst = m_players[1].dwVID; } else { pack.bMode = m_bRevenge ? PVP_MODE_REVENGE : PVP_MODE_AGREE; if (m_players[0].bAgree) { pack.dwVIDSrc = m_players[0].dwVID; pack.dwVIDDst = m_players[1].dwVID; } else { pack.dwVIDSrc = m_players[1].dwVID; pack.dwVIDDst = m_players[0].dwVID; } } const DESC_MANAGER::DESC_SET & c_rSet = DESC_MANAGER::instance().GetClientSet(); DESC_MANAGER::DESC_SET::const_iterator it = c_rSet.begin(); while (it != c_rSet.end()) { LPDESC d = *it++; if (d->IsPhase(PHASE_GAME) || d->IsPhase(PHASE_DEAD)) d->Packet(&pack, sizeof(pack)); } }
void CInputUDP::Handshake(LPDESC pDesc, const char * c_pData) { TPacketCGHandshake * pInfo = (TPacketCGHandshake *) c_pData; if (pDesc->GetHandshake() == pInfo->dwHandshake) { sys_log(0, "UDP: Grant %s:%d", inet_ntoa(m_SockAddr.sin_addr), m_SockAddr.sin_port); pDesc->UDPGrant(m_SockAddr); return; } else sys_log(0, "UDP: Handshake differs %s", pDesc->GetHostName()); }
void CManager::SendLandList(LPDESC d, long lMapIndex) { TLandPacketElement e; TEMP_BUFFER buf; WORD wCount = 0; itertype(m_map_pkLand) it = m_map_pkLand.begin(); while (it != m_map_pkLand.end()) { CLand * pkLand = (it++)->second; const TLand & r = pkLand->GetData(); if (r.lMapIndex != lMapIndex) continue; // LPCHARACTER ch = d->GetCharacter(); if (ch) { CGuild *guild = CGuildManager::instance().FindGuild(r.dwGuildID); ch->SendGuildName(guild); } // e.dwID = r.dwID; e.x = r.x; e.y = r.y; e.width = r.width; e.height = r.height; e.dwGuildID = r.dwGuildID; buf.write(&e, sizeof(TLandPacketElement)); ++wCount; } sys_log(0, "SendLandList map %d count %u elem_size: %d", lMapIndex, wCount, buf.size()); if (wCount != 0) { TPacketGCLandList p; p.header = HEADER_GC_LAND_LIST; p.size = sizeof(TPacketGCLandList) + buf.size(); d->BufferedPacket(&p, sizeof(TPacketGCLandList)); d->Packet(buf.read_peek(), buf.size()); } }
void CInputAuth::PasspodAnswer(LPDESC d, const char * c_pData) { if (!g_bAuthServer) { sys_err ("CInputAuth class is not for game server. IP %s might be a hacker.", inet_ntoa(d->GetAddr().sin_addr)); d->DelayedDisconnect(5); return; } TPacketCGPasspod * packet = (TPacketCGPasspod*)c_pData; RequestConfirmPasspod Confirm; memcpy(Confirm.passpod, packet->szAnswer, MAX_PASSPOD + 1); memcpy(Confirm.login, d->GetAccountTable().login, LOGIN_MAX_LEN + 1); if (!d->GetAccountTable().id) { sys_err("HEADER_CG_PASSPOD_ANSWER received to desc with no account table binded"); return; } int ret_code = 1; sys_log(0, "Passpod start %s %s", d->GetAccountTable().login, packet->szAnswer); ret_code = CPasspod::instance().ConfirmPasspod(d->GetAccountTable().login, packet->szAnswer); if (ret_code != 0) { sys_log(0, "PASSPOD: wrong answer: %s ret_code %d", d->GetAccountTable().login, ret_code); LoginFailure(d, ERR_MESSAGE[ret_code]); if (!d->CheckMatrixTryCount()) { LoginFailure(d, "QUIT"); d->SetPhase(PHASE_CLOSE); } } else { sys_log(0, "PASSPOD: success: %s", d->GetAccountTable().login); DBManager::instance().SendAuthLogin(d); } // g_PasspodDesc->DBPacket(HEADER_GP_CONFIRM_PASSPOD, 0, &Confirm, sizeof(Confirm)); // sys_log(0, "PASSPOD %s %d", Confirm.login, Confirm.passpod); }
void CParty::SendParameter(LPCHARACTER ch) { TPacketGCPartyParameter p; p.bHeader = HEADER_GC_PARTY_PARAMETER; p.bDistributeMode = m_iExpDistributionMode; LPDESC d = ch->GetDesc(); if (d) { d->Packet(&p, sizeof(TPacketGCPartyParameter)); } }
static void __proc_teen_notice(char *login, int hour) { LPDESC desc = DESC_MANAGER::instance().FindByLoginName(login); if (NULL==desc) return; LPCHARACTER ch = desc->GetCharacter(); if (NULL==ch) return; switch (hour) { case 0: { SET_OVER_TIME(ch, OT_NONE); return; } break; case 1: case 2: { ch->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("당신의 누적 온라인 시간이 이미 %d시간이 지났습니다."), hour); SET_OVER_TIME(ch, OT_NONE); } break; case 3: { ch->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("당신의 누적 온라인 시간이 이미 %d시간이 되었습니다,"), hour); ch->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("조속히 접속을 종료하신 후 건강을 위해 휴식을 취해주시기바랍니다.")); SET_OVER_TIME(ch, OT_3HOUR); } break; case 4: { ch->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("당신은 이미 게임 피로 상태에 들어섰으며,")); ch->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("게임 내의 수익이 정상치의 50%로 하향됩니다.")); ch->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("당신의 건강을 위해 조속히 접속을 종료하시고")); ch->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("휴식 및 학업에 열중해주십시오.")); SET_OVER_TIME(ch, OT_3HOUR); } break; default: { ch->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("당신은 이미 온전하지 못한 게임 시간에 들어섰습니다.")); ch->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("건강을 위해 조속히 접속을 종료하신 후 휴식을 취해주십시오,")); ch->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("그렇지 않으면 건강 상에 피해를 입을 수 있으며 게임 내의 수치는 0이 됩니다.")); ch->ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("누적 오프라인 시간이 5시간이 되면 정상으로 돌아옵니다.")); SET_OVER_TIME(ch, OT_5HOUR); } break; } }
LPDESC DESC_MANAGER::AcceptDesc(LPFDWATCH fdw, socket_t s) { socket_t desc; LPDESC newd; static struct sockaddr_in peer; static char host[MAX_HOST_LENGTH + 1]; if ((desc = socket_accept(s, &peer)) == -1) return NULL; strlcpy(host, inet_ntoa(peer.sin_addr), sizeof(host)); if (g_bAuthServer) { if (IsBanIP(peer.sin_addr)) { sys_log(0, "connection from %s was banned.", host); socket_close(desc); return NULL; } } if (!IsValidIP(admin_ip, host)) // admin_ip 에 등록된 IP 는 최대 사용자 수에 구애받지 않는다. { if (m_iSocketsConnected >= MAX_ALLOW_USER) { sys_err("max connection reached. MAX_ALLOW_USER = %d", MAX_ALLOW_USER); socket_close(desc); return NULL; } } newd = M2_NEW DESC; crc_t handshake = CreateHandshake(); if (!newd->Setup(fdw, desc, peer, ++m_iHandleCount, handshake)) { socket_close(desc); M2_DELETE(newd); return NULL; } m_map_handshake.insert(DESC_HANDSHAKE_MAP::value_type(handshake, newd)); m_map_handle.insert(DESC_HANDLE_MAP::value_type(newd->GetHandle(), newd)); m_set_pkDesc.insert(newd); ++m_iSocketsConnected; return (newd); }
void CItem::EncodeRemovePacket(LPENTITY ent) { LPDESC d; if (!(d = ent->GetDesc())) return; struct packet_item_ground_del pack; pack.bHeader = HEADER_GC_ITEM_GROUND_DEL; pack.dwVID = m_dwVID; d->Packet(&pack, sizeof(pack)); sys_log(2, "Item::EncodeRemovePacket %s to %s", GetName(), ((LPCHARACTER) ent)->GetName()); }
int CInputAuth::Analyze(LPDESC d, BYTE bHeader, const char * c_pData) { if (!g_bAuthServer) { sys_err ("CInputAuth class is not for game server. IP %s might be a hacker.", inet_ntoa(d->GetAddr().sin_addr)); d->DelayedDisconnect(5); return 0; } int iExtraLen = 0; if (test_server) sys_log(0, " InputAuth Analyze Header[%d] ", bHeader); switch (bHeader) { case HEADER_CG_PONG: Pong(d); break; case HEADER_CG_LOGIN3: Login(d, c_pData); break; //2012.07.19 OpenID : 김용욱 case HEADER_CG_LOGIN5_OPENID: if (openid_server) LoginOpenID(d, c_pData); else sys_err("HEADER_CG_LOGIN5_OPENID : wrong client access"); break; case HEADER_CG_PASSPOD_ANSWER: PasspodAnswer(d, c_pData); break; case HEADER_CG_HANDSHAKE: break; default: sys_err("This phase does not handle this header %d (0x%x)(phase: AUTH)", bHeader, bHeader); break; } return iExtraLen; }
void CInputProcessor::Pong(LPDESC d) { d->SetPong(true); #ifdef ENABLE_LIMIT_TIME #endif }
void SendTargetDeletePacket(LPDESC d, int iID) { TPacketGCTargetDelete pck; pck.bHeader = HEADER_GC_TARGET_DELETE; pck.lID = iID; d->Packet(&pck, sizeof(TPacketGCTargetDelete)); }
void CObject::EncodeRemovePacket(LPENTITY entity) { LPDESC d; if (!(d = entity->GetDesc())) return; sys_log(0, "ObjectRemovePacket vid %u", m_dwVID); TPacketGCCharacterDelete pack; pack.header = HEADER_GC_CHARACTER_DEL; pack.id = m_dwVID; d->Packet(&pack, sizeof(TPacketGCCharacterDelete)); }
void CWarMap::SendWarPacket(LPDESC d) { TPacketGCGuild pack; TPacketGCGuildWar pack2; pack.header = HEADER_GC_GUILD; pack.subheader = GUILD_SUBHEADER_GC_WAR; pack.size = sizeof(pack) + sizeof(pack2); pack2.dwGuildSelf = m_TeamData[0].dwID; pack2.dwGuildOpp = m_TeamData[1].dwID; pack2.bType = CGuildManager::instance().TouchGuild(m_TeamData[0].dwID)->GetGuildWarType(m_TeamData[1].dwID); pack2.bWarState = CGuildManager::instance().TouchGuild(m_TeamData[0].dwID)->GetGuildWarState(m_TeamData[1].dwID); d->BufferedPacket(&pack, sizeof(pack)); d->Packet(&pack2, sizeof(pack2)); }
static void __input_teen(BYTE header, WORD desc_num, char *body) { switch (header) { case HEADER_TG_FORCE_LOGOUT: { char *data = body; char login[LOGIN_MAX_LEN+1] = {0}; memcpy(login, data, LOGIN_MAX_LEN); data += LOGIN_MAX_LEN; LPDESC d = DESC_MANAGER::instance().FindByLoginName(login); if (NULL==d) return; d->SetPhase(PHASE_CLOSE); } break; case HEADER_TG_TEEN_NOTICE: { char *data = body; char login[LOGIN_MAX_LEN+1] = {0}; memcpy(login, data, LOGIN_MAX_LEN); data += LOGIN_MAX_LEN; int hour = decode_4bytes(data); data += 4; __proc_teen_notice(login, hour); } break; case HEADER_TG_LOGIN_NOTICE: { char *data = body; char login[LOGIN_MAX_LEN+1] = {0}; memcpy(login, data, LOGIN_MAX_LEN); data += LOGIN_MAX_LEN; int on_time = decode_4bytes(data); data += 4; int off_time = decode_4bytes(data); data += 4; __proc_login_notice(login, on_time, off_time); } break; } }
void DESC_MANAGER::Destroy() { if (m_bDestroyed) { return; } m_bDestroyed = true; DESC_SET::iterator i = m_set_pkDesc.begin(); while (i != m_set_pkDesc.end()) { LPDESC d = *i; DESC_SET::iterator ci = i; ++i; if (d->GetType() == DESC_TYPE_CONNECTOR) continue; if (d->IsPhase(PHASE_P2P)) continue; DestroyDesc(d, false); m_set_pkDesc.erase(ci); } i = m_set_pkDesc.begin(); while (i != m_set_pkDesc.end()) { LPDESC d = *i; DESC_SET::iterator ci = i; ++i; DestroyDesc(d, false); m_set_pkDesc.erase(ci); } m_set_pkClientDesc.clear(); //m_AccountIDMap.clear(); m_map_loginName.clear(); m_map_handle.clear(); Initialize(); }
void DSManager::SendRefineResultPacket(LPCHARACTER ch, BYTE bSubHeader, const TItemPos& pos) { TPacketGCDragonSoulRefine pack; pack.bSubType = bSubHeader; if (pos.IsValidItemPosition()) { pack.Pos = pos; } LPDESC d = ch->GetDesc(); if (NULL == d) { return ; } else { d->Packet(&pack, sizeof(pack)); } }
void DESC_MANAGER::DestroyDesc(LPDESC d, bool bEraseFromSet) { if (bEraseFromSet) m_set_pkDesc.erase(d); if (d->GetHandshake()) m_map_handshake.erase(d->GetHandshake()); if (d->GetHandle() != 0) m_map_handle.erase(d->GetHandle()); else m_set_pkClientDesc.erase((LPCLIENT_DESC) d); // Explicit call to the virtual function Destroy() d->Destroy(); M2_DELETE(d); --m_iSocketsConnected; }
void SendTargetUpdatePacket(LPDESC d, int iID, int x, int y) { TPacketGCTargetUpdate pck; pck.bHeader = HEADER_GC_TARGET_UPDATE; pck.lID = iID; pck.lX = x; pck.lY = y; d->Packet(&pck, sizeof(TPacketGCTargetUpdate)); sys_log(0, "SendTargetUpdatePacket %d %dx%d", iID, x, y); }
bool CHARACTER::DragonSoul_RefineWindow_Open(LPENTITY pEntity) { if (NULL == m_pointsInstant.m_pDragonSoulRefineWindowOpener) { m_pointsInstant.m_pDragonSoulRefineWindowOpener = pEntity; } TPacketGCDragonSoulRefine PDS; PDS.header = HEADER_GC_DRAGON_SOUL_REFINE; PDS.bSubType = DS_SUB_HEADER_OPEN; LPDESC d = GetDesc(); if (NULL == d) { sys_err ("User(%s)'s DESC is NULL POINT.", GetName()); return false; } d->Packet(&PDS, sizeof(PDS)); return true; }
void LoginFailure(LPDESC d, const char * c_pszStatus) { if (!d) return; TPacketGCLoginFailure failurePacket; failurePacket.header = HEADER_GC_LOGIN_FAILURE; strlcpy(failurePacket.szStatus, c_pszStatus, sizeof(failurePacket.szStatus)); d->Packet(&failurePacket, sizeof(failurePacket)); }
void SendAffectAddPacket(LPDESC d, CAffect * pkAff) { TPacketGCAffectAdd ptoc; ptoc.bHeader = HEADER_GC_AFFECT_ADD; ptoc.elem.dwType = pkAff->dwType; ptoc.elem.bApplyOn = pkAff->bApplyOn; ptoc.elem.lApplyValue = pkAff->lApplyValue; ptoc.elem.dwFlag = pkAff->dwFlag; ptoc.elem.lDuration = pkAff->lDuration; ptoc.elem.lSPCost = pkAff->lSPCost; d->Packet(&ptoc, sizeof(TPacketGCAffectAdd)); }
void CItem::EncodeInsertPacket(LPENTITY ent) { LPDESC d; if (!(d = ent->GetDesc())) return; const PIXEL_POSITION & c_pos = GetXYZ(); struct packet_item_ground_add pack; pack.bHeader = HEADER_GC_ITEM_GROUND_ADD; pack.x = c_pos.x; pack.y = c_pos.y; pack.z = c_pos.z; pack.dwVnum = GetVnum(); pack.dwVID = m_dwVID; //pack.count = m_dwCount; d->Packet(&pack, sizeof(pack)); if (m_pkOwnershipEvent != NULL) { item_event_info * info = dynamic_cast<item_event_info *>(m_pkOwnershipEvent->info); if ( info == NULL ) { sys_err( "CItem::EncodeInsertPacket> <Factor> Null pointer" ); return; } TPacketGCItemOwnership p; p.bHeader = HEADER_GC_ITEM_OWNERSHIP; p.dwVID = m_dwVID; strlcpy(p.szName, info->szOwnerName, sizeof(p.szName)); d->Packet(&p, sizeof(TPacketGCItemOwnership)); } }
void DESC_MANAGER::SendClientPackageCryptKey( LPDESC desc ) { if( !desc ) { return; } TPacketGCHybridCryptKeys packet; { packet.bHeader = HEADER_GC_HYBRIDCRYPT_KEYS; m_pPackageCrypt->GetPackageCryptKeys( &(packet.pDataKeyStream), packet.KeyStreamLen ); } if( packet.KeyStreamLen > 0 ) { if (g_test_server) { // keys를 string으로 남기는 건 문제가 있음. 중간에 NULL 있으면 잘릴테니.. 그래도 혹시 모르니 남김. sys_log(0, "[PackageCryptInfo] send to %s. (keys: %s, len: %d)", desc->GetAccountTable().login, std::string((char*)packet.pDataKeyStream).c_str(), packet.KeyStreamLen); } desc->Packet( packet.GetStreamData(), packet.GetStreamSize() ); } }