update 2.7 (#46): fix Map teleport

This commit is contained in:
CallowBlack 2022-05-31 18:23:12 +03:00
parent 34fe0dfdaf
commit 3ee761a882
5 changed files with 68 additions and 89 deletions

View File

@ -243,7 +243,7 @@ DO_APP_FUNC(0x065ECB70, void, RenderSettings_set_fog, (void* __this, bool value,
DO_APP_FUNC(0x06621FF0, void, Application_set_targetFrameRate, (void* __this, int32_t value, MethodInfo* method)); DO_APP_FUNC(0x06621FF0, void, Application_set_targetFrameRate, (void* __this, int32_t value, MethodInfo* method));
DO_APP_FUNC(0x06621D80, int32_t, Application_get_targetFrameRate, (void* __this, MethodInfo* method)); DO_APP_FUNC(0x06621D80, int32_t, Application_get_targetFrameRate, (void* __this, MethodInfo* method));
DO_APP_FUNC(0x06678780, bool, RectTransformUtility_ScreenPointToLocalPointInRectangle, (void* __this, void* rect, Vector2 screenPoint, void* cam, Vector2* localPoint, MethodInfo* method)); DO_APP_FUNC(0x06678780, bool, RectTransformUtility_ScreenPointToLocalPointInRectangle, (void* rect, Vector2 screenPoint, void* cam, Vector2* localPoint, MethodInfo* method));
DO_APP_FUNC(0x06555BA0, Vector3, Transform_get_position, (Transform* __this, MethodInfo* method)); DO_APP_FUNC(0x06555BA0, Vector3, Transform_get_position, (Transform* __this, MethodInfo* method));
DO_APP_FUNC(0x065548F0, void, Transform_set_position, (Transform* __this, Vector3 value, MethodInfo* method)); DO_APP_FUNC(0x065548F0, void, Transform_set_position, (Transform* __this, Vector3 value, MethodInfo* method));

View File

@ -8145,6 +8145,7 @@ namespace app {
struct LCBaseCombat_AttackTarget { struct LCBaseCombat_AttackTarget {
uint32_t runtimeID; uint32_t runtimeID;
struct String* lockedPoint; struct String* lockedPoint;
int32_t MBCDNGIFGDD;
}; };
struct LCBaseCombat__Fields { struct LCBaseCombat__Fields {

View File

@ -112,21 +112,28 @@ struct UniList
} }
}; };
template<typename KeyT, typename ValT>
struct UniDictEntry
{
int32_t hashCode;
int32_t next;
KeyT key;
ValT value;
};
template<typename KeyT, typename ValT> template<typename KeyT, typename ValT>
struct __declspec(align(8)) UniDict { struct __declspec(align(8)) UniDict {
void* klass; void* klass;
MonitorData* monitor; MonitorData* monitor;
struct app::Int32__Array* table; void* buckets;
struct app::Link__Array* linkSlots; UniArray<UniDictEntry<KeyT, ValT>>* entries;
struct UniArray<KeyT>* keySlots; int32_t count;
struct UniArray<ValT>* valueSlots; int32_t version;
int32_t touchedSlots; int32_t freeList;
int32_t emptySlot; int32_t freeCount;
int32_t count; void* comparer;
int32_t threshold; void* keys;
void* hcp; void* values;
void* serialization_info;
int32_t generation;
std::vector<std::pair<KeyT, ValT>> pairs() std::vector<std::pair<KeyT, ValT>> pairs()
{ {
@ -134,27 +141,19 @@ struct __declspec(align(8)) UniDict {
#define DictCheckNull(field, msg) if (field == nullptr) { LOG_WARNING("Failed to get dict pairs: %s", msg); return pairs; } #define DictCheckNull(field, msg) if (field == nullptr) { LOG_WARNING("Failed to get dict pairs: %s", msg); return pairs; }
DictCheckNull(linkSlots, "LinkSlots pointer is null."); DictCheckNull(buckets, "Buckets is null.");
DictCheckNull(keySlots, "Key slots is null."); DictCheckNull(entries, "Entries is null.");
DictCheckNull(valueSlots, "ValueSlots pointer is null.");
#undef DictCheckNull #undef DictCheckNull
int32_t next = 0; for (auto& entry : *entries)
const int HASH_FLAG = 0x80000000;
while (next < touchedSlots)
{ {
int32_t cur = next++; if (entry.next != 0xffffffff)
if ((linkSlots->vector[cur].HashCode & HASH_FLAG) != 0) break;
{
pairs.push_back( pairs.push_back({ entry.key, entry.value });
std::make_pair(
keySlots->vector[cur],
valueSlots->vector[cur]
)
);
}
} }
return pairs; return pairs;
} }
}; };

View File

@ -8,14 +8,6 @@
namespace cheat::feature namespace cheat::feature
{ {
static void InLevelMapPageContext_OnMapClicked_Hook(app::InLevelMapPageContext* __this, app::Vector2 screenPos, MethodInfo* method);
static void InLevelMapPageContext_OnMarkClicked_Hook(app::InLevelMapPageContext* __this, app::MonoMapMark* mark, MethodInfo* method);
static app::Vector3 LocalEntityInfoData_get_initPos_Hook(app::LocalEntityInfoData* __this, MethodInfo* method);
static bool LoadingManager_NeedTransByServer_Hook(app::MoleMole_LoadingManager* __this, uint32_t sceneId, app::Vector3 position, MethodInfo* method);
static void LoadingManager_PerformPlayerTransmit_Hook(app::MoleMole_LoadingManager* __this, app::Vector3 position, app::EnterType__Enum someEnum,
uint32_t someUint1, app::EvtTransmitAvatar_EvtTransmitAvatar_TransmitType__Enum teleportType, uint32_t someUint2, MethodInfo* method);
static void Entity_SetRelativePosition_Hook(app::BaseEntity* __this, app::Vector3 position, bool someBool, MethodInfo* method);
MapTeleport::MapTeleport() : Feature(), MapTeleport::MapTeleport() : Feature(),
NF(f_Enabled, "Map teleport", "MapTeleport", false), NF(f_Enabled, "Map teleport", "MapTeleport", false),
@ -28,14 +20,13 @@ namespace cheat::feature
HookManager::install(app::MoleMole_InLevelMapPageContext_OnMapClicked, InLevelMapPageContext_OnMapClicked_Hook); HookManager::install(app::MoleMole_InLevelMapPageContext_OnMapClicked, InLevelMapPageContext_OnMapClicked_Hook);
// Stage 1 // Stage 1
HookManager::install(app::MoleMole_LocalEntityInfoData_get_initPos, LocalEntityInfoData_get_initPos_Hook);
HookManager::install(app::MoleMole_LoadingManager_NeedTransByServer, LoadingManager_NeedTransByServer_Hook); HookManager::install(app::MoleMole_LoadingManager_NeedTransByServer, LoadingManager_NeedTransByServer_Hook);
// Stage 2 // Stage 2
HookManager::install(app::MoleMole_LoadingManager_PerformPlayerTransmit, LoadingManager_PerformPlayerTransmit_Hook); HookManager::install(app::MoleMole_LoadingManager_PerformPlayerTransmit, LoadingManager_PerformPlayerTransmit_Hook);
// Stage 3 // Stage 3
HookManager::install(app::MoleMole_BaseEntity_SetRelativePosition, Entity_SetRelativePosition_Hook); HookManager::install(app::MoleMole_BaseEntity_SetAbsolutePosition, MoleMole_BaseEntity_SetAbsolutePosition_Hook);
events::GameUpdateEvent += MY_METHOD_HANDLER(MapTeleport::OnGameUpdate); events::GameUpdateEvent += MY_METHOD_HANDLER(MapTeleport::OnGameUpdate);
} }
@ -130,7 +121,7 @@ namespace cheat::feature
if (screenCamera == nullptr) if (screenCamera == nullptr)
return false; return false;
bool result = app::RectTransformUtility_ScreenPointToLocalPointInRectangle(nullptr, mapBackground, screenPos, screenCamera, outMapPos, nullptr); bool result = app::RectTransformUtility_ScreenPointToLocalPointInRectangle(mapBackground, screenPos, screenCamera, outMapPos, nullptr);
if (!result) if (!result)
return false; return false;
@ -160,9 +151,9 @@ namespace cheat::feature
// Calling teleport if map clicked. // Calling teleport if map clicked.
// This event invokes only when free space of map clicked, // This event invokes only when free space of map clicked,
// if clicked mark, invokes InLevelMapPageContext_OnMarkClicked_Hook. // if clicked mark, invokes InLevelMapPageContext_OnMarkClicked_Hook.
static void InLevelMapPageContext_OnMapClicked_Hook(app::InLevelMapPageContext* __this, app::Vector2 screenPos, MethodInfo* method) void MapTeleport::InLevelMapPageContext_OnMapClicked_Hook(app::InLevelMapPageContext* __this, app::Vector2 screenPos, MethodInfo* method)
{ {
MapTeleport& mapTeleport = MapTeleport::GetInstance(); MapTeleport& mapTeleport = GetInstance();
if (!mapTeleport.f_Enabled || !mapTeleport.f_Key.value().IsPressed()) if (!mapTeleport.f_Enabled || !mapTeleport.f_Key.value().IsPressed())
return CALL_ORIGIN(InLevelMapPageContext_OnMapClicked_Hook, __this, screenPos, method); return CALL_ORIGIN(InLevelMapPageContext_OnMapClicked_Hook, __this, screenPos, method);
@ -176,36 +167,30 @@ namespace cheat::feature
} }
// Calling teleport if map marks clicked. // Calling teleport if map marks clicked.
static void InLevelMapPageContext_OnMarkClicked_Hook(app::InLevelMapPageContext* __this, app::MonoMapMark* mark, MethodInfo* method) void MapTeleport::InLevelMapPageContext_OnMarkClicked_Hook(app::InLevelMapPageContext* __this, app::MonoMapMark* mark, MethodInfo* method)
{ {
MapTeleport& mapTeleport = MapTeleport::GetInstance(); MapTeleport& mapTeleport = GetInstance();
if (!mapTeleport.f_Enabled || !mapTeleport.f_Key.value().IsPressed()) if (!mapTeleport.f_Enabled || !mapTeleport.f_Key.value().IsPressed())
return CALL_ORIGIN(InLevelMapPageContext_OnMarkClicked_Hook, __this, mark, method); return CALL_ORIGIN(InLevelMapPageContext_OnMarkClicked_Hook, __this, mark, method);
mapTeleport.TeleportTo(mark->fields._levelMapPos); mapTeleport.TeleportTo(mark->fields._levelMapPos);
} }
// Before call, game checked if distance is near (<60) to cast near teleport.
// But it check distance to waypoint location, given by this function.
// So, we need to replace target position to do correct check.
void MapTeleport::OnGetTargetPos(app::Vector3& position)
{
if (taskInfo.currentStage == 3)
{
position = taskInfo.targetPosition;
taskInfo.currentStage--;
LOG_DEBUG("Stage 1. Replace waypoint tp position.");
}
}
// Checking is teleport is far (>60m), if it isn't we clear stage. // Checking is teleport is far (>60m), if it isn't we clear stage.
void MapTeleport::OnCheckTeleportDistance(bool needTransByServer) bool MapTeleport::IsNeedTransByServer(bool originResult, app::Vector3& position)
{ {
if (!needTransByServer && taskInfo.currentStage == 2) if (taskInfo.currentStage != 3)
{ return originResult;
auto& entityManager = game::EntityManager::instance();
bool needServerTrans = entityManager.avatar()->distance(taskInfo.targetPosition) > 60.0f;
if (needServerTrans)
LOG_DEBUG("Stage 1. Distance is more than 60m. Performing server tp.");
else
LOG_DEBUG("Stage 1. Distance is less than 60m. Performing fast tp."); LOG_DEBUG("Stage 1. Distance is less than 60m. Performing fast tp.");
taskInfo.currentStage = 0;
} taskInfo.currentStage--;
return needServerTrans;
} }
// After server responded, it will give us the waypoint target location to load. // After server responded, it will give us the waypoint target location to load.
@ -257,28 +242,16 @@ namespace cheat::feature
} }
} }
static app::Vector3 LocalEntityInfoData_get_initPos_Hook(app::LocalEntityInfoData* __this, MethodInfo* method) bool MapTeleport::LoadingManager_NeedTransByServer_Hook(app::MoleMole_LoadingManager* __this, uint32_t sceneId, app::Vector3 position, MethodInfo* method)
{
auto result = CALL_ORIGIN(LocalEntityInfoData_get_initPos_Hook, __this, method);
MapTeleport& mapTeleport = MapTeleport::GetInstance();
mapTeleport.OnGetTargetPos(result);
return result;
}
static bool LoadingManager_NeedTransByServer_Hook(app::MoleMole_LoadingManager* __this, uint32_t sceneId, app::Vector3 position, MethodInfo* method)
{ {
auto result = CALL_ORIGIN(LoadingManager_NeedTransByServer_Hook, __this, sceneId, position, method); auto result = CALL_ORIGIN(LoadingManager_NeedTransByServer_Hook, __this, sceneId, position, method);
MapTeleport& mapTeleport = MapTeleport::GetInstance(); auto& mapTeleport = GetInstance();
mapTeleport.OnCheckTeleportDistance(result); return mapTeleport.IsNeedTransByServer(result, position);
return result;
} }
static void LoadingManager_PerformPlayerTransmit_Hook(app::MoleMole_LoadingManager* __this, app::Vector3 position, app::EnterType__Enum someEnum, void MapTeleport::LoadingManager_PerformPlayerTransmit_Hook(app::MoleMole_LoadingManager* __this, app::Vector3 position, app::EnterType__Enum someEnum,
uint32_t someUint1, app::EvtTransmitAvatar_EvtTransmitAvatar_TransmitType__Enum teleportType, uint32_t someUint2, MethodInfo* method) uint32_t someUint1, app::EvtTransmitAvatar_EvtTransmitAvatar_TransmitType__Enum teleportType, uint32_t someUint2, MethodInfo* method)
{ {
MapTeleport& mapTeleport = MapTeleport::GetInstance(); MapTeleport& mapTeleport = MapTeleport::GetInstance();
@ -288,7 +261,7 @@ namespace cheat::feature
} }
static void Entity_SetRelativePosition_Hook(app::BaseEntity* __this, app::Vector3 position, bool someBool, MethodInfo* method) void MapTeleport::MoleMole_BaseEntity_SetAbsolutePosition_Hook(app::BaseEntity* __this, app::Vector3 position, bool someBool, MethodInfo* method)
{ {
auto& manager = game::EntityManager::instance(); auto& manager = game::EntityManager::instance();
if (manager.avatar()->raw() == __this) if (manager.avatar()->raw() == __this)
@ -297,7 +270,7 @@ namespace cheat::feature
mapTeleport.OnSetAvatarPosition(position); mapTeleport.OnSetAvatarPosition(position);
} }
CALL_ORIGIN(Entity_SetRelativePosition_Hook, __this, position, someBool, method); CALL_ORIGIN(MoleMole_BaseEntity_SetAbsolutePosition_Hook, __this, position, someBool, method);
} }
} }

View File

@ -22,16 +22,6 @@ namespace cheat::feature
void TeleportTo(app::Vector2 mapPosition); void TeleportTo(app::Vector2 mapPosition);
void OnGetTargetPos(app::Vector3& position);
void OnCheckTeleportDistance(bool needTransByServer);
void OnPerformPlayerTransmit(app::Vector3& position);
void OnSetAvatarPosition(app::Vector3& position);
void OnGameUpdate();
const FeatureGUIInfo& GetGUIInfo() const override; const FeatureGUIInfo& GetGUIInfo() const override;
void DrawMain() override; void DrawMain() override;
@ -47,6 +37,22 @@ namespace cheat::feature
}; };
TeleportTaskInfo taskInfo; TeleportTaskInfo taskInfo;
void OnGetTargetPos(app::Vector3& position);
bool IsNeedTransByServer(bool originResult, app::Vector3& position);
void OnPerformPlayerTransmit(app::Vector3& position);
void OnSetAvatarPosition(app::Vector3& position);
void OnGameUpdate();
// Map client interactions
static void InLevelMapPageContext_OnMapClicked_Hook(app::InLevelMapPageContext* __this, app::Vector2 screenPos, MethodInfo* method);
static void InLevelMapPageContext_OnMarkClicked_Hook(app::InLevelMapPageContext* __this, app::MonoMapMark* mark, MethodInfo* method);
// Teleporting
static bool LoadingManager_NeedTransByServer_Hook(app::MoleMole_LoadingManager* __this, uint32_t sceneId, app::Vector3 position, MethodInfo* method);
static void LoadingManager_PerformPlayerTransmit_Hook(app::MoleMole_LoadingManager* __this, app::Vector3 position, app::EnterType__Enum someEnum,
uint32_t someUint1, app::EvtTransmitAvatar_EvtTransmitAvatar_TransmitType__Enum teleportType, uint32_t someUint2, MethodInfo* method);
static void MoleMole_BaseEntity_SetAbsolutePosition_Hook(app::BaseEntity* __this, app::Vector3 position, bool someBool, MethodInfo* method);
MapTeleport(); MapTeleport();
}; };
} }