1 /* 2 Minetest 3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU Lesser General Public License as published by 7 the Free Software Foundation; either version 2.1 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public License along 16 with this program; if not, write to the Free Software Foundation, Inc., 17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 #pragma once 21 22 #include "irr_v3d.h" 23 #include <string> 24 #include <iostream> 25 #include <list> 26 #include "exceptions.h" 27 #include "inventory.h" 28 29 class Map; 30 class IGameDef; 31 struct MapNode; 32 class InventoryManager; 33 34 struct RollbackNode 35 { 36 std::string name; 37 int param1 = 0; 38 int param2 = 0; 39 std::string meta; 40 41 bool operator == (const RollbackNode &other) 42 { 43 return (name == other.name && param1 == other.param1 && 44 param2 == other.param2 && meta == other.meta); 45 } 46 bool operator != (const RollbackNode &other) { return !(*this == other); } 47 48 RollbackNode() = default; 49 50 RollbackNode(Map *map, v3s16 p, IGameDef *gamedef); 51 }; 52 53 54 struct RollbackAction 55 { 56 enum Type{ 57 TYPE_NOTHING, 58 TYPE_SET_NODE, 59 TYPE_MODIFY_INVENTORY_STACK, 60 } type = TYPE_NOTHING; 61 62 time_t unix_time = 0; 63 std::string actor; 64 bool actor_is_guess = false; 65 66 v3s16 p; 67 RollbackNode n_old; 68 RollbackNode n_new; 69 70 std::string inventory_location; 71 std::string inventory_list; 72 u32 inventory_index; 73 bool inventory_add; 74 ItemStack inventory_stack; 75 76 RollbackAction() = default; 77 setSetNodeRollbackAction78 void setSetNode(v3s16 p_, const RollbackNode &n_old_, 79 const RollbackNode &n_new_) 80 { 81 type = TYPE_SET_NODE; 82 p = p_; 83 n_old = n_old_; 84 n_new = n_new_; 85 } 86 setModifyInventoryStackRollbackAction87 void setModifyInventoryStack(const std::string &inventory_location_, 88 const std::string &inventory_list_, u32 index_, 89 bool add_, const ItemStack &inventory_stack_) 90 { 91 type = TYPE_MODIFY_INVENTORY_STACK; 92 inventory_location = inventory_location_; 93 inventory_list = inventory_list_; 94 inventory_index = index_; 95 inventory_add = add_; 96 inventory_stack = inventory_stack_; 97 } 98 99 // String should not contain newlines or nulls 100 std::string toString() const; 101 102 // Eg. flowing water level changes are not important 103 bool isImportant(IGameDef *gamedef) const; 104 105 bool getPosition(v3s16 *dst) const; 106 107 bool applyRevert(Map *map, InventoryManager *imgr, IGameDef *gamedef) const; 108 }; 109 110 111 class IRollbackManager 112 { 113 public: 114 virtual void reportAction(const RollbackAction &action) = 0; 115 virtual std::string getActor() = 0; 116 virtual bool isActorGuess() = 0; 117 virtual void setActor(const std::string &actor, bool is_guess) = 0; 118 virtual std::string getSuspect(v3s16 p, float nearness_shortcut, 119 float min_nearness) = 0; 120 121 virtual ~IRollbackManager() = default;; 122 virtual void flush() = 0; 123 // Get all actors that did something to position p, but not further than 124 // <seconds> in history 125 virtual std::list<RollbackAction> getNodeActors(v3s16 pos, int range, 126 time_t seconds, int limit) = 0; 127 // Get actions to revert <seconds> of history made by <actor> 128 virtual std::list<RollbackAction> getRevertActions(const std::string &actor, 129 time_t seconds) = 0; 130 }; 131 132 133 class RollbackScopeActor 134 { 135 public: 136 RollbackScopeActor(IRollbackManager * rollback_, 137 const std::string & actor, bool is_guess = false) : rollback(rollback_)138 rollback(rollback_) 139 { 140 if (rollback) { 141 old_actor = rollback->getActor(); 142 old_actor_guess = rollback->isActorGuess(); 143 rollback->setActor(actor, is_guess); 144 } 145 } ~RollbackScopeActor()146 ~RollbackScopeActor() 147 { 148 if (rollback) { 149 rollback->setActor(old_actor, old_actor_guess); 150 } 151 } 152 153 private: 154 IRollbackManager * rollback; 155 std::string old_actor; 156 bool old_actor_guess; 157 }; 158