diff options
-rwxr-xr-x | makepackage_binary.sh | 4 | ||||
-rw-r--r-- | minetest.conf.example | 1 | ||||
-rw-r--r-- | src/constants.h | 2 | ||||
-rw-r--r-- | src/main.cpp | 14 | ||||
-rw-r--r-- | src/map.cpp | 9 | ||||
-rw-r--r-- | src/mapblock.cpp | 89 | ||||
-rw-r--r-- | src/mapblock.h | 4 | ||||
-rw-r--r-- | src/mapnode.h | 18 | ||||
-rw-r--r-- | src/serialization.cpp | 182 | ||||
-rw-r--r-- | src/serialization.h | 7 | ||||
-rw-r--r-- | src/server.cpp | 26 | ||||
-rw-r--r-- | src/test.cpp | 64 | ||||
-rw-r--r-- | src/utility.h | 2 | ||||
-rw-r--r-- | src/voxel.h | 1 |
14 files changed, 368 insertions, 55 deletions
diff --git a/makepackage_binary.sh b/makepackage_binary.sh index 587ba3a63..b8a5e81af 100755 --- a/makepackage_binary.sh +++ b/makepackage_binary.sh @@ -34,8 +34,8 @@ cp -r data/sign_back.png $PACKAGEPATH/data/ cp -r data/rat.png $PACKAGEPATH/data/ cp -r data/mud.png $PACKAGEPATH/data/ cp -r data/torch.png $PACKAGEPATH/data/ -cp -r data/torch_floor.png $PACKAGEPATH/data/ -cp -r data/torch_ceiling.png $PACKAGEPATH/data/ +cp -r data/torch_on_floor.png $PACKAGEPATH/data/ +cp -r data/torch_on_ceiling.png $PACKAGEPATH/data/ cp -r data/skybox1.png $PACKAGEPATH/data/ cp -r data/skybox2.png $PACKAGEPATH/data/ cp -r data/skybox3.png $PACKAGEPATH/data/ diff --git a/minetest.conf.example b/minetest.conf.example index 1ba9a5ba9..3a1226b1a 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -57,5 +57,6 @@ #max_block_generate_distance = 6 #disable_water_climb = true +# Note that this gets applied at map generation time #endless_water = true diff --git a/src/constants.h b/src/constants.h index d59597774..bbd9fa823 100644 --- a/src/constants.h +++ b/src/constants.h @@ -41,6 +41,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #define SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT (60*10) #define SERVER_MAP_SAVE_INTERVAL (60) +/*#define SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT (10) +#define SERVER_MAP_SAVE_INTERVAL (10)*/ #define FOV_ANGLE (PI/2.5) diff --git a/src/main.cpp b/src/main.cpp index 6aa95d879..b1d88090c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -172,25 +172,23 @@ TODO: Remove LazyMeshUpdater. It is not used as supposed. FIXME: Rats somehow go underground sometimes (you can see it in water)
- Does their position get saved to a border value or something?
+ - Does this happen anymore?
SUGG: MovingObject::move and Player::move are basically the same.
combine them.
-TODO: Transfer sign texts as metadata of block and not as data of
- object
-
SUGG: Implement a "Fast check queue" (a queue with a map for checking
if something is already in it)
- - TODO: Use it in active block queue in water flowing
-
-TODO: Proper looking torches.
- - Signs could be done in the same way?
+ - Use it in active block queue in water flowing
-TODO: A mapper to map contents to tile names (for each side)
+SUGG: Signs could be done in the same way as torches. For this, blocks
+ need an additional metadata field for the texts
Doing now:
======================================================================
+TODO: A mapper to map contents to tile names (for each side)
+
======================================================================
*/
diff --git a/src/map.cpp b/src/map.cpp index 8bc914cfd..f9adbd00a 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1504,7 +1504,8 @@ MapSector * ServerMap::emergeSector(v2s16 p2d) sector->setHeightmap(p_in_sector, hm); //TODO: Make these values configurable - hm->generateContinued(1.0, 0.2, corners); + hm->generateContinued(0.0, 0.0, corners); + //hm->generateContinued(1.0, 0.2, corners); //hm->generateContinued(2.0, 0.2, corners); //hm->print(); @@ -3242,8 +3243,8 @@ MapVoxelManipulator::MapVoxelManipulator(Map *map) MapVoxelManipulator::~MapVoxelManipulator() { - dstream<<"MapVoxelManipulator: blocks: "<<m_loaded_blocks.size() - <<std::endl; + /*dstream<<"MapVoxelManipulator: blocks: "<<m_loaded_blocks.size() + <<std::endl;*/ } #if 1 @@ -3358,7 +3359,7 @@ void MapVoxelManipulator::blitBack if(m_area.getExtent() == v3s16(0,0,0)) return; - TimeTaker timer1("blitBack", g_device); + //TimeTaker timer1("blitBack", g_device); /* Initialize block cache diff --git a/src/mapblock.cpp b/src/mapblock.cpp index 7500143c0..4ba597f6a 100644 --- a/src/mapblock.cpp +++ b/src/mapblock.cpp @@ -68,7 +68,7 @@ void MapBlock::setNodeParent(v3s16 p, MapNode & n) } } -FastFace * MapBlock::makeFastFace(u8 material, u8 light, v3f p, +FastFace * MapBlock::makeFastFace(u16 tile, u8 light, v3f p, v3f dir, v3f scale, v3f posRelative_f) { FastFace *f = new FastFace; @@ -111,7 +111,9 @@ FastFace * MapBlock::makeFastFace(u8 material, u8 light, v3f p, u8 alpha = 255; - if(material == CONTENT_WATER || material == CONTENT_OCEAN) + //if(material == CONTENT_WATER || material == CONTENT_OCEAN) + if(tile == CONTENT_WATER || tile == CONTENT_OCEAN) + //if(tile == TILE_WATER) { alpha = 128; } @@ -135,7 +137,7 @@ FastFace * MapBlock::makeFastFace(u8 material, u8 light, v3f p, f->vertices[3] = video::S3DVertex(vertex_pos[3], zerovector, c, core::vector2d<f32>(0,0)); - f->material = material; + f->tile = tile; return f; } @@ -475,7 +477,9 @@ void MapBlock::updateMesh() const u16 indices[] = {0,1,2,2,3,0}; - collector.append(g_materials[f->material], f->vertices, 4, + /*collector.append(g_materials[f->material], f->vertices, 4, + indices, 6);*/ + collector.append(g_materials[f->tile], f->vertices, 4, indices, 6); } @@ -817,8 +821,7 @@ void MapBlock::serialize(std::ostream &os, u8 version) os.write((char*)*dest, dest.getSize()); } - // All otherversions - else + else if(version <= 10) { /* With compression. @@ -857,6 +860,44 @@ void MapBlock::serialize(std::ostream &os, u8 version) compress(pressuredata, os, version); } } + // All other versions (newest) + else + { + // First byte + os.write((char*)&is_underground, 1); + + u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; + + /* + Get data + */ + + SharedBuffer<u8> databuf(nodecount*3); + + // Get contents + for(u32 i=0; i<nodecount; i++) + { + databuf[i] = data[i].d; + } + + // Get params + for(u32 i=0; i<nodecount; i++) + { + databuf[i+nodecount] = data[i].param; + } + + // Get pressure + for(u32 i=0; i<nodecount; i++) + { + databuf[i+nodecount*2] = data[i].pressure; + } + + /* + Compress data to output stream + */ + + compress(databuf, os, version); + } } void MapBlock::deSerialize(std::istream &is, u8 version) @@ -885,8 +926,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version) data[i].deSerialize(*d, version); } } - // All other versions - else + else if(version <= 10) { u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; @@ -936,6 +976,39 @@ void MapBlock::deSerialize(std::istream &is, u8 version) } } } + // All other versions (newest) + else + { + u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; + + u8 t8; + is.read((char*)&t8, 1); + is_underground = t8; + + // Uncompress data + std::ostringstream os(std::ios_base::binary); + decompress(is, os, version); + std::string s = os.str(); + if(s.size() != nodecount*3) + throw SerializationError + ("MapBlock::deSerialize: invalid format"); + + // Set contents + for(u32 i=0; i<nodecount; i++) + { + data[i].d = s[i]; + } + // Set params + for(u32 i=0; i<nodecount; i++) + { + data[i].param = s[i+nodecount]; + } + // Set pressure + for(u32 i=0; i<nodecount; i++) + { + data[i].pressure = s[i+nodecount*2]; + } + } } diff --git a/src/mapblock.h b/src/mapblock.h index 76465903b..f725aa1f5 100644 --- a/src/mapblock.h +++ b/src/mapblock.h @@ -46,7 +46,7 @@ enum{ struct FastFace { - u8 material; + u16 tile; video::S3DVertex vertices[4]; // Precalculated vertices }; @@ -283,7 +283,7 @@ public: setNode(x0+x, y0+y, z0+z, node); } - static FastFace * makeFastFace(u8 material, u8 light, v3f p, + static FastFace * makeFastFace(u16 tile, u8 light, v3f p, v3f dir, v3f scale, v3f posRelative_f); u8 getFaceLight(v3s16 p, v3s16 face_dir); diff --git a/src/mapnode.h b/src/mapnode.h index 9d9aba899..77fd677da 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -66,23 +66,23 @@ enum Content { CONTENT_STONE=0, - CONTENT_GRASS, + CONTENT_GRASS=1, - CONTENT_WATER, + CONTENT_WATER=2, - CONTENT_LIGHT, + CONTENT_LIGHT=3, - CONTENT_TREE, + CONTENT_TREE=4, - CONTENT_LEAVES, + CONTENT_LEAVES=5, - CONTENT_GRASS_FOOTSTEPS, + CONTENT_GRASS_FOOTSTEPS=6, - CONTENT_MESE, + CONTENT_MESE=7, - CONTENT_MUD, + CONTENT_MUD=8, - CONTENT_OCEAN, + CONTENT_OCEAN=9, // This is set to the number of the actual values in this enum USEFUL_CONTENT_COUNT diff --git a/src/serialization.cpp b/src/serialization.cpp index 57db2b40f..eb80f3c60 100644 --- a/src/serialization.cpp +++ b/src/serialization.cpp @@ -17,18 +17,184 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -/* -(c) 2010 Perttu Ahola <celeron55@gmail.com> -*/ - #include "serialization.h" #include "utility.h" +#include "zlib.h" + +/* report a zlib or i/o error */ +void zerr(int ret) +{ + fputs("zerr: ", stderr); + switch (ret) { + case Z_ERRNO: + if (ferror(stdin)) + fputs("error reading stdin\n", stderr); + if (ferror(stdout)) + fputs("error writing stdout\n", stderr); + break; + case Z_STREAM_ERROR: + fputs("invalid compression level\n", stderr); + break; + case Z_DATA_ERROR: + fputs("invalid or incomplete deflate data\n", stderr); + break; + case Z_MEM_ERROR: + fputs("out of memory\n", stderr); + break; + case Z_VERSION_ERROR: + fputs("zlib version mismatch!\n", stderr); + break; + default: + dstream<<"return value = "<<ret<<"\n"; + } +} + +void compressZlib(SharedBuffer<u8> data, std::ostream &os) +{ + z_stream z; + const s32 bufsize = 16384; + //char input_buffer[bufsize]; + char output_buffer[bufsize]; + int input_i = 0; + int status = 0; + int ret; + + z.zalloc = Z_NULL; + z.zfree = Z_NULL; + z.opaque = Z_NULL; + + ret = deflateInit(&z, -1); + if(ret != Z_OK) + throw SerializationError("compressZlib: deflateInit failed"); + + z.avail_in = 0; + + for(;;) + { + int flush = Z_NO_FLUSH; + z.next_out = (Bytef*)output_buffer; + z.avail_out = bufsize; + + if(z.avail_in == 0) + { + //z.next_in = (char*)&data[input_i]; + z.next_in = (Bytef*)&data[input_i]; + z.avail_in = data.getSize() - input_i; + input_i += z.avail_in; + if(input_i == (int)data.getSize()) + flush = Z_FINISH; + } + if(z.avail_in == 0) + break; + status = deflate(&z, flush); + if(status == Z_NEED_DICT || status == Z_DATA_ERROR + || status == Z_MEM_ERROR) + { + zerr(status); + throw SerializationError("compressZlib: deflate failed"); + } + int count = bufsize - z.avail_out; + if(count) + os.write(output_buffer, count); + } + + deflateEnd(&z); + +} + +void decompressZlib(std::istream &is, std::ostream &os) +{ + z_stream z; + const s32 bufsize = 16384; + char input_buffer[bufsize]; + char output_buffer[bufsize]; + int status = 0; + int ret; + int bytes_read = 0; + int input_buffer_len = 0; + + z.zalloc = Z_NULL; + z.zfree = Z_NULL; + z.opaque = Z_NULL; + + ret = inflateInit(&z); + if(ret != Z_OK) + throw SerializationError("compressZlib: inflateInit failed"); + + z.avail_in = 0; + + //dstream<<"initial fail="<<is.fail()<<" bad="<<is.bad()<<std::endl; + + for(;;) + { + z.next_out = (Bytef*)output_buffer; + z.avail_out = bufsize; + + if(z.avail_in == 0) + { + z.next_in = (Bytef*)input_buffer; + input_buffer_len = is.readsome(input_buffer, bufsize); + z.avail_in = input_buffer_len; + //dstream<<"read fail="<<is.fail()<<" bad="<<is.bad()<<std::endl; + } + if(z.avail_in == 0) + { + //dstream<<"z.avail_in == 0"<<std::endl; + break; + } + + //dstream<<"1 z.avail_in="<<z.avail_in<<std::endl; + status = inflate(&z, Z_NO_FLUSH); + //dstream<<"2 z.avail_in="<<z.avail_in<<std::endl; + bytes_read += is.gcount() - z.avail_in; + //dstream<<"bytes_read="<<bytes_read<<std::endl; + + if(status == Z_NEED_DICT || status == Z_DATA_ERROR + || status == Z_MEM_ERROR) + { + zerr(status); + throw SerializationError("compressZlib: inflate failed"); + } + int count = bufsize - z.avail_out; + //dstream<<"count="<<count<<std::endl; + if(count) + os.write(output_buffer, count); + if(status == Z_STREAM_END) + { + //dstream<<"Z_STREAM_END"<<std::endl; + + //dstream<<"z.avail_in="<<z.avail_in<<std::endl; + //dstream<<"fail="<<is.fail()<<" bad="<<is.bad()<<std::endl; + // Unget all the data that inflate didn't take + for(u32 i=0; i < z.avail_in; i++) + { + is.unget(); + if(is.fail() || is.bad()) + { + dstream<<"unget #"<<i<<" failed"<<std::endl; + dstream<<"fail="<<is.fail()<<" bad="<<is.bad()<<std::endl; + throw SerializationError("compressZlib: unget failed"); + } + } + + break; + } + } + + inflateEnd(&z); +} void compress(SharedBuffer<u8> data, std::ostream &os, u8 version) { - if(data.getSize() == 0) + if(version >= 11) + { + compressZlib(data, os); return; + } + if(data.getSize() == 0) + return; + // Write length (u32) u8 tmp[4]; @@ -63,6 +229,12 @@ void compress(SharedBuffer<u8> data, std::ostream &os, u8 version) void decompress(std::istream &is, std::ostream &os, u8 version) { + if(version >= 11) + { + decompressZlib(is, os); + return; + } + // Read length (u32) u8 tmp[4]; diff --git a/src/serialization.h b/src/serialization.h index 8d3c5fee2..c15a2a235 100644 --- a/src/serialization.h +++ b/src/serialization.h @@ -17,10 +17,6 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -/* -(c) 2010 Perttu Ahola <celeron55@gmail.com> -*/ - #ifndef SERIALIZATION_HEADER #define SERIALIZATION_HEADER @@ -47,11 +43,12 @@ with this program; if not, write to the Free Software Foundation, Inc., 8: (dev) server-initiated block transfers and all kinds of stuff 9: (dev) block objects 10: (dev) water pressure + 11: (dev) zlib'd blocks */ // This represents an uninitialized or invalid format #define SER_FMT_VER_INVALID 255 // Highest supported serialization version -#define SER_FMT_VER_HIGHEST 10 +#define SER_FMT_VER_HIGHEST 11 // Lowest supported serialization version #define SER_FMT_VER_LOWEST 2 diff --git a/src/server.cpp b/src/server.cpp index c7b589e7a..139731a9c 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -412,8 +412,10 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime, maximum_simultaneous_block_sends; if(d <= BLOCK_SEND_DISABLE_LIMITS_MAX_D) - maximum_simultaneous_block_sends_now = - maximum_simultaneous_block_sends_setting; + { + maximum_simultaneous_block_sends_now = + maximum_simultaneous_block_sends_setting; + } { JMutexAutoLock lock(m_blocks_sending_mutex); @@ -971,11 +973,19 @@ void Server::AsyncRunStep() { JMutexAutoLock lock1(m_step_dtime_mutex); dtime = m_step_dtime; - if(dtime < 0.001) - return; - m_step_dtime = 0.0; } + // Send blocks to clients + SendBlocks(dtime); + + if(dtime < 0.001) + return; + + { + JMutexAutoLock lock1(m_step_dtime_mutex); + m_step_dtime = 0.0; + } + //dstream<<"Server steps "<<dtime<<std::endl; //dstream<<"Server::AsyncRunStep(): dtime="<<dtime<<std::endl; @@ -1098,9 +1108,6 @@ void Server::AsyncRunStep() } }*/ - // Send blocks to clients - SendBlocks(dtime); - // Send object positions { static float counter = 0.0; @@ -1876,7 +1883,8 @@ void Server::SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver) writeS16(&reply[6], p.Z); memcpy(&reply[8], *blockdata, blockdata.getSize()); - //dstream<<"Sending block: packet size: "<<replysize<<std::endl; + dstream<<"Sending block ("<<p.X<<","<<p.Y<<","<<p.Z<<")" + <<": \tpacket size: "<<replysize<<std::endl; /* Send packet diff --git a/src/test.cpp b/src/test.cpp index 6d71566f4..91d7c1e40 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -72,6 +72,8 @@ struct TestCompress { void Run() { + { // ver 0 + SharedBuffer<u8> fromdata(4); fromdata[0]=1; fromdata[1]=5; @@ -123,6 +125,64 @@ struct TestCompress { assert(str_out2[i] == fromdata[i]); } + + } + + { // ver HIGHEST + + SharedBuffer<u8> fromdata(4); + fromdata[0]=1; + fromdata[1]=5; + fromdata[2]=5; + fromdata[3]=1; + + std::ostringstream os(std::ios_base::binary); + compress(fromdata, os, SER_FMT_VER_HIGHEST); + + std::string str_out = os.str(); + + dstream<<"str_out.size()="<<str_out.size()<<std::endl; + dstream<<"TestCompress: 1,5,5,1 -> "; + for(u32 i=0; i<str_out.size(); i++) + { + dstream<<(u32)str_out[i]<<","; + } + dstream<<std::endl; + + /*assert(str_out.size() == 10); + + assert(str_out[0] == 0); + assert(str_out[1] == 0); + assert(str_out[2] == 0); + assert(str_out[3] == 4); + assert(str_out[4] == 0); + assert(str_out[5] == 1); + assert(str_out[6] == 1); + assert(str_out[7] == 5); + assert(str_out[8] == 0); + assert(str_out[9] == 1);*/ + + std::istringstream is(str_out, std::ios_base::binary); + std::ostringstream os2(std::ios_base::binary); + + decompress(is, os2, SER_FMT_VER_HIGHEST); + std::string str_out2 = os2.str(); + + dstream<<"decompress: "; + for(u32 i=0; i<str_out2.size(); i++) + { + dstream<<(u32)str_out2[i]<<","; + } + dstream<<std::endl; + + assert(str_out2.size() == fromdata.getSize()); + + for(u32 i=0; i<str_out2.size(); i++) + { + assert(str_out2[i] == fromdata[i]); + } + + } } }; @@ -273,8 +333,8 @@ struct TestVoxelManipulator active_nodes.clear(); active_nodes[v3s16(9,1,0)] = 1; - //v.flowWater(active_nodes, 0, false); - v.flowWater(active_nodes, 0, true, 1000); + //v.flowWater(active_nodes, 0, true, 1000); + v.flowWater(active_nodes, 0, false, 1000); dstream<<"Final result of flowWater:"<<std::endl; v.print(dstream, VOXELPRINT_WATERPRESSURE); diff --git a/src/utility.h b/src/utility.h index d22e1d651..4c9a2d73a 100644 --- a/src/utility.h +++ b/src/utility.h @@ -461,12 +461,12 @@ inline void getFacePositions(core::list<v3s16> &list, u16 d) /* This is an optimized sequence of coordinates. */ + list.push_back(v3s16( 0, 1, 0)); // top list.push_back(v3s16( 0, 0, 1)); // back list.push_back(v3s16(-1, 0, 0)); // left list.push_back(v3s16( 1, 0, 0)); // right list.push_back(v3s16( 0, 0,-1)); // front list.push_back(v3s16( 0,-1, 0)); // bottom - list.push_back(v3s16( 0, 1, 0)); // top // 6 list.push_back(v3s16(-1, 0, 1)); // back left list.push_back(v3s16( 1, 0, 1)); // back right diff --git a/src/voxel.h b/src/voxel.h index 43e0baa7a..a90fc37e8 100644 --- a/src/voxel.h +++ b/src/voxel.h @@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "debug.h" #include "mapnode.h" +// For VC++ #undef min #undef max |