From a9d8df83d228635594b75a563a0a8d906b3b883a Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Fri, 27 Jul 2012 13:24:28 +0300 Subject: Make the rollback system VERY FUCKING GOD DAMN POWERFUL --- src/rollback.cpp | 102 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 84 insertions(+), 18 deletions(-) (limited to 'src/rollback.cpp') diff --git a/src/rollback.cpp b/src/rollback.cpp index 3fe791050..db3f01702 100644 --- a/src/rollback.cpp +++ b/src/rollback.cpp @@ -28,10 +28,34 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/serialize.h" #include "util/string.h" #include "strfnd.h" +#include "util/numeric.h" #include "inventorymanager.h" // deserializing InventoryLocations #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" +// Get nearness factor for subject's action for this action +// Return value: 0 = impossible, >0 = factor +static float getSuspectNearness(bool is_guess, v3s16 suspect_p, int suspect_t, + v3s16 action_p, int action_t) +{ + // Suspect cannot cause things in the past + if(action_t < suspect_t) + return 0; // 0 = cannot be + // Start from 100 + int f = 100; + // Distance (1 node = +1 point) + f += 1.0 * intToFloat(suspect_p, 1).getDistanceFrom(intToFloat(action_p, 1)); + // Time (1 second = -1 point) + f -= 1.0 * (action_t - suspect_t); + // If is a guess, halve the points + if(is_guess) + f *= 0.5; + // Limit to 0 + if(f < 0) + f = 0; + return f; +} + class RollbackManager: public IRollbackManager { public: @@ -44,10 +68,23 @@ public: return; RollbackAction action = action_; action.unix_time = time(0); + // Figure out actor action.actor = m_current_actor; + action.actor_is_guess = m_current_actor_is_guess; + // If actor is not known, find out suspect or cancel + if(action.actor.empty()){ + v3s16 p; + if(!action.getPosition(&p)) + return; + action.actor = getSuspect(p, 5); // 5s timeframe + if(action.actor.empty()) + return; + action.actor_is_guess = true; + } infostream<<"RollbackManager::reportAction():" <<" time="<::const_reverse_iterator + i = m_action_latest_buffer.rbegin(); + i != m_action_latest_buffer.rend(); i++) + { + if(i->unix_time < first_time) + break; + // Find position of suspect or continue + v3s16 suspect_p; + if(!i->getPosition(&suspect_p)) + continue; + float f = getSuspectNearness(i->actor_is_guess, suspect_p, + i->unix_time, p, cur_time); + if(f > likely_suspect_nearness){ + likely_suspect_nearness = f; + likely_suspect = *i; + } + } + // No likely suspect was found + if(likely_suspect_nearness == 0) + return ""; + // Likely suspect was found + return likely_suspect.actor; } void flush() { @@ -80,8 +153,12 @@ public: of<<" "; of<actor); of<<" "; - std::string action_s = i->toString(); - of<toString(); + if(i->actor_is_guess){ + of<<" "; + of<<"actor_is_guess"; + } + of<type == RollbackAction::TYPE_SET_NODE) - { - action_p = i->p; - } - else if(i->type == RollbackAction::TYPE_MODIFY_INVENTORY_STACK) - { - InventoryLocation loc; - loc.deSerialize(i->inventory_location); - if(loc.type != InventoryLocation::NODEMETA) - continue; - action_p = loc.p; - } - else + if(!i->getPosition(&action_p)) continue; if(range == 0){ @@ -281,6 +346,7 @@ private: std::string m_filepath; IGameDef *m_gamedef; std::string m_current_actor; + bool m_current_actor_is_guess; std::list m_action_todisk_buffer; std::list m_action_latest_buffer; }; -- cgit v1.2.3