[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()
{
// Perform check only every 10 seconds
if (!AntiCheat::LastCheck.elapsed(10s)) return;
// Perform check only every 20 seconds
if (!AntiCheat::LastCheck.elapsed(20s)) return;
AntiCheat::LastCheck.update();
// Hash .text segment
@ -234,7 +234,7 @@ namespace Components
static Utils::Time::Interval interval;
static std::optional<std::string> hashVal;
if (!interval.elapsed(11s)) return;
if (!interval.elapsed(32s)) return;
interval.update();
// Hash .text segment
@ -256,7 +256,7 @@ namespace Components
static Utils::Time::Interval interval;
static std::optional<std::string> hashVal;
if (!interval.elapsed(12s)) return;
if (!interval.elapsed(42s)) return;
interval.update();
// Hash .text segment

View File

@ -57,7 +57,7 @@ namespace Components
UIFeeder::Add(62.0f, Changelog::GetChangelogCount, Changelog::GetChangelogText, Changelog::SelectChangelog);
#ifndef DISABLE_ANTICHEAT
Scheduler::OnFrame(AntiCheat::QuickCodeScanner1);
Scheduler::OnFrameAsync(AntiCheat::QuickCodeScanner1);
#endif
}

View File

@ -767,7 +767,7 @@ namespace Components
});
#ifndef DISABLE_ANTICHEAT
Scheduler::OnFrame(AntiCheat::QuickCodeScanner2);
Scheduler::OnFrameAsync(AntiCheat::QuickCodeScanner2);
#endif
Command::Add("mp_QuickMessage", [](Command::Params*)

View File

@ -114,7 +114,7 @@ namespace Components
Proto::Node::List list;
std::lock_guard<std::recursive_mutex> _(Node::Mutex);
Node::Mutex.lock();
for (auto& node : Node::Nodes)
{
if (node.isValid())
@ -125,6 +125,7 @@ namespace Components
str->append(reinterpret_cast<char*>(&addr), sizeof(addr));
}
}
Node::Mutex.unlock();
Utils::IO::WriteFile("players/nodes.dat", Utils::Compression::Deflate::ZStd::Compress(list.SerializeAsString()));
}
@ -169,8 +170,6 @@ namespace Components
++i;
}
Node::StoreNodes(false);
}
void Node::Synchronize()
@ -263,6 +262,11 @@ namespace Components
if (ZoneBuilder::IsEnabled()) return;
Dvar::Register<bool>("net_natFix", false, 0, "Fix node registration for certain firewalls/routers");
Scheduler::OnFrameAsync([]()
{
Node::StoreNodes(false);
});
Scheduler::OnFrame(Node::RunFrame);
Session::Handle("nodeListResponse", Node::HandleResponse);
Session::Handle("nodeListRequest", [](Network::Address address, std::string)

View File

@ -39,7 +39,7 @@ namespace Components
DWORD Playlist::StorePlaylistStub(const char** buffer)
{
Playlist::MapRelocation.clear();
Playlist::CurrentPlaylistBuffer = *buffer;
Playlist::CurrentPlaylistBuffer = Utils::Compression::Deflate::ZStd::Compress(*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");
std::string compressedList = Utils::Compression::Deflate::ZStd::Compress(Playlist::CurrentPlaylistBuffer);
std::string compressedList = Playlist::CurrentPlaylistBuffer;
Proto::Party::Playlist list;
list.set_hash(Utils::Cryptography::JenkinsOneAtATime::Compute(compressedList));

View File

@ -2,6 +2,9 @@
namespace Components
{
bool Scheduler::AsyncTerminate;
std::thread Scheduler::AsyncThread;
bool Scheduler::ReadyPassed = false;
Utils::Signal<Scheduler::Callback> Scheduler::ReadySignal;
Utils::Signal<Scheduler::Callback> Scheduler::ShutdownSignal;
@ -10,6 +13,9 @@ namespace Components
Utils::Signal<Scheduler::Callback> Scheduler::FrameOnceSignal;
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)
{
if (clientOnly && (Dedicated::IsEnabled() || ZoneBuilder::IsEnabled())) return;
@ -94,6 +100,15 @@ namespace Components
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()
{
@ -101,6 +116,21 @@ namespace Components
Scheduler::Once(Scheduler::ReadyHandler);
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()
@ -112,6 +142,18 @@ namespace Components
Scheduler::FrameOnceSignal.clear();
Scheduler::DelayedSlots.clear();
Scheduler::AsyncFrameSignal.clear();
Scheduler::AsyncFrameOnceSignal.clear();
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();
void preDestroy() override;
static void OnShutdown(Utils::Slot<Callback> callback);
static void OnFrame(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 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();
private:
@ -27,6 +32,9 @@ namespace Components
Utils::Slot<Callback> callback;
};
static bool AsyncTerminate;
static std::thread AsyncThread;
static Utils::Signal<Callback> FrameSignal;
static Utils::Signal<Callback> FrameOnceSignal;
static std::vector<DelayedSlot> DelayedSlots;
@ -35,6 +43,9 @@ namespace Components
static Utils::Signal<Callback> ReadySignal;
static Utils::Signal<Callback> ShutdownSignal;
static Utils::Signal<Callback> AsyncFrameSignal;
static Utils::Signal<Callback> AsyncFrameOnceSignal;
static void ReadyHandler();
static void DelaySignal();

View File

@ -86,16 +86,61 @@ namespace Utils
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);
return Deflate::Compress(data);
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);
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);
return Deflate::Decompress(data);
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);
return Deflate::Decompress(data);
}
}
Deflate::Semaphore::Semaphore(bool zstd)

View File

@ -21,8 +21,8 @@ namespace Utils
class ZStd
{
public:
static std::string Compress(std::string data);
static std::string Decompress(std::string data);
static std::string Compress(std::string data, bool safe = true);
static std::string Decompress(std::string data, bool safe = true);
};
class Semaphore