mirror of
https://github.com/minetest/minetest.git
synced 2024-09-12 00:26:50 +02:00
Clean up rollback
This commit is contained in:
parent
da0f1e5497
commit
b1965ac209
@ -30,7 +30,7 @@ class ITextureSource;
|
|||||||
class ISoundManager;
|
class ISoundManager;
|
||||||
class IShaderSource;
|
class IShaderSource;
|
||||||
class MtEventManager;
|
class MtEventManager;
|
||||||
class IRollbackReportSink;
|
class IRollbackManager;
|
||||||
namespace irr { namespace scene {
|
namespace irr { namespace scene {
|
||||||
class IAnimatedMesh;
|
class IAnimatedMesh;
|
||||||
class ISceneManager;
|
class ISceneManager;
|
||||||
@ -68,7 +68,7 @@ public:
|
|||||||
|
|
||||||
// Only usable on the server, and NOT thread-safe. It is usable from the
|
// Only usable on the server, and NOT thread-safe. It is usable from the
|
||||||
// environment thread.
|
// environment thread.
|
||||||
virtual IRollbackReportSink* getRollbackReportSink(){return NULL;}
|
virtual IRollbackManager* getRollbackManager(){return NULL;}
|
||||||
|
|
||||||
// Used on the client
|
// Used on the client
|
||||||
virtual bool checkLocalPrivilege(const std::string &priv)
|
virtual bool checkLocalPrivilege(const std::string &priv)
|
||||||
@ -82,7 +82,7 @@ public:
|
|||||||
ISoundManager* sound(){return getSoundManager();}
|
ISoundManager* sound(){return getSoundManager();}
|
||||||
IShaderSource* shsrc(){return getShaderSource();}
|
IShaderSource* shsrc(){return getShaderSource();}
|
||||||
MtEventManager* event(){return getEventManager();}
|
MtEventManager* event(){return getEventManager();}
|
||||||
IRollbackReportSink* rollback(){return getRollbackReportSink();}
|
IRollbackManager* rollback(){return getRollbackManager();}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -183,7 +183,8 @@ void ItemStack::deSerialize(std::istream &is, IItemDefManager *itemdef)
|
|||||||
legacy_nimap.getName(material, name);
|
legacy_nimap.getName(material, name);
|
||||||
if(name == "")
|
if(name == "")
|
||||||
name = "unknown_block";
|
name = "unknown_block";
|
||||||
name = itemdef->getAlias(name);
|
if (itemdef)
|
||||||
|
name = itemdef->getAlias(name);
|
||||||
count = materialcount;
|
count = materialcount;
|
||||||
}
|
}
|
||||||
else if(name == "MaterialItem2")
|
else if(name == "MaterialItem2")
|
||||||
@ -202,7 +203,8 @@ void ItemStack::deSerialize(std::istream &is, IItemDefManager *itemdef)
|
|||||||
legacy_nimap.getName(material, name);
|
legacy_nimap.getName(material, name);
|
||||||
if(name == "")
|
if(name == "")
|
||||||
name = "unknown_block";
|
name = "unknown_block";
|
||||||
name = itemdef->getAlias(name);
|
if (itemdef)
|
||||||
|
name = itemdef->getAlias(name);
|
||||||
count = materialcount;
|
count = materialcount;
|
||||||
}
|
}
|
||||||
else if(name == "node" || name == "NodeItem" || name == "MaterialItem3"
|
else if(name == "node" || name == "NodeItem" || name == "MaterialItem3"
|
||||||
@ -223,7 +225,8 @@ void ItemStack::deSerialize(std::istream &is, IItemDefManager *itemdef)
|
|||||||
name = fnd.next(" ");
|
name = fnd.next(" ");
|
||||||
}
|
}
|
||||||
fnd.skip_over(" ");
|
fnd.skip_over(" ");
|
||||||
name = itemdef->getAlias(name);
|
if (itemdef)
|
||||||
|
name = itemdef->getAlias(name);
|
||||||
count = stoi(trim(fnd.next("")));
|
count = stoi(trim(fnd.next("")));
|
||||||
if(count == 0)
|
if(count == 0)
|
||||||
count = 1;
|
count = 1;
|
||||||
@ -252,7 +255,8 @@ void ItemStack::deSerialize(std::istream &is, IItemDefManager *itemdef)
|
|||||||
count = 1;
|
count = 1;
|
||||||
// Then read wear
|
// Then read wear
|
||||||
fnd.skip_over(" ");
|
fnd.skip_over(" ");
|
||||||
name = itemdef->getAlias(name);
|
if (itemdef)
|
||||||
|
name = itemdef->getAlias(name);
|
||||||
wear = stoi(trim(fnd.next("")));
|
wear = stoi(trim(fnd.next("")));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -262,7 +266,8 @@ void ItemStack::deSerialize(std::istream &is, IItemDefManager *itemdef)
|
|||||||
// The real thing
|
// The real thing
|
||||||
|
|
||||||
// Apply item aliases
|
// Apply item aliases
|
||||||
name = itemdef->getAlias(name);
|
if (itemdef)
|
||||||
|
name = itemdef->getAlias(name);
|
||||||
|
|
||||||
// Read the count
|
// Read the count
|
||||||
std::string count_str;
|
std::string count_str;
|
||||||
@ -294,9 +299,9 @@ void ItemStack::deSerialize(std::istream &is, IItemDefManager *itemdef)
|
|||||||
} while(false);
|
} while(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(name.empty() || count == 0)
|
if (name.empty() || count == 0)
|
||||||
clear();
|
clear();
|
||||||
else if(itemdef->get(name).type == ITEM_TOOL)
|
else if (itemdef && itemdef->get(name).type == ITEM_TOOL)
|
||||||
count = 1;
|
count = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,12 +313,12 @@ void ItemStack::deSerialize(const std::string &str, IItemDefManager *itemdef)
|
|||||||
|
|
||||||
std::string ItemStack::getItemString() const
|
std::string ItemStack::getItemString() const
|
||||||
{
|
{
|
||||||
// Get item string
|
|
||||||
std::ostringstream os(std::ios::binary);
|
std::ostringstream os(std::ios::binary);
|
||||||
serialize(os);
|
serialize(os);
|
||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ItemStack ItemStack::addItem(const ItemStack &newitem_,
|
ItemStack ItemStack::addItem(const ItemStack &newitem_,
|
||||||
IItemDefManager *itemdef)
|
IItemDefManager *itemdef)
|
||||||
{
|
{
|
||||||
|
@ -20,12 +20,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#ifndef INVENTORY_HEADER
|
#ifndef INVENTORY_HEADER
|
||||||
#define INVENTORY_HEADER
|
#define INVENTORY_HEADER
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include "irrlichttypes.h"
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "itemdef.h"
|
#include "itemdef.h"
|
||||||
|
#include "irrlichttypes.h"
|
||||||
|
#include <istream>
|
||||||
|
#include <ostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
struct ToolCapabilities;
|
struct ToolCapabilities;
|
||||||
|
|
||||||
@ -39,8 +40,9 @@ struct ItemStack
|
|||||||
|
|
||||||
// Serialization
|
// Serialization
|
||||||
void serialize(std::ostream &os) const;
|
void serialize(std::ostream &os) const;
|
||||||
void deSerialize(std::istream &is, IItemDefManager *itemdef);
|
// Deserialization. Pass itemdef unless you don't want aliases resolved.
|
||||||
void deSerialize(const std::string &s, IItemDefManager *itemdef);
|
void deSerialize(std::istream &is, IItemDefManager *itemdef = NULL);
|
||||||
|
void deSerialize(const std::string &s, IItemDefManager *itemdef = NULL);
|
||||||
|
|
||||||
// Returns the string used for inventory
|
// Returns the string used for inventory
|
||||||
std::string getItemString() const;
|
std::string getItemString() const;
|
||||||
|
@ -368,7 +368,7 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||||||
*/
|
*/
|
||||||
if(!ignore_rollback && gamedef->rollback())
|
if(!ignore_rollback && gamedef->rollback())
|
||||||
{
|
{
|
||||||
IRollbackReportSink *rollback = gamedef->rollback();
|
IRollbackManager *rollback = gamedef->rollback();
|
||||||
|
|
||||||
// If source is not infinite, record item take
|
// If source is not infinite, record item take
|
||||||
if(src_can_take_count != -1){
|
if(src_can_take_count != -1){
|
||||||
@ -380,7 +380,7 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||||||
loc = os.str();
|
loc = os.str();
|
||||||
}
|
}
|
||||||
action.setModifyInventoryStack(loc, from_list, from_i, false,
|
action.setModifyInventoryStack(loc, from_list, from_i, false,
|
||||||
src_item.getItemString());
|
src_item);
|
||||||
rollback->reportAction(action);
|
rollback->reportAction(action);
|
||||||
}
|
}
|
||||||
// If destination is not infinite, record item put
|
// If destination is not infinite, record item put
|
||||||
@ -393,7 +393,7 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||||||
loc = os.str();
|
loc = os.str();
|
||||||
}
|
}
|
||||||
action.setModifyInventoryStack(loc, to_list, to_i, true,
|
action.setModifyInventoryStack(loc, to_list, to_i, true,
|
||||||
src_item.getItemString());
|
src_item);
|
||||||
rollback->reportAction(action);
|
rollback->reportAction(action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -632,7 +632,7 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||||||
*/
|
*/
|
||||||
if(!ignore_src_rollback && gamedef->rollback())
|
if(!ignore_src_rollback && gamedef->rollback())
|
||||||
{
|
{
|
||||||
IRollbackReportSink *rollback = gamedef->rollback();
|
IRollbackManager *rollback = gamedef->rollback();
|
||||||
|
|
||||||
// If source is not infinite, record item take
|
// If source is not infinite, record item take
|
||||||
if(src_can_take_count != -1){
|
if(src_can_take_count != -1){
|
||||||
@ -644,7 +644,7 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||||||
loc = os.str();
|
loc = os.str();
|
||||||
}
|
}
|
||||||
action.setModifyInventoryStack(loc, from_list, from_i,
|
action.setModifyInventoryStack(loc, from_list, from_i,
|
||||||
false, src_item.getItemString());
|
false, src_item);
|
||||||
rollback->reportAction(action);
|
rollback->reportAction(action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ class ServerMapSector;
|
|||||||
class MapBlock;
|
class MapBlock;
|
||||||
class NodeMetadata;
|
class NodeMetadata;
|
||||||
class IGameDef;
|
class IGameDef;
|
||||||
class IRollbackReportSink;
|
class IRollbackManager;
|
||||||
class EmergeManager;
|
class EmergeManager;
|
||||||
class ServerEnvironment;
|
class ServerEnvironment;
|
||||||
struct BlockMakeData;
|
struct BlockMakeData;
|
||||||
|
1528
src/rollback.cpp
1528
src/rollback.cpp
File diff suppressed because it is too large
Load Diff
@ -24,31 +24,84 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "irr_v3d.h"
|
#include "irr_v3d.h"
|
||||||
#include "rollback_interface.h"
|
#include "rollback_interface.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
#include "sqlite3.h"
|
||||||
|
|
||||||
class IGameDef;
|
class IGameDef;
|
||||||
|
|
||||||
class IRollbackManager: public IRollbackReportSink
|
class ActionRow;
|
||||||
|
class Entity;
|
||||||
|
|
||||||
|
class RollbackManager: public IRollbackManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// IRollbackReportManager
|
RollbackManager(const std::string & world_path, IGameDef * gamedef);
|
||||||
virtual void reportAction(const RollbackAction &action) = 0;
|
~RollbackManager();
|
||||||
virtual std::string getActor() = 0;
|
|
||||||
virtual bool isActorGuess() = 0;
|
|
||||||
virtual void setActor(const std::string &actor, bool is_guess) = 0;
|
|
||||||
virtual std::string getSuspect(v3s16 p, float nearness_shortcut,
|
|
||||||
float min_nearness) = 0;
|
|
||||||
|
|
||||||
virtual ~IRollbackManager() {}
|
void reportAction(const RollbackAction & action_);
|
||||||
virtual void flush() = 0;
|
std::string getActor();
|
||||||
// Get all actors that did something to position p, but not further than
|
bool isActorGuess();
|
||||||
// <seconds> in history
|
void setActor(const std::string & actor, bool is_guess);
|
||||||
virtual std::list<RollbackAction> getNodeActors(v3s16 pos, int range,
|
std::string getSuspect(v3s16 p, float nearness_shortcut,
|
||||||
time_t seconds, int limit) = 0;
|
float min_nearness);
|
||||||
// Get actions to revert <seconds> of history made by <actor>
|
void flush();
|
||||||
virtual std::list<RollbackAction> getRevertActions(const std::string &actor,
|
|
||||||
time_t seconds) = 0;
|
void addAction(const RollbackAction & action);
|
||||||
|
std::list<RollbackAction> getEntriesSince(time_t first_time);
|
||||||
|
std::list<RollbackAction> getNodeActors(v3s16 pos, int range,
|
||||||
|
time_t seconds, int limit);
|
||||||
|
std::list<RollbackAction> getRevertActions(
|
||||||
|
const std::string & actor_filter, time_t seconds);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void registerNewActor(const int id, const std::string & name);
|
||||||
|
void registerNewNode(const int id, const std::string & name);
|
||||||
|
int getActorId(const std::string & name);
|
||||||
|
int getNodeId(const std::string & name);
|
||||||
|
const char * getActorName(const int id);
|
||||||
|
const char * getNodeName(const int id);
|
||||||
|
bool createTables();
|
||||||
|
void initDatabase();
|
||||||
|
bool registerRow(const ActionRow & row);
|
||||||
|
const std::list<ActionRow> actionRowsFromSelect(sqlite3_stmt * stmt);
|
||||||
|
ActionRow actionRowFromRollbackAction(const RollbackAction & action);
|
||||||
|
const std::list<RollbackAction> rollbackActionsFromActionRows(
|
||||||
|
const std::list<ActionRow> & rows);
|
||||||
|
const std::list<ActionRow> getRowsSince(time_t firstTime,
|
||||||
|
const std::string & actor);
|
||||||
|
const std::list<ActionRow> getRowsSince_range(time_t firstTime, v3s16 p,
|
||||||
|
int range, int limit);
|
||||||
|
const std::list<RollbackAction> getActionsSince_range(time_t firstTime, v3s16 p,
|
||||||
|
int range, int limit);
|
||||||
|
const std::list<RollbackAction> getActionsSince(time_t firstTime,
|
||||||
|
const std::string & actor = "");
|
||||||
|
void migrate(const std::string & filepath);
|
||||||
|
static float getSuspectNearness(bool is_guess, v3s16 suspect_p,
|
||||||
|
time_t suspect_t, v3s16 action_p, time_t action_t);
|
||||||
|
|
||||||
|
|
||||||
|
IGameDef * gamedef;
|
||||||
|
|
||||||
|
std::string current_actor;
|
||||||
|
bool current_actor_is_guess;
|
||||||
|
|
||||||
|
std::list<RollbackAction> action_todisk_buffer;
|
||||||
|
std::list<RollbackAction> action_latest_buffer;
|
||||||
|
|
||||||
|
std::string database_path;
|
||||||
|
sqlite3 * db;
|
||||||
|
sqlite3_stmt * stmt_insert;
|
||||||
|
sqlite3_stmt * stmt_replace;
|
||||||
|
sqlite3_stmt * stmt_select;
|
||||||
|
sqlite3_stmt * stmt_select_range;
|
||||||
|
sqlite3_stmt * stmt_select_withActor;
|
||||||
|
sqlite3_stmt * stmt_knownActor_select;
|
||||||
|
sqlite3_stmt * stmt_knownActor_insert;
|
||||||
|
sqlite3_stmt * stmt_knownNode_select;
|
||||||
|
sqlite3_stmt * stmt_knownNode_insert;
|
||||||
|
|
||||||
|
std::vector<Entity> knownActors;
|
||||||
|
std::vector<Entity> knownNodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
IRollbackManager *createRollbackManager(const std::string &filepath, IGameDef *gamedef);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||||
|
|
||||||
|
|
||||||
RollbackNode::RollbackNode(Map *map, v3s16 p, IGameDef *gamedef)
|
RollbackNode::RollbackNode(Map *map, v3s16 p, IGameDef *gamedef)
|
||||||
{
|
{
|
||||||
INodeDefManager *ndef = gamedef->ndef();
|
INodeDefManager *ndef = gamedef->ndef();
|
||||||
@ -42,275 +43,89 @@ RollbackNode::RollbackNode(Map *map, v3s16 p, IGameDef *gamedef)
|
|||||||
param1 = n.param1;
|
param1 = n.param1;
|
||||||
param2 = n.param2;
|
param2 = n.param2;
|
||||||
NodeMetadata *metap = map->getNodeMetadata(p);
|
NodeMetadata *metap = map->getNodeMetadata(p);
|
||||||
if(metap){
|
if (metap) {
|
||||||
std::ostringstream os(std::ios::binary);
|
std::ostringstream os(std::ios::binary);
|
||||||
metap->serialize(os);
|
metap->serialize(os);
|
||||||
meta = os.str();
|
meta = os.str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string RollbackAction::toString() const
|
std::string RollbackAction::toString() const
|
||||||
{
|
{
|
||||||
switch(type){
|
std::ostringstream os(std::ios::binary);
|
||||||
case TYPE_SET_NODE: {
|
switch (type) {
|
||||||
std::ostringstream os(std::ios::binary);
|
case TYPE_SET_NODE:
|
||||||
os<<"[set_node";
|
os << "set_node " << PP(p);
|
||||||
os<<" ";
|
os << ": (" << serializeJsonString(n_old.name);
|
||||||
os<<"("<<itos(p.X)<<","<<itos(p.Y)<<","<<itos(p.Z)<<")";
|
os << ", " << itos(n_old.param1);
|
||||||
os<<" ";
|
os << ", " << itos(n_old.param2);
|
||||||
os<<serializeJsonString(n_old.name);
|
os << ", " << serializeJsonString(n_old.meta);
|
||||||
os<<" ";
|
os << ") -> (" << serializeJsonString(n_new.name);
|
||||||
os<<itos(n_old.param1);
|
os << ", " << itos(n_new.param1);
|
||||||
os<<" ";
|
os << ", " << itos(n_new.param2);
|
||||||
os<<itos(n_old.param2);
|
os << ", " << serializeJsonString(n_new.meta);
|
||||||
os<<" ";
|
os << ')';
|
||||||
os<<serializeJsonString(n_old.meta);
|
case TYPE_MODIFY_INVENTORY_STACK:
|
||||||
os<<" ";
|
os << "modify_inventory_stack (";
|
||||||
os<<serializeJsonString(n_new.name);
|
os << serializeJsonString(inventory_location);
|
||||||
os<<" ";
|
os << ", " << serializeJsonString(inventory_list);
|
||||||
os<<itos(n_new.param1);
|
os << ", " << inventory_index;
|
||||||
os<<" ";
|
os << ", " << (inventory_add ? "add" : "remove");
|
||||||
os<<itos(n_new.param2);
|
os << ", " << serializeJsonString(inventory_stack.getItemString());
|
||||||
os<<" ";
|
os << ')';
|
||||||
os<<serializeJsonString(n_new.meta);
|
|
||||||
os<<"]";
|
|
||||||
return os.str(); }
|
|
||||||
case TYPE_MODIFY_INVENTORY_STACK: {
|
|
||||||
std::ostringstream os(std::ios::binary);
|
|
||||||
os<<"[modify_inventory_stack";
|
|
||||||
os<<" ";
|
|
||||||
os<<serializeJsonString(inventory_location);
|
|
||||||
os<<" ";
|
|
||||||
os<<serializeJsonString(inventory_list);
|
|
||||||
os<<" ";
|
|
||||||
os<<inventory_index;
|
|
||||||
os<<" ";
|
|
||||||
os<<(inventory_add?"add":"remove");
|
|
||||||
os<<" ";
|
|
||||||
os<<serializeJsonString(inventory_stack);
|
|
||||||
os<<"]";
|
|
||||||
return os.str(); }
|
|
||||||
default:
|
default:
|
||||||
return "none";
|
return "<unknown action>";
|
||||||
}
|
}
|
||||||
|
return os.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RollbackAction::fromStream(std::istream &is) throw(SerializationError)
|
|
||||||
{
|
|
||||||
int c = is.get();
|
|
||||||
if(c != '['){
|
|
||||||
is.putback(c);
|
|
||||||
throw SerializationError("RollbackAction: starting [ not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string id;
|
|
||||||
std::getline(is, id, ' ');
|
|
||||||
|
|
||||||
if(id == "set_node")
|
|
||||||
{
|
|
||||||
c = is.get();
|
|
||||||
if(c != '('){
|
|
||||||
is.putback(c);
|
|
||||||
throw SerializationError("RollbackAction: starting ( not found");
|
|
||||||
}
|
|
||||||
// Position
|
|
||||||
std::string px_raw;
|
|
||||||
std::string py_raw;
|
|
||||||
std::string pz_raw;
|
|
||||||
std::getline(is, px_raw, ',');
|
|
||||||
std::getline(is, py_raw, ',');
|
|
||||||
std::getline(is, pz_raw, ')');
|
|
||||||
c = is.get();
|
|
||||||
if(c != ' '){
|
|
||||||
is.putback(c);
|
|
||||||
throw SerializationError("RollbackAction: after-p ' ' not found");
|
|
||||||
}
|
|
||||||
v3s16 loaded_p(stoi(px_raw), stoi(py_raw), stoi(pz_raw));
|
|
||||||
// Old node
|
|
||||||
std::string old_name;
|
|
||||||
try{
|
|
||||||
old_name = deSerializeJsonString(is);
|
|
||||||
}catch(SerializationError &e){
|
|
||||||
errorstream<<"Serialization error in RollbackAction::fromStream(): "
|
|
||||||
<<"old_name: "<<e.what()<<std::endl;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
c = is.get();
|
|
||||||
if(c != ' '){
|
|
||||||
is.putback(c);
|
|
||||||
throw SerializationError("RollbackAction: after-old_name ' ' not found");
|
|
||||||
}
|
|
||||||
std::string old_p1_raw;
|
|
||||||
std::string old_p2_raw;
|
|
||||||
std::getline(is, old_p1_raw, ' ');
|
|
||||||
std::getline(is, old_p2_raw, ' ');
|
|
||||||
int old_p1 = stoi(old_p1_raw);
|
|
||||||
int old_p2 = stoi(old_p2_raw);
|
|
||||||
std::string old_meta;
|
|
||||||
try{
|
|
||||||
old_meta = deSerializeJsonString(is);
|
|
||||||
}catch(SerializationError &e){
|
|
||||||
errorstream<<"Serialization error in RollbackAction::fromStream(): "
|
|
||||||
<<"old_meta: "<<e.what()<<std::endl;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
c = is.get();
|
|
||||||
if(c != ' '){
|
|
||||||
is.putback(c);
|
|
||||||
throw SerializationError("RollbackAction: after-old_meta ' ' not found");
|
|
||||||
}
|
|
||||||
// New node
|
|
||||||
std::string new_name;
|
|
||||||
try{
|
|
||||||
new_name = deSerializeJsonString(is);
|
|
||||||
}catch(SerializationError &e){
|
|
||||||
errorstream<<"Serialization error in RollbackAction::fromStream(): "
|
|
||||||
<<"new_name: "<<e.what()<<std::endl;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
c = is.get();
|
|
||||||
if(c != ' '){
|
|
||||||
is.putback(c);
|
|
||||||
throw SerializationError("RollbackAction: after-new_name ' ' not found");
|
|
||||||
}
|
|
||||||
std::string new_p1_raw;
|
|
||||||
std::string new_p2_raw;
|
|
||||||
std::getline(is, new_p1_raw, ' ');
|
|
||||||
std::getline(is, new_p2_raw, ' ');
|
|
||||||
int new_p1 = stoi(new_p1_raw);
|
|
||||||
int new_p2 = stoi(new_p2_raw);
|
|
||||||
std::string new_meta;
|
|
||||||
try{
|
|
||||||
new_meta = deSerializeJsonString(is);
|
|
||||||
}catch(SerializationError &e){
|
|
||||||
errorstream<<"Serialization error in RollbackAction::fromStream(): "
|
|
||||||
<<"new_meta: "<<e.what()<<std::endl;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
c = is.get();
|
|
||||||
if(c != ']'){
|
|
||||||
is.putback(c);
|
|
||||||
throw SerializationError("RollbackAction: after-new_meta ] not found");
|
|
||||||
}
|
|
||||||
// Set values
|
|
||||||
type = TYPE_SET_NODE;
|
|
||||||
p = loaded_p;
|
|
||||||
n_old.name = old_name;
|
|
||||||
n_old.param1 = old_p1;
|
|
||||||
n_old.param2 = old_p2;
|
|
||||||
n_old.meta = old_meta;
|
|
||||||
n_new.name = new_name;
|
|
||||||
n_new.param1 = new_p1;
|
|
||||||
n_new.param2 = new_p2;
|
|
||||||
n_new.meta = new_meta;
|
|
||||||
}
|
|
||||||
else if(id == "modify_inventory_stack")
|
|
||||||
{
|
|
||||||
// Location
|
|
||||||
std::string location;
|
|
||||||
try{
|
|
||||||
location = deSerializeJsonString(is);
|
|
||||||
}catch(SerializationError &e){
|
|
||||||
errorstream<<"Serialization error in RollbackAction::fromStream(): "
|
|
||||||
<<"location: "<<e.what()<<std::endl;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
c = is.get();
|
|
||||||
if(c != ' '){
|
|
||||||
is.putback(c);
|
|
||||||
throw SerializationError("RollbackAction: after-loc ' ' not found");
|
|
||||||
}
|
|
||||||
// List
|
|
||||||
std::string listname;
|
|
||||||
try{
|
|
||||||
listname = deSerializeJsonString(is);
|
|
||||||
}catch(SerializationError &e){
|
|
||||||
errorstream<<"Serialization error in RollbackAction::fromStream(): "
|
|
||||||
<<"listname: "<<e.what()<<std::endl;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
c = is.get();
|
|
||||||
if(c != ' '){
|
|
||||||
is.putback(c);
|
|
||||||
throw SerializationError("RollbackAction: after-list ' ' not found");
|
|
||||||
}
|
|
||||||
// Index
|
|
||||||
std::string index_raw;
|
|
||||||
std::getline(is, index_raw, ' ');
|
|
||||||
// add/remove
|
|
||||||
std::string addremove;
|
|
||||||
std::getline(is, addremove, ' ');
|
|
||||||
if(addremove != "add" && addremove != "remove"){
|
|
||||||
throw SerializationError("RollbackAction: addremove is not add or remove");
|
|
||||||
}
|
|
||||||
// Itemstring
|
|
||||||
std::string stack;
|
|
||||||
try{
|
|
||||||
stack = deSerializeJsonString(is);
|
|
||||||
}catch(SerializationError &e){
|
|
||||||
errorstream<<"Serialization error in RollbackAction::fromStream(): "
|
|
||||||
<<"stack: "<<e.what()<<std::endl;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
// Set values
|
|
||||||
type = TYPE_MODIFY_INVENTORY_STACK;
|
|
||||||
inventory_location = location;
|
|
||||||
inventory_list = listname;
|
|
||||||
inventory_index = stoi(index_raw);
|
|
||||||
inventory_add = (addremove == "add");
|
|
||||||
inventory_stack = stack;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw SerializationError("RollbackAction: Unknown id");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RollbackAction::isImportant(IGameDef *gamedef) const
|
bool RollbackAction::isImportant(IGameDef *gamedef) const
|
||||||
{
|
{
|
||||||
switch(type){
|
if (type != TYPE_SET_NODE)
|
||||||
case TYPE_SET_NODE: {
|
|
||||||
// If names differ, action is always important
|
|
||||||
if(n_old.name != n_new.name)
|
|
||||||
return true;
|
|
||||||
// If metadata differs, action is always important
|
|
||||||
if(n_old.meta != n_new.meta)
|
|
||||||
return true;
|
|
||||||
INodeDefManager *ndef = gamedef->ndef();
|
|
||||||
// Both are of the same name, so a single definition is needed
|
|
||||||
const ContentFeatures &def = ndef->get(n_old.name);
|
|
||||||
// If the type is flowing liquid, action is not important
|
|
||||||
if(def.liquid_type == LIQUID_FLOWING)
|
|
||||||
return false;
|
|
||||||
// Otherwise action is important
|
|
||||||
return true; }
|
|
||||||
default:
|
|
||||||
return true;
|
return true;
|
||||||
}
|
// If names differ, action is always important
|
||||||
|
if(n_old.name != n_new.name)
|
||||||
|
return true;
|
||||||
|
// If metadata differs, action is always important
|
||||||
|
if(n_old.meta != n_new.meta)
|
||||||
|
return true;
|
||||||
|
INodeDefManager *ndef = gamedef->ndef();
|
||||||
|
// Both are of the same name, so a single definition is needed
|
||||||
|
const ContentFeatures &def = ndef->get(n_old.name);
|
||||||
|
// If the type is flowing liquid, action is not important
|
||||||
|
if (def.liquid_type == LIQUID_FLOWING)
|
||||||
|
return false;
|
||||||
|
// Otherwise action is important
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool RollbackAction::getPosition(v3s16 *dst) const
|
bool RollbackAction::getPosition(v3s16 *dst) const
|
||||||
{
|
{
|
||||||
switch(type){
|
switch (type) {
|
||||||
case RollbackAction::TYPE_SET_NODE:
|
case TYPE_SET_NODE:
|
||||||
if(dst) *dst = p;
|
if (dst) *dst = p;
|
||||||
return true;
|
return true;
|
||||||
case RollbackAction::TYPE_MODIFY_INVENTORY_STACK: {
|
case TYPE_MODIFY_INVENTORY_STACK: {
|
||||||
InventoryLocation loc;
|
InventoryLocation loc;
|
||||||
loc.deSerialize(inventory_location);
|
loc.deSerialize(inventory_location);
|
||||||
if(loc.type != InventoryLocation::NODEMETA)
|
if (loc.type != InventoryLocation::NODEMETA) {
|
||||||
return false;
|
return false;
|
||||||
if(dst) *dst = loc.p;
|
}
|
||||||
|
if (dst) *dst = loc.p;
|
||||||
return true; }
|
return true; }
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool RollbackAction::applyRevert(Map *map, InventoryManager *imgr, IGameDef *gamedef) const
|
bool RollbackAction::applyRevert(Map *map, InventoryManager *imgr, IGameDef *gamedef) const
|
||||||
{
|
{
|
||||||
try{
|
try {
|
||||||
switch(type){
|
switch (type) {
|
||||||
case TYPE_NOTHING:
|
case TYPE_NOTHING:
|
||||||
return true;
|
return true;
|
||||||
case TYPE_SET_NODE: {
|
case TYPE_SET_NODE: {
|
||||||
@ -321,40 +136,39 @@ bool RollbackAction::applyRevert(Map *map, InventoryManager *imgr, IGameDef *gam
|
|||||||
MapNode current_node = map->getNodeNoEx(p);
|
MapNode current_node = map->getNodeNoEx(p);
|
||||||
std::string current_name = ndef->get(current_node).name;
|
std::string current_name = ndef->get(current_node).name;
|
||||||
// If current node not the new node, it's bad
|
// If current node not the new node, it's bad
|
||||||
if(current_name != n_new.name)
|
if (current_name != n_new.name) {
|
||||||
return false;
|
return false;
|
||||||
/*// If current node not the new node and not ignore, it's bad
|
}
|
||||||
if(current_name != n_new.name && current_name != "ignore")
|
|
||||||
return false;*/
|
|
||||||
// Create rollback node
|
// Create rollback node
|
||||||
MapNode n(ndef, n_old.name, n_old.param1, n_old.param2);
|
MapNode n(ndef, n_old.name, n_old.param1, n_old.param2);
|
||||||
// Set rollback node
|
// Set rollback node
|
||||||
try{
|
try {
|
||||||
if(!map->addNodeWithEvent(p, n)){
|
if (!map->addNodeWithEvent(p, n)) {
|
||||||
infostream<<"RollbackAction::applyRevert(): "
|
infostream << "RollbackAction::applyRevert(): "
|
||||||
<<"AddNodeWithEvent failed at "
|
<< "AddNodeWithEvent failed at "
|
||||||
<<PP(p)<<" for "<<n_old.name<<std::endl;
|
<< PP(p) << " for " << n_old.name
|
||||||
|
<< std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
NodeMetadata *meta = map->getNodeMetadata(p);
|
if (n_old.meta.empty()) {
|
||||||
if(n_old.meta != ""){
|
map->removeNodeMetadata(p);
|
||||||
if(!meta){
|
} else {
|
||||||
|
NodeMetadata *meta = map->getNodeMetadata(p);
|
||||||
|
if (!meta) {
|
||||||
meta = new NodeMetadata(gamedef);
|
meta = new NodeMetadata(gamedef);
|
||||||
if(!map->setNodeMetadata(p, meta)){
|
if (!map->setNodeMetadata(p, meta)) {
|
||||||
delete meta;
|
delete meta;
|
||||||
infostream<<"RollbackAction::applyRevert(): "
|
infostream << "RollbackAction::applyRevert(): "
|
||||||
<<"setNodeMetadata failed at "
|
<< "setNodeMetadata failed at "
|
||||||
<<PP(p)<<" for "<<n_old.name<<std::endl;
|
<< PP(p) << " for " << n_old.name
|
||||||
|
<< std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::istringstream is(n_old.meta, std::ios::binary);
|
std::istringstream is(n_old.meta, std::ios::binary);
|
||||||
meta->deSerialize(is);
|
meta->deSerialize(is);
|
||||||
} else {
|
|
||||||
map->removeNodeMetadata(p);
|
|
||||||
}
|
}
|
||||||
// NOTE: This same code is in scriptapi.cpp
|
// Inform other things that the meta data has changed
|
||||||
// Inform other things that the metadata has changed
|
|
||||||
v3s16 blockpos = getContainerPos(p, MAP_BLOCKSIZE);
|
v3s16 blockpos = getContainerPos(p, MAP_BLOCKSIZE);
|
||||||
MapEditEvent event;
|
MapEditEvent event;
|
||||||
event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
|
event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
|
||||||
@ -362,12 +176,14 @@ bool RollbackAction::applyRevert(Map *map, InventoryManager *imgr, IGameDef *gam
|
|||||||
map->dispatchEvent(&event);
|
map->dispatchEvent(&event);
|
||||||
// Set the block to be saved
|
// Set the block to be saved
|
||||||
MapBlock *block = map->getBlockNoCreateNoEx(blockpos);
|
MapBlock *block = map->getBlockNoCreateNoEx(blockpos);
|
||||||
if(block)
|
if (block) {
|
||||||
block->raiseModified(MOD_STATE_WRITE_NEEDED,
|
block->raiseModified(MOD_STATE_WRITE_NEEDED,
|
||||||
"NodeMetaRef::reportMetadataChange");
|
"NodeMetaRef::reportMetadataChange");
|
||||||
}catch(InvalidPositionException &e){
|
}
|
||||||
infostream<<"RollbackAction::applyRevert(): "
|
} catch (InvalidPositionException &e) {
|
||||||
<<"InvalidPositionException: "<<e.what()<<std::endl;
|
infostream << "RollbackAction::applyRevert(): "
|
||||||
|
<< "InvalidPositionException: " << e.what()
|
||||||
|
<< std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Success
|
// Success
|
||||||
@ -375,47 +191,46 @@ bool RollbackAction::applyRevert(Map *map, InventoryManager *imgr, IGameDef *gam
|
|||||||
case TYPE_MODIFY_INVENTORY_STACK: {
|
case TYPE_MODIFY_INVENTORY_STACK: {
|
||||||
InventoryLocation loc;
|
InventoryLocation loc;
|
||||||
loc.deSerialize(inventory_location);
|
loc.deSerialize(inventory_location);
|
||||||
ItemStack stack;
|
std::string real_name = gamedef->idef()->getAlias(inventory_stack.name);
|
||||||
stack.deSerialize(inventory_stack, gamedef->idef());
|
|
||||||
Inventory *inv = imgr->getInventory(loc);
|
Inventory *inv = imgr->getInventory(loc);
|
||||||
if(!inv){
|
if (!inv) {
|
||||||
infostream<<"RollbackAction::applyRevert(): Could not get "
|
infostream << "RollbackAction::applyRevert(): Could not get "
|
||||||
"inventory at "<<inventory_location<<std::endl;
|
"inventory at " << inventory_location << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
InventoryList *list = inv->getList(inventory_list);
|
InventoryList *list = inv->getList(inventory_list);
|
||||||
if(!list){
|
if (!list) {
|
||||||
infostream<<"RollbackAction::applyRevert(): Could not get "
|
infostream << "RollbackAction::applyRevert(): Could not get "
|
||||||
"inventory list \""<<inventory_list<<"\" in "
|
"inventory list \"" << inventory_list << "\" in "
|
||||||
<<inventory_location<<std::endl;
|
<< inventory_location << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(list->getSize() <= inventory_index){
|
if (list->getSize() <= inventory_index) {
|
||||||
infostream<<"RollbackAction::applyRevert(): List index "
|
infostream << "RollbackAction::applyRevert(): List index "
|
||||||
<<inventory_index<<" too large in "
|
<< inventory_index << " too large in "
|
||||||
<<"inventory list \""<<inventory_list<<"\" in "
|
<< "inventory list \"" << inventory_list << "\" in "
|
||||||
<<inventory_location<<std::endl;
|
<< inventory_location << std::endl;
|
||||||
}
|
}
|
||||||
// If item was added, take away item, otherwise add removed item
|
// If item was added, take away item, otherwise add removed item
|
||||||
if(inventory_add){
|
if (inventory_add) {
|
||||||
// Silently ignore different current item
|
// Silently ignore different current item
|
||||||
if(list->getItem(inventory_index).name != stack.name)
|
if (list->getItem(inventory_index).name != real_name)
|
||||||
return false;
|
return false;
|
||||||
list->takeItem(inventory_index, stack.count);
|
list->takeItem(inventory_index, inventory_stack.count);
|
||||||
} else {
|
} else {
|
||||||
list->addItem(inventory_index, stack);
|
list->addItem(inventory_index, inventory_stack);
|
||||||
}
|
}
|
||||||
// Inventory was modified; send to clients
|
// Inventory was modified; send to clients
|
||||||
imgr->setInventoryModified(loc);
|
imgr->setInventoryModified(loc);
|
||||||
return true; }
|
return true; }
|
||||||
default:
|
default:
|
||||||
errorstream<<"RollbackAction::applyRevert(): type not handled"
|
errorstream << "RollbackAction::applyRevert(): type not handled"
|
||||||
<<std::endl;
|
<< std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}catch(SerializationError &e){
|
} catch(SerializationError &e) {
|
||||||
errorstream<<"RollbackAction::applyRevert(): n_old.name="<<n_old.name
|
errorstream << "RollbackAction::applyRevert(): n_old.name=" << n_old.name
|
||||||
<<", SerializationError: "<<e.what()<<std::endl;
|
<< ", SerializationError: " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "irr_v3d.h"
|
#include "irr_v3d.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <list>
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
|
#include "inventory.h"
|
||||||
|
|
||||||
class Map;
|
class Map;
|
||||||
class IGameDef;
|
class IGameDef;
|
||||||
@ -37,15 +39,12 @@ struct RollbackNode
|
|||||||
int param2;
|
int param2;
|
||||||
std::string meta;
|
std::string meta;
|
||||||
|
|
||||||
bool operator==(const RollbackNode &other)
|
bool operator == (const RollbackNode &other)
|
||||||
{
|
{
|
||||||
return (name == other.name && param1 == other.param1 &&
|
return (name == other.name && param1 == other.param1 &&
|
||||||
param2 == other.param2 && meta == other.meta);
|
param2 == other.param2 && meta == other.meta);
|
||||||
}
|
}
|
||||||
bool operator!=(const RollbackNode &other)
|
bool operator != (const RollbackNode &other) { return !(*this == other); }
|
||||||
{
|
|
||||||
return !(*this == other);
|
|
||||||
}
|
|
||||||
|
|
||||||
RollbackNode():
|
RollbackNode():
|
||||||
param1(0),
|
param1(0),
|
||||||
@ -55,6 +54,7 @@ struct RollbackNode
|
|||||||
RollbackNode(Map *map, v3s16 p, IGameDef *gamedef);
|
RollbackNode(Map *map, v3s16 p, IGameDef *gamedef);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct RollbackAction
|
struct RollbackAction
|
||||||
{
|
{
|
||||||
enum Type{
|
enum Type{
|
||||||
@ -75,7 +75,7 @@ struct RollbackAction
|
|||||||
std::string inventory_list;
|
std::string inventory_list;
|
||||||
u32 inventory_index;
|
u32 inventory_index;
|
||||||
bool inventory_add;
|
bool inventory_add;
|
||||||
std::string inventory_stack;
|
ItemStack inventory_stack;
|
||||||
|
|
||||||
RollbackAction():
|
RollbackAction():
|
||||||
type(TYPE_NOTHING),
|
type(TYPE_NOTHING),
|
||||||
@ -94,7 +94,7 @@ struct RollbackAction
|
|||||||
|
|
||||||
void setModifyInventoryStack(const std::string &inventory_location_,
|
void setModifyInventoryStack(const std::string &inventory_location_,
|
||||||
const std::string &inventory_list_, int index_,
|
const std::string &inventory_list_, int index_,
|
||||||
bool add_, const std::string &inventory_stack_)
|
bool add_, const ItemStack &inventory_stack_)
|
||||||
{
|
{
|
||||||
type = TYPE_MODIFY_INVENTORY_STACK;
|
type = TYPE_MODIFY_INVENTORY_STACK;
|
||||||
inventory_location = inventory_location_;
|
inventory_location = inventory_location_;
|
||||||
@ -106,7 +106,6 @@ struct RollbackAction
|
|||||||
|
|
||||||
// String should not contain newlines or nulls
|
// String should not contain newlines or nulls
|
||||||
std::string toString() const;
|
std::string toString() const;
|
||||||
void fromStream(std::istream &is) throw(SerializationError);
|
|
||||||
|
|
||||||
// Eg. flowing water level changes are not important
|
// Eg. flowing water level changes are not important
|
||||||
bool isImportant(IGameDef *gamedef) const;
|
bool isImportant(IGameDef *gamedef) const;
|
||||||
@ -116,41 +115,53 @@ struct RollbackAction
|
|||||||
bool applyRevert(Map *map, InventoryManager *imgr, IGameDef *gamedef) const;
|
bool applyRevert(Map *map, InventoryManager *imgr, IGameDef *gamedef) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IRollbackReportSink
|
|
||||||
|
class IRollbackManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~IRollbackReportSink(){}
|
|
||||||
virtual void reportAction(const RollbackAction &action) = 0;
|
virtual void reportAction(const RollbackAction &action) = 0;
|
||||||
virtual std::string getActor() = 0;
|
virtual std::string getActor() = 0;
|
||||||
virtual bool isActorGuess() = 0;
|
virtual bool isActorGuess() = 0;
|
||||||
virtual void setActor(const std::string &actor, bool is_guess) = 0;
|
virtual void setActor(const std::string &actor, bool is_guess) = 0;
|
||||||
virtual std::string getSuspect(v3s16 p, float nearness_shortcut,
|
virtual std::string getSuspect(v3s16 p, float nearness_shortcut,
|
||||||
float min_nearness) = 0;
|
float min_nearness) = 0;
|
||||||
|
|
||||||
|
virtual ~IRollbackManager() {};
|
||||||
|
virtual void flush() = 0;
|
||||||
|
// Get all actors that did something to position p, but not further than
|
||||||
|
// <seconds> in history
|
||||||
|
virtual std::list<RollbackAction> getNodeActors(v3s16 pos, int range,
|
||||||
|
time_t seconds, int limit) = 0;
|
||||||
|
// Get actions to revert <seconds> of history made by <actor>
|
||||||
|
virtual std::list<RollbackAction> getRevertActions(const std::string &actor,
|
||||||
|
time_t seconds) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class RollbackScopeActor
|
class RollbackScopeActor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RollbackScopeActor(IRollbackReportSink *sink, const std::string &actor,
|
RollbackScopeActor(IRollbackManager * rollback_,
|
||||||
bool is_guess=false):
|
const std::string & actor, bool is_guess = false) :
|
||||||
m_sink(sink)
|
rollback(rollback_)
|
||||||
{
|
{
|
||||||
if(m_sink){
|
if (rollback) {
|
||||||
m_actor_was = m_sink->getActor();
|
old_actor = rollback->getActor();
|
||||||
m_actor_was_guess = m_sink->isActorGuess();
|
old_actor_guess = rollback->isActorGuess();
|
||||||
m_sink->setActor(actor, is_guess);
|
rollback->setActor(actor, is_guess);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
~RollbackScopeActor()
|
~RollbackScopeActor()
|
||||||
{
|
{
|
||||||
if(m_sink){
|
if (rollback) {
|
||||||
m_sink->setActor(m_actor_was, m_actor_was_guess);
|
rollback->setActor(old_actor, old_actor_guess);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IRollbackReportSink *m_sink;
|
IRollbackManager * rollback;
|
||||||
std::string m_actor_was;
|
std::string old_actor;
|
||||||
bool m_actor_was_guess;
|
bool old_actor_guess;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,7 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "lua_api/l_internal.h"
|
#include "lua_api/l_internal.h"
|
||||||
#include "common/c_converter.h"
|
#include "common/c_converter.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "rollback.h"
|
#include "rollback_interface.h"
|
||||||
|
|
||||||
|
|
||||||
void push_RollbackNode(lua_State *L, RollbackNode &node)
|
void push_RollbackNode(lua_State *L, RollbackNode &node)
|
||||||
|
@ -181,7 +181,6 @@ Server::Server(
|
|||||||
this),
|
this),
|
||||||
m_banmanager(NULL),
|
m_banmanager(NULL),
|
||||||
m_rollback(NULL),
|
m_rollback(NULL),
|
||||||
m_rollback_sink_enabled(true),
|
|
||||||
m_enable_rollback_recording(false),
|
m_enable_rollback_recording(false),
|
||||||
m_emerge(NULL),
|
m_emerge(NULL),
|
||||||
m_script(NULL),
|
m_script(NULL),
|
||||||
@ -241,12 +240,11 @@ Server::Server(
|
|||||||
throw ServerError("Failed to initialize world");
|
throw ServerError("Failed to initialize world");
|
||||||
|
|
||||||
// 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";
|
||||||
m_banmanager = new BanManager(ban_path);
|
m_banmanager = new BanManager(ban_path);
|
||||||
|
|
||||||
// Create rollback manager
|
// Create rollback manager
|
||||||
std::string rollback_path = m_path_world+DIR_DELIM+"rollback.txt";
|
m_rollback = new RollbackManager(m_path_world, this);
|
||||||
m_rollback = createRollbackManager(rollback_path, this);
|
|
||||||
|
|
||||||
ModConfiguration modconf(m_path_world);
|
ModConfiguration modconf(m_path_world);
|
||||||
m_mods = modconf.getMods();
|
m_mods = modconf.getMods();
|
||||||
@ -4834,8 +4832,6 @@ bool Server::rollbackRevertActions(const std::list<RollbackAction> &actions,
|
|||||||
{
|
{
|
||||||
infostream<<"Server::rollbackRevertActions(len="<<actions.size()<<")"<<std::endl;
|
infostream<<"Server::rollbackRevertActions(len="<<actions.size()<<")"<<std::endl;
|
||||||
ServerMap *map = (ServerMap*)(&m_env->getMap());
|
ServerMap *map = (ServerMap*)(&m_env->getMap());
|
||||||
// Disable rollback report sink while reverting
|
|
||||||
BoolScopeSet rollback_scope_disable(&m_rollback_sink_enabled, false);
|
|
||||||
|
|
||||||
// Fail if no actions to handle
|
// Fail if no actions to handle
|
||||||
if(actions.empty()){
|
if(actions.empty()){
|
||||||
@ -4915,14 +4911,6 @@ MtEventManager* Server::getEventManager()
|
|||||||
{
|
{
|
||||||
return m_event;
|
return m_event;
|
||||||
}
|
}
|
||||||
IRollbackReportSink* Server::getRollbackReportSink()
|
|
||||||
{
|
|
||||||
if(!m_enable_rollback_recording)
|
|
||||||
return NULL;
|
|
||||||
if(!m_rollback_sink_enabled)
|
|
||||||
return NULL;
|
|
||||||
return m_rollback;
|
|
||||||
}
|
|
||||||
|
|
||||||
IWritableItemDefManager* Server::getWritableItemDefManager()
|
IWritableItemDefManager* Server::getWritableItemDefManager()
|
||||||
{
|
{
|
||||||
|
11
src/server.h
11
src/server.h
@ -29,7 +29,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "mods.h"
|
#include "mods.h"
|
||||||
#include "inventorymanager.h"
|
#include "inventorymanager.h"
|
||||||
#include "subgame.h"
|
#include "subgame.h"
|
||||||
#include "rollback_interface.h" // Needed for rollbackRevertActions()
|
|
||||||
#include "util/numeric.h"
|
#include "util/numeric.h"
|
||||||
#include "util/thread.h"
|
#include "util/thread.h"
|
||||||
#include "environment.h"
|
#include "environment.h"
|
||||||
@ -50,6 +49,7 @@ class Inventory;
|
|||||||
class Player;
|
class Player;
|
||||||
class PlayerSAO;
|
class PlayerSAO;
|
||||||
class IRollbackManager;
|
class IRollbackManager;
|
||||||
|
class RollbackAction;
|
||||||
class EmergeManager;
|
class EmergeManager;
|
||||||
class GameScripting;
|
class GameScripting;
|
||||||
class ServerEnvironment;
|
class ServerEnvironment;
|
||||||
@ -268,9 +268,6 @@ public:
|
|||||||
// Envlock and conlock should be locked when using scriptapi
|
// Envlock and conlock should be locked when using scriptapi
|
||||||
GameScripting *getScriptIface(){ return m_script; }
|
GameScripting *getScriptIface(){ return m_script; }
|
||||||
|
|
||||||
// Envlock should be locked when using the rollback manager
|
|
||||||
IRollbackManager *getRollbackManager(){ return m_rollback; }
|
|
||||||
|
|
||||||
//TODO: determine what (if anything) should be locked to access EmergeManager
|
//TODO: determine what (if anything) should be locked to access EmergeManager
|
||||||
EmergeManager *getEmergeManager(){ return m_emerge; }
|
EmergeManager *getEmergeManager(){ return m_emerge; }
|
||||||
|
|
||||||
@ -289,9 +286,10 @@ public:
|
|||||||
virtual u16 allocateUnknownNodeId(const std::string &name);
|
virtual u16 allocateUnknownNodeId(const std::string &name);
|
||||||
virtual ISoundManager* getSoundManager();
|
virtual ISoundManager* getSoundManager();
|
||||||
virtual MtEventManager* getEventManager();
|
virtual MtEventManager* getEventManager();
|
||||||
virtual IRollbackReportSink* getRollbackReportSink();
|
|
||||||
virtual scene::ISceneManager* getSceneManager();
|
virtual scene::ISceneManager* getSceneManager();
|
||||||
|
virtual IRollbackManager *getRollbackManager() { return m_rollback; }
|
||||||
|
|
||||||
|
|
||||||
IWritableItemDefManager* getWritableItemDefManager();
|
IWritableItemDefManager* getWritableItemDefManager();
|
||||||
IWritableNodeDefManager* getWritableNodeDefManager();
|
IWritableNodeDefManager* getWritableNodeDefManager();
|
||||||
IWritableCraftDefManager* getWritableCraftDefManager();
|
IWritableCraftDefManager* getWritableCraftDefManager();
|
||||||
@ -488,7 +486,6 @@ private:
|
|||||||
|
|
||||||
// Rollback manager (behind m_env_mutex)
|
// Rollback manager (behind m_env_mutex)
|
||||||
IRollbackManager *m_rollback;
|
IRollbackManager *m_rollback;
|
||||||
bool m_rollback_sink_enabled;
|
|
||||||
bool m_enable_rollback_recording; // Updated once in a while
|
bool m_enable_rollback_recording; // Updated once in a while
|
||||||
|
|
||||||
// Emerge manager
|
// Emerge manager
|
||||||
|
Loading…
Reference in New Issue
Block a user