[General] Get rid of FPS drops

This commit is contained in:
momo5502 2017-07-03 15:07:47 +02:00
parent 4a302ace9b
commit e80eb6fb43
9 changed files with 121 additions and 19 deletions

View File

@ -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

View File

@ -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
} }

View File

@ -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*)

View File

@ -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)

View File

@ -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));

View File

@ -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();
}
}
} }

View File

@ -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();

View File

@ -86,16 +86,61 @@ 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)
{ {
Deflate::Semaphore _(DEFLATE_ZSTD); if (safe)
return Deflate::Compress(data); {
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);
return Deflate::Compress(data);
}
} }
std::string Deflate::ZStd::Decompress(std::string data) std::string Deflate::ZStd::Decompress(std::string data, bool safe)
{ {
Deflate::Semaphore _(DEFLATE_ZSTD); if (safe)
return Deflate::Decompress(data); {
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);
return Deflate::Decompress(data);
}
} }
Deflate::Semaphore::Semaphore(bool zstd) Deflate::Semaphore::Semaphore(bool zstd)

View File

@ -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