mirror of https://github.com/minetest/minetest.git
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
c911ab2c17
|
@ -12,7 +12,7 @@ set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string")
|
||||||
# Also remember to set PROTOCOL_VERSION in clientserver.h when releasing
|
# Also remember to set PROTOCOL_VERSION in clientserver.h when releasing
|
||||||
set(VERSION_MAJOR 0)
|
set(VERSION_MAJOR 0)
|
||||||
set(VERSION_MINOR 4)
|
set(VERSION_MINOR 4)
|
||||||
set(VERSION_PATCH 3)
|
set(VERSION_PATCH 4-dev)
|
||||||
if(VERSION_EXTRA)
|
if(VERSION_EXTRA)
|
||||||
set(VERSION_PATCH ${VERSION_PATCH}-${VERSION_EXTRA})
|
set(VERSION_PATCH ${VERSION_PATCH}-${VERSION_EXTRA})
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -138,6 +138,7 @@ minetest.register_chatcommand("grant", {
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
minetest.set_player_privs(grantname, privs)
|
minetest.set_player_privs(grantname, privs)
|
||||||
|
minetest.log(name..' granted ('..minetest.privs_to_string(grantprivs, ', ')..') privileges to '..grantname)
|
||||||
minetest.chat_send_player(name, "Privileges of "..grantname..": "..minetest.privs_to_string(minetest.get_player_privs(grantname), ' '))
|
minetest.chat_send_player(name, "Privileges of "..grantname..": "..minetest.privs_to_string(minetest.get_player_privs(grantname), ' '))
|
||||||
if grantname ~= name then
|
if grantname ~= name then
|
||||||
minetest.chat_send_player(grantname, name.." granted you privileges: "..minetest.privs_to_string(grantprivs, ' '))
|
minetest.chat_send_player(grantname, name.." granted you privileges: "..minetest.privs_to_string(grantprivs, ' '))
|
||||||
|
@ -175,6 +176,7 @@ minetest.register_chatcommand("revoke", {
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
minetest.set_player_privs(revokename, privs)
|
minetest.set_player_privs(revokename, privs)
|
||||||
|
minetest.log(name..' revoked ('..minetest.privs_to_string(revokeprivs, ', ')..') privileges from '..revokename)
|
||||||
minetest.chat_send_player(name, "Privileges of "..revokename..": "..minetest.privs_to_string(minetest.get_player_privs(revokename), ' '))
|
minetest.chat_send_player(name, "Privileges of "..revokename..": "..minetest.privs_to_string(minetest.get_player_privs(revokename), ' '))
|
||||||
if revokename ~= name then
|
if revokename ~= name then
|
||||||
minetest.chat_send_player(revokename, name.." revoked privileges from you: "..minetest.privs_to_string(revokeprivs, ' '))
|
minetest.chat_send_player(revokename, name.." revoked privileges from you: "..minetest.privs_to_string(revokeprivs, ' '))
|
||||||
|
|
|
@ -303,6 +303,7 @@ end
|
||||||
|
|
||||||
minetest.registered_on_chat_messages, minetest.register_on_chat_message = make_registration()
|
minetest.registered_on_chat_messages, minetest.register_on_chat_message = make_registration()
|
||||||
minetest.registered_globalsteps, minetest.register_globalstep = make_registration()
|
minetest.registered_globalsteps, minetest.register_globalstep = make_registration()
|
||||||
|
minetest.registered_on_shutdown, minetest.register_on_shutdown = make_registration()
|
||||||
minetest.registered_on_punchnodes, minetest.register_on_punchnode = make_registration()
|
minetest.registered_on_punchnodes, minetest.register_on_punchnode = make_registration()
|
||||||
minetest.registered_on_placenodes, minetest.register_on_placenode = make_registration()
|
minetest.registered_on_placenodes, minetest.register_on_placenode = make_registration()
|
||||||
minetest.registered_on_dignodes, minetest.register_on_dignode = make_registration()
|
minetest.registered_on_dignodes, minetest.register_on_dignode = make_registration()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Minetest Lua Modding API Reference 0.4.3
|
Minetest Lua Modding API Reference 0.4.4
|
||||||
==========================================
|
==========================================
|
||||||
More information at http://c55.me/minetest/
|
More information at http://c55.me/minetest/
|
||||||
|
|
||||||
|
@ -792,6 +792,11 @@ minetest.register_craft(recipe)
|
||||||
Global callback registration functions: (Call these only at load time)
|
Global callback registration functions: (Call these only at load time)
|
||||||
minetest.register_globalstep(func(dtime))
|
minetest.register_globalstep(func(dtime))
|
||||||
^ Called every server step, usually interval of 0.05s
|
^ Called every server step, usually interval of 0.05s
|
||||||
|
minetest.register_on_shutdown(func())
|
||||||
|
^ Called before server shutdown
|
||||||
|
^ WARNING: If the server terminates abnormally (i.e. crashes), the registered
|
||||||
|
callbacks WILL LIKELY NOT BE RUN. Data should be saved at
|
||||||
|
semi-frequent intervals as well as on server shutdown.
|
||||||
minetest.register_on_placenode(func(pos, newnode, placer, oldnode))
|
minetest.register_on_placenode(func(pos, newnode, placer, oldnode))
|
||||||
^ Called when a node has been placed
|
^ Called when a node has been placed
|
||||||
^ Deprecated: Use on_construct or after_place_node in node definition instead
|
^ Deprecated: Use on_construct or after_place_node in node definition instead
|
||||||
|
|
|
@ -139,8 +139,8 @@
|
||||||
#motd = Welcome to this awesome Minetest server!
|
#motd = Welcome to this awesome Minetest server!
|
||||||
# Maximum number of players connected simultaneously
|
# Maximum number of players connected simultaneously
|
||||||
#max_users = 100
|
#max_users = 100
|
||||||
# Set to false to allow old clients to connect
|
# Set to true to disallow old clients from connecting
|
||||||
#strict_protocol_version_checking = true
|
#strict_protocol_version_checking = false
|
||||||
# Set to true to enable creative mode (unlimited inventory)
|
# Set to true to enable creative mode (unlimited inventory)
|
||||||
#creative_mode = false
|
#creative_mode = false
|
||||||
# Enable players getting damage and dying
|
# Enable players getting damage and dying
|
||||||
|
@ -194,7 +194,12 @@
|
||||||
# To reduce lag, block transfers are slowed down when a player is building something.
|
# To reduce lag, block transfers are slowed down when a player is building something.
|
||||||
# This determines how long they are slowed down after placing or removing a node.
|
# This determines how long they are slowed down after placing or removing a node.
|
||||||
#full_block_send_enable_min_time_from_building = 2.0
|
#full_block_send_enable_min_time_from_building = 2.0
|
||||||
# Length of a server tick in dedicated server
|
# Length of a server tick and the interval at which objects are generally updated over network
|
||||||
#dedicated_server_step = 0.05
|
#dedicated_server_step = 0.1
|
||||||
# Can be set to true to disable shutting down on invalid world data
|
# Can be set to true to disable shutting down on invalid world data
|
||||||
#ignore_world_load_errors = false
|
#ignore_world_load_errors = false
|
||||||
|
# Congestion control parameters
|
||||||
|
# time in seconds, rate in ~500B packets
|
||||||
|
#congestion_control_aim_rtt = 0.2
|
||||||
|
#congestion_control_max_rate = 400
|
||||||
|
#congestion_control_min_rate = 10
|
||||||
|
|
|
@ -202,6 +202,8 @@ set(common_SRCS
|
||||||
sha1.cpp
|
sha1.cpp
|
||||||
base64.cpp
|
base64.cpp
|
||||||
ban.cpp
|
ban.cpp
|
||||||
|
clientserver.cpp
|
||||||
|
staticobject.cpp
|
||||||
util/serialize.cpp
|
util/serialize.cpp
|
||||||
util/directiontables.cpp
|
util/directiontables.cpp
|
||||||
util/numeric.cpp
|
util/numeric.cpp
|
||||||
|
|
|
@ -42,6 +42,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
#include "hex.h"
|
#include "hex.h"
|
||||||
#include "IMeshCache.h"
|
#include "IMeshCache.h"
|
||||||
|
#include "util/serialize.h"
|
||||||
|
|
||||||
static std::string getMediaCacheDir()
|
static std::string getMediaCacheDir()
|
||||||
{
|
{
|
||||||
|
@ -266,6 +267,7 @@ Client::Client(
|
||||||
m_time_of_day_set(false),
|
m_time_of_day_set(false),
|
||||||
m_last_time_of_day_f(-1),
|
m_last_time_of_day_f(-1),
|
||||||
m_time_of_day_update_timer(0),
|
m_time_of_day_update_timer(0),
|
||||||
|
m_recommended_send_interval(0.1),
|
||||||
m_removed_sounds_check_timer(0)
|
m_removed_sounds_check_timer(0)
|
||||||
{
|
{
|
||||||
m_packetcounter_timer = 0.0;
|
m_packetcounter_timer = 0.0;
|
||||||
|
@ -499,8 +501,9 @@ void Client::step(float dtime)
|
||||||
// [2] u8 SER_FMT_VER_HIGHEST
|
// [2] u8 SER_FMT_VER_HIGHEST
|
||||||
// [3] u8[20] player_name
|
// [3] u8[20] player_name
|
||||||
// [23] u8[28] password (new in some version)
|
// [23] u8[28] password (new in some version)
|
||||||
// [51] u16 client network protocol version (new in some version)
|
// [51] u16 minimum supported network protocol version (added sometime)
|
||||||
SharedBuffer<u8> data(2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2);
|
// [53] u16 maximum supported network protocol version (added later than the previous one)
|
||||||
|
SharedBuffer<u8> data(2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2+2);
|
||||||
writeU16(&data[0], TOSERVER_INIT);
|
writeU16(&data[0], TOSERVER_INIT);
|
||||||
writeU8(&data[2], SER_FMT_VER_HIGHEST);
|
writeU8(&data[2], SER_FMT_VER_HIGHEST);
|
||||||
|
|
||||||
|
@ -513,8 +516,8 @@ void Client::step(float dtime)
|
||||||
memset((char*)&data[23], 0, PASSWORD_SIZE);
|
memset((char*)&data[23], 0, PASSWORD_SIZE);
|
||||||
snprintf((char*)&data[23], PASSWORD_SIZE, "%s", m_password.c_str());
|
snprintf((char*)&data[23], PASSWORD_SIZE, "%s", m_password.c_str());
|
||||||
|
|
||||||
// This should be incremented in each version
|
writeU16(&data[51], CLIENT_PROTOCOL_VERSION_MIN);
|
||||||
writeU16(&data[51], PROTOCOL_VERSION);
|
writeU16(&data[53], CLIENT_PROTOCOL_VERSION_MAX);
|
||||||
|
|
||||||
// Send as unreliable
|
// Send as unreliable
|
||||||
Send(0, data, false);
|
Send(0, data, false);
|
||||||
|
@ -656,7 +659,7 @@ void Client::step(float dtime)
|
||||||
{
|
{
|
||||||
float &counter = m_playerpos_send_timer;
|
float &counter = m_playerpos_send_timer;
|
||||||
counter += dtime;
|
counter += dtime;
|
||||||
if(counter >= 0.2)
|
if(counter >= m_recommended_send_interval)
|
||||||
{
|
{
|
||||||
counter = 0.0;
|
counter = 0.0;
|
||||||
sendPlayerPos();
|
sendPlayerPos();
|
||||||
|
@ -1020,6 +1023,14 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||||
m_map_seed = readU64(&data[2+1+6]);
|
m_map_seed = readU64(&data[2+1+6]);
|
||||||
infostream<<"Client: received map seed: "<<m_map_seed<<std::endl;
|
infostream<<"Client: received map seed: "<<m_map_seed<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(datasize >= 2+1+6+8+4)
|
||||||
|
{
|
||||||
|
// Get map seed
|
||||||
|
m_recommended_send_interval = readF1000(&data[2+1+6+8]);
|
||||||
|
infostream<<"Client: received recommended send interval "
|
||||||
|
<<m_recommended_send_interval<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
// Reply to server
|
// Reply to server
|
||||||
u32 replysize = 2;
|
u32 replysize = 2;
|
||||||
|
|
|
@ -382,6 +382,9 @@ private:
|
||||||
float m_last_time_of_day_f;
|
float m_last_time_of_day_f;
|
||||||
float m_time_of_day_update_timer;
|
float m_time_of_day_update_timer;
|
||||||
|
|
||||||
|
// An interval for generally sending object positions and stuff
|
||||||
|
float m_recommended_send_interval;
|
||||||
|
|
||||||
// Sounds
|
// Sounds
|
||||||
float m_removed_sounds_check_timer;
|
float m_removed_sounds_check_timer;
|
||||||
// Mapping from server sound ids to our sound ids
|
// Mapping from server sound ids to our sound ids
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
Minetest-c55
|
||||||
|
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "clientserver.h"
|
||||||
|
#include "util/serialize.h"
|
||||||
|
|
||||||
|
SharedBuffer<u8> makePacket_TOCLIENT_TIME_OF_DAY(u16 time, float time_speed)
|
||||||
|
{
|
||||||
|
SharedBuffer<u8> data(2+2+4);
|
||||||
|
writeU16(&data[0], TOCLIENT_TIME_OF_DAY);
|
||||||
|
writeU16(&data[2], time);
|
||||||
|
writeF1000(&data[4], time_speed);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Minetest-c55
|
Minetest-c55
|
||||||
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
|
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Lesser General Public License as published by
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
@ -20,7 +20,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#ifndef CLIENTSERVER_HEADER
|
#ifndef CLIENTSERVER_HEADER
|
||||||
#define CLIENTSERVER_HEADER
|
#define CLIENTSERVER_HEADER
|
||||||
|
|
||||||
#include "util/serialize.h"
|
#include "util/pointer.h"
|
||||||
|
|
||||||
|
SharedBuffer<u8> makePacket_TOCLIENT_TIME_OF_DAY(u16 time, float time_speed);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
changes by PROTOCOL_VERSION:
|
changes by PROTOCOL_VERSION:
|
||||||
|
@ -73,10 +75,21 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
GENERIC_CMD_SET_ANIMATION
|
GENERIC_CMD_SET_ANIMATION
|
||||||
GENERIC_CMD_SET_BONE_POSITION
|
GENERIC_CMD_SET_BONE_POSITION
|
||||||
GENERIC_CMD_SET_ATTACHMENT
|
GENERIC_CMD_SET_ATTACHMENT
|
||||||
|
PROTOCOL_VERSION 15:
|
||||||
|
Serialization format changes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PROTOCOL_VERSION 14
|
#define LATEST_PROTOCOL_VERSION 15
|
||||||
|
|
||||||
|
// Server's supported network protocol range
|
||||||
|
#define SERVER_PROTOCOL_VERSION_MIN 13
|
||||||
|
#define SERVER_PROTOCOL_VERSION_MAX LATEST_PROTOCOL_VERSION
|
||||||
|
|
||||||
|
// Client's supported network protocol range
|
||||||
|
#define CLIENT_PROTOCOL_VERSION_MIN 13
|
||||||
|
#define CLIENT_PROTOCOL_VERSION_MAX LATEST_PROTOCOL_VERSION
|
||||||
|
|
||||||
|
// Constant that differentiates the protocol from random data and other protocols
|
||||||
#define PROTOCOL_ID 0x4f457403
|
#define PROTOCOL_ID 0x4f457403
|
||||||
|
|
||||||
#define PASSWORD_SIZE 28 // Maximum password length. Allows for
|
#define PASSWORD_SIZE 28 // Maximum password length. Allows for
|
||||||
|
@ -95,6 +108,7 @@ enum ToClientCommand
|
||||||
[2] u8 deployed version
|
[2] u8 deployed version
|
||||||
[3] v3s16 player's position + v3f(0,BS/2,0) floatToInt'd
|
[3] v3s16 player's position + v3f(0,BS/2,0) floatToInt'd
|
||||||
[12] u64 map seed (new as of 2011-02-27)
|
[12] u64 map seed (new as of 2011-02-27)
|
||||||
|
[20] f1000 recommended send interval (in seconds) (new as of 14)
|
||||||
|
|
||||||
NOTE: The position in here is deprecated; position is
|
NOTE: The position in here is deprecated; position is
|
||||||
explicitly sent afterwards
|
explicitly sent afterwards
|
||||||
|
@ -350,7 +364,8 @@ enum ToServerCommand
|
||||||
[2] u8 SER_FMT_VER_HIGHEST
|
[2] u8 SER_FMT_VER_HIGHEST
|
||||||
[3] u8[20] player_name
|
[3] u8[20] player_name
|
||||||
[23] u8[28] password (new in some version)
|
[23] u8[28] password (new in some version)
|
||||||
[51] u16 client network protocol version (new in some version)
|
[51] u16 minimum supported network protocol version (added sometime)
|
||||||
|
[53] u16 maximum supported network protocol version (added later than the previous one)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TOSERVER_INIT2 = 0x11,
|
TOSERVER_INIT2 = 0x11,
|
||||||
|
@ -558,14 +573,5 @@ enum ToServerCommand
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline SharedBuffer<u8> makePacket_TOCLIENT_TIME_OF_DAY(u16 time, float time_speed)
|
|
||||||
{
|
|
||||||
SharedBuffer<u8> data(2+2+4);
|
|
||||||
writeU16(&data[0], TOCLIENT_TIME_OF_DAY);
|
|
||||||
writeU16(&data[2], time);
|
|
||||||
writeF1000(&data[4], time_speed);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "util/serialize.h"
|
#include "util/serialize.h"
|
||||||
#include "util/numeric.h"
|
#include "util/numeric.h"
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
namespace con
|
namespace con
|
||||||
{
|
{
|
||||||
|
@ -466,7 +467,10 @@ Peer::Peer(u16 a_id, Address a_address):
|
||||||
m_sendtime_accu(0),
|
m_sendtime_accu(0),
|
||||||
m_max_packets_per_second(10),
|
m_max_packets_per_second(10),
|
||||||
m_num_sent(0),
|
m_num_sent(0),
|
||||||
m_max_num_sent(0)
|
m_max_num_sent(0),
|
||||||
|
congestion_control_aim_rtt(0.2),
|
||||||
|
congestion_control_max_rate(400),
|
||||||
|
congestion_control_min_rate(10)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
Peer::~Peer()
|
Peer::~Peer()
|
||||||
|
@ -477,15 +481,15 @@ void Peer::reportRTT(float rtt)
|
||||||
{
|
{
|
||||||
if(rtt >= 0.0){
|
if(rtt >= 0.0){
|
||||||
if(rtt < 0.01){
|
if(rtt < 0.01){
|
||||||
if(m_max_packets_per_second < 400)
|
if(m_max_packets_per_second < congestion_control_max_rate)
|
||||||
m_max_packets_per_second += 10;
|
m_max_packets_per_second += 10;
|
||||||
} else if(rtt < 0.2){
|
} else if(rtt < congestion_control_aim_rtt){
|
||||||
if(m_max_packets_per_second < 100)
|
if(m_max_packets_per_second < congestion_control_max_rate)
|
||||||
m_max_packets_per_second += 2;
|
m_max_packets_per_second += 2;
|
||||||
} else {
|
} else {
|
||||||
m_max_packets_per_second *= 0.8;
|
m_max_packets_per_second *= 0.8;
|
||||||
if(m_max_packets_per_second < 10)
|
if(m_max_packets_per_second < congestion_control_min_rate)
|
||||||
m_max_packets_per_second = 10;
|
m_max_packets_per_second = congestion_control_min_rate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -891,12 +895,24 @@ void Connection::receive()
|
||||||
|
|
||||||
void Connection::runTimeouts(float dtime)
|
void Connection::runTimeouts(float dtime)
|
||||||
{
|
{
|
||||||
|
float congestion_control_aim_rtt
|
||||||
|
= g_settings->getFloat("congestion_control_aim_rtt");
|
||||||
|
float congestion_control_max_rate
|
||||||
|
= g_settings->getFloat("congestion_control_max_rate");
|
||||||
|
float congestion_control_min_rate
|
||||||
|
= g_settings->getFloat("congestion_control_min_rate");
|
||||||
|
|
||||||
core::list<u16> timeouted_peers;
|
core::list<u16> timeouted_peers;
|
||||||
core::map<u16, Peer*>::Iterator j;
|
core::map<u16, Peer*>::Iterator j;
|
||||||
j = m_peers.getIterator();
|
j = m_peers.getIterator();
|
||||||
for(; j.atEnd() == false; j++)
|
for(; j.atEnd() == false; j++)
|
||||||
{
|
{
|
||||||
Peer *peer = j.getNode()->getValue();
|
Peer *peer = j.getNode()->getValue();
|
||||||
|
|
||||||
|
// Update congestion control values
|
||||||
|
peer->congestion_control_aim_rtt = congestion_control_aim_rtt;
|
||||||
|
peer->congestion_control_max_rate = congestion_control_max_rate;
|
||||||
|
peer->congestion_control_min_rate = congestion_control_min_rate;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check peer timeout
|
Check peer timeout
|
||||||
|
|
|
@ -394,7 +394,11 @@ public:
|
||||||
float m_max_packets_per_second;
|
float m_max_packets_per_second;
|
||||||
int m_num_sent;
|
int m_num_sent;
|
||||||
int m_max_num_sent;
|
int m_max_num_sent;
|
||||||
|
|
||||||
|
// Updated from configuration by Connection
|
||||||
|
float congestion_control_aim_rtt;
|
||||||
|
float congestion_control_max_rate;
|
||||||
|
float congestion_control_min_rate;
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -647,22 +647,36 @@ public:
|
||||||
{
|
{
|
||||||
infostream<<"GenericCAO: Got init data"<<std::endl;
|
infostream<<"GenericCAO: Got init data"<<std::endl;
|
||||||
std::istringstream is(data, std::ios::binary);
|
std::istringstream is(data, std::ios::binary);
|
||||||
|
int num_messages = 0;
|
||||||
// version
|
// version
|
||||||
u8 version = readU8(is);
|
u8 version = readU8(is);
|
||||||
// check version
|
// check version
|
||||||
if(version != 0){
|
if(version == 1) // In PROTOCOL_VERSION 14
|
||||||
|
{
|
||||||
|
m_name = deSerializeString(is);
|
||||||
|
m_is_player = readU8(is);
|
||||||
|
m_id = readS16(is);
|
||||||
|
m_position = readV3F1000(is);
|
||||||
|
m_yaw = readF1000(is);
|
||||||
|
m_hp = readS16(is);
|
||||||
|
num_messages = readU8(is);
|
||||||
|
}
|
||||||
|
else if(version == 0) // In PROTOCOL_VERSION 13
|
||||||
|
{
|
||||||
|
m_name = deSerializeString(is);
|
||||||
|
m_is_player = readU8(is);
|
||||||
|
m_position = readV3F1000(is);
|
||||||
|
m_yaw = readF1000(is);
|
||||||
|
m_hp = readS16(is);
|
||||||
|
num_messages = readU8(is);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
errorstream<<"GenericCAO: Unsupported init data version"
|
errorstream<<"GenericCAO: Unsupported init data version"
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_name = deSerializeString(is);
|
|
||||||
m_is_player = readU8(is);
|
|
||||||
m_id = readS16(is);
|
|
||||||
m_position = readV3F1000(is);
|
|
||||||
m_yaw = readF1000(is);
|
|
||||||
m_hp = readS16(is);
|
|
||||||
|
|
||||||
int num_messages = readU8(is);
|
|
||||||
for(int i=0; i<num_messages; i++){
|
for(int i=0; i<num_messages; i++){
|
||||||
std::string message = deSerializeLongString(is);
|
std::string message = deSerializeLongString(is);
|
||||||
processMessage(message);
|
processMessage(message);
|
||||||
|
@ -909,6 +923,11 @@ public:
|
||||||
m_prop.visual_size.X));
|
m_prop.visual_size.X));
|
||||||
u8 li = m_last_light;
|
u8 li = m_last_light;
|
||||||
setMeshColor(m_meshnode->getMesh(), video::SColor(255,li,li,li));
|
setMeshColor(m_meshnode->getMesh(), video::SColor(255,li,li,li));
|
||||||
|
|
||||||
|
m_meshnode->setMaterialFlag(video::EMF_LIGHTING, false);
|
||||||
|
m_meshnode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
|
||||||
|
m_meshnode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
|
||||||
|
m_meshnode->setMaterialFlag(video::EMF_FOG_ENABLE, true);
|
||||||
}
|
}
|
||||||
else if(m_prop.visual == "mesh"){
|
else if(m_prop.visual == "mesh"){
|
||||||
infostream<<"GenericCAO::addToScene(): mesh"<<std::endl;
|
infostream<<"GenericCAO::addToScene(): mesh"<<std::endl;
|
||||||
|
@ -922,6 +941,11 @@ public:
|
||||||
m_prop.visual_size.X));
|
m_prop.visual_size.X));
|
||||||
u8 li = m_last_light;
|
u8 li = m_last_light;
|
||||||
setMeshColor(m_animated_meshnode->getMesh(), video::SColor(255,li,li,li));
|
setMeshColor(m_animated_meshnode->getMesh(), video::SColor(255,li,li,li));
|
||||||
|
|
||||||
|
m_animated_meshnode->setMaterialFlag(video::EMF_LIGHTING, false);
|
||||||
|
m_animated_meshnode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
|
||||||
|
m_animated_meshnode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
|
||||||
|
m_animated_meshnode->setMaterialFlag(video::EMF_FOG_ENABLE, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
errorstream<<"GenericCAO::addToScene(): Could not load mesh "<<m_prop.mesh<<std::endl;
|
errorstream<<"GenericCAO::addToScene(): Could not load mesh "<<m_prop.mesh<<std::endl;
|
||||||
|
|
|
@ -26,7 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
#include "gamedef.h"
|
#include "gamedef.h"
|
||||||
#include "util/numeric.h"
|
#include "util/numeric.h"
|
||||||
#include "util/serialize.h"
|
|
||||||
#include "util/directiontables.h"
|
#include "util/directiontables.h"
|
||||||
|
|
||||||
// Create a cuboid.
|
// Create a cuboid.
|
||||||
|
|
|
@ -245,7 +245,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getClientInitializationData()
|
std::string getClientInitializationData(u16 protocol_version)
|
||||||
{
|
{
|
||||||
std::ostringstream os(std::ios::binary);
|
std::ostringstream os(std::ios::binary);
|
||||||
// version
|
// version
|
||||||
|
@ -564,25 +564,41 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LuaEntitySAO::getClientInitializationData()
|
std::string LuaEntitySAO::getClientInitializationData(u16 protocol_version)
|
||||||
{
|
{
|
||||||
std::ostringstream os(std::ios::binary);
|
std::ostringstream os(std::ios::binary);
|
||||||
writeU8(os, 0); // version
|
|
||||||
os<<serializeString(""); // name
|
|
||||||
writeS16(os, getId()); //id
|
|
||||||
writeU8(os, 0); // is_player
|
|
||||||
writeV3F1000(os, m_base_position);
|
|
||||||
writeF1000(os, m_yaw);
|
|
||||||
writeS16(os, m_hp);
|
|
||||||
|
|
||||||
writeU8(os, 4 + m_bone_position.size()); // number of messages stuffed in here
|
if(protocol_version >= 14)
|
||||||
os<<serializeLongString(getPropertyPacket()); // message 1
|
{
|
||||||
os<<serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2
|
writeU8(os, 1); // version
|
||||||
os<<serializeLongString(gob_cmd_update_animation(m_animation_range, m_animation_speed, m_animation_blend)); // 3
|
os<<serializeString(""); // name
|
||||||
for(std::map<std::string, core::vector2d<v3f> >::const_iterator ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii){
|
writeU8(os, 0); // is_player
|
||||||
os<<serializeLongString(gob_cmd_update_bone_position((*ii).first, (*ii).second.X, (*ii).second.Y)); // m_bone_position.size
|
writeS16(os, getId()); //id
|
||||||
|
writeV3F1000(os, m_base_position);
|
||||||
|
writeF1000(os, m_yaw);
|
||||||
|
writeS16(os, m_hp);
|
||||||
|
|
||||||
|
writeU8(os, 4 + m_bone_position.size()); // number of messages stuffed in here
|
||||||
|
os<<serializeLongString(getPropertyPacket()); // message 1
|
||||||
|
os<<serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2
|
||||||
|
os<<serializeLongString(gob_cmd_update_animation(m_animation_range, m_animation_speed, m_animation_blend)); // 3
|
||||||
|
for(std::map<std::string, core::vector2d<v3f> >::const_iterator ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii){
|
||||||
|
os<<serializeLongString(gob_cmd_update_bone_position((*ii).first, (*ii).second.X, (*ii).second.Y)); // m_bone_position.size
|
||||||
|
}
|
||||||
|
os<<serializeLongString(gob_cmd_update_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation)); // 4
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writeU8(os, 0); // version
|
||||||
|
os<<serializeString(""); // name
|
||||||
|
writeU8(os, 0); // is_player
|
||||||
|
writeV3F1000(os, m_base_position);
|
||||||
|
writeF1000(os, m_yaw);
|
||||||
|
writeS16(os, m_hp);
|
||||||
|
writeU8(os, 2); // number of messages stuffed in here
|
||||||
|
os<<serializeLongString(getPropertyPacket()); // message 1
|
||||||
|
os<<serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2
|
||||||
}
|
}
|
||||||
os<<serializeLongString(gob_cmd_update_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation)); // 4
|
|
||||||
|
|
||||||
// return result
|
// return result
|
||||||
return os.str();
|
return os.str();
|
||||||
|
@ -962,25 +978,41 @@ bool PlayerSAO::unlimitedTransferDistance() const
|
||||||
return g_settings->getBool("unlimited_player_transfer_distance");
|
return g_settings->getBool("unlimited_player_transfer_distance");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string PlayerSAO::getClientInitializationData()
|
std::string PlayerSAO::getClientInitializationData(u16 protocol_version)
|
||||||
{
|
{
|
||||||
std::ostringstream os(std::ios::binary);
|
std::ostringstream os(std::ios::binary);
|
||||||
writeU8(os, 0); // version
|
|
||||||
os<<serializeString(m_player->getName()); // name
|
|
||||||
writeU8(os, 1); // is_player
|
|
||||||
writeS16(os, getId()); //id
|
|
||||||
writeV3F1000(os, m_player->getPosition() + v3f(0,BS*1,0));
|
|
||||||
writeF1000(os, m_player->getYaw());
|
|
||||||
writeS16(os, getHP());
|
|
||||||
|
|
||||||
writeU8(os, 4 + m_bone_position.size()); // number of messages stuffed in here
|
if(protocol_version >= 15)
|
||||||
os<<serializeLongString(getPropertyPacket()); // message 1
|
{
|
||||||
os<<serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2
|
writeU8(os, 1); // version
|
||||||
os<<serializeLongString(gob_cmd_update_animation(m_animation_range, m_animation_speed, m_animation_blend)); // 3
|
os<<serializeString(m_player->getName()); // name
|
||||||
for(std::map<std::string, core::vector2d<v3f> >::const_iterator ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii){
|
writeU8(os, 1); // is_player
|
||||||
os<<serializeLongString(gob_cmd_update_bone_position((*ii).first, (*ii).second.X, (*ii).second.Y)); // m_bone_position.size
|
writeS16(os, getId()); //id
|
||||||
|
writeV3F1000(os, m_player->getPosition() + v3f(0,BS*1,0));
|
||||||
|
writeF1000(os, m_player->getYaw());
|
||||||
|
writeS16(os, getHP());
|
||||||
|
|
||||||
|
writeU8(os, 4 + m_bone_position.size()); // number of messages stuffed in here
|
||||||
|
os<<serializeLongString(getPropertyPacket()); // message 1
|
||||||
|
os<<serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2
|
||||||
|
os<<serializeLongString(gob_cmd_update_animation(m_animation_range, m_animation_speed, m_animation_blend)); // 3
|
||||||
|
for(std::map<std::string, core::vector2d<v3f> >::const_iterator ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii){
|
||||||
|
os<<serializeLongString(gob_cmd_update_bone_position((*ii).first, (*ii).second.X, (*ii).second.Y)); // m_bone_position.size
|
||||||
|
}
|
||||||
|
os<<serializeLongString(gob_cmd_update_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation)); // 4
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writeU8(os, 0); // version
|
||||||
|
os<<serializeString(m_player->getName()); // name
|
||||||
|
writeU8(os, 1); // is_player
|
||||||
|
writeV3F1000(os, m_player->getPosition() + v3f(0,BS*1,0));
|
||||||
|
writeF1000(os, m_player->getYaw());
|
||||||
|
writeS16(os, getHP());
|
||||||
|
writeU8(os, 2); // number of messages stuffed in here
|
||||||
|
os<<serializeLongString(getPropertyPacket()); // message 1
|
||||||
|
os<<serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2
|
||||||
}
|
}
|
||||||
os<<serializeLongString(gob_cmd_update_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation)); // 4
|
|
||||||
|
|
||||||
// return result
|
// return result
|
||||||
return os.str();
|
return os.str();
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
const std::string &data);
|
const std::string &data);
|
||||||
bool isAttached();
|
bool isAttached();
|
||||||
void step(float dtime, bool send_recommended);
|
void step(float dtime, bool send_recommended);
|
||||||
std::string getClientInitializationData();
|
std::string getClientInitializationData(u16 protocol_version);
|
||||||
std::string getStaticData();
|
std::string getStaticData();
|
||||||
int punch(v3f dir,
|
int punch(v3f dir,
|
||||||
const ToolCapabilities *toolcap=NULL,
|
const ToolCapabilities *toolcap=NULL,
|
||||||
|
@ -140,7 +140,7 @@ public:
|
||||||
void removingFromEnvironment();
|
void removingFromEnvironment();
|
||||||
bool isStaticAllowed() const;
|
bool isStaticAllowed() const;
|
||||||
bool unlimitedTransferDistance() const;
|
bool unlimitedTransferDistance() const;
|
||||||
std::string getClientInitializationData();
|
std::string getClientInitializationData(u16 protocol_version);
|
||||||
std::string getStaticData();
|
std::string getStaticData();
|
||||||
bool isAttached();
|
bool isAttached();
|
||||||
void step(float dtime, bool send_recommended);
|
void step(float dtime, bool send_recommended);
|
||||||
|
|
|
@ -106,12 +106,17 @@ void set_default_settings(Settings *settings)
|
||||||
settings->setDefault("sound_volume", "0.8");
|
settings->setDefault("sound_volume", "0.8");
|
||||||
settings->setDefault("desynchronize_mapblock_texture_animation", "true");
|
settings->setDefault("desynchronize_mapblock_texture_animation", "true");
|
||||||
|
|
||||||
|
settings->setDefault("mip_map", "false");
|
||||||
|
settings->setDefault("anisotropic_filter", "false");
|
||||||
|
settings->setDefault("bilinear_filter", "false");
|
||||||
|
settings->setDefault("trilinear_filter", "false");
|
||||||
|
|
||||||
// Server stuff
|
// Server stuff
|
||||||
// "map-dir" doesn't exist by default.
|
// "map-dir" doesn't exist by default.
|
||||||
settings->setDefault("default_game", "minetest");
|
settings->setDefault("default_game", "minetest");
|
||||||
settings->setDefault("motd", "");
|
settings->setDefault("motd", "");
|
||||||
settings->setDefault("max_users", "100");
|
settings->setDefault("max_users", "100");
|
||||||
settings->setDefault("strict_protocol_version_checking", "true");
|
settings->setDefault("strict_protocol_version_checking", "false");
|
||||||
settings->setDefault("creative_mode", "false");
|
settings->setDefault("creative_mode", "false");
|
||||||
settings->setDefault("enable_damage", "true");
|
settings->setDefault("enable_damage", "true");
|
||||||
settings->setDefault("only_peaceful_mobs", "false");
|
settings->setDefault("only_peaceful_mobs", "false");
|
||||||
|
@ -140,12 +145,10 @@ void set_default_settings(Settings *settings)
|
||||||
settings->setDefault("server_unload_unused_data_timeout", "29");
|
settings->setDefault("server_unload_unused_data_timeout", "29");
|
||||||
settings->setDefault("server_map_save_interval", "5.3");
|
settings->setDefault("server_map_save_interval", "5.3");
|
||||||
settings->setDefault("full_block_send_enable_min_time_from_building", "2.0");
|
settings->setDefault("full_block_send_enable_min_time_from_building", "2.0");
|
||||||
settings->setDefault("dedicated_server_step", "0.05");
|
settings->setDefault("dedicated_server_step", "0.1");
|
||||||
settings->setDefault("ignore_world_load_errors", "false");
|
settings->setDefault("ignore_world_load_errors", "false");
|
||||||
settings->setDefault("mip_map", "false");
|
settings->setDefault("congestion_control_aim_rtt", "0.2");
|
||||||
settings->setDefault("anisotropic_filter", "false");
|
settings->setDefault("congestion_control_max_rate", "400");
|
||||||
settings->setDefault("bilinear_filter", "false");
|
settings->setDefault("congestion_control_min_rate", "10");
|
||||||
settings->setDefault("trilinear_filter", "false");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#endif
|
#endif
|
||||||
#include "daynightratio.h"
|
#include "daynightratio.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
#include "util/serialize.h"
|
||||||
|
|
||||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||||
|
|
||||||
|
@ -328,7 +329,8 @@ ServerEnvironment::ServerEnvironment(ServerMap *map, lua_State *L,
|
||||||
m_send_recommended_timer(0),
|
m_send_recommended_timer(0),
|
||||||
m_active_block_interval_overload_skip(0),
|
m_active_block_interval_overload_skip(0),
|
||||||
m_game_time(0),
|
m_game_time(0),
|
||||||
m_game_time_fraction_counter(0)
|
m_game_time_fraction_counter(0),
|
||||||
|
m_recommended_send_interval(0.1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -939,6 +941,11 @@ void ServerEnvironment::step(float dtime)
|
||||||
/* Step time of day */
|
/* Step time of day */
|
||||||
stepTimeOfDay(dtime);
|
stepTimeOfDay(dtime);
|
||||||
|
|
||||||
|
// Update this one
|
||||||
|
// NOTE: This is kind of funny on a singleplayer game, but doesn't
|
||||||
|
// really matter that much.
|
||||||
|
m_recommended_send_interval = g_settings->getFloat("dedicated_server_step");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Increment game time
|
Increment game time
|
||||||
*/
|
*/
|
||||||
|
@ -2296,8 +2303,9 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type,
|
||||||
{
|
{
|
||||||
errorstream<<"ClientEnvironment::addActiveObject():"
|
errorstream<<"ClientEnvironment::addActiveObject():"
|
||||||
<<" id="<<id<<" type="<<type
|
<<" id="<<id<<" type="<<type
|
||||||
<<": SerializationError in initialize(),"
|
<<": SerializationError in initialize(): "
|
||||||
<<" init_data="<<serializeJsonString(init_data)
|
<<e.what()
|
||||||
|
<<": init_data="<<serializeJsonString(init_data)
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -205,9 +205,7 @@ public:
|
||||||
{ return m_gamedef; }
|
{ return m_gamedef; }
|
||||||
|
|
||||||
float getSendRecommendedInterval()
|
float getSendRecommendedInterval()
|
||||||
{
|
{ return m_recommended_send_interval; }
|
||||||
return 0.10;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Save players
|
Save players
|
||||||
|
@ -367,6 +365,8 @@ private:
|
||||||
// A helper variable for incrementing the latter
|
// A helper variable for incrementing the latter
|
||||||
float m_game_time_fraction_counter;
|
float m_game_time_fraction_counter;
|
||||||
core::list<ABMWithState> m_abms;
|
core::list<ABMWithState> m_abms;
|
||||||
|
// An interval for generally sending object positions and stuff
|
||||||
|
float m_recommended_send_interval;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef SERVER
|
#ifndef SERVER
|
||||||
|
|
|
@ -1513,7 +1513,7 @@ void the_game(
|
||||||
<<"Launching inventory"<<std::endl;
|
<<"Launching inventory"<<std::endl;
|
||||||
|
|
||||||
GUIFormSpecMenu *menu =
|
GUIFormSpecMenu *menu =
|
||||||
new GUIFormSpecMenu(guienv, guiroot, -1,
|
new GUIFormSpecMenu(device, guiroot, -1,
|
||||||
&g_menumgr,
|
&g_menumgr,
|
||||||
&client, gamedef);
|
&client, gamedef);
|
||||||
|
|
||||||
|
@ -2296,7 +2296,7 @@ void the_game(
|
||||||
/* Create menu */
|
/* Create menu */
|
||||||
|
|
||||||
GUIFormSpecMenu *menu =
|
GUIFormSpecMenu *menu =
|
||||||
new GUIFormSpecMenu(guienv, guiroot, -1,
|
new GUIFormSpecMenu(device, guiroot, -1,
|
||||||
&g_menumgr,
|
&g_menumgr,
|
||||||
&client, gamedef);
|
&client, gamedef);
|
||||||
menu->setFormSpec(meta->getString("formspec"),
|
menu->setFormSpec(meta->getString("formspec"),
|
||||||
|
|
|
@ -92,6 +92,31 @@ std::string gob_cmd_set_sprite(
|
||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string gob_cmd_punched(s16 damage, s16 result_hp)
|
||||||
|
{
|
||||||
|
std::ostringstream os(std::ios::binary);
|
||||||
|
// command
|
||||||
|
writeU8(os, GENERIC_CMD_PUNCHED);
|
||||||
|
// damage
|
||||||
|
writeS16(os, damage);
|
||||||
|
// result_hp
|
||||||
|
writeS16(os, result_hp);
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string gob_cmd_update_armor_groups(const ItemGroupList &armor_groups)
|
||||||
|
{
|
||||||
|
std::ostringstream os(std::ios::binary);
|
||||||
|
writeU8(os, GENERIC_CMD_UPDATE_ARMOR_GROUPS);
|
||||||
|
writeU16(os, armor_groups.size());
|
||||||
|
for(ItemGroupList::const_iterator i = armor_groups.begin();
|
||||||
|
i != armor_groups.end(); i++){
|
||||||
|
os<<serializeString(i->first);
|
||||||
|
writeS16(os, i->second);
|
||||||
|
}
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
std::string gob_cmd_update_animation(v2f frames, float frame_speed, float frame_blend)
|
std::string gob_cmd_update_animation(v2f frames, float frame_speed, float frame_blend)
|
||||||
{
|
{
|
||||||
std::ostringstream os(std::ios::binary);
|
std::ostringstream os(std::ios::binary);
|
||||||
|
@ -129,29 +154,3 @@ std::string gob_cmd_update_attachment(int parent_id, std::string bone, v3f posit
|
||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string gob_cmd_punched(s16 damage, s16 result_hp)
|
|
||||||
{
|
|
||||||
std::ostringstream os(std::ios::binary);
|
|
||||||
// command
|
|
||||||
writeU8(os, GENERIC_CMD_PUNCHED);
|
|
||||||
// damage
|
|
||||||
writeS16(os, damage);
|
|
||||||
// result_hp
|
|
||||||
writeS16(os, result_hp);
|
|
||||||
return os.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string gob_cmd_update_armor_groups(const ItemGroupList &armor_groups)
|
|
||||||
{
|
|
||||||
std::ostringstream os(std::ios::binary);
|
|
||||||
writeU8(os, GENERIC_CMD_UPDATE_ARMOR_GROUPS);
|
|
||||||
writeU16(os, armor_groups.size());
|
|
||||||
for(ItemGroupList::const_iterator i = armor_groups.begin();
|
|
||||||
i != armor_groups.end(); i++){
|
|
||||||
os<<serializeString(i->first);
|
|
||||||
writeS16(os, i->second);
|
|
||||||
}
|
|
||||||
return os.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,11 +28,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#define GENERIC_CMD_UPDATE_POSITION 1
|
#define GENERIC_CMD_UPDATE_POSITION 1
|
||||||
#define GENERIC_CMD_SET_TEXTURE_MOD 2
|
#define GENERIC_CMD_SET_TEXTURE_MOD 2
|
||||||
#define GENERIC_CMD_SET_SPRITE 3
|
#define GENERIC_CMD_SET_SPRITE 3
|
||||||
#define GENERIC_CMD_SET_ANIMATION 4
|
#define GENERIC_CMD_PUNCHED 4
|
||||||
#define GENERIC_CMD_SET_BONE_POSITION 5
|
#define GENERIC_CMD_UPDATE_ARMOR_GROUPS 5
|
||||||
#define GENERIC_CMD_SET_ATTACHMENT 6
|
#define GENERIC_CMD_SET_ANIMATION 6
|
||||||
#define GENERIC_CMD_PUNCHED 7
|
#define GENERIC_CMD_SET_BONE_POSITION 7
|
||||||
#define GENERIC_CMD_UPDATE_ARMOR_GROUPS 8
|
#define GENERIC_CMD_SET_ATTACHMENT 8
|
||||||
|
|
||||||
#include "object_properties.h"
|
#include "object_properties.h"
|
||||||
std::string gob_cmd_set_properties(const ObjectProperties &prop);
|
std::string gob_cmd_set_properties(const ObjectProperties &prop);
|
||||||
|
@ -57,16 +57,16 @@ std::string gob_cmd_set_sprite(
|
||||||
bool select_horiz_by_yawpitch
|
bool select_horiz_by_yawpitch
|
||||||
);
|
);
|
||||||
|
|
||||||
|
std::string gob_cmd_punched(s16 damage, s16 result_hp);
|
||||||
|
|
||||||
|
#include "itemgroup.h"
|
||||||
|
std::string gob_cmd_update_armor_groups(const ItemGroupList &armor_groups);
|
||||||
|
|
||||||
std::string gob_cmd_update_animation(v2f frames, float frame_speed, float frame_blend);
|
std::string gob_cmd_update_animation(v2f frames, float frame_speed, float frame_blend);
|
||||||
|
|
||||||
std::string gob_cmd_update_bone_position(std::string bone, v3f position, v3f rotation);
|
std::string gob_cmd_update_bone_position(std::string bone, v3f position, v3f rotation);
|
||||||
|
|
||||||
std::string gob_cmd_update_attachment(int parent_id, std::string bone, v3f position, v3f rotation);
|
std::string gob_cmd_update_attachment(int parent_id, std::string bone, v3f position, v3f rotation);
|
||||||
|
|
||||||
std::string gob_cmd_punched(s16 damage, s16 result_hp);
|
|
||||||
|
|
||||||
#include "itemgroup.h"
|
|
||||||
std::string gob_cmd_update_armor_groups(const ItemGroupList &armor_groups);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -125,13 +125,14 @@ void drawItemStack(video::IVideoDriver *driver,
|
||||||
GUIFormSpecMenu
|
GUIFormSpecMenu
|
||||||
*/
|
*/
|
||||||
|
|
||||||
GUIFormSpecMenu::GUIFormSpecMenu(gui::IGUIEnvironment* env,
|
GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
|
||||||
gui::IGUIElement* parent, s32 id,
|
gui::IGUIElement* parent, s32 id,
|
||||||
IMenuManager *menumgr,
|
IMenuManager *menumgr,
|
||||||
InventoryManager *invmgr,
|
InventoryManager *invmgr,
|
||||||
IGameDef *gamedef
|
IGameDef *gamedef
|
||||||
):
|
):
|
||||||
GUIModalMenu(env, parent, id, menumgr),
|
GUIModalMenu(dev->getGUIEnvironment(), parent, id, menumgr),
|
||||||
|
m_device(dev),
|
||||||
m_invmgr(invmgr),
|
m_invmgr(invmgr),
|
||||||
m_gamedef(gamedef),
|
m_gamedef(gamedef),
|
||||||
m_form_src(NULL),
|
m_form_src(NULL),
|
||||||
|
@ -698,6 +699,8 @@ void GUIFormSpecMenu::drawMenu()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_pointer = m_device->getCursorControl()->getPosition();
|
||||||
|
|
||||||
updateSelectedItem();
|
updateSelectedItem();
|
||||||
|
|
||||||
gui::IGUISkin* skin = Environment->getSkin();
|
gui::IGUISkin* skin = Environment->getSkin();
|
||||||
|
@ -937,24 +940,15 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(event.EventType==EET_MOUSE_INPUT_EVENT
|
|
||||||
&& event.MouseInput.Event == EMIE_MOUSE_MOVED)
|
|
||||||
{
|
|
||||||
// Mouse moved
|
|
||||||
m_pointer = v2s32(event.MouseInput.X, event.MouseInput.Y);
|
|
||||||
}
|
|
||||||
if(event.EventType==EET_MOUSE_INPUT_EVENT
|
if(event.EventType==EET_MOUSE_INPUT_EVENT
|
||||||
&& event.MouseInput.Event != EMIE_MOUSE_MOVED)
|
&& event.MouseInput.Event != EMIE_MOUSE_MOVED)
|
||||||
{
|
{
|
||||||
// Mouse event other than movement
|
// Mouse event other than movement
|
||||||
|
|
||||||
v2s32 p(event.MouseInput.X, event.MouseInput.Y);
|
|
||||||
m_pointer = p;
|
|
||||||
|
|
||||||
// Get selected item and hovered/clicked item (s)
|
// Get selected item and hovered/clicked item (s)
|
||||||
|
|
||||||
updateSelectedItem();
|
updateSelectedItem();
|
||||||
ItemSpec s = getItemAtPos(p);
|
ItemSpec s = getItemAtPos(m_pointer);
|
||||||
|
|
||||||
Inventory *inv_selected = NULL;
|
Inventory *inv_selected = NULL;
|
||||||
Inventory *inv_s = NULL;
|
Inventory *inv_s = NULL;
|
||||||
|
|
|
@ -144,7 +144,7 @@ class GUIFormSpecMenu : public GUIModalMenu
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GUIFormSpecMenu(gui::IGUIEnvironment* env,
|
GUIFormSpecMenu(irr::IrrlichtDevice* dev,
|
||||||
gui::IGUIElement* parent, s32 id,
|
gui::IGUIElement* parent, s32 id,
|
||||||
IMenuManager *menumgr,
|
IMenuManager *menumgr,
|
||||||
InventoryManager *invmgr,
|
InventoryManager *invmgr,
|
||||||
|
@ -197,6 +197,7 @@ protected:
|
||||||
v2s32 spacing;
|
v2s32 spacing;
|
||||||
v2s32 imgsize;
|
v2s32 imgsize;
|
||||||
|
|
||||||
|
irr::IrrlichtDevice* m_device;
|
||||||
InventoryManager *m_invmgr;
|
InventoryManager *m_invmgr;
|
||||||
IGameDef *m_gamedef;
|
IGameDef *m_gamedef;
|
||||||
|
|
||||||
|
|
|
@ -323,7 +323,7 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
|
||||||
v3s16 camera_np = floatToInt(getEyePosition(), BS);
|
v3s16 camera_np = floatToInt(getEyePosition(), BS);
|
||||||
MapNode n = map.getNodeNoEx(camera_np);
|
MapNode n = map.getNodeNoEx(camera_np);
|
||||||
if(n.getContent() != CONTENT_IGNORE){
|
if(n.getContent() != CONTENT_IGNORE){
|
||||||
if(nodemgr->get(n).walkable){
|
if(nodemgr->get(n).walkable && nodemgr->get(n).solidness == 2){
|
||||||
camera_barely_in_ceiling = true;
|
camera_barely_in_ceiling = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "mapblock_mesh.h"
|
#include "mapblock_mesh.h"
|
||||||
#endif
|
#endif
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
|
#include "util/serialize.h"
|
||||||
|
|
||||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||||
|
|
||||||
|
|
|
@ -77,9 +77,9 @@ void MeshMakeData::fill(MapBlock *block)
|
||||||
// Get map
|
// Get map
|
||||||
Map *map = block->getParent();
|
Map *map = block->getParent();
|
||||||
|
|
||||||
for(u16 i=0; i<6; i++)
|
for(u16 i=0; i<26; i++)
|
||||||
{
|
{
|
||||||
const v3s16 &dir = g_6dirs[i];
|
const v3s16 &dir = g_26dirs[i];
|
||||||
v3s16 bp = m_blockpos + dir;
|
v3s16 bp = m_blockpos + dir;
|
||||||
MapBlock *b = map->getBlockNoCreateNoEx(bp);
|
MapBlock *b = map->getBlockNoCreateNoEx(bp);
|
||||||
if(b)
|
if(b)
|
||||||
|
|
|
@ -39,6 +39,10 @@ static void collectMods(const std::string &modspath,
|
||||||
if(!dirlist[j].dir)
|
if(!dirlist[j].dir)
|
||||||
continue;
|
continue;
|
||||||
std::string modname = dirlist[j].name;
|
std::string modname = dirlist[j].name;
|
||||||
|
// Ignore all directories beginning with a ".", especially
|
||||||
|
// VCS directories like ".git" or ".svn"
|
||||||
|
if(modname[0] == '.')
|
||||||
|
continue;
|
||||||
std::string modpath = modspath + DIR_DELIM + modname;
|
std::string modpath = modspath + DIR_DELIM + modname;
|
||||||
TRACESTREAM(<<indentation<<"collectMods: "<<modname<<" at \""<<modpath<<"\""<<std::endl);
|
TRACESTREAM(<<indentation<<"collectMods: "<<modname<<" at \""<<modpath<<"\""<<std::endl);
|
||||||
// Handle modpacks (defined by containing modpack.txt)
|
// Handle modpacks (defined by containing modpack.txt)
|
||||||
|
|
137
src/nodedef.cpp
137
src/nodedef.cpp
|
@ -215,8 +215,13 @@ void ContentFeatures::reset()
|
||||||
sound_dug = SimpleSoundSpec();
|
sound_dug = SimpleSoundSpec();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentFeatures::serialize(std::ostream &os)
|
void ContentFeatures::serialize(std::ostream &os, u16 protocol_version)
|
||||||
{
|
{
|
||||||
|
if(protocol_version < 14){
|
||||||
|
serializeOld(os, protocol_version);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
writeU8(os, 6); // version
|
writeU8(os, 6); // version
|
||||||
os<<serializeString(name);
|
os<<serializeString(name);
|
||||||
writeU16(os, groups.size());
|
writeU16(os, groups.size());
|
||||||
|
@ -271,8 +276,11 @@ void ContentFeatures::serialize(std::ostream &os)
|
||||||
void ContentFeatures::deSerialize(std::istream &is)
|
void ContentFeatures::deSerialize(std::istream &is)
|
||||||
{
|
{
|
||||||
int version = readU8(is);
|
int version = readU8(is);
|
||||||
if(version != 6)
|
if(version != 6){
|
||||||
throw SerializationError("unsupported ContentFeatures version");
|
deSerializeOld(is, version);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
name = deSerializeString(is);
|
name = deSerializeString(is);
|
||||||
groups.clear();
|
groups.clear();
|
||||||
u32 groups_size = readU16(is);
|
u32 groups_size = readU16(is);
|
||||||
|
@ -693,7 +701,7 @@ public:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
void serialize(std::ostream &os)
|
void serialize(std::ostream &os, u16 protocol_version)
|
||||||
{
|
{
|
||||||
writeU8(os, 1); // version
|
writeU8(os, 1); // version
|
||||||
u16 count = 0;
|
u16 count = 0;
|
||||||
|
@ -709,7 +717,7 @@ public:
|
||||||
// Wrap it in a string to allow different lengths without
|
// Wrap it in a string to allow different lengths without
|
||||||
// strict version incompatibilities
|
// strict version incompatibilities
|
||||||
std::ostringstream wrapper_os(std::ios::binary);
|
std::ostringstream wrapper_os(std::ios::binary);
|
||||||
f->serialize(wrapper_os);
|
f->serialize(wrapper_os, protocol_version);
|
||||||
os2<<serializeString(wrapper_os.str());
|
os2<<serializeString(wrapper_os.str());
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
@ -766,3 +774,122 @@ IWritableNodeDefManager* createNodeDefManager()
|
||||||
return new CNodeDefManager();
|
return new CNodeDefManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Serialization of old ContentFeatures formats
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ContentFeatures::serializeOld(std::ostream &os, u16 protocol_version)
|
||||||
|
{
|
||||||
|
if(protocol_version == 13)
|
||||||
|
{
|
||||||
|
writeU8(os, 5); // version
|
||||||
|
os<<serializeString(name);
|
||||||
|
writeU16(os, groups.size());
|
||||||
|
for(ItemGroupList::const_iterator
|
||||||
|
i = groups.begin(); i != groups.end(); i++){
|
||||||
|
os<<serializeString(i->first);
|
||||||
|
writeS16(os, i->second);
|
||||||
|
}
|
||||||
|
writeU8(os, drawtype);
|
||||||
|
writeF1000(os, visual_scale);
|
||||||
|
writeU8(os, 6);
|
||||||
|
for(u32 i=0; i<6; i++)
|
||||||
|
tiledef[i].serialize(os);
|
||||||
|
writeU8(os, CF_SPECIAL_COUNT);
|
||||||
|
for(u32 i=0; i<CF_SPECIAL_COUNT; i++){
|
||||||
|
tiledef_special[i].serialize(os);
|
||||||
|
}
|
||||||
|
writeU8(os, alpha);
|
||||||
|
writeU8(os, post_effect_color.getAlpha());
|
||||||
|
writeU8(os, post_effect_color.getRed());
|
||||||
|
writeU8(os, post_effect_color.getGreen());
|
||||||
|
writeU8(os, post_effect_color.getBlue());
|
||||||
|
writeU8(os, param_type);
|
||||||
|
writeU8(os, param_type_2);
|
||||||
|
writeU8(os, is_ground_content);
|
||||||
|
writeU8(os, light_propagates);
|
||||||
|
writeU8(os, sunlight_propagates);
|
||||||
|
writeU8(os, walkable);
|
||||||
|
writeU8(os, pointable);
|
||||||
|
writeU8(os, diggable);
|
||||||
|
writeU8(os, climbable);
|
||||||
|
writeU8(os, buildable_to);
|
||||||
|
os<<serializeString(""); // legacy: used to be metadata_name
|
||||||
|
writeU8(os, liquid_type);
|
||||||
|
os<<serializeString(liquid_alternative_flowing);
|
||||||
|
os<<serializeString(liquid_alternative_source);
|
||||||
|
writeU8(os, liquid_viscosity);
|
||||||
|
writeU8(os, light_source);
|
||||||
|
writeU32(os, damage_per_second);
|
||||||
|
node_box.serialize(os);
|
||||||
|
selection_box.serialize(os);
|
||||||
|
writeU8(os, legacy_facedir_simple);
|
||||||
|
writeU8(os, legacy_wallmounted);
|
||||||
|
serializeSimpleSoundSpec(sound_footstep, os);
|
||||||
|
serializeSimpleSoundSpec(sound_dig, os);
|
||||||
|
serializeSimpleSoundSpec(sound_dug, os);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw SerializationError("ContentFeatures::serialize(): Unsupported version requested");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentFeatures::deSerializeOld(std::istream &is, int version)
|
||||||
|
{
|
||||||
|
if(version == 5) // In PROTOCOL_VERSION 13
|
||||||
|
{
|
||||||
|
name = deSerializeString(is);
|
||||||
|
groups.clear();
|
||||||
|
u32 groups_size = readU16(is);
|
||||||
|
for(u32 i=0; i<groups_size; i++){
|
||||||
|
std::string name = deSerializeString(is);
|
||||||
|
int value = readS16(is);
|
||||||
|
groups[name] = value;
|
||||||
|
}
|
||||||
|
drawtype = (enum NodeDrawType)readU8(is);
|
||||||
|
visual_scale = readF1000(is);
|
||||||
|
if(readU8(is) != 6)
|
||||||
|
throw SerializationError("unsupported tile count");
|
||||||
|
for(u32 i=0; i<6; i++)
|
||||||
|
tiledef[i].deSerialize(is);
|
||||||
|
if(readU8(is) != CF_SPECIAL_COUNT)
|
||||||
|
throw SerializationError("unsupported CF_SPECIAL_COUNT");
|
||||||
|
for(u32 i=0; i<CF_SPECIAL_COUNT; i++)
|
||||||
|
tiledef_special[i].deSerialize(is);
|
||||||
|
alpha = readU8(is);
|
||||||
|
post_effect_color.setAlpha(readU8(is));
|
||||||
|
post_effect_color.setRed(readU8(is));
|
||||||
|
post_effect_color.setGreen(readU8(is));
|
||||||
|
post_effect_color.setBlue(readU8(is));
|
||||||
|
param_type = (enum ContentParamType)readU8(is);
|
||||||
|
param_type_2 = (enum ContentParamType2)readU8(is);
|
||||||
|
is_ground_content = readU8(is);
|
||||||
|
light_propagates = readU8(is);
|
||||||
|
sunlight_propagates = readU8(is);
|
||||||
|
walkable = readU8(is);
|
||||||
|
pointable = readU8(is);
|
||||||
|
diggable = readU8(is);
|
||||||
|
climbable = readU8(is);
|
||||||
|
buildable_to = readU8(is);
|
||||||
|
deSerializeString(is); // legacy: used to be metadata_name
|
||||||
|
liquid_type = (enum LiquidType)readU8(is);
|
||||||
|
liquid_alternative_flowing = deSerializeString(is);
|
||||||
|
liquid_alternative_source = deSerializeString(is);
|
||||||
|
liquid_viscosity = readU8(is);
|
||||||
|
light_source = readU8(is);
|
||||||
|
damage_per_second = readU32(is);
|
||||||
|
node_box.deSerialize(is);
|
||||||
|
selection_box.deSerialize(is);
|
||||||
|
legacy_facedir_simple = readU8(is);
|
||||||
|
legacy_wallmounted = readU8(is);
|
||||||
|
deSerializeSimpleSoundSpec(sound_footstep, is);
|
||||||
|
deSerializeSimpleSoundSpec(sound_dig, is);
|
||||||
|
deSerializeSimpleSoundSpec(sound_dug, is);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw SerializationError("unsupported ContentFeatures version");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -234,8 +234,10 @@ struct ContentFeatures
|
||||||
ContentFeatures();
|
ContentFeatures();
|
||||||
~ContentFeatures();
|
~ContentFeatures();
|
||||||
void reset();
|
void reset();
|
||||||
void serialize(std::ostream &os);
|
void serialize(std::ostream &os, u16 protocol_version);
|
||||||
void deSerialize(std::istream &is);
|
void deSerialize(std::istream &is);
|
||||||
|
void serializeOld(std::ostream &os, u16 protocol_version);
|
||||||
|
void deSerializeOld(std::istream &is, int version);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Some handy methods
|
Some handy methods
|
||||||
|
@ -264,7 +266,7 @@ public:
|
||||||
const=0;
|
const=0;
|
||||||
virtual const ContentFeatures& get(const std::string &name) const=0;
|
virtual const ContentFeatures& get(const std::string &name) const=0;
|
||||||
|
|
||||||
virtual void serialize(std::ostream &os)=0;
|
virtual void serialize(std::ostream &os, u16 protocol_version)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IWritableNodeDefManager : public INodeDefManager
|
class IWritableNodeDefManager : public INodeDefManager
|
||||||
|
@ -305,7 +307,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void updateTextures(ITextureSource *tsrc)=0;
|
virtual void updateTextures(ITextureSource *tsrc)=0;
|
||||||
|
|
||||||
virtual void serialize(std::ostream &os)=0;
|
virtual void serialize(std::ostream &os, u16 protocol_version)=0;
|
||||||
virtual void deSerialize(std::istream &is)=0;
|
virtual void deSerialize(std::istream &is)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -81,52 +81,59 @@ void ObjectProperties::serialize(std::ostream &os) const
|
||||||
writeV3F1000(os, collisionbox.MinEdge);
|
writeV3F1000(os, collisionbox.MinEdge);
|
||||||
writeV3F1000(os, collisionbox.MaxEdge);
|
writeV3F1000(os, collisionbox.MaxEdge);
|
||||||
os<<serializeString(visual);
|
os<<serializeString(visual);
|
||||||
os<<serializeString(mesh);
|
|
||||||
writeV2F1000(os, visual_size);
|
writeV2F1000(os, visual_size);
|
||||||
writeU16(os, textures.size());
|
writeU16(os, textures.size());
|
||||||
for(u32 i=0; i<textures.size(); i++){
|
for(u32 i=0; i<textures.size(); i++){
|
||||||
os<<serializeString(textures[i]);
|
os<<serializeString(textures[i]);
|
||||||
}
|
}
|
||||||
writeU16(os, colors.size());
|
|
||||||
for(u32 i=0; i<colors.size(); i++){
|
|
||||||
writeARGB8(os, colors[i]);
|
|
||||||
}
|
|
||||||
writeV2S16(os, spritediv);
|
writeV2S16(os, spritediv);
|
||||||
writeV2S16(os, initial_sprite_basepos);
|
writeV2S16(os, initial_sprite_basepos);
|
||||||
writeU8(os, is_visible);
|
writeU8(os, is_visible);
|
||||||
writeU8(os, makes_footstep_sound);
|
writeU8(os, makes_footstep_sound);
|
||||||
writeF1000(os, automatic_rotate);
|
writeF1000(os, automatic_rotate);
|
||||||
|
// Added in protocol version 14
|
||||||
|
os<<serializeString(mesh);
|
||||||
|
writeU16(os, colors.size());
|
||||||
|
for(u32 i=0; i<colors.size(); i++){
|
||||||
|
writeARGB8(os, colors[i]);
|
||||||
|
}
|
||||||
|
// Add stuff only at the bottom.
|
||||||
|
// Never remove anything, because we don't want new versions of this
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectProperties::deSerialize(std::istream &is)
|
void ObjectProperties::deSerialize(std::istream &is)
|
||||||
{
|
{
|
||||||
int version = readU8(is);
|
int version = readU8(is);
|
||||||
if(version != 1) throw SerializationError(
|
if(version == 1)
|
||||||
"unsupported ObjectProperties version");
|
{
|
||||||
hp_max = readS16(is);
|
try{
|
||||||
physical = readU8(is);
|
hp_max = readS16(is);
|
||||||
weight = readF1000(is);
|
physical = readU8(is);
|
||||||
collisionbox.MinEdge = readV3F1000(is);
|
weight = readF1000(is);
|
||||||
collisionbox.MaxEdge = readV3F1000(is);
|
collisionbox.MinEdge = readV3F1000(is);
|
||||||
visual = deSerializeString(is);
|
collisionbox.MaxEdge = readV3F1000(is);
|
||||||
mesh = deSerializeString(is);
|
visual = deSerializeString(is);
|
||||||
visual_size = readV2F1000(is);
|
visual_size = readV2F1000(is);
|
||||||
textures.clear();
|
textures.clear();
|
||||||
u32 texture_count = readU16(is);
|
u32 texture_count = readU16(is);
|
||||||
for(u32 i=0; i<texture_count; i++){
|
for(u32 i=0; i<texture_count; i++){
|
||||||
textures.push_back(deSerializeString(is));
|
textures.push_back(deSerializeString(is));
|
||||||
|
}
|
||||||
|
spritediv = readV2S16(is);
|
||||||
|
initial_sprite_basepos = readV2S16(is);
|
||||||
|
is_visible = readU8(is);
|
||||||
|
makes_footstep_sound = readU8(is);
|
||||||
|
automatic_rotate = readF1000(is);
|
||||||
|
mesh = deSerializeString(is);
|
||||||
|
u32 color_count = readU16(is);
|
||||||
|
for(u32 i=0; i<color_count; i++){
|
||||||
|
colors.push_back(readARGB8(is));
|
||||||
|
}
|
||||||
|
}catch(SerializationError &e){}
|
||||||
}
|
}
|
||||||
u32 color_count = readU16(is);
|
else
|
||||||
for(u32 i=0; i<color_count; i++){
|
{
|
||||||
colors.push_back(readARGB8(is));
|
throw SerializationError("unsupported ObjectProperties version");
|
||||||
}
|
}
|
||||||
spritediv = readV2S16(is);
|
|
||||||
initial_sprite_basepos = readV2S16(is);
|
|
||||||
is_visible = readU8(is);
|
|
||||||
makes_footstep_sound = readU8(is);
|
|
||||||
try{
|
|
||||||
automatic_rotate = readF1000(is);
|
|
||||||
}catch(SerializationError &e){}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5576,6 +5576,19 @@ bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
|
||||||
return ate;
|
return ate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scriptapi_on_shutdown(lua_State *L)
|
||||||
|
{
|
||||||
|
realitycheck(L);
|
||||||
|
assert(lua_checkstack(L, 20));
|
||||||
|
StackUnroller stack_unroller(L);
|
||||||
|
|
||||||
|
// Get registered shutdown hooks
|
||||||
|
lua_getglobal(L, "minetest");
|
||||||
|
lua_getfield(L, -1, "registered_on_shutdown");
|
||||||
|
// Call callbacks
|
||||||
|
scriptapi_run_callbacks(L, 0, RUN_CALLBACKS_MODE_FIRST);
|
||||||
|
}
|
||||||
|
|
||||||
void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
|
void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
|
||||||
{
|
{
|
||||||
realitycheck(L);
|
realitycheck(L);
|
||||||
|
|
|
@ -55,6 +55,9 @@ void scriptapi_environment_step(lua_State *L, float dtime);
|
||||||
void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp,
|
void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp,
|
||||||
u32 blockseed);
|
u32 blockseed);
|
||||||
|
|
||||||
|
/* server */
|
||||||
|
void scriptapi_on_shutdown(lua_State *L);
|
||||||
|
|
||||||
/* misc */
|
/* misc */
|
||||||
void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player);
|
void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player);
|
||||||
void scriptapi_on_dieplayer(lua_State *L, ServerActiveObject *player);
|
void scriptapi_on_dieplayer(lua_State *L, ServerActiveObject *player);
|
||||||
|
|
104
src/server.cpp
104
src/server.cpp
|
@ -54,6 +54,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "util/pointedthing.h"
|
#include "util/pointedthing.h"
|
||||||
#include "util/mathconstants.h"
|
#include "util/mathconstants.h"
|
||||||
#include "rollback.h"
|
#include "rollback.h"
|
||||||
|
#include "util/serialize.h"
|
||||||
|
|
||||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||||
|
|
||||||
|
@ -1111,7 +1112,17 @@ Server::~Server()
|
||||||
{}
|
{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
JMutexAutoLock envlock(m_env_mutex);
|
||||||
|
JMutexAutoLock conlock(m_con_mutex);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Execute script shutdown hooks
|
||||||
|
*/
|
||||||
|
scriptapi_on_shutdown(m_lua);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
JMutexAutoLock envlock(m_env_mutex);
|
JMutexAutoLock envlock(m_env_mutex);
|
||||||
|
|
||||||
|
@ -1143,14 +1154,6 @@ Server::~Server()
|
||||||
i = m_clients.getIterator();
|
i = m_clients.getIterator();
|
||||||
i.atEnd() == false; i++)
|
i.atEnd() == false; i++)
|
||||||
{
|
{
|
||||||
/*// Delete player
|
|
||||||
// NOTE: These are removed by env destructor
|
|
||||||
{
|
|
||||||
u16 peer_id = i.getNode()->getKey();
|
|
||||||
JMutexAutoLock envlock(m_env_mutex);
|
|
||||||
m_env->removePlayer(peer_id);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Delete client
|
// Delete client
|
||||||
delete i.getNode()->getValue();
|
delete i.getNode()->getValue();
|
||||||
}
|
}
|
||||||
|
@ -1567,7 +1570,7 @@ void Server::AsyncRunStep()
|
||||||
|
|
||||||
if(obj)
|
if(obj)
|
||||||
data_buffer.append(serializeLongString(
|
data_buffer.append(serializeLongString(
|
||||||
obj->getClientInitializationData()));
|
obj->getClientInitializationData(client->net_proto_version)));
|
||||||
else
|
else
|
||||||
data_buffer.append(serializeLongString(""));
|
data_buffer.append(serializeLongString(""));
|
||||||
|
|
||||||
|
@ -2037,40 +2040,74 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
Read and check network protocol version
|
Read and check network protocol version
|
||||||
*/
|
*/
|
||||||
|
|
||||||
u16 net_proto_version = 0;
|
u16 min_net_proto_version = 0;
|
||||||
if(datasize >= 2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2)
|
if(datasize >= 2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2)
|
||||||
|
min_net_proto_version = readU16(&data[2+1+PLAYERNAME_SIZE+PASSWORD_SIZE]);
|
||||||
|
|
||||||
|
// Use same version as minimum and maximum if maximum version field
|
||||||
|
// doesn't exist (backwards compatibility)
|
||||||
|
u16 max_net_proto_version = min_net_proto_version;
|
||||||
|
if(datasize >= 2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2+2)
|
||||||
|
max_net_proto_version = readU16(&data[2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2]);
|
||||||
|
|
||||||
|
// Start with client's maximum version
|
||||||
|
u16 net_proto_version = max_net_proto_version;
|
||||||
|
|
||||||
|
// Figure out a working version if it is possible at all
|
||||||
|
if(max_net_proto_version >= SERVER_PROTOCOL_VERSION_MIN ||
|
||||||
|
min_net_proto_version <= SERVER_PROTOCOL_VERSION_MAX)
|
||||||
{
|
{
|
||||||
net_proto_version = readU16(&data[2+1+PLAYERNAME_SIZE+PASSWORD_SIZE]);
|
// If maximum is larger than our maximum, go with our maximum
|
||||||
|
if(max_net_proto_version > SERVER_PROTOCOL_VERSION_MAX)
|
||||||
|
net_proto_version = SERVER_PROTOCOL_VERSION_MAX;
|
||||||
|
// Else go with client's maximum
|
||||||
|
else
|
||||||
|
net_proto_version = max_net_proto_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
verbosestream<<"Server: "<<peer_id<<" Protocol version: min: "
|
||||||
|
<<min_net_proto_version<<", max: "<<max_net_proto_version
|
||||||
|
<<", chosen: "<<net_proto_version<<std::endl;
|
||||||
|
|
||||||
getClient(peer_id)->net_proto_version = net_proto_version;
|
getClient(peer_id)->net_proto_version = net_proto_version;
|
||||||
|
|
||||||
if(net_proto_version == 0)
|
if(net_proto_version < SERVER_PROTOCOL_VERSION_MIN ||
|
||||||
|
net_proto_version > SERVER_PROTOCOL_VERSION_MAX)
|
||||||
{
|
{
|
||||||
actionstream<<"Server: An old tried to connect from "<<addr_s
|
actionstream<<"Server: A mismatched client tried to connect from "<<addr_s
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
SendAccessDenied(m_con, peer_id, std::wstring(
|
SendAccessDenied(m_con, peer_id, std::wstring(
|
||||||
L"Your client's version is not supported.\n"
|
L"Your client's version is not supported.\n"
|
||||||
L"Server version is ")
|
L"Server version is ")
|
||||||
+ narrow_to_wide(VERSION_STRING) + L"."
|
+ narrow_to_wide(VERSION_STRING) + L",\n"
|
||||||
|
+ L"server's PROTOCOL_VERSION is "
|
||||||
|
+ narrow_to_wide(itos(SERVER_PROTOCOL_VERSION_MIN))
|
||||||
|
+ L"..."
|
||||||
|
+ narrow_to_wide(itos(SERVER_PROTOCOL_VERSION_MAX))
|
||||||
|
+ L", client's PROTOCOL_VERSION is "
|
||||||
|
+ narrow_to_wide(itos(min_net_proto_version))
|
||||||
|
+ L"..."
|
||||||
|
+ narrow_to_wide(itos(max_net_proto_version))
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(g_settings->getBool("strict_protocol_version_checking"))
|
if(g_settings->getBool("strict_protocol_version_checking"))
|
||||||
{
|
{
|
||||||
if(net_proto_version != PROTOCOL_VERSION)
|
if(net_proto_version != LATEST_PROTOCOL_VERSION)
|
||||||
{
|
{
|
||||||
actionstream<<"Server: A mismatched client tried to connect"
|
actionstream<<"Server: A mismatched (strict) client tried to "
|
||||||
<<" from "<<addr_s<<std::endl;
|
<<"connect from "<<addr_s<<std::endl;
|
||||||
SendAccessDenied(m_con, peer_id, std::wstring(
|
SendAccessDenied(m_con, peer_id, std::wstring(
|
||||||
L"Your client's version is not supported.\n"
|
L"Your client's version is not supported.\n"
|
||||||
L"Server version is ")
|
L"Server version is ")
|
||||||
+ narrow_to_wide(VERSION_STRING) + L",\n"
|
+ narrow_to_wide(VERSION_STRING) + L",\n"
|
||||||
+ L"server's PROTOCOL_VERSION is "
|
+ L"server's PROTOCOL_VERSION (strict) is "
|
||||||
+ narrow_to_wide(itos(PROTOCOL_VERSION))
|
+ narrow_to_wide(itos(LATEST_PROTOCOL_VERSION))
|
||||||
+ L", client's PROTOCOL_VERSION is "
|
+ L", client's PROTOCOL_VERSION is "
|
||||||
+ narrow_to_wide(itos(net_proto_version))
|
+ narrow_to_wide(itos(min_net_proto_version))
|
||||||
|
+ L"..."
|
||||||
|
+ narrow_to_wide(itos(max_net_proto_version))
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2212,11 +2249,12 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
Answer with a TOCLIENT_INIT
|
Answer with a TOCLIENT_INIT
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
SharedBuffer<u8> reply(2+1+6+8);
|
SharedBuffer<u8> reply(2+1+6+8+4);
|
||||||
writeU16(&reply[0], TOCLIENT_INIT);
|
writeU16(&reply[0], TOCLIENT_INIT);
|
||||||
writeU8(&reply[2], deployed);
|
writeU8(&reply[2], deployed);
|
||||||
writeV3S16(&reply[2+1], floatToInt(playersao->getPlayer()->getPosition()+v3f(0,BS/2,0), BS));
|
writeV3S16(&reply[2+1], floatToInt(playersao->getPlayer()->getPosition()+v3f(0,BS/2,0), BS));
|
||||||
writeU64(&reply[2+1+6], m_env->getServerMap().getSeed());
|
writeU64(&reply[2+1+6], m_env->getServerMap().getSeed());
|
||||||
|
writeF1000(&reply[2+1+6+8], g_settings->getFloat("dedicated_server_step"));
|
||||||
|
|
||||||
// Send as reliable
|
// Send as reliable
|
||||||
m_con.Send(peer_id, 0, reply, true);
|
m_con.Send(peer_id, 0, reply, true);
|
||||||
|
@ -2242,8 +2280,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
getClient(peer_id)->serialization_version
|
RemoteClient *client = getClient(peer_id);
|
||||||
= getClient(peer_id)->pending_serialization_version;
|
client->serialization_version =
|
||||||
|
getClient(peer_id)->pending_serialization_version;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Send some initialization data
|
Send some initialization data
|
||||||
|
@ -2256,7 +2295,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
SendItemDef(m_con, peer_id, m_itemdef);
|
SendItemDef(m_con, peer_id, m_itemdef);
|
||||||
|
|
||||||
// Send node definitions
|
// Send node definitions
|
||||||
SendNodeDef(m_con, peer_id, m_nodedef);
|
SendNodeDef(m_con, peer_id, m_nodedef, client->net_proto_version);
|
||||||
|
|
||||||
// Send media announcement
|
// Send media announcement
|
||||||
sendMediaAnnouncement(peer_id);
|
sendMediaAnnouncement(peer_id);
|
||||||
|
@ -2310,9 +2349,10 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warnings about protocol version can be issued here
|
// Warnings about protocol version can be issued here
|
||||||
if(getClient(peer_id)->net_proto_version < PROTOCOL_VERSION)
|
if(getClient(peer_id)->net_proto_version < LATEST_PROTOCOL_VERSION)
|
||||||
{
|
{
|
||||||
SendChatMessage(peer_id, L"# Server: WARNING: YOUR CLIENT IS OLD AND MAY WORK PROPERLY WITH THIS SERVER!");
|
SendChatMessage(peer_id, L"# Server: WARNING: YOUR CLIENT'S "
|
||||||
|
L"VERSION MAY NOT BE FULLY COMPATIBLE WITH THIS SERVER!");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2369,7 +2409,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
|
|
||||||
if(command == TOSERVER_PLAYERPOS)
|
if(command == TOSERVER_PLAYERPOS)
|
||||||
{
|
{
|
||||||
if(datasize < 2+12+12+4+4+4)
|
if(datasize < 2+12+12+4+4)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
u32 start = 0;
|
u32 start = 0;
|
||||||
|
@ -2377,7 +2417,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
v3s32 ss = readV3S32(&data[start+2+12]);
|
v3s32 ss = readV3S32(&data[start+2+12]);
|
||||||
f32 pitch = (f32)readS32(&data[2+12+12]) / 100.0;
|
f32 pitch = (f32)readS32(&data[2+12+12]) / 100.0;
|
||||||
f32 yaw = (f32)readS32(&data[2+12+12+4]) / 100.0;
|
f32 yaw = (f32)readS32(&data[2+12+12+4]) / 100.0;
|
||||||
u32 keyPressed = (u32)readU32(&data[2+12+12+4+4]);
|
u32 keyPressed = 0;
|
||||||
|
if(datasize >= 2+12+12+4+4+4)
|
||||||
|
keyPressed = (u32)readU32(&data[2+12+12+4+4]);
|
||||||
v3f position((f32)ps.X/100., (f32)ps.Y/100., (f32)ps.Z/100.);
|
v3f position((f32)ps.X/100., (f32)ps.Y/100., (f32)ps.Z/100.);
|
||||||
v3f speed((f32)ss.X/100., (f32)ss.Y/100., (f32)ss.Z/100.);
|
v3f speed((f32)ss.X/100., (f32)ss.Y/100., (f32)ss.Z/100.);
|
||||||
pitch = wrapDegrees(pitch);
|
pitch = wrapDegrees(pitch);
|
||||||
|
@ -3508,7 +3550,7 @@ void Server::SendItemDef(con::Connection &con, u16 peer_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::SendNodeDef(con::Connection &con, u16 peer_id,
|
void Server::SendNodeDef(con::Connection &con, u16 peer_id,
|
||||||
INodeDefManager *nodedef)
|
INodeDefManager *nodedef, u16 protocol_version)
|
||||||
{
|
{
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
std::ostringstream os(std::ios_base::binary);
|
std::ostringstream os(std::ios_base::binary);
|
||||||
|
@ -3520,7 +3562,7 @@ void Server::SendNodeDef(con::Connection &con, u16 peer_id,
|
||||||
*/
|
*/
|
||||||
writeU16(os, TOCLIENT_NODEDEF);
|
writeU16(os, TOCLIENT_NODEDEF);
|
||||||
std::ostringstream tmp_os(std::ios::binary);
|
std::ostringstream tmp_os(std::ios::binary);
|
||||||
nodedef->serialize(tmp_os);
|
nodedef->serialize(tmp_os, protocol_version);
|
||||||
std::ostringstream tmp_os2(std::ios::binary);
|
std::ostringstream tmp_os2(std::ios::binary);
|
||||||
compressZlib(tmp_os.str(), tmp_os2);
|
compressZlib(tmp_os.str(), tmp_os2);
|
||||||
os<<serializeLongString(tmp_os2.str());
|
os<<serializeLongString(tmp_os2.str());
|
||||||
|
|
|
@ -602,7 +602,7 @@ private:
|
||||||
static void SendItemDef(con::Connection &con, u16 peer_id,
|
static void SendItemDef(con::Connection &con, u16 peer_id,
|
||||||
IItemDefManager *itemdef);
|
IItemDefManager *itemdef);
|
||||||
static void SendNodeDef(con::Connection &con, u16 peer_id,
|
static void SendNodeDef(con::Connection &con, u16 peer_id,
|
||||||
INodeDefManager *nodedef);
|
INodeDefManager *nodedef, u16 protocol_version);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Non-static send methods.
|
Non-static send methods.
|
||||||
|
|
|
@ -118,7 +118,7 @@ public:
|
||||||
The return value of this is passed to the client-side object
|
The return value of this is passed to the client-side object
|
||||||
when it is created
|
when it is created
|
||||||
*/
|
*/
|
||||||
virtual std::string getClientInitializationData(){return "";}
|
virtual std::string getClientInitializationData(u16 protocol_version){return "";}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The return value of this is passed to the server-side object
|
The return value of this is passed to the server-side object
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
Minetest-c55
|
||||||
|
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "staticobject.h"
|
||||||
|
#include "util/serialize.h"
|
||||||
|
|
||||||
|
void StaticObject::serialize(std::ostream &os)
|
||||||
|
{
|
||||||
|
char buf[12];
|
||||||
|
// type
|
||||||
|
buf[0] = type;
|
||||||
|
os.write(buf, 1);
|
||||||
|
// pos
|
||||||
|
writeV3S32((u8*)buf, v3s32(pos.X*1000,pos.Y*1000,pos.Z*1000));
|
||||||
|
os.write(buf, 12);
|
||||||
|
// data
|
||||||
|
os<<serializeString(data);
|
||||||
|
}
|
||||||
|
void StaticObject::deSerialize(std::istream &is, u8 version)
|
||||||
|
{
|
||||||
|
char buf[12];
|
||||||
|
// type
|
||||||
|
is.read(buf, 1);
|
||||||
|
type = buf[0];
|
||||||
|
// pos
|
||||||
|
is.read(buf, 12);
|
||||||
|
v3s32 intp = readV3S32((u8*)buf);
|
||||||
|
pos.X = (f32)intp.X/1000;
|
||||||
|
pos.Y = (f32)intp.Y/1000;
|
||||||
|
pos.Z = (f32)intp.Z/1000;
|
||||||
|
// data
|
||||||
|
data = deSerializeString(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StaticObjectList::serialize(std::ostream &os)
|
||||||
|
{
|
||||||
|
char buf[12];
|
||||||
|
// version
|
||||||
|
buf[0] = 0;
|
||||||
|
os.write(buf, 1);
|
||||||
|
// count
|
||||||
|
u16 count = m_stored.size() + m_active.size();
|
||||||
|
writeU16((u8*)buf, count);
|
||||||
|
os.write(buf, 2);
|
||||||
|
for(core::list<StaticObject>::Iterator
|
||||||
|
i = m_stored.begin();
|
||||||
|
i != m_stored.end(); i++)
|
||||||
|
{
|
||||||
|
StaticObject &s_obj = *i;
|
||||||
|
s_obj.serialize(os);
|
||||||
|
}
|
||||||
|
for(core::map<u16, StaticObject>::Iterator
|
||||||
|
i = m_active.getIterator();
|
||||||
|
i.atEnd()==false; i++)
|
||||||
|
{
|
||||||
|
StaticObject s_obj = i.getNode()->getValue();
|
||||||
|
s_obj.serialize(os);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void StaticObjectList::deSerialize(std::istream &is)
|
||||||
|
{
|
||||||
|
char buf[12];
|
||||||
|
// version
|
||||||
|
is.read(buf, 1);
|
||||||
|
u8 version = buf[0];
|
||||||
|
// count
|
||||||
|
is.read(buf, 2);
|
||||||
|
u16 count = readU16((u8*)buf);
|
||||||
|
for(u16 i=0; i<count; i++)
|
||||||
|
{
|
||||||
|
StaticObject s_obj;
|
||||||
|
s_obj.deSerialize(is, version);
|
||||||
|
m_stored.push_back(s_obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "irrlichttypes_bloated.h"
|
#include "irrlichttypes_bloated.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "util/serialize.h"
|
#include "debug.h"
|
||||||
|
|
||||||
struct StaticObject
|
struct StaticObject
|
||||||
{
|
{
|
||||||
|
@ -43,33 +43,8 @@ struct StaticObject
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(std::ostream &os)
|
void serialize(std::ostream &os);
|
||||||
{
|
void deSerialize(std::istream &is, u8 version);
|
||||||
char buf[12];
|
|
||||||
// type
|
|
||||||
buf[0] = type;
|
|
||||||
os.write(buf, 1);
|
|
||||||
// pos
|
|
||||||
writeV3S32((u8*)buf, v3s32(pos.X*1000,pos.Y*1000,pos.Z*1000));
|
|
||||||
os.write(buf, 12);
|
|
||||||
// data
|
|
||||||
os<<serializeString(data);
|
|
||||||
}
|
|
||||||
void deSerialize(std::istream &is, u8 version)
|
|
||||||
{
|
|
||||||
char buf[12];
|
|
||||||
// type
|
|
||||||
is.read(buf, 1);
|
|
||||||
type = buf[0];
|
|
||||||
// pos
|
|
||||||
is.read(buf, 12);
|
|
||||||
v3s32 intp = readV3S32((u8*)buf);
|
|
||||||
pos.X = (f32)intp.X/1000;
|
|
||||||
pos.Y = (f32)intp.Y/1000;
|
|
||||||
pos.Z = (f32)intp.Z/1000;
|
|
||||||
// data
|
|
||||||
data = deSerializeString(is);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class StaticObjectList
|
class StaticObjectList
|
||||||
|
@ -110,47 +85,8 @@ public:
|
||||||
m_active.remove(id);
|
m_active.remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialize(std::ostream &os)
|
void serialize(std::ostream &os);
|
||||||
{
|
void deSerialize(std::istream &is);
|
||||||
char buf[12];
|
|
||||||
// version
|
|
||||||
buf[0] = 0;
|
|
||||||
os.write(buf, 1);
|
|
||||||
// count
|
|
||||||
u16 count = m_stored.size() + m_active.size();
|
|
||||||
writeU16((u8*)buf, count);
|
|
||||||
os.write(buf, 2);
|
|
||||||
for(core::list<StaticObject>::Iterator
|
|
||||||
i = m_stored.begin();
|
|
||||||
i != m_stored.end(); i++)
|
|
||||||
{
|
|
||||||
StaticObject &s_obj = *i;
|
|
||||||
s_obj.serialize(os);
|
|
||||||
}
|
|
||||||
for(core::map<u16, StaticObject>::Iterator
|
|
||||||
i = m_active.getIterator();
|
|
||||||
i.atEnd()==false; i++)
|
|
||||||
{
|
|
||||||
StaticObject s_obj = i.getNode()->getValue();
|
|
||||||
s_obj.serialize(os);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void deSerialize(std::istream &is)
|
|
||||||
{
|
|
||||||
char buf[12];
|
|
||||||
// version
|
|
||||||
is.read(buf, 1);
|
|
||||||
u8 version = buf[0];
|
|
||||||
// count
|
|
||||||
is.read(buf, 2);
|
|
||||||
u16 count = readU16((u8*)buf);
|
|
||||||
for(u16 i=0; i<count; i++)
|
|
||||||
{
|
|
||||||
StaticObject s_obj;
|
|
||||||
s_obj.deSerialize(is, version);
|
|
||||||
m_stored.push_back(s_obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NOTE: When an object is transformed to active, it is removed
|
NOTE: When an object is transformed to active, it is removed
|
||||||
|
|
22
src/test.cpp
22
src/test.cpp
|
@ -41,6 +41,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "util/numeric.h"
|
#include "util/numeric.h"
|
||||||
#include "util/serialize.h"
|
#include "util/serialize.h"
|
||||||
#include "noise.h" // PseudoRandom used for random data for compression
|
#include "noise.h" // PseudoRandom used for random data for compression
|
||||||
|
#include "clientserver.h" // LATEST_PROTOCOL_VERSION
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Asserts that the exception occurs
|
Asserts that the exception occurs
|
||||||
|
@ -314,6 +315,26 @@ struct TestSerialization: public TestBase
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TestNodedefSerialization: public TestBase
|
||||||
|
{
|
||||||
|
void Run()
|
||||||
|
{
|
||||||
|
ContentFeatures f;
|
||||||
|
f.name = "default:stone";
|
||||||
|
for(int i = 0; i < 6; i++)
|
||||||
|
f.tiledef[i].name = "default_stone.png";
|
||||||
|
f.is_ground_content = true;
|
||||||
|
std::ostringstream os(std::ios::binary);
|
||||||
|
f.serialize(os, LATEST_PROTOCOL_VERSION);
|
||||||
|
verbosestream<<"Test ContentFeatures size: "<<os.str().size()<<std::endl;
|
||||||
|
std::istringstream is(os.str(), std::ios::binary);
|
||||||
|
ContentFeatures f2;
|
||||||
|
f2.deSerialize(is);
|
||||||
|
UASSERT(f.walkable == f2.walkable);
|
||||||
|
UASSERT(f.node_box.type == f2.node_box.type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct TestCompress: public TestBase
|
struct TestCompress: public TestBase
|
||||||
{
|
{
|
||||||
void Run()
|
void Run()
|
||||||
|
@ -1736,6 +1757,7 @@ void run_tests()
|
||||||
TEST(TestSettings);
|
TEST(TestSettings);
|
||||||
TEST(TestCompress);
|
TEST(TestCompress);
|
||||||
TEST(TestSerialization);
|
TEST(TestSerialization);
|
||||||
|
TEST(TestNodedefSerialization);
|
||||||
TESTPARAMS(TestMapNode, ndef);
|
TESTPARAMS(TestMapNode, ndef);
|
||||||
TESTPARAMS(TestVoxelManipulator, ndef);
|
TESTPARAMS(TestVoxelManipulator, ndef);
|
||||||
TESTPARAMS(TestVoxelAlgorithms, ndef);
|
TESTPARAMS(TestVoxelAlgorithms, ndef);
|
||||||
|
|
16
src/tile.cpp
16
src/tile.cpp
|
@ -372,6 +372,18 @@ public:
|
||||||
// Update new texture pointer and texture coordinates to an
|
// Update new texture pointer and texture coordinates to an
|
||||||
// AtlasPointer based on it's texture id
|
// AtlasPointer based on it's texture id
|
||||||
void updateAP(AtlasPointer &ap);
|
void updateAP(AtlasPointer &ap);
|
||||||
|
|
||||||
|
bool isKnownSourceImage(const std::string &name)
|
||||||
|
{
|
||||||
|
bool is_known = false;
|
||||||
|
bool cache_found = m_source_image_existence.get(name, &is_known);
|
||||||
|
if(cache_found)
|
||||||
|
return is_known;
|
||||||
|
// Not found in cache; find out if a local file exists
|
||||||
|
is_known = (getTexturePath(name) != "");
|
||||||
|
m_source_image_existence.set(name, is_known);
|
||||||
|
return is_known;
|
||||||
|
}
|
||||||
|
|
||||||
// Processes queued texture requests from other threads.
|
// Processes queued texture requests from other threads.
|
||||||
// Shall be called from the main thread.
|
// Shall be called from the main thread.
|
||||||
|
@ -400,6 +412,9 @@ private:
|
||||||
// This should be only accessed from the main thread
|
// This should be only accessed from the main thread
|
||||||
SourceImageCache m_sourcecache;
|
SourceImageCache m_sourcecache;
|
||||||
|
|
||||||
|
// Thread-safe cache of what source images are known (true = known)
|
||||||
|
MutexedMap<std::string, bool> m_source_image_existence;
|
||||||
|
|
||||||
// A texture id is index in this array.
|
// A texture id is index in this array.
|
||||||
// The first position contains a NULL texture.
|
// The first position contains a NULL texture.
|
||||||
core::array<SourceAtlasPointer> m_atlaspointer_cache;
|
core::array<SourceAtlasPointer> m_atlaspointer_cache;
|
||||||
|
@ -781,6 +796,7 @@ void TextureSource::insertSourceImage(const std::string &name, video::IImage *im
|
||||||
assert(get_current_thread_id() == m_main_thread);
|
assert(get_current_thread_id() == m_main_thread);
|
||||||
|
|
||||||
m_sourcecache.insert(name, img, true, m_device->getVideoDriver());
|
m_sourcecache.insert(name, img, true, m_device->getVideoDriver());
|
||||||
|
m_source_image_existence.set(name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureSource::rebuildImagesAndTextures()
|
void TextureSource::rebuildImagesAndTextures()
|
||||||
|
|
|
@ -131,6 +131,7 @@ public:
|
||||||
virtual IrrlichtDevice* getDevice()
|
virtual IrrlichtDevice* getDevice()
|
||||||
{return NULL;}
|
{return NULL;}
|
||||||
virtual void updateAP(AtlasPointer &ap){};
|
virtual void updateAP(AtlasPointer &ap){};
|
||||||
|
virtual bool isKnownSourceImage(const std::string &name)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IWritableTextureSource : public ITextureSource
|
class IWritableTextureSource : public ITextureSource
|
||||||
|
@ -149,6 +150,7 @@ public:
|
||||||
virtual IrrlichtDevice* getDevice()
|
virtual IrrlichtDevice* getDevice()
|
||||||
{return NULL;}
|
{return NULL;}
|
||||||
virtual void updateAP(AtlasPointer &ap){};
|
virtual void updateAP(AtlasPointer &ap){};
|
||||||
|
virtual bool isKnownSourceImage(const std::string &name)=0;
|
||||||
|
|
||||||
virtual void processQueue()=0;
|
virtual void processQueue()=0;
|
||||||
virtual void insertSourceImage(const std::string &name, video::IImage *img)=0;
|
virtual void insertSourceImage(const std::string &name, video::IImage *img)=0;
|
||||||
|
|
|
@ -222,7 +222,7 @@ public:
|
||||||
/*
|
/*
|
||||||
Copies whole buffer
|
Copies whole buffer
|
||||||
*/
|
*/
|
||||||
SharedBuffer(T *t, unsigned int size)
|
SharedBuffer(const T *t, unsigned int size)
|
||||||
{
|
{
|
||||||
m_size = size;
|
m_size = size;
|
||||||
if(m_size != 0)
|
if(m_size != 0)
|
||||||
|
|
Loading…
Reference in New Issue