Patch traffic edge score weighting
This commit is contained in:
@@ -102,6 +102,7 @@ constexpr bool kEnableGpsProviderClassPatchTrace = false;
|
||||
constexpr bool kEnableGpsTraceHooks = true;
|
||||
constexpr bool kEnableGpsQueryLifecycleHooks = true;
|
||||
constexpr bool kEnableGpsAsyncTrafficProbe = true;
|
||||
constexpr bool kEnableGpsTrafficEdgeWeightPatch = true;
|
||||
constexpr bool kEnableGpsRouteJobLifecycleHooks = false;
|
||||
constexpr bool kEnableGpsRouteJobStartTrace = false;
|
||||
constexpr bool kEnableGpsLocalSearchHooks = false;
|
||||
@@ -165,6 +166,7 @@ constexpr uintptr_t kGpsMapRouteSubmitReturnRva = 0x08D20D4;
|
||||
constexpr uintptr_t kGpsDispatchAdvanceRva = 0x08D17D8;
|
||||
constexpr uintptr_t kGpsTrafficResultTakeRva = 0x0709D5C;
|
||||
constexpr uintptr_t kGpsRoutePostprocessRva = 0x044830C;
|
||||
constexpr uintptr_t kGpsTrafficEdgeScoreRva = 0x08D46CC;
|
||||
constexpr uintptr_t kGpsAsyncWorkerTickRva = 0x0126B28;
|
||||
constexpr uintptr_t kGpsRouteJobStartRva = 0x0818928;
|
||||
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,
|
||||
};
|
||||
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
|
||||
{
|
||||
@@ -268,6 +276,7 @@ uint32_t gGpsQueryStatusLogCount = 0;
|
||||
uint32_t gGpsDispatchAdvanceLogCount = 0;
|
||||
uint32_t gGpsTrafficResultTakeLogCount = 0;
|
||||
uint32_t gGpsRoutePostprocessLogCount = 0;
|
||||
LONG gGpsTrafficEdgeScoreLogCount = 0;
|
||||
uint32_t gGpsAsyncWorkerTickLogCount = 0;
|
||||
uint32_t gGpsRouteJobStartLogCount = 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,
|
||||
void* aOutMeta);
|
||||
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 GpsRouteJobStartFunc = bool (*)(void* aRouteSystem, void* aActiveEntry, float aDelta, void* aOutLocal);
|
||||
using GpsRouteJobPollFunc = bool (*)(void* aRouteSystem, void* aActiveEntry);
|
||||
@@ -492,6 +502,7 @@ GpsQueryStatusFunc gOriginalGpsQueryStatus = nullptr;
|
||||
GpsDispatchAdvanceFunc gOriginalGpsDispatchAdvance = nullptr;
|
||||
GpsTrafficResultTakeFunc gOriginalGpsTrafficResultTake = nullptr;
|
||||
GpsRoutePostprocessFunc gOriginalGpsRoutePostprocess = nullptr;
|
||||
GpsTrafficEdgeScoreFunc gOriginalGpsTrafficEdgeScore = nullptr;
|
||||
GpsAsyncWorkerTickFunc gOriginalGpsAsyncWorkerTick = nullptr;
|
||||
GpsRouteJobStartFunc gOriginalGpsRouteJobStart = 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)
|
||||
{
|
||||
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**>(&gOriginalGpsRoutePostprocess));
|
||||
}
|
||||
if (kEnableGpsTrafficEdgeWeightPatch)
|
||||
{
|
||||
AttachProbeHook("GPSTrafficEdgeScore 0x8d46cc", kGpsTrafficEdgeScoreRva,
|
||||
reinterpret_cast<void*>(&DetourGpsTrafficEdgeScore),
|
||||
reinterpret_cast<void**>(&gOriginalGpsTrafficEdgeScore));
|
||||
}
|
||||
if (kEnableGpsRouteJobLifecycleHooks)
|
||||
{
|
||||
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("GPSRoutePostprocess 0x44830c", kGpsRoutePostprocessRva);
|
||||
}
|
||||
if (kEnableGpsTrafficEdgeWeightPatch)
|
||||
{
|
||||
DetachProbeHook("GPSTrafficEdgeScore 0x8d46cc", kGpsTrafficEdgeScoreRva);
|
||||
}
|
||||
if (kEnableGpsRouteJobLifecycleHooks)
|
||||
{
|
||||
DetachProbeHook("GPSDispatchAdvance 0x8d17d8", kGpsDispatchAdvanceRva);
|
||||
|
||||
Reference in New Issue
Block a user