Don't use a separate thread to fake invalid actions

--HG--
branch : item_group
This commit is contained in:
Guillaume Dupuy 2017-03-23 16:06:47 +01:00
parent 6e62b186d0
commit 850613ac7e
3 changed files with 74 additions and 61 deletions

View file

@ -130,6 +130,7 @@ using namespace NLGUI;
#include "../global.h"
#include "user_agent.h"
#include "../item_group_manager.h"
using namespace NLMISC;
@ -1542,6 +1543,8 @@ void CInterfaceManager::updateFrameEvents()
CBGDownloaderAccess::getInstance().update();
CItemGroupManager::getInstance()->update();
}
// ------------------------------------------------------------------------------------------------

View file

@ -152,56 +152,10 @@ void CItemGroup::readFrom(xmlNodePtr node)
}
void CFakeEquipTime::invalidActions()
{
NLGUI::CDBManager *pDB = NLGUI::CDBManager::getInstance();
NLMISC::CCDBNodeLeaf *node;
// This are the db update server sends when an user equip an item, see egs/player_manager/gear_latency.cpp CGearLatency::setSlot
node = pDB->getDbProp("SERVER:USER:ACT_TSTART", false);
if (node) node->setValue64(NetMngr.getCurrentServerTick());
node = pDB->getDbProp("SERVER:USER:ACT_TEND", false);
if(node) node->setValue64(NetMngr.getCurrentServerTick() + time);
node = pDB->getDbProp("SERVER:EXECUTE_PHRASE:SHEET", false);
static NLMISC::CSheetId equipSheet("big_equip_item.sbrick");
if(node) node->setValue64((sint64)equipSheet.asInt());
node = pDB->getDbProp("SERVER:EXECUTE_PHRASE:PHRASE", false);
if(node) node->setValue64(0);
}
void CFakeEquipTime::validActions()
{
NLGUI::CDBManager *pDB = NLGUI::CDBManager::getInstance();
NLMISC::CCDBNodeLeaf *node;
node = pDB->getDbProp("SERVER:USER:ACT_TSTART", false);
if (node) node->setValue64(0);
node = pDB->getDbProp("SERVER:USER:ACT_TEND", false);
if(node) node->setValue64(0);
node = pDB->getDbProp("SERVER:EXECUTE_PHRASE:SHEET", false);
if(node) node->setValue32(0);
node = pDB->getDbProp("SERVER:EXECUTE_PHRASE:PHRASE", false);
if(node) node->setValue32(0);
}
void CFakeEquipTime::run()
{
//We wait a bit before invalidating actions, or server will override us
//Might not be accurate for everyone, but if it's wrong at worst you'll still get the timer
// Just with a blank icon instead of a "equipping item" red cross
NLMISC::nlSleep(600);
invalidActions();
NLMISC::nlSleep((time-6) * 100); // time is in ticks, sleep takes ms
validActions();
}
CItemGroupManager::CItemGroupManager()
{
_EndInvalidAction = 0;
_StartInvalidAction = 0;
}
void CItemGroupManager::init()
@ -331,6 +285,66 @@ bool CItemGroupManager::loadGroups()
return true;
}
void CItemGroupManager::update()
{
if(_StartInvalidAction != 0 && _StartInvalidAction <= NetMngr.getCurrentServerTick())
{
invalidActions(_StartInvalidAction, _EndInvalidAction);
_StartInvalidAction = 0;
}
if(_EndInvalidAction != 0 && _EndInvalidAction <= NetMngr.getCurrentServerTick())
{
_EndInvalidAction = 0;
validActions();
}
}
void CItemGroupManager::fakeInvalidActions(NLMISC::TGameCycle time)
{
// We cannot directly ivnalidate action or our invalidate will be overriden by the server
// (and that means we won't actually have one because it's buggy with multiple equip in a short time)
// So we wait a bit (currently 6 ticks is enough) to do it
_StartInvalidAction = NetMngr.getCurrentServerTick() + 6;
_EndInvalidAction = NetMngr.getCurrentServerTick() + time;
invalidActions(NetMngr.getCurrentServerTick(), _EndInvalidAction);
}
void CItemGroupManager::invalidActions(NLMISC::TGameCycle begin, NLMISC::TGameCycle end)
{
NLGUI::CDBManager *pDB = NLGUI::CDBManager::getInstance();
NLMISC::CCDBNodeLeaf *node;
// This are the db update server sends when an user equip an item, see egs/player_manager/gear_latency.cpp CGearLatency::setSlot
node = pDB->getDbProp("SERVER:USER:ACT_TSTART", false);
if (node) node->setValue64(begin);
node = pDB->getDbProp("SERVER:USER:ACT_TEND", false);
if(node) node->setValue64(end);
node = pDB->getDbProp("SERVER:EXECUTE_PHRASE:SHEET", false);
static NLMISC::CSheetId equipSheet("big_equip_item.sbrick");
if(node) node->setValue64((sint64)equipSheet.asInt());
node = pDB->getDbProp("SERVER:EXECUTE_PHRASE:PHRASE", false);
if(node) node->setValue64(0);
}
void CItemGroupManager::validActions()
{
NLGUI::CDBManager *pDB = NLGUI::CDBManager::getInstance();
NLMISC::CCDBNodeLeaf *node;
node = pDB->getDbProp("SERVER:USER:ACT_TSTART", false);
if (node) node->setValue64(0);
node = pDB->getDbProp("SERVER:USER:ACT_TEND", false);
if(node) node->setValue64(0);
node = pDB->getDbProp("SERVER:EXECUTE_PHRASE:SHEET", false);
if(node) node->setValue32(0);
node = pDB->getDbProp("SERVER:EXECUTE_PHRASE:PHRASE", false);
if(node) node->setValue32(0);
}
//move a group from all available inventory to dst
bool CItemGroupManager::moveGroup(std::string name, INVENTORIES::TInventory dst)
{
@ -459,9 +473,7 @@ bool CItemGroupManager::equipGroup(std::string name, bool pullBefore)
}
// For some reason, there is no (visual) invalidation (server still blocks any action), force one
// Unfortunately, there is no clean way to do this, so we'll simulate one
NLMISC::IRunnable *runnable = (NLMISC::IRunnable *)(new CFakeEquipTime((NLMISC::TGameCycle)maxEquipTime));
NLMISC::IThread *thread = NLMISC::IThread::create(runnable);
thread->start();
fakeInvalidActions((NLMISC::TGameCycle)maxEquipTime);
return true;
}

View file

@ -89,6 +89,8 @@ public:
bool deleteGroup(std::string name);
void listGroup();
std::vector<std::string> getGroupNames(CDBCtrlSheet *pCS);
//Used to fake invalid actions
void update();
private:
CItemGroup* findGroup(std::string name);
@ -98,17 +100,13 @@ private:
std::string toDbPath(INVENTORIES::TInventory inventory);
// Singleton's instance
static CItemGroupManager *_Instance;
};
class CFakeEquipTime : public NLMISC::IRunnable
{
public:
CFakeEquipTime(NLMISC::TGameCycle time) : time(time) {}
void invalidActions();
//
void fakeInvalidActions(NLMISC::TGameCycle time);
void invalidActions(NLMISC::TGameCycle begin, NLMISC::TGameCycle end);
void validActions();
void run();
NLMISC::TGameCycle time;
NLMISC::TGameCycle _EndInvalidAction;
NLMISC::TGameCycle _StartInvalidAction;
};
#endif // RY_ITEM_GROUP_MANAGER_H