bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 instance_id) { char errbuf[MYSQL_ERRMSG_SIZE]; char* query = 0; MYSQL_RES *result; MYSQL_ROW row; int len; //clear out old stuff.. spawn_conditions.clear(); //load spawn conditions SpawnCondition cond; len = MakeAnyLenString(&query, "SELECT id, onchange, value FROM spawn_conditions WHERE zone='%s'", zone_name); if (database.RunQuery(query, len, errbuf, &result)) { safe_delete_array(query); while((row = mysql_fetch_row(result))) { cond.condition_id = atoi(row[0]); cond.value = atoi(row[2]); cond.on_change = (SpawnCondition::OnChange) atoi(row[1]); spawn_conditions[cond.condition_id] = cond; _log(SPAWNS__CONDITIONS, "Loaded spawn condition %d with value %d and on_change %d", cond.condition_id, cond.value, cond.on_change); } mysql_free_result(result); } else { LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query, errbuf); safe_delete_array(query); return false; } //load values len = MakeAnyLenString(&query, "SELECT id, value FROM spawn_condition_values WHERE zone='%s' and instance_id=%u", zone_name, instance_id); if (database.RunQuery(query, len, errbuf, &result)) { safe_delete_array(query); while((row = mysql_fetch_row(result))) { std::map<uint16, SpawnCondition>::iterator iter = spawn_conditions.find(atoi(row[0])); if(iter != spawn_conditions.end()) { iter->second.value = atoi(row[1]); } } mysql_free_result(result); } else { LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query, errbuf); safe_delete_array(query); spawn_conditions.clear(); return false; } //load spawn events SpawnEvent event; len = MakeAnyLenString(&query, "SELECT id,cond_id,period,next_minute,next_hour,next_day,next_month,next_year,enabled,action,argument " "FROM spawn_events WHERE zone='%s'", zone_name); if (database.RunQuery(query, len, errbuf, &result)) { safe_delete_array(query); while((row = mysql_fetch_row(result))) { event.id = atoi(row[0]); event.condition_id = atoi(row[1]); event.period = atoi(row[2]); if(event.period == 0) { LogFile->write(EQEMuLog::Error, "Refusing to load spawn event #%d because it has a period of 0\n", event.id); continue; } event.next.minute = atoi(row[3]); event.next.hour = atoi(row[4]); event.next.day = atoi(row[5]); event.next.month = atoi(row[6]); event.next.year = atoi(row[7]); event.enabled = atoi(row[8])==0?false:true; event.action = (SpawnEvent::Action) atoi(row[9]); event.argument = atoi(row[10]); spawn_events.push_back(event); _log(SPAWNS__CONDITIONS, "Loaded %s spawn event %d on condition %d with period %d, action %d, argument %d", event.enabled?"enabled":"disabled", event.id, event.condition_id, event.period, event.action, event.argument); } mysql_free_result(result); } else { LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions events query '%s': %s", query, errbuf); safe_delete_array(query); return false; } //now we need to catch up on events that happened while we were away //and use them to alter just the condition variables. //each spawn2 will then use its correct condition value when //it decides what to do. This essentially forces a 'depop' action //on spawn points which are turned off, and a 'repop' action on //spawn points which get turned on. Im too lazy to figure out a //better solution, and I just dont care thats much. //get our current time TimeOfDay_Struct tod; zone->zone_time.getEQTimeOfDay(&tod); std::vector<SpawnEvent>::iterator cur,end; cur = spawn_events.begin(); end = spawn_events.end(); bool ran; for(; cur != end; cur++) { SpawnEvent &cevent = *cur; if(!cevent.enabled) continue; //watch for special case of all 0s, which means to reset next to now if(cevent.next.year == 0 && cevent.next.month == 0 && cevent.next.day == 0 && cevent.next.hour == 0 && cevent.next.minute == 0) { _log(SPAWNS__CONDITIONS, "Initial next trigger time set for spawn event %d", cevent.id); memcpy(&cevent.next, &tod, sizeof(cevent.next)); //add one period EQTime::AddMinutes(cevent.period, &cevent.next); //save it in the db. UpdateDBEvent(cevent); continue; //were done with this event. } ran = false; while(EQTime::IsTimeBefore(&tod, &cevent.next)) { _log(SPAWNS__CONDITIONS, "Catch up triggering on event %d", cevent.id); //this event has been triggered. //execute the event ExecEvent(cevent, false); //add the period of the event to the trigger time EQTime::AddMinutes(cevent.period, &cevent.next); ran = true; } //only write it out if the event actually ran if(ran) { //save the event in the DB UpdateDBEvent(cevent); } } //now our event timers are all up to date, find our closest event. FindNearestEvent(); return(true); }
// Load the equipmentset from the DB. Might be worthwhile to load these into // shared memory at some point due to the number of queries needed to load a // nested set. bool ZoneDatabase::GetBasePetItems(int32 equipmentset, uint32 *items) { if (equipmentset < 0 || items == nullptr) return false; // Equipment sets can be nested. We start with the top-most one and // add all items in it to the items array. Referenced equipmentsets // are loaded after that, up to a max depth of 5. (Arbitrary limit // so we don't go into an endless loop if the DB data is cyclic for // some reason.) // A slot will only get an item put in it if it is empty. That way // an equipmentset can overload a slot for the set(s) it includes. char errbuf[MYSQL_ERRMSG_SIZE]; char *query = 0; uint32 querylen = 0; MYSQL_RES *result; MYSQL_ROW row; int depth = 0; int32 curset = equipmentset; int32 nextset = -1; uint32 slot; // outline: // get equipmentset from DB. (Mainly check if we exist and get the // nested ID) // query pets_equipmentset_entries with the set_id and loop over // all of the result rows. Check if we have something in the slot // already. If no, add the item id to the equipment array. while (curset >= 0 && depth < 5) { if (RunQuery(query, MakeAnyLenString(&query, "SELECT nested_set FROM pets_equipmentset WHERE set_id='%s'", curset), errbuf, &result)) { safe_delete_array(query); if (mysql_num_rows(result) == 1) { row = mysql_fetch_row(result); nextset = atoi(row[0]); mysql_free_result(result); if (RunQuery(query, MakeAnyLenString(&query, "SELECT slot, item_id FROM pets_equipmentset_entries WHERE set_id='%s'", curset), errbuf, &result)) { safe_delete_array(query); while ((row = mysql_fetch_row(result))) { slot = atoi(row[0]); if (slot >= MAX_WORN_INVENTORY) continue; if (items[slot] == 0) items[slot] = atoi(row[1]); } mysql_free_result(result); } else { LogFile->write(EQEMuLog::Error, "Error in GetBasePetItems query '%s': %s", query, errbuf); safe_delete_array(query); } curset = nextset; depth++; } else { // invalid set reference, it doesn't exist LogFile->write(EQEMuLog::Error, "Error in GetBasePetItems equipment set '%d' does not exist", curset); mysql_free_result(result); return false; } } else { LogFile->write(EQEMuLog::Error, "Error in GetBasePetItems query '%s': %s", query, errbuf); safe_delete_array(query); return false; } } // end while return true; }
void CWndPartyCtrl::OnDraw( C2DRender* p2DRender ) { if( NULL == g_pPlayer ) return; CPoint pt( 3, 3 ); // pt.y -= ( m_nFontHeight + 3 ) * m_wndScrollBar.GetScrollPos(); #if __VER < 11 // __CSC_VER11_4 CWndMessenger* pWndMessenger = (CWndMessenger*)GetWndBase( APP_MESSENGER_ ); #endif //__CSC_VER11_4 CWndWorld* pWndWorld = (CWndWorld*)g_WndMng.GetWndBase( APP_WORLD ); int nMax = g_Party.m_nSizeofMember; // 눈에 보이는 갯수가 페이지라인수 보다 크면 보이는 갯수를 페이지라인수로 조정 if( nMax - m_wndScrollBar.GetScrollPos() > m_wndScrollBar.GetScrollPage() ) nMax = m_wndScrollBar.GetScrollPage() + m_wndScrollBar.GetScrollPos(); if( nMax < m_wndScrollBar.GetScrollPos() ) nMax = 0; TEXTUREVERTEX2* pVertex = new TEXTUREVERTEX2[ 6 * 2 * nMax ]; TEXTUREVERTEX2* pVertices = pVertex; for( int i = m_wndScrollBar.GetScrollPos(); i < nMax; i++ ) { CMover* pObjMember = prj.GetUserByID( g_Party.m_aMember[i].m_uPlayerId ); CString strMember; #if __VER >= 11 // __SYS_PLAYER_DATA PlayerData* pPlayerData = CPlayerDataCenter::GetInstance()->GetPlayerData( g_Party.m_aMember[i].m_uPlayerId ); int nJob = pPlayerData->data.nJob; int nSex = pPlayerData->data.nSex; #else // __SYS_PLAYER_DATA int nJob = g_Party.m_aMember[ i ].m_nJob; int nSex = g_Party.m_aMember[ i ].m_nSex; #endif // __SYS_PLAYER_DATA // 상태에 따라 색 변경 DWORD dwColor = 0xff000000; if( IsValidObj(pObjMember) ) { if( pObjMember->GetHitPoint() == 0 ) dwColor = 0xffff0000; // 죽은놈 else if( ((FLOAT)pObjMember->GetHitPoint()) / ((FLOAT)pObjMember->GetMaxHitPoint()) < 0.1f ) dwColor = 0xffffff00; // HP 10% 이하인 놈 strMember.Format( "%d %s", pObjMember->GetLevel(), pObjMember->GetName() ); } else { dwColor = 0xff878787; // 디폴트는 주위에 없는 놈 if( g_Party.m_aMember[ i ].m_bRemove ) dwColor = 0xff000000; // 서버에 없는 놈 #if __VER >= 11 // __SYS_PLAYER_DATA strMember.Format( "?? %s", pPlayerData->szPlayer ); #else // __SYS_PLAYER_DATA strMember.Format( "?? %s", g_Party.m_aMember[ i ].m_szName ); #endif // __SYS_PLAYER_DATA } if( i == m_nCurSelect ) dwColor = 0xff6060ff; int x = 0, nWidth = m_rectClient.Width() - 10;// - 1; CRect rect( x, pt.y, x + nWidth, pt.y + m_nFontHeight ); rect.SetRect( x + 20, pt.y + 18, x + nWidth - 10, pt.y + 30 ); nWidth = pObjMember ? pObjMember->GetHitPointPercent( rect.Width() ) : 0; CRect rectTemp = rect; rectTemp.right = rectTemp.left + nWidth; if( rect.right < rectTemp.right ) rectTemp.right = rect.right; m_pTheme->RenderGauge( p2DRender, &rect, 0xffffffff, m_pVBGauge, &m_texGauEmptyNormal ); m_pTheme->RenderGauge( p2DRender, &rectTemp, 0x64ff0000, m_pVBGauge, &m_texGauFillNormal ); rect.SetRect( x + 3, pt.y, x + 3 + 32, pt.y + 6 + 32 ); p2DRender->TextOut( x + 20, pt.y + 3, strMember, dwColor ); if( MAX_EXPERT <= nJob ) { #if __VER >= 10 // __LEGEND if( MAX_PROFESSIONAL <= nJob && nJob < MAX_MASTER ) pWndWorld->m_texMsgIcon.MakeVertex( p2DRender, CPoint( 2, pt.y ), ( 70 + nJob - 16 ) + ( 8 * nSex ), &pVertices, 0xffffffff ); else if( MAX_MASTER <= nJob ) pWndWorld->m_texMsgIcon.MakeVertex( p2DRender, CPoint( 2, pt.y ), ( 70 + nJob - 24 ) + ( 8 * nSex ), &pVertices, 0xffffffff ); else #endif //__LEGEND pWndWorld->m_texMsgIcon.MakeVertex( p2DRender, CPoint( 2, pt.y ), ( 70 + nJob - 6 ) + ( 8 * nSex ), &pVertices, 0xffffffff ); } else { pWndWorld->m_texMsgIcon.MakeVertex( p2DRender, CPoint( 2, pt.y ), 12 + nJob + ( 6 * nSex ), &pVertices, 0xffffffff ); } pt.y += m_nFontHeight + 3; } pWndWorld->m_texMsgIcon.Render( m_pApp->m_pd3dDevice, pVertex, ( (int) pVertices - (int) pVertex ) / sizeof( TEXTUREVERTEX2 ) ); safe_delete_array( pVertex ); }
char *SerializeItem(const ItemInst *inst, int16 slot_id, uint32 *length, uint8 depth) { char *serialization = nullptr; char *instance = nullptr; const char *protection=(const char *)"\\\\\\\\\\"; char *sub_items[10] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; bool stackable=inst->IsStackable(); uint32 merchant_slot=inst->GetMerchantSlot(); int16 charges=inst->GetCharges(); const Item_Struct *item=inst->GetItem(); int i; uint32 sub_length; MakeAnyLenString(&instance, "%i|%i|%i|%i|%i|%i|%i|%i|%i|%i|%i|", stackable ? charges : 0, 0, (merchant_slot==0) ? slot_id : merchant_slot, inst->GetPrice(), (merchant_slot==0) ? 1 : inst->GetMerchantCount(), 0, //merchant_slot, //instance ID, bullshit for now (merchant_slot==0) ? inst->GetSerialNumber() : merchant_slot, 0, (stackable ? ((inst->GetItem()->ItemType == ItemTypePotion) ? 1 : 0) : charges), inst->IsInstNoDrop() ? 1 : 0, 0 ); for(i=0;i<10;i++) { ItemInst *sub=inst->GetItem(i); if (sub) { sub_items[i]=SerializeItem(sub,0,&sub_length,depth+1); } } *length=MakeAnyLenString(&serialization, "%.*s%s" // For leading quotes (and protection) if a subitem; "%s" // Instance data "%.*s\"" // Quotes (and protection, if needed) around static data "%i" // item->ItemClass so we can do |%s instead of %s| #define I(field) "|%i" #define C(field) "|%s" #define S(field) "|%s" #define F(field) "|%f" #include "Titanium_itemfields.h" "%.*s\"" // Quotes (and protection, if needed) around static data "|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s" // Sub items "%.*s%s" // For trailing quotes (and protection) if a subitem; ,depth ? depth-1 : 0,protection,(depth) ? "\"" : "" ,instance ,depth,protection ,item->ItemClass #define I(field) ,item->field #define C(field) ,field #define S(field) ,item->field #define F(field) ,item->field #include "Titanium_itemfields.h" ,depth,protection ,sub_items[0] ? sub_items[0] : "" ,sub_items[1] ? sub_items[1] : "" ,sub_items[2] ? sub_items[2] : "" ,sub_items[3] ? sub_items[3] : "" ,sub_items[4] ? sub_items[4] : "" ,sub_items[5] ? sub_items[5] : "" ,sub_items[6] ? sub_items[6] : "" ,sub_items[7] ? sub_items[7] : "" ,sub_items[8] ? sub_items[8] : "" ,sub_items[9] ? sub_items[9] : "" ,(depth) ? depth-1 : 0,protection,(depth) ? "\"" : "" ); for(i=0;i<10;i++) { if (sub_items[i]) safe_delete_array(sub_items[i]); } safe_delete_array(instance); return serialization; }
void WorldServer::ProcessMessage(uint16 opcode, EQ::Net::Packet &p) { ServerPacket tpack(opcode, p); ServerPacket *pack = &tpack; Log(Logs::Detail, Logs::UCS_Server, "Received Opcode: %4X", opcode); switch (opcode) { case 0: { break; } case ServerOP_KeepAlive: { break; } case ServerOP_UCSMessage: { char *Buffer = (char *)pack->pBuffer; auto From = new char[strlen(Buffer) + 1]; VARSTRUCT_DECODE_STRING(From, Buffer); std::string Message = Buffer; Log(Logs::Detail, Logs::UCS_Server, "Player: %s, Sent Message: %s", From, Message.c_str()); Client *c = g_Clientlist->FindCharacter(From); safe_delete_array(From); if (Message.length() < 2) break; if (!c) { Log(Logs::Detail, Logs::UCS_Server, "Client not found."); break; } if (Message[0] == ';') { std::string new_message; switch (c->GetClientVersion()) { case EQEmu::versions::ClientVersion::Titanium: Client45ToServerSayLink(new_message, Message.substr(1, std::string::npos)); break; case EQEmu::versions::ClientVersion::SoF: case EQEmu::versions::ClientVersion::SoD: case EQEmu::versions::ClientVersion::UF: Client50ToServerSayLink(new_message, Message.substr(1, std::string::npos)); break; case EQEmu::versions::ClientVersion::RoF: Client55ToServerSayLink(new_message, Message.substr(1, std::string::npos)); break; case EQEmu::versions::ClientVersion::RoF2: default: new_message = Message.substr(1, std::string::npos); break; } c->SendChannelMessageByNumber(new_message); } else if (Message[0] == '[') { g_Clientlist->ProcessOPMailCommand(c, Message.substr(1, std::string::npos)); } break; } case ServerOP_UCSMailMessage: { ServerMailMessageHeader_Struct *mail = (ServerMailMessageHeader_Struct*)pack->pBuffer; database.SendMail(std::string("SOE.EQ.") + Config->ShortName + std::string(".") + std::string(mail->to), std::string(mail->from), mail->subject, mail->message, std::string()); break; } } }
bool TCPConnection::SendData(bool &sent_something, char* errbuf) { if (errbuf) errbuf[0] = 0; /************ Get first send packet on queue and send it! ************/ uchar* data = 0; int32 size = 0; int status = 0; if (ServerSendQueuePop(&data, &size)) { #ifdef _WINDOWS status = send(connection_socket, (const char *) data, size, 0); #else status = send(connection_socket, data, size, MSG_NOSIGNAL); if(errno==EPIPE) status = SOCKET_ERROR; #endif if (status >= 1) { #if TCPN_LOG_RAW_DATA_OUT >= 1 struct in_addr in; in.s_addr = GetrIP(); CoutTimestamp(true); std::cout << ": Wrote " << status << " bytes to network. " << inet_ntoa(in) << ":" << GetrPort(); std::cout << std::endl; #if TCPN_LOG_RAW_DATA_OUT == 2 int32 tmp = status; if (tmp > 32) tmp = 32; DumpPacket(data, status); #elif TCPN_LOG_RAW_DATA_OUT >= 3 DumpPacket(data, status); #endif #endif sent_something = true; if (status < (signed)size) { #if TCPN_LOG_RAW_DATA_OUT >= 1 struct in_addr in; in.s_addr = GetrIP(); CoutTimestamp(true); std::cout << ": Pushed " << (size - status) << " bytes back onto the send queue. " << inet_ntoa(in) << ":" << GetrPort(); std::cout << std::endl; #endif // If there's network congestion, the number of bytes sent can be less than // what we tried to give it... Push the extra back on the queue for later ServerSendQueuePushFront(&data[status], size - status); } else if (status > (signed)size) { return false; } // else if (status == size) {} } else { ServerSendQueuePushFront(data, size); } safe_delete_array(data); if (status == SOCKET_ERROR) { #ifdef _WINDOWS if (WSAGetLastError() != WSAEWOULDBLOCK) #else if (errno != EWOULDBLOCK) #endif { if (errbuf) { #ifdef _WINDOWS snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::SendData(): send(): Errorcode: %i", WSAGetLastError()); #else snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::SendData(): send(): Errorcode: %s", strerror(errno)); #endif } //if we get an error while disconnecting, just jump to disconnected MState.lock(); if(pState == TCPS_Disconnecting) pState = TCPS_Disconnected; MState.unlock(); return false; } } } return true; }
/* C28182 Dereferencing a copy of a null pointer Dereferencing NULL pointer. 'recvbuf' contains the same NULL value as 'size' did. common emu_tcp_connection.cpp 537 'size' is equal to 7 531 Enter this branch, (assume 'recvbuf!=0') 534 Enter this loop, (assume '((recvbuf_used-base))>=size') 536 Skip this branch, (assume 'size>=524288' is false) 540 Skip this branch, (assume '((recvbuf_used-base))>=size' is false) 549 Continue this loop, (assume '((recvbuf_used-base))>=size') 536 'size' is dereferenced, but may still be NULL 537 */ bool EmuTCPConnection::ProcessReceivedDataAsPackets(char* errbuf) { if (errbuf) errbuf[0] = 0; int32 base = 0; int32 size = 7; uchar* buffer; ServerPacket* pack = 0; while ((recvbuf_used - base) >= size) { EmuTCPNetPacket_Struct* tnps = (EmuTCPNetPacket_Struct*) &recvbuf[base]; buffer = tnps->buffer; size = tnps->size; if (size >= MaxTCPReceiveBuffferSize) { #if TCPN_DEBUG_Memory >= 1 std::cout << "TCPConnection[" << GetID() << "]::ProcessReceivedDataAsPackets(): size[" << size << "] >= MaxTCPReceiveBuffferSize" << std::endl; DumpPacket(&recvbuf[base], 16); #endif if (errbuf) snprintf(errbuf, TCPConnection_ErrorBufferSize, "EmuTCPConnection::ProcessReceivedDataAsPackets(): size >= MaxTCPReceiveBuffferSize"); return false; } if ((recvbuf_used - base) >= size) { // ok, we got enough data to make this packet! pack = new ServerPacket; pack->size = size - sizeof(EmuTCPNetPacket_Struct); // read headers pack->opcode = tnps->opcode; if (tnps->flags.compressed) { pack->compressed = true; pack->InflatedSize = *((int32*)buffer); pack->size -= 4; buffer += 4; } if (tnps->flags.destination) { pack->destination = *((int32*)buffer); pack->size -= 4; buffer += 4; } // end read headers if (pack->size > 0) { if (tnps->flags.compressed) { // Lets decompress the packet here pack->compressed = false; pack->pBuffer = new uchar[pack->InflatedSize]; pack->size = InflatePacket(buffer, pack->size, pack->pBuffer, pack->InflatedSize); } else { pack->pBuffer = new uchar[pack->size]; memcpy(pack->pBuffer, buffer, pack->size); } } if (pack->opcode == 0) { if (pack->size) { #if TCPN_DEBUG >= 2 std::cout << "Received TCP Network layer packet" << std::endl; #endif ProcessNetworkLayerPacket(pack); } #if TCPN_DEBUG >= 5 else { std::cout << "Received TCP keepalive packet. (opcode=0)" << std::endl; } #endif // keepalive, no need to process safe_delete(pack); } else { #if TCPN_LOG_PACKETS >= 1 if (pack && pack->opcode != 0) { struct in_addr in; in.s_addr = GetrIP(); CoutTimestamp(true); std::cout << ": Logging incoming TCP packet. OPCode: 0x" << std::hex << std::setw(4) << std::setfill('0') << pack->opcode << std::dec << ", size: " << std::setw(5) << std::setfill(' ') << pack->size << " " << inet_ntoa(in) << ":" << GetrPort() << std::endl; #if TCPN_LOG_PACKETS == 2 if (pack->size >= 32) DumpPacket(pack->pBuffer, 32); else DumpPacket(pack); #endif #if TCPN_LOG_PACKETS >= 3 DumpPacket(pack); #endif } #endif if (RelayServer && Server && pack->destination) { EmuTCPConnection* con = Server->FindConnection(pack->destination); if (!con) { #if TCPN_DEBUG >= 1 std::cout << "Error relaying packet: con = 0" << std::endl; #endif safe_delete(pack); } else con->OutQueuePush(pack); } else OutQueuePush(pack); } base += size; size = 7; } } if (base != 0) { if (base >= recvbuf_used) { safe_delete_array(recvbuf); } else { uchar* tmpbuf = new uchar[recvbuf_size - base]; memcpy(tmpbuf, &recvbuf[base], recvbuf_used - base); safe_delete_array(recvbuf); recvbuf = tmpbuf; recvbuf_used -= base; recvbuf_size -= base; } } return true; }
bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc) { char errbuf[MYSQL_ERRMSG_SIZE]; char *query = 0; MYSQL_RES *result; MYSQL_ROW row = 0; int rows; if(!in_pp || !in_cc) return false; in_pp->x = in_pp->y = in_pp->z = in_pp->heading = in_pp->zone_id = 0; in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = 0; if(!RunQuery(query, MakeAnyLenString(&query, "SELECT x,y,z,heading,zone_id,bind_id FROM start_zones WHERE player_choice=%i AND player_class=%i " "AND player_deity=%i AND player_race=%i", in_cc->start_zone, in_cc->class_, in_cc->deity, in_cc->race), errbuf, &result)) { LogFile->write(EQEMuLog::Error, "Start zone query failed: %s : %s\n", query, errbuf); safe_delete_array(query); return false; } LogFile->write(EQEMuLog::Status, "Start zone query: %s\n", query); safe_delete_array(query); if((rows = mysql_num_rows(result)) > 0) row = mysql_fetch_row(result); if(row) { LogFile->write(EQEMuLog::Status, "Found starting location in start_zones"); in_pp->x = atof(row[0]); in_pp->y = atof(row[1]); in_pp->z = atof(row[2]); in_pp->heading = atof(row[3]); in_pp->zone_id = atoi(row[4]); in_pp->binds[0].zoneId = atoi(row[5]); } else { printf("No start_zones entry in database, using defaults\n"); switch(in_cc->start_zone) { case 0: { in_pp->zone_id = 24; // erudnext in_pp->binds[0].zoneId = 38; // tox break; } case 1: { in_pp->zone_id =2; // qeynos2 in_pp->binds[0].zoneId = 2; // qeynos2 break; } case 2: { in_pp->zone_id =29; // halas in_pp->binds[0].zoneId = 30; // everfrost break; } case 3: { in_pp->zone_id =19; // rivervale in_pp->binds[0].zoneId = 20; // kithicor break; } case 4: { in_pp->zone_id =9; // freportw in_pp->binds[0].zoneId = 9; // freportw break; } case 5: { in_pp->zone_id =40; // neriaka in_pp->binds[0].zoneId = 25; // nektulos break; } case 6: { in_pp->zone_id =52; // gukta in_pp->binds[0].zoneId = 46; // innothule break; } case 7: { in_pp->zone_id =49; // oggok in_pp->binds[0].zoneId = 47; // feerrott break; } case 8: { in_pp->zone_id =60; // kaladima in_pp->binds[0].zoneId = 68; // butcher break; } case 9: { in_pp->zone_id =54; // gfaydark in_pp->binds[0].zoneId = 54; // gfaydark break; } case 10: { in_pp->zone_id =61; // felwithea in_pp->binds[0].zoneId = 54; // gfaydark break; } case 11: { in_pp->zone_id =55; // akanon in_pp->binds[0].zoneId = 56; // steamfont break; } case 12: { in_pp->zone_id =82; // cabwest in_pp->binds[0].zoneId = 78; // fieldofbone break; } case 13: { in_pp->zone_id =155; // sharvahl in_pp->binds[0].zoneId = 155; // sharvahl break; } } } if(in_pp->x == 0 && in_pp->y == 0 && in_pp->z == 0) database.GetSafePoints(in_pp->zone_id, 0, &in_pp->x, &in_pp->y, &in_pp->z); if(in_pp->binds[0].x == 0 && in_pp->binds[0].y == 0 && in_pp->binds[0].z == 0) database.GetSafePoints(in_pp->binds[0].zoneId, 0, &in_pp->binds[0].x, &in_pp->binds[0].y, &in_pp->binds[0].z); if(result) mysql_free_result(result); return true; }
// solar: the current stuff is at the bottom of this function void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct* cs) { char errbuf[MYSQL_ERRMSG_SIZE]; char* query = 0; MYSQL_RES *result; MYSQL_ROW row; Inventory *inv; for (int i=0; i<10; i++) { strcpy(cs->name[i], "<none>"); cs->zone[i] = 0; cs->level[i] = 0; cs->tutorial[i] = 0; cs->gohome[i] = 0; } int char_num = 0; unsigned long* lengths; // Populate character info if (RunQuery(query, MakeAnyLenString(&query, "SELECT name,profile,zonename,class,level FROM character_ WHERE account_id=%i order by name limit 10", account_id), errbuf, &result)) { safe_delete_array(query); while ((row = mysql_fetch_row(result))) { lengths = mysql_fetch_lengths(result); //////////// //////////// This is the current one, the other are for converting //////////// if ((lengths[1] == sizeof(PlayerProfile_Struct))) { strcpy(cs->name[char_num], row[0]); PlayerProfile_Struct* pp = (PlayerProfile_Struct*)row[1]; uint8 clas = atoi(row[3]); uint8 lvl = atoi(row[4]); // Character information if(lvl == 0) cs->level[char_num] = pp->level; //no level in DB, trust PP else cs->level[char_num] = lvl; if(clas == 0) cs->class_[char_num] = pp->class_; //no class in DB, trust PP else cs->class_[char_num] = clas; cs->race[char_num] = pp->race; cs->gender[char_num] = pp->gender; cs->deity[char_num] = pp->deity; cs->zone[char_num] = GetZoneID(row[2]); cs->face[char_num] = pp->face; cs->haircolor[char_num] = pp->haircolor; cs->beardcolor[char_num] = pp->beardcolor; cs->eyecolor2[char_num] = pp->eyecolor2; cs->eyecolor1[char_num] = pp->eyecolor1; cs->hairstyle[char_num] = pp->hairstyle; cs->beard[char_num] = pp->beard; cs->drakkin_heritage[char_num] = pp->drakkin_heritage; cs->drakkin_tattoo[char_num] = pp->drakkin_tattoo; cs->drakkin_details[char_num] = pp->drakkin_details; if(RuleB(World, EnableTutorialButton) && (lvl <= RuleI(World, MaxLevelForTutorial))) cs->tutorial[char_num] = 1; if(RuleB(World, EnableReturnHomeButton)) { int now = time(nullptr); if((now - pp->lastlogin) >= RuleI(World, MinOfflineTimeToReturnHome)) cs->gohome[char_num] = 1; } // This part creates home city entries for characters created before the home bind point was tracked. // Do it here because the player profile is already loaded and it's as good a spot as any. This whole block should // probably be removed at some point, when most accounts are safely converted. if(pp->binds[4].zoneId == 0) { bool altered = false; MYSQL_RES *result2; MYSQL_ROW row2; char startzone[50] = {0}; // check for start zone variable (I didn't even know any variables were still being used...) if(database.GetVariable("startzone", startzone, 50)) { uint32 zoneid = database.GetZoneID(startzone); if(zoneid) { pp->binds[4].zoneId = zoneid; GetSafePoints(zoneid, 0, &pp->binds[4].x, &pp->binds[4].y, &pp->binds[4].z); altered = true; } } else { RunQuery(query, MakeAnyLenString(&query, "SELECT zone_id,bind_id,x,y,z FROM start_zones " "WHERE player_class=%i AND player_deity=%i AND player_race=%i", pp->class_, pp->deity, pp->race ), errbuf, &result2 ); safe_delete_array(query); // if there is only one possible start city, set it if(mysql_num_rows(result2) == 1) { row2 = mysql_fetch_row(result2); if(atoi(row2[1]) != 0) { // if a bind_id is specified, make them start there pp->binds[4].zoneId = (uint32)atoi(row2[1]); GetSafePoints(pp->binds[4].zoneId, 0, &pp->binds[4].x, &pp->binds[4].y, &pp->binds[4].z); } else { // otherwise, use the zone and coordinates given pp->binds[4].zoneId = (uint32)atoi(row2[0]); float x = atof(row2[2]); float y = atof(row2[3]); float z = atof(row2[4]); if(x == 0 && y == 0 && z == 0) GetSafePoints(pp->binds[4].zoneId, 0, &x, &y, &z); pp->binds[4].x = x; pp->binds[4].y = y; pp->binds[4].z = z; } altered = true; } mysql_free_result(result2); } // update the player profile if(altered) { uint32 char_id = GetCharacterID(cs->name[char_num]); RunQuery(query,MakeAnyLenString(&query,"SELECT extprofile FROM character_ WHERE id=%i",char_id), errbuf, &result2); safe_delete_array(query); if(result2) { row2 = mysql_fetch_row(result2); ExtendedProfile_Struct* ext = (ExtendedProfile_Struct*)row2[0]; SetPlayerProfile(account_id,char_id,pp,inv,ext, 0, 0, 5); } mysql_free_result(result2); } } // end of "set start zone" block // Character's equipped items // @merth: Haven't done bracer01/bracer02 yet. // Also: this needs a second look after items are a little more solid // NOTE: items don't have a color, players MAY have a tint, if the // use_tint part is set. otherwise use the regular color inv = new Inventory; if(GetInventory(account_id, cs->name[char_num], inv)) { for (uint8 material = 0; material <= 8; material++) { uint32 color; ItemInst *item = inv->GetItem(Inventory::CalcSlotFromMaterial(material)); if(item == 0) continue; cs->equip[char_num][material] = item->GetItem()->Material; if(pp->item_tint[material].rgb.use_tint) // they have a tint (LoY dye) color = pp->item_tint[material].color; else // no tint, use regular item color color = item->GetItem()->Color; cs->cs_colors[char_num][material].color = color; // the weapons are kept elsewhere if ((material==MaterialPrimary) || (material==MaterialSecondary)) { if(strlen(item->GetItem()->IDFile) > 2) { uint32 idfile=atoi(&item->GetItem()->IDFile[2]); if (material==MaterialPrimary) cs->primary[char_num]=idfile; else cs->secondary[char_num]=idfile; } } } } else { printf("Error loading inventory for %s\n", cs->name[char_num]); } safe_delete(inv); if (++char_num > 10) break; } else { std::cout << "Got a bogus character (" << row[0] << ") Ignoring!!!" << std::endl; std::cout << "PP length ="<<lengths[1]<<" but PP should be "<<sizeof(PlayerProfile_Struct) << std::endl; //DeleteCharacter(row[0]); } } mysql_free_result(result); } else { std::cerr << "Error in GetCharSelectInfo query '" << query << "' " << errbuf << std::endl; safe_delete_array(query); return; } return; }
bool Database::SendMail(std::string Recipient, std::string From, std::string Subject, std::string Body, std::string RecipientsString) { int CharacterID; std::string CharacterName; //printf("Database::SendMail(%s, %s, %s)\n", Recipient.c_str(), From.c_str(), Subject.c_str()); std::string::size_type LastPeriod = Recipient.find_last_of("."); if(LastPeriod == std::string::npos) CharacterName = Recipient; else CharacterName = Recipient.substr(LastPeriod+1); CharacterName[0] = toupper(CharacterName[0]); for(unsigned int i = 1; i < CharacterName.length(); i++) CharacterName[i] = tolower(CharacterName[i]); CharacterID = FindCharacter(CharacterName.c_str()); _log(UCS__TRACE, "SendMail: CharacterID for recipient %s is %i", CharacterName.c_str(), CharacterID); if(CharacterID <= 0) return false; char errbuf[MYSQL_ERRMSG_SIZE]; char* query = 0; char *EscSubject = new char[Subject.length() * 2 + 1]; char *EscBody = new char[Body.length() * 2 + 1]; DoEscapeString(EscSubject, Subject.c_str(), Subject.length()); DoEscapeString(EscBody, Body.c_str(), Body.length()); const char *MailQuery="INSERT INTO `mail` (`charid`, `timestamp`, `from`, `subject`, `body`, `to`, `status`) " "VALUES ('%i', %i, '%s', '%s', '%s', '%s', %i)"; uint32 LastMsgID; int Now = time(nullptr); // time returns a 64 bit int on Windows at least, which vsnprintf doesn't like. if(!RunQuery(query, MakeAnyLenString(&query, MailQuery, CharacterID, Now, From.c_str(), EscSubject, EscBody, RecipientsString.c_str(), 1), errbuf, 0, 0, &LastMsgID)) { _log(UCS__ERROR, "SendMail: Query %s failed with error %s", query, errbuf); safe_delete_array(EscSubject); safe_delete_array(EscBody); safe_delete_array(query); return false; } _log(UCS__TRACE, "MessageID %i generated, from %s, to %s", LastMsgID, From.c_str(), Recipient.c_str()); safe_delete_array(EscSubject); safe_delete_array(EscBody); safe_delete_array(query); Client *c = CL->IsCharacterOnline(CharacterName); if(c) { std::string FQN = GetMailPrefix() + From; c->SendNotification(c->GetMailBoxNumber(CharacterName), Subject, FQN, LastMsgID); } MailMessagesSent++; return true; }
Fragment::~Fragment() { safe_delete_array(data); }
void Database::SendHeaders(Client *c) { int UnknownField2 = 25015275; int UnknownField3 = 1; int CharacterID = FindCharacter(c->MailBoxName().c_str()); _log(UCS__TRACE, "Sendheaders for %s, CharID is %i", c->MailBoxName().c_str(), CharacterID); if(CharacterID <= 0) return; char errbuf[MYSQL_ERRMSG_SIZE]; char* query = 0; MYSQL_RES *result; MYSQL_ROW row; if (!RunQuery(query,MakeAnyLenString(&query, "select `msgid`,`timestamp`,`from`,`subject`, `status` from `mail` " "where `charid`=%i", CharacterID),errbuf,&result)){ safe_delete_array(query); return ; } safe_delete_array(query); char Buf[100]; uint32 NumRows = mysql_num_rows(result); int HeaderCountPacketLength = 0; sprintf(Buf, "%i", c->GetMailBoxNumber()); HeaderCountPacketLength += (strlen(Buf) + 1); sprintf(Buf, "%i", UnknownField2); HeaderCountPacketLength += (strlen(Buf) + 1); sprintf(Buf, "%i", UnknownField3); HeaderCountPacketLength += (strlen(Buf) + 1); sprintf(Buf, "%i", NumRows); HeaderCountPacketLength += (strlen(Buf) + 1); EQApplicationPacket *outapp = new EQApplicationPacket(OP_MailHeaderCount, HeaderCountPacketLength); char *PacketBuffer = (char *)outapp->pBuffer; VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, c->GetMailBoxNumber()); VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, UnknownField2); VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, UnknownField3); VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, NumRows); _pkt(UCS__PACKETS, outapp); c->QueuePacket(outapp); safe_delete(outapp); int RowNum = 0; while((row = mysql_fetch_row(result))) { int HeaderPacketLength = 0; sprintf(Buf, "%i", c->GetMailBoxNumber()); HeaderPacketLength = HeaderPacketLength + strlen(Buf) + 1; sprintf(Buf, "%i", UnknownField2); HeaderPacketLength = HeaderPacketLength + strlen(Buf) + 1; sprintf(Buf, "%i", RowNum); HeaderPacketLength = HeaderPacketLength + strlen(Buf) + 1; HeaderPacketLength = HeaderPacketLength + strlen(row[0]) + 1; HeaderPacketLength = HeaderPacketLength + strlen(row[1]) + 1; HeaderPacketLength = HeaderPacketLength + strlen(row[4]) + 1; HeaderPacketLength = HeaderPacketLength + GetMailPrefix().length() + strlen(row[2]) + 1; HeaderPacketLength = HeaderPacketLength + strlen(row[3]) + 1; outapp = new EQApplicationPacket(OP_MailHeader, HeaderPacketLength); PacketBuffer = (char *)outapp->pBuffer; VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, c->GetMailBoxNumber()); VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, UnknownField2); VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, RowNum); VARSTRUCT_ENCODE_STRING(PacketBuffer, row[0]); VARSTRUCT_ENCODE_STRING(PacketBuffer, row[1]); VARSTRUCT_ENCODE_STRING(PacketBuffer, row[4]); VARSTRUCT_ENCODE_STRING(PacketBuffer, GetMailPrefix().c_str()); PacketBuffer--; VARSTRUCT_ENCODE_STRING(PacketBuffer, row[2]); VARSTRUCT_ENCODE_STRING(PacketBuffer, row[3]); _pkt(UCS__PACKETS, outapp); c->QueuePacket(outapp); safe_delete(outapp); RowNum++; } mysql_free_result(result); }
bool TCPConnection::ConnectIP(uint32 in_ip, uint16 in_port, char* errbuf) { if (errbuf) { errbuf[0] = 0; } if (ConnectionType != Outgoing) { // If this code runs, we got serious problems // Crash and burn. return false; } MState.lock(); if (ConnectReady()) { pState = TCPS_Connecting; } else { MState.unlock(); SetAsyncConnect(false); return false; } MState.unlock(); if (!pRunLoop) { pRunLoop = true; #ifdef _WINDOWS _beginthread(TCPConnectionLoop, 0, this); #else pthread_t thread; pthread_create(&thread, nullptr, TCPConnectionLoop, this); #endif } connection_socket = INVALID_SOCKET; struct sockaddr_in server_sin; if ((connection_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET || connection_socket == 0) { #ifdef _WINDOWS if (errbuf) { snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::Connect(): Allocating socket failed. Error: %i", WSAGetLastError()); #else if (errbuf) { snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::Connect(): Allocating socket failed. Error: %s", strerror(errno)); #endif } SetState(TCPS_Ready); SetAsyncConnect(false); return false; } server_sin.sin_family = AF_INET; server_sin.sin_addr.s_addr = in_ip; server_sin.sin_port = htons(in_port); // Establish a connection to the server socket. #ifdef _WINDOWS if (connect(connection_socket, (PSOCKADDR) &server_sin, sizeof (server_sin)) == SOCKET_ERROR) { if (errbuf) { snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::Connect(): connect() failed. Error: %i", WSAGetLastError()); } closesocket(connection_socket); connection_socket = 0; SetState(TCPS_Ready); SetAsyncConnect(false); return false; } #else if (connect(connection_socket, (struct sockaddr *) &server_sin, sizeof (server_sin)) == SOCKET_ERROR) { if (errbuf) { snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::Connect(): connect() failed. Error: %s", strerror(errno)); } close(connection_socket); connection_socket = 0; SetState(TCPS_Ready); SetAsyncConnect(false); return false; } #endif int bufsize = 64 * 1024; // 64kbyte receive buffer, up from default of 8k setsockopt(connection_socket, SOL_SOCKET, SO_RCVBUF, (char*) &bufsize, sizeof(bufsize)); #ifdef _WINDOWS unsigned long nonblocking = 1; ioctlsocket(connection_socket, FIONBIO, &nonblocking); #else fcntl(connection_socket, F_SETFL, O_NONBLOCK); #endif SetEcho(false); ClearBuffers(); rIP = in_ip; rPort = in_port; SetState(TCPS_Connected); SetAsyncConnect(false); return true; } void TCPConnection::ClearBuffers() { LockMutex lock1(&MSendQueue); LockMutex lock3(&MRunLoop); LockMutex lock4(&MState); safe_delete_array(recvbuf); safe_delete_array(sendbuf); char* line = 0; while ((line = LineOutQueue.pop())) { safe_delete_array(line); } }
PerlPacket::~PerlPacket() { if(packet != NULL) safe_delete_array(packet); }
bool TCPConnection::RecvData(char* errbuf) { if (errbuf) errbuf[0] = 0; if (!Connected()) { return false; } int status = 0; if (recvbuf == 0) { recvbuf = new uchar[5120]; recvbuf_size = 5120; recvbuf_used = 0; recvbuf_echo = 0; } else if ((recvbuf_size - recvbuf_used) < 2048) { uchar* tmpbuf = new uchar[recvbuf_size + 5120]; memcpy(tmpbuf, recvbuf, recvbuf_used); recvbuf_size += 5120; safe_delete_array(recvbuf); recvbuf = tmpbuf; if (recvbuf_size >= MaxTCPReceiveBuffferSize) { if (errbuf) snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::RecvData(): recvbuf_size >= MaxTCPReceiveBuffferSize"); return false; } } status = recv(connection_socket, (char *) &recvbuf[recvbuf_used], (recvbuf_size - recvbuf_used), 0); if (status >= 1) { #if TCPN_LOG_RAW_DATA_IN >= 1 struct in_addr in; in.s_addr = GetrIP(); CoutTimestamp(true); std::cout << ": Read " << status << " bytes from network. (recvbuf_used = " << recvbuf_used << ") " << inet_ntoa(in) << ":" << GetrPort(); std::cout << std::endl; #if TCPN_LOG_RAW_DATA_IN == 2 int32 tmp = status; if (tmp > 32) tmp = 32; DumpPacket(&recvbuf[recvbuf_used], status); #elif TCPN_LOG_RAW_DATA_IN >= 3 DumpPacket(&recvbuf[recvbuf_used], status); #endif #endif recvbuf_used += status; if (!ProcessReceivedData(errbuf)) return false; } else if (status == SOCKET_ERROR) { #ifdef _WINDOWS if (!(WSAGetLastError() == WSAEWOULDBLOCK)) { if (errbuf) snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::RecvData(): Error: %i", WSAGetLastError()); return false; } #else if (!(errno == EWOULDBLOCK)) { if (errbuf) snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::RecvData(): Error: %s", strerror(errno)); return false; } #endif } else if (status == 0) { snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::RecvData(): Connection closed"); return false; } return true; }
bool WorldDatabase::GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc) { // SoF doesn't send the player_choice field in character creation, it now sends the real zoneID instead. // // For SoF, search for an entry in start_zones with a matching zone_id, class, race and deity. // // For now, if no row matching row is found, send them to Crescent Reach, as that is probably the most likely // reason for no match being found. // char errbuf[MYSQL_ERRMSG_SIZE]; char *query = 0; MYSQL_RES *result; MYSQL_ROW row = 0; int rows; if(!in_pp || !in_cc) return false; in_pp->x = in_pp->y = in_pp->z = in_pp->heading = in_pp->zone_id = 0; in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = 0; if(!RunQuery(query, MakeAnyLenString(&query, "SELECT x,y,z,heading,bind_id FROM start_zones WHERE zone_id=%i AND player_class=%i " "AND player_deity=%i AND player_race=%i", in_cc->start_zone, in_cc->class_, in_cc->deity, in_cc->race), errbuf, &result)) { LogFile->write(EQEMuLog::Status, "SoF Start zone query failed: %s : %s\n", query, errbuf); safe_delete_array(query); return false; } LogFile->write(EQEMuLog::Status, "SoF Start zone query: %s\n", query); safe_delete_array(query); if((rows = mysql_num_rows(result)) > 0) row = mysql_fetch_row(result); if(row) { LogFile->write(EQEMuLog::Status, "Found starting location in start_zones"); in_pp->x = atof(row[0]); in_pp->y = atof(row[1]); in_pp->z = atof(row[2]); in_pp->heading = atof(row[3]); in_pp->zone_id = in_cc->start_zone; in_pp->binds[0].zoneId = atoi(row[4]); } else { printf("No start_zones entry in database, using defaults\n"); if(in_cc->start_zone == RuleI(World, TutorialZoneID)) in_pp->zone_id = in_cc->start_zone; else { in_pp->x = in_pp->binds[0].x = -51; in_pp->y = in_pp->binds[0].y = -20; in_pp->z = in_pp->binds[0].z = 0.79; in_pp->zone_id = in_pp->binds[0].zoneId = 394; // Crescent Reach. } } if(in_pp->x == 0 && in_pp->y == 0 && in_pp->z == 0) database.GetSafePoints(in_pp->zone_id, 0, &in_pp->x, &in_pp->y, &in_pp->z); if(in_pp->binds[0].x == 0 && in_pp->binds[0].y == 0 && in_pp->binds[0].z == 0) database.GetSafePoints(in_pp->binds[0].zoneId, 0, &in_pp->binds[0].x, &in_pp->binds[0].y, &in_pp->binds[0].z); if(result) mysql_free_result(result); return true; }
bool TCPConnection::ProcessReceivedData(char* errbuf) { if (errbuf) errbuf[0] = 0; if (!recvbuf) return true; #if TCPN_DEBUG_Console >= 4 if (recvbuf_used) { std::cout << "Starting Processing: recvbuf=" << recvbuf_used << std::endl; DumpPacket(recvbuf, recvbuf_used); } #endif for (int i=0; i < recvbuf_used; i++) { if (GetEcho() && i >= recvbuf_echo) { Send(&recvbuf[i], 1); recvbuf_echo = i + 1; } switch(recvbuf[i]) { case 0: { // 0 is the code for clear buffer if (i==0) { recvbuf_used--; recvbuf_echo--; memmove(recvbuf, &recvbuf[1], recvbuf_used); i = -1; } else { if (i == recvbuf_used) { safe_delete_array(recvbuf); i = -1; } else { uchar* tmpdel = recvbuf; recvbuf = new uchar[recvbuf_size]; memcpy(recvbuf, &tmpdel[i+1], recvbuf_used-i); recvbuf_used -= i + 1; recvbuf_echo -= i + 1; safe_delete_array(tmpdel); i = -1; } } #if TCPN_DEBUG_Console >= 5 std::cout << "Removed 0x00" << std::endl; if (recvbuf_used) { std::cout << "recvbuf left: " << recvbuf_used << std::endl; DumpPacket(recvbuf, recvbuf_used); } else std::cout << "recbuf left: None" << std::endl; #endif m_previousLineEnd = false; break; } case 10: case 13: // newline marker { char *line = nullptr; if (i==0) { // empty line if(!m_previousLineEnd) { //char right before this was NOT a CR, report the empty line. line = new char[1]; line[0] = '\0'; m_previousLineEnd = true; } else { m_previousLineEnd = false; } recvbuf_used--; recvbuf_echo--; memcpy(recvbuf, &recvbuf[1], recvbuf_used); i = -1; } else { line = new char[i+1]; memset(line, 0, i+1); memcpy(line, recvbuf, i); #if TCPN_DEBUG_Console >= 3 std::cout << "Line Out: " << std::endl; DumpPacket((uchar*) line, i); #endif //line[i] = 0; uchar* tmpdel = recvbuf; recvbuf = new uchar[recvbuf_size]; recvbuf_used -= i+1; recvbuf_echo -= i+1; memcpy(recvbuf, &tmpdel[i+1], recvbuf_used); #if TCPN_DEBUG_Console >= 5 std::cout << "i+1=" << i+1 << std::endl; if (recvbuf_used) { std::cout << "recvbuf left: " << recvbuf_used << std::endl; DumpPacket(recvbuf, recvbuf_used); } else std::cout << "recbuf left: None" << std::endl; #endif safe_delete_array(tmpdel); i = -1; m_previousLineEnd = true; } if(line != nullptr) { bool finish_proc = false; finish_proc = LineOutQueuePush(line); if(finish_proc) return(true); //break early as requested by LineOutQueuePush } break; } case 8: // backspace { if (i==0) { // nothin to backspace recvbuf_used--; recvbuf_echo--; memmove(recvbuf, &recvbuf[1], recvbuf_used); i = -1; } else { uchar* tmpdel = recvbuf; recvbuf = new uchar[recvbuf_size]; memcpy(recvbuf, tmpdel, i-1); memcpy(&recvbuf[i-1], &tmpdel[i+1], recvbuf_used-i); recvbuf_used -= 2; recvbuf_echo -= 2; safe_delete_array(tmpdel); i -= 2; } break; m_previousLineEnd = false; } default: m_previousLineEnd = false; } } if (recvbuf_used < 0) safe_delete_array(recvbuf); return true; }
bool WebInterfaceConnection::Process() { if (!stream || !stream->Connected()) return false; ServerPacket *pack = 0; while((pack = stream->PopPacket())) { if (!authenticated) { if (WorldConfig::get()->SharedKey.length() > 0) { if (pack->opcode == ServerOP_ZAAuth && pack->size == 16) { uint8 tmppass[16]; MD5::Generate((const uchar*) WorldConfig::get()->SharedKey.c_str(), WorldConfig::get()->SharedKey.length(), tmppass); if (memcmp(pack->pBuffer, tmppass, 16) == 0) authenticated = true; else { struct in_addr in; in.s_addr = GetIP(); _log(WEB_INTERFACE__ERROR, "WebInterface authorization failed."); ServerPacket* pack = new ServerPacket(ServerOP_ZAAuthFailed); SendPacket(pack); delete pack; Disconnect(); return false; } } else { struct in_addr in; in.s_addr = GetIP(); _log(WEB_INTERFACE__ERROR, "WebInterface authorization failed."); ServerPacket* pack = new ServerPacket(ServerOP_ZAAuthFailed); SendPacket(pack); delete pack; Disconnect(); return false; } } else { _log(WEB_INTERFACE__ERROR, "**WARNING** You have not configured a world shared key in your config file. You should add a <key>STRING</key> element to your <world> element to prevent unauthorized zone access."); authenticated = true; } delete pack; continue; } switch(pack->opcode) { case 0: break; case ServerOP_KeepAlive: { // ignore this break; } case ServerOP_ZAAuth: { _log(WEB_INTERFACE__ERROR, "Got authentication from WebInterface when they are already authenticated."); break; } case ServerOP_WIRemoteCall: { char *id = nullptr; char *session_id = nullptr; char *method = nullptr; id = new char[pack->ReadUInt32() + 1]; pack->ReadString(id); session_id = new char[pack->ReadUInt32() + 1]; pack->ReadString(session_id); method = new char[pack->ReadUInt32() + 1]; pack->ReadString(method); uint32 param_count = pack->ReadUInt32(); std::vector<std::string> params; for(uint32 i = 0; i < param_count; ++i) { char *p = new char[pack->ReadUInt32() + 1]; pack->ReadString(p); params.push_back(p); safe_delete_array(p); } if (remote_call_methods.count(method) != 0) { auto f = remote_call_methods[method]; f(method, session_id, id, params); } safe_delete_array(id); safe_delete_array(session_id); safe_delete_array(method); break; } case ServerOP_WIClientSessionResponse: { uint32 zone_id = pack->ReadUInt32(); uint32 instance_id = pack->ReadUInt32(); ZoneServer *zs = nullptr; if(instance_id != 0) { zs = zoneserver_list.FindByInstanceID(instance_id); } else { zs = zoneserver_list.FindByZoneID(zone_id); } if(zs) { ServerPacket *npack = new ServerPacket(ServerOP_WIClientSessionResponse, pack->size - 8); memcpy(npack->pBuffer, pack->pBuffer + 8, pack->size - 8); zs->SendPacket(npack); safe_delete(npack); } break; } default: { _log(WEB_INTERFACE__ERROR, "Unknown ServerOPcode from WebInterface 0x%04x, size %d", pack->opcode, pack->size); DumpPacket(pack->pBuffer, pack->size); break; } } delete pack; } return(true); }
bool EmuTCPConnection::LineOutQueuePush(char* line) { #if defined(GOTFRAGS) && 0 if (strcmp(line, "**CRASHME**") == 0) { int i = 0; std::cout << (5 / i) << std::endl; } #endif if(line[0] == '*') { if (strcmp(line, "**PACKETMODE**") == 0) { MSendQueue.lock(); safe_delete_array(sendbuf); if (TCPMode == modeConsole) Send((const uchar*) "\0**PACKETMODE**\r", 16); TCPMode = modePacket; PacketMode = packetModeLogin; EmuTCPNetPacket_Struct* tnps = 0; while ((tnps = InModeQueue.pop())) { SendPacket(tnps); safe_delete_array(tnps); } MSendQueue.unlock(); safe_delete_array(line); return(true); } if (strcmp(line, "**PACKETMODEZONE**") == 0) { MSendQueue.lock(); safe_delete_array(sendbuf); if (TCPMode == modeConsole) Send((const uchar*) "\0**PACKETMODEZONE**\r", 20); TCPMode = modePacket; PacketMode = packetModeZone; EmuTCPNetPacket_Struct* tnps = 0; while ((tnps = InModeQueue.pop())) { SendPacket(tnps); safe_delete_array(tnps); } MSendQueue.unlock(); safe_delete_array(line); return(true); } if (strcmp(line, "**PACKETMODELAUNCHER**") == 0) { MSendQueue.lock(); safe_delete_array(sendbuf); if (TCPMode == modeConsole) Send((const uchar*) "\0**PACKETMODELAUNCHER**\r", 24); TCPMode = modePacket; PacketMode = packetModeLauncher; EmuTCPNetPacket_Struct* tnps = 0; while ((tnps = InModeQueue.pop())) { SendPacket(tnps); safe_delete_array(tnps); } MSendQueue.unlock(); safe_delete_array(line); return(true); } if (strcmp(line, "**PACKETMODEUCS**") == 0) { MSendQueue.lock(); safe_delete_array(sendbuf); if (TCPMode == modeConsole) Send((const uchar*) "\0**PACKETMODEUCS**\r", 19); TCPMode = modePacket; PacketMode = packetModeUCS; EmuTCPNetPacket_Struct* tnps = 0; while ((tnps = InModeQueue.pop())) { SendPacket(tnps); safe_delete_array(tnps); } MSendQueue.unlock(); safe_delete_array(line); return(true); } if (strcmp(line, "**PACKETMODEQS**") == 0) { MSendQueue.lock(); safe_delete_array(sendbuf); if (TCPMode == modeConsole) Send((const uchar*) "\0**PACKETMODEQS**\r", 18); TCPMode = modePacket; PacketMode = packetModeQueryServ; EmuTCPNetPacket_Struct* tnps = 0; while ((tnps = InModeQueue.pop())) { SendPacket(tnps); safe_delete_array(tnps); } MSendQueue.unlock(); safe_delete_array(line); return(true); } if (strcmp(line, "**PACKETMODEWI**") == 0) { MSendQueue.lock(); safe_delete_array(sendbuf); if (TCPMode == modeConsole) Send((const uchar*) "\0**PACKETMODEWI**\r", 18); TCPMode = modePacket; PacketMode = packetModeWebInterface; EmuTCPNetPacket_Struct* tnps = 0; while ((tnps = InModeQueue.pop())) { SendPacket(tnps); safe_delete_array(tnps); } MSendQueue.unlock(); safe_delete_array(line); return(true); } } return(TCPConnection::LineOutQueuePush(line)); }
void Adventure::MoveCorpsesToGraveyard() { if(GetTemplate()->graveyard_zone_id == 0) { return; } list<uint32> dbid_list; list<uint32> charid_list; char errbuf[MYSQL_ERRMSG_SIZE]; char* query = 0; MYSQL_RES *result; MYSQL_ROW row; if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT id, charid FROM player_corpses WHERE instanceid=%d", GetInstanceID()), errbuf, &result)) { while((row = mysql_fetch_row(result))) { dbid_list.push_back(atoi(row[0])); charid_list.push_back(atoi(row[1])); } mysql_free_result(result); safe_delete_array(query); } else { LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::MoveCorpsesToGraveyard: %s (%s)", query, errbuf); safe_delete_array(query); } list<uint32>::iterator iter = dbid_list.begin(); while(iter != dbid_list.end()) { float x = GetTemplate()->graveyard_x + MakeRandomFloat(-GetTemplate()->graveyard_radius, GetTemplate()->graveyard_radius); float y = GetTemplate()->graveyard_y + MakeRandomFloat(-GetTemplate()->graveyard_radius, GetTemplate()->graveyard_radius); float z = GetTemplate()->graveyard_z; if(database.RunQuery(query,MakeAnyLenString(&query, "UPDATE player_corpses SET zoneid=%d, instanceid=0, x=%f, y=%f, z=%f WHERE instanceid=%d", GetTemplate()->graveyard_zone_id, x, y, z, GetInstanceID()), errbuf)) { safe_delete_array(query); } else { LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::MoveCorpsesToGraveyard: %s (%s)", query, errbuf); safe_delete_array(query); } iter++; } iter = dbid_list.begin(); list<uint32>::iterator c_iter = charid_list.begin(); while(iter != dbid_list.end()) { ServerPacket* pack = new ServerPacket(ServerOP_DepopAllPlayersCorpses, sizeof(ServerDepopAllPlayersCorpses_Struct)); ServerDepopAllPlayersCorpses_Struct *dpc = (ServerDepopAllPlayersCorpses_Struct*)pack->pBuffer; dpc->CharacterID = (*c_iter); dpc->InstanceID = 0; dpc->ZoneID = GetTemplate()->graveyard_zone_id; zoneserver_list.SendPacket(0, GetInstanceID(), pack); delete pack; pack = new ServerPacket(ServerOP_SpawnPlayerCorpse, sizeof(SpawnPlayerCorpse_Struct)); SpawnPlayerCorpse_Struct* spc = (SpawnPlayerCorpse_Struct*)pack->pBuffer; spc->player_corpse_id = (*iter); spc->zone_id = GetTemplate()->graveyard_zone_id; zoneserver_list.SendPacket(spc->zone_id, 0, pack); delete pack; iter++; c_iter++; } }
bool EmuTCPConnection::ProcessReceivedDataAsOldPackets(char* errbuf) { int32 base = 0; int32 size = 4; uchar* buffer; ServerPacket* pack = 0; while ((recvbuf_used - base) >= size) { buffer = &recvbuf[base]; memcpy(&size, &buffer[2], 2); if (size >= MaxTCPReceiveBuffferSize) { #if TCPN_DEBUG_Memory >= 1 std::cout << "TCPConnection[" << GetID() << "]::ProcessReceivedDataAsPackets(): size[" << size << "] >= MaxTCPReceiveBuffferSize" << std::endl; #endif if (errbuf) snprintf(errbuf, TCPConnection_ErrorBufferSize, "EmuTCPConnection::ProcessReceivedDataAsPackets(): size >= MaxTCPReceiveBuffferSize"); return false; } if ((recvbuf_used - base) >= size) { // ok, we got enough data to make this packet! pack = new ServerPacket; memcpy(&pack->opcode, &buffer[0], 2); pack->size = size - 4; /* if () { // TODO: Checksum or size check or something similar // Datastream corruption, get the hell outta here! delete pack; return false; }*/ if (pack->size > 0) { pack->pBuffer = new uchar[pack->size]; memcpy(pack->pBuffer, &buffer[4], pack->size); } if (pack->opcode == 0) { // keepalive, no need to process safe_delete(pack); } else { #if TCPN_LOG_PACKETS >= 1 if (pack && pack->opcode != 0) { struct in_addr in; in.s_addr = GetrIP(); CoutTimestamp(true); std::cout << ": Logging incoming TCP OldPacket. OPCode: 0x" << std::hex << std::setw(4) << std::setfill('0') << pack->opcode << std::dec << ", size: " << std::setw(5) << std::setfill(' ') << pack->size << " " << inet_ntoa(in) << ":" << GetrPort() << std::endl; #if TCPN_LOG_PACKETS == 2 if (pack->size >= 32) DumpPacket(pack->pBuffer, 32); else DumpPacket(pack); #endif #if TCPN_LOG_PACKETS >= 3 DumpPacket(pack); #endif } #endif OutQueuePush(pack); } base += size; size = 4; } } if (base != 0) { if (base >= recvbuf_used) { safe_delete_array(recvbuf); } else { uchar* tmpbuf = new uchar[recvbuf_size - base]; memcpy(tmpbuf, &recvbuf[base], recvbuf_used - base); safe_delete_array(recvbuf); recvbuf = tmpbuf; recvbuf_used -= base; recvbuf_size -= base; } } return true; }
void CWndInfoNotice::OnInitialUpdate() { CWndNeuz::OnInitialUpdate(); // 여기에 코딩하세요 CWndButton* pWndCheck = (CWndButton*)GetDlgItem( WIDC_CHECK1 ); pWndCheck->SetCheck( !g_Option.m_bNotice ); CWndText* pWndText = (CWndText*)GetDlgItem( WIDC_TEXT1 ); #ifdef __YNOTICE_UNI1026 CString strnotice; strnotice = GetLangFileName( ::GetLanguage(), FILE_NOTICE ); CScript scanner; if( scanner.Load( "Client\\"+strnotice ) == FALSE ) return; pWndText->m_string.AddParsingString( scanner.m_pProg ); pWndText->ResetString(); #else //__YNOTICE_UNI1026 CFileStatus fileStatus; CString strnotice; strnotice = GetLangFileName( ::GetLanguage(), FILE_NOTICE ); if( CFile::GetStatus( "Client\\"+strnotice, fileStatus ) == TRUE ) { if( g_Option.m_tNoticeTime != fileStatus.m_mtime.GetTime() ) g_Option.m_tNoticeTime = static_cast< time_t >( fileStatus.m_mtime.GetTime() ); CFileIO file; strnotice = GetLangFileName( ::GetLanguage(), FILE_NOTICE ); if(::GetLanguage() == LANG_VTN) { if( file.Open( "Client\\"+strnotice, "rb" ) ) { int nLength = file.GetLength(); TCHAR* pChar = new TCHAR[ nLength + 2 ]; file.Read( pChar, nLength ); *(pChar + nLength ) = '\0'; *(pChar + nLength + 1 ) = '\0'; char* lpMultiByte = new char[ nLength + 2 ]; int nResult = WideCharToMultiByteEx( g_codePage, 0, (LPWSTR)(pChar+2), -1, lpMultiByte, nLength, NULL, NULL ); if( nResult > 0 ) { lpMultiByte[nResult-1] = 0; pWndText->m_string.AddParsingString( lpMultiByte ); pWndText->ResetString(); } safe_delete_array(pChar); safe_delete_array(lpMultiByte); } } else { if( file.Open( "Client\\"+strnotice, "rb" ) ) { int nLength = file.GetLength(); TCHAR* pChar = new TCHAR[ nLength + 1]; file.Read( pChar, nLength ); pChar[ nLength ] = 0; //pWndText->SetString( pChar ); pWndText->m_string.AddParsingString( pChar ); pWndText->ResetString(); safe_delete( pChar ); } } } #endif //__YNOTICE_UNI1026 // 윈도를 중앙으로 옮기는 부분. CRect rectRoot = m_pWndRoot->GetLayoutRect(); CRect rectWindow = GetWindowRect(); CPoint point( rectRoot.right - rectWindow.Width(), 110 ); Move( point ); MoveParentCenter(); ///////////////////////////////////////////////////////////////////////////////////////// int nCount = 0; CScript script; if( script.Load(MakePath(DIR_THEME, "TexBannerList.inc" )) ) { int nLang; nLang = script.GetNumber(); do { if( nLang == ::GetLanguage() ) { script.GetToken(); nCount = atoi( script.token ); script.GetToken(); for( int i=0; i<nCount; i++ ) { CString addStr = script.token; m_vecStrBanner.push_back( addStr ); script.GetToken(); } if( nCount <= 0 ) { Error( "TexBannerList.inc의 갯수가 0이다" ); return; } break; } else script.GetLastFull(); nLang = script.GetNumber(); } while( script.tok != FINISHED ); } SAFE_DELETE( m_atexPannel ); if( nCount > 0 ) { m_atexPannel = new IMAGE; LoadImage( MakePath( DIR_THEME, m_vecStrBanner[xRandom(nCount)] ), m_atexPannel ); AdjustWndBase(); } ///////////////////////////////////////////////////////////////////////////////////////// }
void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z, float heading, uint8 ignorerestrictions, ZoneMode zm) { bool ReadyToZone = true; int iZoneNameLength = 0; const char* pShortZoneName = nullptr; char* pZoneName = nullptr; pShortZoneName = database.GetZoneName(zoneID); database.GetZoneLongName(pShortZoneName, &pZoneName); SetPortExemption(true); if(!pZoneName) { Message(13, "Invalid zone number specified"); safe_delete_array(pZoneName); return; } iZoneNameLength = strlen(pZoneName); switch(zm) { case EvacToSafeCoords: case ZoneToSafeCoords: x = zone->safe_x(); y = zone->safe_y(); z = zone->safe_z(); SetHeading(heading); break; case GMSummon: zonesummon_x = x_pos = x; zonesummon_y = y_pos = y; zonesummon_z = z_pos = z; SetHeading(heading); zonesummon_id = zoneID; zonesummon_ignorerestrictions = 1; break; case ZoneSolicited: zonesummon_x = x; zonesummon_y = y; zonesummon_z = z; SetHeading(heading); zonesummon_id = zoneID; zonesummon_ignorerestrictions = ignorerestrictions; break; case GateToBindPoint: x = x_pos = m_pp.binds[0].x; y = y_pos = m_pp.binds[0].y; z = z_pos = m_pp.binds[0].z; heading = m_pp.binds[0].heading; break; case ZoneToBindPoint: x = x_pos = m_pp.binds[0].x; y = y_pos = m_pp.binds[0].y; z = z_pos = m_pp.binds[0].z; heading = m_pp.binds[0].heading; zonesummon_ignorerestrictions = 1; LogFile->write(EQEMuLog::Debug, "Player %s has died and will be zoned to bind point in zone: %s at LOC x=%f, y=%f, z=%f, heading=%f", GetName(), pZoneName, m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, m_pp.binds[0].heading); break; case SummonPC: zonesummon_x = x_pos = x; zonesummon_y = y_pos = y; zonesummon_z = z_pos = z; SetHeading(heading); break; case Rewind: LogFile->write(EQEMuLog::Debug, "%s has requested a /rewind from %f, %f, %f, to %f, %f, %f in %s", GetName(), x_pos, y_pos, z_pos, rewind_x, rewind_y, rewind_z, zone->GetShortName()); zonesummon_x = x_pos = x; zonesummon_y = y_pos = y; zonesummon_z = z_pos = z; SetHeading(heading); break; default: LogFile->write(EQEMuLog::Error, "Client::ZonePC() received a reguest to perform an unsupported client zone operation."); ReadyToZone = false; break; } if(ReadyToZone) { zone_mode = zm; if(zm == ZoneToBindPoint) { EQApplicationPacket* outapp = new EQApplicationPacket(OP_ZonePlayerToBind, sizeof(ZonePlayerToBind_Struct) + iZoneNameLength); ZonePlayerToBind_Struct* gmg = (ZonePlayerToBind_Struct*) outapp->pBuffer; // If we are SoF and later and are respawning from hover, we want the real zone ID, else zero to use the old hack. // if((GetClientVersionBit() & BIT_SoFAndLater) && (!RuleB(Character, RespawnFromHover) || !IsHoveringForRespawn())) gmg->bind_zone_id = 0; else gmg->bind_zone_id = zoneID; gmg->x = x; gmg->y = y; gmg->z = z; gmg->heading = heading; strcpy(gmg->zone_name, pZoneName); outapp->priority = 6; FastQueuePacket(&outapp); safe_delete(outapp); } else if(zm == ZoneSolicited || zm == ZoneToSafeCoords) { EQApplicationPacket* outapp = new EQApplicationPacket(OP_RequestClientZoneChange, sizeof(RequestClientZoneChange_Struct)); RequestClientZoneChange_Struct* gmg = (RequestClientZoneChange_Struct*) outapp->pBuffer; gmg->zone_id = zoneID; gmg->x = x; gmg->y = y; gmg->z = z; gmg->heading = heading; gmg->instance_id = instance_id; gmg->type = 0x01; //an observed value, not sure of meaning outapp->priority = 6; FastQueuePacket(&outapp); safe_delete(outapp); } else if(zm == EvacToSafeCoords) { EQApplicationPacket* outapp = new EQApplicationPacket(OP_RequestClientZoneChange, sizeof(RequestClientZoneChange_Struct)); RequestClientZoneChange_Struct* gmg = (RequestClientZoneChange_Struct*) outapp->pBuffer; // if we are in the same zone we want to evac to, client will not send OP_ZoneChange back to do an actual // zoning of the client, so we have to send a viable zoneid that the client *could* zone to to make it believe // we are leaving the zone, even though we are not. We have to do this because we are missing the correct op code // and struct that should be used for evac/succor. // 213 is Plane of War // 76 is orignial Plane of Hate // WildcardX 27 January 2008. Tested this for 6.2 and Titanium clients. if(this->GetZoneID() == 1) gmg->zone_id = 2; else if(this->GetZoneID() == 2) gmg->zone_id = 1; else gmg->zone_id = 1; gmg->x = x; gmg->y = y; gmg->z = z; gmg->heading = heading; gmg->instance_id = instance_id; gmg->type = 0x01; // '0x01' was an observed value for the type field, not sure of meaning // we hide the real zoneid we want to evac/succor to here zonesummon_id = zoneID; outapp->priority = 6; FastQueuePacket(&outapp); safe_delete(outapp); } else { if(zoneID == GetZoneID()) { //properly handle proximities entity_list.ProcessMove(this, x_pos, y_pos, z_pos); proximity_x = x_pos; proximity_y = y_pos; proximity_z = z_pos; //send out updates to people in zone. SendPosition(); } EQApplicationPacket* outapp = new EQApplicationPacket(OP_RequestClientZoneChange, sizeof(RequestClientZoneChange_Struct)); RequestClientZoneChange_Struct* gmg = (RequestClientZoneChange_Struct*) outapp->pBuffer; gmg->zone_id = zoneID; gmg->x = x; gmg->y = y; gmg->z = z; gmg->heading = heading; gmg->instance_id = instance_id; gmg->type = 0x01; //an observed value, not sure of meaning outapp->priority = 6; FastQueuePacket(&outapp); safe_delete(outapp); } _log(NET__DEBUG, "Player %s has requested a zoning to LOC x=%f, y=%f, z=%f, heading=%f in zoneid=%i", GetName(), x, y, z, heading, zoneID); //Clear zonesummon variables if we're zoning to our own zone //Client wont generate a zone change packet to the server in this case so //They aren't needed and it keeps behavior on next zone attempt from being undefined. if(zoneID == zone->GetZoneID() && instance_id == zone->GetInstanceID()) { if(zm != EvacToSafeCoords && zm != ZoneToSafeCoords && zm != ZoneToBindPoint) { zonesummon_x = 0; zonesummon_y = 0; zonesummon_z = 0; zonesummon_id = 0; zonesummon_ignorerestrictions = 0; zone_mode = ZoneUnsolicited; } } } safe_delete_array(pZoneName); }
bool SharedMemory::LoadItems(){ char errbuf[MYSQL_ERRMSG_SIZE]; char *query = 0; MYSQL_RES *result; MYSQL_ROW row; int id; query = new char[256]; strcpy(query, "SELECT MAX(id) FROM items"); EQC::Common::PrintF(CP_SHAREDMEMORY, "Loading items... "); if (Database::Instance()->RunQuery(query, strlen(query), errbuf, &result)) { safe_delete(query); row = mysql_fetch_row(result); if (row != 0 && row[0] > 0) { getPtr()->max_item = atoi(row[0]); if (getPtr()->max_item >= MAXITEMID) { EQC::Common::PrintF(CP_SHAREDMEMORY, "bool SharedMemory::LoadItems(): More items than MAXITEMID. Change constant in SharedMemory.hpp"); return false; } memset(&getPtr()->item_array, 0, sizeof(getPtr()->item_array)); mysql_free_result(result); MakeAnyLenString(&query, "SELECT id,raw_data FROM items"); if (Database::Instance()->RunQuery(query, strlen(query), errbuf, &result)) { safe_delete_array(query);//delete[] query; while(row = mysql_fetch_row(result)) { unsigned long* lengths; lengths = mysql_fetch_lengths(result); if (lengths[1] == sizeof(Item_Struct)) { id = atoi(row[0]); memcpy(&getPtr()->item_array[id], row[1], sizeof(Item_Struct)); //Yeahlight: Client item exceptions if(getPtr()->item_array[id].type == 0) { //Yeahlight: Remove 'BST' (01000000 00000000) from item classes as long as the list does not compute to 'ALL' (01111111 11111111) if(getPtr()->item_array[id].common.classes - 16384 >= 0 && getPtr()->item_array[id].common.classes != 32767) getPtr()->item_array[id].common.classes -= 16384; //Yeahlight: Remove 'VAH' (00100000 00000000) from item races as long as the list does not compute to 'ALL' (00111111 11111111) if(getPtr()->item_array[id].common.normal.races - 8192 >= 0 && getPtr()->item_array[id].common.normal.races != 16383) getPtr()->item_array[id].common.normal.races -= 8192; //Yeahlight: Our client cannot handle H2H skill weapons, so flag them as 1HB if(getPtr()->item_array[id].common.itemType == ItemTypeHand2Hand) getPtr()->item_array[id].common.itemType = ItemType1HB; //Yeahlight: There will be no gear with recommended levels on the server, so zero out this field if(getPtr()->item_array[id].common.recommendedLevel != 0) getPtr()->item_array[id].common.recommendedLevel = 0; //Yeahlight: This purges focus effects from our items if(getPtr()->item_array[id].common.click_effect_id >= 2330 && getPtr()->item_array[id].common.click_effect_id <= 2374) { getPtr()->item_array[id].common.click_effect_id = 0; getPtr()->item_array[id].common.spell_effect_id = 0; getPtr()->item_array[id].common.charges = 0; getPtr()->item_array[id].common.normal.click_effect_type = 0; getPtr()->item_array[id].common.effecttype = 0; getPtr()->item_array[id].common.clicktype = 0; } } //Yeahlight: Client container exceptions else if(getPtr()->item_array[id].type == 1) { //Tazadar : We clean this or the client crashes or bag are full of shit memset(&getPtr()->item_array[id].common.level,0x00,69*sizeof(int8)); memset(&getPtr()->item_array[id].unknown0144[0],0x00,68*sizeof(int8)); } //Yeahlight: Client book exceptions else if(getPtr()->item_array[id].type == 2) { } } else { cout << "Invalid items in database..." << endl; } Sleep(0); } mysql_free_result(result); } else { cerr << "Error in PopulateZoneLists query '" << query << "' " << errbuf << endl; safe_delete_array(query);//delete[] query; return false; } } else { mysql_free_result(result); } } else { cerr << "Error in PopulateZoneLists query '" << query << "' " << errbuf << endl; safe_delete_array(query);//delete[] query; return false; } EQC::Common::PrintF(CP_SHAREDMEMORY, "Item loading finished."); return true; }
// Split from the basic MakePet to allow backward compatiblity with existing code while also // making it possible for petpower to be retained without the focus item having to // stay equipped when the character zones. petpower of -1 means that the currently equipped petfocus // of a client is searched for and used instead. void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower, const char *petname, float in_size) { // Sanity and early out checking first. if(HasPet() || pettype == nullptr) return; int16 act_power = 0; // The actual pet power we'll use. if (petpower == -1) { if (this->IsClient()) { act_power = CastToClient()->GetFocusEffect(focusPetPower, spell_id); act_power = CastToClient()->mod_pet_power(act_power, spell_id); } } else if (petpower > 0) act_power = petpower; // optional rule: classic style variance in pets. Achieve this by // adding a random 0-4 to pet power, since it only comes in increments // of five from focus effects. //lookup our pets table record for this type PetRecord record; if(!database.GetPoweredPetEntry(pettype, act_power, &record)) { Message(13, "Unable to find data for pet %s", pettype); LogFile->write(EQEMuLog::Error, "Unable to find data for pet %s, check pets table.", pettype); return; } //find the NPC data for the specified NPC type const NPCType *base = database.GetNPCType(record.npc_type); if(base == nullptr) { Message(13, "Unable to load NPC data for pet %s", pettype); LogFile->write(EQEMuLog::Error, "Unable to load NPC data for pet %s (NPC ID %d), check pets and npc_types tables.", pettype, record.npc_type); return; } //we copy the npc_type data because we need to edit it a bit NPCType *npc_type = new NPCType; memcpy(npc_type, base, sizeof(NPCType)); // If pet power is set to -1 in the DB, use stat scaling if (this->IsClient() && record.petpower == -1) { float scale_power = (float)act_power / 100.0f; if(scale_power > 0) { npc_type->max_hp *= (1 + scale_power); npc_type->cur_hp = npc_type->max_hp; npc_type->AC *= (1 + scale_power); npc_type->level += 1 + ((int)act_power / 25); // gains an additional level for every 25 pet power npc_type->min_dmg = (npc_type->min_dmg * (1 + (scale_power / 2))); npc_type->max_dmg = (npc_type->max_dmg * (1 + (scale_power / 2))); npc_type->size *= (1 + (scale_power / 2)); } record.petpower = act_power; } //Live AA - Elemental Durability int16 MaxHP = aabonuses.PetMaxHP + itembonuses.PetMaxHP + spellbonuses.PetMaxHP; if (MaxHP){ npc_type->max_hp += (npc_type->max_hp*MaxHP)/100; npc_type->cur_hp = npc_type->max_hp; } //TODO: think about regen (engaged vs. not engaged) // Pet naming: // 0 - `s pet // 1 - `s familiar // 2 - `s Warder // 3 - Random name if client, `s pet for others // 4 - Keep DB name if (petname != nullptr) { // Name was provided, use it. strn0cpy(npc_type->name, petname, 64); } else if (record.petnaming == 0) { strcpy(npc_type->name, this->GetCleanName()); npc_type->name[25] = '\0'; strcat(npc_type->name, "`s_pet"); } else if (record.petnaming == 1) { strcpy(npc_type->name, this->GetName()); npc_type->name[19] = '\0'; strcat(npc_type->name, "`s_familiar"); } else if (record.petnaming == 2) { strcpy(npc_type->name, this->GetName()); npc_type->name[21] = 0; strcat(npc_type->name, "`s_Warder"); } else if (record.petnaming == 4) { // Keep the DB name } else if (record.petnaming == 3 && IsClient()) { strcpy(npc_type->name, GetRandPetName()); } else { strcpy(npc_type->name, this->GetCleanName()); npc_type->name[25] = '\0'; strcat(npc_type->name, "`s_pet"); } //handle beastlord pet appearance if(record.petnaming == 2) { switch(GetBaseRace()) { case VAHSHIR: npc_type->race = TIGER; npc_type->size *= 0.8f; break; case TROLL: npc_type->race = ALLIGATOR; npc_type->size *= 2.5f; break; case OGRE: npc_type->race = BEAR; npc_type->texture = 3; npc_type->gender = 2; break; case BARBARIAN: npc_type->race = WOLF; npc_type->texture = 2; break; case IKSAR: npc_type->race = WOLF; npc_type->texture = 0; npc_type->gender = 1; npc_type->size *= 2.0f; npc_type->luclinface = 0; break; default: npc_type->race = WOLF; npc_type->texture = 0; } } // handle monster summoning pet appearance if(record.monsterflag) { char errbuf[MYSQL_ERRMSG_SIZE]; char* query = 0; MYSQL_RES *result = nullptr; MYSQL_ROW row = nullptr; uint32 monsterid; // get a random npc id from the spawngroups assigned to this zone if (database.RunQuery(query, MakeAnyLenString(&query, "SELECT npcID FROM (spawnentry INNER JOIN spawn2 ON spawn2.spawngroupID = spawnentry.spawngroupID) " "INNER JOIN npc_types ON npc_types.id = spawnentry.npcID " "WHERE spawn2.zone = '%s' AND npc_types.bodytype NOT IN (11, 33, 66, 67) " "AND npc_types.race NOT IN (0,1,2,3,4,5,6,7,8,9,10,11,12,44,55,67,71,72,73,77,78,81,90,92,93,94,106,112,114,127,128,130,139,141,183,236,237,238,239,254,266,329,330,378,379,380,381,382,383,404,522) " "ORDER BY RAND() LIMIT 1", zone->GetShortName()), errbuf, &result)) { row = mysql_fetch_row(result); if (row) monsterid = atoi(row[0]); else monsterid = 567; // since we don't have any monsters, just make it look like an earth pet for now } else { // if the database query failed LogFile->write(EQEMuLog::Error, "Error querying database for monster summoning pet in zone %s (%s)", zone->GetShortName(), errbuf); monsterid = 567; } // give the summoned pet the attributes of the monster we found const NPCType* monster = database.GetNPCType(monsterid); if(monster) { npc_type->race = monster->race; npc_type->size = monster->size; npc_type->texture = monster->texture; npc_type->gender = monster->gender; npc_type->luclinface = monster->luclinface; npc_type->helmtexture = monster->helmtexture; } else { LogFile->write(EQEMuLog::Error, "Error loading NPC data for monster summoning pet (NPC ID %d)", monsterid); } safe_delete_array(query); } //this takes ownership of the npc_type data Pet *npc = new Pet(npc_type, this, (PetType)record.petcontrol, spell_id, record.petpower); // Now that we have an actual object to interact with, load // the base items for the pet. These are always loaded // so that a rank 1 suspend minion does not kill things // like the special back items some focused pets may receive. uint32 petinv[MAX_WORN_INVENTORY]; memset(petinv, 0, sizeof(petinv)); const Item_Struct *item = 0; if (database.GetBasePetItems(record.equipmentset, petinv)) { for (int i=0; i<MAX_WORN_INVENTORY; i++) if (petinv[i]) { item = database.GetItem(petinv[i]); npc->AddLootDrop(item, &npc->itemlist, 0, 1, 127, true, true); } } // finally, override size if one was provided if (in_size > 0.0f) npc->size = in_size; entity_list.AddNPC(npc, true, true); SetPetID(npc->GetID()); // We need to handle PetType 5 (petHatelist), add the current target to the hatelist of the pet }
void TCPConnection::AsyncConnect(const char* irAddress, uint16 irPort) { safe_delete_array(charAsyncConnect); charAsyncConnect = new char[strlen(irAddress) + 1]; strcpy(charAsyncConnect, irAddress); AsyncConnect((uint32) 0, irPort); }
uint32 ZoneDatabase::GetZoneFishing(uint32 ZoneID, uint8 skill, uint32 &npc_id, uint8 &npc_chance) { char errbuf[MYSQL_ERRMSG_SIZE]; char *query = 0; MYSQL_RES *result; MYSQL_ROW row; uint8 index = 0; uint32 item[50]; uint32 chance[50]; uint32 npc_ids[50]; uint32 npc_chances[50]; uint32 chancepool = 0; uint32 ret = 0; for (int c=0; c<50; c++) { item[c]=0; chance[c]=0; } if (RunQuery(query, MakeAnyLenString(&query, "SELECT itemid,chance,npc_id,npc_chance FROM fishing WHERE (zoneid= '%i' || zoneid = 0) and skill_level <= '%i'",ZoneID, skill ), errbuf, &result)) { safe_delete_array(query); while ((row = mysql_fetch_row(result))&&(index<50)) { item[index] = atoi(row[0]); chance[index] = atoi(row[1])+chancepool; chancepool = chance[index]; npc_ids[index] = atoi(row[2]); npc_chances[index] = atoi(row[3]); index++; } mysql_free_result(result); } else { std::cerr << "Error in Fishing query '" << query << "' " << errbuf << std::endl; safe_delete_array(query); return 0; } npc_id = 0; npc_chance = 0; if (index>0) { uint32 random = MakeRandomInt(1, chancepool); for (int i = 0; i < index; i++) { if (random <= chance[i]) { ret = item[i]; npc_id = npc_ids[i]; npc_chance = npc_chances[i]; break; } } } else { ret = 0; } return ret; }
/* This is always called from an IO thread. Either the server socket's thread, or a * special thread we create when we make an outbound connection. */ bool TCPConnection::Process() { char errbuf[TCPConnection_ErrorBufferSize]; switch(GetState()) { case TCPS_Ready: case TCPS_Connecting: if (ConnectionType == Outgoing) { if (GetAsyncConnect()) { if (charAsyncConnect) rIP = ResolveIP(charAsyncConnect); ConnectIP(rIP, rPort); } } return(true); case TCPS_Connected: // only receive data in the connected state, no others... if (!RecvData(errbuf)) { struct in_addr in; in.s_addr = GetrIP(); //std::cout << inet_ntoa(in) << ":" << GetrPort() << ": " << errbuf << std::endl; return false; } /* we break to do the send */ break; case TCPS_Disconnecting: { //waiting for any sending data to go out... MSendQueue.lock(); if(sendbuf) { if(sendbuf_used > 0) { //something left to send, keep processing... MSendQueue.unlock(); break; } //else, send buffer is empty. safe_delete_array(sendbuf); } //else, no send buffer, we are done. MSendQueue.unlock(); } /* Fallthrough */ case TCPS_Disconnected: FinishDisconnect(); MRunLoop.lock(); pRunLoop = false; MRunLoop.unlock(); // SetState(TCPS_Ready); //reset the state in case they want to use it again... return(false); case TCPS_Closing: //I dont understand this state... case TCPS_Error: MRunLoop.lock(); pRunLoop = false; MRunLoop.unlock(); return(false); } /* we get here in connected or disconnecting with more data to send */ bool sent_something = false; if (!SendData(sent_something, errbuf)) { struct in_addr in; in.s_addr = GetrIP(); std::cout << inet_ntoa(in) << ":" << GetrPort() << ": " << errbuf << std::endl; return false; } return true; }
void ClientList::SendWhoAll(uint32 fromid,const char* to, int16 admin, Who_All_Struct* whom, WorldTCPConnection* connection) { try{ LinkedListIterator<ClientListEntry*> iterator(clientlist); LinkedListIterator<ClientListEntry*> countclients(clientlist); ClientListEntry* cle = 0; ClientListEntry* countcle = 0; //char tmpgm[25] = ""; //char accinfo[150] = ""; char line[300] = ""; //char tmpguild[50] = ""; //char LFG[10] = ""; //uint32 x = 0; int whomlen = 0; if (whom) { whomlen = strlen(whom->whom); if(whom->wrace == 0x001A) // 0x001A is the old Froglok race number and is sent by the client for /who all froglok whom->wrace = FROGLOK; // This is what EQEmu uses for the Froglok Race number. } char* output = 0; uint32 outsize = 0, outlen = 0; uint32 totalusers=0; uint32 totallength=0; AppendAnyLenString(&output, &outsize, &outlen, "Players on server:"); if (connection->IsConsole()) AppendAnyLenString(&output, &outsize, &outlen, "\r\n"); else AppendAnyLenString(&output, &outsize, &outlen, "\n"); countclients.Reset(); while(countclients.MoreElements()){ countcle = countclients.GetData(); const char* tmpZone = database.GetZoneName(countcle->zone()); if ( (countcle->Online() >= CLE_Status_Zoning) && (!countcle->GetGM() || countcle->Anon() != 1 || admin >= countcle->Admin()) && (whom == 0 || ( ((countcle->Admin() >= 80 && countcle->GetGM()) || whom->gmlookup == 0xFFFF) && (whom->lvllow == 0xFFFF || (countcle->level() >= whom->lvllow && countcle->level() <= whom->lvlhigh && (countcle->Anon()==0 || admin > countcle->Admin()))) && (whom->wclass == 0xFFFF || (countcle->class_() == whom->wclass && (countcle->Anon()==0 || admin > countcle->Admin()))) && (whom->wrace == 0xFFFF || (countcle->race() == whom->wrace && (countcle->Anon()==0 || admin > countcle->Admin()))) && (whomlen == 0 || ( (tmpZone != 0 && strncasecmp(tmpZone, whom->whom, whomlen) == 0) || strncasecmp(countcle->name(),whom->whom, whomlen) == 0 || (strncasecmp(guild_mgr.GetGuildName(countcle->GuildID()), whom->whom, whomlen) == 0) || (admin >= 100 && strncasecmp(countcle->AccountName(), whom->whom, whomlen) == 0) )) )) ) { if((countcle->Anon()>0 && admin>=countcle->Admin() && admin>0) || countcle->Anon()==0 ){ totalusers++; if(totalusers<=20 || admin>=100) totallength=totallength+strlen(countcle->name())+strlen(countcle->AccountName())+strlen(guild_mgr.GetGuildName(countcle->GuildID()))+5; } else if((countcle->Anon()>0 && admin<=countcle->Admin()) || (countcle->Anon()==0 && !countcle->GetGM())) { totalusers++; if(totalusers<=20 || admin>=100) totallength=totallength+strlen(countcle->name())+strlen(guild_mgr.GetGuildName(countcle->GuildID()))+5; } } countclients.Advance(); } uint32 plid=fromid; uint32 playerineqstring=5001; const char line2[]="---------------------------"; uint8 unknown35=0x0A; uint32 unknown36=0; uint32 playersinzonestring=5028; if(totalusers>20 && admin<100){ totalusers=20; playersinzonestring=5033; } else if(totalusers>1) playersinzonestring=5036; uint32 unknown44[2]; unknown44[0]=0; unknown44[1]=0; uint32 unknown52=totalusers; uint32 unknown56=1; auto pack2 = new ServerPacket(ServerOP_WhoAllReply, 64 + totallength + (49 * totalusers)); memset(pack2->pBuffer,0,pack2->size); uchar *buffer=pack2->pBuffer; uchar *bufptr=buffer; //memset(buffer,0,pack2->size); memcpy(bufptr,&plid, sizeof(uint32)); bufptr+=sizeof(uint32); memcpy(bufptr,&playerineqstring, sizeof(uint32)); bufptr+=sizeof(uint32); memcpy(bufptr,&line2, strlen(line2)); bufptr+=strlen(line2); memcpy(bufptr,&unknown35, sizeof(uint8)); bufptr+=sizeof(uint8); memcpy(bufptr,&unknown36, sizeof(uint32)); bufptr+=sizeof(uint32); memcpy(bufptr,&playersinzonestring, sizeof(uint32)); bufptr+=sizeof(uint32); memcpy(bufptr,&unknown44[0], sizeof(uint32)); bufptr+=sizeof(uint32); memcpy(bufptr,&unknown44[1], sizeof(uint32)); bufptr+=sizeof(uint32); memcpy(bufptr,&unknown52, sizeof(uint32)); bufptr+=sizeof(uint32); memcpy(bufptr,&unknown56, sizeof(uint32)); bufptr+=sizeof(uint32); memcpy(bufptr,&totalusers, sizeof(uint32)); bufptr+=sizeof(uint32); iterator.Reset(); int idx=-1; while(iterator.MoreElements()) { cle = iterator.GetData(); const char* tmpZone = database.GetZoneName(cle->zone()); if ( (cle->Online() >= CLE_Status_Zoning) && (!cle->GetGM() || cle->Anon() != 1 || admin >= cle->Admin()) && (whom == 0 || ( ((cle->Admin() >= 80 && cle->GetGM()) || whom->gmlookup == 0xFFFF) && (whom->lvllow == 0xFFFF || (cle->level() >= whom->lvllow && cle->level() <= whom->lvlhigh && (cle->Anon()==0 || admin>cle->Admin()))) && (whom->wclass == 0xFFFF || (cle->class_() == whom->wclass && (cle->Anon()==0 || admin>cle->Admin()))) && (whom->wrace == 0xFFFF || (cle->race() == whom->wrace && (cle->Anon()==0 || admin>cle->Admin()))) && (whomlen == 0 || ( (tmpZone != 0 && strncasecmp(tmpZone, whom->whom, whomlen) == 0) || strncasecmp(cle->name(),whom->whom, whomlen) == 0 || (strncasecmp(guild_mgr.GetGuildName(cle->GuildID()), whom->whom, whomlen) == 0) || (admin >= 100 && strncasecmp(cle->AccountName(), whom->whom, whomlen) == 0) )) )) ) { line[0] = 0; uint32 rankstring=0xFFFFFFFF; if((cle->Anon()==1 && cle->GetGM() && cle->Admin()>admin) || (idx>=20 && admin<100)){ //hide gms that are anon from lesser gms and normal players, cut off at 20 rankstring=0; iterator.Advance(); continue; } else if (cle->GetGM()) { if (cle->Admin() >=250) rankstring=5021; else if (cle->Admin() >= 200) rankstring=5020; else if (cle->Admin() >= 180) rankstring=5019; else if (cle->Admin() >= 170) rankstring=5018; else if (cle->Admin() >= 160) rankstring=5017; else if (cle->Admin() >= 150) rankstring=5016; else if (cle->Admin() >= 100) rankstring=5015; else if (cle->Admin() >= 95) rankstring=5014; else if (cle->Admin() >= 90) rankstring=5013; else if (cle->Admin() >= 85) rankstring=5012; else if (cle->Admin() >= 81) rankstring=5011; else if (cle->Admin() >= 80) rankstring=5010; else if (cle->Admin() >= 50) rankstring=5009; else if (cle->Admin() >= 20) rankstring=5008; else if (cle->Admin() >= 10) rankstring=5007; } idx++; char guildbuffer[67]={0}; if (cle->GuildID() != GUILD_NONE && cle->GuildID()>0) sprintf(guildbuffer,"<%s>", guild_mgr.GetGuildName(cle->GuildID())); uint32 formatstring=5025; if(cle->Anon()==1 && (admin<cle->Admin() || admin==0)) formatstring=5024; else if(cle->Anon()==1 && admin>=cle->Admin() && admin>0) formatstring=5022; else if(cle->Anon()==2 && (admin<cle->Admin() || admin==0)) formatstring=5023;//display guild else if(cle->Anon()==2 && admin>=cle->Admin() && admin>0) formatstring=5022;//display everything //war* wars2 = (war*)pack2->pBuffer; uint32 plclass_=0; uint32 pllevel=0; uint32 pidstring=0xFFFFFFFF;//5003; uint32 plrace=0; uint32 zonestring=0xFFFFFFFF; uint32 plzone=0; uint32 unknown80[2]; if(cle->Anon()==0 || (admin>=cle->Admin() && admin>0)){ plclass_=cle->class_(); pllevel=cle->level(); if(admin>=100) pidstring=5003; plrace=cle->race(); zonestring=5006; plzone=cle->zone(); } if(admin>=cle->Admin() && admin>0) unknown80[0]=cle->Admin(); else unknown80[0]=0xFFFFFFFF; unknown80[1]=0xFFFFFFFF;//1035 //char plstatus[20]={0}; //sprintf(plstatus, "Status %i",cle->Admin()); char plname[64]={0}; strcpy(plname,cle->name()); char placcount[30]={0}; if(admin>=cle->Admin() && admin>0) strcpy(placcount,cle->AccountName()); memcpy(bufptr,&formatstring, sizeof(uint32)); bufptr+=sizeof(uint32); memcpy(bufptr,&pidstring, sizeof(uint32)); bufptr+=sizeof(uint32); memcpy(bufptr,&plname, strlen(plname)+1); bufptr+=strlen(plname)+1; memcpy(bufptr,&rankstring, sizeof(uint32)); bufptr+=sizeof(uint32); memcpy(bufptr,&guildbuffer, strlen(guildbuffer)+1); bufptr+=strlen(guildbuffer)+1; memcpy(bufptr,&unknown80[0], sizeof(uint32)); bufptr+=sizeof(uint32); memcpy(bufptr,&unknown80[1], sizeof(uint32)); bufptr+=sizeof(uint32); memcpy(bufptr,&zonestring, sizeof(uint32)); bufptr+=sizeof(uint32); memcpy(bufptr,&plzone, sizeof(uint32)); bufptr+=sizeof(uint32); memcpy(bufptr,&plclass_, sizeof(uint32)); bufptr+=sizeof(uint32); memcpy(bufptr,&pllevel, sizeof(uint32)); bufptr+=sizeof(uint32); memcpy(bufptr,&plrace, sizeof(uint32)); bufptr+=sizeof(uint32); uint32 ending=0; memcpy(bufptr,&placcount, strlen(placcount)+1); bufptr+=strlen(placcount)+1; ending=207; memcpy(bufptr,&ending, sizeof(uint32)); bufptr+=sizeof(uint32); } iterator.Advance(); } pack2->Deflate(); //zoneserver_list.SendPacket(pack2); // NO NO NO WHY WOULD YOU SEND IT TO EVERY ZONE SERVER?!? SendPacket(to,pack2); safe_delete(pack2); safe_delete_array(output); } catch(...){ Log.Out(Logs::Detail, Logs::World_Server,"Unknown error in world's SendWhoAll (probably mem error), ignoring..."); return; } }
Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std::string in_charname, const glm::vec4& position, std::string time_of_death, bool rezzed, bool was_at_graveyard) { uint32 item_count = database.GetCharacterCorpseItemCount(in_dbid); char *buffer = new char[sizeof(PlayerCorpse_Struct) + (item_count * sizeof(player_lootitem::ServerLootItem_Struct))]; PlayerCorpse_Struct *pcs = (PlayerCorpse_Struct*)buffer; database.LoadCharacterCorpseData(in_dbid, pcs); /* Load Items */ ItemList itemlist; ServerLootItem_Struct* tmp = 0; for (unsigned int i = 0; i < pcs->itemcount; i++) { tmp = new ServerLootItem_Struct; memcpy(tmp, &pcs->items[i], sizeof(player_lootitem::ServerLootItem_Struct)); itemlist.push_back(tmp); } /* Create Corpse Entity */ Corpse* pc = new Corpse( in_dbid, // uint32 in_dbid in_charid, // uint32 in_charid in_charname.c_str(), // char* in_charname &itemlist, // ItemList* in_itemlist pcs->copper, // uint32 in_copper pcs->silver, // uint32 in_silver pcs->gold, // uint32 in_gold pcs->plat, // uint32 in_plat position, pcs->size, // float in_size pcs->gender, // uint8 in_gender pcs->race, // uint16 in_race pcs->class_, // uint8 in_class pcs->deity, // uint8 in_deity pcs->level, // uint8 in_level pcs->texture, // uint8 in_texture pcs->helmtexture, // uint8 in_helmtexture pcs->exp, // uint32 in_rezexp was_at_graveyard // bool wasAtGraveyard ); if (pcs->locked) pc->Lock(); /* Load Item Tints */ pc->item_tint[0].color = pcs->item_tint[0].color; pc->item_tint[1].color = pcs->item_tint[1].color; pc->item_tint[2].color = pcs->item_tint[2].color; pc->item_tint[3].color = pcs->item_tint[3].color; pc->item_tint[4].color = pcs->item_tint[4].color; pc->item_tint[5].color = pcs->item_tint[5].color; pc->item_tint[6].color = pcs->item_tint[6].color; pc->item_tint[7].color = pcs->item_tint[7].color; pc->item_tint[8].color = pcs->item_tint[8].color; /* Load Physical Appearance */ pc->haircolor = pcs->haircolor; pc->beardcolor = pcs->beardcolor; pc->eyecolor1 = pcs->eyecolor1; pc->eyecolor2 = pcs->eyecolor2; pc->hairstyle = pcs->hairstyle; pc->luclinface = pcs->face; pc->beard = pcs->beard; pc->drakkin_heritage = pcs->drakkin_heritage; pc->drakkin_tattoo = pcs->drakkin_tattoo; pc->drakkin_details = pcs->drakkin_details; pc->IsRezzed(rezzed); pc->become_npc = false; pc->spell_light = pc->innate_light = NOT_USED; pc->UpdateEquipLightValue(); //pc->UpdateActiveLightValue(); safe_delete_array(pcs); return pc; }