mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 10:03:45 +01:00
Node definition names
This commit is contained in:
parent
50d63e4b0a
commit
c0f6395cf0
@ -94,6 +94,7 @@ configure_file(
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(common_SRCS
|
set(common_SRCS
|
||||||
|
nameidmapping.cpp
|
||||||
tooldef.cpp
|
tooldef.cpp
|
||||||
nodedef.cpp
|
nodedef.cpp
|
||||||
luaentity_common.cpp
|
luaentity_common.cpp
|
||||||
|
@ -848,7 +848,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
|||||||
//TimeTaker t1("TOCLIENT_ADDNODE");
|
//TimeTaker t1("TOCLIENT_ADDNODE");
|
||||||
|
|
||||||
MapNode n;
|
MapNode n;
|
||||||
n.deSerialize(&data[8], ser_version, m_nodedef);
|
n.deSerialize(&data[8], ser_version);
|
||||||
|
|
||||||
addNode(p, n);
|
addNode(p, n);
|
||||||
}
|
}
|
||||||
@ -2331,4 +2331,11 @@ ITextureSource* Client::getTextureSource()
|
|||||||
{
|
{
|
||||||
return m_tsrc;
|
return m_tsrc;
|
||||||
}
|
}
|
||||||
|
u16 Client::allocateUnknownNodeId(const std::string &name)
|
||||||
|
{
|
||||||
|
errorstream<<"Client::allocateUnknownNodeId(): "
|
||||||
|
<<"Client cannot allocate node IDs"<<std::endl;
|
||||||
|
assert(0);
|
||||||
|
return CONTENT_IGNORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -324,10 +324,10 @@ public:
|
|||||||
float getRTT(void);
|
float getRTT(void);
|
||||||
|
|
||||||
// IGameDef interface
|
// IGameDef interface
|
||||||
// Under envlock
|
|
||||||
virtual IToolDefManager* getToolDefManager();
|
virtual IToolDefManager* getToolDefManager();
|
||||||
virtual INodeDefManager* getNodeDefManager();
|
virtual INodeDefManager* getNodeDefManager();
|
||||||
virtual ITextureSource* getTextureSource();
|
virtual ITextureSource* getTextureSource();
|
||||||
|
virtual u16 allocateUnknownNodeId(const std::string &name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -42,6 +42,10 @@ extern content_t trans_table_19[21][2];
|
|||||||
MapNode mapnode_translate_from_internal(MapNode n_from, u8 version);
|
MapNode mapnode_translate_from_internal(MapNode n_from, u8 version);
|
||||||
MapNode mapnode_translate_to_internal(MapNode n_from, u8 version);
|
MapNode mapnode_translate_to_internal(MapNode n_from, u8 version);
|
||||||
|
|
||||||
|
// Get legacy node name mapping
|
||||||
|
class NameIdMapping;
|
||||||
|
void content_mapnode_get_name_id_mapping(NameIdMapping *nimap);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Node content type IDs
|
Node content type IDs
|
||||||
Ranges:
|
Ranges:
|
||||||
|
@ -20,6 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#ifndef GAMEDEF_HEADER
|
#ifndef GAMEDEF_HEADER
|
||||||
#define GAMEDEF_HEADER
|
#define GAMEDEF_HEADER
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
class IToolDefManager;
|
class IToolDefManager;
|
||||||
class INodeDefManager;
|
class INodeDefManager;
|
||||||
//class IItemDefManager; //TODO
|
//class IItemDefManager; //TODO
|
||||||
@ -43,6 +45,9 @@ public:
|
|||||||
// This is always thread-safe, but referencing the irrlicht texture
|
// This is always thread-safe, but referencing the irrlicht texture
|
||||||
// pointers in other threads than main thread will make things explode.
|
// pointers in other threads than main thread will make things explode.
|
||||||
virtual ITextureSource* getTextureSource()=0;
|
virtual ITextureSource* getTextureSource()=0;
|
||||||
|
|
||||||
|
// Used for keeping track of names/ids of unknown nodes
|
||||||
|
virtual u16 allocateUnknownNodeId(const std::string &name)=0;
|
||||||
|
|
||||||
// Shorthands
|
// Shorthands
|
||||||
IToolDefManager* tdef(){return getToolDefManager();}
|
IToolDefManager* tdef(){return getToolDefManager();}
|
||||||
|
@ -3367,10 +3367,10 @@ void ServerMap::loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool
|
|||||||
Save blocks loaded in old format in new format
|
Save blocks loaded in old format in new format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(version < SER_FMT_VER_HIGHEST || save_after_load)
|
//if(version < SER_FMT_VER_HIGHEST || save_after_load)
|
||||||
{
|
// Only save if asked to; no need to update version
|
||||||
|
if(save_after_load)
|
||||||
saveBlock(block);
|
saveBlock(block);
|
||||||
}
|
|
||||||
|
|
||||||
// We just loaded it from, so it's up-to-date.
|
// We just loaded it from, so it's up-to-date.
|
||||||
block->resetModified();
|
block->resetModified();
|
||||||
|
129
src/mapblock.cpp
129
src/mapblock.cpp
@ -18,14 +18,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mapblock.h"
|
#include "mapblock.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
// For g_settings
|
// For g_settings
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "light.h"
|
#include "light.h"
|
||||||
#include <sstream>
|
|
||||||
#include "nodedef.h"
|
#include "nodedef.h"
|
||||||
#include "nodemetadata.h"
|
#include "nodemetadata.h"
|
||||||
#include "gamedef.h"
|
#include "gamedef.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "nameidmapping.h"
|
||||||
|
#include "content_mapnode.h" // For legacy name-id mapping
|
||||||
|
|
||||||
/*
|
/*
|
||||||
MapBlock
|
MapBlock
|
||||||
@ -188,13 +192,13 @@ void MapBlock::replaceMesh(scene::SMesh *mesh_new)
|
|||||||
IMeshBuffer *buf = mesh_old->getMeshBuffer(i);
|
IMeshBuffer *buf = mesh_old->getMeshBuffer(i);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
/*dstream<<"mesh_old->getReferenceCount()="
|
/*infostream<<"mesh_old->getReferenceCount()="
|
||||||
<<mesh_old->getReferenceCount()<<std::endl;
|
<<mesh_old->getReferenceCount()<<std::endl;
|
||||||
u32 c = mesh_old->getMeshBufferCount();
|
u32 c = mesh_old->getMeshBufferCount();
|
||||||
for(u32 i=0; i<c; i++)
|
for(u32 i=0; i<c; i++)
|
||||||
{
|
{
|
||||||
scene::IMeshBuffer *buf = mesh_old->getMeshBuffer(i);
|
scene::IMeshBuffer *buf = mesh_old->getMeshBuffer(i);
|
||||||
dstream<<"buf->getReferenceCount()="
|
infostream<<"buf->getReferenceCount()="
|
||||||
<<buf->getReferenceCount()<<std::endl;
|
<<buf->getReferenceCount()<<std::endl;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
@ -519,6 +523,86 @@ s16 MapBlock::getGroundLevel(v2s16 p2d)
|
|||||||
Serialization
|
Serialization
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// List relevant id-name pairs for ids in the block using nodedef
|
||||||
|
static void getBlockNodeIdMapping(NameIdMapping *nimap, MapBlock *block,
|
||||||
|
INodeDefManager *nodedef)
|
||||||
|
{
|
||||||
|
std::set<content_t> unknown_contents;
|
||||||
|
for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
|
||||||
|
for(s16 y0=0; y0<MAP_BLOCKSIZE; y0++)
|
||||||
|
for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
|
||||||
|
{
|
||||||
|
v3s16 p(x0,y0,z0);
|
||||||
|
MapNode n = block->getNode(p);
|
||||||
|
content_t id = n.getContent();
|
||||||
|
const ContentFeatures &f = nodedef->get(id);
|
||||||
|
const std::string &name = f.name;
|
||||||
|
if(name == "")
|
||||||
|
unknown_contents.insert(id);
|
||||||
|
else
|
||||||
|
nimap->set(id, name);
|
||||||
|
}
|
||||||
|
for(std::set<content_t>::const_iterator
|
||||||
|
i = unknown_contents.begin();
|
||||||
|
i != unknown_contents.end(); i++){
|
||||||
|
errorstream<<"getBlockNodeIdMapping(): IGNORING ERROR: "
|
||||||
|
<<"Name for node id "<<(*i)<<" not known"<<std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Correct ids in the block to match nodedef based on names.
|
||||||
|
// Unknown ones are added to nodedef.
|
||||||
|
// Will not update itself to match id-name pairs in nodedef.
|
||||||
|
void correctBlockNodeIds(const NameIdMapping *nimap, MapBlock *block,
|
||||||
|
IGameDef *gamedef)
|
||||||
|
{
|
||||||
|
INodeDefManager *nodedef = gamedef->ndef();
|
||||||
|
// This means the block contains incorrect ids, and we contain
|
||||||
|
// the information to convert those to names.
|
||||||
|
// nodedef contains information to convert our names to globally
|
||||||
|
// correct ids.
|
||||||
|
std::set<content_t> unnamed_contents;
|
||||||
|
std::set<std::string> unallocatable_contents;
|
||||||
|
for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
|
||||||
|
for(s16 y0=0; y0<MAP_BLOCKSIZE; y0++)
|
||||||
|
for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
|
||||||
|
{
|
||||||
|
v3s16 p(x0,y0,z0);
|
||||||
|
MapNode n = block->getNode(p);
|
||||||
|
content_t local_id = n.getContent();
|
||||||
|
std::string name;
|
||||||
|
bool found = nimap->getName(local_id, name);
|
||||||
|
if(!found){
|
||||||
|
unnamed_contents.insert(local_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
content_t global_id;
|
||||||
|
found = nodedef->getId(name, global_id);
|
||||||
|
if(!found){
|
||||||
|
global_id = gamedef->allocateUnknownNodeId(name);
|
||||||
|
if(global_id == CONTENT_IGNORE){
|
||||||
|
unallocatable_contents.insert(name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n.setContent(global_id);
|
||||||
|
block->setNode(p, n);
|
||||||
|
}
|
||||||
|
for(std::set<content_t>::const_iterator
|
||||||
|
i = unnamed_contents.begin();
|
||||||
|
i != unnamed_contents.end(); i++){
|
||||||
|
errorstream<<"correctBlockNodeIds(): IGNORING ERROR: "
|
||||||
|
<<"Block contains id "<<(*i)
|
||||||
|
<<" with no name mapping"<<std::endl;
|
||||||
|
}
|
||||||
|
for(std::set<std::string>::const_iterator
|
||||||
|
i = unallocatable_contents.begin();
|
||||||
|
i != unallocatable_contents.end(); i++){
|
||||||
|
errorstream<<"correctBlockNodeIds(): IGNORING ERROR: "
|
||||||
|
<<"Could not allocate global id for node name \""
|
||||||
|
<<(*i)<<"\""<<std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MapBlock::serialize(std::ostream &os, u8 version)
|
void MapBlock::serialize(std::ostream &os, u8 version)
|
||||||
{
|
{
|
||||||
if(!ser_ver_supported(version))
|
if(!ser_ver_supported(version))
|
||||||
@ -602,7 +686,7 @@ void MapBlock::serialize(std::ostream &os, u8 version)
|
|||||||
flags |= 0x08;
|
flags |= 0x08;
|
||||||
}
|
}
|
||||||
os.write((char*)&flags, 1);
|
os.write((char*)&flags, 1);
|
||||||
|
|
||||||
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
|
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -663,8 +747,6 @@ void MapBlock::serialize(std::ostream &os, u8 version)
|
|||||||
|
|
||||||
void MapBlock::deSerialize(std::istream &is, u8 version)
|
void MapBlock::deSerialize(std::istream &is, u8 version)
|
||||||
{
|
{
|
||||||
INodeDefManager *nodemgr = m_gamedef->ndef();
|
|
||||||
|
|
||||||
if(!ser_ver_supported(version))
|
if(!ser_ver_supported(version))
|
||||||
throw VersionMismatchException("ERROR: MapBlock format not supported");
|
throw VersionMismatchException("ERROR: MapBlock format not supported");
|
||||||
|
|
||||||
@ -698,7 +780,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
|
|||||||
if(is.gcount() != len)
|
if(is.gcount() != len)
|
||||||
throw SerializationError
|
throw SerializationError
|
||||||
("MapBlock::deSerialize: no enough input data");
|
("MapBlock::deSerialize: no enough input data");
|
||||||
data[i].deSerialize(*d, version, nodemgr);
|
data[i].deSerialize(*d, version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(version <= 10)
|
else if(version <= 10)
|
||||||
@ -780,7 +862,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
|
|||||||
buf[0] = s[i];
|
buf[0] = s[i];
|
||||||
buf[1] = s[i+nodecount];
|
buf[1] = s[i+nodecount];
|
||||||
buf[2] = s[i+nodecount*2];
|
buf[2] = s[i+nodecount*2];
|
||||||
data[i].deSerialize(buf, version, m_gamedef->getNodeDefManager());
|
data[i].deSerialize(buf, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -807,7 +889,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
|
|||||||
}
|
}
|
||||||
catch(SerializationError &e)
|
catch(SerializationError &e)
|
||||||
{
|
{
|
||||||
dstream<<"WARNING: MapBlock::deSerialize(): Ignoring an error"
|
errorstream<<"WARNING: MapBlock::deSerialize(): Ignoring an error"
|
||||||
<<" while deserializing node metadata"<<std::endl;
|
<<" while deserializing node metadata"<<std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -834,6 +916,13 @@ void MapBlock::serializeDiskExtra(std::ostream &os, u8 version)
|
|||||||
{
|
{
|
||||||
writeU32(os, getTimestamp());
|
writeU32(os, getTimestamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scan and write node definition id mapping
|
||||||
|
if(version >= 21){
|
||||||
|
NameIdMapping nimap;
|
||||||
|
getBlockNodeIdMapping(&nimap, this, m_gamedef->ndef());
|
||||||
|
nimap.serialize(os);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapBlock::deSerializeDiskExtra(std::istream &is, u8 version)
|
void MapBlock::deSerializeDiskExtra(std::istream &is, u8 version)
|
||||||
@ -841,12 +930,11 @@ void MapBlock::deSerializeDiskExtra(std::istream &is, u8 version)
|
|||||||
/*
|
/*
|
||||||
Versions up from 9 have block objects. (DEPRECATED)
|
Versions up from 9 have block objects. (DEPRECATED)
|
||||||
*/
|
*/
|
||||||
if(version >= 9)
|
if(version >= 9){
|
||||||
{
|
|
||||||
u16 count = readU16(is);
|
u16 count = readU16(is);
|
||||||
// Not supported and length not known if count is not 0
|
// Not supported and length not known if count is not 0
|
||||||
if(count != 0){
|
if(count != 0){
|
||||||
dstream<<"WARNING: MapBlock::deSerializeDiskExtra(): "
|
errorstream<<"WARNING: MapBlock::deSerializeDiskExtra(): "
|
||||||
<<"Ignoring stuff coming at and after MBOs"<<std::endl;
|
<<"Ignoring stuff coming at and after MBOs"<<std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -856,19 +944,24 @@ void MapBlock::deSerializeDiskExtra(std::istream &is, u8 version)
|
|||||||
Versions up from 15 have static objects.
|
Versions up from 15 have static objects.
|
||||||
*/
|
*/
|
||||||
if(version >= 15)
|
if(version >= 15)
|
||||||
{
|
|
||||||
m_static_objects.deSerialize(is);
|
m_static_objects.deSerialize(is);
|
||||||
}
|
|
||||||
|
|
||||||
// Timestamp
|
// Timestamp
|
||||||
if(version >= 17)
|
if(version >= 17)
|
||||||
{
|
|
||||||
setTimestamp(readU32(is));
|
setTimestamp(readU32(is));
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
setTimestamp(BLOCK_TIMESTAMP_UNDEFINED);
|
setTimestamp(BLOCK_TIMESTAMP_UNDEFINED);
|
||||||
|
|
||||||
|
// Dynamically re-set ids based on node names
|
||||||
|
NameIdMapping nimap;
|
||||||
|
// If supported, read node definition id mapping
|
||||||
|
if(version >= 21){
|
||||||
|
nimap.deSerialize(is);
|
||||||
|
// Else set the legacy mapping
|
||||||
|
} else {
|
||||||
|
content_mapnode_get_name_id_mapping(&nimap);
|
||||||
}
|
}
|
||||||
|
correctBlockNodeIds(&nimap, this, m_gamedef);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -877,9 +970,7 @@ void MapBlock::deSerializeDiskExtra(std::istream &is, u8 version)
|
|||||||
std::string analyze_block(MapBlock *block)
|
std::string analyze_block(MapBlock *block)
|
||||||
{
|
{
|
||||||
if(block == NULL)
|
if(block == NULL)
|
||||||
{
|
|
||||||
return "NULL";
|
return "NULL";
|
||||||
}
|
|
||||||
|
|
||||||
std::ostringstream desc;
|
std::ostringstream desc;
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
class Map;
|
class Map;
|
||||||
class NodeMetadataList;
|
class NodeMetadataList;
|
||||||
class IGameDef;
|
class IGameDef;
|
||||||
|
class IWritableNodeDefManager;
|
||||||
|
|
||||||
#define BLOCK_TIMESTAMP_UNDEFINED 0xffffffff
|
#define BLOCK_TIMESTAMP_UNDEFINED 0xffffffff
|
||||||
|
|
||||||
@ -540,8 +541,11 @@ public:
|
|||||||
// These don't write or read version by itself
|
// These don't write or read version by itself
|
||||||
void serialize(std::ostream &os, u8 version);
|
void serialize(std::ostream &os, u8 version);
|
||||||
void deSerialize(std::istream &is, u8 version);
|
void deSerialize(std::istream &is, u8 version);
|
||||||
|
|
||||||
// Used after the basic ones when writing on disk (serverside)
|
// Used after the basic ones when writing on disk (serverside)
|
||||||
void serializeDiskExtra(std::ostream &os, u8 version);
|
void serializeDiskExtra(std::ostream &os, u8 version);
|
||||||
|
// In addition to doing other things, will add unknown blocks from
|
||||||
|
// id-name mapping to wndef
|
||||||
void deSerializeDiskExtra(std::istream &is, u8 version);
|
void deSerializeDiskExtra(std::istream &is, u8 version);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -268,7 +268,7 @@ void MapNode::serialize(u8 *dest, u8 version)
|
|||||||
dest[2] = n_foreign.param2;
|
dest[2] = n_foreign.param2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void MapNode::deSerialize(u8 *source, u8 version, INodeDefManager *nodemgr)
|
void MapNode::deSerialize(u8 *source, u8 version)
|
||||||
{
|
{
|
||||||
if(!ser_ver_supported(version))
|
if(!ser_ver_supported(version))
|
||||||
throw VersionMismatchException("ERROR: MapNode format not supported");
|
throw VersionMismatchException("ERROR: MapNode format not supported");
|
||||||
@ -280,11 +280,6 @@ void MapNode::deSerialize(u8 *source, u8 version, INodeDefManager *nodemgr)
|
|||||||
else if(version == 1)
|
else if(version == 1)
|
||||||
{
|
{
|
||||||
param0 = source[0];
|
param0 = source[0];
|
||||||
// This version doesn't support saved lighting
|
|
||||||
if(nodemgr->get(*this).light_propagates || nodemgr->get(*this).light_source > 0)
|
|
||||||
param1 = 0;
|
|
||||||
else
|
|
||||||
param1 = source[1];
|
|
||||||
}
|
}
|
||||||
else if(version <= 9)
|
else if(version <= 9)
|
||||||
{
|
{
|
||||||
|
@ -221,7 +221,7 @@ struct MapNode
|
|||||||
|
|
||||||
static u32 serializedLength(u8 version);
|
static u32 serializedLength(u8 version);
|
||||||
void serialize(u8 *dest, u8 version);
|
void serialize(u8 *dest, u8 version);
|
||||||
void deSerialize(u8 *source, u8 version, INodeDefManager *nodemgr);
|
void deSerialize(u8 *source, u8 version);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
50
src/nameidmapping.cpp
Normal file
50
src/nameidmapping.cpp
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
Minetest-c55
|
||||||
|
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nameidmapping.h"
|
||||||
|
#include "utility.h"
|
||||||
|
|
||||||
|
void NameIdMapping::serialize(std::ostream &os) const
|
||||||
|
{
|
||||||
|
writeU8(os, 0); // version
|
||||||
|
writeU16(os, m_id_to_name.size());
|
||||||
|
for(std::map<u16, std::string>::const_iterator
|
||||||
|
i = m_id_to_name.begin();
|
||||||
|
i != m_id_to_name.end(); i++){
|
||||||
|
writeU16(os, i->first);
|
||||||
|
os<<serializeString(i->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NameIdMapping::deSerialize(std::istream &is)
|
||||||
|
{
|
||||||
|
int version = readU8(is);
|
||||||
|
if(version != 0)
|
||||||
|
throw SerializationError("unsupported NameIdMapping version");
|
||||||
|
u32 count = readU16(is);
|
||||||
|
m_id_to_name.clear();
|
||||||
|
m_name_to_id.clear();
|
||||||
|
for(u32 i=0; i<count; i++){
|
||||||
|
u16 id = readU16(is);
|
||||||
|
std::string name = deSerializeString(is);
|
||||||
|
m_id_to_name[id] = name;
|
||||||
|
m_name_to_id[name] = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
79
src/nameidmapping.h
Normal file
79
src/nameidmapping.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
Minetest-c55
|
||||||
|
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NAMEIDMAPPING_HEADER
|
||||||
|
#define NAMEIDMAPPING_HEADER
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <set>
|
||||||
|
#include <map>
|
||||||
|
#include "irrlichttypes.h"
|
||||||
|
|
||||||
|
class NameIdMapping
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void serialize(std::ostream &os) const;
|
||||||
|
void deSerialize(std::istream &is);
|
||||||
|
|
||||||
|
void clear(){
|
||||||
|
m_id_to_name.clear();
|
||||||
|
m_name_to_id.clear();
|
||||||
|
}
|
||||||
|
void set(u16 id, const std::string &name){
|
||||||
|
m_id_to_name[id] = name;
|
||||||
|
m_name_to_id[name] = id;
|
||||||
|
}
|
||||||
|
void removeId(u16 id){
|
||||||
|
std::string name;
|
||||||
|
bool found = getName(id, name);
|
||||||
|
if(!found) return;
|
||||||
|
m_id_to_name.erase(id);
|
||||||
|
m_name_to_id.erase(name);
|
||||||
|
}
|
||||||
|
void eraseName(const std::string &name){
|
||||||
|
u16 id;
|
||||||
|
bool found = getId(name, id);
|
||||||
|
if(!found) return;
|
||||||
|
m_id_to_name.erase(id);
|
||||||
|
m_name_to_id.erase(name);
|
||||||
|
}
|
||||||
|
bool getName(u16 id, std::string &result) const{
|
||||||
|
std::map<u16, std::string>::const_iterator i;
|
||||||
|
i = m_id_to_name.find(id);
|
||||||
|
if(i == m_id_to_name.end())
|
||||||
|
return false;
|
||||||
|
result = i->second;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool getId(const std::string &name, u16 &result) const{
|
||||||
|
std::map<std::string, u16>::const_iterator i;
|
||||||
|
i = m_name_to_id.find(name);
|
||||||
|
if(i == m_name_to_id.end())
|
||||||
|
return false;
|
||||||
|
result = i->second;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::map<u16, std::string> m_id_to_name;
|
||||||
|
std::map<std::string, u16> m_name_to_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
115
src/nodedef.cpp
115
src/nodedef.cpp
@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#endif
|
#endif
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include "nameidmapping.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NodeBox
|
NodeBox
|
||||||
@ -318,20 +319,63 @@ class CNodeDefManager: public IWritableNodeDefManager
|
|||||||
public:
|
public:
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
|
m_name_id_mapping.clear();
|
||||||
for(u16 i=0; i<=MAX_CONTENT; i++)
|
for(u16 i=0; i<=MAX_CONTENT; i++)
|
||||||
{
|
{
|
||||||
ContentFeatures *f = &m_content_features[i];
|
ContentFeatures &f = m_content_features[i];
|
||||||
f->reset(); // Reset to defaults
|
f.reset(); // Reset to defaults
|
||||||
if(i == CONTENT_IGNORE || i == CONTENT_AIR){
|
f.setAllTextures("unknown_block.png");
|
||||||
f->drawtype = NDT_AIRLIKE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
f->setAllTextures("unknown_block.png");
|
|
||||||
}
|
}
|
||||||
#ifndef SERVER
|
|
||||||
// Make CONTENT_IGNORE to not block the view when occlusion culling
|
// Set CONTENT_AIR
|
||||||
m_content_features[CONTENT_IGNORE].solidness = 0;
|
{
|
||||||
#endif
|
ContentFeatures f;
|
||||||
|
f.name = "air";
|
||||||
|
f.drawtype = NDT_AIRLIKE;
|
||||||
|
f.param_type = CPT_LIGHT;
|
||||||
|
f.light_propagates = true;
|
||||||
|
f.sunlight_propagates = true;
|
||||||
|
f.walkable = false;
|
||||||
|
f.pointable = false;
|
||||||
|
f.diggable = false;
|
||||||
|
f.buildable_to = true;
|
||||||
|
f.air_equivalent = true;
|
||||||
|
set(CONTENT_AIR, f);
|
||||||
|
}
|
||||||
|
// Set CONTENT_IGNORE
|
||||||
|
{
|
||||||
|
ContentFeatures f;
|
||||||
|
f.name = "ignore";
|
||||||
|
f.drawtype = NDT_AIRLIKE;
|
||||||
|
f.param_type = CPT_LIGHT;
|
||||||
|
f.light_propagates = true;
|
||||||
|
f.sunlight_propagates = true;
|
||||||
|
f.walkable = false;
|
||||||
|
f.pointable = false;
|
||||||
|
f.diggable = false;
|
||||||
|
f.buildable_to = true;
|
||||||
|
f.air_equivalent = true;
|
||||||
|
set(CONTENT_AIR, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// CONTENT_IGNORE = not found
|
||||||
|
content_t getFreeId(bool require_full_param2)
|
||||||
|
{
|
||||||
|
// If allowed, first search in the large 4-byte-param2 pool
|
||||||
|
if(!require_full_param2){
|
||||||
|
for(u16 i=0x800; i<=0xfff; i++){
|
||||||
|
const ContentFeatures &f = m_content_features[i];
|
||||||
|
if(f.name == "")
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Then search from the small 8-byte-param2 pool
|
||||||
|
for(u16 i=0; i<=125; i++){
|
||||||
|
const ContentFeatures &f = m_content_features[i];
|
||||||
|
if(f.name == "")
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return CONTENT_IGNORE;
|
||||||
}
|
}
|
||||||
CNodeDefManager()
|
CNodeDefManager()
|
||||||
{
|
{
|
||||||
@ -358,18 +402,54 @@ public:
|
|||||||
{
|
{
|
||||||
return get(n.getContent());
|
return get(n.getContent());
|
||||||
}
|
}
|
||||||
// Writable
|
virtual bool getId(const std::string &name, content_t &result) const
|
||||||
|
{
|
||||||
|
return m_name_id_mapping.getId(name, result);
|
||||||
|
}
|
||||||
|
// IWritableNodeDefManager
|
||||||
virtual void set(content_t c, const ContentFeatures &def)
|
virtual void set(content_t c, const ContentFeatures &def)
|
||||||
{
|
{
|
||||||
infostream<<"registerNode: registering content id \""<<c
|
infostream<<"registerNode: registering content id \""<<c
|
||||||
<<"\": name=\""<<def.name<<"\""<<std::endl;
|
<<"\": name=\""<<def.name<<"\""<<std::endl;
|
||||||
assert(c <= MAX_CONTENT);
|
assert(c <= MAX_CONTENT);
|
||||||
m_content_features[c] = def;
|
m_content_features[c] = def;
|
||||||
|
if(def.name != "")
|
||||||
|
m_name_id_mapping.set(c, def.name);
|
||||||
}
|
}
|
||||||
virtual ContentFeatures* getModifiable(content_t c)
|
virtual content_t set(const std::string &name,
|
||||||
|
const ContentFeatures &def)
|
||||||
{
|
{
|
||||||
assert(c <= MAX_CONTENT);
|
assert(name == def.name);
|
||||||
return &m_content_features[c];
|
u16 id = CONTENT_IGNORE;
|
||||||
|
bool found = m_name_id_mapping.getId(name, id);
|
||||||
|
if(!found){
|
||||||
|
// Determine if full param2 is required
|
||||||
|
bool require_full_param2 = (
|
||||||
|
def.liquid_type == LIQUID_FLOWING
|
||||||
|
||
|
||||||
|
def.drawtype == NDT_FLOWINGLIQUID
|
||||||
|
||
|
||||||
|
def.drawtype == NDT_TORCHLIKE
|
||||||
|
||
|
||||||
|
def.drawtype == NDT_SIGNLIKE
|
||||||
|
);
|
||||||
|
// Get some id
|
||||||
|
id = getFreeId(require_full_param2);
|
||||||
|
if(id == CONTENT_IGNORE)
|
||||||
|
return CONTENT_IGNORE;
|
||||||
|
if(name != "")
|
||||||
|
m_name_id_mapping.set(id, name);
|
||||||
|
}
|
||||||
|
set(id, def);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
virtual content_t allocateDummy(const std::string &name)
|
||||||
|
{
|
||||||
|
assert(name != "");
|
||||||
|
ContentFeatures f;
|
||||||
|
f.name = name;
|
||||||
|
f.setAllTextures("unknown_block.png");
|
||||||
|
return set(name, f);
|
||||||
}
|
}
|
||||||
virtual void updateTextures(ITextureSource *tsrc)
|
virtual void updateTextures(ITextureSource *tsrc)
|
||||||
{
|
{
|
||||||
@ -499,6 +579,8 @@ public:
|
|||||||
std::ostringstream tmp_os(std::ios::binary);
|
std::ostringstream tmp_os(std::ios::binary);
|
||||||
for(u16 i=0; i<=MAX_CONTENT; i++)
|
for(u16 i=0; i<=MAX_CONTENT; i++)
|
||||||
{
|
{
|
||||||
|
if(i == CONTENT_IGNORE || i == CONTENT_AIR)
|
||||||
|
continue;
|
||||||
ContentFeatures *f = &m_content_features[i];
|
ContentFeatures *f = &m_content_features[i];
|
||||||
if(f->name == "")
|
if(f->name == "")
|
||||||
continue;
|
continue;
|
||||||
@ -523,10 +605,13 @@ public:
|
|||||||
}
|
}
|
||||||
ContentFeatures *f = &m_content_features[i];
|
ContentFeatures *f = &m_content_features[i];
|
||||||
f->deSerialize(tmp_is, gamedef);
|
f->deSerialize(tmp_is, gamedef);
|
||||||
|
if(f->name != "")
|
||||||
|
m_name_id_mapping.set(i, f->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
ContentFeatures m_content_features[MAX_CONTENT+1];
|
ContentFeatures m_content_features[MAX_CONTENT+1];
|
||||||
|
NameIdMapping m_name_id_mapping;
|
||||||
};
|
};
|
||||||
|
|
||||||
IWritableNodeDefManager* createNodeDefManager()
|
IWritableNodeDefManager* createNodeDefManager()
|
||||||
|
@ -253,6 +253,7 @@ public:
|
|||||||
// Get node definition
|
// Get node definition
|
||||||
virtual const ContentFeatures& get(content_t c) const=0;
|
virtual const ContentFeatures& get(content_t c) const=0;
|
||||||
virtual const ContentFeatures& get(const MapNode &n) const=0;
|
virtual const ContentFeatures& get(const MapNode &n) const=0;
|
||||||
|
virtual bool getId(const std::string &name, content_t &result) const=0;
|
||||||
|
|
||||||
virtual void serialize(std::ostream &os)=0;
|
virtual void serialize(std::ostream &os)=0;
|
||||||
};
|
};
|
||||||
@ -266,10 +267,16 @@ public:
|
|||||||
// Get node definition
|
// Get node definition
|
||||||
virtual const ContentFeatures& get(content_t c) const=0;
|
virtual const ContentFeatures& get(content_t c) const=0;
|
||||||
virtual const ContentFeatures& get(const MapNode &n) const=0;
|
virtual const ContentFeatures& get(const MapNode &n) const=0;
|
||||||
|
virtual bool getId(const std::string &name, content_t &result) const=0;
|
||||||
|
|
||||||
// Register node definition
|
// Register node definition
|
||||||
virtual void set(content_t c, const ContentFeatures &def)=0;
|
virtual void set(content_t c, const ContentFeatures &def)=0;
|
||||||
virtual ContentFeatures* getModifiable(content_t c)=0;
|
// Register node definition by name (allocate an id)
|
||||||
|
// If returns CONTENT_IGNORE, could not allocate id
|
||||||
|
virtual content_t set(const std::string &name,
|
||||||
|
const ContentFeatures &def)=0;
|
||||||
|
// If returns CONTENT_IGNORE, could not allocate id
|
||||||
|
virtual content_t allocateDummy(const std::string &name)=0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Update tile textures to latest return values of TextueSource.
|
Update tile textures to latest return values of TextueSource.
|
||||||
|
@ -56,11 +56,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
18: new generator (not really necessary, but it's there)
|
18: new generator (not really necessary, but it's there)
|
||||||
19: new content type handling
|
19: new content type handling
|
||||||
20: many existing content types translated to extended ones
|
20: many existing content types translated to extended ones
|
||||||
|
21: dynamic content type allocation
|
||||||
*/
|
*/
|
||||||
// This represents an uninitialized or invalid format
|
// This represents an uninitialized or invalid format
|
||||||
#define SER_FMT_VER_INVALID 255
|
#define SER_FMT_VER_INVALID 255
|
||||||
// Highest supported serialization version
|
// Highest supported serialization version
|
||||||
#define SER_FMT_VER_HIGHEST 20
|
#define SER_FMT_VER_HIGHEST 21
|
||||||
// Lowest supported serialization version
|
// Lowest supported serialization version
|
||||||
#define SER_FMT_VER_LOWEST 0
|
#define SER_FMT_VER_LOWEST 0
|
||||||
|
|
||||||
|
@ -4428,6 +4428,10 @@ ITextureSource* Server::getTextureSource()
|
|||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
u16 Server::allocateUnknownNodeId(const std::string &name)
|
||||||
|
{
|
||||||
|
return m_nodemgr->allocateDummy(name);
|
||||||
|
}
|
||||||
|
|
||||||
IWritableToolDefManager* Server::getWritableToolDefManager()
|
IWritableToolDefManager* Server::getWritableToolDefManager()
|
||||||
{
|
{
|
||||||
|
@ -491,6 +491,7 @@ public:
|
|||||||
virtual IToolDefManager* getToolDefManager();
|
virtual IToolDefManager* getToolDefManager();
|
||||||
virtual INodeDefManager* getNodeDefManager();
|
virtual INodeDefManager* getNodeDefManager();
|
||||||
virtual ITextureSource* getTextureSource();
|
virtual ITextureSource* getTextureSource();
|
||||||
|
virtual u16 allocateUnknownNodeId(const std::string &name);
|
||||||
|
|
||||||
IWritableToolDefManager* getWritableToolDefManager();
|
IWritableToolDefManager* getWritableToolDefManager();
|
||||||
IWritableNodeDefManager* getWritableNodeDefManager();
|
IWritableNodeDefManager* getWritableNodeDefManager();
|
||||||
|
Loading…
Reference in New Issue
Block a user