Skip to content

Commit

Permalink
feat: add TimerFix
Browse files Browse the repository at this point in the history
  • Loading branch information
Dofes committed Jan 8, 2025
1 parent 0815e38 commit ff5ee7b
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 5 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Upon its first run, LeviOptimize will generate configuration files in `mod/LeviO
- **`optMovingBlock`**: Improves FPS and TPS by optimizing block entities' processing during piston movements.
- **`fixChunkLeak`**: Addresses the issue of chunks remaining loaded after players leave.
- **`fixPowerAssocMap`**:Fixes the memory leak issue in PowerAssociationMap. from [glibcxx/PowerAssociationMapLeakFix](https://github.com/glibcxx/PowerAssociationMapLeakFix)
- **`fixTimer`**: Fixes the accuracy issue of timer. from [glibcxx/TimerFix](https://github.com/glibcxx/TimerFix)
- **`optSeenPercent`**: Caches "SeenPercent" values to improve TPS, with a note of caution regarding potential hash collisions.
- **`optPacketSender`**: Optimizes the packet sending process to improve server performance.
>Some mods rely on this feature to achieve multi-threaded sending packets, it is best to keep it enabled.
Expand Down
1 change: 1 addition & 0 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ lip install github.com/LiteLDev/LeviOptimize
- **`optMovingBlock`**:通过优化活塞运动过程中的方块实体处理来提高FPS和TPS。
- **`fixChunkLeak`**:修复玩家离开后区块未卸载的问题。
- **`fixPowerAssocMap`**:修复PowerAssociationMap的内存泄漏问题。from [glibcxx/PowerAssociationMapLeakFix](https://github.com/glibcxx/PowerAssociationMapLeakFix)
- **`fixTimer`**: 修复计时器的精度问题。 from [glibcxx/TimerFix](https://github.com/glibcxx/TimerFix)
- **`optSeenPercent`**:缓存特定坐标及其相应边界框内的“SeenPercent”值,以提高TPS。由于存在哈希冲突可能导致性能下降的可能性,实际效果不确定。
- **`optPacketSender`**:优化数据包发送过程以提高服务器性能。
> 一些插件依赖此功能以实现多线程发包,最好保持启用。
Expand Down
3 changes: 2 additions & 1 deletion src/levioptimize/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ namespace lo {
using ll::reflection::Dispatcher;
struct Config {

int version = 12;
int version = 13;

struct {
Dispatcher<bool, moving_block_opt::MovingBlockOpt> optMovingBlock = true;
Dispatcher<bool, hopper_item_opt::HopperItemOpt> optHopperItem = true;
Dispatcher<bool, chunk_leak_fix::ChunkLeakFix> fixChunkLeak = true;
Dispatcher<bool, power_association_map_leak_fix::PowerAssociationMapLeakFix> fixPowerAssocMap = true;
Dispatcher<bool, timer_fix::TimerFix> fixTimer = true;
Dispatcher<bool, seen_percent_opt::SeenPercentOpt> optSeenPercent = true;
Dispatcher<packet_sender_opt::Config, packet_sender_opt::PacketSenderOpt> packetSenderOpt = true;
Dispatcher<bool, player_lookup_opt::PlayerLookupOpt> playerLookupOpt = true;
Expand Down
8 changes: 4 additions & 4 deletions src/levioptimize/features/PowerAssociationMapLeakFix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ LL_TYPE_INSTANCE_HOOK(
&CircuitSceneGraph::removeStaleRelationships,
void
) {
for (auto iterUpdate = this->mPendingUpdates.begin(); iterUpdate != this->mPendingUpdates.end(); iterUpdate++) {
for (auto iterUpdate = mPendingUpdates.begin(); iterUpdate != mPendingUpdates.end(); iterUpdate++) {
BlockPos& posUpdate = *iterUpdate->second.mPos;
auto powerAssociationIter = this->mPowerAssociationMap.find(posUpdate);
if (powerAssociationIter != this->mPowerAssociationMap.end()) {
auto powerAssociationIter = mPowerAssociationMap.find(posUpdate);
if (powerAssociationIter != mPowerAssociationMap.end()) {
CircuitComponentList& relationships = powerAssociationIter->second;
for (auto perChunkIter = relationships.mComponents.begin();
perChunkIter != relationships.mComponents.end();) {
perChunkIter = relationships.mComponents.erase(perChunkIter);
auto allListIter = this->mAllComponents.find(perChunkIter->mPos);
auto allListIter = mAllComponents.find(perChunkIter->mPos);
if (allListIter != mAllComponents.end()) {
allListIter->second->removeSource(posUpdate, iterUpdate->second.mRawComponentPtr);
}
Expand Down
103 changes: 103 additions & 0 deletions src/levioptimize/features/TimerFix.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#include "features.h"
#include "ll/api/memory/Hook.h"
#include "mc/util/Timer.h"

namespace lo::timer_fix {
float inlineClamp(float value, float min, float max) { return (value < min) ? min : (value > max) ? max : value; }

using namespace ll::literals;

class FixedTimer : public Timer {
public:
FixedTimer(
float ticksPerSecond,
::std::function<int64()> getTimeMSCallback = []() -> int64 { return Timer::getMillisecondsSinceLaunch(); }

)
: Timer(ticksPerSecond, getTimeMSCallback) {}

double mLastTimeSecondsFixed = mLastMs * 0.001;
};

LL_STATIC_HOOK(
TimerCtorHook,
ll::memory::HookPriority::Highest,
"??$make_unique@VTimer@@AEBH$0A@@std@@YA?AV?$unique_ptr@VTimer@@U?$default_delete@VTimer@@@std@@@0@AEBH@Z"_sym,
std::unique_ptr<Timer>,
int const& ticksPerSecond
) {
return std::make_unique<FixedTimer>(ticksPerSecond);
}

LL_TYPE_INSTANCE_HOOK(
TimerUpdateHook,
ll::memory::HookPriority::Highest,
FixedTimer,
&Timer::advanceTime,
void,
float preferredFrameStep
) {
if (mSteppingTick >= 0) {
if (mSteppingTick) {
mTicks = 1;
--mSteppingTick;
} else {
mTicks = 0;
mAlpha = 0.0f;
}
} else {
int64 nowMs = mGetTimeMSCallback.get()();
int64 passedMs = nowMs - mLastMs;
if (passedMs > 1000) {
int64 passedMsSysTime = nowMs - mLastMsSysTime;
if (passedMsSysTime == 0) {
passedMsSysTime = 1;
passedMs = 1;
}
double adjustTimeT = (double)passedMs / (double)passedMsSysTime;
mAdjustTime += (adjustTimeT - mAdjustTime) * 0.2;
mLastMs = nowMs;
mLastMsSysTime = nowMs;
}
if (passedMs < 0) {
mLastMs = nowMs;
mLastMsSysTime = nowMs;
}
double passedSeconds = (nowMs * 0.001 - mLastTimeSecondsFixed) * mAdjustTime; // the key modification
mLastTimeSeconds = mLastTimeSecondsFixed = nowMs * 0.001;
if (preferredFrameStep > 0.0f) {
float newFrameStepAlignmentRemainder = inlineClamp(
mFrameStepAlignmentRemainder + preferredFrameStep - passedSeconds,
0.0f,
4.0f * preferredFrameStep
);
passedSeconds -= mFrameStepAlignmentRemainder - newFrameStepAlignmentRemainder;
mFrameStepAlignmentRemainder = newFrameStepAlignmentRemainder;
}
if (passedSeconds < 0.0) passedSeconds = 0.0;
if (passedSeconds > 0.1) passedSeconds = 0.1;
mLastTimestep = passedSeconds;
mPassedTime += passedSeconds * mTimeScale * mTicksPerSecond;
mTicks = mPassedTime;
mPassedTime -= mTicks;
if (mTicks > 10) mTicks = 10;
mAlpha = mPassedTime;
}
}

struct TimerFix::Impl {
ll::memory::HookRegistrar<TimerCtorHook, TimerUpdateHook> r;
};

void TimerFix::call(bool enable) {
if (enable) {
if (!impl) impl = std::make_unique<Impl>();
} else {
impl.reset();
}
}

TimerFix::TimerFix() = default;
TimerFix::~TimerFix() = default;

} // namespace lo::timer_fix
12 changes: 12 additions & 0 deletions src/levioptimize/features/features.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ struct PowerAssociationMapLeakFix {
~PowerAssociationMapLeakFix();
};
} // namespace power_association_map_leak_fix

namespace timer_fix {
struct TimerFix {
struct Impl;
std::unique_ptr<Impl> impl;

void call(bool);
TimerFix();
~TimerFix();
};
} // namespace chunk_leak_fix

namespace push_entity_opt {
struct Config {
bool enable = true;
Expand Down

0 comments on commit ff5ee7b

Please sign in to comment.