[General] Get rid of FPS drops
This commit is contained in:
parent
4a302ace9b
commit
e80eb6fb43
@ -200,8 +200,8 @@ namespace Components
|
|||||||
|
|
||||||
void AntiCheat::PerformScan()
|
void AntiCheat::PerformScan()
|
||||||
{
|
{
|
||||||
// Perform check only every 10 seconds
|
// Perform check only every 20 seconds
|
||||||
if (!AntiCheat::LastCheck.elapsed(10s)) return;
|
if (!AntiCheat::LastCheck.elapsed(20s)) return;
|
||||||
AntiCheat::LastCheck.update();
|
AntiCheat::LastCheck.update();
|
||||||
|
|
||||||
// Hash .text segment
|
// Hash .text segment
|
||||||
@ -234,7 +234,7 @@ namespace Components
|
|||||||
static Utils::Time::Interval interval;
|
static Utils::Time::Interval interval;
|
||||||
static std::optional<std::string> hashVal;
|
static std::optional<std::string> hashVal;
|
||||||
|
|
||||||
if (!interval.elapsed(11s)) return;
|
if (!interval.elapsed(32s)) return;
|
||||||
interval.update();
|
interval.update();
|
||||||
|
|
||||||
// Hash .text segment
|
// Hash .text segment
|
||||||
@ -256,7 +256,7 @@ namespace Components
|
|||||||
static Utils::Time::Interval interval;
|
static Utils::Time::Interval interval;
|
||||||
static std::optional<std::string> hashVal;
|
static std::optional<std::string> hashVal;
|
||||||
|
|
||||||
if (!interval.elapsed(12s)) return;
|
if (!interval.elapsed(42s)) return;
|
||||||
interval.update();
|
interval.update();
|
||||||
|
|
||||||
// Hash .text segment
|
// Hash .text segment
|
||||||
|
@ -57,7 +57,7 @@ namespace Components
|
|||||||
UIFeeder::Add(62.0f, Changelog::GetChangelogCount, Changelog::GetChangelogText, Changelog::SelectChangelog);
|
UIFeeder::Add(62.0f, Changelog::GetChangelogCount, Changelog::GetChangelogText, Changelog::SelectChangelog);
|
||||||
|
|
||||||
#ifndef DISABLE_ANTICHEAT
|
#ifndef DISABLE_ANTICHEAT
|
||||||
Scheduler::OnFrame(AntiCheat::QuickCodeScanner1);
|
Scheduler::OnFrameAsync(AntiCheat::QuickCodeScanner1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -767,7 +767,7 @@ namespace Components
|
|||||||
});
|
});
|
||||||
|
|
||||||
#ifndef DISABLE_ANTICHEAT
|
#ifndef DISABLE_ANTICHEAT
|
||||||
Scheduler::OnFrame(AntiCheat::QuickCodeScanner2);
|
Scheduler::OnFrameAsync(AntiCheat::QuickCodeScanner2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Command::Add("mp_QuickMessage", [](Command::Params*)
|
Command::Add("mp_QuickMessage", [](Command::Params*)
|
||||||
|
@ -114,7 +114,7 @@ namespace Components
|
|||||||
|
|
||||||
Proto::Node::List list;
|
Proto::Node::List list;
|
||||||
|
|
||||||
std::lock_guard<std::recursive_mutex> _(Node::Mutex);
|
Node::Mutex.lock();
|
||||||
for (auto& node : Node::Nodes)
|
for (auto& node : Node::Nodes)
|
||||||
{
|
{
|
||||||
if (node.isValid())
|
if (node.isValid())
|
||||||
@ -125,6 +125,7 @@ namespace Components
|
|||||||
str->append(reinterpret_cast<char*>(&addr), sizeof(addr));
|
str->append(reinterpret_cast<char*>(&addr), sizeof(addr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Node::Mutex.unlock();
|
||||||
|
|
||||||
Utils::IO::WriteFile("players/nodes.dat", Utils::Compression::Deflate::ZStd::Compress(list.SerializeAsString()));
|
Utils::IO::WriteFile("players/nodes.dat", Utils::Compression::Deflate::ZStd::Compress(list.SerializeAsString()));
|
||||||
}
|
}
|
||||||
@ -169,8 +170,6 @@ namespace Components
|
|||||||
|
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node::StoreNodes(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::Synchronize()
|
void Node::Synchronize()
|
||||||
@ -263,6 +262,11 @@ namespace Components
|
|||||||
if (ZoneBuilder::IsEnabled()) return;
|
if (ZoneBuilder::IsEnabled()) return;
|
||||||
Dvar::Register<bool>("net_natFix", false, 0, "Fix node registration for certain firewalls/routers");
|
Dvar::Register<bool>("net_natFix", false, 0, "Fix node registration for certain firewalls/routers");
|
||||||
|
|
||||||
|
Scheduler::OnFrameAsync([]()
|
||||||
|
{
|
||||||
|
Node::StoreNodes(false);
|
||||||
|
});
|
||||||
|
|
||||||
Scheduler::OnFrame(Node::RunFrame);
|
Scheduler::OnFrame(Node::RunFrame);
|
||||||
Session::Handle("nodeListResponse", Node::HandleResponse);
|
Session::Handle("nodeListResponse", Node::HandleResponse);
|
||||||
Session::Handle("nodeListRequest", [](Network::Address address, std::string)
|
Session::Handle("nodeListRequest", [](Network::Address address, std::string)
|
||||||
|
@ -39,7 +39,7 @@ namespace Components
|
|||||||
DWORD Playlist::StorePlaylistStub(const char** buffer)
|
DWORD Playlist::StorePlaylistStub(const char** buffer)
|
||||||
{
|
{
|
||||||
Playlist::MapRelocation.clear();
|
Playlist::MapRelocation.clear();
|
||||||
Playlist::CurrentPlaylistBuffer = *buffer;
|
Playlist::CurrentPlaylistBuffer = Utils::Compression::Deflate::ZStd::Compress(*buffer);
|
||||||
return Utils::Hook::Call<DWORD(const char**)>(0x4C0350)(buffer);
|
return Utils::Hook::Call<DWORD(const char**)>(0x4C0350)(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ namespace Components
|
|||||||
|
|
||||||
Logger::Print("Received playlist request, sending currently stored buffer.\n");
|
Logger::Print("Received playlist request, sending currently stored buffer.\n");
|
||||||
|
|
||||||
std::string compressedList = Utils::Compression::Deflate::ZStd::Compress(Playlist::CurrentPlaylistBuffer);
|
std::string compressedList = Playlist::CurrentPlaylistBuffer;
|
||||||
|
|
||||||
Proto::Party::Playlist list;
|
Proto::Party::Playlist list;
|
||||||
list.set_hash(Utils::Cryptography::JenkinsOneAtATime::Compute(compressedList));
|
list.set_hash(Utils::Cryptography::JenkinsOneAtATime::Compute(compressedList));
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
namespace Components
|
namespace Components
|
||||||
{
|
{
|
||||||
|
bool Scheduler::AsyncTerminate;
|
||||||
|
std::thread Scheduler::AsyncThread;
|
||||||
|
|
||||||
bool Scheduler::ReadyPassed = false;
|
bool Scheduler::ReadyPassed = false;
|
||||||
Utils::Signal<Scheduler::Callback> Scheduler::ReadySignal;
|
Utils::Signal<Scheduler::Callback> Scheduler::ReadySignal;
|
||||||
Utils::Signal<Scheduler::Callback> Scheduler::ShutdownSignal;
|
Utils::Signal<Scheduler::Callback> Scheduler::ShutdownSignal;
|
||||||
@ -10,6 +13,9 @@ namespace Components
|
|||||||
Utils::Signal<Scheduler::Callback> Scheduler::FrameOnceSignal;
|
Utils::Signal<Scheduler::Callback> Scheduler::FrameOnceSignal;
|
||||||
std::vector<Scheduler::DelayedSlot> Scheduler::DelayedSlots;
|
std::vector<Scheduler::DelayedSlot> Scheduler::DelayedSlots;
|
||||||
|
|
||||||
|
Utils::Signal<Scheduler::Callback> Scheduler::AsyncFrameSignal;
|
||||||
|
Utils::Signal<Scheduler::Callback> Scheduler::AsyncFrameOnceSignal;
|
||||||
|
|
||||||
void Scheduler::Once(Utils::Slot<Scheduler::Callback> callback, bool clientOnly)
|
void Scheduler::Once(Utils::Slot<Scheduler::Callback> callback, bool clientOnly)
|
||||||
{
|
{
|
||||||
if (clientOnly && (Dedicated::IsEnabled() || ZoneBuilder::IsEnabled())) return;
|
if (clientOnly && (Dedicated::IsEnabled() || ZoneBuilder::IsEnabled())) return;
|
||||||
@ -94,6 +100,15 @@ namespace Components
|
|||||||
Utils::Hook::Call<void(int)>(0x46B370)(num);
|
Utils::Hook::Call<void(int)>(0x46B370)(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Scheduler::OnFrameAsync(Utils::Slot<Scheduler::Callback> callback)
|
||||||
|
{
|
||||||
|
Scheduler::AsyncFrameSignal.connect(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scheduler::OnceAsync(Utils::Slot<Scheduler::Callback> callback)
|
||||||
|
{
|
||||||
|
Scheduler::AsyncFrameOnceSignal.connect(callback);
|
||||||
|
}
|
||||||
|
|
||||||
Scheduler::Scheduler()
|
Scheduler::Scheduler()
|
||||||
{
|
{
|
||||||
@ -101,6 +116,21 @@ namespace Components
|
|||||||
Scheduler::Once(Scheduler::ReadyHandler);
|
Scheduler::Once(Scheduler::ReadyHandler);
|
||||||
|
|
||||||
Utils::Hook(0x4D697A, Scheduler::ShutdownStub, HOOK_CALL).install()->quick();
|
Utils::Hook(0x4D697A, Scheduler::ShutdownStub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
|
Scheduler::AsyncTerminate = false;
|
||||||
|
Scheduler::AsyncThread = std::thread([]()
|
||||||
|
{
|
||||||
|
while (!Scheduler::AsyncTerminate)
|
||||||
|
{
|
||||||
|
Scheduler::AsyncFrameSignal();
|
||||||
|
|
||||||
|
Utils::Signal<Scheduler::Callback> copy(Scheduler::AsyncFrameOnceSignal);
|
||||||
|
Scheduler::AsyncFrameOnceSignal.clear();
|
||||||
|
copy();
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(16ms);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Scheduler::~Scheduler()
|
Scheduler::~Scheduler()
|
||||||
@ -112,6 +142,18 @@ namespace Components
|
|||||||
Scheduler::FrameOnceSignal.clear();
|
Scheduler::FrameOnceSignal.clear();
|
||||||
Scheduler::DelayedSlots.clear();
|
Scheduler::DelayedSlots.clear();
|
||||||
|
|
||||||
|
Scheduler::AsyncFrameSignal.clear();
|
||||||
|
Scheduler::AsyncFrameOnceSignal.clear();
|
||||||
|
|
||||||
Scheduler::ReadyPassed = false;
|
Scheduler::ReadyPassed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Scheduler::preDestroy()
|
||||||
|
{
|
||||||
|
Scheduler::AsyncTerminate = true;
|
||||||
|
if (Scheduler::AsyncThread.joinable())
|
||||||
|
{
|
||||||
|
Scheduler::AsyncThread.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,12 +10,17 @@ namespace Components
|
|||||||
Scheduler();
|
Scheduler();
|
||||||
~Scheduler();
|
~Scheduler();
|
||||||
|
|
||||||
|
void preDestroy() override;
|
||||||
|
|
||||||
static void OnShutdown(Utils::Slot<Callback> callback);
|
static void OnShutdown(Utils::Slot<Callback> callback);
|
||||||
static void OnFrame(Utils::Slot<Callback> callback, bool clientOnly = false);
|
static void OnFrame(Utils::Slot<Callback> callback, bool clientOnly = false);
|
||||||
static void OnReady(Utils::Slot<Callback> callback, bool clientOnly = false);
|
static void OnReady(Utils::Slot<Callback> callback, bool clientOnly = false);
|
||||||
static void Once(Utils::Slot<Callback> callback, bool clientOnly = false);
|
static void Once(Utils::Slot<Callback> callback, bool clientOnly = false);
|
||||||
static void OnDelay(Utils::Slot<Callback> callback, std::chrono::nanoseconds delay, bool clientOnly = false);
|
static void OnDelay(Utils::Slot<Callback> callback, std::chrono::nanoseconds delay, bool clientOnly = false);
|
||||||
|
|
||||||
|
static void OnFrameAsync(Utils::Slot<Callback> callback);
|
||||||
|
static void OnceAsync(Utils::Slot<Callback> callback);
|
||||||
|
|
||||||
static void FrameHandler();
|
static void FrameHandler();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -27,6 +32,9 @@ namespace Components
|
|||||||
Utils::Slot<Callback> callback;
|
Utils::Slot<Callback> callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool AsyncTerminate;
|
||||||
|
static std::thread AsyncThread;
|
||||||
|
|
||||||
static Utils::Signal<Callback> FrameSignal;
|
static Utils::Signal<Callback> FrameSignal;
|
||||||
static Utils::Signal<Callback> FrameOnceSignal;
|
static Utils::Signal<Callback> FrameOnceSignal;
|
||||||
static std::vector<DelayedSlot> DelayedSlots;
|
static std::vector<DelayedSlot> DelayedSlots;
|
||||||
@ -35,6 +43,9 @@ namespace Components
|
|||||||
static Utils::Signal<Callback> ReadySignal;
|
static Utils::Signal<Callback> ReadySignal;
|
||||||
static Utils::Signal<Callback> ShutdownSignal;
|
static Utils::Signal<Callback> ShutdownSignal;
|
||||||
|
|
||||||
|
static Utils::Signal<Callback> AsyncFrameSignal;
|
||||||
|
static Utils::Signal<Callback> AsyncFrameOnceSignal;
|
||||||
|
|
||||||
static void ReadyHandler();
|
static void ReadyHandler();
|
||||||
static void DelaySignal();
|
static void DelaySignal();
|
||||||
|
|
||||||
|
@ -86,17 +86,62 @@ namespace Utils
|
|||||||
return Deflate::Decompress(data);
|
return Deflate::Decompress(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Deflate::ZStd::Compress(std::string data)
|
std::string Deflate::ZStd::Compress(std::string data, bool safe)
|
||||||
|
{
|
||||||
|
if (safe)
|
||||||
|
{
|
||||||
|
Utils::Memory::Allocator allocator;
|
||||||
|
|
||||||
|
size_t size = data.size() + 100;
|
||||||
|
size = ZSTD_compressBound(size);
|
||||||
|
char* buffer = allocator.allocateArray<char>(size);
|
||||||
|
|
||||||
|
size = ZSTD_compress(buffer, size, data.data(), data.size(), ZSTD_maxCLevel());
|
||||||
|
if (size == 0 || ZSTD_isError(size)) return "";
|
||||||
|
|
||||||
|
return std::string(buffer, size);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
Deflate::Semaphore _(DEFLATE_ZSTD);
|
Deflate::Semaphore _(DEFLATE_ZSTD);
|
||||||
return Deflate::Compress(data);
|
return Deflate::Compress(data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string Deflate::ZStd::Decompress(std::string data)
|
std::string Deflate::ZStd::Decompress(std::string data, bool safe)
|
||||||
|
{
|
||||||
|
if (safe)
|
||||||
|
{
|
||||||
|
if (data.empty()) return "";
|
||||||
|
|
||||||
|
Utils::Memory::Allocator allocator;
|
||||||
|
|
||||||
|
size_t size = data.size() + 100;
|
||||||
|
size = ZSTD_compressBound(size);
|
||||||
|
size_t maxSize = size;
|
||||||
|
char* buffer = allocator.allocateArray<char>(size);
|
||||||
|
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
size = ZSTD_decompress(buffer, size, data.data(), data.size());
|
||||||
|
if (!ZSTD_isError(size)) break;
|
||||||
|
|
||||||
|
maxSize++;
|
||||||
|
maxSize *= 2;
|
||||||
|
size = maxSize;
|
||||||
|
|
||||||
|
allocator.free(buffer);
|
||||||
|
buffer = allocator.allocateArray<char>(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::string(buffer, size);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
Deflate::Semaphore _(DEFLATE_ZSTD);
|
Deflate::Semaphore _(DEFLATE_ZSTD);
|
||||||
return Deflate::Decompress(data);
|
return Deflate::Decompress(data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Deflate::Semaphore::Semaphore(bool zstd)
|
Deflate::Semaphore::Semaphore(bool zstd)
|
||||||
{
|
{
|
||||||
|
@ -21,8 +21,8 @@ namespace Utils
|
|||||||
class ZStd
|
class ZStd
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::string Compress(std::string data);
|
static std::string Compress(std::string data, bool safe = true);
|
||||||
static std::string Decompress(std::string data);
|
static std::string Decompress(std::string data, bool safe = true);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Semaphore
|
class Semaphore
|
||||||
|
Loading…
Reference in New Issue
Block a user