static void get_range(const char **s) { range_from = get_add(s); if ( **s != '-' ) { range_to = range_from; } else { (*s)++; skip_space(s); range_to = get_add(s); } }
static void map_cmd(const char **s) { if ( **s == '*' ) { range_from = 32; range_to = 255; map_to = 32; is_exclude = 0; (*s)++; skip_space(s); } else if ( **s == '~' ) { is_exclude = 1; map_to = 0; /*will be ignored */ (*s)++; skip_space(s); get_range(s); } else { is_exclude = 0; get_range(s); map_to = range_from; if ( **s == '>') { (*s)++; skip_space(s); map_to = get_add(s); } } }
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; }