Patch traffic edge score weighting
This commit is contained in:
@@ -102,6 +102,7 @@ constexpr bool kEnableGpsProviderClassPatchTrace = false;
|
|||||||
constexpr bool kEnableGpsTraceHooks = true;
|
constexpr bool kEnableGpsTraceHooks = true;
|
||||||
constexpr bool kEnableGpsQueryLifecycleHooks = true;
|
constexpr bool kEnableGpsQueryLifecycleHooks = true;
|
||||||
constexpr bool kEnableGpsAsyncTrafficProbe = true;
|
constexpr bool kEnableGpsAsyncTrafficProbe = true;
|
||||||
|
constexpr bool kEnableGpsTrafficEdgeWeightPatch = true;
|
||||||
constexpr bool kEnableGpsRouteJobLifecycleHooks = false;
|
constexpr bool kEnableGpsRouteJobLifecycleHooks = false;
|
||||||
constexpr bool kEnableGpsRouteJobStartTrace = false;
|
constexpr bool kEnableGpsRouteJobStartTrace = false;
|
||||||
constexpr bool kEnableGpsLocalSearchHooks = false;
|
constexpr bool kEnableGpsLocalSearchHooks = false;
|
||||||
@@ -165,6 +166,7 @@ constexpr uintptr_t kGpsMapRouteSubmitReturnRva = 0x08D20D4;
|
|||||||
constexpr uintptr_t kGpsDispatchAdvanceRva = 0x08D17D8;
|
constexpr uintptr_t kGpsDispatchAdvanceRva = 0x08D17D8;
|
||||||
constexpr uintptr_t kGpsTrafficResultTakeRva = 0x0709D5C;
|
constexpr uintptr_t kGpsTrafficResultTakeRva = 0x0709D5C;
|
||||||
constexpr uintptr_t kGpsRoutePostprocessRva = 0x044830C;
|
constexpr uintptr_t kGpsRoutePostprocessRva = 0x044830C;
|
||||||
|
constexpr uintptr_t kGpsTrafficEdgeScoreRva = 0x08D46CC;
|
||||||
constexpr uintptr_t kGpsAsyncWorkerTickRva = 0x0126B28;
|
constexpr uintptr_t kGpsAsyncWorkerTickRva = 0x0126B28;
|
||||||
constexpr uintptr_t kGpsRouteJobStartRva = 0x0818928;
|
constexpr uintptr_t kGpsRouteJobStartRva = 0x0818928;
|
||||||
constexpr uintptr_t kGpsRouteJobPollRva = 0x0883CD8;
|
constexpr uintptr_t kGpsRouteJobPollRva = 0x0883CD8;
|
||||||
@@ -189,6 +191,12 @@ constexpr std::array<float, 7> kGpsPatchedCostMultipliers = {
|
|||||||
12.0f, 7.0f, 2.5f, 0.0f, 3.0f, 2.0f, 1.25f,
|
12.0f, 7.0f, 2.5f, 0.0f, 3.0f, 2.0f, 1.25f,
|
||||||
};
|
};
|
||||||
constexpr size_t kGpsProviderClassCount = 64;
|
constexpr size_t kGpsProviderClassCount = 64;
|
||||||
|
constexpr uint16_t kTrafficLaneFlagPavement = 0x0008;
|
||||||
|
constexpr uint16_t kTrafficLaneFlagRoad = 0x0010;
|
||||||
|
constexpr uint16_t kTrafficLaneFlagGpsOnly = 0x0200;
|
||||||
|
constexpr uint16_t kTrafficLaneFlagNoAiDriving = 0x2000;
|
||||||
|
constexpr uint16_t kTrafficLaneFlagHighway = 0x4000;
|
||||||
|
constexpr uint16_t kTrafficLaneFlagNoAutodrive = 0x8000;
|
||||||
|
|
||||||
struct GpsProviderClassOverride
|
struct GpsProviderClassOverride
|
||||||
{
|
{
|
||||||
@@ -268,6 +276,7 @@ uint32_t gGpsQueryStatusLogCount = 0;
|
|||||||
uint32_t gGpsDispatchAdvanceLogCount = 0;
|
uint32_t gGpsDispatchAdvanceLogCount = 0;
|
||||||
uint32_t gGpsTrafficResultTakeLogCount = 0;
|
uint32_t gGpsTrafficResultTakeLogCount = 0;
|
||||||
uint32_t gGpsRoutePostprocessLogCount = 0;
|
uint32_t gGpsRoutePostprocessLogCount = 0;
|
||||||
|
LONG gGpsTrafficEdgeScoreLogCount = 0;
|
||||||
uint32_t gGpsAsyncWorkerTickLogCount = 0;
|
uint32_t gGpsAsyncWorkerTickLogCount = 0;
|
||||||
uint32_t gGpsRouteJobStartLogCount = 0;
|
uint32_t gGpsRouteJobStartLogCount = 0;
|
||||||
uint32_t gGpsRouteJobPollLogCount = 0;
|
uint32_t gGpsRouteJobPollLogCount = 0;
|
||||||
@@ -423,6 +432,7 @@ using GpsDispatchAdvanceFunc = void (*)(void* aRouteSystem, void* aRuntimeQuery,
|
|||||||
using GpsTrafficResultTakeFunc = void* (*)(void* aTrafficService, void* aOutResult, uint32_t aTicket,
|
using GpsTrafficResultTakeFunc = void* (*)(void* aTrafficService, void* aOutResult, uint32_t aTicket,
|
||||||
void* aOutMeta);
|
void* aOutMeta);
|
||||||
using GpsRoutePostprocessFunc = void (*)(void* aOutPath, void* aTrafficResult, void* aRouteRecords, float aScale);
|
using GpsRoutePostprocessFunc = void (*)(void* aOutPath, void* aTrafficResult, void* aRouteRecords, float aScale);
|
||||||
|
using GpsTrafficEdgeScoreFunc = float (*)(void* aSearchContext, void* aCandidate, void* aReferencePoint);
|
||||||
using GpsAsyncWorkerTickFunc = void (*)(void* aRouteSystem);
|
using GpsAsyncWorkerTickFunc = void (*)(void* aRouteSystem);
|
||||||
using GpsRouteJobStartFunc = bool (*)(void* aRouteSystem, void* aActiveEntry, float aDelta, void* aOutLocal);
|
using GpsRouteJobStartFunc = bool (*)(void* aRouteSystem, void* aActiveEntry, float aDelta, void* aOutLocal);
|
||||||
using GpsRouteJobPollFunc = bool (*)(void* aRouteSystem, void* aActiveEntry);
|
using GpsRouteJobPollFunc = bool (*)(void* aRouteSystem, void* aActiveEntry);
|
||||||
@@ -492,6 +502,7 @@ GpsQueryStatusFunc gOriginalGpsQueryStatus = nullptr;
|
|||||||
GpsDispatchAdvanceFunc gOriginalGpsDispatchAdvance = nullptr;
|
GpsDispatchAdvanceFunc gOriginalGpsDispatchAdvance = nullptr;
|
||||||
GpsTrafficResultTakeFunc gOriginalGpsTrafficResultTake = nullptr;
|
GpsTrafficResultTakeFunc gOriginalGpsTrafficResultTake = nullptr;
|
||||||
GpsRoutePostprocessFunc gOriginalGpsRoutePostprocess = nullptr;
|
GpsRoutePostprocessFunc gOriginalGpsRoutePostprocess = nullptr;
|
||||||
|
GpsTrafficEdgeScoreFunc gOriginalGpsTrafficEdgeScore = nullptr;
|
||||||
GpsAsyncWorkerTickFunc gOriginalGpsAsyncWorkerTick = nullptr;
|
GpsAsyncWorkerTickFunc gOriginalGpsAsyncWorkerTick = nullptr;
|
||||||
GpsRouteJobStartFunc gOriginalGpsRouteJobStart = nullptr;
|
GpsRouteJobStartFunc gOriginalGpsRouteJobStart = nullptr;
|
||||||
GpsRouteJobPollFunc gOriginalGpsRouteJobPoll = nullptr;
|
GpsRouteJobPollFunc gOriginalGpsRouteJobPoll = nullptr;
|
||||||
@@ -3759,6 +3770,122 @@ void DetourGpsRoutePostprocess(void* aOutPath, void* aTrafficResult, void* aRout
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* TrafficLaneCategory(uint16_t aFlags)
|
||||||
|
{
|
||||||
|
if ((aFlags & kTrafficLaneFlagHighway) != 0)
|
||||||
|
{
|
||||||
|
return "highway";
|
||||||
|
}
|
||||||
|
if ((aFlags & kTrafficLaneFlagRoad) != 0)
|
||||||
|
{
|
||||||
|
return "road";
|
||||||
|
}
|
||||||
|
if ((aFlags & kTrafficLaneFlagPavement) != 0)
|
||||||
|
{
|
||||||
|
return "pavement";
|
||||||
|
}
|
||||||
|
if ((aFlags & kTrafficLaneFlagGpsOnly) != 0)
|
||||||
|
{
|
||||||
|
return "gpsonly";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "other";
|
||||||
|
}
|
||||||
|
|
||||||
|
float TrafficEdgeScoreMultiplier(uint16_t aFlags, bool aDriving)
|
||||||
|
{
|
||||||
|
if (!aDriving)
|
||||||
|
{
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((aFlags & kTrafficLaneFlagHighway) != 0)
|
||||||
|
{
|
||||||
|
return 0.35f;
|
||||||
|
}
|
||||||
|
if ((aFlags & kTrafficLaneFlagRoad) != 0)
|
||||||
|
{
|
||||||
|
return 0.70f;
|
||||||
|
}
|
||||||
|
if ((aFlags & kTrafficLaneFlagGpsOnly) != 0)
|
||||||
|
{
|
||||||
|
return 1.35f;
|
||||||
|
}
|
||||||
|
if ((aFlags & kTrafficLaneFlagPavement) != 0)
|
||||||
|
{
|
||||||
|
return 2.75f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.50f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float DetourGpsTrafficEdgeScore(void* aSearchContext, void* aCandidate, void* aReferencePoint)
|
||||||
|
{
|
||||||
|
float baseScore = 0.0f;
|
||||||
|
if (gOriginalGpsTrafficEdgeScore)
|
||||||
|
{
|
||||||
|
baseScore = gOriginalGpsTrafficEdgeScore(aSearchContext, aCandidate, aReferencePoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* query = nullptr;
|
||||||
|
void* lane = nullptr;
|
||||||
|
uint8_t queryMode = 0xFF;
|
||||||
|
uint16_t laneFlags = 0;
|
||||||
|
|
||||||
|
if (aSearchContext)
|
||||||
|
{
|
||||||
|
query = *reinterpret_cast<void**>(reinterpret_cast<uintptr_t>(aSearchContext) + 0x10);
|
||||||
|
}
|
||||||
|
if (query)
|
||||||
|
{
|
||||||
|
queryMode = *reinterpret_cast<uint8_t*>(reinterpret_cast<uintptr_t>(query) + 0x41);
|
||||||
|
}
|
||||||
|
if (aCandidate)
|
||||||
|
{
|
||||||
|
lane = *reinterpret_cast<void**>(aCandidate);
|
||||||
|
}
|
||||||
|
if (lane)
|
||||||
|
{
|
||||||
|
laneFlags = *reinterpret_cast<uint16_t*>(reinterpret_cast<uintptr_t>(lane) + 0x88);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto driving = queryMode == 0;
|
||||||
|
const auto multiplier = TrafficEdgeScoreMultiplier(laneFlags, driving);
|
||||||
|
const auto patchedScore = baseScore * multiplier;
|
||||||
|
|
||||||
|
constexpr LONG kMaxLoggedCalls = 256;
|
||||||
|
LONG callCount = -1;
|
||||||
|
if (gGpsTrafficEdgeScoreLogCount < kMaxLoggedCalls)
|
||||||
|
{
|
||||||
|
callCount = InterlockedIncrement(&gGpsTrafficEdgeScoreLogCount) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callCount >= 0 && callCount < kMaxLoggedCalls)
|
||||||
|
{
|
||||||
|
std::ostringstream line;
|
||||||
|
const auto flags = line.flags();
|
||||||
|
const auto precision = line.precision();
|
||||||
|
line << "hook GPSTrafficEdgeScore 0x8d46cc call=" << callCount
|
||||||
|
<< " category=" << TrafficLaneCategory(laneFlags)
|
||||||
|
<< " driving=" << static_cast<uint32_t>(driving)
|
||||||
|
<< " query41=" << static_cast<uint32_t>(queryMode)
|
||||||
|
<< " laneFlags88=0x" << std::hex << laneFlags << std::dec
|
||||||
|
<< " base=" << std::fixed << std::setprecision(3) << baseScore
|
||||||
|
<< " multiplier=" << multiplier
|
||||||
|
<< " result=" << patchedScore;
|
||||||
|
line.flags(flags);
|
||||||
|
line.precision(precision);
|
||||||
|
AppendPointerWithRva(line, "ctx", aSearchContext);
|
||||||
|
AppendPointerWithRva(line, "query", query);
|
||||||
|
AppendPointerWithRva(line, "candidate", aCandidate);
|
||||||
|
AppendPointerWithRva(line, "lane", lane);
|
||||||
|
AppendReturnRva(line, __builtin_return_address(0));
|
||||||
|
LogRed4ext(line.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return patchedScore;
|
||||||
|
}
|
||||||
|
|
||||||
void DetourGpsAsyncWorkerTick(void* aRouteSystem)
|
void DetourGpsAsyncWorkerTick(void* aRouteSystem)
|
||||||
{
|
{
|
||||||
constexpr uint32_t kMaxCalls = 192;
|
constexpr uint32_t kMaxCalls = 192;
|
||||||
@@ -4667,6 +4794,12 @@ RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::v1::PluginHandle aHandle, RED4e
|
|||||||
reinterpret_cast<void*>(&DetourGpsRoutePostprocess),
|
reinterpret_cast<void*>(&DetourGpsRoutePostprocess),
|
||||||
reinterpret_cast<void**>(&gOriginalGpsRoutePostprocess));
|
reinterpret_cast<void**>(&gOriginalGpsRoutePostprocess));
|
||||||
}
|
}
|
||||||
|
if (kEnableGpsTrafficEdgeWeightPatch)
|
||||||
|
{
|
||||||
|
AttachProbeHook("GPSTrafficEdgeScore 0x8d46cc", kGpsTrafficEdgeScoreRva,
|
||||||
|
reinterpret_cast<void*>(&DetourGpsTrafficEdgeScore),
|
||||||
|
reinterpret_cast<void**>(&gOriginalGpsTrafficEdgeScore));
|
||||||
|
}
|
||||||
if (kEnableGpsRouteJobLifecycleHooks)
|
if (kEnableGpsRouteJobLifecycleHooks)
|
||||||
{
|
{
|
||||||
AttachProbeHook("GPSDispatchAdvance 0x8d17d8", kGpsDispatchAdvanceRva,
|
AttachProbeHook("GPSDispatchAdvance 0x8d17d8", kGpsDispatchAdvanceRva,
|
||||||
@@ -4853,6 +4986,10 @@ RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::v1::PluginHandle aHandle, RED4e
|
|||||||
DetachProbeHook("GPSTrafficResultTake 0x709d5c", kGpsTrafficResultTakeRva);
|
DetachProbeHook("GPSTrafficResultTake 0x709d5c", kGpsTrafficResultTakeRva);
|
||||||
DetachProbeHook("GPSRoutePostprocess 0x44830c", kGpsRoutePostprocessRva);
|
DetachProbeHook("GPSRoutePostprocess 0x44830c", kGpsRoutePostprocessRva);
|
||||||
}
|
}
|
||||||
|
if (kEnableGpsTrafficEdgeWeightPatch)
|
||||||
|
{
|
||||||
|
DetachProbeHook("GPSTrafficEdgeScore 0x8d46cc", kGpsTrafficEdgeScoreRva);
|
||||||
|
}
|
||||||
if (kEnableGpsRouteJobLifecycleHooks)
|
if (kEnableGpsRouteJobLifecycleHooks)
|
||||||
{
|
{
|
||||||
DetachProbeHook("GPSDispatchAdvance 0x8d17d8", kGpsDispatchAdvanceRva);
|
DetachProbeHook("GPSDispatchAdvance 0x8d17d8", kGpsDispatchAdvanceRva);
|
||||||
|
|||||||
Reference in New Issue
Block a user