-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathPathingModule.cpp
95 lines (83 loc) · 3.21 KB
/
PathingModule.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "pch.h"
#include "PathingModule.h"
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/MapMgr.h>
#include <future>
#include <payloads/PathingPayload.h>
#include <json.hpp>
#include <queue>
#include <GWCA/GameEntities/Pathing.h>
namespace Daybreak::Modules::PathingModule {
std::queue<std::promise<PathingPayload>*> PromiseQueue;
std::mutex GameThreadMutex;
GW::HookEntry GameThreadHook;
volatile bool initialized = false;
PathingPayload GetPayload() {
PathingPayload pathingPayload;
pathingPayload.Trapezoids.clear();
pathingPayload.AdjacencyList.clear();
if (!GW::Map::GetIsMapLoaded()) {
return pathingPayload;
}
auto pathingMap = GW::Map::GetPathingMap();
std::list<PathingTrapezoid> trapezoids;
std::map<int, std::list<int>> adjacencyMap;
for (int i = 0; i < pathingMap->size(); i++) {
auto gwPathingMap = pathingMap->at(i);
for (int j = 0; j < gwPathingMap.trapezoid_count; j++) {
auto gwTrapezoid = gwPathingMap.trapezoids[j];
PathingTrapezoid trapezoid;
trapezoid.Id = gwTrapezoid.id;
trapezoid.PathingMapId = i;
trapezoid.XTL = gwTrapezoid.XTL;
trapezoid.XBL = gwTrapezoid.XBL;
trapezoid.XTR = gwTrapezoid.XTR;
trapezoid.XBR = gwTrapezoid.XBR;
trapezoid.YT = gwTrapezoid.YT;
trapezoid.YB = gwTrapezoid.YB;
trapezoids.push_back(trapezoid);
for (int k = 0; k < 4; k++) {
auto adjacentTrapezoid = gwTrapezoid.adjacent[k];
if (adjacentTrapezoid) {
adjacencyMap[trapezoid.Id].push_back(adjacentTrapezoid->id);
}
}
}
}
std::list<std::list<int>> adjacencyList;
for (const auto& pair : adjacencyMap) {
adjacencyList.push_back(pair.second);
}
pathingPayload.Trapezoids = trapezoids;
pathingPayload.AdjacencyList = adjacencyList;
return pathingPayload;
}
void EnsureInitialized() {
GameThreadMutex.lock();
if (!initialized) {
GW::GameThread::RegisterGameThreadCallback(&GameThreadHook, [&](GW::HookStatus*) {
while (!PromiseQueue.empty()) {
auto promise = PromiseQueue.front();
PromiseQueue.pop();
try {
auto payload = GetPayload();
promise->set_value(payload);
}
catch (...) {
PathingPayload payload;
promise->set_value(payload);
}
}
});
initialized = true;
}
GameThreadMutex.unlock();
}
void GetPathingData(const httplib::Request&, httplib::Response& res) {
auto response = std::promise<PathingPayload>();
EnsureInitialized();
PromiseQueue.emplace(&response);
json responsePayload = response.get_future().get();
res.set_content(responsePayload.dump(), "text/json");
}
}