mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-21 16:24:05 +00:00
Firehose auto-tick-rate anti-feature, closes #2665
This commit is contained in:
parent
d9880de2ef
commit
6bd43a8215
@ -108,12 +108,11 @@ class StatusCommand extends VanillaCommand{
|
||||
|
||||
foreach($server->getLevelManager()->getLevels() as $level){
|
||||
$levelName = $level->getFolderName() !== $level->getDisplayName() ? " (" . $level->getDisplayName() . ")" : "";
|
||||
$timeColor = ($level->getTickRate() > 1 or $level->getTickRateTime() > 40) ? TextFormat::RED : TextFormat::YELLOW;
|
||||
$tickRate = $level->getTickRate() > 1 ? " (tick rate " . $level->getTickRate() . ")" : "";
|
||||
$timeColor = $level->getTickRateTime() > 40 ? TextFormat::RED : TextFormat::YELLOW;
|
||||
$sender->sendMessage(TextFormat::GOLD . "World \"{$level->getFolderName()}\"$levelName: " .
|
||||
TextFormat::RED . number_format(count($level->getChunks())) . TextFormat::GREEN . " chunks, " .
|
||||
TextFormat::RED . number_format(count($level->getEntities())) . TextFormat::GREEN . " entities. " .
|
||||
"Time $timeColor" . round($level->getTickRateTime(), 2) . "ms" . $tickRate
|
||||
"Time $timeColor" . round($level->getTickRateTime(), 2) . "ms"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1422,7 +1422,8 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
||||
|
||||
assert(abs($dx) <= 20 and abs($dy) <= 20 and abs($dz) <= 20, "Movement distance is excessive: dx=$dx, dy=$dy, dz=$dz");
|
||||
|
||||
$list = $this->level->getCollisionBoxes($this, $this->level->getTickRate() > 1 ? $this->boundingBox->offsetCopy($dx, $dy, $dz) : $this->boundingBox->addCoord($dx, $dy, $dz), false);
|
||||
//TODO: bad hack here will cause unexpected behaviour under heavy lag
|
||||
$list = $this->level->getCollisionBoxes($this, $this->level->getTickRateTime() > 50 ? $this->boundingBox->offsetCopy($dx, $dy, $dz) : $this->boundingBox->addCoord($dx, $dy, $dz), false);
|
||||
|
||||
foreach($list as $bb){
|
||||
$dy = $bb->calculateYOffset($this->boundingBox, $dy);
|
||||
|
@ -256,12 +256,8 @@ class Level implements ChunkManager, Metadatable{
|
||||
/** @var LevelTimings */
|
||||
public $timings;
|
||||
|
||||
/** @var int */
|
||||
private $tickRate;
|
||||
/** @var int */
|
||||
public $tickRateTime = 0;
|
||||
/** @var int */
|
||||
public $tickRateCounter = 0;
|
||||
|
||||
/** @var bool */
|
||||
private $doingTick = false;
|
||||
@ -401,21 +397,12 @@ class Level implements ChunkManager, Metadatable{
|
||||
$this->timings = new LevelTimings($this);
|
||||
$this->temporalPosition = new Position(0, 0, 0, $this);
|
||||
$this->temporalVector = new Vector3(0, 0, 0);
|
||||
$this->tickRate = 1;
|
||||
}
|
||||
|
||||
public function getTickRate() : int{
|
||||
return $this->tickRate;
|
||||
}
|
||||
|
||||
public function getTickRateTime() : float{
|
||||
return $this->tickRateTime;
|
||||
}
|
||||
|
||||
public function setTickRate(int $tickRate){
|
||||
$this->tickRate = $tickRate;
|
||||
}
|
||||
|
||||
public function registerGeneratorToWorker(int $worker) : void{
|
||||
$this->generatorRegisteredWorkers[$worker] = true;
|
||||
$this->server->getAsyncPool()->submitTaskToWorker(new GeneratorRegisterTask($this, $this->generator, $this->provider->getLevelData()->getGeneratorOptions()), $worker);
|
||||
|
@ -40,11 +40,8 @@ use function array_shift;
|
||||
use function asort;
|
||||
use function assert;
|
||||
use function count;
|
||||
use function floor;
|
||||
use function implode;
|
||||
use function max;
|
||||
use function microtime;
|
||||
use function min;
|
||||
use function random_int;
|
||||
use function round;
|
||||
use function sprintf;
|
||||
@ -61,31 +58,17 @@ class LevelManager{
|
||||
/** @var Server */
|
||||
private $server;
|
||||
|
||||
/** @var bool */
|
||||
private $autoTickRate = true;
|
||||
/** @var int */
|
||||
private $autoTickRateLimit = 20;
|
||||
/** @var bool */
|
||||
private $alwaysTickPlayers = false;
|
||||
/** @var int */
|
||||
private $baseTickRate = 1;
|
||||
/** @var bool */
|
||||
private $autoSave = true;
|
||||
/** @var int */
|
||||
private $autoSaveTicks = 6000;
|
||||
|
||||
|
||||
/** @var int */
|
||||
private $autoSaveTicker = 0;
|
||||
|
||||
public function __construct(Server $server){
|
||||
$this->server = $server;
|
||||
|
||||
$this->autoTickRate = (bool) $this->server->getProperty("level-settings.auto-tick-rate", $this->autoTickRate);
|
||||
$this->autoTickRateLimit = (int) $this->server->getProperty("level-settings.auto-tick-rate-limit", $this->autoTickRateLimit);
|
||||
$this->alwaysTickPlayers = (bool) $this->server->getProperty("level-settings.always-tick-players", $this->alwaysTickPlayers);
|
||||
$this->baseTickRate = (int) $this->server->getProperty("level-settings.base-tick-rate", $this->baseTickRate);
|
||||
|
||||
$this->autoSave = $this->server->getConfigBool("auto-save", $this->autoSave);
|
||||
$this->autoSaveTicks = (int) $this->server->getProperty("ticks-per.autosave", 6000);
|
||||
}
|
||||
@ -239,7 +222,6 @@ class LevelManager{
|
||||
}
|
||||
|
||||
$this->levels[$level->getId()] = $level;
|
||||
$level->setTickRate($this->baseTickRate);
|
||||
$level->setAutoSave($this->autoSave);
|
||||
|
||||
(new LevelLoadEvent($level))->call();
|
||||
@ -278,7 +260,6 @@ class LevelManager{
|
||||
$level = new Level($this->server, $name, new $providerClass($path));
|
||||
$this->levels[$level->getId()] = $level;
|
||||
|
||||
$level->setTickRate($this->baseTickRate);
|
||||
$level->setAutoSave($this->autoSave);
|
||||
|
||||
(new LevelInitEvent($level))->call();
|
||||
@ -360,40 +341,11 @@ class LevelManager{
|
||||
// Level unloaded during the tick of a level earlier in this loop, perhaps by plugin
|
||||
continue;
|
||||
}
|
||||
if($level->getTickRate() > $this->baseTickRate and --$level->tickRateCounter > 0){
|
||||
if($this->alwaysTickPlayers){
|
||||
foreach($level->getPlayers() as $p){
|
||||
if($p->spawned){
|
||||
$p->onUpdate($currentTick);
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$levelTime = microtime(true);
|
||||
$level->doTick($currentTick);
|
||||
$tickMs = (microtime(true) - $levelTime) * 1000;
|
||||
$level->tickRateTime = $tickMs;
|
||||
|
||||
if($this->autoTickRate){
|
||||
if($tickMs < 50 and $level->getTickRate() > $this->baseTickRate){
|
||||
$level->setTickRate($r = $level->getTickRate() - 1);
|
||||
if($r > $this->baseTickRate){
|
||||
$level->tickRateCounter = $level->getTickRate();
|
||||
}
|
||||
$this->server->getLogger()->debug("Raising world \"{$level->getDisplayName()}\" tick rate to {$level->getTickRate()} ticks");
|
||||
}elseif($tickMs >= 50){
|
||||
if($level->getTickRate() === $this->baseTickRate){
|
||||
$level->setTickRate(max($this->baseTickRate + 1, min($this->autoTickRateLimit, (int) floor($tickMs / 50))));
|
||||
$this->server->getLogger()->debug(sprintf("World \"%s\" took %gms, setting tick rate to %d ticks", $level->getDisplayName(), (int) round($tickMs, 2), $level->getTickRate()));
|
||||
}elseif(($tickMs / $level->getTickRate()) >= 50 and $level->getTickRate() < $this->autoTickRateLimit){
|
||||
$level->setTickRate($level->getTickRate() + 1);
|
||||
$this->server->getLogger()->debug(sprintf("World \"%s\" took %gms, setting tick rate to %d ticks", $level->getDisplayName(), (int) round($tickMs, 2), $level->getTickRate()));
|
||||
}
|
||||
$level->tickRateCounter = $level->getTickRate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($this->autoSave and ++$this->autoSaveTicker >= $this->autoSaveTicks){
|
||||
|
Loading…
x
Reference in New Issue
Block a user