bool GzipOutputStream::Flush() { zerror_ = Deflate(Z_FULL_FLUSH); // Return true if the flush succeeded or if it was a no-op. return (zerror_ == Z_OK) || (zerror_ == Z_BUF_ERROR && zcontext_.avail_in == 0 && zcontext_.avail_out != 0); }
BOOL Flate::Compress(CByteArray& dst, const BYTE* src, UINT srcLen) { CBAStreamReader sr(src, srcLen); CBAStreamWriter sw(dst); Deflate(&sw, &sr); return dst.GetSize() != 0; }
public func FxControlFloatTimer(object target, proplist effect, int time) { // Balloon deflates if any vertex has contact if (GetContact(-1, CNAT_Bottom)) { Deflate(); return FX_Execute_Kill; } return _inherited(target, effect, time, ...); }
bool GzipOutputStream::Close() { if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) { return false; } do { zerror_ = Deflate(Z_FINISH); } while (zerror_ == Z_OK); zerror_ = deflateEnd(&zcontext_); bool ok = zerror_ == Z_OK; zerror_ = Z_STREAM_END; return ok; }
qint64 CCompressedConnection::writeToNetwork(qint64 nBytes) { if(m_bCompressedOutput) { if(m_pOutput->size() == 0) { Deflate(); } } return CNetworkConnection::writeToNetwork(nBytes); }
void OnMouseMove(wxMouseEvent& e) { auto rectWin = GetClientRect(); rectWin.Deflate(1); // work around off-by-one issue on OS X auto evtWin = static_cast<wxWindow*>(e.GetEventObject()); auto mpos = e.GetPosition(); if (evtWin != this) mpos += evtWin->GetPosition(); bool highlighted = rectWin.Contains(mpos); SetBackgroundColour(highlighted ? m_bgHighlight : m_bg); Refresh(); }
void Code(FILE *input_file, FILE *output_file) { switch (test_mode) { case DEFLATE_MODE: { Deflate(input_file, output_file); break; } case INFLATE_MODE: { Inflate(input_file, output_file); break; } default: { ERROR("invalid mode: %d", test_mode); } } }
void ZSList::SendEmoteMessageRaw(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message) { if (!message) return; auto pack = new ServerPacket; pack->opcode = ServerOP_EmoteMessage; pack->size = sizeof(ServerEmoteMessage_Struct)+strlen(message)+1; pack->pBuffer = new uchar[pack->size]; memset(pack->pBuffer, 0, pack->size); ServerEmoteMessage_Struct* sem = (ServerEmoteMessage_Struct*) pack->pBuffer; if (to) { if (to[0] == '*') { Console* con = console_list.FindByAccountName(&to[1]); if (con) con->SendEmoteMessageRaw(to, to_guilddbid, to_minstatus, type, message); delete pack; return; } strcpy((char *) sem->to, to); } else { sem->to[0] = 0; } sem->guilddbid = to_guilddbid; sem->minstatus = to_minstatus; sem->type = type; strcpy(&sem->message[0], message); char tempto[64]={0}; if(to) strn0cpy(tempto,to,64); pack->Deflate(); if (tempto[0] == 0) { SendPacket(pack); if (to_guilddbid == 0) console_list.SendEmoteMessageRaw(type, message); } else { ZoneServer* zs = FindByName(to); if (zs != 0) zs->SendPacket(pack); else SendPacket(pack); } delete pack; }
// implements ZeroCopyOutputStream --------------------------------- bool GzipOutputStream::Next(void** data, int* size) { if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) { return false; } if (zcontext_.avail_in != 0) { zerror_ = Deflate(Z_NO_FLUSH); if (zerror_ != Z_OK) { return false; } } if (zcontext_.avail_in == 0) { // all input was consumed. reset the buffer. zcontext_.next_in = static_cast<Bytef*>(input_buffer_); zcontext_.avail_in = input_buffer_length_; *data = input_buffer_; *size = input_buffer_length_; } else { // The loop in Deflate should consume all avail_in GOOGLE_LOG(DFATAL) << "Deflate left bytes unconsumed"; } return true; }
void ZSList::SendChannelMessageRaw(const char* from, const char* to, uint8 chan_num, uint8 language, const char* message) { if (!message) return; auto pack = new ServerPacket; pack->opcode = ServerOP_ChannelMessage; pack->size = sizeof(ServerChannelMessage_Struct)+strlen(message)+1; pack->pBuffer = new uchar[pack->size]; memset(pack->pBuffer, 0, pack->size); ServerChannelMessage_Struct* scm = (ServerChannelMessage_Struct*) pack->pBuffer; if (from == 0) { strcpy(scm->from, "WServer"); scm->noreply = true; } else if (from[0] == 0) { strcpy(scm->from, "WServer"); scm->noreply = true; } else strcpy(scm->from, from); if (to != 0) { strcpy((char *) scm->to, to); strcpy((char *) scm->deliverto, to); } else { scm->to[0] = 0; scm->deliverto[0] = 0; } scm->language = language; scm->chan_num = chan_num; strcpy(&scm->message[0], message); if (scm->chan_num == 5 || scm->chan_num == 6 || scm->chan_num == 11) { console_list.SendChannelMessage(scm); } pack->Deflate(); SendPacket(pack); delete pack; }
void CV8File::Deflate(char *filename_in, char *filename_out) { HANDLE hFile=CreateFile(filename_in,GENERIC_READ,FILE_SHARE_READ,NULL, OPEN_EXISTING,0,NULL); if(hFile != INVALID_HANDLE_VALUE) { DWORD FileSizeLow=GetFileSize(hFile,NULL); HANDLE hFileMapping=CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL); CloseHandle(hFile); if(hFileMapping != NULL) { unsigned char *pFileData = (unsigned char *)MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,FileSizeLow); BYTE *DataOut = NULL; CV8File V8File; UINT packed_size = Deflate(pFileData, FileSizeLow, &DataOut); FILE *file_metadata; file_metadata = fopen(filename_out, "wb"); fwrite(DataOut, 1, packed_size, file_metadata); fclose(file_metadata); free(DataOut); UnmapViewOfFile(pFileData); CloseHandle(hFileMapping); } } }
void CSG_Rect::Deflate(double d, bool bPercent) { Deflate(d, d, bPercent); }
void ClientList::SendLFGMatches(ServerLFGMatchesRequest_Struct *smrs) { // Send back matches when someone searches player's Looking For A Group. LinkedListIterator<ClientListEntry*> Iterator(clientlist); ClientListEntry* CLE = 0; int Matches = 0; Iterator.Reset(); // We run the ClientList twice. The first time is to determine how big the outgoing packet needs to be. while(Iterator.MoreElements()) { CLE = Iterator.GetData(); if(CLE->LFG()) { unsigned int BitMask = 1 << CLE->class_(); // First we check that the player meets the level and class criteria of the person // doing the search. if((CLE->level() >= smrs->FromLevel) && (CLE->level() <= smrs->ToLevel) && (BitMask & smrs->Classes)) // Then we check if if the player doing the search meets the level criteria specified // by the player who is LFG. // // GetLFGMatchFilter returns the setting of the 'Only players who match my posted filters // can query me' checkbox. // // FromLevel and ToLevel are the settings of the 'Want group levels:' boxes. if(!CLE->GetLFGMatchFilter() || ((smrs->QuerierLevel >= CLE->GetLFGFromLevel()) && (smrs->QuerierLevel <= CLE->GetLFGToLevel()))) Matches++; } Iterator.Advance(); } auto Pack = new ServerPacket(ServerOP_LFGMatches, (sizeof(ServerLFGMatchesResponse_Struct) * Matches) + 4); char *Buf = (char *)Pack->pBuffer; // FromID is the Entity ID of the player doing the search. VARSTRUCT_ENCODE_TYPE(uint32, Buf, smrs->FromID); ServerLFGMatchesResponse_Struct* Buffer = (ServerLFGMatchesResponse_Struct*)Buf; Iterator.Reset(); if(Matches) { while(Iterator.MoreElements() && (Matches > 0)) { CLE = Iterator.GetData(); if(CLE->LFG()) { unsigned int BitMask = 1 << CLE->class_(); if((CLE->level() >= smrs->FromLevel) && (CLE->level() <= smrs->ToLevel) && (BitMask & smrs->Classes)) { Matches--; strcpy(Buffer->Name, CLE->name()); Buffer->Class_ = CLE->class_(); Buffer->Level = CLE->level(); Buffer->Zone = CLE->zone(); // If the LFG player is anon, level and class are still displayed, but // zone shows as UNAVAILABLE. Buffer->Anon = (CLE->Anon() != 0); // The client can filter on Guildname Buffer->GuildID = CLE->GuildID(); strcpy(Buffer->Comments, CLE->GetLFGComments()); Buffer++; } } Iterator.Advance(); } Pack->Deflate(); } SendPacket(smrs->FromName,Pack); safe_delete(Pack); }
void ClientList::SendFriendsWho(ServerFriendsWho_Struct *FriendsWho, WorldTCPConnection* connection) { std::vector<ClientListEntry*> FriendsCLEs; FriendsCLEs.reserve(100); char Friend_[65]; char *FriendsPointer = FriendsWho->FriendsString; // FriendsString is a comma delimited list of names. char *Seperator = nullptr; Seperator = strchr(FriendsPointer, ','); if(!Seperator) Seperator = strchr(FriendsPointer, '\0'); uint32 TotalLength=0; while(Seperator != nullptr) { if((Seperator - FriendsPointer) > 64) return; strncpy(Friend_, FriendsPointer, Seperator - FriendsPointer); Friend_[Seperator - FriendsPointer] = 0; ClientListEntry* CLE = FindCharacter(Friend_); if(CLE && CLE->name() && (CLE->Online() >= CLE_Status_Zoning) && !(CLE->GetGM() && CLE->Anon())) { FriendsCLEs.push_back(CLE); TotalLength += strlen(CLE->name()); int GuildNameLength = strlen(guild_mgr.GetGuildName(CLE->GuildID())); if(GuildNameLength>0) TotalLength += (GuildNameLength + 2); } if(Seperator[0] == '\0') break; FriendsPointer = Seperator + 1; Seperator = strchr(FriendsPointer, ','); if(!Seperator) Seperator = strchr(FriendsPointer, '\0'); } try{ ClientListEntry* cle; int FriendsOnline = FriendsCLEs.size(); int PacketLength = sizeof(WhoAllReturnStruct) + (47 * FriendsOnline) + TotalLength; auto pack2 = new ServerPacket(ServerOP_WhoAllReply, PacketLength); memset(pack2->pBuffer,0,pack2->size); uchar *buffer=pack2->pBuffer; uchar *bufptr=buffer; WhoAllReturnStruct *WARS = (WhoAllReturnStruct *)bufptr; WARS->id = FriendsWho->FromID; WARS->playerineqstring = 0xffffffff; strcpy(WARS->line, ""); WARS->unknown35 = 0x0a; WARS->unknown36 = 0x00; if(FriendsCLEs.size() == 1) WARS->playersinzonestring = 5028; // 5028 There is %1 player in EverQuest. else WARS->playersinzonestring = 5036; // 5036 There are %1 players in EverQuest. WARS->unknown44[0] = 0; WARS->unknown44[1] = 0; WARS->unknown52 = FriendsOnline; WARS->unknown56 = 1; WARS->playercount = FriendsOnline; bufptr+=sizeof(WhoAllReturnStruct); for(int CLEEntry = 0; CLEEntry < FriendsOnline; CLEEntry++) { cle = FriendsCLEs[CLEEntry]; char GuildName[67]={0}; if (cle->GuildID() != GUILD_NONE && cle->GuildID()>0) sprintf(GuildName,"<%s>", guild_mgr.GetGuildName(cle->GuildID())); uint32 FormatMSGID=5025; // 5025 %T1[%2 %3] %4 (%5) %6 %7 %8 %9 if(cle->Anon()==1) FormatMSGID=5024; // 5024 %T1[ANONYMOUS] %2 %3 else if(cle->Anon()==2) FormatMSGID=5023; // 5023 %T1[ANONYMOUS] %2 %3 %4 uint32 PlayerClass=0; uint32 PlayerLevel=0; uint32 PlayerRace=0; uint32 ZoneMSGID=0xffffffff; uint32 PlayerZone=0; if(cle->Anon()==0) { PlayerClass=cle->class_(); PlayerLevel=cle->level(); PlayerRace=cle->race(); ZoneMSGID=5006; // 5006 ZONE: %1 PlayerZone=cle->zone(); } char PlayerName[64]={0}; strcpy(PlayerName,cle->name()); WhoAllPlayerPart1* WAPP1 = (WhoAllPlayerPart1*)bufptr; WAPP1->FormatMSGID = FormatMSGID; WAPP1->PIDMSGID = 0xffffffff; strcpy(WAPP1->Name, PlayerName); bufptr += sizeof(WhoAllPlayerPart1) + strlen(PlayerName); WhoAllPlayerPart2* WAPP2 = (WhoAllPlayerPart2*)bufptr; WAPP2->RankMSGID = 0xffffffff; strcpy(WAPP2->Guild, GuildName); bufptr += sizeof(WhoAllPlayerPart2) + strlen(GuildName); WhoAllPlayerPart3* WAPP3 = (WhoAllPlayerPart3*)bufptr; WAPP3->Unknown80[0] = 0xffffffff; WAPP3->Unknown80[1] = 0xffffffff; WAPP3->ZoneMSGID = ZoneMSGID; WAPP3->Zone = PlayerZone; WAPP3->Class_ = PlayerClass; WAPP3->Level = PlayerLevel; WAPP3->Race = PlayerRace; WAPP3->Account[0] = 0; bufptr += sizeof(WhoAllPlayerPart3); WhoAllPlayerPart4* WAPP4 = (WhoAllPlayerPart4*)bufptr; WAPP4->Unknown100 = 207; bufptr += sizeof(WhoAllPlayerPart4); } pack2->Deflate(); SendPacket(FriendsWho->FromName,pack2); safe_delete(pack2); } catch(...){ Log.Out(Logs::Detail, Logs::World_Server,"Unknown error in world's SendFriendsWho (probably mem error), ignoring..."); return; } }
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; } }
ColumnContainer::PacketType ColumnContainer::ToChunkData () const { // This gives all chunks from // bottom-to-top which are not // all air bool chunks [16]; std::memset(chunks,0,sizeof(chunks)); // This gives all chunks from // bottom-to-top which require the // "add" array bool add [16]; std::memset(add,0,sizeof(add)); // Scan all blocks to determine // // A. Which chunks we need to send. // B. Which of A need the add array. Word chunk=0; Word next_chunk=16*16*16; for (Word i=0;i<(16*16*16*16);++i) { // Maintain record of which // chunk we're in if (i==next_chunk) { next_chunk+=16*16*16; ++chunk; } // Type of this block auto type=Blocks[i].GetType(); // Are we sending this chunk? if (type!=0) { // YES chunks[chunk]=true; // Is the block type too large // for one byte? I.e. do we have // to send the add array for this // chunk? if (type>std::numeric_limits<Byte>::max()) add[chunk]=true; } } // Do we have to send skylight? bool skylight=HasSkylight(id.Dimension); // Determine the masks that we'll be // sending, the start offset of the // "add" array, as well as the distance // between arrays Word add_offset=0; UInt16 primary_mask=0; UInt16 add_mask=0; Word spacing=0; for (Word i=0;i<16;++i) if (chunks[i]) { // The "spacing" of arrays, i.e. // if the block type array starts // at index 0, at what index does the // metadata array begin? spacing+=16*16*16; UInt16 mask=1<<i; // Add bit in appropriate // position to mask primary_mask|=mask; // Offset the start of the // "add" array appropriately add_offset+=16*16*16*2; if (skylight) add_offset+=(16*16*16)/2; // If the "add" array will be // sent for this chunk, update // the mask if (add[i]) add_mask|=mask; } // Create a buffer on the stack big // enough to hold the largest possible // packet in Mojang format Byte column [(16*16*16*16*3)+(16*16)]; // Loop and convert Word offset=0; Word nibble_offset=spacing; spacing/=2; chunk=0; next_chunk=16*16*16; bool even=true; for (Word i=0;i<(16*16*16*16);++i) { // Advance to next chunk if // necessary if (i==next_chunk) { next_chunk+=16*16*16; ++chunk; } // Skip null chunks if (!chunks[chunk]) { i+=(16*16*16)-1; continue; } // Current block const auto & b=Blocks[i]; // Write non-"add" byte of block // type column[offset++]=static_cast<Byte>(b.GetType()); Word curr=nibble_offset; // Write nibbles if (even) { // Metadata column[curr]=b.GetMetadata()<<4; // Light column[curr+=spacing]=b.GetLight()<<4; // Skylight (if applicable) if (skylight) column[curr+spacing]=b.GetSkylight()<<4; // "Add" (if applicable) if (add[chunk]) column[add_offset]=get_add(b)<<4; } else { // Metadata column[curr]|=b.GetMetadata(); // Light column[curr+=spacing]|=b.GetLight(); // Skylight (if applicable) if (skylight) column[curr+spacing]|=b.GetSkylight(); // "Add" (if applicable) if (add[chunk]) column[add_offset++]|=get_add(b); // After every odd/even pair, // we move onto the next full // byte ++nibble_offset; } even=!even; } // Copy biomes std::memcpy( column+add_offset, Biomes, sizeof(Biomes) ); // Prepare a packet PacketType retr; retr.X=id.X; retr.Z=id.Z; retr.Continuous=true; retr.Primary=primary_mask; retr.Add=add_mask; retr.Data=Deflate( column, column+add_offset+sizeof(Biomes) ); return retr; }