Skip to content

Commit

Permalink
Fix backface culling when connecting to new servers.
Browse files Browse the repository at this point in the history
Introduce a new contentfeatures version (8). When clients
connect using v27 protocol version, they can assume that
the tiledef.backface_culling is trustable, but if clients
connect to servers providing contentfeatures version 7,
then the v27 clients know that backface culling settings
provided by the server in tiledefs are bogus for mesh,
plantlike, firelike or liquid drawtype nodes.

thanks to hmmmm, est31, nerzhul.

Tested on new client - new server, new client - old server
old client - new server.
  • Loading branch information
sofar authored and est31 committed Feb 9, 2016
1 parent ba8fa9e commit 47464c9
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 50 deletions.
43 changes: 18 additions & 25 deletions src/nodedef.cpp
Expand Up @@ -139,7 +139,7 @@ void TileDef::serialize(std::ostream &os, u16 protocol_version) const
}
}

void TileDef::deSerialize(std::istream &is, bool culling_ignore)
void TileDef::deSerialize(std::istream &is, const u8 contenfeatures_version, const NodeDrawType drawtype)
{
int version = readU8(is);
name = deSerializeString(is);
Expand All @@ -153,10 +153,12 @@ void TileDef::deSerialize(std::istream &is, bool culling_ignore)
tileable_horizontal = readU8(is);
tileable_vertical = readU8(is);
}
// when connecting to old servers - do not use
// provided values here since culling needs to be
// disabled by default for these drawtypes
if (culling_ignore)

if ((contenfeatures_version < 8) &&
((drawtype == NDT_MESH) ||
(drawtype == NDT_FIRELIKE) ||
(drawtype == NDT_LIQUID) ||
(drawtype == NDT_PLANTLIKE)))
backface_culling = false;
}

Expand Down Expand Up @@ -268,7 +270,8 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
return;
}

writeU8(os, 7); // version
writeU8(os, protocol_version < 27 ? 7 : 8);

os<<serializeString(name);
writeU16(os, groups.size());
for(ItemGroupList::const_iterator
Expand Down Expand Up @@ -330,9 +333,11 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
void ContentFeatures::deSerialize(std::istream &is)
{
int version = readU8(is);
if(version != 7){
if (version < 7) {
deSerializeOld(is, version);
return;
} else if (version > 8) {
throw SerializationError("unsupported ContentFeatures version");
}

name = deSerializeString(is);
Expand All @@ -345,21 +350,15 @@ void ContentFeatures::deSerialize(std::istream &is)
}
drawtype = (enum NodeDrawType)readU8(is);

bool ignore_culling = ((version <= 26) &&
((drawtype == NDT_MESH) ||
(drawtype == NDT_PLANTLIKE) ||
(drawtype == NDT_FIRELIKE) ||
(drawtype == NDT_LIQUID)));

visual_scale = readF1000(is);
if(readU8(is) != 6)
throw SerializationError("unsupported tile count");
for(u32 i = 0; i < 6; i++)
tiledef[i].deSerialize(is, ignore_culling);
tiledef[i].deSerialize(is, version, drawtype);
if(readU8(is) != CF_SPECIAL_COUNT)
throw SerializationError("unsupported CF_SPECIAL_COUNT");
for(u32 i = 0; i < CF_SPECIAL_COUNT; i++)
tiledef_special[i].deSerialize(is, ignore_culling);
tiledef_special[i].deSerialize(is, version, drawtype);
alpha = readU8(is);
post_effect_color.setAlpha(readU8(is));
post_effect_color.setRed(readU8(is));
Expand Down Expand Up @@ -1284,21 +1283,15 @@ void ContentFeatures::deSerializeOld(std::istream &is, int version)
}
drawtype = (enum NodeDrawType)readU8(is);

bool ignore_culling = ((version <= 26) &&
((drawtype == NDT_MESH) ||
(drawtype == NDT_PLANTLIKE) ||
(drawtype == NDT_FIRELIKE) ||
(drawtype == NDT_LIQUID)));

visual_scale = readF1000(is);
if (readU8(is) != 6)
throw SerializationError("unsupported tile count");
for (u32 i = 0; i < 6; i++)
tiledef[i].deSerialize(is, ignore_culling);
tiledef[i].deSerialize(is, version, drawtype);
if (readU8(is) != CF_SPECIAL_COUNT)
throw SerializationError("unsupported CF_SPECIAL_COUNT");
for (u32 i = 0; i < CF_SPECIAL_COUNT; i++)
tiledef_special[i].deSerialize(is, ignore_culling);
tiledef_special[i].deSerialize(is, version, drawtype);
alpha = readU8(is);
post_effect_color.setAlpha(readU8(is));
post_effect_color.setRed(readU8(is));
Expand Down Expand Up @@ -1342,12 +1335,12 @@ void ContentFeatures::deSerializeOld(std::istream &is, int version)
if (readU8(is) != 6)
throw SerializationError("unsupported tile count");
for (u32 i = 0; i < 6; i++)
tiledef[i].deSerialize(is, drawtype);
tiledef[i].deSerialize(is, version, drawtype);
// CF_SPECIAL_COUNT in version 6 = 2
if (readU8(is) != 2)
throw SerializationError("unsupported CF_SPECIAL_COUNT");
for (u32 i = 0; i < 2; i++)
tiledef_special[i].deSerialize(is, drawtype);
tiledef_special[i].deSerialize(is, version, drawtype);
alpha = readU8(is);
post_effect_color.setAlpha(readU8(is));
post_effect_color.setRed(readU8(is));
Expand Down
50 changes: 25 additions & 25 deletions src/nodedef.h
Expand Up @@ -104,6 +104,30 @@ struct NodeBox
struct MapNode;
class NodeMetadata;

enum NodeDrawType
{
NDT_NORMAL, // A basic solid block
NDT_AIRLIKE, // Nothing is drawn
NDT_LIQUID, // Do not draw face towards same kind of flowing/source liquid
NDT_FLOWINGLIQUID, // A very special kind of thing
NDT_GLASSLIKE, // Glass-like, don't draw faces towards other glass
NDT_ALLFACES, // Leaves-like, draw all faces no matter what
NDT_ALLFACES_OPTIONAL, // Fancy -> allfaces, fast -> normal
NDT_TORCHLIKE,
NDT_SIGNLIKE,
NDT_PLANTLIKE,
NDT_FENCELIKE,
NDT_RAILLIKE,
NDT_NODEBOX,
NDT_GLASSLIKE_FRAMED, // Glass-like, draw connected frames and all all
// visible faces
// uses 2 textures, one for frames, second for faces
NDT_FIRELIKE, // Draw faces slightly rotated and only on connecting nodes,
NDT_GLASSLIKE_FRAMED_OPTIONAL, // enabled -> connected, disabled -> Glass-like
// uses 2 textures, one for frames, second for faces
NDT_MESH, // Uses static meshes
};

/*
Stand-alone definition of a TileSpec (basically a server-side TileSpec)
*/
Expand Down Expand Up @@ -137,31 +161,7 @@ struct TileDef
}

void serialize(std::ostream &os, u16 protocol_version) const;
void deSerialize(std::istream &is, bool culling_ignore);
};

enum NodeDrawType
{
NDT_NORMAL, // A basic solid block
NDT_AIRLIKE, // Nothing is drawn
NDT_LIQUID, // Do not draw face towards same kind of flowing/source liquid
NDT_FLOWINGLIQUID, // A very special kind of thing
NDT_GLASSLIKE, // Glass-like, don't draw faces towards other glass
NDT_ALLFACES, // Leaves-like, draw all faces no matter what
NDT_ALLFACES_OPTIONAL, // Fancy -> allfaces, fast -> normal
NDT_TORCHLIKE,
NDT_SIGNLIKE,
NDT_PLANTLIKE,
NDT_FENCELIKE,
NDT_RAILLIKE,
NDT_NODEBOX,
NDT_GLASSLIKE_FRAMED, // Glass-like, draw connected frames and all all
// visible faces
// uses 2 textures, one for frames, second for faces
NDT_FIRELIKE, // Draw faces slightly rotated and only on connecting nodes,
NDT_GLASSLIKE_FRAMED_OPTIONAL, // enabled -> connected, disabled -> Glass-like
// uses 2 textures, one for frames, second for faces
NDT_MESH, // Uses static meshes
void deSerialize(std::istream &is, const u8 contentfeatures_version, const NodeDrawType drawtype);
};

#define CF_SPECIAL_COUNT 6
Expand Down

0 comments on commit 47464c9

Please sign in to comment.