mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 01:53:45 +01:00
General code refactoring/improvements in server, treegen and connection
This commit is contained in:
parent
24f2c38093
commit
bc4ab8b99e
@ -57,18 +57,11 @@ public:
|
|||||||
s32 id
|
s32 id
|
||||||
);
|
);
|
||||||
|
|
||||||
virtual ~ClientMap();
|
|
||||||
|
|
||||||
bool maySaveBlocks() override
|
bool maySaveBlocks() override
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void drop() override
|
|
||||||
{
|
|
||||||
ISceneNode::drop(); // calls destructor
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset, video::SColor light_color);
|
void updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset, video::SColor light_color);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -122,6 +115,9 @@ public:
|
|||||||
void onSettingChanged(const std::string &name);
|
void onSettingChanged(const std::string &name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// use drop() instead
|
||||||
|
virtual ~ClientMap();
|
||||||
|
|
||||||
void reportMetrics(u64 save_time_us, u32 saved_blocks, u32 all_blocks) override;
|
void reportMetrics(u64 save_time_us, u32 saved_blocks, u32 all_blocks) override;
|
||||||
private:
|
private:
|
||||||
bool isMeshOccluded(MapBlock *mesh_block, u16 mesh_size, v3s16 cam_pos_nodes);
|
bool isMeshOccluded(MapBlock *mesh_block, u16 mesh_size, v3s16 cam_pos_nodes);
|
||||||
|
@ -89,7 +89,7 @@ static inline v3f truncate(const v3f& vec, const f32 factor)
|
|||||||
// The time after which the collision occurs is stored in dtime.
|
// The time after which the collision occurs is stored in dtime.
|
||||||
CollisionAxis axisAlignedCollision(
|
CollisionAxis axisAlignedCollision(
|
||||||
const aabb3f &staticbox, const aabb3f &movingbox,
|
const aabb3f &staticbox, const aabb3f &movingbox,
|
||||||
const v3f &speed, f32 *dtime)
|
const v3f speed, f32 *dtime)
|
||||||
{
|
{
|
||||||
//TimeTaker tt("axisAlignedCollision");
|
//TimeTaker tt("axisAlignedCollision");
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ collisionMoveResult collisionMoveSimple(Environment *env,IGameDef *gamedef,
|
|||||||
// dtime receives time until first collision, invalid if -1 is returned
|
// dtime receives time until first collision, invalid if -1 is returned
|
||||||
CollisionAxis axisAlignedCollision(
|
CollisionAxis axisAlignedCollision(
|
||||||
const aabb3f &staticbox, const aabb3f &movingbox,
|
const aabb3f &staticbox, const aabb3f &movingbox,
|
||||||
const v3f &speed, f32 *dtime);
|
v3f speed, f32 *dtime);
|
||||||
|
|
||||||
// Helper function:
|
// Helper function:
|
||||||
// Checks if moving the movingbox up by the given distance would hit a ceiling.
|
// Checks if moving the movingbox up by the given distance would hit a ceiling.
|
||||||
|
@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "filesys.h"
|
#include "filesys.h"
|
||||||
#include "server/player_sao.h"
|
#include "server/player_sao.h"
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
|
#include <json/json.h>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
// !!! WARNING !!!
|
// !!! WARNING !!!
|
||||||
|
@ -94,7 +94,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Json::Value *getOrCreateJson(const std::string &modname);
|
Json::Value *getOrCreateJson(const std::string &modname);
|
||||||
bool writeJson(const std::string &modname, const Json::Value &json);
|
|
||||||
|
|
||||||
std::string m_storage_dir;
|
std::string m_storage_dir;
|
||||||
std::unordered_map<std::string, Json::Value> m_mod_storage;
|
std::unordered_map<std::string, Json::Value> m_mod_storage;
|
||||||
|
@ -646,7 +646,7 @@ void *EmergeThread::run()
|
|||||||
std::map<v3s16, MapBlock *> modified_blocks;
|
std::map<v3s16, MapBlock *> modified_blocks;
|
||||||
|
|
||||||
m_map = &m_server->m_env->getServerMap();
|
m_map = &m_server->m_env->getServerMap();
|
||||||
m_emerge = m_server->m_emerge;
|
m_emerge = m_server->getEmergeManager();
|
||||||
m_mapgen = m_emerge->m_mapgens[id];
|
m_mapgen = m_emerge->m_mapgens[id];
|
||||||
enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info;
|
enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info;
|
||||||
|
|
||||||
|
@ -19,8 +19,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#include "httpfetch.h"
|
#include "httpfetch.h"
|
||||||
#include "porting.h" // for sleep_ms(), get_sysinfo(), secure_rand_fill_buf()
|
#include "porting.h" // for sleep_ms(), get_sysinfo(), secure_rand_fill_buf()
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
@ -152,9 +150,9 @@ bool httpfetch_async_get(u64 caller, HTTPFetchResult &fetch_result)
|
|||||||
static size_t httpfetch_writefunction(
|
static size_t httpfetch_writefunction(
|
||||||
char *ptr, size_t size, size_t nmemb, void *userdata)
|
char *ptr, size_t size, size_t nmemb, void *userdata)
|
||||||
{
|
{
|
||||||
std::ostringstream *stream = (std::ostringstream*)userdata;
|
auto *dest = reinterpret_cast<std::string*>(userdata);
|
||||||
size_t count = size * nmemb;
|
size_t count = size * nmemb;
|
||||||
stream->write(ptr, count);
|
dest->append(ptr, count);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,7 +213,6 @@ private:
|
|||||||
CURLM *multi = nullptr;
|
CURLM *multi = nullptr;
|
||||||
HTTPFetchRequest request;
|
HTTPFetchRequest request;
|
||||||
HTTPFetchResult result;
|
HTTPFetchResult result;
|
||||||
std::ostringstream oss;
|
|
||||||
struct curl_slist *http_header = nullptr;
|
struct curl_slist *http_header = nullptr;
|
||||||
curl_mime *multipart_mime = nullptr;
|
curl_mime *multipart_mime = nullptr;
|
||||||
};
|
};
|
||||||
@ -225,8 +222,7 @@ HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_,
|
|||||||
CurlHandlePool *pool_):
|
CurlHandlePool *pool_):
|
||||||
pool(pool_),
|
pool(pool_),
|
||||||
request(request_),
|
request(request_),
|
||||||
result(request_),
|
result(request_)
|
||||||
oss(std::ios::binary)
|
|
||||||
{
|
{
|
||||||
curl = pool->alloc();
|
curl = pool->alloc();
|
||||||
if (!curl)
|
if (!curl)
|
||||||
@ -277,16 +273,15 @@ HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_,
|
|||||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, request.useragent.c_str());
|
curl_easy_setopt(curl, CURLOPT_USERAGENT, request.useragent.c_str());
|
||||||
|
|
||||||
// Set up a write callback that writes to the
|
// Set up a write callback that writes to the
|
||||||
// ostringstream ongoing->oss, unless the data
|
// result struct, unless the data is to be discarded
|
||||||
// is to be discarded
|
|
||||||
if (request.caller == HTTPFETCH_DISCARD) {
|
if (request.caller == HTTPFETCH_DISCARD) {
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
|
||||||
httpfetch_discardfunction);
|
httpfetch_discardfunction);
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL);
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, nullptr);
|
||||||
} else {
|
} else {
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
|
||||||
httpfetch_writefunction);
|
httpfetch_writefunction);
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &oss);
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set data from fields or raw_data
|
// Set data from fields or raw_data
|
||||||
@ -372,7 +367,6 @@ const HTTPFetchResult * HTTPFetchOngoing::complete(CURLcode res)
|
|||||||
{
|
{
|
||||||
result.succeeded = (res == CURLE_OK);
|
result.succeeded = (res == CURLE_OK);
|
||||||
result.timeout = (res == CURLE_OPERATION_TIMEDOUT);
|
result.timeout = (res == CURLE_OPERATION_TIMEDOUT);
|
||||||
result.data = oss.str();
|
|
||||||
|
|
||||||
// Get HTTP/FTP response code
|
// Get HTTP/FTP response code
|
||||||
result.response_code = 0;
|
result.response_code = 0;
|
||||||
|
@ -600,7 +600,7 @@ void Map::removeNodeTimer(v3s16 p)
|
|||||||
block->removeNodeTimer(p_rel);
|
block->removeNodeTimer(p_rel);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Map::determineAdditionalOcclusionCheck(const v3s16 &pos_camera,
|
bool Map::determineAdditionalOcclusionCheck(const v3s16 pos_camera,
|
||||||
const core::aabbox3d<s16> &block_bounds, v3s16 &check)
|
const core::aabbox3d<s16> &block_bounds, v3s16 &check)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -664,7 +664,7 @@ bool Map::determineAdditionalOcclusionCheck(const v3s16 &pos_camera,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Map::isOccluded(const v3s16 &pos_camera, const v3s16 &pos_target,
|
bool Map::isOccluded(const v3s16 pos_camera, const v3s16 pos_target,
|
||||||
float step, float stepfac, float offset, float end_offset, u32 needed_count)
|
float step, float stepfac, float offset, float end_offset, u32 needed_count)
|
||||||
{
|
{
|
||||||
v3f direction = intToFloat(pos_target - pos_camera, BS);
|
v3f direction = intToFloat(pos_target - pos_camera, BS);
|
||||||
|
14
src/map.h
14
src/map.h
@ -120,14 +120,6 @@ public:
|
|||||||
virtual ~Map();
|
virtual ~Map();
|
||||||
DISABLE_CLASS_COPY(Map);
|
DISABLE_CLASS_COPY(Map);
|
||||||
|
|
||||||
/*
|
|
||||||
Drop (client) or delete (server) the map.
|
|
||||||
*/
|
|
||||||
virtual void drop()
|
|
||||||
{
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addEventReceiver(MapEventReceiver *event_receiver);
|
void addEventReceiver(MapEventReceiver *event_receiver);
|
||||||
void removeEventReceiver(MapEventReceiver *event_receiver);
|
void removeEventReceiver(MapEventReceiver *event_receiver);
|
||||||
// event shall be deleted by caller after the call.
|
// event shall be deleted by caller after the call.
|
||||||
@ -314,9 +306,9 @@ protected:
|
|||||||
// Can be implemented by child class
|
// Can be implemented by child class
|
||||||
virtual void reportMetrics(u64 save_time_us, u32 saved_blocks, u32 all_blocks) {}
|
virtual void reportMetrics(u64 save_time_us, u32 saved_blocks, u32 all_blocks) {}
|
||||||
|
|
||||||
bool determineAdditionalOcclusionCheck(const v3s16 &pos_camera,
|
bool determineAdditionalOcclusionCheck(v3s16 pos_camera,
|
||||||
const core::aabbox3d<s16> &block_bounds, v3s16 &check);
|
const core::aabbox3d<s16> &block_bounds, v3s16 &to_check);
|
||||||
bool isOccluded(const v3s16 &pos_camera, const v3s16 &pos_target,
|
bool isOccluded(v3s16 pos_camera, v3s16 pos_target,
|
||||||
float step, float stepfac, float start_offset, float end_offset,
|
float step, float stepfac, float start_offset, float end_offset,
|
||||||
u32 needed_count);
|
u32 needed_count);
|
||||||
};
|
};
|
||||||
|
@ -492,5 +492,5 @@ size_t DecoLSystem::generate(MMVManip *vm, PcgRandom *pr, v3s16 p, bool ceiling)
|
|||||||
|
|
||||||
// Make sure that tree_def can't be modified, since it is shared.
|
// Make sure that tree_def can't be modified, since it is shared.
|
||||||
const auto &ref = *tree_def;
|
const auto &ref = *tree_def;
|
||||||
return treegen::make_ltree(*vm, p, m_ndef, ref);
|
return treegen::make_ltree(*vm, p, ref);
|
||||||
}
|
}
|
||||||
|
@ -19,14 +19,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "irr_v3d.h"
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
#include "treegen.h"
|
||||||
|
#include "irr_v3d.h"
|
||||||
#include "util/pointer.h"
|
#include "util/pointer.h"
|
||||||
#include "util/numeric.h"
|
#include "util/numeric.h"
|
||||||
#include "servermap.h"
|
#include "servermap.h"
|
||||||
#include "mapblock.h"
|
#include "mapblock.h"
|
||||||
#include "nodedef.h"
|
#include "noise.h"
|
||||||
#include "treegen.h"
|
|
||||||
#include "voxelalgorithms.h"
|
#include "voxelalgorithms.h"
|
||||||
|
|
||||||
namespace treegen
|
namespace treegen
|
||||||
@ -42,6 +42,23 @@ void TreeDef::resolveNodeNames()
|
|||||||
getIdFromNrBacklog(&fruitnode.param0, "", CONTENT_IGNORE);
|
getIdFromNrBacklog(&fruitnode.param0, "", CONTENT_IGNORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
L-System tree gen helper functions
|
||||||
|
|
||||||
|
NOTE: the PseudoRandom parameters here were probably accidentally used
|
||||||
|
as by-value instead of by-reference. But don't change this now to keep
|
||||||
|
the old behaviour.
|
||||||
|
*/
|
||||||
|
static void tree_trunk_placement(MMVManip &vmanip, v3f p0, const TreeDef &def);
|
||||||
|
static void tree_leaves_placement(MMVManip &vmanip, v3f p0,
|
||||||
|
PseudoRandom ps, const TreeDef &def);
|
||||||
|
static void tree_single_leaves_placement(MMVManip &vmanip, v3f p0,
|
||||||
|
PseudoRandom ps, const TreeDef &def);
|
||||||
|
static void tree_fruit_placement(MMVManip &vmanip, v3f p0, const TreeDef &def);
|
||||||
|
|
||||||
|
static void setRotationAxisRadians(core::matrix4 &M, float angle, v3f axis);
|
||||||
|
static v3f transposeMatrix(const core::matrix4 &M, v3f v);
|
||||||
|
|
||||||
void make_tree(MMVManip &vmanip, v3s16 p0, bool is_apple_tree,
|
void make_tree(MMVManip &vmanip, v3s16 p0, bool is_apple_tree,
|
||||||
const NodeDefManager *ndef, s32 seed)
|
const NodeDefManager *ndef, s32 seed)
|
||||||
{
|
{
|
||||||
@ -128,20 +145,18 @@ void make_tree(MMVManip &vmanip, v3s16 p0, bool is_apple_tree,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// L-System tree LUA spawner
|
|
||||||
treegen::error spawn_ltree(ServerMap *map, v3s16 p0,
|
treegen::error spawn_ltree(ServerMap *map, v3s16 p0,
|
||||||
const NodeDefManager *ndef, const TreeDef &tree_definition)
|
const TreeDef &tree_definition)
|
||||||
{
|
{
|
||||||
std::map<v3s16, MapBlock*> modified_blocks;
|
|
||||||
MMVManip vmanip(map);
|
MMVManip vmanip(map);
|
||||||
v3s16 tree_blockp = getNodeBlockPos(p0);
|
v3s16 tree_blockp = getNodeBlockPos(p0);
|
||||||
treegen::error e;
|
|
||||||
|
|
||||||
vmanip.initialEmerge(tree_blockp - v3s16(1, 1, 1), tree_blockp + v3s16(1, 3, 1));
|
vmanip.initialEmerge(tree_blockp - v3s16(1, 1, 1), tree_blockp + v3s16(1, 3, 1));
|
||||||
e = make_ltree(vmanip, p0, ndef, tree_definition);
|
treegen::error e = make_ltree(vmanip, p0, tree_definition);
|
||||||
if (e != SUCCESS)
|
if (e != SUCCESS)
|
||||||
return e;
|
return e;
|
||||||
|
|
||||||
|
std::map<v3s16, MapBlock*> modified_blocks;
|
||||||
voxalgo::blit_back_with_light(map, &vmanip, &modified_blocks);
|
voxalgo::blit_back_with_light(map, &vmanip, &modified_blocks);
|
||||||
|
|
||||||
// Send a MEET_OTHER event
|
// Send a MEET_OTHER event
|
||||||
@ -153,9 +168,8 @@ treegen::error spawn_ltree(ServerMap *map, v3s16 p0,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//L-System tree generator
|
|
||||||
treegen::error make_ltree(MMVManip &vmanip, v3s16 p0,
|
treegen::error make_ltree(MMVManip &vmanip, v3s16 p0,
|
||||||
const NodeDefManager *ndef, TreeDef tree_definition)
|
const TreeDef &tree_definition)
|
||||||
{
|
{
|
||||||
s32 seed;
|
s32 seed;
|
||||||
if (tree_definition.explicit_seed)
|
if (tree_definition.explicit_seed)
|
||||||
@ -165,10 +179,10 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0,
|
|||||||
PseudoRandom ps(seed);
|
PseudoRandom ps(seed);
|
||||||
|
|
||||||
// chance of inserting abcd rules
|
// chance of inserting abcd rules
|
||||||
double prop_a = 9;
|
constexpr float prop_a = 9;
|
||||||
double prop_b = 8;
|
constexpr float prop_b = 8;
|
||||||
double prop_c = 7;
|
constexpr float prop_c = 7;
|
||||||
double prop_d = 6;
|
constexpr float prop_d = 6;
|
||||||
|
|
||||||
//randomize tree growth level, minimum=2
|
//randomize tree growth level, minimum=2
|
||||||
s16 iterations = tree_definition.iterations;
|
s16 iterations = tree_definition.iterations;
|
||||||
@ -177,13 +191,13 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0,
|
|||||||
if (iterations < 2)
|
if (iterations < 2)
|
||||||
iterations = 2;
|
iterations = 2;
|
||||||
|
|
||||||
s16 MAX_ANGLE_OFFSET = 5;
|
constexpr s16 MAX_ANGLE_OFFSET = 5;
|
||||||
double angle_in_radians = (double)tree_definition.angle * M_PI / 180;
|
float angle_in_radians = tree_definition.angle * M_PI / 180;
|
||||||
double angleOffset_in_radians = (s16)(ps.range(0, 1) % MAX_ANGLE_OFFSET) * M_PI / 180;
|
float angleOffset_in_radians = (s16)(ps.range(0, 1) % MAX_ANGLE_OFFSET) * M_PI / 180;
|
||||||
|
|
||||||
//initialize rotation matrix, position and stacks for branches
|
//initialize rotation matrix, position and stacks for branches
|
||||||
core::matrix4 rotation;
|
core::matrix4 rotation;
|
||||||
rotation = setRotationAxisRadians(rotation, M_PI / 2, v3f(0, 0, 1));
|
setRotationAxisRadians(rotation, M_PI / 2, v3f(0, 0, 1));
|
||||||
v3f position;
|
v3f position;
|
||||||
position.X = p0.X;
|
position.X = p0.X;
|
||||||
position.Y = p0.Y;
|
position.Y = p0.Y;
|
||||||
@ -494,37 +508,37 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0,
|
|||||||
break;
|
break;
|
||||||
case '+':
|
case '+':
|
||||||
temp_rotation.makeIdentity();
|
temp_rotation.makeIdentity();
|
||||||
temp_rotation = setRotationAxisRadians(temp_rotation,
|
setRotationAxisRadians(temp_rotation,
|
||||||
angle_in_radians + angleOffset_in_radians, v3f(0, 0, 1));
|
angle_in_radians + angleOffset_in_radians, v3f(0, 0, 1));
|
||||||
rotation *= temp_rotation;
|
rotation *= temp_rotation;
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
temp_rotation.makeIdentity();
|
temp_rotation.makeIdentity();
|
||||||
temp_rotation = setRotationAxisRadians(temp_rotation,
|
setRotationAxisRadians(temp_rotation,
|
||||||
angle_in_radians + angleOffset_in_radians, v3f(0, 0, -1));
|
angle_in_radians + angleOffset_in_radians, v3f(0, 0, -1));
|
||||||
rotation *= temp_rotation;
|
rotation *= temp_rotation;
|
||||||
break;
|
break;
|
||||||
case '&':
|
case '&':
|
||||||
temp_rotation.makeIdentity();
|
temp_rotation.makeIdentity();
|
||||||
temp_rotation = setRotationAxisRadians(temp_rotation,
|
setRotationAxisRadians(temp_rotation,
|
||||||
angle_in_radians + angleOffset_in_radians, v3f(0, 1, 0));
|
angle_in_radians + angleOffset_in_radians, v3f(0, 1, 0));
|
||||||
rotation *= temp_rotation;
|
rotation *= temp_rotation;
|
||||||
break;
|
break;
|
||||||
case '^':
|
case '^':
|
||||||
temp_rotation.makeIdentity();
|
temp_rotation.makeIdentity();
|
||||||
temp_rotation = setRotationAxisRadians(temp_rotation,
|
setRotationAxisRadians(temp_rotation,
|
||||||
angle_in_radians + angleOffset_in_radians, v3f(0, -1, 0));
|
angle_in_radians + angleOffset_in_radians, v3f(0, -1, 0));
|
||||||
rotation *= temp_rotation;
|
rotation *= temp_rotation;
|
||||||
break;
|
break;
|
||||||
case '*':
|
case '*':
|
||||||
temp_rotation.makeIdentity();
|
temp_rotation.makeIdentity();
|
||||||
temp_rotation = setRotationAxisRadians(temp_rotation,
|
setRotationAxisRadians(temp_rotation,
|
||||||
angle_in_radians, v3f(1, 0, 0));
|
angle_in_radians, v3f(1, 0, 0));
|
||||||
rotation *= temp_rotation;
|
rotation *= temp_rotation;
|
||||||
break;
|
break;
|
||||||
case '/':
|
case '/':
|
||||||
temp_rotation.makeIdentity();
|
temp_rotation.makeIdentity();
|
||||||
temp_rotation = setRotationAxisRadians(temp_rotation,
|
setRotationAxisRadians(temp_rotation,
|
||||||
angle_in_radians, v3f(-1, 0, 0));
|
angle_in_radians, v3f(-1, 0, 0));
|
||||||
rotation *= temp_rotation;
|
rotation *= temp_rotation;
|
||||||
break;
|
break;
|
||||||
@ -537,7 +551,7 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void tree_trunk_placement(MMVManip &vmanip, v3f p0, TreeDef &tree_definition)
|
void tree_trunk_placement(MMVManip &vmanip, v3f p0, const TreeDef &tree_definition)
|
||||||
{
|
{
|
||||||
v3s16 p1 = v3s16(myround(p0.X), myround(p0.Y), myround(p0.Z));
|
v3s16 p1 = v3s16(myround(p0.X), myround(p0.Y), myround(p0.Z));
|
||||||
if (!vmanip.m_area.contains(p1))
|
if (!vmanip.m_area.contains(p1))
|
||||||
@ -554,7 +568,7 @@ void tree_trunk_placement(MMVManip &vmanip, v3f p0, TreeDef &tree_definition)
|
|||||||
|
|
||||||
|
|
||||||
void tree_leaves_placement(MMVManip &vmanip, v3f p0,
|
void tree_leaves_placement(MMVManip &vmanip, v3f p0,
|
||||||
PseudoRandom ps, TreeDef &tree_definition)
|
PseudoRandom ps, const TreeDef &tree_definition)
|
||||||
{
|
{
|
||||||
MapNode leavesnode = tree_definition.leavesnode;
|
MapNode leavesnode = tree_definition.leavesnode;
|
||||||
if (ps.range(1, 100) > 100 - tree_definition.leaves2_chance)
|
if (ps.range(1, 100) > 100 - tree_definition.leaves2_chance)
|
||||||
@ -578,7 +592,7 @@ void tree_leaves_placement(MMVManip &vmanip, v3f p0,
|
|||||||
|
|
||||||
|
|
||||||
void tree_single_leaves_placement(MMVManip &vmanip, v3f p0,
|
void tree_single_leaves_placement(MMVManip &vmanip, v3f p0,
|
||||||
PseudoRandom ps, TreeDef &tree_definition)
|
PseudoRandom ps, const TreeDef &tree_definition)
|
||||||
{
|
{
|
||||||
MapNode leavesnode = tree_definition.leavesnode;
|
MapNode leavesnode = tree_definition.leavesnode;
|
||||||
if (ps.range(1, 100) > 100 - tree_definition.leaves2_chance)
|
if (ps.range(1, 100) > 100 - tree_definition.leaves2_chance)
|
||||||
@ -594,7 +608,7 @@ void tree_single_leaves_placement(MMVManip &vmanip, v3f p0,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void tree_fruit_placement(MMVManip &vmanip, v3f p0, TreeDef &tree_definition)
|
void tree_fruit_placement(MMVManip &vmanip, v3f p0, const TreeDef &tree_definition)
|
||||||
{
|
{
|
||||||
v3s16 p1 = v3s16(myround(p0.X), myround(p0.Y), myround(p0.Z));
|
v3s16 p1 = v3s16(myround(p0.X), myround(p0.Y), myround(p0.Z));
|
||||||
if (!vmanip.m_area.contains(p1))
|
if (!vmanip.m_area.contains(p1))
|
||||||
@ -607,18 +621,18 @@ void tree_fruit_placement(MMVManip &vmanip, v3f p0, TreeDef &tree_definition)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
irr::core::matrix4 setRotationAxisRadians(irr::core::matrix4 M, double angle, v3f axis)
|
void setRotationAxisRadians(core::matrix4 &M, float angle, v3f axis)
|
||||||
{
|
{
|
||||||
double c = cos(angle);
|
float c = std::cos(angle);
|
||||||
double s = sin(angle);
|
float s = std::sin(angle);
|
||||||
double t = 1.0 - c;
|
float t = 1.0f - c;
|
||||||
|
|
||||||
double tx = t * axis.X;
|
float tx = t * axis.X;
|
||||||
double ty = t * axis.Y;
|
float ty = t * axis.Y;
|
||||||
double tz = t * axis.Z;
|
float tz = t * axis.Z;
|
||||||
double sx = s * axis.X;
|
float sx = s * axis.X;
|
||||||
double sy = s * axis.Y;
|
float sy = s * axis.Y;
|
||||||
double sz = s * axis.Z;
|
float sz = s * axis.Z;
|
||||||
|
|
||||||
M[0] = tx * axis.X + c;
|
M[0] = tx * axis.X + c;
|
||||||
M[1] = tx * axis.Y + sz;
|
M[1] = tx * axis.Y + sz;
|
||||||
@ -631,19 +645,15 @@ irr::core::matrix4 setRotationAxisRadians(irr::core::matrix4 M, double angle, v3
|
|||||||
M[8] = tz * axis.X + sy;
|
M[8] = tz * axis.X + sy;
|
||||||
M[9] = tz * axis.Y - sx;
|
M[9] = tz * axis.Y - sx;
|
||||||
M[10] = tz * axis.Z + c;
|
M[10] = tz * axis.Z + c;
|
||||||
return M;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
v3f transposeMatrix(irr::core::matrix4 M, v3f v)
|
v3f transposeMatrix(const core::matrix4 &M, v3f v)
|
||||||
{
|
{
|
||||||
v3f translated;
|
v3f translated;
|
||||||
double x = M[0] * v.X + M[4] * v.Y + M[8] * v.Z +M[12];
|
translated.X = M[0] * v.X + M[4] * v.Y + M[8] * v.Z + M[12];
|
||||||
double y = M[1] * v.X + M[5] * v.Y + M[9] * v.Z +M[13];
|
translated.Y = M[1] * v.X + M[5] * v.Y + M[9] * v.Z + M[13];
|
||||||
double z = M[2] * v.X + M[6] * v.Y + M[10] * v.Z +M[14];
|
translated.Z = M[2] * v.X + M[6] * v.Y + M[10] * v.Z + M[14];
|
||||||
translated.X = x;
|
|
||||||
translated.Y = y;
|
|
||||||
translated.Z = z;
|
|
||||||
return translated;
|
return translated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,8 +21,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <matrix4.h>
|
#include <string>
|
||||||
#include "noise.h"
|
#include "irr_v3d.h"
|
||||||
|
#include "nodedef.h"
|
||||||
|
#include "mapnode.h"
|
||||||
|
|
||||||
class MMVManip;
|
class MMVManip;
|
||||||
class NodeDefManager;
|
class NodeDefManager;
|
||||||
@ -77,24 +79,8 @@ namespace treegen {
|
|||||||
void make_pine_tree(MMVManip &vmanip, v3s16 p0,
|
void make_pine_tree(MMVManip &vmanip, v3s16 p0,
|
||||||
const NodeDefManager *ndef, s32 seed);
|
const NodeDefManager *ndef, s32 seed);
|
||||||
|
|
||||||
// Add L-Systems tree (used by engine)
|
// Spawn L-Systems tree on VManip
|
||||||
treegen::error make_ltree(MMVManip &vmanip, v3s16 p0,
|
treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, const TreeDef &def);
|
||||||
const NodeDefManager *ndef, TreeDef tree_definition);
|
// Helper to spawn it directly on map
|
||||||
// Spawn L-systems tree from LUA
|
treegen::error spawn_ltree(ServerMap *map, v3s16 p0, const TreeDef &def);
|
||||||
treegen::error spawn_ltree (ServerMap *map, v3s16 p0,
|
|
||||||
const NodeDefManager *ndef, const TreeDef &tree_definition);
|
|
||||||
|
|
||||||
// L-System tree gen helper functions
|
|
||||||
void tree_trunk_placement(MMVManip &vmanip, v3f p0,
|
|
||||||
TreeDef &tree_definition);
|
|
||||||
void tree_leaves_placement(MMVManip &vmanip, v3f p0,
|
|
||||||
PseudoRandom ps, TreeDef &tree_definition);
|
|
||||||
void tree_single_leaves_placement(MMVManip &vmanip, v3f p0,
|
|
||||||
PseudoRandom ps, TreeDef &tree_definition);
|
|
||||||
void tree_fruit_placement(MMVManip &vmanip, v3f p0,
|
|
||||||
TreeDef &tree_definition);
|
|
||||||
irr::core::matrix4 setRotationAxisRadians(irr::core::matrix4 M, double angle, v3f axis);
|
|
||||||
|
|
||||||
v3f transposeMatrix(irr::core::matrix4 M ,v3f v);
|
|
||||||
|
|
||||||
}; // namespace treegen
|
}; // namespace treegen
|
||||||
|
@ -68,7 +68,7 @@ u16 BufferedPacket::getSeqnum() const
|
|||||||
return readU16(&data[BASE_HEADER_SIZE + 1]);
|
return readU16(&data[BASE_HEADER_SIZE + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferedPacketPtr makePacket(Address &address, const SharedBuffer<u8> &data,
|
BufferedPacketPtr makePacket(const Address &address, const SharedBuffer<u8> &data,
|
||||||
u32 protocol_id, session_t sender_peer_id, u8 channel)
|
u32 protocol_id, session_t sender_peer_id, u8 channel)
|
||||||
{
|
{
|
||||||
u32 packet_size = data.getSize() + BASE_HEADER_SIZE;
|
u32 packet_size = data.getSize() + BASE_HEADER_SIZE;
|
||||||
@ -834,13 +834,6 @@ void Channel::UpdateTimers(float dtime)
|
|||||||
Peer
|
Peer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PeerHelper::PeerHelper(Peer* peer) :
|
|
||||||
m_peer(peer)
|
|
||||||
{
|
|
||||||
if (peer && !peer->IncUseCount())
|
|
||||||
m_peer = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
PeerHelper::~PeerHelper()
|
PeerHelper::~PeerHelper()
|
||||||
{
|
{
|
||||||
if (m_peer)
|
if (m_peer)
|
||||||
@ -851,32 +844,14 @@ PeerHelper::~PeerHelper()
|
|||||||
|
|
||||||
PeerHelper& PeerHelper::operator=(Peer* peer)
|
PeerHelper& PeerHelper::operator=(Peer* peer)
|
||||||
{
|
{
|
||||||
|
if (m_peer)
|
||||||
|
m_peer->DecUseCount();
|
||||||
m_peer = peer;
|
m_peer = peer;
|
||||||
if (peer && !peer->IncUseCount())
|
if (peer && !peer->IncUseCount())
|
||||||
m_peer = nullptr;
|
m_peer = nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Peer* PeerHelper::operator->() const
|
|
||||||
{
|
|
||||||
return m_peer;
|
|
||||||
}
|
|
||||||
|
|
||||||
Peer* PeerHelper::operator&() const
|
|
||||||
{
|
|
||||||
return m_peer;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PeerHelper::operator!()
|
|
||||||
{
|
|
||||||
return ! m_peer;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PeerHelper::operator!=(void* ptr)
|
|
||||||
{
|
|
||||||
return ((void*) m_peer != ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Peer::IncUseCount()
|
bool Peer::IncUseCount()
|
||||||
{
|
{
|
||||||
MutexAutoLock lock(m_exclusive_access_mutex);
|
MutexAutoLock lock(m_exclusive_access_mutex);
|
||||||
@ -989,8 +964,8 @@ void Peer::Drop()
|
|||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
UDPPeer::UDPPeer(session_t a_id, Address a_address, Connection* connection) :
|
UDPPeer::UDPPeer(session_t id, const Address &address, Connection *connection) :
|
||||||
Peer(a_address,a_id,connection)
|
Peer(id, address, connection)
|
||||||
{
|
{
|
||||||
for (Channel &channel : channels)
|
for (Channel &channel : channels)
|
||||||
channel.setWindowSize(START_RELIABLE_WINDOW_SIZE);
|
channel.setWindowSize(START_RELIABLE_WINDOW_SIZE);
|
||||||
@ -1014,17 +989,6 @@ bool UDPPeer::isTimedOut(float timeout, std::string &reason)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UDPPeer::getAddress(MTProtocols type,Address& toset)
|
|
||||||
{
|
|
||||||
if ((type == MTP_UDP) || (type == MTP_MINETEST_RELIABLE_UDP) || (type == MTP_PRIMARY))
|
|
||||||
{
|
|
||||||
toset = address;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UDPPeer::reportRTT(float rtt)
|
void UDPPeer::reportRTT(float rtt)
|
||||||
{
|
{
|
||||||
if (rtt < 0.0) {
|
if (rtt < 0.0) {
|
||||||
@ -1377,20 +1341,12 @@ PeerHelper Connection::getPeerNoEx(session_t peer_id)
|
|||||||
session_t Connection::lookupPeer(const Address& sender)
|
session_t Connection::lookupPeer(const Address& sender)
|
||||||
{
|
{
|
||||||
MutexAutoLock peerlock(m_peers_mutex);
|
MutexAutoLock peerlock(m_peers_mutex);
|
||||||
std::map<u16, Peer*>::iterator j;
|
for (auto &it: m_peers) {
|
||||||
j = m_peers.begin();
|
Peer *peer = it.second;
|
||||||
for(; j != m_peers.end(); ++j)
|
|
||||||
{
|
|
||||||
Peer *peer = j->second;
|
|
||||||
if (peer->isPendingDeletion())
|
if (peer->isPendingDeletion())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Address tocheck;
|
if (peer->getAddress() == sender)
|
||||||
|
|
||||||
if ((peer->getAddress(MTP_MINETEST_RELIABLE_UDP, tocheck)) && (tocheck == sender))
|
|
||||||
return peer->id;
|
|
||||||
|
|
||||||
if ((peer->getAddress(MTP_UDP, tocheck)) && (tocheck == sender))
|
|
||||||
return peer->id;
|
return peer->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1427,12 +1383,8 @@ bool Connection::deletePeer(session_t peer_id, bool timeout)
|
|||||||
m_peer_ids.erase(it);
|
m_peer_ids.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
Address peer_address;
|
|
||||||
//any peer has a primary address this never fails!
|
|
||||||
peer->getAddress(MTP_PRIMARY, peer_address);
|
|
||||||
|
|
||||||
// Create event
|
// Create event
|
||||||
putEvent(ConnectionEvent::peerRemoved(peer_id, timeout, peer_address));
|
putEvent(ConnectionEvent::peerRemoved(peer_id, timeout, peer->getAddress()));
|
||||||
|
|
||||||
peer->Drop();
|
peer->Drop();
|
||||||
return true;
|
return true;
|
||||||
@ -1562,15 +1514,14 @@ Address Connection::GetPeerAddress(session_t peer_id)
|
|||||||
|
|
||||||
if (!peer)
|
if (!peer)
|
||||||
throw PeerNotFoundException("No address for peer found!");
|
throw PeerNotFoundException("No address for peer found!");
|
||||||
Address peer_address;
|
return peer->getAddress();
|
||||||
peer->getAddress(MTP_PRIMARY, peer_address);
|
|
||||||
return peer_address;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float Connection::getPeerStat(session_t peer_id, rtt_stat_type type)
|
float Connection::getPeerStat(session_t peer_id, rtt_stat_type type)
|
||||||
{
|
{
|
||||||
PeerHelper peer = getPeerNoEx(peer_id);
|
PeerHelper peer = getPeerNoEx(peer_id);
|
||||||
if (!peer) return -1;
|
if (!peer)
|
||||||
|
return -1;
|
||||||
return peer->getStat(type);
|
return peer->getStat(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1580,7 +1531,7 @@ float Connection::getLocalStat(rate_stat_type type)
|
|||||||
|
|
||||||
FATAL_ERROR_IF(!peer, "Connection::getLocalStat we couldn't get our own peer? are you serious???");
|
FATAL_ERROR_IF(!peer, "Connection::getLocalStat we couldn't get our own peer? are you serious???");
|
||||||
|
|
||||||
float retval = 0.0;
|
float retval = 0;
|
||||||
|
|
||||||
for (Channel &channel : dynamic_cast<UDPPeer *>(&peer)->channels) {
|
for (Channel &channel : dynamic_cast<UDPPeer *>(&peer)->channels) {
|
||||||
switch(type) {
|
switch(type) {
|
||||||
@ -1609,7 +1560,7 @@ float Connection::getLocalStat(rate_stat_type type)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
session_t Connection::createPeer(Address& sender, MTProtocols protocol, int fd)
|
session_t Connection::createPeer(const Address &sender, int fd)
|
||||||
{
|
{
|
||||||
// Somebody wants to make a new connection
|
// Somebody wants to make a new connection
|
||||||
|
|
||||||
@ -1694,12 +1645,10 @@ void Connection::sendAck(session_t peer_id, u8 channelnum, u16 seqnum)
|
|||||||
m_sendThread->Trigger();
|
m_sendThread->Trigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
UDPPeer* Connection::createServerPeer(Address& address)
|
UDPPeer* Connection::createServerPeer(const Address &address)
|
||||||
{
|
{
|
||||||
if (ConnectedToServer())
|
if (ConnectedToServer())
|
||||||
{
|
|
||||||
throw ConnectionException("Already connected to a server");
|
throw ConnectionException("Already connected to a server");
|
||||||
}
|
|
||||||
|
|
||||||
UDPPeer *peer = new UDPPeer(PEER_ID_SERVER, address, this);
|
UDPPeer *peer = new UDPPeer(PEER_ID_SERVER, address, this);
|
||||||
peer->SetFullyOpen();
|
peer->SetFullyOpen();
|
||||||
|
@ -25,8 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "util/pointer.h"
|
#include "util/pointer.h"
|
||||||
#include "util/container.h"
|
#include "util/container.h"
|
||||||
#include "util/thread.h"
|
|
||||||
#include "util/numeric.h"
|
#include "util/numeric.h"
|
||||||
|
#include "porting.h"
|
||||||
#include "networkprotocol.h"
|
#include "networkprotocol.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -40,12 +40,6 @@ namespace con
|
|||||||
class ConnectionReceiveThread;
|
class ConnectionReceiveThread;
|
||||||
class ConnectionSendThread;
|
class ConnectionSendThread;
|
||||||
|
|
||||||
enum MTProtocols {
|
|
||||||
MTP_PRIMARY,
|
|
||||||
MTP_UDP,
|
|
||||||
MTP_MINETEST_RELIABLE_UDP
|
|
||||||
};
|
|
||||||
|
|
||||||
enum rate_stat_type {
|
enum rate_stat_type {
|
||||||
CUR_DL_RATE,
|
CUR_DL_RATE,
|
||||||
AVG_DL_RATE,
|
AVG_DL_RATE,
|
||||||
@ -57,18 +51,20 @@ enum rate_stat_type {
|
|||||||
|
|
||||||
class Peer;
|
class Peer;
|
||||||
|
|
||||||
|
// FIXME: Peer refcounting should generally be replaced by std::shared_ptr
|
||||||
class PeerHelper
|
class PeerHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PeerHelper() = default;
|
PeerHelper() = default;
|
||||||
PeerHelper(Peer* peer);
|
inline PeerHelper(Peer *peer) { *this = peer; }
|
||||||
~PeerHelper();
|
~PeerHelper();
|
||||||
|
|
||||||
PeerHelper& operator=(Peer* peer);
|
PeerHelper& operator=(Peer *peer);
|
||||||
Peer* operator->() const;
|
inline Peer* operator->() const { return m_peer; }
|
||||||
bool operator!();
|
inline Peer* operator&() const { return m_peer; }
|
||||||
Peer* operator&() const;
|
|
||||||
bool operator!=(void* ptr);
|
inline bool operator!() { return !m_peer; }
|
||||||
|
inline bool operator!=(std::nullptr_t) { return !!m_peer; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Peer *m_peer = nullptr;
|
Peer *m_peer = nullptr;
|
||||||
@ -127,18 +123,10 @@ class Peer {
|
|||||||
public:
|
public:
|
||||||
friend class PeerHelper;
|
friend class PeerHelper;
|
||||||
|
|
||||||
Peer(Address address_,session_t id_,Connection* connection) :
|
|
||||||
id(id_),
|
|
||||||
m_connection(connection),
|
|
||||||
address(address_),
|
|
||||||
m_last_timeout_check(porting::getTimeMs())
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ~Peer() {
|
virtual ~Peer() {
|
||||||
MutexAutoLock usage_lock(m_exclusive_access_mutex);
|
MutexAutoLock usage_lock(m_exclusive_access_mutex);
|
||||||
FATAL_ERROR_IF(m_usage != 0, "Reference counting failure");
|
FATAL_ERROR_IF(m_usage != 0, "Reference counting failure");
|
||||||
};
|
}
|
||||||
|
|
||||||
// Unique id of the peer
|
// Unique id of the peer
|
||||||
const session_t id;
|
const session_t id;
|
||||||
@ -148,16 +136,25 @@ class Peer {
|
|||||||
virtual void PutReliableSendCommand(ConnectionCommandPtr &c,
|
virtual void PutReliableSendCommand(ConnectionCommandPtr &c,
|
||||||
unsigned int max_packet_size) {};
|
unsigned int max_packet_size) {};
|
||||||
|
|
||||||
virtual bool getAddress(MTProtocols type, Address& toset) = 0;
|
virtual const Address &getAddress() const = 0;
|
||||||
|
|
||||||
bool isPendingDeletion()
|
bool isPendingDeletion() const {
|
||||||
{ MutexAutoLock lock(m_exclusive_access_mutex); return m_pending_deletion; };
|
MutexAutoLock lock(m_exclusive_access_mutex);
|
||||||
|
return m_pending_deletion;
|
||||||
|
}
|
||||||
|
void ResetTimeout() {
|
||||||
|
MutexAutoLock lock(m_exclusive_access_mutex);
|
||||||
|
m_timeout_counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void ResetTimeout()
|
bool isHalfOpen() const {
|
||||||
{MutexAutoLock lock(m_exclusive_access_mutex); m_timeout_counter = 0.0; };
|
MutexAutoLock lock(m_exclusive_access_mutex);
|
||||||
|
return m_half_open;
|
||||||
bool isHalfOpen() const { return m_half_open; }
|
}
|
||||||
void SetFullyOpen() { m_half_open = false; }
|
void SetFullyOpen() {
|
||||||
|
MutexAutoLock lock(m_exclusive_access_mutex);
|
||||||
|
m_half_open = false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool isTimedOut(float timeout, std::string &reason);
|
virtual bool isTimedOut(float timeout, std::string &reason);
|
||||||
|
|
||||||
@ -168,10 +165,8 @@ class Peer {
|
|||||||
virtual SharedBuffer<u8> addSplitPacket(u8 channel, BufferedPacketPtr &toadd,
|
virtual SharedBuffer<u8> addSplitPacket(u8 channel, BufferedPacketPtr &toadd,
|
||||||
bool reliable)
|
bool reliable)
|
||||||
{
|
{
|
||||||
errorstream << "Peer::addSplitPacket called,"
|
FATAL_ERROR("unimplemented in abstract class");
|
||||||
<< " this is supposed to be never called!" << std::endl;
|
}
|
||||||
return SharedBuffer<u8>(0);
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual bool Ping(float dtime, SharedBuffer<u8>& data) { return false; };
|
virtual bool Ping(float dtime, SharedBuffer<u8>& data) { return false; };
|
||||||
|
|
||||||
@ -192,7 +187,16 @@ class Peer {
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
Peer(session_t id, const Address &address, Connection *connection) :
|
||||||
|
id(id),
|
||||||
|
m_connection(connection),
|
||||||
|
address(address),
|
||||||
|
m_last_timeout_check(porting::getTimeMs())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
virtual void reportRTT(float rtt) {};
|
virtual void reportRTT(float rtt) {};
|
||||||
|
|
||||||
void RTTStatistics(float rtt,
|
void RTTStatistics(float rtt,
|
||||||
@ -206,15 +210,15 @@ class Peer {
|
|||||||
|
|
||||||
bool m_pending_deletion = false;
|
bool m_pending_deletion = false;
|
||||||
|
|
||||||
Connection* m_connection;
|
Connection *m_connection;
|
||||||
|
|
||||||
// Address of the peer
|
// Address of the peer
|
||||||
Address address;
|
Address address;
|
||||||
|
|
||||||
// Ping timer
|
// Ping timer
|
||||||
float m_ping_timer = 0.0f;
|
float m_ping_timer = 0.0f;
|
||||||
private:
|
|
||||||
|
|
||||||
|
private:
|
||||||
struct rttstats {
|
struct rttstats {
|
||||||
float jitter_min = FLT_MAX;
|
float jitter_min = FLT_MAX;
|
||||||
float jitter_max = 0.0f;
|
float jitter_max = 0.0f;
|
||||||
@ -222,8 +226,6 @@ class Peer {
|
|||||||
float min_rtt = FLT_MAX;
|
float min_rtt = FLT_MAX;
|
||||||
float max_rtt = 0.0f;
|
float max_rtt = 0.0f;
|
||||||
float avg_rtt = -1.0f;
|
float avg_rtt = -1.0f;
|
||||||
|
|
||||||
rttstats() = default;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
rttstats m_rtt;
|
rttstats m_rtt;
|
||||||
@ -285,8 +287,8 @@ protected:
|
|||||||
PeerHelper getPeerNoEx(session_t peer_id);
|
PeerHelper getPeerNoEx(session_t peer_id);
|
||||||
session_t lookupPeer(const Address& sender);
|
session_t lookupPeer(const Address& sender);
|
||||||
|
|
||||||
session_t createPeer(Address& sender, MTProtocols protocol, int fd);
|
session_t createPeer(const Address& sender, int fd);
|
||||||
UDPPeer* createServerPeer(Address& sender);
|
UDPPeer* createServerPeer(const Address& sender);
|
||||||
bool deletePeer(session_t peer_id, bool timeout);
|
bool deletePeer(session_t peer_id, bool timeout);
|
||||||
|
|
||||||
void SetPeerID(session_t id) { m_peer_id = id; }
|
void SetPeerID(session_t id) { m_peer_id = id; }
|
||||||
|
@ -193,7 +193,7 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
// This adds the base headers to the data and makes a packet out of it
|
// This adds the base headers to the data and makes a packet out of it
|
||||||
BufferedPacketPtr makePacket(Address &address, const SharedBuffer<u8> &data,
|
BufferedPacketPtr makePacket(const Address &address, const SharedBuffer<u8> &data,
|
||||||
u32 protocol_id, session_t sender_peer_id, u8 channel);
|
u32 protocol_id, session_t sender_peer_id, u8 channel);
|
||||||
|
|
||||||
// Depending on size, make a TYPE_ORIGINAL or TYPE_SPLIT packet
|
// Depending on size, make a TYPE_ORIGINAL or TYPE_SPLIT packet
|
||||||
@ -235,9 +235,7 @@ private:
|
|||||||
class ReliablePacketBuffer
|
class ReliablePacketBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ReliablePacketBuffer() = default;
|
bool getFirstSeqnum(u16 &result);
|
||||||
|
|
||||||
bool getFirstSeqnum(u16& result);
|
|
||||||
|
|
||||||
BufferedPacketPtr popFirst();
|
BufferedPacketPtr popFirst();
|
||||||
BufferedPacketPtr popSeqnum(u16 seqnum);
|
BufferedPacketPtr popSeqnum(u16 seqnum);
|
||||||
@ -273,6 +271,7 @@ class IncomingSplitBuffer
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
~IncomingSplitBuffer();
|
~IncomingSplitBuffer();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Returns a reference counted buffer of length != 0 when a full split
|
Returns a reference counted buffer of length != 0 when a full split
|
||||||
packet is constructed. If not, returns one of length 0.
|
packet is constructed. If not, returns one of length 0.
|
||||||
@ -450,13 +449,15 @@ public:
|
|||||||
friend class ConnectionSendThread;
|
friend class ConnectionSendThread;
|
||||||
friend class Connection;
|
friend class Connection;
|
||||||
|
|
||||||
UDPPeer(u16 id, Address address, Connection *connection);
|
UDPPeer(session_t id, const Address &address, Connection *connection);
|
||||||
virtual ~UDPPeer() = default;
|
virtual ~UDPPeer() = default;
|
||||||
|
|
||||||
void PutReliableSendCommand(ConnectionCommandPtr &c,
|
void PutReliableSendCommand(ConnectionCommandPtr &c,
|
||||||
unsigned int max_packet_size) override;
|
unsigned int max_packet_size) override;
|
||||||
|
|
||||||
bool getAddress(MTProtocols type, Address& toset) override;
|
virtual const Address &getAddress() const {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
u16 getNextSplitSequenceNumber(u8 channel) override;
|
u16 getNextSplitSequenceNumber(u8 channel) override;
|
||||||
void setNextSplitSequenceNumber(u8 channel, u16 seqnum) override;
|
void setNextSplitSequenceNumber(u8 channel, u16 seqnum) override;
|
||||||
|
@ -348,11 +348,9 @@ bool ConnectionSendThread::rawSendAsPacket(session_t peer_id, u8 channelnum,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
SharedBuffer<u8> reliable = makeReliablePacket(data, seqnum);
|
SharedBuffer<u8> reliable = makeReliablePacket(data, seqnum);
|
||||||
Address peer_address;
|
|
||||||
peer->getAddress(MTP_MINETEST_RELIABLE_UDP, peer_address);
|
|
||||||
|
|
||||||
// Add base headers and make a packet
|
// Add base headers and make a packet
|
||||||
BufferedPacketPtr p = con::makePacket(peer_address, reliable,
|
BufferedPacketPtr p = con::makePacket(peer->getAddress(), reliable,
|
||||||
m_connection->GetProtocolID(), m_connection->GetPeerID(),
|
m_connection->GetProtocolID(), m_connection->GetPeerID(),
|
||||||
channelnum);
|
channelnum);
|
||||||
|
|
||||||
@ -374,22 +372,14 @@ bool ConnectionSendThread::rawSendAsPacket(session_t peer_id, u8 channelnum,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Address peer_address;
|
// Add base headers and make a packet
|
||||||
if (peer->getAddress(MTP_UDP, peer_address)) {
|
BufferedPacketPtr p = con::makePacket(peer->getAddress(), data,
|
||||||
// Add base headers and make a packet
|
m_connection->GetProtocolID(), m_connection->GetPeerID(),
|
||||||
BufferedPacketPtr p = con::makePacket(peer_address, data,
|
channelnum);
|
||||||
m_connection->GetProtocolID(), m_connection->GetPeerID(),
|
|
||||||
channelnum);
|
|
||||||
|
|
||||||
// Send the packet
|
// Send the packet
|
||||||
rawSend(p.get());
|
rawSend(p.get());
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
LOG(dout_con << m_connection->getDesc()
|
|
||||||
<< " INFO: dropped unreliable packet for peer_id: " << peer_id
|
|
||||||
<< " because of (yet) missing udp address" << std::endl);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionSendThread::processReliableCommand(ConnectionCommandPtr &c)
|
void ConnectionSendThread::processReliableCommand(ConnectionCommandPtr &c)
|
||||||
@ -984,7 +974,7 @@ void ConnectionReceiveThread::receive(SharedBuffer<u8> &packetdata,
|
|||||||
l.logged = true;
|
l.logged = true;
|
||||||
// We simply drop the packet, the client can try again.
|
// We simply drop the packet, the client can try again.
|
||||||
} else {
|
} else {
|
||||||
peer_id = m_connection->createPeer(sender, MTP_MINETEST_RELIABLE_UDP, 0);
|
peer_id = m_connection->createPeer(sender, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -999,17 +989,9 @@ void ConnectionReceiveThread::receive(SharedBuffer<u8> &packetdata,
|
|||||||
|
|
||||||
// Validate peer address
|
// Validate peer address
|
||||||
|
|
||||||
Address peer_address;
|
if (sender != peer->getAddress()) {
|
||||||
if (peer->getAddress(MTP_UDP, peer_address)) {
|
|
||||||
if (peer_address != sender) {
|
|
||||||
LOG(derr_con << m_connection->getDesc()
|
|
||||||
<< " Peer " << peer_id << " sending from different address."
|
|
||||||
" Ignoring." << std::endl);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOG(derr_con << m_connection->getDesc()
|
LOG(derr_con << m_connection->getDesc()
|
||||||
<< " Peer " << peer_id << " doesn't have an address?!"
|
<< " Peer " << peer_id << " sending from different address."
|
||||||
" Ignoring." << std::endl);
|
" Ignoring." << std::endl);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1284,32 +1266,25 @@ SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Original(Channel *cha
|
|||||||
SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Split(Channel *channel,
|
SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Split(Channel *channel,
|
||||||
const SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum, bool reliable)
|
const SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum, bool reliable)
|
||||||
{
|
{
|
||||||
Address peer_address;
|
// We have to create a packet again for buffering
|
||||||
|
// This isn't actually too bad an idea.
|
||||||
|
BufferedPacketPtr packet = con::makePacket(peer->getAddress(),
|
||||||
|
packetdata,
|
||||||
|
m_connection->GetProtocolID(),
|
||||||
|
peer->id,
|
||||||
|
channelnum);
|
||||||
|
|
||||||
if (peer->getAddress(MTP_UDP, peer_address)) {
|
// Buffer the packet
|
||||||
// We have to create a packet again for buffering
|
SharedBuffer<u8> data = peer->addSplitPacket(channelnum, packet, reliable);
|
||||||
// This isn't actually too bad an idea.
|
|
||||||
BufferedPacketPtr packet = con::makePacket(peer_address,
|
|
||||||
packetdata,
|
|
||||||
m_connection->GetProtocolID(),
|
|
||||||
peer->id,
|
|
||||||
channelnum);
|
|
||||||
|
|
||||||
// Buffer the packet
|
if (data.getSize() != 0) {
|
||||||
SharedBuffer<u8> data = peer->addSplitPacket(channelnum, packet, reliable);
|
LOG(dout_con << m_connection->getDesc()
|
||||||
|
<< "RETURNING TYPE_SPLIT: Constructed full data, "
|
||||||
if (data.getSize() != 0) {
|
<< "size=" << data.getSize() << std::endl);
|
||||||
LOG(dout_con << m_connection->getDesc()
|
return data;
|
||||||
<< "RETURNING TYPE_SPLIT: Constructed full data, "
|
|
||||||
<< "size=" << data.getSize() << std::endl);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
LOG(dout_con << m_connection->getDesc() << "BUFFERED TYPE_SPLIT" << std::endl);
|
|
||||||
throw ProcessedSilentlyException("Buffered a split packet chunk");
|
|
||||||
}
|
}
|
||||||
|
LOG(dout_con << m_connection->getDesc() << "BUFFERED TYPE_SPLIT" << std::endl);
|
||||||
// We should never get here.
|
throw ProcessedSilentlyException("Buffered a split packet chunk");
|
||||||
FATAL_ERROR("Invalid execution point");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Reliable(Channel *channel,
|
SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Reliable(Channel *channel,
|
||||||
@ -1361,15 +1336,11 @@ SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Reliable(Channel *cha
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (seqnum != channel->readNextIncomingSeqNum()) {
|
if (seqnum != channel->readNextIncomingSeqNum()) {
|
||||||
Address peer_address;
|
|
||||||
|
|
||||||
// this is a reliable packet so we have a udp address for sure
|
|
||||||
peer->getAddress(MTP_MINETEST_RELIABLE_UDP, peer_address);
|
|
||||||
// This one comes later, buffer it.
|
// This one comes later, buffer it.
|
||||||
// Actually we have to make a packet to buffer one.
|
// Actually we have to make a packet to buffer one.
|
||||||
// Well, we have all the ingredients, so just do it.
|
// Well, we have all the ingredients, so just do it.
|
||||||
BufferedPacketPtr packet = con::makePacket(
|
BufferedPacketPtr packet = con::makePacket(
|
||||||
peer_address,
|
peer->getAddress(),
|
||||||
packetdata,
|
packetdata,
|
||||||
m_connection->GetProtocolID(),
|
m_connection->GetProtocolID(),
|
||||||
peer->id,
|
peer->id,
|
||||||
|
@ -70,8 +70,8 @@ RaycastState::RaycastState(const core::line3d<f32> &shootline,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool boxLineCollision(const aabb3f &box, const v3f &start,
|
bool boxLineCollision(const aabb3f &box, const v3f start,
|
||||||
const v3f &dir, v3f *collision_point, v3f *collision_normal)
|
const v3f dir, v3f *collision_point, v3f *collision_normal)
|
||||||
{
|
{
|
||||||
if (box.isPointInside(start)) {
|
if (box.isPointInside(start)) {
|
||||||
*collision_point = start;
|
*collision_point = start;
|
||||||
@ -139,8 +139,8 @@ bool boxLineCollision(const aabb3f &box, const v3f &start,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool boxLineCollision(const aabb3f &box, const v3f &rotation,
|
bool boxLineCollision(const aabb3f &box, const v3f rotation,
|
||||||
const v3f &start, const v3f &dir,
|
const v3f start, const v3f dir,
|
||||||
v3f *collision_point, v3f *collision_normal, v3f *raw_collision_normal)
|
v3f *collision_point, v3f *collision_normal, v3f *raw_collision_normal)
|
||||||
{
|
{
|
||||||
// Inversely transform the ray rather than rotating the box faces;
|
// Inversely transform the ray rather than rotating the box faces;
|
||||||
@ -149,7 +149,8 @@ bool boxLineCollision(const aabb3f &box, const v3f &rotation,
|
|||||||
rot.makeInverse();
|
rot.makeInverse();
|
||||||
|
|
||||||
bool collision = boxLineCollision(box, rot * start, rot * dir, collision_point, collision_normal);
|
bool collision = boxLineCollision(box, rot * start, rot * dir, collision_point, collision_normal);
|
||||||
if (!collision) return collision;
|
if (!collision)
|
||||||
|
return collision;
|
||||||
|
|
||||||
// Transform the results back
|
// Transform the results back
|
||||||
rot.makeInverse();
|
rot.makeInverse();
|
||||||
|
@ -74,9 +74,9 @@ public:
|
|||||||
* outwards of the surface. If start is in the box, zero vector.
|
* outwards of the surface. If start is in the box, zero vector.
|
||||||
* @returns true if a collision point was found
|
* @returns true if a collision point was found
|
||||||
*/
|
*/
|
||||||
bool boxLineCollision(const aabb3f &box, const v3f &start, const v3f &dir,
|
bool boxLineCollision(const aabb3f &box, v3f start, v3f dir,
|
||||||
v3f *collision_point, v3f *collision_normal);
|
v3f *collision_point, v3f *collision_normal);
|
||||||
|
|
||||||
bool boxLineCollision(const aabb3f &box, const v3f &box_rotation,
|
bool boxLineCollision(const aabb3f &box, v3f box_rotation,
|
||||||
const v3f &start, const v3f &dir,
|
v3f start, v3f dir,
|
||||||
v3f *collision_point, v3f *collision_normal, v3f *raw_collision_normal);
|
v3f *collision_point, v3f *collision_normal, v3f *raw_collision_normal);
|
||||||
|
@ -1346,7 +1346,7 @@ int ModApiEnv::l_spawn_tree(lua_State *L)
|
|||||||
|
|
||||||
ServerMap *map = &env->getServerMap();
|
ServerMap *map = &env->getServerMap();
|
||||||
treegen::error e;
|
treegen::error e;
|
||||||
if ((e = treegen::spawn_ltree (map, p0, ndef, tree_def)) != treegen::SUCCESS) {
|
if ((e = treegen::spawn_ltree (map, p0, tree_def)) != treegen::SUCCESS) {
|
||||||
if (e == treegen::UNBALANCED_BRACKETS) {
|
if (e == treegen::UNBALANCED_BRACKETS) {
|
||||||
luaL_error(L, "spawn_tree(): closing ']' has no matching opening bracket");
|
luaL_error(L, "spawn_tree(): closing ']' has no matching opening bracket");
|
||||||
} else {
|
} else {
|
||||||
@ -1652,7 +1652,7 @@ int ModApiEnvVM::l_spawn_tree(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
treegen::error e;
|
treegen::error e;
|
||||||
if ((e = treegen::make_ltree(*vm, p0, ndef, tree_def)) != treegen::SUCCESS) {
|
if ((e = treegen::make_ltree(*vm, p0, tree_def)) != treegen::SUCCESS) {
|
||||||
if (e == treegen::UNBALANCED_BRACKETS) {
|
if (e == treegen::UNBALANCED_BRACKETS) {
|
||||||
throw LuaError("spawn_tree(): closing ']' has no matching opening bracket");
|
throw LuaError("spawn_tree(): closing ']' has no matching opening bracket");
|
||||||
} else {
|
} else {
|
||||||
|
@ -400,11 +400,8 @@ Server::~Server()
|
|||||||
|
|
||||||
// Delete the rest in the reverse order of creation
|
// Delete the rest in the reverse order of creation
|
||||||
delete m_game_settings;
|
delete m_game_settings;
|
||||||
delete m_emerge;
|
|
||||||
delete m_banmanager;
|
delete m_banmanager;
|
||||||
delete m_mod_storage_database;
|
delete m_mod_storage_database;
|
||||||
delete m_startup_server_map; // if available
|
|
||||||
delete m_script;
|
|
||||||
delete m_rollback;
|
delete m_rollback;
|
||||||
delete m_itemdef;
|
delete m_itemdef;
|
||||||
delete m_nodedef;
|
delete m_nodedef;
|
||||||
@ -438,7 +435,7 @@ void Server::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create emerge manager
|
// Create emerge manager
|
||||||
m_emerge = new EmergeManager(this, m_metrics_backend.get());
|
m_emerge = std::make_unique<EmergeManager>(this, m_metrics_backend.get());
|
||||||
|
|
||||||
// Create ban manager
|
// Create ban manager
|
||||||
std::string ban_path = m_path_world + DIR_DELIM "ipban.txt";
|
std::string ban_path = m_path_world + DIR_DELIM "ipban.txt";
|
||||||
@ -460,13 +457,13 @@ void Server::init()
|
|||||||
MutexAutoLock envlock(m_env_mutex);
|
MutexAutoLock envlock(m_env_mutex);
|
||||||
|
|
||||||
// Create the Map (loads map_meta.txt, overriding configured mapgen params)
|
// Create the Map (loads map_meta.txt, overriding configured mapgen params)
|
||||||
ServerMap *servermap = new ServerMap(m_path_world, this, m_emerge, m_metrics_backend.get());
|
auto startup_server_map = std::make_unique<ServerMap>(m_path_world, this,
|
||||||
m_startup_server_map = servermap;
|
m_emerge.get(), m_metrics_backend.get());
|
||||||
|
|
||||||
// Initialize scripting
|
// Initialize scripting
|
||||||
infostream << "Server: Initializing Lua" << std::endl;
|
infostream << "Server: Initializing Lua" << std::endl;
|
||||||
|
|
||||||
m_script = new ServerScripting(this);
|
m_script = std::make_unique<ServerScripting>(this);
|
||||||
|
|
||||||
// Must be created before mod loading because we have some inventory creation
|
// Must be created before mod loading because we have some inventory creation
|
||||||
m_inventory_mgr = std::make_unique<ServerInventoryManager>();
|
m_inventory_mgr = std::make_unique<ServerInventoryManager>();
|
||||||
@ -474,7 +471,7 @@ void Server::init()
|
|||||||
m_script->loadBuiltin();
|
m_script->loadBuiltin();
|
||||||
|
|
||||||
m_gamespec.checkAndLog();
|
m_gamespec.checkAndLog();
|
||||||
m_modmgr->loadMods(m_script);
|
m_modmgr->loadMods(*m_script);
|
||||||
|
|
||||||
m_script->saveGlobals();
|
m_script->saveGlobals();
|
||||||
|
|
||||||
@ -506,19 +503,18 @@ void Server::init()
|
|||||||
m_craftdef->initHashes(this);
|
m_craftdef->initHashes(this);
|
||||||
|
|
||||||
// Initialize Environment
|
// Initialize Environment
|
||||||
m_startup_server_map = nullptr; // Ownership moved to ServerEnvironment
|
m_env = new ServerEnvironment(std::move(startup_server_map),
|
||||||
m_env = new ServerEnvironment(servermap, m_script, this,
|
this, m_metrics_backend.get());
|
||||||
m_path_world, m_metrics_backend.get());
|
|
||||||
m_env->init();
|
m_env->init();
|
||||||
|
|
||||||
m_inventory_mgr->setEnv(m_env);
|
m_inventory_mgr->setEnv(m_env);
|
||||||
m_clients.setEnv(m_env);
|
m_clients.setEnv(m_env);
|
||||||
|
|
||||||
if (!servermap->settings_mgr.makeMapgenParams())
|
|
||||||
FATAL_ERROR("Couldn't create any mapgen type");
|
|
||||||
|
|
||||||
// Initialize mapgens
|
// Initialize mapgens
|
||||||
m_emerge->initMapgens(servermap->getMapgenParams());
|
auto &servermap = m_env->getServerMap();
|
||||||
|
if (!servermap.settings_mgr.makeMapgenParams())
|
||||||
|
FATAL_ERROR("Couldn't create any mapgen type");
|
||||||
|
m_emerge->initMapgens(servermap.getMapgenParams());
|
||||||
|
|
||||||
if (g_settings->getBool("enable_rollback_recording")) {
|
if (g_settings->getBool("enable_rollback_recording")) {
|
||||||
// Create rollback manager
|
// Create rollback manager
|
||||||
@ -532,7 +528,7 @@ void Server::init()
|
|||||||
m_script->initAsync();
|
m_script->initAsync();
|
||||||
|
|
||||||
// Register us to receive map edit events
|
// Register us to receive map edit events
|
||||||
servermap->addEventReceiver(this);
|
servermap.addEventReceiver(this);
|
||||||
|
|
||||||
m_env->loadMeta();
|
m_env->loadMeta();
|
||||||
|
|
||||||
@ -1502,8 +1498,7 @@ void Server::SendInventory(RemotePlayer *player, bool incremental)
|
|||||||
player->inventory.setModified(false);
|
player->inventory.setModified(false);
|
||||||
player->setModified(true);
|
player->setModified(true);
|
||||||
|
|
||||||
const std::string &s = os.str();
|
pkt.putRawString(os.str());
|
||||||
pkt.putRawString(s.c_str(), s.size());
|
|
||||||
Send(&pkt);
|
Send(&pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1638,32 +1633,30 @@ void Server::SendAddParticleSpawner(session_t peer_id, u16 protocol_version,
|
|||||||
|
|
||||||
pkt << p.amount << p.time;
|
pkt << p.amount << p.time;
|
||||||
|
|
||||||
|
std::ostringstream os(std::ios_base::binary);
|
||||||
if (protocol_version >= 42) {
|
if (protocol_version >= 42) {
|
||||||
// Serialize entire thing
|
// Serialize entire thing
|
||||||
std::ostringstream os(std::ios_base::binary);
|
|
||||||
p.pos.serialize(os);
|
p.pos.serialize(os);
|
||||||
p.vel.serialize(os);
|
p.vel.serialize(os);
|
||||||
p.acc.serialize(os);
|
p.acc.serialize(os);
|
||||||
p.exptime.serialize(os);
|
p.exptime.serialize(os);
|
||||||
p.size.serialize(os);
|
p.size.serialize(os);
|
||||||
pkt.putRawString(os.str());
|
|
||||||
} else {
|
} else {
|
||||||
// serialize legacy fields only (compatibility)
|
// serialize legacy fields only (compatibility)
|
||||||
std::ostringstream os(std::ios_base::binary);
|
|
||||||
p.pos.start.legacySerialize(os);
|
p.pos.start.legacySerialize(os);
|
||||||
p.vel.start.legacySerialize(os);
|
p.vel.start.legacySerialize(os);
|
||||||
p.acc.start.legacySerialize(os);
|
p.acc.start.legacySerialize(os);
|
||||||
p.exptime.start.legacySerialize(os);
|
p.exptime.start.legacySerialize(os);
|
||||||
p.size.start.legacySerialize(os);
|
p.size.start.legacySerialize(os);
|
||||||
pkt.putRawString(os.str());
|
|
||||||
}
|
}
|
||||||
|
pkt.putRawString(os.str());
|
||||||
pkt << p.collisiondetection;
|
pkt << p.collisiondetection;
|
||||||
|
|
||||||
pkt.putLongString(p.texture.string);
|
pkt.putLongString(p.texture.string);
|
||||||
|
|
||||||
pkt << id << p.vertical << p.collision_removal << attached_id;
|
pkt << id << p.vertical << p.collision_removal << attached_id;
|
||||||
{
|
{
|
||||||
std::ostringstream os(std::ios_base::binary);
|
os.str("");
|
||||||
p.animation.serialize(os, protocol_version);
|
p.animation.serialize(os, protocol_version);
|
||||||
pkt.putRawString(os.str());
|
pkt.putRawString(os.str());
|
||||||
}
|
}
|
||||||
@ -1671,7 +1664,7 @@ void Server::SendAddParticleSpawner(session_t peer_id, u16 protocol_version,
|
|||||||
pkt << p.node.param0 << p.node.param2 << p.node_tile;
|
pkt << p.node.param0 << p.node.param2 << p.node_tile;
|
||||||
|
|
||||||
{ // serialize new fields
|
{ // serialize new fields
|
||||||
std::ostringstream os(std::ios_base::binary);
|
os.str("");
|
||||||
if (protocol_version < 42) {
|
if (protocol_version < 42) {
|
||||||
// initial bias for older properties
|
// initial bias for older properties
|
||||||
pkt << p.pos.start.bias
|
pkt << p.pos.start.bias
|
||||||
@ -2121,7 +2114,7 @@ void Server::SendActiveObjectMessages(session_t peer_id, const std::string &data
|
|||||||
NetworkPacket pkt(TOCLIENT_ACTIVE_OBJECT_MESSAGES,
|
NetworkPacket pkt(TOCLIENT_ACTIVE_OBJECT_MESSAGES,
|
||||||
datas.size(), peer_id);
|
datas.size(), peer_id);
|
||||||
|
|
||||||
pkt.putRawString(datas.c_str(), datas.size());
|
pkt.putRawString(datas);
|
||||||
|
|
||||||
auto &ccf = clientCommandFactoryTable[pkt.getCommand()];
|
auto &ccf = clientCommandFactoryTable[pkt.getCommand()];
|
||||||
m_clients.sendCustom(pkt.getPeerId(), reliable ? ccf.channel : 1, &pkt, reliable);
|
m_clients.sendCustom(pkt.getPeerId(), reliable ? ccf.channel : 1, &pkt, reliable);
|
||||||
@ -2459,7 +2452,7 @@ void Server::SendBlocks(float dtime)
|
|||||||
|
|
||||||
total_sending += client->getSendingCount();
|
total_sending += client->getSendingCount();
|
||||||
const auto old_count = queue.size();
|
const auto old_count = queue.size();
|
||||||
client->GetNextBlocks(m_env,m_emerge, dtime, queue);
|
client->GetNextBlocks(m_env, m_emerge.get(), dtime, queue);
|
||||||
unique_clients += queue.size() > old_count ? 1 : 0;
|
unique_clients += queue.size() > old_count ? 1 : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2693,7 +2686,7 @@ void Server::sendRequestedMedia(session_t peer_id,
|
|||||||
|
|
||||||
// Note that applying a "real" bin packing algorithm here is not necessarily
|
// Note that applying a "real" bin packing algorithm here is not necessarily
|
||||||
// an improvement (might even perform worse) since games usually have lots
|
// an improvement (might even perform worse) since games usually have lots
|
||||||
// of files larger than 5KB and the current algorithm already minimized
|
// of files larger than 5KB and the current algorithm already minimizes
|
||||||
// the amount of bunches quite well (at the expense of overshooting).
|
// the amount of bunches quite well (at the expense of overshooting).
|
||||||
|
|
||||||
u32 file_size_bunch_total = 0;
|
u32 file_size_bunch_total = 0;
|
||||||
@ -3800,7 +3793,7 @@ bool Server::rollbackRevertActions(const std::list<RollbackAction> &actions,
|
|||||||
std::list<std::string> *log)
|
std::list<std::string> *log)
|
||||||
{
|
{
|
||||||
infostream<<"Server::rollbackRevertActions(len="<<actions.size()<<")"<<std::endl;
|
infostream<<"Server::rollbackRevertActions(len="<<actions.size()<<")"<<std::endl;
|
||||||
ServerMap *map = (ServerMap*)(&m_env->getMap());
|
auto *map = &m_env->getServerMap();
|
||||||
|
|
||||||
// Fail if no actions to handle
|
// Fail if no actions to handle
|
||||||
if (actions.empty()) {
|
if (actions.empty()) {
|
||||||
@ -3989,24 +3982,22 @@ void Server::requestShutdown(const std::string &msg, bool reconnect, float delay
|
|||||||
} else if (delay < 0.0f && m_shutdown_state.isTimerRunning()) {
|
} else if (delay < 0.0f && m_shutdown_state.isTimerRunning()) {
|
||||||
// Negative delay, cancel shutdown if requested
|
// Negative delay, cancel shutdown if requested
|
||||||
m_shutdown_state.reset();
|
m_shutdown_state.reset();
|
||||||
std::wstringstream ws;
|
|
||||||
|
|
||||||
ws << L"*** Server shutdown canceled.";
|
const char *s = "*** Server shutdown canceled.";
|
||||||
|
|
||||||
infostream << wide_to_utf8(ws.str()).c_str() << std::endl;
|
infostream << s << std::endl;
|
||||||
SendChatMessage(PEER_ID_INEXISTENT, ws.str());
|
SendChatMessage(PEER_ID_INEXISTENT, utf8_to_wide(s));
|
||||||
// m_shutdown_* are already handled, skip.
|
// m_shutdown_state already handled, skip.
|
||||||
return;
|
return;
|
||||||
} else if (delay > 0.0f) {
|
} else if (delay > 0.0f) {
|
||||||
// Positive delay, tell the clients when the server will shut down
|
// Positive delay, tell the clients when the server will shut down
|
||||||
std::wstringstream ws;
|
std::ostringstream oss;
|
||||||
|
|
||||||
ws << L"*** Server shutting down in "
|
oss << "*** Server shutting down in "
|
||||||
<< duration_to_string(myround(delay)).c_str()
|
<< duration_to_string(myround(delay)) << ".";
|
||||||
<< ".";
|
|
||||||
|
|
||||||
infostream << wide_to_utf8(ws.str()).c_str() << std::endl;
|
infostream << oss.str() << std::endl;
|
||||||
SendChatMessage(PEER_ID_INEXISTENT, ws.str());
|
SendChatMessage(PEER_ID_INEXISTENT, utf8_to_wide(oss.str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_shutdown_state.trigger(delay, msg, reconnect);
|
m_shutdown_state.trigger(delay, msg, reconnect);
|
||||||
|
30
src/server.h
30
src/server.h
@ -280,7 +280,7 @@ public:
|
|||||||
void sendDetachedInventory(Inventory *inventory, const std::string &name, session_t peer_id);
|
void sendDetachedInventory(Inventory *inventory, const std::string &name, session_t peer_id);
|
||||||
|
|
||||||
// Envlock and conlock should be locked when using scriptapi
|
// Envlock and conlock should be locked when using scriptapi
|
||||||
ServerScripting *getScriptIface(){ return m_script; }
|
inline ServerScripting *getScriptIface() { return m_script.get(); }
|
||||||
|
|
||||||
// actions: time-reversed list
|
// actions: time-reversed list
|
||||||
// Return value: success/failure
|
// Return value: success/failure
|
||||||
@ -294,7 +294,7 @@ public:
|
|||||||
virtual ICraftDefManager* getCraftDefManager();
|
virtual ICraftDefManager* getCraftDefManager();
|
||||||
virtual u16 allocateUnknownNodeId(const std::string &name);
|
virtual u16 allocateUnknownNodeId(const std::string &name);
|
||||||
IRollbackManager *getRollbackManager() { return m_rollback; }
|
IRollbackManager *getRollbackManager() { return m_rollback; }
|
||||||
virtual EmergeManager *getEmergeManager() { return m_emerge; }
|
virtual EmergeManager *getEmergeManager() { return m_emerge.get(); }
|
||||||
virtual ModStorageDatabase *getModStorageDatabase() { return m_mod_storage_database; }
|
virtual ModStorageDatabase *getModStorageDatabase() { return m_mod_storage_database; }
|
||||||
|
|
||||||
IWritableItemDefManager* getWritableItemDefManager();
|
IWritableItemDefManager* getWritableItemDefManager();
|
||||||
@ -432,6 +432,16 @@ public:
|
|||||||
// Environment mutex (envlock)
|
// Environment mutex (envlock)
|
||||||
std::mutex m_env_mutex;
|
std::mutex m_env_mutex;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/* Do not add more members here, this is only required to make unit tests work. */
|
||||||
|
|
||||||
|
// Scripting
|
||||||
|
// Envlock and conlock should be locked when using Lua
|
||||||
|
std::unique_ptr<ServerScripting> m_script;
|
||||||
|
|
||||||
|
// Mods
|
||||||
|
std::unique_ptr<ServerModManager> m_modmgr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class EmergeThread;
|
friend class EmergeThread;
|
||||||
friend class RemoteClient;
|
friend class RemoteClient;
|
||||||
@ -478,7 +488,6 @@ private:
|
|||||||
void SendBreath(session_t peer_id, u16 breath);
|
void SendBreath(session_t peer_id, u16 breath);
|
||||||
void SendAccessDenied(session_t peer_id, AccessDeniedCode reason,
|
void SendAccessDenied(session_t peer_id, AccessDeniedCode reason,
|
||||||
const std::string &custom_reason, bool reconnect = false);
|
const std::string &custom_reason, bool reconnect = false);
|
||||||
void SendAccessDenied_Legacy(session_t peer_id, const std::wstring &reason);
|
|
||||||
void SendDeathscreen(session_t peer_id, bool set_camera_point_target,
|
void SendDeathscreen(session_t peer_id, bool set_camera_point_target,
|
||||||
v3f camera_point_target);
|
v3f camera_point_target);
|
||||||
void SendItemDef(session_t peer_id, IItemDefManager *itemdef, u16 protocol_version);
|
void SendItemDef(session_t peer_id, IItemDefManager *itemdef, u16 protocol_version);
|
||||||
@ -608,6 +617,8 @@ private:
|
|||||||
u16 m_max_chatmessage_length;
|
u16 m_max_chatmessage_length;
|
||||||
// For "dedicated" server list flag
|
// For "dedicated" server list flag
|
||||||
bool m_dedicated;
|
bool m_dedicated;
|
||||||
|
|
||||||
|
// Game settings layer
|
||||||
Settings *m_game_settings = nullptr;
|
Settings *m_game_settings = nullptr;
|
||||||
|
|
||||||
// Thread can set; step() will throw as ServerError
|
// Thread can set; step() will throw as ServerError
|
||||||
@ -626,10 +637,6 @@ private:
|
|||||||
// Environment
|
// Environment
|
||||||
ServerEnvironment *m_env = nullptr;
|
ServerEnvironment *m_env = nullptr;
|
||||||
|
|
||||||
// Reference to the server map until ServerEnvironment is initialized
|
|
||||||
// after that this variable must be a nullptr
|
|
||||||
ServerMap *m_startup_server_map = nullptr;
|
|
||||||
|
|
||||||
// server connection
|
// server connection
|
||||||
std::shared_ptr<con::Connection> m_con;
|
std::shared_ptr<con::Connection> m_con;
|
||||||
|
|
||||||
@ -640,11 +647,7 @@ private:
|
|||||||
IRollbackManager *m_rollback = nullptr;
|
IRollbackManager *m_rollback = nullptr;
|
||||||
|
|
||||||
// Emerge manager
|
// Emerge manager
|
||||||
EmergeManager *m_emerge = nullptr;
|
std::unique_ptr<EmergeManager> m_emerge;
|
||||||
|
|
||||||
// Scripting
|
|
||||||
// Envlock and conlock should be locked when using Lua
|
|
||||||
ServerScripting *m_script = nullptr;
|
|
||||||
|
|
||||||
// Item definition manager
|
// Item definition manager
|
||||||
IWritableItemDefManager *m_itemdef;
|
IWritableItemDefManager *m_itemdef;
|
||||||
@ -655,9 +658,6 @@ private:
|
|||||||
// Craft definition manager
|
// Craft definition manager
|
||||||
IWritableCraftDefManager *m_craftdef;
|
IWritableCraftDefManager *m_craftdef;
|
||||||
|
|
||||||
// Mods
|
|
||||||
std::unique_ptr<ServerModManager> m_modmgr;
|
|
||||||
|
|
||||||
std::unordered_map<std::string, Translations> server_translations;
|
std::unordered_map<std::string, Translations> server_translations;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -50,7 +50,7 @@ ServerModManager::ServerModManager(const std::string &worldpath):
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This function cannot be currenctly easily tested but it should be ASAP
|
// This function cannot be currenctly easily tested but it should be ASAP
|
||||||
void ServerModManager::loadMods(ServerScripting *script)
|
void ServerModManager::loadMods(ServerScripting &script)
|
||||||
{
|
{
|
||||||
// Print mods
|
// Print mods
|
||||||
infostream << "Server: Loading mods: ";
|
infostream << "Server: Loading mods: ";
|
||||||
@ -65,13 +65,13 @@ void ServerModManager::loadMods(ServerScripting *script)
|
|||||||
|
|
||||||
std::string script_path = mod.path + DIR_DELIM + "init.lua";
|
std::string script_path = mod.path + DIR_DELIM + "init.lua";
|
||||||
auto t = porting::getTimeMs();
|
auto t = porting::getTimeMs();
|
||||||
script->loadMod(script_path, mod.name);
|
script.loadMod(script_path, mod.name);
|
||||||
infostream << "Mod \"" << mod.name << "\" loaded after "
|
infostream << "Mod \"" << mod.name << "\" loaded after "
|
||||||
<< (porting::getTimeMs() - t) << " ms" << std::endl;
|
<< (porting::getTimeMs() - t) << " ms" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run a callback when mods are loaded
|
// Run a callback when mods are loaded
|
||||||
script->on_mods_loaded();
|
script.on_mods_loaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
const ModSpec *ServerModManager::getModSpec(const std::string &modname) const
|
const ModSpec *ServerModManager::getModSpec(const std::string &modname) const
|
||||||
|
@ -22,12 +22,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "content/mod_configuration.h"
|
#include "content/mod_configuration.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class MetricsBackend;
|
|
||||||
class MetricCounter;
|
|
||||||
class ServerScripting;
|
class ServerScripting;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manage server mods
|
* Manages server mods
|
||||||
*
|
*
|
||||||
* All new calls to this class must be tested in test_servermodmanager.cpp
|
* All new calls to this class must be tested in test_servermodmanager.cpp
|
||||||
*/
|
*/
|
||||||
@ -36,12 +34,20 @@ class ServerModManager
|
|||||||
ModConfiguration configuration;
|
ModConfiguration configuration;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a ServerModManager which targets worldpath
|
* Creates a ServerModManager which targets worldpath
|
||||||
* @param worldpath
|
* @param worldpath
|
||||||
*/
|
*/
|
||||||
ServerModManager(const std::string &worldpath);
|
ServerModManager(const std::string &worldpath);
|
||||||
void loadMods(ServerScripting *script);
|
|
||||||
|
/**
|
||||||
|
* Creates an empty ServerModManager. For testing purposes.
|
||||||
|
* Note: definition looks like this so it isn't accidentally used.
|
||||||
|
*/
|
||||||
|
explicit ServerModManager(std::nullptr_t) {};
|
||||||
|
|
||||||
|
void loadMods(ServerScripting &script);
|
||||||
const ModSpec *getModSpec(const std::string &modname) const;
|
const ModSpec *getModSpec(const std::string &modname) const;
|
||||||
void getModNames(std::vector<std::string> &modlist) const;
|
void getModNames(std::vector<std::string> &modlist) const;
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "scripting_server.h"
|
#include "scripting_server.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "util/serialize.h"
|
#include "util/serialize.h"
|
||||||
|
#include "util/numeric.h"
|
||||||
#include "util/basic_macros.h"
|
#include "util/basic_macros.h"
|
||||||
#include "util/pointedthing.h"
|
#include "util/pointedthing.h"
|
||||||
#include "threading/mutex_auto_lock.h"
|
#include "threading/mutex_auto_lock.h"
|
||||||
@ -158,8 +159,7 @@ void LBMManager::loadIntroductionTimes(const std::string ×,
|
|||||||
// Storing it in a map first instead of
|
// Storing it in a map first instead of
|
||||||
// handling the stuff directly in the loop
|
// handling the stuff directly in the loop
|
||||||
// removes all duplicate entries.
|
// removes all duplicate entries.
|
||||||
// TODO make this std::unordered_map
|
std::unordered_map<std::string, u32> introduction_times;
|
||||||
std::map<std::string, u32> introduction_times;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The introduction times string consists of name~time entries,
|
The introduction times string consists of name~time entries,
|
||||||
@ -181,13 +181,11 @@ void LBMManager::loadIntroductionTimes(const std::string ×,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Put stuff from introduction_times into m_lbm_lookup
|
// Put stuff from introduction_times into m_lbm_lookup
|
||||||
for (std::map<std::string, u32>::const_iterator it = introduction_times.begin();
|
for (auto &it : introduction_times) {
|
||||||
it != introduction_times.end(); ++it) {
|
const std::string &name = it.first;
|
||||||
const std::string &name = it->first;
|
u32 time = it.second;
|
||||||
u32 time = it->second;
|
|
||||||
|
|
||||||
std::map<std::string, LoadingBlockModifierDef *>::iterator def_it =
|
auto def_it = m_lbm_defs.find(name);
|
||||||
m_lbm_defs.find(name);
|
|
||||||
if (def_it == m_lbm_defs.end()) {
|
if (def_it == m_lbm_defs.end()) {
|
||||||
// This seems to be an LBM entry for
|
// This seems to be an LBM entry for
|
||||||
// an LBM we haven't loaded. Discard it.
|
// an LBM we haven't loaded. Discard it.
|
||||||
@ -298,7 +296,7 @@ void LBMManager::applyLBMs(ServerEnvironment *env, MapBlock *block,
|
|||||||
ActiveBlockList
|
ActiveBlockList
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void fillRadiusBlock(v3s16 p0, s16 r, std::set<v3s16> &list)
|
static void fillRadiusBlock(v3s16 p0, s16 r, std::set<v3s16> &list)
|
||||||
{
|
{
|
||||||
v3s16 p;
|
v3s16 p;
|
||||||
for(p.X=p0.X-r; p.X<=p0.X+r; p.X++)
|
for(p.X=p0.X-r; p.X<=p0.X+r; p.X++)
|
||||||
@ -313,7 +311,7 @@ void fillRadiusBlock(v3s16 p0, s16 r, std::set<v3s16> &list)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fillViewConeBlock(v3s16 p0,
|
static void fillViewConeBlock(v3s16 p0,
|
||||||
const s16 r,
|
const s16 r,
|
||||||
const v3f camera_pos,
|
const v3f camera_pos,
|
||||||
const v3f camera_dir,
|
const v3f camera_dir,
|
||||||
@ -435,18 +433,12 @@ void OnMapblocksChangedReceiver::onMapEditEvent(const MapEditEvent &event)
|
|||||||
ServerEnvironment
|
ServerEnvironment
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Random device to seed pseudo random generators.
|
ServerEnvironment::ServerEnvironment(std::unique_ptr<ServerMap> map,
|
||||||
static std::random_device seed;
|
Server *server, MetricsBackend *mb):
|
||||||
|
|
||||||
ServerEnvironment::ServerEnvironment(ServerMap *map,
|
|
||||||
ServerScripting *script_iface, Server *server,
|
|
||||||
const std::string &path_world, MetricsBackend *mb):
|
|
||||||
Environment(server),
|
Environment(server),
|
||||||
m_map(map),
|
m_map(std::move(map)),
|
||||||
m_script(script_iface),
|
m_script(server->getScriptIface()),
|
||||||
m_server(server),
|
m_server(server)
|
||||||
m_path_world(path_world),
|
|
||||||
m_rgen(seed())
|
|
||||||
{
|
{
|
||||||
m_step_time_counter = mb->addCounter(
|
m_step_time_counter = mb->addCounter(
|
||||||
"minetest_env_step_time", "Time spent in environment step (in microseconds)");
|
"minetest_env_step_time", "Time spent in environment step (in microseconds)");
|
||||||
@ -461,7 +453,8 @@ ServerEnvironment::ServerEnvironment(ServerMap *map,
|
|||||||
void ServerEnvironment::init()
|
void ServerEnvironment::init()
|
||||||
{
|
{
|
||||||
// Determine which database backend to use
|
// Determine which database backend to use
|
||||||
std::string conf_path = m_path_world + DIR_DELIM + "world.mt";
|
const std::string world_path = m_server->getWorldPath();
|
||||||
|
const std::string conf_path = world_path + DIR_DELIM "world.mt";
|
||||||
Settings conf;
|
Settings conf;
|
||||||
|
|
||||||
std::string player_backend_name = "sqlite3";
|
std::string player_backend_name = "sqlite3";
|
||||||
@ -475,7 +468,7 @@ void ServerEnvironment::init()
|
|||||||
u16 blocksize = 16;
|
u16 blocksize = 16;
|
||||||
conf.getU16NoEx("blocksize", blocksize);
|
conf.getU16NoEx("blocksize", blocksize);
|
||||||
if (blocksize != MAP_BLOCKSIZE) {
|
if (blocksize != MAP_BLOCKSIZE) {
|
||||||
throw BaseException(std::string("The map's blocksize is not supported."));
|
throw BaseException("The map's blocksize is not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read those values before setting defaults
|
// Read those values before setting defaults
|
||||||
@ -524,8 +517,8 @@ void ServerEnvironment::init()
|
|||||||
<< "please read http://wiki.minetest.net/Database_backends." << std::endl;
|
<< "please read http://wiki.minetest.net/Database_backends." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_player_database = openPlayerDatabase(player_backend_name, m_path_world, conf);
|
m_player_database = openPlayerDatabase(player_backend_name, world_path, conf);
|
||||||
m_auth_database = openAuthDatabase(auth_backend_name, m_path_world, conf);
|
m_auth_database = openAuthDatabase(auth_backend_name, world_path, conf);
|
||||||
|
|
||||||
if (m_map && m_script->has_on_mapblocks_changed()) {
|
if (m_map && m_script->has_on_mapblocks_changed()) {
|
||||||
m_map->addEventReceiver(&m_on_mapblocks_changed_receiver);
|
m_map->addEventReceiver(&m_on_mapblocks_changed_receiver);
|
||||||
@ -547,8 +540,7 @@ ServerEnvironment::~ServerEnvironment()
|
|||||||
assert(m_active_blocks.size() == 0); // deactivateBlocksAndObjects does this
|
assert(m_active_blocks.size() == 0); // deactivateBlocksAndObjects does this
|
||||||
|
|
||||||
// Drop/delete map
|
// Drop/delete map
|
||||||
if (m_map)
|
m_map.reset();
|
||||||
m_map->drop();
|
|
||||||
|
|
||||||
// Delete ActiveBlockModifiers
|
// Delete ActiveBlockModifiers
|
||||||
for (ABMWithState &m_abm : m_abms) {
|
for (ABMWithState &m_abm : m_abms) {
|
||||||
@ -702,7 +694,7 @@ void ServerEnvironment::saveMeta()
|
|||||||
if (!m_meta_loaded)
|
if (!m_meta_loaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::string path = m_path_world + DIR_DELIM "env_meta.txt";
|
std::string path = m_server->getWorldPath() + DIR_DELIM "env_meta.txt";
|
||||||
|
|
||||||
// Open file and serialize
|
// Open file and serialize
|
||||||
std::ostringstream ss(std::ios_base::binary);
|
std::ostringstream ss(std::ios_base::binary);
|
||||||
@ -730,8 +722,10 @@ void ServerEnvironment::loadMeta()
|
|||||||
SANITY_CHECK(!m_meta_loaded);
|
SANITY_CHECK(!m_meta_loaded);
|
||||||
m_meta_loaded = true;
|
m_meta_loaded = true;
|
||||||
|
|
||||||
|
std::string path = m_server->getWorldPath() + DIR_DELIM "env_meta.txt";
|
||||||
|
|
||||||
// If file doesn't exist, load default environment metadata
|
// If file doesn't exist, load default environment metadata
|
||||||
if (!fs::PathExists(m_path_world + DIR_DELIM "env_meta.txt")) {
|
if (!fs::PathExists(path)) {
|
||||||
infostream << "ServerEnvironment: Loading default environment metadata"
|
infostream << "ServerEnvironment: Loading default environment metadata"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
loadDefaultMeta();
|
loadDefaultMeta();
|
||||||
@ -740,8 +734,6 @@ void ServerEnvironment::loadMeta()
|
|||||||
|
|
||||||
infostream << "ServerEnvironment: Loading environment metadata" << std::endl;
|
infostream << "ServerEnvironment: Loading environment metadata" << std::endl;
|
||||||
|
|
||||||
std::string path = m_path_world + DIR_DELIM "env_meta.txt";
|
|
||||||
|
|
||||||
// Open file and deserialize
|
// Open file and deserialize
|
||||||
std::ifstream is(path.c_str(), std::ios_base::binary);
|
std::ifstream is(path.c_str(), std::ios_base::binary);
|
||||||
if (!is.good()) {
|
if (!is.good()) {
|
||||||
@ -786,8 +778,7 @@ void ServerEnvironment::loadMeta()
|
|||||||
}
|
}
|
||||||
m_lbm_mgr.loadIntroductionTimes(lbm_introduction_times, m_server, m_game_time);
|
m_lbm_mgr.loadIntroductionTimes(lbm_introduction_times, m_server, m_game_time);
|
||||||
|
|
||||||
m_day_count = args.exists("day_count") ?
|
m_day_count = args.exists("day_count") ? args.getU32("day_count") : 0;
|
||||||
args.getU64("day_count") : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1518,7 +1509,7 @@ void ServerEnvironment::step(float dtime)
|
|||||||
TimeTaker timer("modify in active blocks per interval");
|
TimeTaker timer("modify in active blocks per interval");
|
||||||
|
|
||||||
// Shuffle to prevent persistent artifacts of ordering
|
// Shuffle to prevent persistent artifacts of ordering
|
||||||
std::shuffle(m_abms.begin(), m_abms.end(), m_rgen);
|
std::shuffle(m_abms.begin(), m_abms.end(), MyRandGenerator());
|
||||||
|
|
||||||
// Initialize handling of ActiveBlockModifiers
|
// Initialize handling of ActiveBlockModifiers
|
||||||
ABMHandler abmhandler(m_abms, m_cache_abm_interval, this, true);
|
ABMHandler abmhandler(m_abms, m_cache_abm_interval, this, true);
|
||||||
@ -1532,7 +1523,7 @@ void ServerEnvironment::step(float dtime)
|
|||||||
// Shuffle the active blocks so that each block gets an equal chance
|
// Shuffle the active blocks so that each block gets an equal chance
|
||||||
// of having its ABMs run.
|
// of having its ABMs run.
|
||||||
std::copy(m_active_blocks.m_abm_list.begin(), m_active_blocks.m_abm_list.end(), output.begin());
|
std::copy(m_active_blocks.m_abm_list.begin(), m_active_blocks.m_abm_list.end(), output.begin());
|
||||||
std::shuffle(output.begin(), output.end(), m_rgen);
|
std::shuffle(output.begin(), output.end(), MyRandGenerator());
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
// determine the time budget for ABMs
|
// determine the time budget for ABMs
|
||||||
|
@ -20,7 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <random>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "activeobject.h"
|
#include "activeobject.h"
|
||||||
@ -113,7 +112,7 @@ struct LBMContentMapping
|
|||||||
// many times during operation in the lbm_lookup_map.
|
// many times during operation in the lbm_lookup_map.
|
||||||
void deleteContents();
|
void deleteContents();
|
||||||
void addLBM(LoadingBlockModifierDef *lbm_def, IGameDef *gamedef);
|
void addLBM(LoadingBlockModifierDef *lbm_def, IGameDef *gamedef);
|
||||||
const std::vector<LoadingBlockModifierDef *> *lookup(content_t c) const;
|
const lbm_map::mapped_type *lookup(content_t c) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LBMManager
|
class LBMManager
|
||||||
@ -145,8 +144,7 @@ private:
|
|||||||
|
|
||||||
// For m_query_mode == false:
|
// For m_query_mode == false:
|
||||||
// The key of the map is the LBM def's name.
|
// The key of the map is the LBM def's name.
|
||||||
// TODO make this std::unordered_map
|
std::unordered_map<std::string, LoadingBlockModifierDef *> m_lbm_defs;
|
||||||
std::map<std::string, LoadingBlockModifierDef *> m_lbm_defs;
|
|
||||||
|
|
||||||
// For m_query_mode == true:
|
// For m_query_mode == true:
|
||||||
// The key of the map is the LBM def's first introduction time.
|
// The key of the map is the LBM def's first introduction time.
|
||||||
@ -221,8 +219,7 @@ enum ClearObjectsMode {
|
|||||||
class ServerEnvironment final : public Environment
|
class ServerEnvironment final : public Environment
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ServerEnvironment(ServerMap *map, ServerScripting *script_iface,
|
ServerEnvironment(std::unique_ptr<ServerMap> map, Server *server, MetricsBackend *mb);
|
||||||
Server *server, const std::string &path_world, MetricsBackend *mb);
|
|
||||||
~ServerEnvironment();
|
~ServerEnvironment();
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
@ -457,7 +454,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// The map
|
// The map
|
||||||
ServerMap *m_map;
|
std::unique_ptr<ServerMap> m_map;
|
||||||
// Lua state
|
// Lua state
|
||||||
ServerScripting* m_script;
|
ServerScripting* m_script;
|
||||||
// Server definition
|
// Server definition
|
||||||
@ -466,8 +463,6 @@ private:
|
|||||||
server::ActiveObjectMgr m_ao_manager;
|
server::ActiveObjectMgr m_ao_manager;
|
||||||
// on_mapblocks_changed map event receiver
|
// on_mapblocks_changed map event receiver
|
||||||
OnMapblocksChangedReceiver m_on_mapblocks_changed_receiver;
|
OnMapblocksChangedReceiver m_on_mapblocks_changed_receiver;
|
||||||
// World path
|
|
||||||
const std::string m_path_world;
|
|
||||||
// Outgoing network message buffer for active objects
|
// Outgoing network message buffer for active objects
|
||||||
std::queue<ActiveObjectMessage> m_active_object_messages;
|
std::queue<ActiveObjectMessage> m_active_object_messages;
|
||||||
// Some timers
|
// Some timers
|
||||||
@ -504,9 +499,6 @@ private:
|
|||||||
PlayerDatabase *m_player_database = nullptr;
|
PlayerDatabase *m_player_database = nullptr;
|
||||||
AuthDatabase *m_auth_database = nullptr;
|
AuthDatabase *m_auth_database = nullptr;
|
||||||
|
|
||||||
// Pseudo random generator for shuffling, etc.
|
|
||||||
std::mt19937 m_rgen;
|
|
||||||
|
|
||||||
// Particles
|
// Particles
|
||||||
IntervalLimiter m_particle_management_interval;
|
IntervalLimiter m_particle_management_interval;
|
||||||
std::unordered_map<u32, float> m_particle_spawners;
|
std::unordered_map<u32, float> m_particle_spawners;
|
||||||
|
@ -402,11 +402,11 @@ DigParams getDigParams(const ItemGroupList &groups,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
const std::string &groupname = groupcap.first;
|
const std::string &groupname = groupcap.first;
|
||||||
float time = 0;
|
|
||||||
int rating = itemgroup_get(groups, groupname);
|
int rating = itemgroup_get(groups, groupname);
|
||||||
bool time_exists = cap.getTime(rating, &time);
|
const auto time_o = cap.getTime(rating);
|
||||||
if (!time_exists)
|
if (!time_o.has_value())
|
||||||
continue;
|
continue;
|
||||||
|
float time = *time_o;
|
||||||
|
|
||||||
if (leveldiff > 1)
|
if (leveldiff > 1)
|
||||||
time /= leveldiff;
|
time /= leveldiff;
|
||||||
|
23
src/tool.h
23
src/tool.h
@ -23,11 +23,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "itemgroup.h"
|
#include "itemgroup.h"
|
||||||
#include "json-forwards.h"
|
#include "json-forwards.h"
|
||||||
#include "common/c_types.h"
|
#include "common/c_types.h"
|
||||||
#include <json/json.h>
|
|
||||||
#include <SColor.h>
|
#include <SColor.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
struct ItemDefinition;
|
struct ItemDefinition;
|
||||||
@ -41,15 +42,11 @@ struct ToolGroupCap
|
|||||||
|
|
||||||
ToolGroupCap() = default;
|
ToolGroupCap() = default;
|
||||||
|
|
||||||
bool getTime(int rating, float *time) const
|
std::optional<float> getTime(int rating) const {
|
||||||
{
|
auto i = times.find(rating);
|
||||||
std::unordered_map<int, float>::const_iterator i = times.find(rating);
|
if (i == times.end())
|
||||||
if (i == times.end()) {
|
return std::nullopt;
|
||||||
*time = 0;
|
return i->second;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*time = i->second;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void toJson(Json::Value &object) const;
|
void toJson(Json::Value &object) const;
|
||||||
@ -91,7 +88,7 @@ struct ToolCapabilities
|
|||||||
struct WearBarParams
|
struct WearBarParams
|
||||||
{
|
{
|
||||||
std::map<f32, video::SColor> colorStops;
|
std::map<f32, video::SColor> colorStops;
|
||||||
enum BlendMode: u8 {
|
enum BlendMode : u8 {
|
||||||
BLEND_MODE_CONSTANT,
|
BLEND_MODE_CONSTANT,
|
||||||
BLEND_MODE_LINEAR,
|
BLEND_MODE_LINEAR,
|
||||||
BlendMode_END // Dummy for validity check
|
BlendMode_END // Dummy for validity check
|
||||||
@ -99,7 +96,7 @@ struct WearBarParams
|
|||||||
constexpr const static EnumString es_BlendMode[3] = {
|
constexpr const static EnumString es_BlendMode[3] = {
|
||||||
{WearBarParams::BLEND_MODE_CONSTANT, "constant"},
|
{WearBarParams::BLEND_MODE_CONSTANT, "constant"},
|
||||||
{WearBarParams::BLEND_MODE_LINEAR, "linear"},
|
{WearBarParams::BLEND_MODE_LINEAR, "linear"},
|
||||||
{0, NULL}
|
{0, nullptr}
|
||||||
};
|
};
|
||||||
BlendMode blend;
|
BlendMode blend;
|
||||||
|
|
||||||
@ -109,7 +106,7 @@ struct WearBarParams
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
WearBarParams(const video::SColor color):
|
WearBarParams(const video::SColor color):
|
||||||
WearBarParams({{0.0, color}}, WearBarParams::BLEND_MODE_CONSTANT)
|
WearBarParams({{0.0f, color}}, WearBarParams::BLEND_MODE_CONSTANT)
|
||||||
{};
|
{};
|
||||||
|
|
||||||
void serialize(std::ostream &os) const;
|
void serialize(std::ostream &os) const;
|
||||||
|
@ -20,17 +20,29 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
#include "server/mods.h"
|
||||||
|
#include "scripting_server.h"
|
||||||
|
|
||||||
class MockServer : public Server
|
class MockServer : public Server
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/* Set path_world to a real existing folder if you plan to initialize scripting! */
|
/* Set `path_world` to a real existing folder if you plan to initialize scripting! */
|
||||||
MockServer(const std::string &path_world = "fakepath") :
|
MockServer(const std::string &path_world = "fakepath") :
|
||||||
Server(path_world, SubgameSpec("fakespec", "fakespec"), true,
|
Server(path_world, SubgameSpec("fakespec", "fakespec"), true,
|
||||||
Address(), true, nullptr
|
Address(), true, nullptr
|
||||||
)
|
)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use this in unit tests to create scripting.
|
||||||
|
* Note that you still need to call script->loadBuiltin() and don't forget
|
||||||
|
* a try-catch for `ModError`.
|
||||||
|
*/
|
||||||
|
void createScripting() {
|
||||||
|
m_script = std::make_unique<ServerScripting>(this);
|
||||||
|
m_modmgr = std::make_unique<ServerModManager>(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
void start() = delete;
|
void start() = delete;
|
||||||
void stop() = delete;
|
void stop() = delete;
|
||||||
|
|
||||||
|
@ -22,8 +22,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "mock_inventorymanager.h"
|
#include "mock_inventorymanager.h"
|
||||||
#include "mock_server.h"
|
#include "mock_server.h"
|
||||||
#include "mock_serveractiveobject.h"
|
#include "mock_serveractiveobject.h"
|
||||||
#include "scripting_server.h"
|
|
||||||
#include "server/mods.h"
|
|
||||||
|
|
||||||
class TestMoveAction : public TestBase
|
class TestMoveAction : public TestBase
|
||||||
{
|
{
|
||||||
@ -53,27 +51,21 @@ void TestMoveAction::runTests(IGameDef *gamedef)
|
|||||||
{
|
{
|
||||||
MockServer server(getTestTempDirectory());
|
MockServer server(getTestTempDirectory());
|
||||||
|
|
||||||
ServerScripting server_scripting(&server);
|
server.createScripting();
|
||||||
try {
|
try {
|
||||||
// FIXME: When removing the line below, the unittest does NOT crash
|
|
||||||
// (but it should) when running all unittests in order or registration.
|
|
||||||
// Some Lua API functions used in builtin require the Mgr to be present.
|
|
||||||
server.m_modmgr = std::make_unique<ServerModManager>(server.m_path_world);
|
|
||||||
|
|
||||||
std::string builtin = Server::getBuiltinLuaPath() + DIR_DELIM;
|
std::string builtin = Server::getBuiltinLuaPath() + DIR_DELIM;
|
||||||
server_scripting.loadBuiltin();
|
auto script = server.getScriptIface();
|
||||||
server_scripting.loadMod(builtin + "game" DIR_DELIM "tests" DIR_DELIM "test_moveaction.lua", BUILTIN_MOD_NAME);
|
script->loadBuiltin();
|
||||||
|
script->loadMod(builtin + "game" DIR_DELIM "tests" DIR_DELIM "test_moveaction.lua", BUILTIN_MOD_NAME);
|
||||||
} catch (ModError &e) {
|
} catch (ModError &e) {
|
||||||
// Print backtrace in case of syntax errors
|
|
||||||
rawstream << e.what() << std::endl;
|
rawstream << e.what() << std::endl;
|
||||||
num_tests_failed = 1;
|
num_tests_failed = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
server.m_script = &server_scripting;
|
|
||||||
|
|
||||||
MetricsBackend mb;
|
MetricsBackend mb;
|
||||||
ServerEnvironment server_env(nullptr, &server_scripting, &server, "", &mb);
|
auto null_map = std::unique_ptr<ServerMap>();
|
||||||
|
ServerEnvironment server_env(std::move(null_map), &server, &mb);
|
||||||
MockServerActiveObject obj(&server_env);
|
MockServerActiveObject obj(&server_env);
|
||||||
|
|
||||||
TEST(testMove, &obj, gamedef);
|
TEST(testMove, &obj, gamedef);
|
||||||
@ -88,8 +80,6 @@ void TestMoveAction::runTests(IGameDef *gamedef)
|
|||||||
|
|
||||||
TEST(testCallbacks, &obj, &server);
|
TEST(testCallbacks, &obj, &server);
|
||||||
TEST(testCallbacksSwap, &obj, &server);
|
TEST(testCallbacksSwap, &obj, &server);
|
||||||
|
|
||||||
server.m_script = nullptr; // Do not free stack memory
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ItemStack parse_itemstack(const char *s)
|
static ItemStack parse_itemstack(const char *s)
|
||||||
|
@ -20,7 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
#include "mock_server.h"
|
#include "mock_server.h"
|
||||||
#include "scripting_server.h"
|
|
||||||
#include "server/luaentity_sao.h"
|
#include "server/luaentity_sao.h"
|
||||||
#include "emerge.h"
|
#include "emerge.h"
|
||||||
|
|
||||||
@ -73,10 +72,11 @@ void TestSAO::runTests(IGameDef *gamedef)
|
|||||||
ofs2 << "backend = dummy\n";
|
ofs2 << "backend = dummy\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerScripting server_scripting(&server);
|
server.createScripting();
|
||||||
try {
|
try {
|
||||||
server_scripting.loadBuiltin();
|
auto script = server.getScriptIface();
|
||||||
server_scripting.loadMod(helper_lua, BUILTIN_MOD_NAME);
|
script->loadBuiltin();
|
||||||
|
script->loadMod(helper_lua, BUILTIN_MOD_NAME);
|
||||||
} catch (ModError &e) {
|
} catch (ModError &e) {
|
||||||
rawstream << e.what() << std::endl;
|
rawstream << e.what() << std::endl;
|
||||||
num_tests_failed = 1;
|
num_tests_failed = 1;
|
||||||
@ -88,8 +88,8 @@ void TestSAO::runTests(IGameDef *gamedef)
|
|||||||
// EmergeManager should become mockable
|
// EmergeManager should become mockable
|
||||||
MetricsBackend mb;
|
MetricsBackend mb;
|
||||||
EmergeManager emerge(&server, &mb);
|
EmergeManager emerge(&server, &mb);
|
||||||
auto *map = new ServerMap(server.getWorldPath(), gamedef, &emerge, &mb);
|
auto map = std::make_unique<ServerMap>(server.getWorldPath(), gamedef, &emerge, &mb);
|
||||||
ServerEnvironment env(map, &server_scripting, &server, "", &mb);
|
ServerEnvironment env(std::move(map), &server, &mb);
|
||||||
env.loadMeta();
|
env.loadMeta();
|
||||||
|
|
||||||
m_step_interval = std::max(
|
m_step_interval = std::max(
|
||||||
|
@ -29,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
// myrand
|
// myrand
|
||||||
|
|
||||||
PcgRandom g_pcgrand;
|
static PcgRandom g_pcgrand;
|
||||||
|
|
||||||
u32 myrand()
|
u32 myrand()
|
||||||
{
|
{
|
||||||
@ -187,7 +187,7 @@ s16 adjustDist(s16 dist, float zoom_fov)
|
|||||||
return std::round(adjustDist((float)dist, zoom_fov));
|
return std::round(adjustDist((float)dist, zoom_fov));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPitchYawRollRad(core::matrix4 &m, const v3f &rot)
|
void setPitchYawRollRad(core::matrix4 &m, v3f rot)
|
||||||
{
|
{
|
||||||
f64 a1 = rot.Z, a2 = rot.X, a3 = rot.Y;
|
f64 a1 = rot.Z, a2 = rot.X, a3 = rot.Y;
|
||||||
f64 c1 = cos(a1), s1 = sin(a1);
|
f64 c1 = cos(a1), s1 = sin(a1);
|
||||||
|
@ -250,6 +250,16 @@ int myrand_range(int min, int max);
|
|||||||
float myrand_range(float min, float max);
|
float myrand_range(float min, float max);
|
||||||
float myrand_float();
|
float myrand_float();
|
||||||
|
|
||||||
|
// Implements a C++11 UniformRandomBitGenerator using the above functions
|
||||||
|
struct MyRandGenerator {
|
||||||
|
typedef u32 result_type;
|
||||||
|
static constexpr result_type min() { return 0; }
|
||||||
|
static constexpr result_type max() { return MYRAND_RANGE; }
|
||||||
|
inline result_type operator()() {
|
||||||
|
return myrand();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Miscellaneous functions
|
Miscellaneous functions
|
||||||
*/
|
*/
|
||||||
@ -448,18 +458,18 @@ inline void wrappedApproachShortest(T ¤t, const T target, const T stepsize
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPitchYawRollRad(core::matrix4 &m, const v3f &rot);
|
void setPitchYawRollRad(core::matrix4 &m, v3f rot);
|
||||||
|
|
||||||
inline void setPitchYawRoll(core::matrix4 &m, const v3f &rot)
|
inline void setPitchYawRoll(core::matrix4 &m, v3f rot)
|
||||||
{
|
{
|
||||||
setPitchYawRollRad(m, rot * core::DEGTORAD64);
|
setPitchYawRollRad(m, rot * core::DEGTORAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
v3f getPitchYawRollRad(const core::matrix4 &m);
|
v3f getPitchYawRollRad(const core::matrix4 &m);
|
||||||
|
|
||||||
inline v3f getPitchYawRoll(const core::matrix4 &m)
|
inline v3f getPitchYawRoll(const core::matrix4 &m)
|
||||||
{
|
{
|
||||||
return getPitchYawRollRad(m) * core::RADTODEG64;
|
return getPitchYawRollRad(m) * core::RADTODEG;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Muliply the RGB value of a color linearly, and clamp to black/white
|
// Muliply the RGB value of a color linearly, and clamp to black/white
|
||||||
|
@ -574,7 +574,7 @@ bool parseColorString(const std::string &value, video::SColor &color, bool quiet
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string encodeHexColorString(const video::SColor &color)
|
std::string encodeHexColorString(video::SColor color)
|
||||||
{
|
{
|
||||||
std::string color_string = "#";
|
std::string color_string = "#";
|
||||||
const char red = color.getRed();
|
const char red = color.getRed();
|
||||||
|
@ -97,7 +97,7 @@ char *mystrtok_r(char *s, const char *sep, char **lasts) noexcept;
|
|||||||
u64 read_seed(const char *str);
|
u64 read_seed(const char *str);
|
||||||
bool parseColorString(const std::string &value, video::SColor &color, bool quiet,
|
bool parseColorString(const std::string &value, video::SColor &color, bool quiet,
|
||||||
unsigned char default_alpha = 0xff);
|
unsigned char default_alpha = 0xff);
|
||||||
std::string encodeHexColorString(const video::SColor &color);
|
std::string encodeHexColorString(video::SColor color);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user