Skip to content

Commit

Permalink
use taskmaster for async tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
KurtThiemann committed Nov 13, 2023
1 parent f5c43d6 commit 6b2a928
Show file tree
Hide file tree
Showing 8 changed files with 250 additions and 57 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ This library includes a simple cli tool.
```bash
./thanos.php /path/to/world/directory [/path/to/output/directory]
```
Thanos uses [Taskmaster](https://github.com/aternosorg/taskmaster) for asynchronous tasks, which can be configured [using environment variables](https://github.com/aternosorg/taskmaster#defining-workers-using-environment-variables).

### Worlds

Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"require": {
"php": ">=8.1",
"ext-zlib": "*",
"aternos/nbt": "^v1.9.0"
"aternos/nbt": "^v1.9.0",
"aternos/taskmaster": "^1.0"
},
"autoload": {
"psr-4": {
Expand Down
52 changes: 50 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions src/RegionDirectory/AnvilRegionDirectory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Aternos\Nbt\IO\Reader\GZipCompressedStringReader;
use Aternos\Nbt\NbtFormat;
use Aternos\Nbt\Tag\CompoundTag;
use Aternos\Nbt\Tag\Tag;
use Aternos\Thanos\Chunk\AnvilChunk;
use Exception;
Expand Down Expand Up @@ -347,4 +348,37 @@ public function readDataFile(string $filename): ?Tag
}
return Tag::load(new GZipCompressedStringReader(file_get_contents($path), NbtFormat::JAVA_EDITION));
}

/**
* @inheritDoc
*/
public function getForceLoadedChunks(): array
{
$chunksDat = $this->readDataFile("chunks.dat");
if(!$chunksDat instanceof CompoundTag) {
return [];
}

$data = $chunksDat->getCompound("data");
if($data === null) {
return [];
}

$list = $data->getLongArray("Forced");
if($list === null) {
return [];
}

$data = $list->getRawValue();
$coordinates = [];
$currentCoordinate = [];
for($i = 0; $i < count($list)*2; $i++) {
$currentCoordinate[] = unpack("N", $data, $i*4)[1] << 32 >> 32;
if($i % 2 === 1) {
$coordinates[] = $currentCoordinate;
$currentCoordinate = [];
}
}
return $coordinates;
}
}
5 changes: 5 additions & 0 deletions src/RegionDirectory/RegionDirectoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ public function getRegions(): array;
*/
public function saveAll(): void;

/**
* @return int[][]
*/
public function getForceLoadedChunks(): array;

/**
* Check if a directory is a region directory
*
Expand Down
49 changes: 49 additions & 0 deletions src/Task/RegionTask.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace Aternos\Thanos\Task;

use Aternos\Taskmaster\Task\OnChild;
use Aternos\Taskmaster\Task\Task;
use Aternos\Thanos\Region\AnvilRegion;
use Exception;

class RegionTask extends Task
{
public function __construct(
#[OnChild] protected string $inputFile,
#[OnChild] protected string $outputFile,
#[OnChild] protected int $inhabitedTimeThreshold,
#[OnChild] protected bool $removeUnknownChunks,

/**
* @var int[][]
*/
#[OnChild] protected array $forceLoadedChunks,
)
{
}

/**
* @inheritDoc
* @throws Exception
*/
#[OnChild] public function run()
{
$removedChunks = 0;
$region = new AnvilRegion($this->inputFile, $this->outputFile);
foreach ($region->getChunks() as $chunk) {
if (in_array([$chunk->getGlobalXPos(), $chunk->getGlobalYPos()], $this->forceLoadedChunks, true)) {
$chunk->save();
continue;
}
$time = $chunk->getInhabitedTime();
if ($time > $this->inhabitedTimeThreshold || ($time === -1 && !$this->removeUnknownChunks)) {
$chunk->save();
} else {
$removedChunks++;
}
}
$region->save();
return $removedChunks;
}
}
55 changes: 55 additions & 0 deletions src/Task/RegionTaskFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace Aternos\Thanos\Task;

use Aternos\Taskmaster\Task\TaskFactory;
use Aternos\Taskmaster\Task\TaskInterface;
use Aternos\Thanos\World\AnvilWorld;
use Generator;

class RegionTaskFactory extends TaskFactory
{
protected Generator $taskGenerator;

public function __construct(
protected AnvilWorld $world,
protected int $inhabitedTimeThreshold,
protected bool $removeUnknownChunks
)
{
$this->taskGenerator = $this->generateTasks();
}

/**
* @return Generator<RegionTask>
*/
protected function generateTasks(): Generator
{
foreach ($this->world->getRegionDirectories() as $regionDirectory) {
$forcedChunks = $regionDirectory->getForceLoadedChunks();

foreach ($regionDirectory->getRegionFiles() as $file) {
yield new RegionTask(
$regionDirectory->getPath() . DIRECTORY_SEPARATOR . $file,
$regionDirectory->getDestination() . DIRECTORY_SEPARATOR . $file,
$this->inhabitedTimeThreshold,
$this->removeUnknownChunks,
$forcedChunks
);
}
}
}

/**
* @inheritDoc
*/
public function createNextTask(?string $group): ?TaskInterface
{
if (!$this->taskGenerator->valid()) {
return null;
}
$task = $this->taskGenerator->current();
$this->taskGenerator->next();
return $task;
}
}
Loading

0 comments on commit 6b2a928

Please sign in to comment.