forked from citizenfx/fivem
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathPurePackfile.cpp
More file actions
104 lines (87 loc) · 2.68 KB
/
PurePackfile.cpp
File metadata and controls
104 lines (87 loc) · 2.68 KB
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
96
97
98
99
100
101
102
103
104
#include <StdInc.h>
#include <unordered_set>
#include <PureModeState.h>
#include <botan/sha2_32.h>
#ifdef GTA_FIVE
#include <BaseGameRpfHeaderHashes.h>
#include <UpdateRpfHeaderHashes.h>
#include <DlcRpfHeaderHashes.h>
#else
#include <BaseGameRpfHeaderHashes_RDR3.h>
#include <UpdateRpfHeaderHashes_RDR3.h>
#include <DlcRpfHeaderHashes_RDR3.h>
#endif
#include <ManualRpfHeaderHashes.h>
DLL_IMPORT void SetPackfileValidationRoutine(bool (*routine)(const char*, const uint8_t*, size_t));
constexpr size_t shaHashSize = sizeof(cfx::puremode::Sha256Result);
constexpr size_t baseGameTableSize = sizeof(cfx::puremode::baseGameSafeHashesInit) / shaHashSize;
constexpr size_t updateTableSize = sizeof(cfx::puremode::updateSafeHashesInit) / shaHashSize;
constexpr size_t dlcTableSize = sizeof(cfx::puremode::dlcSafeHashesInit) / shaHashSize;
constexpr size_t manualTableSize = sizeof(cfx::puremode::manualSafeHashesInit) / shaHashSize;
static InitFunction initFunction([]
{
if (fx::client::GetPureLevel() == 0)
{
return;
}
static std::unordered_set<cfx::puremode::Sha256Result> safeHashes;
safeHashes.reserve(baseGameTableSize + updateTableSize + dlcTableSize + manualTableSize);
for (int i = 0; i < baseGameTableSize; ++i)
{
safeHashes.insert(cfx::puremode::baseGameSafeHashesInit[i]);
}
for (int i = 0; i < updateTableSize; ++i)
{
safeHashes.insert(cfx::puremode::updateSafeHashesInit[i]);
}
for (int i = 0; i < dlcTableSize; ++i)
{
safeHashes.insert(cfx::puremode::dlcSafeHashesInit[i]);
}
for (int i = 0; i < manualTableSize; ++i)
{
safeHashes.insert(cfx::puremode::manualSafeHashesInit[i]);
}
auto validationCallback = [](const char* path, const uint8_t* header, size_t headerLength)
{
if (fx::client::GetPureLevel() == 1)
{
std::string_view pathTest{ path };
if (pathTest == "x64/audio/sfx/RESIDENT.rpf" ||
pathTest == "x64/audio/sfx/WEAPONS_PLAYER.rpf" ||
#ifdef GTA_FIVE
pathTest.find("x64/audio/sfx/STREAMED_VEHICLES") == 0 ||
pathTest.find("x64/audio/sfx/RADIO") == 0
#else
pathTest.find("x64/audio/sfx/STREAMED_AMBIENCE") == 0
#endif
)
{
return true;
}
}
std::vector<uint8_t> fixedHeader(header, header + headerLength);
#ifdef GTA_FIVE
for (size_t i = 0; i < fixedHeader.size(); i += 16)
{
auto x = *(uint32_t*)(&fixedHeader[i + 4]);
if (x != 0x7fffff00 && (x & 0x80000000) == 0)
{
auto y = (uint32_t*)(&fixedHeader[i + 12]);
if (*y)
{
*y = 1;
}
}
}
#endif
cfx::puremode::Sha256Result out;
{
Botan::SHA_256 hash;
hash.update(fixedHeader);
hash.final(reinterpret_cast<uint8_t*>(&out));
}
return (safeHashes.find(out) != safeHashes.end());
};
SetPackfileValidationRoutine(validationCallback);
});