Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(extra-natives/five): make track junction ids permanent #3200

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 63 additions & 10 deletions code/components/extra-natives-five/src/TrackNatives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <GameInit.h>
#include <scrEngine.h>
#include <ScriptSerialization.h>
#include <queue>

class CTrain : public CVehicle
{
Expand Down Expand Up @@ -87,10 +88,19 @@ struct CTrainJunction
bool direction;
bool isActive;

CTrainJunction()
: onTrack(0), onNode(0), newTrack(0), newNode(0), direction(false), isActive(false)
{
}

CTrainJunction(int8_t track, uint32_t node, int8_t newTrack, uint32_t newNode, bool direction)
: onTrack(track), onNode(node), newTrack(newTrack), newNode(newNode), direction(direction), isActive(true)
{
}

~CTrainJunction()
{
}
};

struct scrTrackNodeInfo
Expand All @@ -101,8 +111,15 @@ struct scrTrackNodeInfo
MSGPACK_DEFINE_ARRAY(nodeIndex, trackId)
};

static std::vector<CTrainJunction> g_trackJunctions;
static std::unordered_map<int,CTrainJunction> g_trackJunctions;
static std::queue<int> g_freeTrackJunctions;
static std::mutex g_trackJunctionLock;
static const int g_maxTrackJunctions = 8912; // If this needs increasing, wtf are you doing?

static bool IsTrackJunctionIdValid(int junctionIndex)
{
return junctionIndex > 0 && junctionIndex < g_maxTrackJunctions && g_trackJunctions.find(junctionIndex) != g_trackJunctions.end();
}

static float CalculateDistance(const float& x, const float& y, const float& z, const float& x1, const float& y1, const float& z1)
{
Expand Down Expand Up @@ -193,7 +210,7 @@ static bool CTrain__Update(CTrain* self, float unk)
}

const std::lock_guard _(g_trackJunctionLock);
for (const auto& data : g_trackJunctions)
for (const auto& [_, data] : g_trackJunctions)
{
if (!data.isActive)
{
Expand Down Expand Up @@ -337,8 +354,28 @@ static InitFunction initFunction([]()
}
});

fx::ScriptEngine::RegisterNativeHandler("GET_ALL_TRACK_JUNCTIONS", [](fx::ScriptContext& context)
{
std::vector<int> junctionList;
const std::lock_guard _(g_trackJunctionLock);

for (auto& [index, _] : g_trackJunctions)
{
junctionList.push_back(index);
}

context.SetResult(fx::SerializeObject(junctionList));
});

fx::ScriptEngine::RegisterNativeHandler("REGISTER_TRACK_JUNCTION", [](fx::ScriptContext& context)
{
if (g_freeTrackJunctions.empty() || g_trackJunctions.size() >= g_maxTrackJunctions)
{
fx::scripting::Warningf("natives", "REGISTER_TRACK_JUNCTION: Reached the maximum track junctions limit (%i)\n", g_maxTrackJunctions);
context.SetResult<int>(-1);
return;
}

int8_t trackIndex = context.GetArgument<int8_t>(0);
uint32_t trackNode = context.GetArgument<uint32_t>(1);

Expand Down Expand Up @@ -375,7 +412,7 @@ static InitFunction initFunction([]()
}

const std::lock_guard _(g_trackJunctionLock);
for (const auto& data : g_trackJunctions)
for (const auto& [_, data] : g_trackJunctions)
{
if (data.direction == direction && data.onTrack == trackIndex && data.newTrack == newTrackIndex && data.onNode == trackNode && data.newNode == newTrackNode)
{
Expand All @@ -385,8 +422,12 @@ static InitFunction initFunction([]()
}
}

context.SetResult<int>(g_trackJunctions.size());
g_trackJunctions.push_back(CTrainJunction(trackIndex, trackNode, newTrackIndex, newTrackNode, direction));
int junctionIndex = g_freeTrackJunctions.front();
g_freeTrackJunctions.pop();

context.SetResult<int>(junctionIndex);
g_trackJunctions[junctionIndex] = CTrainJunction(trackIndex, trackNode, newTrackIndex, newTrackNode, direction);

});

fx::ScriptEngine::RegisterNativeHandler("REMOVE_TRACK_JUNCTION", [](fx::ScriptContext& context)
Expand All @@ -395,14 +436,15 @@ static InitFunction initFunction([]()

const std::lock_guard _(g_trackJunctionLock);

if (junctionIndex >= g_trackJunctions.size())
if (!IsTrackJunctionIdValid(junctionIndex))
{
fx::scripting::Warningf("natives", "REMOVE_TRACK_JUNCTION: Invalid junction id (%i), should be from 0 to %i\n", junctionIndex, g_trackJunctions.size());
fx::scripting::Warningf("natives", "REMOVE_TRACK_JUNCTION: Invalid junction id (%i) provided.", junctionIndex);
context.SetResult<bool>(false);
return;
}

g_trackJunctions.erase(g_trackJunctions.begin() + junctionIndex);
g_trackJunctions.erase(junctionIndex);
g_freeTrackJunctions.push(junctionIndex);

context.SetResult<bool>(true);
});
Expand All @@ -414,9 +456,9 @@ static InitFunction initFunction([]()

const std::lock_guard _(g_trackJunctionLock);

if (junctionIndex >= g_trackJunctions.size())
if (!IsTrackJunctionIdValid(junctionIndex))
{
fx::scripting::Warningf("natives", "SET_TRACK_JUNCTION_ACTIVE: Invalid junction id (%i) provided. There are %i registered junctions\n", junctionIndex, g_trackJunctions.size());
fx::scripting::Warningf("natives", "SET_TRACK_JUNCTION_ACTIVE: Invalid junction id (%i) provided.", junctionIndex);
context.SetResult<bool>(false);
return;
}
Expand Down Expand Up @@ -496,9 +538,20 @@ static HookFunction hookFunction([]()

g_CTrain__Update = hook::trampoline(hook::get_call(hook::get_pattern("E8 ? ? ? ? 44 8A B5 ? ? ? ? 48 85 F6")), CTrain__Update);


for (int i = 1; i < g_maxTrackJunctions; i++)
{
g_freeTrackJunctions.push(i);
}

OnKillNetworkDone.Connect([]()
{
const std::lock_guard _(g_trackJunctionLock);
g_trackJunctions.clear();
g_freeTrackJunctions = std::queue<int>();
for (int i = 1; i < g_maxTrackJunctions; i++)
{
g_freeTrackJunctions.push(i);
}
});
});
20 changes: 20 additions & 0 deletions ext/native-decls/GetAllTrackJunctions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
ns: CFX
apiset: client
game: gta5
---
## GET_ALL_TRACK_JUNCTIONS

```c
object GET_ALL_TRACK_JUNCTIONS();
```

Returns all track junctions on the client
The data returned adheres to the following structure:
```
[1, 2, 4, 6, 69, 420]
```

## Return value
An object containing a list of track junctions ids.
```
Loading