summaryrefslogtreecommitdiff
path: root/src/rollback_interface.cpp
diff options
context:
space:
mode:
authorShadowNinja <shadowninja@minetest.net>2014-06-25 20:28:41 -0400
committerShadowNinja <shadowninja@minetest.net>2014-11-19 16:21:59 -0500
commitb1965ac20922e3722392114bd63a22b403dcbe98 (patch)
treeab7ba20d23e01be920d7161fbfd20d2e265f2b70 /src/rollback_interface.cpp
parentda0f1e5497c7dece9ff5092adfb5881b0dd2e10c (diff)
downloadminetest-b1965ac20922e3722392114bd63a22b403dcbe98.tar.gz
minetest-b1965ac20922e3722392114bd63a22b403dcbe98.tar.bz2
minetest-b1965ac20922e3722392114bd63a22b403dcbe98.zip
Clean up rollback
Diffstat (limited to 'src/rollback_interface.cpp')
-rw-r--r--src/rollback_interface.cpp385
1 files changed, 100 insertions, 285 deletions
diff --git a/src/rollback_interface.cpp b/src/rollback_interface.cpp
index 808b07fed..c35ad5781 100644
--- a/src/rollback_interface.cpp
+++ b/src/rollback_interface.cpp
@@ -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<<")"
+
RollbackNode::RollbackNode(Map *map, v3s16 p, IGameDef *gamedef)
{
INodeDefManager *ndef = gamedef->ndef();
@@ -42,275 +43,89 @@ RollbackNode::RollbackNode(Map *map, v3s16 p, IGameDef *gamedef)
param1 = n.param1;
param2 = n.param2;
NodeMetadata *metap = map->getNodeMetadata(p);
- if(metap){
+ if (metap) {
std::ostringstream os(std::ios::binary);
metap->serialize(os);
meta = os.str();
}
}
+
std::string RollbackAction::toString() const
{
- switch(type){
- case TYPE_SET_NODE: {
- std::ostringstream os(std::ios::binary);
- os<<"[set_node";
- os<<" ";
- os<<"("<<itos(p.X)<<","<<itos(p.Y)<<","<<itos(p.Z)<<")";
- os<<" ";
- os<<serializeJsonString(n_old.name);
- os<<" ";
- os<<itos(n_old.param1);
- os<<" ";
- os<<itos(n_old.param2);
- os<<" ";
- os<<serializeJsonString(n_old.meta);
- os<<" ";
- os<<serializeJsonString(n_new.name);
- os<<" ";
- os<<itos(n_new.param1);
- os<<" ";
- os<<itos(n_new.param2);
- 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(); }
+ std::ostringstream os(std::ios::binary);
+ switch (type) {
+ case TYPE_SET_NODE:
+ os << "set_node " << PP(p);
+ os << ": (" << serializeJsonString(n_old.name);
+ os << ", " << itos(n_old.param1);
+ os << ", " << itos(n_old.param2);
+ os << ", " << serializeJsonString(n_old.meta);
+ os << ") -> (" << serializeJsonString(n_new.name);
+ os << ", " << itos(n_new.param1);
+ os << ", " << itos(n_new.param2);
+ os << ", " << serializeJsonString(n_new.meta);
+ os << ')';
+ case TYPE_MODIFY_INVENTORY_STACK:
+ os << "modify_inventory_stack (";
+ os << serializeJsonString(inventory_location);
+ os << ", " << serializeJsonString(inventory_list);
+ os << ", " << inventory_index;
+ os << ", " << (inventory_add ? "add" : "remove");
+ os << ", " << serializeJsonString(inventory_stack.getItemString());
+ os << ')';
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
{
- switch(type){
- 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:
+ if (type != TYPE_SET_NODE)
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
{
- switch(type){
- case RollbackAction::TYPE_SET_NODE:
- if(dst) *dst = p;
+ switch (type) {
+ case TYPE_SET_NODE:
+ if (dst) *dst = p;
return true;
- case RollbackAction::TYPE_MODIFY_INVENTORY_STACK: {
+ case TYPE_MODIFY_INVENTORY_STACK: {
InventoryLocation loc;
loc.deSerialize(inventory_location);
- if(loc.type != InventoryLocation::NODEMETA)
+ if (loc.type != InventoryLocation::NODEMETA) {
return false;
- if(dst) *dst = loc.p;
+ }
+ if (dst) *dst = loc.p;
return true; }
default:
return false;
}
}
+
bool RollbackAction::applyRevert(Map *map, InventoryManager *imgr, IGameDef *gamedef) const
{
- try{
- switch(type){
+ try {
+ switch (type) {
case TYPE_NOTHING:
return true;
case TYPE_SET_NODE: {
@@ -321,40 +136,39 @@ bool RollbackAction::applyRevert(Map *map, InventoryManager *imgr, IGameDef *gam
MapNode current_node = map->getNodeNoEx(p);
std::string current_name = ndef->get(current_node).name;
// If current node not the new node, it's bad
- if(current_name != n_new.name)
+ if (current_name != n_new.name) {
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
MapNode n(ndef, n_old.name, n_old.param1, n_old.param2);
// Set rollback node
- try{
- if(!map->addNodeWithEvent(p, n)){
- infostream<<"RollbackAction::applyRevert(): "
- <<"AddNodeWithEvent failed at "
- <<PP(p)<<" for "<<n_old.name<<std::endl;
+ try {
+ if (!map->addNodeWithEvent(p, n)) {
+ infostream << "RollbackAction::applyRevert(): "
+ << "AddNodeWithEvent failed at "
+ << PP(p) << " for " << n_old.name
+ << std::endl;
return false;
}
- NodeMetadata *meta = map->getNodeMetadata(p);
- if(n_old.meta != ""){
- if(!meta){
+ if (n_old.meta.empty()) {
+ map->removeNodeMetadata(p);
+ } else {
+ NodeMetadata *meta = map->getNodeMetadata(p);
+ if (!meta) {
meta = new NodeMetadata(gamedef);
- if(!map->setNodeMetadata(p, meta)){
+ if (!map->setNodeMetadata(p, meta)) {
delete meta;
- infostream<<"RollbackAction::applyRevert(): "
- <<"setNodeMetadata failed at "
- <<PP(p)<<" for "<<n_old.name<<std::endl;
+ infostream << "RollbackAction::applyRevert(): "
+ << "setNodeMetadata failed at "
+ << PP(p) << " for " << n_old.name
+ << std::endl;
return false;
}
}
std::istringstream is(n_old.meta, std::ios::binary);
meta->deSerialize(is);
- } else {
- map->removeNodeMetadata(p);
}
- // NOTE: This same code is in scriptapi.cpp
- // Inform other things that the metadata has changed
+ // Inform other things that the meta data has changed
v3s16 blockpos = getContainerPos(p, MAP_BLOCKSIZE);
MapEditEvent event;
event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
@@ -362,12 +176,14 @@ bool RollbackAction::applyRevert(Map *map, InventoryManager *imgr, IGameDef *gam
map->dispatchEvent(&event);
// Set the block to be saved
MapBlock *block = map->getBlockNoCreateNoEx(blockpos);
- if(block)
+ if (block) {
block->raiseModified(MOD_STATE_WRITE_NEEDED,
- "NodeMetaRef::reportMetadataChange");
- }catch(InvalidPositionException &e){
- infostream<<"RollbackAction::applyRevert(): "
- <<"InvalidPositionException: "<<e.what()<<std::endl;
+ "NodeMetaRef::reportMetadataChange");
+ }
+ } catch (InvalidPositionException &e) {
+ infostream << "RollbackAction::applyRevert(): "
+ << "InvalidPositionException: " << e.what()
+ << std::endl;
return false;
}
// Success
@@ -375,47 +191,46 @@ bool RollbackAction::applyRevert(Map *map, InventoryManager *imgr, IGameDef *gam
case TYPE_MODIFY_INVENTORY_STACK: {
InventoryLocation loc;
loc.deSerialize(inventory_location);
- ItemStack stack;
- stack.deSerialize(inventory_stack, gamedef->idef());
+ std::string real_name = gamedef->idef()->getAlias(inventory_stack.name);
Inventory *inv = imgr->getInventory(loc);
- if(!inv){
- infostream<<"RollbackAction::applyRevert(): Could not get "
- "inventory at "<<inventory_location<<std::endl;
+ if (!inv) {
+ infostream << "RollbackAction::applyRevert(): Could not get "
+ "inventory at " << inventory_location << std::endl;
return false;
}
InventoryList *list = inv->getList(inventory_list);
- if(!list){
- infostream<<"RollbackAction::applyRevert(): Could not get "
- "inventory list \""<<inventory_list<<"\" in "
- <<inventory_location<<std::endl;
+ if (!list) {
+ infostream << "RollbackAction::applyRevert(): Could not get "
+ "inventory list \"" << inventory_list << "\" in "
+ << inventory_location << std::endl;
return false;
}
- if(list->getSize() <= inventory_index){
- infostream<<"RollbackAction::applyRevert(): List index "
- <<inventory_index<<" too large in "
- <<"inventory list \""<<inventory_list<<"\" in "
- <<inventory_location<<std::endl;
+ if (list->getSize() <= inventory_index) {
+ infostream << "RollbackAction::applyRevert(): List index "
+ << inventory_index << " too large in "
+ << "inventory list \"" << inventory_list << "\" in "
+ << inventory_location << std::endl;
}
// If item was added, take away item, otherwise add removed item
- if(inventory_add){
+ if (inventory_add) {
// Silently ignore different current item
- if(list->getItem(inventory_index).name != stack.name)
+ if (list->getItem(inventory_index).name != real_name)
return false;
- list->takeItem(inventory_index, stack.count);
+ list->takeItem(inventory_index, inventory_stack.count);
} else {
- list->addItem(inventory_index, stack);
+ list->addItem(inventory_index, inventory_stack);
}
// Inventory was modified; send to clients
imgr->setInventoryModified(loc);
return true; }
default:
- errorstream<<"RollbackAction::applyRevert(): type not handled"
- <<std::endl;
+ errorstream << "RollbackAction::applyRevert(): type not handled"
+ << std::endl;
return false;
}
- }catch(SerializationError &e){
- errorstream<<"RollbackAction::applyRevert(): n_old.name="<<n_old.name
- <<", SerializationError: "<<e.what()<<std::endl;
+ } catch(SerializationError &e) {
+ errorstream << "RollbackAction::applyRevert(): n_old.name=" << n_old.name
+ << ", SerializationError: " << e.what() << std::endl;
}
return false;
}