Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f8bf11660
|
||
|
|
f8dcf33fcb
|
||
|
|
116976d8e8 | ||
|
|
800a4fa743 | ||
|
|
3124d52e3b | ||
|
|
b973781649 | ||
|
|
107bb79474 | ||
|
|
f35cb20714 | ||
|
|
aab04df0b6 | ||
|
|
eda3874ba7 | ||
|
|
609fea09f6 | ||
|
|
d3956d688b | ||
|
|
e46c1c3abe | ||
|
|
ca668d2434 | ||
|
|
af621921e9 | ||
|
|
9f165e647d | ||
|
|
4cff7a4711 | ||
|
|
a60f083e08 | ||
|
|
74f6ab4866 | ||
|
|
ea68abc3cc | ||
|
|
73813786c0 | ||
|
|
7b5594c196 | ||
|
|
87a13cf729 | ||
|
|
324f042f77 | ||
|
|
83a9e8b8c3 | ||
|
|
2a58fdaf80 | ||
|
|
62c437dcc8 | ||
|
|
a2e8736c14 | ||
|
|
b93468e9f6 | ||
|
|
9947f37a26 | ||
|
|
ce93af7c81 | ||
|
|
f132397ae6 | ||
|
|
c15c600b45 | ||
|
|
f59d7c4759 | ||
|
|
76b678aec4 | ||
|
|
e51f093ce8 | ||
|
|
10f1478474 | ||
|
|
29c92a8dc8 | ||
|
|
9e447d4a2a | ||
|
|
1726479648 | ||
|
|
117c03fb46 | ||
|
|
4d562aa62c | ||
|
|
e398cc2d8e | ||
|
|
e6137925f3 | ||
|
|
f08fb59aa3 | ||
|
|
f9429cd717 | ||
|
|
fc7e1b0bae | ||
|
|
c833f27a92 | ||
|
|
5975a9f5f3 | ||
|
|
0f65dbc19b | ||
|
|
646043cdf0 | ||
|
|
caef3640d1 | ||
|
|
fe130e8b8e | ||
|
|
586a14e409 | ||
|
|
213c5ce763 | ||
|
|
cadf998c32 | ||
|
|
886be957cd | ||
|
|
580f0072e3 | ||
|
|
5079beb68e | ||
|
|
f609ab4a34 | ||
|
|
ee02cec5ac | ||
|
|
e2d8f7b89b | ||
|
|
f12a5a9258 | ||
|
|
709f2a5376 | ||
|
|
329937a7f7 | ||
|
|
61ca4e7bbf | ||
|
|
6edaeaa0b0 | ||
|
|
176928cff2 | ||
|
|
1cdd07b2d5 | ||
|
|
ebd263954a | ||
|
|
b487702986 | ||
|
|
3597ec3465 | ||
|
|
33b6080ccd | ||
|
|
bfb30e58cc | ||
|
|
4a329e8029 | ||
|
|
f435293368 | ||
|
|
3666d58e88 | ||
|
|
38e99a8703 | ||
|
|
2ff6a5dddf | ||
|
|
b1d088bef6 | ||
|
|
c5f15db2b8 | ||
|
|
98baadfe32 | ||
|
|
d4c0af18aa | ||
|
|
6df5aa1e1e | ||
|
|
410ddd106f | ||
|
|
5d83912c3b | ||
|
|
953196facb | ||
|
|
9474b9144c | ||
|
|
b347572f84 | ||
|
|
2a3f089861 | ||
|
|
f8b7d0fba5 | ||
|
|
96bb1ea7e2 | ||
|
|
9ee34d3983 | ||
|
|
dbc51fbedf | ||
|
|
0f914e461f | ||
|
|
66179d4a45 | ||
|
|
75640077b4 | ||
|
|
b7cbd6775b | ||
|
|
f912195a26 | ||
|
|
02923bee53 | ||
|
|
bda5898a35 | ||
|
|
5eecf8b671 | ||
|
|
e2b76451ab | ||
|
|
51c2dae5f9 | ||
|
|
c17ad230ca | ||
|
|
b4d2748f94 | ||
|
|
6922cd49f5 | ||
|
|
469dd57931 | ||
|
|
447c3daca0 | ||
|
|
cdd1d92fcb | ||
|
|
2776307e51 | ||
|
|
c25ea97301 | ||
|
|
eeaf3cccac | ||
|
|
0e0d5395b2 | ||
|
|
4e70b40e26 | ||
|
|
0cc7d22190 |
No files matched your search
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
|
||||
</classpath>
|
||||
@@ -0,0 +1 @@
|
||||
.gitea/CODEOWNERS linguist-detectable=false
|
||||
@@ -0,0 +1,3 @@
|
||||
# Pull requests request review from the eligible staff team(s).
|
||||
# One approval from either an Admin or Developer satisfies branch protection.
|
||||
* @trueog/Admins @trueog/Developers
|
||||
+15
-15
@@ -6,42 +6,42 @@ jobs:
|
||||
if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: gradle/wrapper-validation-action@v1
|
||||
- name: Gradle wrapper validation
|
||||
uses: gradle/wrapper-validation-action@v2
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v2
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
cache: 'gradle'
|
||||
- name: Build
|
||||
run: ./gradlew build
|
||||
- name: Upload Bukkit
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Bukkit
|
||||
path: "bukkit/build/libs/Chunky-*.jar"
|
||||
- name: Upload Fabric
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Fabric
|
||||
path: "fabric/build/libs/Chunky-*.jar"
|
||||
- name: Upload Forge
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Forge
|
||||
path: "forge/build/libs/Chunky-*.jar"
|
||||
- name: Upload NeoForge
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: NeoForge
|
||||
path: "neoforge/build/libs/Chunky-*.jar"
|
||||
- name: Upload Sponge
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Sponge
|
||||
path: "sponge/build/libs/Chunky-*.jar"
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Chunky</name>
|
||||
<comment>Pre-generates chunks, quickly, efficiently, and safely</comment>
|
||||
<projects/>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments/>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<linkedResources/>
|
||||
<filteredResources/>
|
||||
</projectDescription>
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||

|
||||
|
||||
Minecraft chunk pre-generator, supporting a wide variety of server implementations including Spigot, Paper, Fabric, Forge, and Sponge.
|
||||
Minecraft chunk pre-generator, supporting a wide variety of server implementations including Spigot, Paper, Fabric, Forge, NeoForge, and Sponge.
|
||||
|
||||
Pre-generate chunks, quickly, efficiently, and safely!
|
||||
|
||||
|
||||
+48
-34
@@ -1,26 +1,21 @@
|
||||
import java.io.ByteArrayOutputStream
|
||||
|
||||
buildscript {
|
||||
configurations.all {
|
||||
resolutionStrategy {
|
||||
force("org.ow2.asm:asm:9.3")
|
||||
force("org.ow2.asm:asm-commons:9.3")
|
||||
}
|
||||
}
|
||||
}
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.gradle.api.tasks.Sync
|
||||
import org.gradle.api.tasks.bundling.Jar
|
||||
|
||||
plugins {
|
||||
eclipse
|
||||
id("java-library")
|
||||
id("maven-publish")
|
||||
id("com.github.johnrengelman.shadow") version "7.1.2"
|
||||
id("com.gradleup.shadow") version "8.3.9" apply false
|
||||
}
|
||||
|
||||
subprojects {
|
||||
plugins.apply("java-library")
|
||||
plugins.apply("maven-publish")
|
||||
plugins.apply("com.github.johnrengelman.shadow")
|
||||
plugins.apply("com.gradleup.shadow")
|
||||
|
||||
group = "${project.property("group")}"
|
||||
group = project.property("group") as String
|
||||
version = "${project.property("version")}.${commitsSinceLastTag()}"
|
||||
|
||||
repositories {
|
||||
@@ -29,60 +24,79 @@ subprojects {
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(17))
|
||||
}
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
tasks {
|
||||
withType<JavaCompile> {
|
||||
options.encoding = "UTF-8"
|
||||
options.release = 17
|
||||
options.compilerArgs.add("-Xlint:none")
|
||||
}
|
||||
jar {
|
||||
|
||||
withType<AbstractArchiveTask> {
|
||||
isPreserveFileTimestamps = false
|
||||
isReproducibleFileOrder = true
|
||||
}
|
||||
|
||||
named<Jar>("jar") {
|
||||
archiveClassifier.set("noshade")
|
||||
}
|
||||
shadowJar {
|
||||
|
||||
named<ShadowJar>("shadowJar") {
|
||||
archiveClassifier.set("")
|
||||
archiveFileName.set("${rootProject.name.capitalize()}-${project.version}.jar")
|
||||
archiveFileName.set("${project.property("artifactName")}-${project.version}.jar")
|
||||
isEnableRelocation = true
|
||||
relocationPrefix = "${project.group}.${rootProject.name.lowercase()}.shadow"
|
||||
}
|
||||
build {
|
||||
dependsOn(shadowJar)
|
||||
|
||||
named("build") {
|
||||
dependsOn("shadowJar")
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
if (project.hasProperty("mavenUsername") && project.hasProperty("mavenPassword")) {
|
||||
if (hasProperty("mavenUsername") && hasProperty("mavenPassword")) {
|
||||
maven {
|
||||
credentials {
|
||||
username = "${project.property("mavenUsername")}"
|
||||
password = "${project.property("mavenPassword")}"
|
||||
username = project.property("mavenUsername") as String
|
||||
password = project.property("mavenPassword") as String
|
||||
}
|
||||
url = uri("https://repo.codemc.io/repository/maven-releases/")
|
||||
}
|
||||
}
|
||||
}
|
||||
publications {
|
||||
create<MavenPublication>("maven") {
|
||||
groupId = "${project.group}"
|
||||
artifactId = project.name
|
||||
version = "${project.version}"
|
||||
from(components["java"])
|
||||
}
|
||||
publications.create<MavenPublication>("maven") {
|
||||
groupId = project.group.toString()
|
||||
artifactId = project.name
|
||||
version = project.version.toString()
|
||||
from(components["java"])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named<Jar>("jar") {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
val pluginArtifact by tasks.registering(Sync::class) {
|
||||
dependsOn(":Chunky-bukkit:shadowJar")
|
||||
from(project(":Chunky-bukkit").tasks.named("shadowJar"))
|
||||
into(layout.buildDirectory.dir("libs"))
|
||||
}
|
||||
|
||||
tasks.named("build") {
|
||||
dependsOn(pluginArtifact)
|
||||
}
|
||||
|
||||
fun commitsSinceLastTag(): String {
|
||||
val tagDescription = ByteArrayOutputStream()
|
||||
exec {
|
||||
commandLine("git", "describe", "--tags")
|
||||
standardOutput = tagDescription
|
||||
}
|
||||
if (tagDescription.toString().indexOf('-') < 0) {
|
||||
return "0"
|
||||
}
|
||||
return tagDescription.toString().split('-')[1]
|
||||
val desc = tagDescription.toString().trim()
|
||||
return if ('-' !in desc) "0" else desc.split('-')[1]
|
||||
}
|
||||
+18
-9
@@ -1,24 +1,30 @@
|
||||
plugins {
|
||||
id("com.gradleup.shadow")
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven("https://repo.purpurmc.org/snapshots")
|
||||
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
|
||||
maven("https://papermc.io/repo/repository/maven-public")
|
||||
maven("https://repo.papermc.io/repository/maven-public/")
|
||||
maven("https://jitpack.io")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(group = "org.spigotmc", name = "spigot-api", version = "1.18.2-R0.1-SNAPSHOT")
|
||||
compileOnly(group = "org.purpurmc.purpur", name = "purpur-api", version = "1.19.4-R0.1-SNAPSHOT")
|
||||
compileOnly(group = "com.github.Puremin0rez", name = "WorldBorder", version = "1.19") {
|
||||
isTransitive = false
|
||||
}
|
||||
implementation(group = "io.papermc", name = "paperlib", version = "1.0.8-SNAPSHOT")
|
||||
implementation(group = "org.bstats", name = "bstats-bukkit", version = "3.0.0")
|
||||
implementation(project(":chunky-common"))
|
||||
implementation(group = "org.bstats", name = "bstats-bukkit", version = "3.0.2")
|
||||
implementation(project(":Chunky-common"))
|
||||
implementation(project(":Chunky-paper"))
|
||||
implementation(project(":Chunky-folia"))
|
||||
}
|
||||
|
||||
tasks {
|
||||
processResources {
|
||||
filesMatching("plugin.yml") {
|
||||
expand(
|
||||
"name" to rootProject.name.capitalize(),
|
||||
"name" to project.property("artifactName"),
|
||||
"version" to project.version,
|
||||
"group" to project.group,
|
||||
"author" to project.property("author"),
|
||||
@@ -27,10 +33,13 @@ tasks {
|
||||
}
|
||||
}
|
||||
shadowJar {
|
||||
archiveClassifier.set("")
|
||||
isEnableRelocation = false
|
||||
minimize {
|
||||
exclude(project(":chunky-common"))
|
||||
exclude(project(":Chunky-common"))
|
||||
exclude(project(":Chunky-paper"))
|
||||
exclude(project(":Chunky-folia"))
|
||||
}
|
||||
relocate("io.papermc.lib", "${project.group}.${rootProject.name}.lib.paperlib")
|
||||
relocate("org.bstats", "${project.group}.${rootProject.name}.lib.bstats")
|
||||
relocate("org.bstats", "${project.group}.${rootProject.name.lowercase()}.lib.bstats")
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.popcraft.chunky;
|
||||
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bstats.charts.SimplePie;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -23,6 +22,7 @@ import org.popcraft.chunky.platform.BukkitConfig;
|
||||
import org.popcraft.chunky.platform.BukkitPlayer;
|
||||
import org.popcraft.chunky.platform.BukkitSender;
|
||||
import org.popcraft.chunky.platform.BukkitServer;
|
||||
import org.popcraft.chunky.platform.Folia;
|
||||
import org.popcraft.chunky.platform.Sender;
|
||||
import org.popcraft.chunky.util.TranslationKey;
|
||||
import org.popcraft.chunky.util.Version;
|
||||
@@ -42,10 +42,7 @@ public final class ChunkyBukkit extends JavaPlugin implements Listener {
|
||||
public void onEnable() {
|
||||
this.chunky = new Chunky(new BukkitServer(this), new BukkitConfig(this));
|
||||
final Version currentVersion = new Version(Bukkit.getBukkitVersion(), true);
|
||||
if (Version.MINECRAFT_1_13_2.isEqualTo(currentVersion) && !PaperLib.isPaper()) {
|
||||
getLogger().severe(() -> translate(TranslationKey.ERROR_VERSION_SPIGOT));
|
||||
getServer().getPluginManager().disablePlugin(this);
|
||||
} else if (currentVersion.isValid() && Version.MINECRAFT_1_13_2.isHigherThan(currentVersion)) {
|
||||
if (currentVersion.isValid() && Version.MINECRAFT_1_13_2.isHigherThan(currentVersion)) {
|
||||
getLogger().severe(() -> translate(TranslationKey.ERROR_VERSION));
|
||||
getServer().getPluginManager().disablePlugin(this);
|
||||
}
|
||||
@@ -55,7 +52,12 @@ public final class ChunkyBukkit extends JavaPlugin implements Listener {
|
||||
getServer().getServicesManager().register(Chunky.class, chunky, this, ServicePriority.Normal);
|
||||
getServer().getServicesManager().register(ChunkyAPI.class, chunky.getApi(), this, ServicePriority.Normal);
|
||||
if (chunky.getConfig().getContinueOnRestart()) {
|
||||
getServer().getScheduler().scheduleSyncDelayedTask(this, () -> chunky.getCommands().get(CommandLiteral.CONTINUE).execute(chunky.getServer().getConsole(), CommandArguments.empty()));
|
||||
final Runnable continueTask = () -> chunky.getCommands().get(CommandLiteral.CONTINUE).execute(chunky.getServer().getConsole(), CommandArguments.empty());
|
||||
if (Folia.isFolia()) {
|
||||
Folia.onServerInit(this, continueTask);
|
||||
} else {
|
||||
getServer().getScheduler().scheduleSyncDelayedTask(this, continueTask);
|
||||
}
|
||||
}
|
||||
if (getServer().getPluginManager().getPlugin("WorldBorder") != null) {
|
||||
chunky.getServer().getIntegrations().put("border", new WorldBorderIntegration());
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
package org.popcraft.chunky.platform;
|
||||
|
||||
import io.papermc.lib.PaperLib;
|
||||
import net.md_5.bungee.api.ChatMessageType;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.popcraft.chunky.ChunkyBukkit;
|
||||
import org.popcraft.chunky.platform.util.Location;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.popcraft.chunky.util.Translator.translateKey;
|
||||
|
||||
public class BukkitPlayer extends BukkitSender implements Player {
|
||||
private static final boolean ACTION_BAR_SUPPORTED;
|
||||
private final JavaPlugin plugin = JavaPlugin.getPlugin(ChunkyBukkit.class);
|
||||
|
||||
static {
|
||||
boolean barSupported;
|
||||
@@ -58,14 +63,36 @@ public class BukkitPlayer extends BukkitSender implements Player {
|
||||
return player.getUniqueId();
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
@Override
|
||||
public void teleport(final Location location) {
|
||||
final org.bukkit.World world = Bukkit.getWorld(location.getWorld().getName());
|
||||
final org.bukkit.Location loc = new org.bukkit.Location(world, location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
final Entity vehicle = player.getVehicle();
|
||||
PaperLib.teleportAsync(player, loc);
|
||||
if (vehicle != null) {
|
||||
PaperLib.teleportAsync(vehicle, loc);
|
||||
if (vehicle == null) {
|
||||
teleportAsync(player, loc);
|
||||
} else {
|
||||
final List<Entity> passengers = new ArrayList<>(vehicle.getPassengers());
|
||||
vehicle.eject();
|
||||
teleportAsync(player, loc).thenAcceptAsync(ignored -> {
|
||||
vehicle.teleport(player);
|
||||
for (final Entity passenger : passengers) {
|
||||
passenger.teleport(player);
|
||||
if (passenger instanceof final org.bukkit.entity.Player playerPassenger) {
|
||||
playerPassenger.hideEntity(plugin, vehicle);
|
||||
playerPassenger.showEntity(plugin, vehicle);
|
||||
}
|
||||
vehicle.addPassenger(passenger);
|
||||
}
|
||||
}, command -> plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, command, 1));
|
||||
}
|
||||
}
|
||||
|
||||
private CompletableFuture<Boolean> teleportAsync(final Entity entity, final org.bukkit.Location location) {
|
||||
if (Paper.isPaper()) {
|
||||
return Paper.teleportAsync(entity, location);
|
||||
} else {
|
||||
return CompletableFuture.completedFuture(entity.teleport(location));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,11 @@ public class BukkitServer implements Server {
|
||||
return worlds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxWorldSize() {
|
||||
return plugin.getServer().getMaxWorldSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sender getConsole() {
|
||||
return new BukkitSender(plugin.getServer().getConsoleSender());
|
||||
|
||||
@@ -1,26 +1,43 @@
|
||||
package org.popcraft.chunky.platform;
|
||||
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.popcraft.chunky.ChunkyBukkit;
|
||||
import org.popcraft.chunky.platform.util.Location;
|
||||
import org.popcraft.chunky.util.Input;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class BukkitWorld implements World {
|
||||
private static final boolean IS_GENERATED_SUPPORTED;
|
||||
private static final int TICKING_LOAD_DURATION = Input.tryInteger(System.getProperty("chunky.tickingLoadDuration")).orElse(0);
|
||||
private static final boolean AWAIT_TICKET_REMOVAL = Boolean.getBoolean("chunky.awaitTicketRemoval");
|
||||
private final JavaPlugin plugin = JavaPlugin.getPlugin(ChunkyBukkit.class);
|
||||
private final org.bukkit.World world;
|
||||
private final Border worldBorder;
|
||||
|
||||
static {
|
||||
boolean isGeneratedSupported;
|
||||
try {
|
||||
Chunk.class.getMethod("isGenerated");
|
||||
isGeneratedSupported = true;
|
||||
} catch (NoSuchMethodException e) {
|
||||
isGeneratedSupported = false;
|
||||
}
|
||||
IS_GENERATED_SUPPORTED = isGeneratedSupported;
|
||||
}
|
||||
|
||||
public BukkitWorld(final org.bukkit.World world) {
|
||||
this.world = world;
|
||||
this.worldBorder = new BukkitBorder(world.getWorldBorder());
|
||||
@@ -37,17 +54,54 @@ public class BukkitWorld implements World {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkGenerated(final int x, final int z) {
|
||||
try {
|
||||
return PaperLib.isPaper() && PaperLib.isChunkGenerated(world, x, z);
|
||||
} catch (CompletionException e) {
|
||||
return false;
|
||||
public CompletableFuture<Boolean> isChunkGenerated(final int x, final int z) {
|
||||
if (Paper.isPaper()) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
return world.isChunkGenerated(x, z);
|
||||
} catch (CompletionException e) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (IS_GENERATED_SUPPORTED) {
|
||||
return CompletableFuture.completedFuture(world.getChunkAt(x, z, false).isGenerated());
|
||||
} else {
|
||||
return CompletableFuture.completedFuture(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> getChunkAtAsync(final int x, final int z) {
|
||||
return CompletableFuture.allOf(PaperLib.getChunkAtAsync(world, x, z));
|
||||
final CompletableFuture<Void> chunkFuture;
|
||||
if (Paper.isPaper()) {
|
||||
chunkFuture = CompletableFuture.allOf(Paper.getChunkAtAsync(world, x, z));
|
||||
} else {
|
||||
chunkFuture = CompletableFuture.allOf(CompletableFuture.completedFuture(world.getChunkAt(x, z)));
|
||||
}
|
||||
if (TICKING_LOAD_DURATION > 0) {
|
||||
final CompletableFuture<Void> removeTicketFuture = new CompletableFuture<>();
|
||||
chunkFuture.thenAccept(ignored -> {
|
||||
final Runnable addTicketTask = () -> world.addPluginChunkTicket(x, z, plugin);
|
||||
final Runnable removeTicketTask = () -> {
|
||||
world.removePluginChunkTicket(x, z, plugin);
|
||||
removeTicketFuture.complete(null);
|
||||
};
|
||||
if (Folia.isFolia()) {
|
||||
final org.bukkit.Location location = new org.bukkit.Location(world, x << 4, 0, z << 4);
|
||||
Folia.schedule(plugin, location, addTicketTask);
|
||||
CompletableFuture.runAsync(() -> Folia.schedule(plugin, location, removeTicketTask), CompletableFuture.delayedExecutor(TICKING_LOAD_DURATION, TimeUnit.SECONDS));
|
||||
} else {
|
||||
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, addTicketTask);
|
||||
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, removeTicketTask, TICKING_LOAD_DURATION * 20L);
|
||||
}
|
||||
});
|
||||
if (AWAIT_TICKET_REMOVAL) {
|
||||
return removeTicketFuture;
|
||||
}
|
||||
}
|
||||
return chunkFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,6 +127,17 @@ public class BukkitWorld implements World {
|
||||
|
||||
@Override
|
||||
public int getElevation(final int x, final int z) {
|
||||
if (Folia.isFolia()) {
|
||||
final org.bukkit.Location location = new org.bukkit.Location(world, x, 0, z);
|
||||
return CompletableFuture
|
||||
.supplyAsync(() -> getElevationForLocation(x, z), command -> Folia.schedule(plugin, location, command))
|
||||
.join();
|
||||
} else {
|
||||
return getElevationForLocation(x, z);
|
||||
}
|
||||
}
|
||||
|
||||
private int getElevationForLocation(final int x, final int z) {
|
||||
final int height = world.getHighestBlockYAt(x, z) + 1;
|
||||
final int logicalHeight = world.getLogicalHeight();
|
||||
if (height >= logicalHeight) {
|
||||
@@ -123,15 +188,19 @@ public class BukkitWorld implements World {
|
||||
|
||||
@Override
|
||||
public Optional<Path> getDirectory(final String name) {
|
||||
if (name != null) {
|
||||
try (Stream<Path> paths = Files.walk(world.getWorldFolder().toPath())) {
|
||||
return paths.filter(Files::isDirectory)
|
||||
.filter(path -> name.equals(path.getFileName().toString()))
|
||||
.findFirst();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (name == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.empty();
|
||||
final org.bukkit.World.Environment environment = world.getEnvironment();
|
||||
final String parent;
|
||||
if (org.bukkit.World.Environment.NETHER.equals(environment)) {
|
||||
parent = "DIM-1";
|
||||
} else if (org.bukkit.World.Environment.THE_END.equals(environment)) {
|
||||
parent = "DIM1";
|
||||
} else {
|
||||
parent = "";
|
||||
}
|
||||
final Path directory = world.getWorldFolder().toPath().resolve(parent).normalize().resolve(name);
|
||||
return Files.isDirectory(directory) ? Optional.of(directory) : Optional.empty();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
# Chunky Configuration
|
||||
# https://github.com/pop4959/Chunky/wiki/Configuration
|
||||
|
||||
version: 2
|
||||
language: en
|
||||
continue-on-restart: false
|
||||
continue-on-restart: true
|
||||
force-load-existing-chunks: false
|
||||
silent: false
|
||||
update-interval: 1
|
||||
@@ -2,6 +2,7 @@ name: ${name}
|
||||
version: ${version}
|
||||
main: ${group}.chunky.ChunkyBukkit
|
||||
api-version: 1.13
|
||||
folia-supported: true
|
||||
softdepend: [dynmap, BlueMap, squaremap, WorldBorder]
|
||||
load: POSTWORLD
|
||||
authors: [${author}]
|
||||
|
||||
@@ -2,6 +2,7 @@ dependencies {
|
||||
compileOnly(group = "com.google.code.gson", name = "gson", version = "2.8.9")
|
||||
testImplementation(group = "junit", name = "junit", version = "4.13.2")
|
||||
testImplementation(group = "com.google.code.gson", name = "gson", version = "2.8.9")
|
||||
implementation(project(":Chunky-nbt"))
|
||||
}
|
||||
|
||||
tasks {
|
||||
|
||||
@@ -54,6 +54,7 @@ public class Chunky {
|
||||
private final Selection.Builder selection;
|
||||
private final TaskScheduler scheduler = new TaskScheduler();
|
||||
private final Map<String, GenerationTask> generationTasks = new ConcurrentHashMap<>();
|
||||
private final Map<String, TrimCommand.Task> trimTasks = new ConcurrentHashMap<>();
|
||||
private final Map<String, PendingAction> pendingActions = new HashMap<>();
|
||||
private final RegionCache regionCache = new RegionCache();
|
||||
private final double limit;
|
||||
@@ -151,6 +152,10 @@ public class Chunky {
|
||||
return generationTasks;
|
||||
}
|
||||
|
||||
public Map<String, TrimCommand.Task> getTrimTasks() {
|
||||
return trimTasks;
|
||||
}
|
||||
|
||||
public Map<String, ChunkyCommand> getCommands() {
|
||||
return commands;
|
||||
}
|
||||
|
||||
@@ -16,12 +16,15 @@ import org.popcraft.chunky.util.RegionCache;
|
||||
import org.popcraft.chunky.util.TranslationKey;
|
||||
|
||||
import java.util.Deque;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
public class GenerationTask implements Runnable {
|
||||
private static final int MAX_WORKING_COUNT = Input.tryInteger(System.getProperty("chunky.maxWorkingCount")).orElse(50);
|
||||
private static final double SAMPLE_INTERVAL = 1000d * Math.max(Input.tryInteger(System.getProperty("chunky.sampleInterval")).orElse(30), 30);
|
||||
private static final double SAMPLE_SUB_INTERVAL = SAMPLE_INTERVAL / 30;
|
||||
private final Chunky chunky;
|
||||
private final Selection selection;
|
||||
private final Shape shape;
|
||||
@@ -52,7 +55,7 @@ public class GenerationTask implements Runnable {
|
||||
this.worldState = chunky.getRegionCache().getWorld(selection.world().getName());
|
||||
}
|
||||
|
||||
private void update(final int chunkX, final int chunkZ, final boolean loaded) {
|
||||
private synchronized void update(final int chunkX, final int chunkZ, final boolean loaded) {
|
||||
if (stopped) {
|
||||
return;
|
||||
}
|
||||
@@ -62,10 +65,10 @@ public class GenerationTask implements Runnable {
|
||||
final Pair<Long, AtomicLong> bin = updateSamples.peekLast();
|
||||
if (loaded) {
|
||||
worldState.setGenerated(chunkX, chunkZ);
|
||||
if (bin != null && currentTime - bin.left() < 2e3) {
|
||||
if (bin != null && currentTime - bin.left() < SAMPLE_SUB_INTERVAL) {
|
||||
bin.right().addAndGet(1);
|
||||
} else if (updateSamples.add(Pair.of(currentTime, new AtomicLong(1)))) {
|
||||
while (!updateSamples.isEmpty() && currentTime - updateSamples.peek().left() > 1e4) {
|
||||
while (!updateSamples.isEmpty() && currentTime - updateSamples.peek().left() > SAMPLE_INTERVAL) {
|
||||
updateSamples.poll();
|
||||
}
|
||||
}
|
||||
@@ -115,7 +118,11 @@ public class GenerationTask implements Runnable {
|
||||
public void run() {
|
||||
final String poolThreadName = Thread.currentThread().getName();
|
||||
Thread.currentThread().setName(String.format("Chunky-%s Thread", selection.world().getName()));
|
||||
if (!chunkIterator.process()) {
|
||||
stop(true);
|
||||
}
|
||||
final Semaphore working = new Semaphore(MAX_WORKING_COUNT);
|
||||
final boolean forceLoadExistingChunks = chunky.getConfig().isForceLoadExistingChunks();
|
||||
startTime.set(System.currentTimeMillis());
|
||||
while (!stopped && chunkIterator.hasNext()) {
|
||||
final ChunkCoordinate chunk = chunkIterator.next();
|
||||
@@ -125,15 +132,9 @@ public class GenerationTask implements Runnable {
|
||||
update(chunk.x(), chunk.z(), false);
|
||||
continue;
|
||||
}
|
||||
if (!chunky.getConfig().isForceLoadExistingChunks()) {
|
||||
if (worldState.isGenerated(chunk.x(), chunk.z())) {
|
||||
update(chunk.x(), chunk.z(), false);
|
||||
continue;
|
||||
}
|
||||
if (selection.world().isChunkGenerated(chunk.x(), chunk.z())) {
|
||||
update(chunk.x(), chunk.z(), true);
|
||||
continue;
|
||||
}
|
||||
if (!forceLoadExistingChunks && worldState.isGenerated(chunk.x(), chunk.z())) {
|
||||
update(chunk.x(), chunk.z(), false);
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
working.acquire();
|
||||
@@ -142,10 +143,20 @@ public class GenerationTask implements Runnable {
|
||||
stop(cancelled);
|
||||
break;
|
||||
}
|
||||
selection.world().getChunkAtAsync(chunk.x(), chunk.z()).whenComplete((ignored, throwable) -> {
|
||||
working.release();
|
||||
update(chunk.x(), chunk.z(), true);
|
||||
});
|
||||
final CompletableFuture<Boolean> isChunkGenerated = forceLoadExistingChunks ?
|
||||
CompletableFuture.completedFuture(false) :
|
||||
selection.world().isChunkGenerated(chunk.x(), chunk.z());
|
||||
isChunkGenerated
|
||||
.thenCompose(generated -> {
|
||||
if (Boolean.TRUE.equals(generated)) {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
} else {
|
||||
return selection.world().getChunkAtAsync(chunk.x(), chunk.z());
|
||||
}
|
||||
}).whenComplete((ignored, throwable) -> {
|
||||
working.release();
|
||||
update(chunk.x(), chunk.z(), true);
|
||||
});
|
||||
}
|
||||
if (stopped) {
|
||||
chunky.getServer().getConsole().sendMessagePrefixed(TranslationKey.TASK_STOPPED, selection.world().getName());
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.popcraft.chunky.platform.util.Vector2;
|
||||
import org.popcraft.chunky.shape.ShapeType;
|
||||
import org.popcraft.chunky.util.Parameter;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class Selection {
|
||||
public static final double DEFAULT_CENTER_X = 0d;
|
||||
public static final double DEFAULT_CENTER_Z = 0d;
|
||||
@@ -26,6 +27,12 @@ public final class Selection {
|
||||
private final int radiusChunksZ;
|
||||
private final int diameterChunksX;
|
||||
private final int diameterChunksZ;
|
||||
private final int centerRegionX;
|
||||
private final int centerRegionZ;
|
||||
private final int radiusRegionsX;
|
||||
private final int radiusRegionsZ;
|
||||
private final int diameterRegionsX;
|
||||
private final int diameterRegionsZ;
|
||||
|
||||
private Selection(final Chunky chunky, final World world, final double centerX, final double centerZ, final double radiusX, final double radiusZ, final Parameter pattern, final String shape) {
|
||||
this.chunky = chunky;
|
||||
@@ -42,6 +49,12 @@ public final class Selection {
|
||||
this.radiusChunksZ = (int) Math.ceil(radiusZ / 16f);
|
||||
this.diameterChunksX = 2 * radiusChunksX + 1;
|
||||
this.diameterChunksZ = 2 * radiusChunksZ + 1;
|
||||
this.centerRegionX = centerChunkX >> 5;
|
||||
this.centerRegionZ = centerChunkZ >> 5;
|
||||
this.radiusRegionsX = (int) Math.ceil(radiusChunksX / 32f);
|
||||
this.radiusRegionsZ = (int) Math.ceil(radiusChunksZ / 32f);
|
||||
this.diameterRegionsX = 2 * radiusRegionsX + 1;
|
||||
this.diameterRegionsZ = 2 * radiusRegionsZ + 1;
|
||||
}
|
||||
|
||||
public static Builder builder(final Chunky chunky, final World world) {
|
||||
@@ -104,7 +117,30 @@ public final class Selection {
|
||||
return this.diameterChunksZ;
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
public int centerRegionX() {
|
||||
return this.centerRegionX;
|
||||
}
|
||||
|
||||
public int centerRegionZ() {
|
||||
return this.centerRegionZ;
|
||||
}
|
||||
|
||||
public int radiusRegionsX() {
|
||||
return this.radiusRegionsX;
|
||||
}
|
||||
|
||||
public int radiusRegionsZ() {
|
||||
return this.radiusRegionsZ;
|
||||
}
|
||||
|
||||
public int diameterRegionsX() {
|
||||
return this.diameterRegionsX;
|
||||
}
|
||||
|
||||
public int diameterRegionsZ() {
|
||||
return this.diameterRegionsZ;
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
private final Chunky chunky;
|
||||
private World world;
|
||||
@@ -112,7 +148,7 @@ public final class Selection {
|
||||
private double centerZ = DEFAULT_CENTER_Z;
|
||||
private double radiusX = DEFAULT_RADIUS;
|
||||
private double radiusZ = DEFAULT_RADIUS;
|
||||
private Parameter pattern = Parameter.of(PatternType.CONCENTRIC);
|
||||
private Parameter pattern = Parameter.of(PatternType.REGION);
|
||||
private String shape = ShapeType.SQUARE;
|
||||
|
||||
private Builder(final Chunky chunky, final World world) {
|
||||
|
||||
@@ -22,7 +22,10 @@ public class CancelCommand implements ChunkyCommand {
|
||||
@Override
|
||||
public void execute(final Sender sender, final CommandArguments arguments) {
|
||||
final Map<String, GenerationTask> generationTasks = chunky.getGenerationTasks();
|
||||
if (generationTasks.isEmpty() && chunky.getTaskLoader().loadTasks().stream().allMatch(GenerationTask::isCancelled)) {
|
||||
final Map<String, TrimCommand.Task> trimTasks = chunky.getTrimTasks();
|
||||
if (generationTasks.isEmpty()
|
||||
&& chunky.getTaskLoader().loadTasks().stream().allMatch(GenerationTask::isCancelled)
|
||||
&& trimTasks.isEmpty()) {
|
||||
sender.sendMessagePrefixed(TranslationKey.FORMAT_CANCEL_NO_TASKS);
|
||||
return;
|
||||
}
|
||||
@@ -39,6 +42,9 @@ public class CancelCommand implements ChunkyCommand {
|
||||
if (chunky.getGenerationTasks().containsKey(world.get().getName())) {
|
||||
chunky.getGenerationTasks().remove(world.get().getName()).stop(true);
|
||||
}
|
||||
if (chunky.getTrimTasks().containsKey(world.get().getName())) {
|
||||
chunky.getTrimTasks().remove(world.get().getName()).setCancelled(true);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
cancelAction = () -> {
|
||||
@@ -47,6 +53,8 @@ public class CancelCommand implements ChunkyCommand {
|
||||
chunky.getGenerationTasks().values().forEach(generationTask -> generationTask.stop(true));
|
||||
chunky.getGenerationTasks().clear();
|
||||
chunky.getScheduler().cancelTasks();
|
||||
chunky.getTrimTasks().values().forEach(trimTask -> trimTask.setCancelled(true));
|
||||
chunky.getTrimTasks().clear();
|
||||
};
|
||||
}
|
||||
chunky.setPendingAction(sender, cancelAction);
|
||||
|
||||
@@ -11,6 +11,7 @@ public final class CommandLiteral {
|
||||
public static final String CONTINUE = "continue";
|
||||
public static final String CORNERS = "corners";
|
||||
public static final String HELP = "help";
|
||||
public static final String INHABITED = "inhabited";
|
||||
public static final String INTERVAL = "interval";
|
||||
public static final String PAGE = "page";
|
||||
public static final String PATTERN = "pattern";
|
||||
@@ -27,6 +28,7 @@ public final class CommandLiteral {
|
||||
public static final String SPAWN = "spawn";
|
||||
public static final String START = "start";
|
||||
public static final String TRIM = "trim";
|
||||
public static final String TRIM_MODE = "trimMode";
|
||||
public static final String WORLDBORDER = "worldborder";
|
||||
public static final String WORLD = "world";
|
||||
public static final String X = "x";
|
||||
|
||||
@@ -33,7 +33,7 @@ public class ShapeCommand implements ChunkyCommand {
|
||||
@Override
|
||||
public List<String> suggestions(final CommandArguments arguments) {
|
||||
if (arguments.size() == 1) {
|
||||
return ShapeType.ALL;
|
||||
return ShapeType.all();
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ public class StartCommand implements ChunkyCommand {
|
||||
chunky.getServer().getWorlds().forEach(world -> suggestions.add(world.getName()));
|
||||
return suggestions;
|
||||
} else if (arguments.size() == 2) {
|
||||
return ShapeType.ALL;
|
||||
return ShapeType.all();
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,11 @@ package org.popcraft.chunky.command;
|
||||
|
||||
import org.popcraft.chunky.Chunky;
|
||||
import org.popcraft.chunky.Selection;
|
||||
import org.popcraft.chunky.nbt.LongTag;
|
||||
import org.popcraft.chunky.nbt.Tag;
|
||||
import org.popcraft.chunky.nbt.TagType;
|
||||
import org.popcraft.chunky.nbt.util.ChunkFilter;
|
||||
import org.popcraft.chunky.nbt.util.RegionFile;
|
||||
import org.popcraft.chunky.platform.Sender;
|
||||
import org.popcraft.chunky.platform.World;
|
||||
import org.popcraft.chunky.shape.Shape;
|
||||
@@ -79,80 +84,89 @@ public class TrimCommand implements ChunkyCommand {
|
||||
return;
|
||||
}
|
||||
}
|
||||
final boolean inside;
|
||||
if (arguments.size() > 6) {
|
||||
final Optional<String> side = arguments.next().map(String::toLowerCase).filter(s -> "outside".equals(s) || "inside".equals(s));
|
||||
if (side.isPresent()) {
|
||||
inside = side.map("inside"::equals).orElse(false);
|
||||
} else {
|
||||
sender.sendMessage(TranslationKey.HELP_TRIM);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
inside = false;
|
||||
}
|
||||
final int inhabitedTime = arguments.next().flatMap(Input::tryIntegerSuffixed).orElse(Integer.MAX_VALUE);
|
||||
final boolean inhabitedTimeCheck = inhabitedTime < Integer.MAX_VALUE;
|
||||
final Selection selection = chunky.getSelection().build();
|
||||
final Shape shape = ShapeFactory.getShape(selection);
|
||||
final Runnable deletionAction = () -> chunky.getScheduler().runTask(() -> {
|
||||
sender.sendMessagePrefixed(TranslationKey.FORMAT_START, selection.world().getName(), translate("shape_" + selection.shape()), Formatting.number(selection.centerX()), Formatting.number(selection.centerZ()), Formatting.radius(selection));
|
||||
TrimCommand.Task trimTask = new TrimCommand.Task();
|
||||
chunky.getTrimTasks().put(selection.world().getName(), trimTask);
|
||||
final Optional<Path> regionPath = selection.world().getRegionDirectory();
|
||||
final Optional<Path> poiPath = selection.world().getPOIDirectory();
|
||||
final Optional<Path> entitiesPath = selection.world().getEntitiesDirectory();
|
||||
final AtomicLong finishedRegions = new AtomicLong();
|
||||
final AtomicLong deleted = new AtomicLong();
|
||||
final long startTime = System.currentTimeMillis();
|
||||
final AtomicLong updateTime = new AtomicLong(startTime);
|
||||
try {
|
||||
if (regionPath.isPresent()) {
|
||||
try (final Stream<Path> regionWalker = Files.walk(regionPath.get())) {
|
||||
regionWalker.forEach(region -> deleted.getAndAdd(checkRegion(region, shape)));
|
||||
}
|
||||
}
|
||||
if (poiPath.isPresent()) {
|
||||
try (final Stream<Path> poiWalker = Files.walk(poiPath.get())) {
|
||||
poiWalker.forEach(region -> checkRegion(region, shape));
|
||||
}
|
||||
}
|
||||
if (entitiesPath.isPresent()) {
|
||||
try (final Stream<Path> entityWalker = Files.walk(entitiesPath.get())) {
|
||||
entityWalker.forEach(region -> checkRegion(region, shape));
|
||||
try (final Stream<Path> files = Files.list(regionPath.get())) {
|
||||
final List<Path> regions = files
|
||||
.filter(file -> ChunkCoordinate.fromRegionFile(file.getFileName().toString()).isPresent())
|
||||
.toList();
|
||||
final long totalRegions = regions.size();
|
||||
for (final Path region : regions) {
|
||||
if (trimTask.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
deleted.getAndAdd(checkRegion(selection.world(), region.getFileName().toString(), shape, inside, inhabitedTimeCheck, inhabitedTime));
|
||||
finishedRegions.getAndIncrement();
|
||||
if (!trimTask.isCancelled() && !chunky.getConfig().isSilent()) {
|
||||
final long currentTime = System.currentTimeMillis();
|
||||
final boolean updateIntervalElapsed = ((currentTime - updateTime.get()) / 1e3) > chunky.getConfig().getUpdateInterval();
|
||||
if (updateIntervalElapsed || finishedRegions.get() == totalRegions) {
|
||||
chunky.getServer().getConsole().sendMessagePrefixed(TranslationKey.TASK_TRIM_UPDATE, selection.world().getName(), finishedRegions.get(), String.format("%.2f", 100f * finishedRegions.get() / totalRegions));
|
||||
updateTime.set(currentTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
final long totalTime = System.currentTimeMillis() - startTime;
|
||||
chunky.getTrimTasks().remove(selection.world().getName());
|
||||
sender.sendMessagePrefixed(TranslationKey.TASK_TRIM, deleted.get(), selection.world().getName(), String.format("%.3f", totalTime / 1e3f));
|
||||
});
|
||||
chunky.setPendingAction(sender, deletionAction);
|
||||
sender.sendMessagePrefixed(TranslationKey.FORMAT_TRIM_CONFIRM, selection.world().getName(), translate("shape_" + selection.shape()), Formatting.number(selection.centerX()), Formatting.number(selection.centerZ()), Formatting.radius(selection), "/chunky confirm");
|
||||
sender.sendMessagePrefixed(inside ? TranslationKey.FORMAT_TRIM_CONFIRM_INSIDE : TranslationKey.FORMAT_TRIM_CONFIRM, selection.world().getName(), translate("shape_" + selection.shape()), Formatting.number(selection.centerX()), Formatting.number(selection.centerZ()), Formatting.radius(selection), "/chunky confirm");
|
||||
if (inhabitedTimeCheck) {
|
||||
sender.sendMessagePrefixed(TranslationKey.FORMAT_TRIM_CONFIRM_INHABITED, Formatting.number(inhabitedTime));
|
||||
}
|
||||
}
|
||||
|
||||
private int checkRegion(final Path region, final Shape shape) {
|
||||
final Optional<ChunkCoordinate> regionCoordinate = tryRegionCoordinate(region);
|
||||
private int checkRegion(final World world, final String regionFileName, final Shape shape, final boolean inside, final boolean inhabitedTimeCheck, final int inhabitedTime) {
|
||||
final Optional<ChunkCoordinate> regionCoordinate = ChunkCoordinate.fromRegionFile(regionFileName);
|
||||
if (regionCoordinate.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
final int chunkX = regionCoordinate.get().x() << 5;
|
||||
final int chunkZ = regionCoordinate.get().z() << 5;
|
||||
if (shouldDeleteRegion(shape, chunkX, chunkZ)) {
|
||||
return deleteRegion(region);
|
||||
if (!inhabitedTimeCheck && shouldDeleteRegion(shape, inside, chunkX, chunkZ)) {
|
||||
return deleteRegion(world, regionFileName);
|
||||
} else {
|
||||
return trimRegion(region, shape, chunkX, chunkZ);
|
||||
return trimRegion(world, regionFileName, shape, inside, chunkX, chunkZ, inhabitedTimeCheck, inhabitedTime);
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<ChunkCoordinate> tryRegionCoordinate(final Path region) {
|
||||
final String fileName = region.getFileName().toString();
|
||||
if (!fileName.startsWith("r.")) {
|
||||
return Optional.empty();
|
||||
}
|
||||
final int extension = fileName.indexOf(".mca");
|
||||
if (extension < 2) {
|
||||
return Optional.empty();
|
||||
}
|
||||
final String regionCoordinates = fileName.substring(2, extension);
|
||||
final int separator = regionCoordinates.indexOf('.');
|
||||
final Optional<Integer> regionX = Input.tryInteger(regionCoordinates.substring(0, separator));
|
||||
final Optional<Integer> regionZ = Input.tryInteger(regionCoordinates.substring(separator + 1));
|
||||
if (regionX.isPresent() && regionZ.isPresent()) {
|
||||
return Optional.of(new ChunkCoordinate(regionX.get(), regionZ.get()));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private boolean shouldDeleteRegion(final Shape shape, final int chunkX, final int chunkZ) {
|
||||
private boolean shouldDeleteRegion(final Shape shape, final boolean inside, final int chunkX, final int chunkZ) {
|
||||
for (int offsetX = 0; offsetX < 32; ++offsetX) {
|
||||
for (int offsetZ = 0; offsetZ < 32; ++offsetZ) {
|
||||
final int chunkCenterX = ((chunkX + offsetX) << 4) + 8;
|
||||
final int chunkCenterZ = ((chunkZ + offsetZ) << 4) + 8;
|
||||
if (shape.isBounding(chunkCenterX, chunkCenterZ)) {
|
||||
if (inside != shape.isBounding(chunkCenterX, chunkCenterZ)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -160,9 +174,18 @@ public class TrimCommand implements ChunkyCommand {
|
||||
return true;
|
||||
}
|
||||
|
||||
private int deleteRegion(final Path region) {
|
||||
private int deleteRegion(final World world, final String regionFileName) {
|
||||
try {
|
||||
Files.deleteIfExists(region);
|
||||
final Path regionPath = world.getRegionDirectory().map(region -> region.resolve(regionFileName)).orElseThrow(IllegalStateException::new);
|
||||
Files.deleteIfExists(regionPath);
|
||||
final Path poiPath = world.getPOIDirectory().map(region -> region.resolve(regionFileName)).orElse(null);
|
||||
if (poiPath != null) {
|
||||
Files.deleteIfExists(poiPath);
|
||||
}
|
||||
final Path entitiesPath = world.getEntitiesDirectory().map(region -> region.resolve(regionFileName)).orElse(null);
|
||||
if (entitiesPath != null) {
|
||||
Files.deleteIfExists(entitiesPath);
|
||||
}
|
||||
return 1024;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@@ -170,17 +193,44 @@ public class TrimCommand implements ChunkyCommand {
|
||||
}
|
||||
}
|
||||
|
||||
private int trimRegion(final Path region, final Shape shape, final int chunkX, final int chunkZ) {
|
||||
private int trimRegion(final World world, final String regionFileName, final Shape shape, final boolean inside, final int chunkX, final int chunkZ, final boolean inhabitedTimeCheck, final int inhabitedTime) {
|
||||
final Path regionPath = world.getRegionDirectory().map(region -> region.resolve(regionFileName)).orElseThrow(IllegalStateException::new);
|
||||
final Path poiPath = world.getPOIDirectory().map(region -> region.resolve(regionFileName)).orElse(null);
|
||||
final Path entitiesPath = world.getEntitiesDirectory().map(region -> region.resolve(regionFileName)).orElse(null);
|
||||
int marked = 0;
|
||||
int deleted = 0;
|
||||
try (RandomAccessFile regionFile = new RandomAccessFile(region.toFile(), "rw")) {
|
||||
final RegionFile regionData = inhabitedTimeCheck ? new RegionFile(regionPath.toFile(), ChunkFilter.of(TagType.LONG, "InhabitedTime")) : null;
|
||||
try (final RandomAccessFile regionFile = new RandomAccessFile(regionPath.toFile(), "rw");
|
||||
final RandomAccessFile poiFile = poiPath == null || Files.notExists(poiPath) ? null : new RandomAccessFile(poiPath.toFile(), "rw");
|
||||
final RandomAccessFile entitiesFile = entitiesPath == null || Files.notExists(entitiesPath) ? null : new RandomAccessFile(entitiesPath.toFile(), "rw")) {
|
||||
if (regionFile.length() < 4096) {
|
||||
return 0;
|
||||
}
|
||||
final boolean poiValid = poiFile != null && poiFile.length() >= 4096;
|
||||
final boolean entitiesValid = entitiesFile != null && entitiesFile.length() >= 4096;
|
||||
for (int offsetX = 0; offsetX < 32; ++offsetX) {
|
||||
for (int offsetZ = 0; offsetZ < 32; ++offsetZ) {
|
||||
final int chunkCenterX = ((chunkX + offsetX) << 4) + 8;
|
||||
final int chunkCenterZ = ((chunkZ + offsetZ) << 4) + 8;
|
||||
if (!shape.isBounding(chunkCenterX, chunkCenterZ)) {
|
||||
final int offsetChunkX = chunkX + offsetX;
|
||||
final int offsetChunkZ = chunkZ + offsetZ;
|
||||
final int chunkCenterX = (offsetChunkX << 4) + 8;
|
||||
final int chunkCenterZ = (offsetChunkZ << 4) + 8;
|
||||
final boolean trimChunk;
|
||||
if (inside) {
|
||||
trimChunk = shape.isBounding(chunkCenterX, chunkCenterZ);
|
||||
} else {
|
||||
trimChunk = !shape.isBounding(chunkCenterX, chunkCenterZ);
|
||||
}
|
||||
final boolean trimInhabited = regionData == null || regionData.getChunk(offsetChunkX, offsetChunkZ)
|
||||
.map(chunk -> {
|
||||
final Tag tag = chunk.getData();
|
||||
if (!(tag instanceof final LongTag inhabited)) {
|
||||
return true;
|
||||
}
|
||||
return inhabited.value() <= inhabitedTime;
|
||||
})
|
||||
.orElse(true);
|
||||
if (trimChunk && trimInhabited) {
|
||||
++marked;
|
||||
final int chunkLocation = ((offsetX % 32) + (offsetZ % 32) * 32) * 4;
|
||||
regionFile.seek(chunkLocation);
|
||||
if (regionFile.readInt() != 0) {
|
||||
@@ -188,12 +238,29 @@ public class TrimCommand implements ChunkyCommand {
|
||||
regionFile.writeInt(0);
|
||||
++deleted;
|
||||
}
|
||||
if (poiValid) {
|
||||
poiFile.seek(chunkLocation);
|
||||
if (poiFile.readInt() != 0) {
|
||||
poiFile.seek(chunkLocation);
|
||||
poiFile.writeInt(0);
|
||||
}
|
||||
}
|
||||
if (entitiesValid) {
|
||||
entitiesFile.seek(chunkLocation);
|
||||
if (entitiesFile.readInt() != 0) {
|
||||
entitiesFile.seek(chunkLocation);
|
||||
entitiesFile.writeInt(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (inhabitedTimeCheck && marked == 1024) {
|
||||
deleteRegion(world, regionFileName);
|
||||
}
|
||||
return deleted;
|
||||
}
|
||||
|
||||
@@ -204,8 +271,20 @@ public class TrimCommand implements ChunkyCommand {
|
||||
chunky.getServer().getWorlds().forEach(world -> suggestions.add(world.getName()));
|
||||
return suggestions;
|
||||
} else if (arguments.size() == 2) {
|
||||
return ShapeType.ALL;
|
||||
return ShapeType.all();
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
public static final class Task {
|
||||
private boolean cancelled;
|
||||
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
public void setCancelled(final boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,13 @@ import org.popcraft.chunky.platform.Sender;
|
||||
import org.popcraft.chunky.platform.World;
|
||||
import org.popcraft.chunky.platform.util.Vector2;
|
||||
import org.popcraft.chunky.util.Formatting;
|
||||
import org.popcraft.chunky.util.Input;
|
||||
import org.popcraft.chunky.util.TranslationKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class WorldBorderCommand implements ChunkyCommand {
|
||||
private final Chunky chunky;
|
||||
@@ -23,6 +26,15 @@ public class WorldBorderCommand implements ChunkyCommand {
|
||||
|
||||
@Override
|
||||
public void execute(final Sender sender, final CommandArguments arguments) {
|
||||
if (arguments.size() > 0) {
|
||||
final Optional<World> world = arguments.next().flatMap(arg -> Input.tryWorld(chunky, arg));
|
||||
if (world.isPresent()) {
|
||||
chunky.getSelection().world(world.get());
|
||||
} else {
|
||||
sender.sendMessage(TranslationKey.HELP_WORLDBORDER);
|
||||
return;
|
||||
}
|
||||
}
|
||||
final Selection previous = chunky.getSelection().build();
|
||||
if (!setBorderViaIntegration(previous.world())) {
|
||||
chunky.getSelection().worldborder();
|
||||
@@ -37,10 +49,18 @@ public class WorldBorderCommand implements ChunkyCommand {
|
||||
if (!previous.shape().equals(current.shape())) {
|
||||
sender.sendMessagePrefixed(TranslationKey.FORMAT_SHAPE, current.shape());
|
||||
}
|
||||
if (current.radiusX() > chunky.getServer().getMaxWorldSize()) {
|
||||
sender.sendMessagePrefixed(TranslationKey.FORMAT_WORLDBORDER_TOO_LARGE, chunky.getServer().getMaxWorldSize());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> suggestions(final CommandArguments arguments) {
|
||||
if (arguments.size() == 1) {
|
||||
final List<String> suggestions = new ArrayList<>();
|
||||
chunky.getServer().getWorlds().forEach(world -> suggestions.add(world.getName()));
|
||||
return suggestions;
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
|
||||
@@ -8,4 +8,8 @@ public interface ChunkIterator extends Iterator<ChunkCoordinate> {
|
||||
long total();
|
||||
|
||||
String name();
|
||||
|
||||
default boolean process() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,9 @@ public final class ChunkIteratorFactory {
|
||||
}
|
||||
|
||||
public static ChunkIterator getChunkIterator(final Selection selection, final long count) {
|
||||
if (selection.pattern().getType().equals(PatternType.WORLD)) {
|
||||
return new WorldChunkIterator(selection);
|
||||
}
|
||||
final String shape = selection.shape();
|
||||
if (ShapeType.RECTANGLE.equals(shape) || ShapeType.ELLIPSE.equals(shape) || ShapeType.OVAL.equals(shape)) {
|
||||
return new Loop2ChunkIterator(selection, count);
|
||||
@@ -16,7 +19,8 @@ public final class ChunkIteratorFactory {
|
||||
case PatternType.LOOP -> new Loop2ChunkIterator(selection, count);
|
||||
case PatternType.SPIRAL -> new SpiralChunkIterator(selection, count);
|
||||
case PatternType.CSV -> new CsvChunkIterator(selection, count);
|
||||
default -> new ConcentricChunkIterator(selection, count);
|
||||
case PatternType.CONCENTRIC -> new ConcentricChunkIterator(selection, count);
|
||||
default -> new RegionChunkIterator(selection, count);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -7,8 +7,10 @@ public final class PatternType {
|
||||
public static final String LOOP = "loop";
|
||||
public static final String SPIRAL = "spiral";
|
||||
public static final String CSV = "csv";
|
||||
public static final String REGION = "region";
|
||||
public static final String WORLD = "world";
|
||||
|
||||
public static final List<String> ALL = List.of(CONCENTRIC, LOOP, SPIRAL, CSV);
|
||||
public static final List<String> ALL = List.of(CONCENTRIC, LOOP, SPIRAL, CSV, REGION, WORLD);
|
||||
|
||||
private PatternType() {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
package org.popcraft.chunky.iterator;
|
||||
|
||||
import org.popcraft.chunky.Selection;
|
||||
import org.popcraft.chunky.util.ChunkCoordinate;
|
||||
import org.popcraft.chunky.util.Hilbert;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class RegionChunkIterator implements ChunkIterator {
|
||||
private final int centerRegionX;
|
||||
private final int centerRegionZ;
|
||||
private final int radiusRegions;
|
||||
private final int minChunkX;
|
||||
private final int minChunkZ;
|
||||
private final int maxChunkX;
|
||||
private final int maxChunkZ;
|
||||
private final long totalChunks;
|
||||
private RegionChunkProgress currentRegionProgress;
|
||||
private int regionX;
|
||||
private int regionZ;
|
||||
private int annulusRegions;
|
||||
private int spanRegions;
|
||||
private int downRegions;
|
||||
private int leftRegions;
|
||||
private int upRegions;
|
||||
private int rightRegions;
|
||||
private boolean hasNextRegion = true;
|
||||
private boolean hasNext = true;
|
||||
|
||||
public RegionChunkIterator(final Selection selection, final long count) {
|
||||
this(selection);
|
||||
if (count <= 0) {
|
||||
return;
|
||||
}
|
||||
this.currentRegionProgress = null;
|
||||
this.regionX = centerRegionX;
|
||||
this.regionZ = centerRegionZ;
|
||||
this.annulusRegions = 0;
|
||||
this.spanRegions = 0;
|
||||
this.downRegions = this.leftRegions = this.upRegions = this.rightRegions = 0;
|
||||
this.hasNextRegion = true;
|
||||
this.hasNext = true;
|
||||
long countRemainingChunks = count;
|
||||
final long estimatedRegionCount = count / 1024;
|
||||
int estimatedDiameterRegions = (int) Math.floor(Math.sqrt(estimatedRegionCount));
|
||||
if (estimatedDiameterRegions % 2 == 0) {
|
||||
--estimatedDiameterRegions;
|
||||
}
|
||||
if (estimatedDiameterRegions > 2) {
|
||||
final int skipDiameterRegions = estimatedDiameterRegions - 2;
|
||||
this.annulusRegions = skipDiameterRegions / 2 + 1;
|
||||
this.regionX += annulusRegions;
|
||||
this.regionZ += annulusRegions - 1;
|
||||
this.spanRegions = 2 * annulusRegions;
|
||||
++this.downRegions;
|
||||
final long skipChunks = ((long) skipDiameterRegions * skipDiameterRegions) * 1024;
|
||||
countRemainingChunks -= skipChunks;
|
||||
}
|
||||
currentRegionProgress = nextRegionChunkProgress(countRemainingChunks);
|
||||
countRemainingChunks -= Math.min(countRemainingChunks, currentRegionProgress == null ? 0 : currentRegionProgress.total());
|
||||
while (currentRegionProgress != null && !currentRegionProgress.hasNext()) {
|
||||
currentRegionProgress = nextRegionChunkProgress(countRemainingChunks);
|
||||
countRemainingChunks -= Math.min(countRemainingChunks, currentRegionProgress == null ? 0 : currentRegionProgress.total());
|
||||
}
|
||||
if (currentRegionProgress == null) {
|
||||
hasNext = false;
|
||||
}
|
||||
}
|
||||
|
||||
public RegionChunkIterator(final Selection selection) {
|
||||
this.centerRegionX = selection.centerRegionX();
|
||||
this.centerRegionZ = selection.centerRegionZ();
|
||||
this.radiusRegions = selection.radiusRegionsX();
|
||||
final int centerChunkX = selection.centerChunkX();
|
||||
final int centerChunkZ = selection.centerChunkZ();
|
||||
final int radiusChunks = selection.radiusChunksX();
|
||||
this.minChunkX = centerChunkX - radiusChunks;
|
||||
this.minChunkZ = centerChunkZ - radiusChunks;
|
||||
this.maxChunkX = centerChunkX + radiusChunks;
|
||||
this.maxChunkZ = centerChunkZ + radiusChunks;
|
||||
this.regionX = centerRegionX;
|
||||
this.regionZ = centerRegionZ;
|
||||
final long diameterChunks = selection.diameterChunksX();
|
||||
this.totalChunks = diameterChunks * diameterChunks;
|
||||
this.currentRegionProgress = nextRegionChunkProgress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return hasNext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkCoordinate next() {
|
||||
if (!hasNext) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
final ChunkCoordinate chunkCoord = currentRegionProgress.next();
|
||||
while (currentRegionProgress != null && !currentRegionProgress.hasNext()) {
|
||||
currentRegionProgress = nextRegionChunkProgress();
|
||||
}
|
||||
if (currentRegionProgress == null) {
|
||||
hasNext = false;
|
||||
}
|
||||
return chunkCoord;
|
||||
}
|
||||
|
||||
private RegionChunkProgress nextRegionChunkProgress() {
|
||||
return nextRegionChunkProgress(0);
|
||||
}
|
||||
|
||||
private RegionChunkProgress nextRegionChunkProgress(final long count) {
|
||||
if (!hasNextRegion) {
|
||||
return null;
|
||||
}
|
||||
final RegionChunkProgress regionChunkProgress = new RegionChunkProgress(regionX, regionZ, count);
|
||||
if (regionX == centerRegionX + annulusRegions && regionZ == centerRegionZ + annulusRegions) {
|
||||
++annulusRegions;
|
||||
++regionX;
|
||||
++regionZ;
|
||||
if (annulusRegions > radiusRegions) {
|
||||
hasNextRegion = false;
|
||||
}
|
||||
spanRegions = 2 * annulusRegions;
|
||||
downRegions = leftRegions = upRegions = rightRegions = 0;
|
||||
}
|
||||
if (downRegions < spanRegions) {
|
||||
--regionZ;
|
||||
++downRegions;
|
||||
} else if (leftRegions < spanRegions) {
|
||||
--regionX;
|
||||
++leftRegions;
|
||||
} else if (upRegions < spanRegions) {
|
||||
++regionZ;
|
||||
++upRegions;
|
||||
} else if (rightRegions < spanRegions) {
|
||||
++regionX;
|
||||
++rightRegions;
|
||||
}
|
||||
return regionChunkProgress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long total() {
|
||||
return totalChunks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return PatternType.REGION;
|
||||
}
|
||||
|
||||
public final class RegionChunkProgress implements ChunkIterator {
|
||||
private final int minX;
|
||||
private final int minZ;
|
||||
private final int sizeZ;
|
||||
private final int total;
|
||||
private final boolean full;
|
||||
private final String name;
|
||||
private int current;
|
||||
private int offsetX;
|
||||
private int offsetZ;
|
||||
private boolean hasNext = true;
|
||||
|
||||
public RegionChunkProgress(final int x, final int z, final long count) {
|
||||
this(x, z);
|
||||
if (count <= 0) {
|
||||
return;
|
||||
}
|
||||
this.current = (int) Math.min(count, 1024);
|
||||
if (!full && sizeZ > 0) {
|
||||
offsetX = current / sizeZ;
|
||||
offsetZ = current % sizeZ;
|
||||
}
|
||||
if (current >= total) {
|
||||
this.hasNext = false;
|
||||
}
|
||||
}
|
||||
|
||||
public RegionChunkProgress(final int x, final int z) {
|
||||
final int lowEdgeX = x << 5;
|
||||
final int lowEdgeZ = z << 5;
|
||||
final int highEdgeX = lowEdgeX + 31;
|
||||
final int highEdgeZ = lowEdgeZ + 31;
|
||||
this.minX = Math.max(lowEdgeX, minChunkX);
|
||||
this.minZ = Math.max(lowEdgeZ, minChunkZ);
|
||||
final int maxX = Math.min(highEdgeX, maxChunkX);
|
||||
final int maxZ = Math.min(highEdgeZ, maxChunkZ);
|
||||
final int sizeX = maxX - minX + 1;
|
||||
if (minX > highEdgeX || minZ > highEdgeZ || maxX < lowEdgeX || maxZ < lowEdgeZ) {
|
||||
this.sizeZ = 0;
|
||||
this.total = 0;
|
||||
this.full = false;
|
||||
this.hasNext = false;
|
||||
} else {
|
||||
this.sizeZ = maxZ - minZ + 1;
|
||||
this.total = sizeX * sizeZ;
|
||||
this.full = total == 1024;
|
||||
}
|
||||
this.name = "region_chunk_progress_%d_%d".formatted(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return hasNext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkCoordinate next() {
|
||||
if (!hasNext) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
final ChunkCoordinate chunkCoord;
|
||||
if (full) {
|
||||
final ChunkCoordinate offset = Hilbert.regionDistanceToChunkCoordinateOffset(current);
|
||||
chunkCoord = new ChunkCoordinate(minX + offset.x(), minZ + offset.z());
|
||||
} else {
|
||||
chunkCoord = new ChunkCoordinate(minX + offsetX, minZ + offsetZ);
|
||||
if (++offsetZ >= sizeZ) {
|
||||
offsetZ = 0;
|
||||
++offsetX;
|
||||
}
|
||||
}
|
||||
++current;
|
||||
if (current >= total) {
|
||||
hasNext = false;
|
||||
}
|
||||
return chunkCoord;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long total() {
|
||||
return total;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
package org.popcraft.chunky.iterator;
|
||||
|
||||
import org.popcraft.chunky.Chunky;
|
||||
import org.popcraft.chunky.Selection;
|
||||
import org.popcraft.chunky.nbt.StringTag;
|
||||
import org.popcraft.chunky.nbt.TagType;
|
||||
import org.popcraft.chunky.nbt.util.ChunkFilter;
|
||||
import org.popcraft.chunky.nbt.util.RegionFile;
|
||||
import org.popcraft.chunky.util.ChunkCoordinate;
|
||||
import org.popcraft.chunky.util.Hilbert;
|
||||
import org.popcraft.chunky.util.Parameter;
|
||||
import org.popcraft.chunky.util.TranslationKey;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Optional;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class WorldChunkIterator implements ChunkIterator {
|
||||
private final Chunky chunky;
|
||||
private final int minRegionX;
|
||||
private final int minRegionZ;
|
||||
private final int maxRegionX;
|
||||
private final int maxRegionZ;
|
||||
private final int minChunkX;
|
||||
private final int minChunkZ;
|
||||
private final int maxChunkX;
|
||||
private final int maxChunkZ;
|
||||
private final String worldName;
|
||||
private final Queue<ChunkCoordinate> chunks;
|
||||
private final AtomicLong total = new AtomicLong();
|
||||
private final Path savePath;
|
||||
private final Path regionPath;
|
||||
private final String name;
|
||||
|
||||
public WorldChunkIterator(final Selection selection) {
|
||||
this.chunky = selection.chunky();
|
||||
final int centerRegionX = selection.centerRegionX();
|
||||
final int centerRegionZ = selection.centerRegionZ();
|
||||
final int radiusRegionsX = selection.radiusRegionsX();
|
||||
final int radiusRegionsZ = selection.radiusRegionsZ();
|
||||
this.minRegionX = centerRegionX - radiusRegionsX;
|
||||
this.minRegionZ = centerRegionZ - radiusRegionsZ;
|
||||
this.maxRegionX = centerRegionX + radiusRegionsX;
|
||||
this.maxRegionZ = centerRegionZ + radiusRegionsZ;
|
||||
final int centerChunkX = selection.centerChunkX();
|
||||
final int centerChunkZ = selection.centerChunkZ();
|
||||
final int radiusChunksX = selection.radiusChunksX();
|
||||
final int radiusChunksZ = selection.radiusChunksZ();
|
||||
this.minChunkX = centerChunkX - radiusChunksX;
|
||||
this.minChunkZ = centerChunkZ - radiusChunksZ;
|
||||
this.maxChunkX = centerChunkX + radiusChunksX;
|
||||
this.maxChunkZ = centerChunkZ + radiusChunksZ;
|
||||
this.chunks = new LinkedList<>();
|
||||
this.worldName = selection.world().getName();
|
||||
final String saveFile = worldName.substring(worldName.indexOf(':') + 1);
|
||||
this.savePath = selection.chunky().getConfig().getDirectory().resolve(String.format("%s.csv", saveFile));
|
||||
this.regionPath = selection.world().getRegionDirectory().orElse(null);
|
||||
this.name = Parameter.of(PatternType.CSV, saveFile).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return !chunks.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkCoordinate next() {
|
||||
if (chunks.isEmpty()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
return chunks.poll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long total() {
|
||||
return total.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean process() {
|
||||
if (regionPath == null) {
|
||||
return false;
|
||||
}
|
||||
final long startTime = System.currentTimeMillis();
|
||||
final AtomicLong updateTime = new AtomicLong(startTime);
|
||||
final StringBuilder saveData = new StringBuilder();
|
||||
try (final Stream<Path> files = Files.list(regionPath)) {
|
||||
final List<Path> regions = files
|
||||
.filter(file -> {
|
||||
final ChunkCoordinate regionCoordinate = ChunkCoordinate.fromRegionFile(file.getFileName().toString())
|
||||
.orElse(null);
|
||||
return regionCoordinate != null && regionCoordinate.x() >= minRegionX && regionCoordinate.x() <= maxRegionX && regionCoordinate.z() >= minRegionZ && regionCoordinate.z() <= maxRegionZ;
|
||||
})
|
||||
.toList();
|
||||
final long totalRegions = regions.size();
|
||||
final AtomicLong finishedRegions = new AtomicLong();
|
||||
for (final Path region : regions) {
|
||||
final ChunkCoordinate regionCoordinate = ChunkCoordinate.fromRegionFile(region.getFileName().toString())
|
||||
.orElseThrow(IllegalStateException::new);
|
||||
final int regionX = regionCoordinate.x();
|
||||
final int regionZ = regionCoordinate.z();
|
||||
final RegionFile regionFile = new RegionFile(region.toFile(), ChunkFilter.of(TagType.STRING, "Status"));
|
||||
for (final ChunkCoordinate offset : Hilbert.chunkCoordinateOffsets()) {
|
||||
final ChunkCoordinate chunkCoordinate = new ChunkCoordinate((regionX << 5) + offset.x(), (regionZ << 5) + offset.z());
|
||||
if (chunkCoordinate.x() < minChunkX || chunkCoordinate.x() > maxChunkX || chunkCoordinate.z() < minChunkZ || chunkCoordinate.z() > maxChunkZ) {
|
||||
continue;
|
||||
}
|
||||
regionFile.getChunk(chunkCoordinate.x(), chunkCoordinate.z()).ifPresent(chunk -> {
|
||||
final boolean generated = Optional.ofNullable(chunk.getData())
|
||||
.filter(StringTag.class::isInstance)
|
||||
.map(StringTag.class::cast)
|
||||
.map(StringTag::value)
|
||||
.map(status -> "minecraft:full".equals(status) || "full".equals(status))
|
||||
.orElse(false);
|
||||
if (generated) {
|
||||
chunks.add(chunkCoordinate);
|
||||
saveData.append(chunkCoordinate.x()).append(',').append(chunkCoordinate.z()).append('\n');
|
||||
total.incrementAndGet();
|
||||
}
|
||||
});
|
||||
}
|
||||
finishedRegions.getAndIncrement();
|
||||
if (!chunky.getConfig().isSilent()) {
|
||||
final long currentTime = System.currentTimeMillis();
|
||||
final boolean updateIntervalElapsed = ((currentTime - updateTime.get()) / 1e3) > chunky.getConfig().getUpdateInterval();
|
||||
if (updateIntervalElapsed || finishedRegions.get() == totalRegions) {
|
||||
chunky.getServer().getConsole().sendMessagePrefixed(TranslationKey.TASK_TRIM_UPDATE, worldName, finishedRegions.get(), String.format("%.2f", 100f * finishedRegions.get() / totalRegions));
|
||||
updateTime.set(currentTime);
|
||||
}
|
||||
}
|
||||
if (Thread.interrupted()) {
|
||||
Thread.currentThread().interrupt();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Files.writeString(savePath, saveData, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,8 @@ public interface Server {
|
||||
|
||||
List<World> getWorlds();
|
||||
|
||||
int getMaxWorldSize();
|
||||
|
||||
Sender getConsole();
|
||||
|
||||
Collection<Player> getPlayers();
|
||||
|
||||
@@ -12,7 +12,7 @@ public interface World {
|
||||
|
||||
String getKey();
|
||||
|
||||
boolean isChunkGenerated(int x, int z);
|
||||
CompletableFuture<Boolean> isChunkGenerated(int x, int z);
|
||||
|
||||
CompletableFuture<Void> getChunkAtAsync(int x, int z);
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.popcraft.chunky.shape;
|
||||
|
||||
import org.popcraft.chunky.Selection;
|
||||
import org.popcraft.chunky.platform.util.Vector2;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.popcraft.chunky.shape.ShapeUtil.insideLine;
|
||||
|
||||
public class Hexagon extends AbstractPolygon {
|
||||
private final double p1x, p1z, p2x, p2z, p3x, p3z, p4x, p4z, p5x, p5z, p6x, p6z;
|
||||
|
||||
public Hexagon(final Selection selection, final boolean chunkAligned) {
|
||||
super(selection, chunkAligned);
|
||||
this.p1x = centerX + radiusX * Math.cos(Math.toRadians(60));
|
||||
this.p1z = centerZ + radiusX * Math.sin(Math.toRadians(60));
|
||||
this.p2x = centerX + radiusX * Math.cos(Math.toRadians(120));
|
||||
this.p2z = centerZ + radiusX * Math.sin(Math.toRadians(120));
|
||||
this.p3x = centerX + radiusX * Math.cos(Math.toRadians(180));
|
||||
this.p3z = centerZ + radiusX * Math.sin(Math.toRadians(180));
|
||||
this.p4x = centerX + radiusX * Math.cos(Math.toRadians(240));
|
||||
this.p4z = centerZ + radiusX * Math.sin(Math.toRadians(240));
|
||||
this.p5x = centerX + radiusX * Math.cos(Math.toRadians(300));
|
||||
this.p5z = centerZ + radiusX * Math.sin(Math.toRadians(300));
|
||||
this.p6x = centerX + radiusX * Math.cos(Math.toRadians(360));
|
||||
this.p6z = centerZ + radiusX * Math.sin(Math.toRadians(360));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Vector2> points() {
|
||||
return Arrays.asList(
|
||||
Vector2.of(p1x, p1z),
|
||||
Vector2.of(p2x, p2z),
|
||||
Vector2.of(p3x, p3z),
|
||||
Vector2.of(p4x, p4z),
|
||||
Vector2.of(p5x, p5z),
|
||||
Vector2.of(p6x, p6z)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBounding(final double x, final double z) {
|
||||
final boolean inside12 = insideLine(p1x, p1z, p2x, p2z, x, z);
|
||||
final boolean inside23 = insideLine(p2x, p2z, p3x, p3z, x, z);
|
||||
final boolean inside34 = insideLine(p3x, p3z, p4x, p4z, x, z);
|
||||
final boolean inside45 = insideLine(p4x, p4z, p5x, p5z, x, z);
|
||||
final boolean inside56 = insideLine(p5x, p5z, p6x, p6z, x, z);
|
||||
final boolean inside61 = insideLine(p6x, p6z, p1x, p1z, x, z);
|
||||
return inside12 && inside23 && inside34 && inside45 && inside56 && inside61;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return ShapeType.HEXAGON;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,16 @@
|
||||
package org.popcraft.chunky.shape;
|
||||
|
||||
import org.popcraft.chunky.Selection;
|
||||
import org.popcraft.chunky.util.Translator;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public final class ShapeFactory {
|
||||
private static final Map<String, BiFunction<Selection, Boolean, Shape>> custom = new HashMap<>();
|
||||
|
||||
private ShapeFactory() {
|
||||
}
|
||||
|
||||
@@ -15,11 +23,21 @@ public final class ShapeFactory {
|
||||
case ShapeType.CIRCLE -> new Circle(selection, chunkAligned);
|
||||
case ShapeType.DIAMOND -> new Diamond(selection, chunkAligned);
|
||||
case ShapeType.ELLIPSE, ShapeType.OVAL -> new Ellipse(selection, chunkAligned);
|
||||
case ShapeType.HEXAGON -> new Hexagon(selection, chunkAligned);
|
||||
case ShapeType.PENTAGON -> new Pentagon(selection, chunkAligned);
|
||||
case ShapeType.RECTANGLE -> new Rectangle(selection, chunkAligned);
|
||||
case ShapeType.STAR -> new Star(selection, chunkAligned);
|
||||
case ShapeType.TRIANGLE -> new Triangle(selection, chunkAligned);
|
||||
default -> new Square(selection, chunkAligned);
|
||||
default -> custom.getOrDefault(selection.shape(), Square::new).apply(selection, chunkAligned);
|
||||
};
|
||||
}
|
||||
|
||||
public static void registerCustom(final String name, final BiFunction<Selection, Boolean, Shape> shapeFunction) {
|
||||
custom.put(name, shapeFunction);
|
||||
Translator.addCustomTranslation("shape_%s".formatted(name), name);
|
||||
}
|
||||
|
||||
public static Set<String> getCustomTypes() {
|
||||
return custom.keySet();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
package org.popcraft.chunky.shape;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public final class ShapeType {
|
||||
public static final String CIRCLE = "circle";
|
||||
public static final String DIAMOND = "diamond";
|
||||
public static final String ELLIPSE = "ellipse";
|
||||
public static final String HEXAGON = "hexagon";
|
||||
public static final String OVAL = "oval";
|
||||
public static final String PENTAGON = "pentagon";
|
||||
public static final String RECTANGLE = "rectangle";
|
||||
@@ -13,8 +16,18 @@ public final class ShapeType {
|
||||
public static final String STAR = "star";
|
||||
public static final String TRIANGLE = "triangle";
|
||||
|
||||
public static final List<String> ALL = List.of(CIRCLE, DIAMOND, ELLIPSE, PENTAGON, RECTANGLE, SQUARE, STAR, TRIANGLE);
|
||||
private static final List<String> DEFAULTS = List.of(CIRCLE, DIAMOND, ELLIPSE, HEXAGON, PENTAGON, RECTANGLE, SQUARE, STAR, TRIANGLE);
|
||||
|
||||
private ShapeType() {
|
||||
}
|
||||
|
||||
public static List<String> all() {
|
||||
final Set<String> customTypes = ShapeFactory.getCustomTypes();
|
||||
if (customTypes.isEmpty()) {
|
||||
return DEFAULTS;
|
||||
}
|
||||
final List<String> allTypes = new ArrayList<>(DEFAULTS);
|
||||
allTypes.addAll(customTypes);
|
||||
return allTypes;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,27 @@
|
||||
package org.popcraft.chunky.util;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public record ChunkCoordinate(int x, int z) implements Comparable<ChunkCoordinate> {
|
||||
public static Optional<ChunkCoordinate> fromRegionFile(final String regionFileName) {
|
||||
if (!regionFileName.startsWith("r.")) {
|
||||
return Optional.empty();
|
||||
}
|
||||
final int extension = regionFileName.indexOf(".mca");
|
||||
if (extension < 2) {
|
||||
return Optional.empty();
|
||||
}
|
||||
final String regionCoordinates = regionFileName.substring(2, extension);
|
||||
final int separator = regionCoordinates.indexOf('.');
|
||||
final Optional<Integer> regionX = Input.tryInteger(regionCoordinates.substring(0, separator));
|
||||
final Optional<Integer> regionZ = Input.tryInteger(regionCoordinates.substring(separator + 1));
|
||||
if (regionX.isPresent() && regionZ.isPresent()) {
|
||||
return Optional.of(new ChunkCoordinate(regionX.get(), regionZ.get()));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final ChunkCoordinate o) {
|
||||
return this.x == o.x ? Integer.compare(this.z, o.z) : Integer.compare(this.x, o.x);
|
||||
|
||||
@@ -0,0 +1,362 @@
|
||||
package org.popcraft.chunky.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
public final class Hilbert {
|
||||
private static final ChunkCoordinate[] regionChunkCoordinateOffsets = {
|
||||
new ChunkCoordinate(0, 0), new ChunkCoordinate(0, 1), new ChunkCoordinate(1, 1),
|
||||
new ChunkCoordinate(1, 0), new ChunkCoordinate(2, 0), new ChunkCoordinate(3, 0),
|
||||
new ChunkCoordinate(3, 1), new ChunkCoordinate(2, 1), new ChunkCoordinate(2, 2),
|
||||
new ChunkCoordinate(3, 2), new ChunkCoordinate(3, 3), new ChunkCoordinate(2, 3),
|
||||
new ChunkCoordinate(1, 3), new ChunkCoordinate(1, 2), new ChunkCoordinate(0, 2),
|
||||
new ChunkCoordinate(0, 3), new ChunkCoordinate(0, 4), new ChunkCoordinate(1, 4),
|
||||
new ChunkCoordinate(1, 5), new ChunkCoordinate(0, 5), new ChunkCoordinate(0, 6),
|
||||
new ChunkCoordinate(0, 7), new ChunkCoordinate(1, 7), new ChunkCoordinate(1, 6),
|
||||
new ChunkCoordinate(2, 6), new ChunkCoordinate(2, 7), new ChunkCoordinate(3, 7),
|
||||
new ChunkCoordinate(3, 6), new ChunkCoordinate(3, 5), new ChunkCoordinate(2, 5),
|
||||
new ChunkCoordinate(2, 4), new ChunkCoordinate(3, 4), new ChunkCoordinate(4, 4),
|
||||
new ChunkCoordinate(5, 4), new ChunkCoordinate(5, 5), new ChunkCoordinate(4, 5),
|
||||
new ChunkCoordinate(4, 6), new ChunkCoordinate(4, 7), new ChunkCoordinate(5, 7),
|
||||
new ChunkCoordinate(5, 6), new ChunkCoordinate(6, 6), new ChunkCoordinate(6, 7),
|
||||
new ChunkCoordinate(7, 7), new ChunkCoordinate(7, 6), new ChunkCoordinate(7, 5),
|
||||
new ChunkCoordinate(6, 5), new ChunkCoordinate(6, 4), new ChunkCoordinate(7, 4),
|
||||
new ChunkCoordinate(7, 3), new ChunkCoordinate(7, 2), new ChunkCoordinate(6, 2),
|
||||
new ChunkCoordinate(6, 3), new ChunkCoordinate(5, 3), new ChunkCoordinate(4, 3),
|
||||
new ChunkCoordinate(4, 2), new ChunkCoordinate(5, 2), new ChunkCoordinate(5, 1),
|
||||
new ChunkCoordinate(4, 1), new ChunkCoordinate(4, 0), new ChunkCoordinate(5, 0),
|
||||
new ChunkCoordinate(6, 0), new ChunkCoordinate(6, 1), new ChunkCoordinate(7, 1),
|
||||
new ChunkCoordinate(7, 0), new ChunkCoordinate(8, 0), new ChunkCoordinate(9, 0),
|
||||
new ChunkCoordinate(9, 1), new ChunkCoordinate(8, 1), new ChunkCoordinate(8, 2),
|
||||
new ChunkCoordinate(8, 3), new ChunkCoordinate(9, 3), new ChunkCoordinate(9, 2),
|
||||
new ChunkCoordinate(10, 2), new ChunkCoordinate(10, 3), new ChunkCoordinate(11, 3),
|
||||
new ChunkCoordinate(11, 2), new ChunkCoordinate(11, 1), new ChunkCoordinate(10, 1),
|
||||
new ChunkCoordinate(10, 0), new ChunkCoordinate(11, 0), new ChunkCoordinate(12, 0),
|
||||
new ChunkCoordinate(12, 1), new ChunkCoordinate(13, 1), new ChunkCoordinate(13, 0),
|
||||
new ChunkCoordinate(14, 0), new ChunkCoordinate(15, 0), new ChunkCoordinate(15, 1),
|
||||
new ChunkCoordinate(14, 1), new ChunkCoordinate(14, 2), new ChunkCoordinate(15, 2),
|
||||
new ChunkCoordinate(15, 3), new ChunkCoordinate(14, 3), new ChunkCoordinate(13, 3),
|
||||
new ChunkCoordinate(13, 2), new ChunkCoordinate(12, 2), new ChunkCoordinate(12, 3),
|
||||
new ChunkCoordinate(12, 4), new ChunkCoordinate(12, 5), new ChunkCoordinate(13, 5),
|
||||
new ChunkCoordinate(13, 4), new ChunkCoordinate(14, 4), new ChunkCoordinate(15, 4),
|
||||
new ChunkCoordinate(15, 5), new ChunkCoordinate(14, 5), new ChunkCoordinate(14, 6),
|
||||
new ChunkCoordinate(15, 6), new ChunkCoordinate(15, 7), new ChunkCoordinate(14, 7),
|
||||
new ChunkCoordinate(13, 7), new ChunkCoordinate(13, 6), new ChunkCoordinate(12, 6),
|
||||
new ChunkCoordinate(12, 7), new ChunkCoordinate(11, 7), new ChunkCoordinate(10, 7),
|
||||
new ChunkCoordinate(10, 6), new ChunkCoordinate(11, 6), new ChunkCoordinate(11, 5),
|
||||
new ChunkCoordinate(11, 4), new ChunkCoordinate(10, 4), new ChunkCoordinate(10, 5),
|
||||
new ChunkCoordinate(9, 5), new ChunkCoordinate(9, 4), new ChunkCoordinate(8, 4),
|
||||
new ChunkCoordinate(8, 5), new ChunkCoordinate(8, 6), new ChunkCoordinate(9, 6),
|
||||
new ChunkCoordinate(9, 7), new ChunkCoordinate(8, 7), new ChunkCoordinate(8, 8),
|
||||
new ChunkCoordinate(9, 8), new ChunkCoordinate(9, 9), new ChunkCoordinate(8, 9),
|
||||
new ChunkCoordinate(8, 10), new ChunkCoordinate(8, 11), new ChunkCoordinate(9, 11),
|
||||
new ChunkCoordinate(9, 10), new ChunkCoordinate(10, 10), new ChunkCoordinate(10, 11),
|
||||
new ChunkCoordinate(11, 11), new ChunkCoordinate(11, 10), new ChunkCoordinate(11, 9),
|
||||
new ChunkCoordinate(10, 9), new ChunkCoordinate(10, 8), new ChunkCoordinate(11, 8),
|
||||
new ChunkCoordinate(12, 8), new ChunkCoordinate(12, 9), new ChunkCoordinate(13, 9),
|
||||
new ChunkCoordinate(13, 8), new ChunkCoordinate(14, 8), new ChunkCoordinate(15, 8),
|
||||
new ChunkCoordinate(15, 9), new ChunkCoordinate(14, 9), new ChunkCoordinate(14, 10),
|
||||
new ChunkCoordinate(15, 10), new ChunkCoordinate(15, 11), new ChunkCoordinate(14, 11),
|
||||
new ChunkCoordinate(13, 11), new ChunkCoordinate(13, 10), new ChunkCoordinate(12, 10),
|
||||
new ChunkCoordinate(12, 11), new ChunkCoordinate(12, 12), new ChunkCoordinate(12, 13),
|
||||
new ChunkCoordinate(13, 13), new ChunkCoordinate(13, 12), new ChunkCoordinate(14, 12),
|
||||
new ChunkCoordinate(15, 12), new ChunkCoordinate(15, 13), new ChunkCoordinate(14, 13),
|
||||
new ChunkCoordinate(14, 14), new ChunkCoordinate(15, 14), new ChunkCoordinate(15, 15),
|
||||
new ChunkCoordinate(14, 15), new ChunkCoordinate(13, 15), new ChunkCoordinate(13, 14),
|
||||
new ChunkCoordinate(12, 14), new ChunkCoordinate(12, 15), new ChunkCoordinate(11, 15),
|
||||
new ChunkCoordinate(10, 15), new ChunkCoordinate(10, 14), new ChunkCoordinate(11, 14),
|
||||
new ChunkCoordinate(11, 13), new ChunkCoordinate(11, 12), new ChunkCoordinate(10, 12),
|
||||
new ChunkCoordinate(10, 13), new ChunkCoordinate(9, 13), new ChunkCoordinate(9, 12),
|
||||
new ChunkCoordinate(8, 12), new ChunkCoordinate(8, 13), new ChunkCoordinate(8, 14),
|
||||
new ChunkCoordinate(9, 14), new ChunkCoordinate(9, 15), new ChunkCoordinate(8, 15),
|
||||
new ChunkCoordinate(7, 15), new ChunkCoordinate(7, 14), new ChunkCoordinate(6, 14),
|
||||
new ChunkCoordinate(6, 15), new ChunkCoordinate(5, 15), new ChunkCoordinate(4, 15),
|
||||
new ChunkCoordinate(4, 14), new ChunkCoordinate(5, 14), new ChunkCoordinate(5, 13),
|
||||
new ChunkCoordinate(4, 13), new ChunkCoordinate(4, 12), new ChunkCoordinate(5, 12),
|
||||
new ChunkCoordinate(6, 12), new ChunkCoordinate(6, 13), new ChunkCoordinate(7, 13),
|
||||
new ChunkCoordinate(7, 12), new ChunkCoordinate(7, 11), new ChunkCoordinate(6, 11),
|
||||
new ChunkCoordinate(6, 10), new ChunkCoordinate(7, 10), new ChunkCoordinate(7, 9),
|
||||
new ChunkCoordinate(7, 8), new ChunkCoordinate(6, 8), new ChunkCoordinate(6, 9),
|
||||
new ChunkCoordinate(5, 9), new ChunkCoordinate(5, 8), new ChunkCoordinate(4, 8),
|
||||
new ChunkCoordinate(4, 9), new ChunkCoordinate(4, 10), new ChunkCoordinate(5, 10),
|
||||
new ChunkCoordinate(5, 11), new ChunkCoordinate(4, 11), new ChunkCoordinate(3, 11),
|
||||
new ChunkCoordinate(2, 11), new ChunkCoordinate(2, 10), new ChunkCoordinate(3, 10),
|
||||
new ChunkCoordinate(3, 9), new ChunkCoordinate(3, 8), new ChunkCoordinate(2, 8),
|
||||
new ChunkCoordinate(2, 9), new ChunkCoordinate(1, 9), new ChunkCoordinate(1, 8),
|
||||
new ChunkCoordinate(0, 8), new ChunkCoordinate(0, 9), new ChunkCoordinate(0, 10),
|
||||
new ChunkCoordinate(1, 10), new ChunkCoordinate(1, 11), new ChunkCoordinate(0, 11),
|
||||
new ChunkCoordinate(0, 12), new ChunkCoordinate(0, 13), new ChunkCoordinate(1, 13),
|
||||
new ChunkCoordinate(1, 12), new ChunkCoordinate(2, 12), new ChunkCoordinate(3, 12),
|
||||
new ChunkCoordinate(3, 13), new ChunkCoordinate(2, 13), new ChunkCoordinate(2, 14),
|
||||
new ChunkCoordinate(3, 14), new ChunkCoordinate(3, 15), new ChunkCoordinate(2, 15),
|
||||
new ChunkCoordinate(1, 15), new ChunkCoordinate(1, 14), new ChunkCoordinate(0, 14),
|
||||
new ChunkCoordinate(0, 15), new ChunkCoordinate(0, 16), new ChunkCoordinate(1, 16),
|
||||
new ChunkCoordinate(1, 17), new ChunkCoordinate(0, 17), new ChunkCoordinate(0, 18),
|
||||
new ChunkCoordinate(0, 19), new ChunkCoordinate(1, 19), new ChunkCoordinate(1, 18),
|
||||
new ChunkCoordinate(2, 18), new ChunkCoordinate(2, 19), new ChunkCoordinate(3, 19),
|
||||
new ChunkCoordinate(3, 18), new ChunkCoordinate(3, 17), new ChunkCoordinate(2, 17),
|
||||
new ChunkCoordinate(2, 16), new ChunkCoordinate(3, 16), new ChunkCoordinate(4, 16),
|
||||
new ChunkCoordinate(4, 17), new ChunkCoordinate(5, 17), new ChunkCoordinate(5, 16),
|
||||
new ChunkCoordinate(6, 16), new ChunkCoordinate(7, 16), new ChunkCoordinate(7, 17),
|
||||
new ChunkCoordinate(6, 17), new ChunkCoordinate(6, 18), new ChunkCoordinate(7, 18),
|
||||
new ChunkCoordinate(7, 19), new ChunkCoordinate(6, 19), new ChunkCoordinate(5, 19),
|
||||
new ChunkCoordinate(5, 18), new ChunkCoordinate(4, 18), new ChunkCoordinate(4, 19),
|
||||
new ChunkCoordinate(4, 20), new ChunkCoordinate(4, 21), new ChunkCoordinate(5, 21),
|
||||
new ChunkCoordinate(5, 20), new ChunkCoordinate(6, 20), new ChunkCoordinate(7, 20),
|
||||
new ChunkCoordinate(7, 21), new ChunkCoordinate(6, 21), new ChunkCoordinate(6, 22),
|
||||
new ChunkCoordinate(7, 22), new ChunkCoordinate(7, 23), new ChunkCoordinate(6, 23),
|
||||
new ChunkCoordinate(5, 23), new ChunkCoordinate(5, 22), new ChunkCoordinate(4, 22),
|
||||
new ChunkCoordinate(4, 23), new ChunkCoordinate(3, 23), new ChunkCoordinate(2, 23),
|
||||
new ChunkCoordinate(2, 22), new ChunkCoordinate(3, 22), new ChunkCoordinate(3, 21),
|
||||
new ChunkCoordinate(3, 20), new ChunkCoordinate(2, 20), new ChunkCoordinate(2, 21),
|
||||
new ChunkCoordinate(1, 21), new ChunkCoordinate(1, 20), new ChunkCoordinate(0, 20),
|
||||
new ChunkCoordinate(0, 21), new ChunkCoordinate(0, 22), new ChunkCoordinate(1, 22),
|
||||
new ChunkCoordinate(1, 23), new ChunkCoordinate(0, 23), new ChunkCoordinate(0, 24),
|
||||
new ChunkCoordinate(0, 25), new ChunkCoordinate(1, 25), new ChunkCoordinate(1, 24),
|
||||
new ChunkCoordinate(2, 24), new ChunkCoordinate(3, 24), new ChunkCoordinate(3, 25),
|
||||
new ChunkCoordinate(2, 25), new ChunkCoordinate(2, 26), new ChunkCoordinate(3, 26),
|
||||
new ChunkCoordinate(3, 27), new ChunkCoordinate(2, 27), new ChunkCoordinate(1, 27),
|
||||
new ChunkCoordinate(1, 26), new ChunkCoordinate(0, 26), new ChunkCoordinate(0, 27),
|
||||
new ChunkCoordinate(0, 28), new ChunkCoordinate(1, 28), new ChunkCoordinate(1, 29),
|
||||
new ChunkCoordinate(0, 29), new ChunkCoordinate(0, 30), new ChunkCoordinate(0, 31),
|
||||
new ChunkCoordinate(1, 31), new ChunkCoordinate(1, 30), new ChunkCoordinate(2, 30),
|
||||
new ChunkCoordinate(2, 31), new ChunkCoordinate(3, 31), new ChunkCoordinate(3, 30),
|
||||
new ChunkCoordinate(3, 29), new ChunkCoordinate(2, 29), new ChunkCoordinate(2, 28),
|
||||
new ChunkCoordinate(3, 28), new ChunkCoordinate(4, 28), new ChunkCoordinate(5, 28),
|
||||
new ChunkCoordinate(5, 29), new ChunkCoordinate(4, 29), new ChunkCoordinate(4, 30),
|
||||
new ChunkCoordinate(4, 31), new ChunkCoordinate(5, 31), new ChunkCoordinate(5, 30),
|
||||
new ChunkCoordinate(6, 30), new ChunkCoordinate(6, 31), new ChunkCoordinate(7, 31),
|
||||
new ChunkCoordinate(7, 30), new ChunkCoordinate(7, 29), new ChunkCoordinate(6, 29),
|
||||
new ChunkCoordinate(6, 28), new ChunkCoordinate(7, 28), new ChunkCoordinate(7, 27),
|
||||
new ChunkCoordinate(7, 26), new ChunkCoordinate(6, 26), new ChunkCoordinate(6, 27),
|
||||
new ChunkCoordinate(5, 27), new ChunkCoordinate(4, 27), new ChunkCoordinate(4, 26),
|
||||
new ChunkCoordinate(5, 26), new ChunkCoordinate(5, 25), new ChunkCoordinate(4, 25),
|
||||
new ChunkCoordinate(4, 24), new ChunkCoordinate(5, 24), new ChunkCoordinate(6, 24),
|
||||
new ChunkCoordinate(6, 25), new ChunkCoordinate(7, 25), new ChunkCoordinate(7, 24),
|
||||
new ChunkCoordinate(8, 24), new ChunkCoordinate(8, 25), new ChunkCoordinate(9, 25),
|
||||
new ChunkCoordinate(9, 24), new ChunkCoordinate(10, 24), new ChunkCoordinate(11, 24),
|
||||
new ChunkCoordinate(11, 25), new ChunkCoordinate(10, 25), new ChunkCoordinate(10, 26),
|
||||
new ChunkCoordinate(11, 26), new ChunkCoordinate(11, 27), new ChunkCoordinate(10, 27),
|
||||
new ChunkCoordinate(9, 27), new ChunkCoordinate(9, 26), new ChunkCoordinate(8, 26),
|
||||
new ChunkCoordinate(8, 27), new ChunkCoordinate(8, 28), new ChunkCoordinate(9, 28),
|
||||
new ChunkCoordinate(9, 29), new ChunkCoordinate(8, 29), new ChunkCoordinate(8, 30),
|
||||
new ChunkCoordinate(8, 31), new ChunkCoordinate(9, 31), new ChunkCoordinate(9, 30),
|
||||
new ChunkCoordinate(10, 30), new ChunkCoordinate(10, 31), new ChunkCoordinate(11, 31),
|
||||
new ChunkCoordinate(11, 30), new ChunkCoordinate(11, 29), new ChunkCoordinate(10, 29),
|
||||
new ChunkCoordinate(10, 28), new ChunkCoordinate(11, 28), new ChunkCoordinate(12, 28),
|
||||
new ChunkCoordinate(13, 28), new ChunkCoordinate(13, 29), new ChunkCoordinate(12, 29),
|
||||
new ChunkCoordinate(12, 30), new ChunkCoordinate(12, 31), new ChunkCoordinate(13, 31),
|
||||
new ChunkCoordinate(13, 30), new ChunkCoordinate(14, 30), new ChunkCoordinate(14, 31),
|
||||
new ChunkCoordinate(15, 31), new ChunkCoordinate(15, 30), new ChunkCoordinate(15, 29),
|
||||
new ChunkCoordinate(14, 29), new ChunkCoordinate(14, 28), new ChunkCoordinate(15, 28),
|
||||
new ChunkCoordinate(15, 27), new ChunkCoordinate(15, 26), new ChunkCoordinate(14, 26),
|
||||
new ChunkCoordinate(14, 27), new ChunkCoordinate(13, 27), new ChunkCoordinate(12, 27),
|
||||
new ChunkCoordinate(12, 26), new ChunkCoordinate(13, 26), new ChunkCoordinate(13, 25),
|
||||
new ChunkCoordinate(12, 25), new ChunkCoordinate(12, 24), new ChunkCoordinate(13, 24),
|
||||
new ChunkCoordinate(14, 24), new ChunkCoordinate(14, 25), new ChunkCoordinate(15, 25),
|
||||
new ChunkCoordinate(15, 24), new ChunkCoordinate(15, 23), new ChunkCoordinate(14, 23),
|
||||
new ChunkCoordinate(14, 22), new ChunkCoordinate(15, 22), new ChunkCoordinate(15, 21),
|
||||
new ChunkCoordinate(15, 20), new ChunkCoordinate(14, 20), new ChunkCoordinate(14, 21),
|
||||
new ChunkCoordinate(13, 21), new ChunkCoordinate(13, 20), new ChunkCoordinate(12, 20),
|
||||
new ChunkCoordinate(12, 21), new ChunkCoordinate(12, 22), new ChunkCoordinate(13, 22),
|
||||
new ChunkCoordinate(13, 23), new ChunkCoordinate(12, 23), new ChunkCoordinate(11, 23),
|
||||
new ChunkCoordinate(11, 22), new ChunkCoordinate(10, 22), new ChunkCoordinate(10, 23),
|
||||
new ChunkCoordinate(9, 23), new ChunkCoordinate(8, 23), new ChunkCoordinate(8, 22),
|
||||
new ChunkCoordinate(9, 22), new ChunkCoordinate(9, 21), new ChunkCoordinate(8, 21),
|
||||
new ChunkCoordinate(8, 20), new ChunkCoordinate(9, 20), new ChunkCoordinate(10, 20),
|
||||
new ChunkCoordinate(10, 21), new ChunkCoordinate(11, 21), new ChunkCoordinate(11, 20),
|
||||
new ChunkCoordinate(11, 19), new ChunkCoordinate(11, 18), new ChunkCoordinate(10, 18),
|
||||
new ChunkCoordinate(10, 19), new ChunkCoordinate(9, 19), new ChunkCoordinate(8, 19),
|
||||
new ChunkCoordinate(8, 18), new ChunkCoordinate(9, 18), new ChunkCoordinate(9, 17),
|
||||
new ChunkCoordinate(8, 17), new ChunkCoordinate(8, 16), new ChunkCoordinate(9, 16),
|
||||
new ChunkCoordinate(10, 16), new ChunkCoordinate(10, 17), new ChunkCoordinate(11, 17),
|
||||
new ChunkCoordinate(11, 16), new ChunkCoordinate(12, 16), new ChunkCoordinate(13, 16),
|
||||
new ChunkCoordinate(13, 17), new ChunkCoordinate(12, 17), new ChunkCoordinate(12, 18),
|
||||
new ChunkCoordinate(12, 19), new ChunkCoordinate(13, 19), new ChunkCoordinate(13, 18),
|
||||
new ChunkCoordinate(14, 18), new ChunkCoordinate(14, 19), new ChunkCoordinate(15, 19),
|
||||
new ChunkCoordinate(15, 18), new ChunkCoordinate(15, 17), new ChunkCoordinate(14, 17),
|
||||
new ChunkCoordinate(14, 16), new ChunkCoordinate(15, 16), new ChunkCoordinate(16, 16),
|
||||
new ChunkCoordinate(17, 16), new ChunkCoordinate(17, 17), new ChunkCoordinate(16, 17),
|
||||
new ChunkCoordinate(16, 18), new ChunkCoordinate(16, 19), new ChunkCoordinate(17, 19),
|
||||
new ChunkCoordinate(17, 18), new ChunkCoordinate(18, 18), new ChunkCoordinate(18, 19),
|
||||
new ChunkCoordinate(19, 19), new ChunkCoordinate(19, 18), new ChunkCoordinate(19, 17),
|
||||
new ChunkCoordinate(18, 17), new ChunkCoordinate(18, 16), new ChunkCoordinate(19, 16),
|
||||
new ChunkCoordinate(20, 16), new ChunkCoordinate(20, 17), new ChunkCoordinate(21, 17),
|
||||
new ChunkCoordinate(21, 16), new ChunkCoordinate(22, 16), new ChunkCoordinate(23, 16),
|
||||
new ChunkCoordinate(23, 17), new ChunkCoordinate(22, 17), new ChunkCoordinate(22, 18),
|
||||
new ChunkCoordinate(23, 18), new ChunkCoordinate(23, 19), new ChunkCoordinate(22, 19),
|
||||
new ChunkCoordinate(21, 19), new ChunkCoordinate(21, 18), new ChunkCoordinate(20, 18),
|
||||
new ChunkCoordinate(20, 19), new ChunkCoordinate(20, 20), new ChunkCoordinate(20, 21),
|
||||
new ChunkCoordinate(21, 21), new ChunkCoordinate(21, 20), new ChunkCoordinate(22, 20),
|
||||
new ChunkCoordinate(23, 20), new ChunkCoordinate(23, 21), new ChunkCoordinate(22, 21),
|
||||
new ChunkCoordinate(22, 22), new ChunkCoordinate(23, 22), new ChunkCoordinate(23, 23),
|
||||
new ChunkCoordinate(22, 23), new ChunkCoordinate(21, 23), new ChunkCoordinate(21, 22),
|
||||
new ChunkCoordinate(20, 22), new ChunkCoordinate(20, 23), new ChunkCoordinate(19, 23),
|
||||
new ChunkCoordinate(18, 23), new ChunkCoordinate(18, 22), new ChunkCoordinate(19, 22),
|
||||
new ChunkCoordinate(19, 21), new ChunkCoordinate(19, 20), new ChunkCoordinate(18, 20),
|
||||
new ChunkCoordinate(18, 21), new ChunkCoordinate(17, 21), new ChunkCoordinate(17, 20),
|
||||
new ChunkCoordinate(16, 20), new ChunkCoordinate(16, 21), new ChunkCoordinate(16, 22),
|
||||
new ChunkCoordinate(17, 22), new ChunkCoordinate(17, 23), new ChunkCoordinate(16, 23),
|
||||
new ChunkCoordinate(16, 24), new ChunkCoordinate(16, 25), new ChunkCoordinate(17, 25),
|
||||
new ChunkCoordinate(17, 24), new ChunkCoordinate(18, 24), new ChunkCoordinate(19, 24),
|
||||
new ChunkCoordinate(19, 25), new ChunkCoordinate(18, 25), new ChunkCoordinate(18, 26),
|
||||
new ChunkCoordinate(19, 26), new ChunkCoordinate(19, 27), new ChunkCoordinate(18, 27),
|
||||
new ChunkCoordinate(17, 27), new ChunkCoordinate(17, 26), new ChunkCoordinate(16, 26),
|
||||
new ChunkCoordinate(16, 27), new ChunkCoordinate(16, 28), new ChunkCoordinate(17, 28),
|
||||
new ChunkCoordinate(17, 29), new ChunkCoordinate(16, 29), new ChunkCoordinate(16, 30),
|
||||
new ChunkCoordinate(16, 31), new ChunkCoordinate(17, 31), new ChunkCoordinate(17, 30),
|
||||
new ChunkCoordinate(18, 30), new ChunkCoordinate(18, 31), new ChunkCoordinate(19, 31),
|
||||
new ChunkCoordinate(19, 30), new ChunkCoordinate(19, 29), new ChunkCoordinate(18, 29),
|
||||
new ChunkCoordinate(18, 28), new ChunkCoordinate(19, 28), new ChunkCoordinate(20, 28),
|
||||
new ChunkCoordinate(21, 28), new ChunkCoordinate(21, 29), new ChunkCoordinate(20, 29),
|
||||
new ChunkCoordinate(20, 30), new ChunkCoordinate(20, 31), new ChunkCoordinate(21, 31),
|
||||
new ChunkCoordinate(21, 30), new ChunkCoordinate(22, 30), new ChunkCoordinate(22, 31),
|
||||
new ChunkCoordinate(23, 31), new ChunkCoordinate(23, 30), new ChunkCoordinate(23, 29),
|
||||
new ChunkCoordinate(22, 29), new ChunkCoordinate(22, 28), new ChunkCoordinate(23, 28),
|
||||
new ChunkCoordinate(23, 27), new ChunkCoordinate(23, 26), new ChunkCoordinate(22, 26),
|
||||
new ChunkCoordinate(22, 27), new ChunkCoordinate(21, 27), new ChunkCoordinate(20, 27),
|
||||
new ChunkCoordinate(20, 26), new ChunkCoordinate(21, 26), new ChunkCoordinate(21, 25),
|
||||
new ChunkCoordinate(20, 25), new ChunkCoordinate(20, 24), new ChunkCoordinate(21, 24),
|
||||
new ChunkCoordinate(22, 24), new ChunkCoordinate(22, 25), new ChunkCoordinate(23, 25),
|
||||
new ChunkCoordinate(23, 24), new ChunkCoordinate(24, 24), new ChunkCoordinate(24, 25),
|
||||
new ChunkCoordinate(25, 25), new ChunkCoordinate(25, 24), new ChunkCoordinate(26, 24),
|
||||
new ChunkCoordinate(27, 24), new ChunkCoordinate(27, 25), new ChunkCoordinate(26, 25),
|
||||
new ChunkCoordinate(26, 26), new ChunkCoordinate(27, 26), new ChunkCoordinate(27, 27),
|
||||
new ChunkCoordinate(26, 27), new ChunkCoordinate(25, 27), new ChunkCoordinate(25, 26),
|
||||
new ChunkCoordinate(24, 26), new ChunkCoordinate(24, 27), new ChunkCoordinate(24, 28),
|
||||
new ChunkCoordinate(25, 28), new ChunkCoordinate(25, 29), new ChunkCoordinate(24, 29),
|
||||
new ChunkCoordinate(24, 30), new ChunkCoordinate(24, 31), new ChunkCoordinate(25, 31),
|
||||
new ChunkCoordinate(25, 30), new ChunkCoordinate(26, 30), new ChunkCoordinate(26, 31),
|
||||
new ChunkCoordinate(27, 31), new ChunkCoordinate(27, 30), new ChunkCoordinate(27, 29),
|
||||
new ChunkCoordinate(26, 29), new ChunkCoordinate(26, 28), new ChunkCoordinate(27, 28),
|
||||
new ChunkCoordinate(28, 28), new ChunkCoordinate(29, 28), new ChunkCoordinate(29, 29),
|
||||
new ChunkCoordinate(28, 29), new ChunkCoordinate(28, 30), new ChunkCoordinate(28, 31),
|
||||
new ChunkCoordinate(29, 31), new ChunkCoordinate(29, 30), new ChunkCoordinate(30, 30),
|
||||
new ChunkCoordinate(30, 31), new ChunkCoordinate(31, 31), new ChunkCoordinate(31, 30),
|
||||
new ChunkCoordinate(31, 29), new ChunkCoordinate(30, 29), new ChunkCoordinate(30, 28),
|
||||
new ChunkCoordinate(31, 28), new ChunkCoordinate(31, 27), new ChunkCoordinate(31, 26),
|
||||
new ChunkCoordinate(30, 26), new ChunkCoordinate(30, 27), new ChunkCoordinate(29, 27),
|
||||
new ChunkCoordinate(28, 27), new ChunkCoordinate(28, 26), new ChunkCoordinate(29, 26),
|
||||
new ChunkCoordinate(29, 25), new ChunkCoordinate(28, 25), new ChunkCoordinate(28, 24),
|
||||
new ChunkCoordinate(29, 24), new ChunkCoordinate(30, 24), new ChunkCoordinate(30, 25),
|
||||
new ChunkCoordinate(31, 25), new ChunkCoordinate(31, 24), new ChunkCoordinate(31, 23),
|
||||
new ChunkCoordinate(30, 23), new ChunkCoordinate(30, 22), new ChunkCoordinate(31, 22),
|
||||
new ChunkCoordinate(31, 21), new ChunkCoordinate(31, 20), new ChunkCoordinate(30, 20),
|
||||
new ChunkCoordinate(30, 21), new ChunkCoordinate(29, 21), new ChunkCoordinate(29, 20),
|
||||
new ChunkCoordinate(28, 20), new ChunkCoordinate(28, 21), new ChunkCoordinate(28, 22),
|
||||
new ChunkCoordinate(29, 22), new ChunkCoordinate(29, 23), new ChunkCoordinate(28, 23),
|
||||
new ChunkCoordinate(27, 23), new ChunkCoordinate(27, 22), new ChunkCoordinate(26, 22),
|
||||
new ChunkCoordinate(26, 23), new ChunkCoordinate(25, 23), new ChunkCoordinate(24, 23),
|
||||
new ChunkCoordinate(24, 22), new ChunkCoordinate(25, 22), new ChunkCoordinate(25, 21),
|
||||
new ChunkCoordinate(24, 21), new ChunkCoordinate(24, 20), new ChunkCoordinate(25, 20),
|
||||
new ChunkCoordinate(26, 20), new ChunkCoordinate(26, 21), new ChunkCoordinate(27, 21),
|
||||
new ChunkCoordinate(27, 20), new ChunkCoordinate(27, 19), new ChunkCoordinate(27, 18),
|
||||
new ChunkCoordinate(26, 18), new ChunkCoordinate(26, 19), new ChunkCoordinate(25, 19),
|
||||
new ChunkCoordinate(24, 19), new ChunkCoordinate(24, 18), new ChunkCoordinate(25, 18),
|
||||
new ChunkCoordinate(25, 17), new ChunkCoordinate(24, 17), new ChunkCoordinate(24, 16),
|
||||
new ChunkCoordinate(25, 16), new ChunkCoordinate(26, 16), new ChunkCoordinate(26, 17),
|
||||
new ChunkCoordinate(27, 17), new ChunkCoordinate(27, 16), new ChunkCoordinate(28, 16),
|
||||
new ChunkCoordinate(29, 16), new ChunkCoordinate(29, 17), new ChunkCoordinate(28, 17),
|
||||
new ChunkCoordinate(28, 18), new ChunkCoordinate(28, 19), new ChunkCoordinate(29, 19),
|
||||
new ChunkCoordinate(29, 18), new ChunkCoordinate(30, 18), new ChunkCoordinate(30, 19),
|
||||
new ChunkCoordinate(31, 19), new ChunkCoordinate(31, 18), new ChunkCoordinate(31, 17),
|
||||
new ChunkCoordinate(30, 17), new ChunkCoordinate(30, 16), new ChunkCoordinate(31, 16),
|
||||
new ChunkCoordinate(31, 15), new ChunkCoordinate(31, 14), new ChunkCoordinate(30, 14),
|
||||
new ChunkCoordinate(30, 15), new ChunkCoordinate(29, 15), new ChunkCoordinate(28, 15),
|
||||
new ChunkCoordinate(28, 14), new ChunkCoordinate(29, 14), new ChunkCoordinate(29, 13),
|
||||
new ChunkCoordinate(28, 13), new ChunkCoordinate(28, 12), new ChunkCoordinate(29, 12),
|
||||
new ChunkCoordinate(30, 12), new ChunkCoordinate(30, 13), new ChunkCoordinate(31, 13),
|
||||
new ChunkCoordinate(31, 12), new ChunkCoordinate(31, 11), new ChunkCoordinate(30, 11),
|
||||
new ChunkCoordinate(30, 10), new ChunkCoordinate(31, 10), new ChunkCoordinate(31, 9),
|
||||
new ChunkCoordinate(31, 8), new ChunkCoordinate(30, 8), new ChunkCoordinate(30, 9),
|
||||
new ChunkCoordinate(29, 9), new ChunkCoordinate(29, 8), new ChunkCoordinate(28, 8),
|
||||
new ChunkCoordinate(28, 9), new ChunkCoordinate(28, 10), new ChunkCoordinate(29, 10),
|
||||
new ChunkCoordinate(29, 11), new ChunkCoordinate(28, 11), new ChunkCoordinate(27, 11),
|
||||
new ChunkCoordinate(26, 11), new ChunkCoordinate(26, 10), new ChunkCoordinate(27, 10),
|
||||
new ChunkCoordinate(27, 9), new ChunkCoordinate(27, 8), new ChunkCoordinate(26, 8),
|
||||
new ChunkCoordinate(26, 9), new ChunkCoordinate(25, 9), new ChunkCoordinate(25, 8),
|
||||
new ChunkCoordinate(24, 8), new ChunkCoordinate(24, 9), new ChunkCoordinate(24, 10),
|
||||
new ChunkCoordinate(25, 10), new ChunkCoordinate(25, 11), new ChunkCoordinate(24, 11),
|
||||
new ChunkCoordinate(24, 12), new ChunkCoordinate(24, 13), new ChunkCoordinate(25, 13),
|
||||
new ChunkCoordinate(25, 12), new ChunkCoordinate(26, 12), new ChunkCoordinate(27, 12),
|
||||
new ChunkCoordinate(27, 13), new ChunkCoordinate(26, 13), new ChunkCoordinate(26, 14),
|
||||
new ChunkCoordinate(27, 14), new ChunkCoordinate(27, 15), new ChunkCoordinate(26, 15),
|
||||
new ChunkCoordinate(25, 15), new ChunkCoordinate(25, 14), new ChunkCoordinate(24, 14),
|
||||
new ChunkCoordinate(24, 15), new ChunkCoordinate(23, 15), new ChunkCoordinate(22, 15),
|
||||
new ChunkCoordinate(22, 14), new ChunkCoordinate(23, 14), new ChunkCoordinate(23, 13),
|
||||
new ChunkCoordinate(23, 12), new ChunkCoordinate(22, 12), new ChunkCoordinate(22, 13),
|
||||
new ChunkCoordinate(21, 13), new ChunkCoordinate(21, 12), new ChunkCoordinate(20, 12),
|
||||
new ChunkCoordinate(20, 13), new ChunkCoordinate(20, 14), new ChunkCoordinate(21, 14),
|
||||
new ChunkCoordinate(21, 15), new ChunkCoordinate(20, 15), new ChunkCoordinate(19, 15),
|
||||
new ChunkCoordinate(19, 14), new ChunkCoordinate(18, 14), new ChunkCoordinate(18, 15),
|
||||
new ChunkCoordinate(17, 15), new ChunkCoordinate(16, 15), new ChunkCoordinate(16, 14),
|
||||
new ChunkCoordinate(17, 14), new ChunkCoordinate(17, 13), new ChunkCoordinate(16, 13),
|
||||
new ChunkCoordinate(16, 12), new ChunkCoordinate(17, 12), new ChunkCoordinate(18, 12),
|
||||
new ChunkCoordinate(18, 13), new ChunkCoordinate(19, 13), new ChunkCoordinate(19, 12),
|
||||
new ChunkCoordinate(19, 11), new ChunkCoordinate(19, 10), new ChunkCoordinate(18, 10),
|
||||
new ChunkCoordinate(18, 11), new ChunkCoordinate(17, 11), new ChunkCoordinate(16, 11),
|
||||
new ChunkCoordinate(16, 10), new ChunkCoordinate(17, 10), new ChunkCoordinate(17, 9),
|
||||
new ChunkCoordinate(16, 9), new ChunkCoordinate(16, 8), new ChunkCoordinate(17, 8),
|
||||
new ChunkCoordinate(18, 8), new ChunkCoordinate(18, 9), new ChunkCoordinate(19, 9),
|
||||
new ChunkCoordinate(19, 8), new ChunkCoordinate(20, 8), new ChunkCoordinate(21, 8),
|
||||
new ChunkCoordinate(21, 9), new ChunkCoordinate(20, 9), new ChunkCoordinate(20, 10),
|
||||
new ChunkCoordinate(20, 11), new ChunkCoordinate(21, 11), new ChunkCoordinate(21, 10),
|
||||
new ChunkCoordinate(22, 10), new ChunkCoordinate(22, 11), new ChunkCoordinate(23, 11),
|
||||
new ChunkCoordinate(23, 10), new ChunkCoordinate(23, 9), new ChunkCoordinate(22, 9),
|
||||
new ChunkCoordinate(22, 8), new ChunkCoordinate(23, 8), new ChunkCoordinate(23, 7),
|
||||
new ChunkCoordinate(22, 7), new ChunkCoordinate(22, 6), new ChunkCoordinate(23, 6),
|
||||
new ChunkCoordinate(23, 5), new ChunkCoordinate(23, 4), new ChunkCoordinate(22, 4),
|
||||
new ChunkCoordinate(22, 5), new ChunkCoordinate(21, 5), new ChunkCoordinate(21, 4),
|
||||
new ChunkCoordinate(20, 4), new ChunkCoordinate(20, 5), new ChunkCoordinate(20, 6),
|
||||
new ChunkCoordinate(21, 6), new ChunkCoordinate(21, 7), new ChunkCoordinate(20, 7),
|
||||
new ChunkCoordinate(19, 7), new ChunkCoordinate(19, 6), new ChunkCoordinate(18, 6),
|
||||
new ChunkCoordinate(18, 7), new ChunkCoordinate(17, 7), new ChunkCoordinate(16, 7),
|
||||
new ChunkCoordinate(16, 6), new ChunkCoordinate(17, 6), new ChunkCoordinate(17, 5),
|
||||
new ChunkCoordinate(16, 5), new ChunkCoordinate(16, 4), new ChunkCoordinate(17, 4),
|
||||
new ChunkCoordinate(18, 4), new ChunkCoordinate(18, 5), new ChunkCoordinate(19, 5),
|
||||
new ChunkCoordinate(19, 4), new ChunkCoordinate(19, 3), new ChunkCoordinate(19, 2),
|
||||
new ChunkCoordinate(18, 2), new ChunkCoordinate(18, 3), new ChunkCoordinate(17, 3),
|
||||
new ChunkCoordinate(16, 3), new ChunkCoordinate(16, 2), new ChunkCoordinate(17, 2),
|
||||
new ChunkCoordinate(17, 1), new ChunkCoordinate(16, 1), new ChunkCoordinate(16, 0),
|
||||
new ChunkCoordinate(17, 0), new ChunkCoordinate(18, 0), new ChunkCoordinate(18, 1),
|
||||
new ChunkCoordinate(19, 1), new ChunkCoordinate(19, 0), new ChunkCoordinate(20, 0),
|
||||
new ChunkCoordinate(21, 0), new ChunkCoordinate(21, 1), new ChunkCoordinate(20, 1),
|
||||
new ChunkCoordinate(20, 2), new ChunkCoordinate(20, 3), new ChunkCoordinate(21, 3),
|
||||
new ChunkCoordinate(21, 2), new ChunkCoordinate(22, 2), new ChunkCoordinate(22, 3),
|
||||
new ChunkCoordinate(23, 3), new ChunkCoordinate(23, 2), new ChunkCoordinate(23, 1),
|
||||
new ChunkCoordinate(22, 1), new ChunkCoordinate(22, 0), new ChunkCoordinate(23, 0),
|
||||
new ChunkCoordinate(24, 0), new ChunkCoordinate(24, 1), new ChunkCoordinate(25, 1),
|
||||
new ChunkCoordinate(25, 0), new ChunkCoordinate(26, 0), new ChunkCoordinate(27, 0),
|
||||
new ChunkCoordinate(27, 1), new ChunkCoordinate(26, 1), new ChunkCoordinate(26, 2),
|
||||
new ChunkCoordinate(27, 2), new ChunkCoordinate(27, 3), new ChunkCoordinate(26, 3),
|
||||
new ChunkCoordinate(25, 3), new ChunkCoordinate(25, 2), new ChunkCoordinate(24, 2),
|
||||
new ChunkCoordinate(24, 3), new ChunkCoordinate(24, 4), new ChunkCoordinate(25, 4),
|
||||
new ChunkCoordinate(25, 5), new ChunkCoordinate(24, 5), new ChunkCoordinate(24, 6),
|
||||
new ChunkCoordinate(24, 7), new ChunkCoordinate(25, 7), new ChunkCoordinate(25, 6),
|
||||
new ChunkCoordinate(26, 6), new ChunkCoordinate(26, 7), new ChunkCoordinate(27, 7),
|
||||
new ChunkCoordinate(27, 6), new ChunkCoordinate(27, 5), new ChunkCoordinate(26, 5),
|
||||
new ChunkCoordinate(26, 4), new ChunkCoordinate(27, 4), new ChunkCoordinate(28, 4),
|
||||
new ChunkCoordinate(29, 4), new ChunkCoordinate(29, 5), new ChunkCoordinate(28, 5),
|
||||
new ChunkCoordinate(28, 6), new ChunkCoordinate(28, 7), new ChunkCoordinate(29, 7),
|
||||
new ChunkCoordinate(29, 6), new ChunkCoordinate(30, 6), new ChunkCoordinate(30, 7),
|
||||
new ChunkCoordinate(31, 7), new ChunkCoordinate(31, 6), new ChunkCoordinate(31, 5),
|
||||
new ChunkCoordinate(30, 5), new ChunkCoordinate(30, 4), new ChunkCoordinate(31, 4),
|
||||
new ChunkCoordinate(31, 3), new ChunkCoordinate(31, 2), new ChunkCoordinate(30, 2),
|
||||
new ChunkCoordinate(30, 3), new ChunkCoordinate(29, 3), new ChunkCoordinate(28, 3),
|
||||
new ChunkCoordinate(28, 2), new ChunkCoordinate(29, 2), new ChunkCoordinate(29, 1),
|
||||
new ChunkCoordinate(28, 1), new ChunkCoordinate(28, 0), new ChunkCoordinate(29, 0),
|
||||
new ChunkCoordinate(30, 0), new ChunkCoordinate(30, 1), new ChunkCoordinate(31, 1),
|
||||
new ChunkCoordinate(31, 0)
|
||||
};
|
||||
|
||||
private Hilbert() {
|
||||
}
|
||||
|
||||
public static ChunkCoordinate regionDistanceToChunkCoordinateOffset(final int distance) {
|
||||
return regionChunkCoordinateOffsets[distance];
|
||||
}
|
||||
|
||||
public static ChunkCoordinate[] chunkCoordinateOffsets() {
|
||||
return regionChunkCoordinateOffsets;
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ public final class Input {
|
||||
return Optional.empty();
|
||||
}
|
||||
final String inputLower = input.toLowerCase();
|
||||
if (ShapeType.ALL.contains(inputLower)) {
|
||||
if (ShapeType.all().contains(inputLower)) {
|
||||
return Optional.of(inputLower);
|
||||
}
|
||||
return Optional.empty();
|
||||
|
||||
@@ -66,7 +66,7 @@ public class TaskLoader {
|
||||
final double centerZ = Input.tryDouble(task.getProperty(TaskProperty.CENTER_Z.key())).orElse(Selection.DEFAULT_CENTER_Z);
|
||||
final double radiusX = Input.tryDouble(task.getProperty(TaskProperty.RADIUS_X.key())).orElse(Selection.DEFAULT_RADIUS);
|
||||
final double radiusZ = Input.tryDouble(task.getProperty(TaskProperty.RADIUS_Z.key())).orElse(radiusX);
|
||||
final String pattern = task.getProperty(TaskProperty.PATTERN.key(), PatternType.CONCENTRIC);
|
||||
final String pattern = task.getProperty(TaskProperty.PATTERN.key(), PatternType.REGION);
|
||||
final String file = task.getProperty(TaskProperty.CSV.key());
|
||||
final String shape = task.getProperty(TaskProperty.SHAPE.key(), ShapeType.SQUARE);
|
||||
final Selection.Builder selection = Selection.builder(chunky, world)
|
||||
@@ -102,10 +102,10 @@ public class TaskLoader {
|
||||
if (ShapeType.RECTANGLE.equals(shape) || ShapeType.ELLIPSE.equals(shape)) {
|
||||
properties.setProperty(TaskProperty.RADIUS_Z.key(), String.valueOf(selection.radiusZ()));
|
||||
}
|
||||
final String pattern = task.getChunkIterator().name();
|
||||
properties.setProperty(TaskProperty.PATTERN.key(), pattern);
|
||||
if (PatternType.CSV.equals(pattern)) {
|
||||
task.getSelection().pattern().getValue().ifPresent(file -> properties.setProperty(TaskProperty.CSV.key(), file));
|
||||
final Parameter pattern = Parameter.of(task.getChunkIterator().name());
|
||||
properties.setProperty(TaskProperty.PATTERN.key(), pattern.getType());
|
||||
if (PatternType.CSV.equals(pattern.getType())) {
|
||||
pattern.getValue().ifPresent(file -> properties.setProperty(TaskProperty.CSV.key(), file));
|
||||
}
|
||||
properties.setProperty(TaskProperty.SHAPE.key(), shape);
|
||||
properties.setProperty(TaskProperty.CHUNKS.key(), String.valueOf(task.getCount()));
|
||||
|
||||
@@ -28,6 +28,8 @@ public final class TranslationKey {
|
||||
public static final String FORMAT_CONTINUE = "format_continue";
|
||||
public static final String FORMAT_CONTINUE_NO_TASKS = "format_continue_no_tasks";
|
||||
public static final String FORMAT_TRIM_CONFIRM = "format_trim_confirm";
|
||||
public static final String FORMAT_TRIM_CONFIRM_INSIDE = "format_trim_confirm_inside";
|
||||
public static final String FORMAT_TRIM_CONFIRM_INHABITED = "format_trim_confirm_inhabited";
|
||||
public static final String FORMAT_PATTERN = "format_pattern";
|
||||
public static final String FORMAT_PAUSE = "format_pause";
|
||||
public static final String FORMAT_PAUSE_NO_TASKS = "format_pause_no_tasks";
|
||||
@@ -51,6 +53,7 @@ public final class TranslationKey {
|
||||
public static final String FORMAT_START_LIMIT = "format_start_limit";
|
||||
public static final String FORMAT_STARTED_ALREADY = "format_started_already";
|
||||
public static final String FORMAT_WORLD = "format_world";
|
||||
public static final String FORMAT_WORLDBORDER_TOO_LARGE = "format_worldborder_too_large";
|
||||
public static final String HELP_BORDER = "help_border";
|
||||
public static final String HELP_CANCEL = "help_cancel";
|
||||
public static final String HELP_CENTER = "help_center";
|
||||
@@ -76,15 +79,18 @@ public final class TranslationKey {
|
||||
public static final String PATTERN_LOOP = "pattern_loop";
|
||||
public static final String PATTERN_SPIRAL = "pattern_spiral";
|
||||
public static final String PATTERN_CSV = "pattern_csv";
|
||||
public static final String PATTERN_REGION = "pattern_region";
|
||||
public static final String SHAPE_CIRCLE = "shape_circle";
|
||||
public static final String SHAPE_DIAMOND = "shape_diamond";
|
||||
public static final String SHAPE_ELLIPSE = "shape_ellipse";
|
||||
public static final String SHAPE_HEXAGON = "shape_hexagon";
|
||||
public static final String SHAPE_PENTAGON = "shape_pentagon";
|
||||
public static final String SHAPE_RECTANGLE = "shape_rectangle";
|
||||
public static final String SHAPE_SQUARE = "shape_square";
|
||||
public static final String SHAPE_STAR = "shape_star";
|
||||
public static final String SHAPE_TRIANGLE = "shape_triangle";
|
||||
public static final String TASK_TRIM = "task_trim";
|
||||
public static final String TASK_TRIM_UPDATE = "task_trim_update";
|
||||
public static final String TASK_DONE = "task_done";
|
||||
public static final String TASK_STOPPED = "task_stopped";
|
||||
public static final String TASK_UPDATE = "task_update";
|
||||
|
||||
@@ -31,7 +31,7 @@ public final class Translator {
|
||||
|
||||
public static String translateKey(final String key, final boolean prefixed, final Object... args) {
|
||||
final StringBuilder translation = new StringBuilder();
|
||||
final String message = translations.getOrDefault(key, fallbackTranslations.getOrDefault(key, "Missing translation"));
|
||||
final String message = translations.getOrDefault(key, fallbackTranslations.getOrDefault(key, key));
|
||||
if (prefixed) {
|
||||
translation.append("[Chunky] ");
|
||||
}
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
package org.popcraft.chunky.world;
|
||||
|
||||
import org.popcraft.chunky.nbt.CompoundTag;
|
||||
import org.popcraft.chunky.nbt.IntTag;
|
||||
import org.popcraft.chunky.nbt.Tag;
|
||||
import org.popcraft.chunky.util.ChunkMath;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
public final class RegionFile {
|
||||
private static final int ENTRIES = 1024;
|
||||
private static final int SECTOR_SIZE = 4096;
|
||||
private final Map<Long, Chunk> chunks = new HashMap<>();
|
||||
|
||||
public RegionFile(final File file) {
|
||||
try (final RandomAccessFile region = new RandomAccessFile(file, "r")) {
|
||||
final int[] offsetTable = new int[ENTRIES];
|
||||
final int[] sizeTable = new int[ENTRIES];
|
||||
for (int i = 0; i < ENTRIES; ++i) {
|
||||
final int location = region.readInt();
|
||||
offsetTable[i] = (location >> 8) & 0xFFFFFF;
|
||||
sizeTable[i] = location & 0xFF;
|
||||
}
|
||||
final int[] timestampTable = new int[ENTRIES];
|
||||
for (int i = 0; i < ENTRIES; ++i) {
|
||||
timestampTable[i] = region.readInt();
|
||||
}
|
||||
for (int i = 0; i < ENTRIES; ++i) {
|
||||
final int offset = offsetTable[i] * SECTOR_SIZE;
|
||||
final int size = sizeTable[i] * SECTOR_SIZE;
|
||||
if (offset == 0 && size == 0) {
|
||||
continue;
|
||||
}
|
||||
region.seek(offset);
|
||||
final int length = region.readInt();
|
||||
final byte compressionType = region.readByte();
|
||||
if (compressionType != 2) {
|
||||
throw new UnsupportedOperationException("Not in zlib format");
|
||||
}
|
||||
final byte[] compressed = new byte[length - 1];
|
||||
region.readFully(compressed);
|
||||
final DataInputStream input = new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(compressed)));
|
||||
if (Tag.load(input) instanceof final CompoundTag data) {
|
||||
final Optional<IntTag> xPos = data.getInt("xPos");
|
||||
final Optional<IntTag> zPos = data.getInt("zPos");
|
||||
if (xPos.isEmpty() || zPos.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
final int x = xPos.get().value();
|
||||
final int z = zPos.get().value();
|
||||
final long pos = ChunkMath.pack(x, z);
|
||||
chunks.put(pos, new Chunk(data, timestampTable[i], x, z));
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<Chunk> getChunks() {
|
||||
return chunks.values();
|
||||
}
|
||||
|
||||
public Optional<Chunk> getChunk(final int x, final int z) {
|
||||
final long pos = ChunkMath.pack(x, z);
|
||||
return Optional.ofNullable(chunks.get(pos));
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "Задача възобновена за %s.",
|
||||
"format_continue_no_tasks": "Няма задачи за възобновяване.",
|
||||
"format_trim_confirm": "&cПредупреждение: Чънкове в %s, извън %s региона центриран на %s, %s с радиус от %s ще бъдат перманентно изтрити. Моля, уверете се, че сте направили бакъп на Вашият сървър преди да продължите, за да избегнете потенциални щети. Ще бъдете задължени напълно да рестартирате Вашият сървър, след като задачата приключи. Ако разбирате и желаете да продължите напишете '%s'.",
|
||||
"format_trim_confirm_inside": "&cWarning: Chunks in %s inside of the %s region centered at %s, %s with radius %s will be permanently deleted. Please make sure you have taken a backup of your server before continuing to avoid potential damage. You will be required to restart your server fully after the task has finished. If you understand and wish to proceed, type '%s'.",
|
||||
"format_trim_confirm_inhabited": "&eNotice: Filtering chunks by a maximum inhabited time of %s ticks. Trim may take longer than usual to complete.",
|
||||
"format_pattern": "Шарка променена на %s.",
|
||||
"format_pause": "Задача поставена на пауза за %s.",
|
||||
"format_pause_no_tasks": "Няма задачи за поставяне на пауза.",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "Вашият хост е ограничил максималният радиус на прегенерация на %s, за да избегне прекомерно използване на дисковото пространство. Намалете радиус или се свържете с Вашият хост, ако желаете този лимит да бъде премахнат.",
|
||||
"format_started_already": "Задачата е вече стартирана за %s!",
|
||||
"format_world": "Свят променен на %s.",
|
||||
"format_worldborder_too_large": "&eNotice: Your world border is currently set larger than the maximum of %s configured in server.properties. This is normally an error and can cause issues.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Управлявайте персонализираните световни граници",
|
||||
"help_cancel": "&2chunky cancel&r - Спиране и изтриване на текущи или запазени задачи",
|
||||
"help_center": "&2chunky center <x> <z>&r - Задаване на позицията на централния блок",
|
||||
@@ -74,15 +77,19 @@
|
||||
"pattern_loop": "цикличен",
|
||||
"pattern_spiral": "спирален",
|
||||
"pattern_csv": "цсв",
|
||||
"pattern_region": "регион",
|
||||
"pattern_world": "свят",
|
||||
"shape_circle": "кръгъл",
|
||||
"shape_diamond": "диамантен",
|
||||
"shape_ellipse": "елипса",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "петоъгълен",
|
||||
"shape_rectangle": "правоъгълен",
|
||||
"shape_square": "квадратен",
|
||||
"shape_star": "звезден",
|
||||
"shape_triangle": "триъгълен",
|
||||
"task_trim": "Изтрити %s чънка от %s за %s секунди.",
|
||||
"task_trim_update": "Task running for %s. Processed: %s regions (%s%%)",
|
||||
"task_done": "Завършена задача за %s. Обработени: %s чънкове (%s%%), Общо време: %s:%s:%s",
|
||||
"task_stopped": "Задача спряна за %s.",
|
||||
"task_update": "Протичаща задача за %s. Обработени: %s чънкове (%s%%), ETA: %s:%s:%s, Скорост: %s cps, Текущ: %s, %s",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"format_border_load": "Selekcija učitana iz bordera svijeta %s.",
|
||||
"format_border_no_border": "Nema bordera svijeta za %s.",
|
||||
"format_border_remove": "Obrisan border svijeta iz %s.",
|
||||
"format_border_wrap": "World border wrap changed to %s for %s.",
|
||||
"format_border_wrap": "Wrapped border promijenjen u %s za %s.",
|
||||
"format_cancel": "Proces otkazan za %s.",
|
||||
"format_cancel_all": "Otkazivanje svih procesa.",
|
||||
"format_cancel_confirm": "Otkazani procesi ne mogu biti nastavljeni. Ako sigurno želite da otkažete, kucajte '%s'.",
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "Proces nastavljen za %s.",
|
||||
"format_continue_no_tasks": "Nema procesa za nastavak.",
|
||||
"format_trim_confirm": "&cUpozorenje: Čankovi u %s izvan %s regije centrirani u %s, %s sa razdaljinom %s će biti trajno obrisani. Napravite rezervnu kopiju servera prije nego što nastavite da biste izbjegli potencijalnu štetu. Morate restartovati server kada se proces završi. Ako ste razumjeli i želite nastaviti, napišite '%s'.",
|
||||
"format_trim_confirm_inside": "&cWarning: Chunks in %s inside of the %s region centered at %s, %s with radius %s will be permanently deleted. Please make sure you have taken a backup of your server before continuing to avoid potential damage. You will be required to restart your server fully after the task has finished. If you understand and wish to proceed, type '%s'.",
|
||||
"format_trim_confirm_inhabited": "&eNotice: Filtering chunks by a maximum inhabited time of %s ticks. Trim may take longer than usual to complete.",
|
||||
"format_pattern": "Oblik promijenjen u %s.",
|
||||
"format_pause": "Proces za %s pauziran.",
|
||||
"format_pause_no_tasks": "Nema procesa za pauziranje.",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "Vaš host je ograničio maksimalnu razdaljinu pregenerisanja na %s da bi izbjegao veće korištenje memorije. Smanjite razdaljinu ili ih kontaktirajte da biste uklonili ovo ograničenje.",
|
||||
"format_started_already": "Proces je već pokrenut za %s!",
|
||||
"format_world": "Svijet promijenjen u %s.",
|
||||
"format_worldborder_too_large": "&eNotice: Your world border is currently set larger than the maximum of %s configured in server.properties. This is normally an error and can cause issues.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Upravljajte borderima svijetova",
|
||||
"help_cancel": "&2chunky cancel&r - Prekinite i obrišite trenutne ili sačuvane procese",
|
||||
"help_center": "&2chunky center <x> <z>&r - Postavite centralne koordinate",
|
||||
@@ -74,23 +77,27 @@
|
||||
"pattern_loop": "petlja",
|
||||
"pattern_spiral": "spirala",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "region",
|
||||
"pattern_world": "world",
|
||||
"shape_circle": "krug",
|
||||
"shape_diamond": "romb",
|
||||
"shape_ellipse": "elipsa",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "pentagon",
|
||||
"shape_rectangle": "pravougaonik",
|
||||
"shape_square": "kvadrat",
|
||||
"shape_star": "zvijezda",
|
||||
"shape_triangle": "trougao",
|
||||
"task_trim": "Obrisano %s čankova iz %s u %s sekundi.",
|
||||
"task_trim_update": "Task running for %s. Processed: %s regions (%s%%)",
|
||||
"task_done": "Proces završen za %s. Obrađeno: %s čankova (%s%%), Proteklo vremena: %s:%s:%s",
|
||||
"task_stopped": "Proces zaustavljen za %s.",
|
||||
"task_update": "U toku je proces za %s. Obrađeno: %s čankova (%s%%), Preostalo: %s:%s:%s, Brzina: %s čps, Trenutno: %s, %s",
|
||||
"wrap_both": "both",
|
||||
"wrap_default": "default",
|
||||
"wrap_both": "oba",
|
||||
"wrap_default": "podrazumijevano",
|
||||
"wrap_earth": "earth",
|
||||
"wrap_none": "none",
|
||||
"wrap_radial": "radial",
|
||||
"wrap_none": "ništa",
|
||||
"wrap_radial": "radijalno",
|
||||
"wrap_x": "x",
|
||||
"wrap_z": "z"
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
"format_border_load": "Výběr byl načten z okraje světa pro %s.",
|
||||
"format_border_no_border": "Pro %s neexistuje žádná hranice světa.",
|
||||
"format_border_remove": "Ohraničení světa bylo odebráno z %s.",
|
||||
"format_border_wrap": "World border wrap changed to %s for %s.",
|
||||
"format_border_wrap": "Zabalování hranic světa změněno na %s pro %s.",
|
||||
"format_cancel": "Úkol zrušen pro %s.",
|
||||
"format_cancel_all": "Rušení všech úkolů.",
|
||||
"format_cancel_confirm": "Ve zrušeném úkolu nelze pokračovat. Pokud jsi si jistý, že chceš zrušit úkol, napiš '%s'.",
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "Úkol pokračuje pro %s.",
|
||||
"format_continue_no_tasks": "Žádné úkoly k pokračování.",
|
||||
"format_trim_confirm": "&cVarování: chunky v %s mimo oblast %s se středem na %s, %s s poloměrem %s budou natrvalo odstraněny. Před pokračováním se ujistěte, že jste si vytvořili zálohu svého serveru a zabránili tak potenciálnímu poškození. Po dokončení úkolu budete muset plně restartovat server. Pokud souhlasíte a přejete si pokračovat, zadejte '%s'.",
|
||||
"format_trim_confirm_inside": "&cVarování: chunky v %s uvnitř oblasti %s se středem v %s, %s s poloměrem %s budou natrvalo odstraněny. Před pokračováním se ujistěte, že jste si vytvořili zálohu svého serveru a zabránili tak potenciálnímu poškození. Po dokončení úkolu budete muset plně restartovat server. Pokud souhlasíte a přejete si pokračovat, zadejte '%s'.",
|
||||
"format_trim_confirm_inhabited": "&eUpozornění: Filtrování chunků podle maximální doby osídlení z %s tiků. Dokončení může trvat déle než obvykle.",
|
||||
"format_pattern": "Vzor změněn na %s.",
|
||||
"format_pause": "Úkol pozastaven pro %s.",
|
||||
"format_pause_no_tasks": "Žádné úkoly k pozastavení.",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "Váš hostitel omezil maximální poloměr před generováním na %s, aby se zabránilo nadměrnému využívání místa na disku. Omezte poloměr nebo kontaktujte svého hostitele, pokud chcete odebrat tento limit.",
|
||||
"format_started_already": "Úkol byl již zahájen pro %s!",
|
||||
"format_world": "Svět změněn na %s.",
|
||||
"format_worldborder_too_large": "&eUpozornění: Váše hranice světa je aktuálně nastavena větší než maximálních %s nakonfigurovaných v server.properties. To je obvykle chyba a může způsobit problémy.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Spravujte vlastní hranice světa",
|
||||
"help_cancel": "&2chunky cancel&r - Zastaví a smaže aktuální nebo uložené úkoly",
|
||||
"help_center": "&2chunky center <x> <z>&r - Nastaví středový blok",
|
||||
@@ -74,23 +77,27 @@
|
||||
"pattern_loop": "opakování",
|
||||
"pattern_spiral": "spirála",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "oblast",
|
||||
"pattern_world": "svět",
|
||||
"shape_circle": "kruh",
|
||||
"shape_diamond": "diamant",
|
||||
"shape_ellipse": "elipsa",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "pětiúhelník",
|
||||
"shape_rectangle": "obdélník",
|
||||
"shape_square": "čtverec",
|
||||
"shape_star": "hvězda",
|
||||
"shape_triangle": "trojúhelník",
|
||||
"task_trim": "Smazáno %s chunků z %s za %s vteřin.",
|
||||
"task_trim_update": "Úkol běží pro %s. Zpracováno: %s regionů (%s%%)",
|
||||
"task_done": "Úkol pro %s byl dokončen. Zpracováno: %s chunků (%s%%), Celkový čas: %s:%s:%s",
|
||||
"task_stopped": "Úkol pro %s byl zastaven.",
|
||||
"task_update": "Úkol běží po dobu %s. Zpracováno: %s chunků (%s%%), ETA: %s:%s:%s, Hodnota: %s cps, Aktuální: %s, %s",
|
||||
"wrap_both": "both",
|
||||
"wrap_default": "default",
|
||||
"wrap_earth": "earth",
|
||||
"wrap_none": "none",
|
||||
"wrap_radial": "radial",
|
||||
"wrap_both": "oboje",
|
||||
"wrap_default": "výchozí",
|
||||
"wrap_earth": "země",
|
||||
"wrap_none": "žádné",
|
||||
"wrap_radial": "kruhové",
|
||||
"wrap_x": "x",
|
||||
"wrap_z": "z"
|
||||
}
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "Mache weiter mit Aufgabe für %s.",
|
||||
"format_continue_no_tasks": "Keine Aufgaben zum Weitermachen.",
|
||||
"format_trim_confirm": "&cWarnung: Chunks in %s ausserhalb von der %s Region zentriert bei %s, %s mit Radius %s wird vollständig gelöscht. Bitte stelle sicher, dass du ein Backup von deinem Server gemacht hast, bevor du weiter machst, um eventuelle Schäden zu verhindern. Du musst deinen Server komplett neustarten nachdem die Aufgabe erledigt ist. Wenn du dies verstehst und weitermachen willst, schreibe '%s'.",
|
||||
"format_trim_confirm_inside": "&cWarnung: Chunks in %s der %s Region zentriert bei %s, %s mit Radius %s wird vollständig gelöscht. Bitte stelle sicher, dass du ein Backup von deinem Server gemacht hast, bevor du weiter machst, um eventuelle Schäden zu verhindern. Du musst deinen Server komplett neustarten nachdem die Aufgabe erledigt ist. Wenn du dies verstehst und weitermachen willst, schreibe '%s'.",
|
||||
"format_trim_confirm_inhabited": "&eHinweis: Filtere Chunks nach einer maximalen bewohnten Zeit von %s ticks. Trimmen kann länger dauern als üblich zum abschliessen.",
|
||||
"format_pattern": "Muster geändert zu %s.",
|
||||
"format_pause": "Aufgabe pausiert für %s.",
|
||||
"format_pause_no_tasks": "Keine aufgaben zum pausieren.",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "Dein Host hat den maximalen Radius fürs generieren auf %s beschränkt, um übermässigen Speicherplatzverbrauch zu vermeiden. Verringere den Radius oder kontaktiere deinen Host wenn du dieses Limit entfernt haben willst.",
|
||||
"format_started_already": "Aufgabe für %s bereits gestartet!",
|
||||
"format_world": "Welt geändert zu %s.",
|
||||
"format_worldborder_too_large": "&eNotice: Your world border is currently set larger than the maximum of %s configured in server.properties. This is normally an error and can cause issues.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Verwalten von benutzerdefinierten Weltgrenzen",
|
||||
"help_cancel": "&2chunky cancel&r - Stoppe und lösche alle momentan gespeicherten Aufgaben",
|
||||
"help_center": "&2chunky center <x> <z>&r - Setze die mittlere Block-Position",
|
||||
@@ -74,15 +77,19 @@
|
||||
"pattern_loop": "Schleife",
|
||||
"pattern_spiral": "Spirale",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "region",
|
||||
"pattern_world": "world",
|
||||
"shape_circle": "Kreis",
|
||||
"shape_diamond": "Diamant",
|
||||
"shape_ellipse": "Ellipse",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "Pentagon",
|
||||
"shape_rectangle": "Rechteck",
|
||||
"shape_square": "Quadrat",
|
||||
"shape_star": "Stern",
|
||||
"shape_triangle": "Dreieck",
|
||||
"task_trim": "Löschte %s Chunks von %s in %s Sekunden.",
|
||||
"task_trim_update": "Task running for %s. Processed: %s regions (%s%%)",
|
||||
"task_done": "Aufgabe für %s beendet. Verarbeitet: %s Chunks (%s%%), Gesamte Zeit: %s:%s:%s",
|
||||
"task_stopped": "Aufgabe für %s gestoppt.",
|
||||
"task_update": "Aufgabe für %s läuft. Verarbeitet: %s Chunks (%s%%), ETA: %s:%s:%s, Rate: %s cps, Aktuell: %s, %s",
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "Task continuing for %s.",
|
||||
"format_continue_no_tasks": "No tasks to continue.",
|
||||
"format_trim_confirm": "&cWarning: Chunks in %s outside of the %s region centered at %s, %s with radius %s will be permanently deleted. Please make sure you have taken a backup of your server before continuing to avoid potential damage. You will be required to restart your server fully after the task has finished. If you understand and wish to proceed, type '%s'.",
|
||||
"format_trim_confirm_inside": "&cWarning: Chunks in %s inside of the %s region centered at %s, %s with radius %s will be permanently deleted. Please make sure you have taken a backup of your server before continuing to avoid potential damage. You will be required to restart your server fully after the task has finished. If you understand and wish to proceed, type '%s'.",
|
||||
"format_trim_confirm_inhabited": "&eNotice: Filtering chunks by a maximum inhabited time of %s ticks. Trim may take longer than usual to complete.",
|
||||
"format_pattern": "Pattern changed to %s.",
|
||||
"format_pause": "Task paused for %s.",
|
||||
"format_pause_no_tasks": "No tasks to pause.",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "Your host has limited the maximum pre-generation radius to %s to avoid excessive disk space usage. Reduce the radius or contact your host if you wish to have this limit removed.",
|
||||
"format_started_already": "Task already started for %s!",
|
||||
"format_world": "World changed to %s.",
|
||||
"format_worldborder_too_large": "&eNotice: Your world border is currently set larger than the maximum of %s configured in server.properties. This is normally an error and can cause issues.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Manage custom world borders",
|
||||
"help_cancel": "&2chunky cancel&r - Stop and delete current or saved tasks",
|
||||
"help_center": "&2chunky center <x> <z>&r - Set the center block location",
|
||||
@@ -74,15 +77,19 @@
|
||||
"pattern_loop": "loop",
|
||||
"pattern_spiral": "spiral",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "region",
|
||||
"pattern_world": "world",
|
||||
"shape_circle": "circle",
|
||||
"shape_diamond": "diamond",
|
||||
"shape_ellipse": "ellipse",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "pentagon",
|
||||
"shape_rectangle": "rectangle",
|
||||
"shape_square": "square",
|
||||
"shape_star": "star",
|
||||
"shape_triangle": "triangle",
|
||||
"task_trim": "Deleted %s chunks from %s in %s seconds.",
|
||||
"task_trim_update": "Task running for %s. Processed: %s regions (%s%%)",
|
||||
"task_done": "Task finished for %s. Processed: %s chunks (%s%%), Total time: %s:%s:%s",
|
||||
"task_stopped": "Task stopped for %s.",
|
||||
"task_update": "Task running for %s. Processed: %s chunks (%s%%), ETA: %s:%s:%s, Rate: %s cps, Current: %s, %s",
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "Tarea continuando para %s.",
|
||||
"format_continue_no_tasks": "No hay tareas que continuar.",
|
||||
"format_trim_confirm": "&cAdvertencia: Los chunks en %s fuera de la región de forma %s, centrada en %s, %s con radio %s serán permanentemente borrados. Por favor asegúrate que has hecho un respaldo de tu servidor antes de continuar para evitar cualquier daño posible. Necesitarás reiniciar tu servidor por completo una vez la tarea termine. Si entiendes esto y deseas continuar, usa '%s'.",
|
||||
"format_trim_confirm_inside": "&cWarning: Chunks in %s inside of the %s region centered at %s, %s with radius %s will be permanently deleted. Please make sure you have taken a backup of your server before continuing to avoid potential damage. You will be required to restart your server fully after the task has finished. If you understand and wish to proceed, type '%s'.",
|
||||
"format_trim_confirm_inhabited": "&eNotice: Filtering chunks by a maximum inhabited time of %s ticks. Trim may take longer than usual to complete.",
|
||||
"format_pattern": "Patrón cambiado a %s.",
|
||||
"format_pause": "Tarea pausada para %s.",
|
||||
"format_pause_no_tasks": "No hay tareas que pausar.",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "Tu proveedor de servicio ha limitado el radio máximo de pre-generación a %s para evitar un uso excesivo de espacio en disco. Reduce el radio o ponte en contacto con tu proveedor necesitas eliminar este límite.",
|
||||
"format_started_already": "¡Tarea ya iniciada para %s!",
|
||||
"format_world": "Mundo cambiado a %s.",
|
||||
"format_worldborder_too_large": "&eNotice: Your world border is currently set larger than the maximum of %s configured in server.properties. This is normally an error and can cause issues.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Administrar bordes personalizados del mundo",
|
||||
"help_cancel": "&2chunky cancel&r - Detiene y elimina las tareas actuales o guardadas",
|
||||
"help_center": "&2chunky center <x> <z>&r - Establece el centro",
|
||||
@@ -74,15 +77,19 @@
|
||||
"pattern_loop": "bucle",
|
||||
"pattern_spiral": "espiral",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "region",
|
||||
"pattern_world": "world",
|
||||
"shape_circle": "círculo",
|
||||
"shape_diamond": "diamante",
|
||||
"shape_ellipse": "elipse",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "pentágono",
|
||||
"shape_rectangle": "rectángulo",
|
||||
"shape_square": "cuadrado",
|
||||
"shape_star": "estrella",
|
||||
"shape_triangle": "triángulo",
|
||||
"task_trim": "Borrados %s chunks de %s en %s segundos.",
|
||||
"task_trim_update": "Task running for %s. Processed: %s regions (%s%%)",
|
||||
"task_done": "Tarea finalizada en %s. Chunks procesados: %s (%s%%), Tiempo total: %s:%s:%s",
|
||||
"task_stopped": "Tarea pausada por %s.",
|
||||
"task_update": "Tarea en %s. Chunks procesados: %s (%s%%), tiempo estimado restante: %s:%s:%s, Promedio de: %s cps, Chunk actual: %s, %s",
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "Task continuing for %s.",
|
||||
"format_continue_no_tasks": "No tasks to continue.",
|
||||
"format_trim_confirm": "&cWarning: Chunks in %s outside of the %s region centered at %s, %s with radius %s will be permanently deleted. Please make sure you have taken a backup of your server before continuing to avoid potential damage. You will be required to restart your server fully after the task has finished. If you understand and wish to proceed, type '%s'.",
|
||||
"format_trim_confirm_inside": "&cWarning: Chunks in %s inside of the %s region centered at %s, %s with radius %s will be permanently deleted. Please make sure you have taken a backup of your server before continuing to avoid potential damage. You will be required to restart your server fully after the task has finished. If you understand and wish to proceed, type '%s'.",
|
||||
"format_trim_confirm_inhabited": "&eNotice: Filtering chunks by a maximum inhabited time of %s ticks. Trim may take longer than usual to complete.",
|
||||
"format_pattern": "Pattern changed to %s.",
|
||||
"format_pause": "Task paused for %s.",
|
||||
"format_pause_no_tasks": "No tasks to pause.",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "Your host has limited the maximum pre-generation radius to %s to avoid excessive disk space usage. Reduce the radius or contact your host if you wish to have this limit removed.",
|
||||
"format_started_already": "Task already started for %s!",
|
||||
"format_world": "World changed to %s.",
|
||||
"format_worldborder_too_large": "&eNotice: Your world border is currently set larger than the maximum of %s configured in server.properties. This is normally an error and can cause issues.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Manage custom world borders",
|
||||
"help_cancel": "&2chunky cancel&r - Stop and delete current or saved tasks",
|
||||
"help_center": "&2chunky center <x> <z>&r - Set the center block location",
|
||||
@@ -74,15 +77,19 @@
|
||||
"pattern_loop": "loop",
|
||||
"pattern_spiral": "spiral",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "region",
|
||||
"pattern_world": "world",
|
||||
"shape_circle": "circle",
|
||||
"shape_diamond": "diamond",
|
||||
"shape_ellipse": "ellipse",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "pentagon",
|
||||
"shape_rectangle": "rectangle",
|
||||
"shape_square": "square",
|
||||
"shape_star": "star",
|
||||
"shape_triangle": "triangle",
|
||||
"task_trim": "Deleted %s chunks from %s in %s seconds.",
|
||||
"task_trim_update": "Task running for %s. Processed: %s regions (%s%%)",
|
||||
"task_done": "Task finished for %s. Processed: %s chunks (%s%%), Total time: %s:%s:%s",
|
||||
"task_stopped": "Task stopped for %s.",
|
||||
"task_update": "Task running for %s. Processed: %s chunks (%s%%), ETA: %s:%s:%s, Rate: %s cps, Current: %s, %s",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"command_no_permission": "&cVous n'avez pas la permission pour cette commande.",
|
||||
"disabled": "désactivé",
|
||||
"enabled": "activé",
|
||||
"error_version": "Ce plugin n'est pas compatible avec les versions de Minecraft ultérieures à la 1.13.",
|
||||
"error_version": "Ce plugin n'est pas compatible avec les versions de Minecraft antérieures à la 1.13.",
|
||||
"error_version_spigot": "Ce plugin n'est pas compatible avec Spigot 1.13 !",
|
||||
"format_border_add": "Ajout de la bordure du monde %s pour %s avec pour centre %s, %s, et de rayon %s.",
|
||||
"format_border_bypass": "Contournement de bordure temporaire %s pour %s.",
|
||||
@@ -16,7 +16,7 @@
|
||||
"format_border_load": "Sélection chargée de la bordure du monde pour le monde %s.",
|
||||
"format_border_no_border": "Aucune bordure de monde n'existe pour %s.",
|
||||
"format_border_remove": "La bordure du monde %s a été supprimée.",
|
||||
"format_border_wrap": "World border wrap changed to %s for %s.",
|
||||
"format_border_wrap": "L'enveloppe de bordure du monde a été changée de %s à %s.",
|
||||
"format_cancel": "Tâche annulée pour le monde: %s.",
|
||||
"format_cancel_all": "Annulation de toutes les tâches.",
|
||||
"format_cancel_confirm": "Les tâches annulées ne peuvent pas être continuées. Si vous êtes sûr(e) de vouloir annuler, tapez '%s'.",
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "La tâche se poursuit pour %s.",
|
||||
"format_continue_no_tasks": "Aucune tâche à continuer.",
|
||||
"format_trim_confirm": "&cAvertissement: Les tronçons dans %s en dehors de la région %s centrée à %s, %s avec le rayon %s seront définitivement supprimés. Veuillez vous assurer que vous avez fait une sauvegarde de votre serveur avant de continuer pour éviter des dommages potentiels. Vous devrez redémarrer votre serveur une fois la tâche terminée. Si vous comprenez et souhaitez continuer, tapez '%s'.",
|
||||
"format_trim_confirm_inside": "&cAvertissement : Les Chunks dans %s à l'intérieur de la région %s, coordonnées %s, %s avec un rayon de %s, seront définitivement supprimés. Veuillez vous assurer que vous avez fait une sauvegarde de votre serveur avant de continuer afin d'éviter tout dommage potentiel. Vous devrez redémarrer votre serveur une fois la tâche terminée. Si vous souhaitez continuer, tapez '%s'.",
|
||||
"format_trim_confirm_inhabited": "&eRemarque: Filtrage des chunks non occupés depuis %s ticks. Le traitement peut être plus long que d'habitude.",
|
||||
"format_pattern": "Le modèle a été changé en %s.",
|
||||
"format_pause": "Tâche interrompue pour %s.",
|
||||
"format_pause_no_tasks": "Aucune tâche à mettre en pause.",
|
||||
@@ -38,7 +40,7 @@
|
||||
"format_selection": "Sélection active",
|
||||
"format_selection_center": "Centre: %s, %s",
|
||||
"format_selection_radius": "Rayon: %s",
|
||||
"format_selection_radii": "Radii: %s, %s",
|
||||
"format_selection_radii": "Rayons: %s,%s",
|
||||
"format_selection_shape": "Forme: %s",
|
||||
"format_selection_world": "Monde: %s",
|
||||
"format_shape": "La forme a été changée en %s.",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "Votre hôte a limité le rayon de pré-génération maximum à %s pour éviter une utilisation excessive de l'espace disque. Réduisez le rayon ou contactez votre hôte si vous souhaitez que cette limite soit supprimée.",
|
||||
"format_started_already": "La tâche a déjà commencé pour %s !",
|
||||
"format_world": "Le monde est passé à %s.",
|
||||
"format_worldborder_too_large": "&eRemarque : La bordure de votre monde est actuellement plus grande que le maximum de %s configuré dans server.properties. Il s'agit normalement d'une erreur qui peut entraîner des problèmes.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Gérer les bordures personnalisées du monde",
|
||||
"help_cancel": "&2chunky cancel&r - Arrêter et supprimer les tâches en cours ou enregistrées",
|
||||
"help_center": "&2chunky center <x> <z>&r - Définir l'emplacement du bloc central",
|
||||
@@ -74,22 +77,26 @@
|
||||
"pattern_loop": "boucle",
|
||||
"pattern_spiral": "spirale",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "région",
|
||||
"pattern_world": "world",
|
||||
"shape_circle": "cercle",
|
||||
"shape_diamond": "diamant",
|
||||
"shape_ellipse": "ellipse",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "pentagone",
|
||||
"shape_rectangle": "rectangle",
|
||||
"shape_square": "carré",
|
||||
"shape_star": "étoile",
|
||||
"shape_triangle": "triangle",
|
||||
"task_trim": "%s tronçons supprimés de %s en %s secondes.",
|
||||
"task_trim_update": "Tâche en cours d'exécution pour %s. Traitée : %s régions (%s%%)",
|
||||
"task_done": "Tâche terminée pour %s. Traité: %s tronçons (%s%%), Durée totale: %s:%s:%s",
|
||||
"task_stopped": "Tâche arrêtée pour %s.",
|
||||
"task_update": "Tâche en cours pour %s. Traité: %s tronçons (%s%%), Prévision: %s:%s:%s, Moyenne: %s cps, Actuellement: %s, %s",
|
||||
"wrap_both": "both",
|
||||
"wrap_default": "default",
|
||||
"wrap_earth": "earth",
|
||||
"wrap_none": "none",
|
||||
"wrap_both": "les deux",
|
||||
"wrap_default": "par défaut",
|
||||
"wrap_earth": "terrestre",
|
||||
"wrap_none": "aucun",
|
||||
"wrap_radial": "radial",
|
||||
"wrap_x": "x",
|
||||
"wrap_z": "z"
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "ממשיך משימה עבור %s.",
|
||||
"format_continue_no_tasks": "אין משימות להמשיך.",
|
||||
"format_trim_confirm": "&cאזהרה: צאנקים בעולם %s מחוץ לאזור ה %s הממורכז ב %s, %s עם רדיוס %s ימחקו לאלתר. אנא וודא כי שמרת גיבוי של השרת לפני שתמשיך כדי למנוע נזק אפשרי. אתה תצטרך להפעיל מחדש את השרת לגמרי לאחר שהמשימה הושלמה. אם אתה מבין ורוצה להמשיך, הקלד '%s'.",
|
||||
"format_trim_confirm_inside": "&cWarning: Chunks in %s inside of the %s region centered at %s, %s with radius %s will be permanently deleted. Please make sure you have taken a backup of your server before continuing to avoid potential damage. You will be required to restart your server fully after the task has finished. If you understand and wish to proceed, type '%s'.",
|
||||
"format_trim_confirm_inhabited": "&eNotice: Filtering chunks by a maximum inhabited time of %s ticks. Trim may take longer than usual to complete.",
|
||||
"format_pattern": "דפוס השתנה ל%s.",
|
||||
"format_pause": "משימה הושהתה עבור %s.",
|
||||
"format_pause_no_tasks": "אין משימות להשהות.",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "מאחסן השרת שלך הגביל את הרדיוס המקסימלי עבור יצירה מראש ל%s כדי להימנע משימוש מופרז בשטח הדיסק. הקטן את הרדיוס או צור קשר עם מאחסן השרת אם ברצונך שתוסר ההגבלה.",
|
||||
"format_started_already": "משימה כבר החלה עבור %s!",
|
||||
"format_world": "עולם השתנה ל%s.",
|
||||
"format_worldborder_too_large": "&eNotice: Your world border is currently set larger than the maximum of %s configured in server.properties. This is normally an error and can cause issues.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - מנהל גבולות עולם מותאמות אישית",
|
||||
"help_cancel": "&2chunky cancel&r - עוצר ומוחק משימות שמורות או נוכחיות",
|
||||
"help_center": "&2chunky center <x> <z>&r - מגדיר את מיקום הבלוק המרכזי",
|
||||
@@ -74,15 +77,19 @@
|
||||
"pattern_loop": "הלוך ושוב",
|
||||
"pattern_spiral": "ספירלית",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "region",
|
||||
"pattern_world": "world",
|
||||
"shape_circle": "מעגל",
|
||||
"shape_diamond": "יהלום",
|
||||
"shape_ellipse": "אליפסה",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "מחומש",
|
||||
"shape_rectangle": "מלבן",
|
||||
"shape_square": "ריבוע",
|
||||
"shape_star": "כוכב",
|
||||
"shape_triangle": "משולש",
|
||||
"task_trim": "נמחק %s צאנקים מ%s ב%s שניות.",
|
||||
"task_trim_update": "Task running for %s. Processed: %s regions (%s%%)",
|
||||
"task_done": "משימה הושלמה עבור %s. עובד: %s צאנקים (%s%%), זמן סך הכל: %s:%s:%s",
|
||||
"task_stopped": "משימה הופסקה עבור %s.",
|
||||
"task_update": "משימה פועלת עבור %s. עובד: %s צאנקים (%s%%), זמן משוער: %s:%s:%s, קצב: %s צאנקים לשנייה, כעת: %s, %s",
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
"format_border_add": "%2$s में %1$s वर्ल्ड सीमा केंद्र %s,%s और त्रिज्या %s के साथ जोड़ी गयी।",
|
||||
"format_border_bypass": "%2$s के लिए अस्थायी सीमा बाईपास %1$s किया गया।",
|
||||
"format_border_bypass_no_target": "%s नाम का कोई प्लेयर नहीं मिला।",
|
||||
"format_border_list": "वर्ल्ड सीमायें",
|
||||
"format_border_list": "दुनिया सीमा",
|
||||
"format_border_list_border": "%s: %s आकार में केंद्र %s,%s और त्रिज्या %s.",
|
||||
"format_border_list_none": "कोई वर्ल्ड सीमायें नहीं।",
|
||||
"format_border_load": "%s के लिए वर्ल्ड सीमा से चयन लोड किया गया।",
|
||||
"format_border_no_border": "%s के लिए कोई वर्ल्ड सीमा मौजूद नहीं है।",
|
||||
"format_border_remove": "%s से वर्ल्ड सीमा हटाई गयी।",
|
||||
"format_border_wrap": "World border wrap changed to %s for %s.",
|
||||
"format_border_wrap": "वर्ल्ड सीमा रैप %s से %s बदल दी गयी।",
|
||||
"format_cancel": "%s के लिए कार्य रद्द किया गया।",
|
||||
"format_cancel_all": "सभी कार्यों को रद्द कर रहा है।",
|
||||
"format_cancel_confirm": "रद्द किये गए कार्य जारी नहीं किये जा सकते। अगर आप वाकई रद्द करना चाहते हैं तो, लिखिए '%s'.",
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "%s के लिए कार्य जारी है।",
|
||||
"format_continue_no_tasks": "जारी करने के लिए कोई कार्य नहीं।",
|
||||
"format_trim_confirm": "&cचेतावनी: %s में केंद्र %3$s, %4$s और त्रिज्या %5$s में %2$s आकार से बाहर के सारे चंक स्थायी रूप से हट जाएंगे। संभावित हानि को टालने के लिए सुनिश्चित करें कि आपने अपने सर्वर का बैकअप ले लिया है। कार्य पूरा होने के बाद आपको अपने सर्वर को रीस्टार्ट करना होगा। अगर आप इसे समझते है और आगे बढ़ना चाहते हैं तो, लिखे '%s'.",
|
||||
"format_trim_confirm_inside": "&cचेतावनी: %s में केंद्र %s, %s और त्रिज्या %s में %s आकार से बाहर के सारे चंक स्थायी रूप से हट जाएंगे। संभावित हानि को टालने के लिए सुनिश्चित करें कि आपने अपने सर्वर का बैकअप ले लिया है। कार्य पूरा होने के बाद आपको अपने सर्वर को रीस्टार्ट करना होगा। अगर आप इसे समझते है और आगे बढ़ना चाहते हैं तो, लिखे '%s'.",
|
||||
"format_trim_confirm_inhabited": "&eNotice: Filtering chunks by a maximum inhabited time of %s ticks. Trim may take longer than usual to complete.",
|
||||
"format_pattern": "पैटर्न %s से बदला गया।",
|
||||
"format_pause": "%s के लिए कार्य रोका गया।",
|
||||
"format_pause_no_tasks": "रोकने के लिए कोई कार्य नहीं।",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "आपके होस्ट ने अत्यधिक डिस्क स्थान उपयोग से बचने के लिए अधिकतम प्री-जेनरेशन त्रिज्या %s कर दी है। यदि आप इस सीमा को हटाना चाहते हैं तो अपने होस्ट से संपर्क करें या सीमा कम रखें।",
|
||||
"format_started_already": "%s के लिए कार्य पहले से ही जारी है!",
|
||||
"format_world": "वर्ल्ड को %s से बदला गया।",
|
||||
"format_worldborder_too_large": "&eNotice: Your world border is currently set larger than the maximum of %s configured in server.properties. This is normally an error and can cause issues.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - कस्टम वर्ल्ड सीमायें प्रबंधित करना",
|
||||
"help_cancel": "&2chunky cancel&r - वर्तमान या सहजें गए कार्य रोकना या हटाना",
|
||||
"help_center": "&2chunky center <x> <z>&r - केंद्र ब्लॉक का स्थान सेट करना",
|
||||
@@ -74,23 +77,27 @@
|
||||
"pattern_loop": "लूप",
|
||||
"pattern_spiral": "कुंडली",
|
||||
"pattern_csv": "csv",
|
||||
"shape_circle": "गोल",
|
||||
"pattern_region": "क्षेत्र",
|
||||
"pattern_world": "world",
|
||||
"shape_circle": "वृत्त",
|
||||
"shape_diamond": "डायमंड",
|
||||
"shape_ellipse": "अंडाकार",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "पंचभुज",
|
||||
"shape_rectangle": "आयात",
|
||||
"shape_square": "वर्ग",
|
||||
"shape_star": "तारा",
|
||||
"shape_triangle": "त्रिभुज",
|
||||
"task_trim": "%2$s वर्ल्ड में %1$s चंक %3$s सेकंड में हटाए गए।",
|
||||
"task_trim_update": "Task running for %s. Processed: %s regions (%s%%)",
|
||||
"task_done": "%s के लिए कार्य पूरा किया गया। प्रसंस्कृत: %s चंक (%s%%), कुल समय: %s:%s:%s",
|
||||
"task_stopped": "%s के लिए कार्य रोका गया।",
|
||||
"task_update": "%s के लिए कार्य जारी है। प्रसंस्कृत: %s चंक (%s%%), ETA: %s:%s:%s, दर: %s cps, वर्तमान: %s,%s",
|
||||
"wrap_both": "both",
|
||||
"wrap_default": "default",
|
||||
"wrap_earth": "earth",
|
||||
"wrap_none": "none",
|
||||
"wrap_radial": "radial",
|
||||
"wrap_both": "दोनों",
|
||||
"wrap_default": "डिफ़ॉल्ट",
|
||||
"wrap_earth": "पृथ्वी",
|
||||
"wrap_none": "कुछ नही",
|
||||
"wrap_radial": "त्रैज्यिक",
|
||||
"wrap_x": "x",
|
||||
"wrap_z": "z"
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
"format_border_load": "Selekcija učitana iz bordera svijeta %s.",
|
||||
"format_border_no_border": "Nema bordera svijeta za %s.",
|
||||
"format_border_remove": "Obrisan border svijeta iz %s.",
|
||||
"format_border_wrap": "World border wrap changed to %s for %s.",
|
||||
"format_border_wrap": "Wrapped border promijenjen u %s za %s.",
|
||||
"format_cancel": "Proces otkazan za %s.",
|
||||
"format_cancel_all": "Otkazivanje svih procesa.",
|
||||
"format_cancel_confirm": "Otkazani procesi ne mogu biti nastavljeni. Ako sigurno želite da otkažete, kucajte '%s'.",
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "Proces nastavljen za %s.",
|
||||
"format_continue_no_tasks": "Nema procesa za nastavak.",
|
||||
"format_trim_confirm": "&cUpozorenje: Čankovi u %s izvan %s regije centrirani u %s, %s sa razdaljinom %s će biti trajno obrisani. Napravite rezervnu kopiju servera prije nego što nastavite da biste izbjegli potencijalnu štetu. Morate restartovati server kada se proces završi. Ako ste razumijeli i želite nastaviti, napišite '%s'.",
|
||||
"format_trim_confirm_inside": "&cWarning: Chunks in %s inside of the %s region centered at %s, %s with radius %s will be permanently deleted. Please make sure you have taken a backup of your server before continuing to avoid potential damage. You will be required to restart your server fully after the task has finished. If you understand and wish to proceed, type '%s'.",
|
||||
"format_trim_confirm_inhabited": "&eNotice: Filtering chunks by a maximum inhabited time of %s ticks. Trim may take longer than usual to complete.",
|
||||
"format_pattern": "Oblik promijenjen u %s.",
|
||||
"format_pause": "Proces za %s pauziran.",
|
||||
"format_pause_no_tasks": "Nema procesa za pauziranje.",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "Vaš host je ograničio maksimalnu razdaljinu pregenerisanja na %s da bi izbjegao veće korištenje memorije. Smanjite razdaljinu ili ih kontaktirajte da biste uklonili ovo ograničenje.",
|
||||
"format_started_already": "Proces je već pokrenut za %s!",
|
||||
"format_world": "Svijet promijenjen u %s.",
|
||||
"format_worldborder_too_large": "&eNotice: Your world border is currently set larger than the maximum of %s configured in server.properties. This is normally an error and can cause issues.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Upravljajte borderima svijetova",
|
||||
"help_cancel": "&2chunky cancel&r - Prekinite i obrišite trenutačne ili sačuvane procese",
|
||||
"help_center": "&2chunky center <x> <z>&r - Postavite centralne koordinate",
|
||||
@@ -74,23 +77,27 @@
|
||||
"pattern_loop": "petlja",
|
||||
"pattern_spiral": "spirala",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "region",
|
||||
"pattern_world": "world",
|
||||
"shape_circle": "krug",
|
||||
"shape_diamond": "romb",
|
||||
"shape_ellipse": "elipsa",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "pentagon",
|
||||
"shape_rectangle": "pravokutnik",
|
||||
"shape_square": "kvadrat",
|
||||
"shape_star": "zvijezda",
|
||||
"shape_triangle": "trokut",
|
||||
"task_trim": "Obrisano %s čankova iz %s u %s sekundi.",
|
||||
"task_trim_update": "Task running for %s. Processed: %s regions (%s%%)",
|
||||
"task_done": "Proces završen za %s. Obrađeno: %s čankova (%s%%), Protjeklo vremena: %s:%s:%s",
|
||||
"task_stopped": "Proces zaustavljen za %s.",
|
||||
"task_update": "U toku je proces za %s. Obrađeno: %s čankova (%s%%), Preostalo: %s:%s:%s, Brzina: %s čps, Trenutačno: %s, %s",
|
||||
"wrap_both": "both",
|
||||
"wrap_default": "default",
|
||||
"wrap_both": "oboje",
|
||||
"wrap_default": "podrazumijevano",
|
||||
"wrap_earth": "earth",
|
||||
"wrap_none": "none",
|
||||
"wrap_radial": "radial",
|
||||
"wrap_none": "ništa",
|
||||
"wrap_radial": "radijalno",
|
||||
"wrap_x": "x",
|
||||
"wrap_z": "z"
|
||||
}
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "Continuazione dell'attività per %s.",
|
||||
"format_continue_no_tasks": "Nessuna attività da continuare.",
|
||||
"format_trim_confirm": "&cAttenzione: I chunk in %s fuori dalla regione %s centrata in %s, %s con raggio %s verranno eliminati definitivamente. Assicurati di aver effettuato un backup del tuo server prima di continuare per evitare potenziali danni. Ti sarà richiesto di riavviare il server completamente dopo che l'attività sarà terminata. Se hai compreso e desideri procedere, digita '%s'.",
|
||||
"format_trim_confirm_inside": "&cWarning: Chunks in %s inside of the %s region centered at %s, %s with radius %s will be permanently deleted. Please make sure you have taken a backup of your server before continuing to avoid potential damage. You will be required to restart your server fully after the task has finished. If you understand and wish to proceed, type '%s'.",
|
||||
"format_trim_confirm_inhabited": "&eNotice: Filtering chunks by a maximum inhabited time of %s ticks. Trim may take longer than usual to complete.",
|
||||
"format_pattern": "Modello cambiato in %s.",
|
||||
"format_pause": "Attività in pausa per %s.",
|
||||
"format_pause_no_tasks": "Nessuna attività da fermare.",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "Il tuo host ha limitato il raggio massimo di pre-generazione a %s per evitare un uso eccessivo dello spazio su disco. Riduci il raggio o contatta il tuo host se desideri che questo limite venga rimosso.",
|
||||
"format_started_already": "Attività già iniziata per %s!",
|
||||
"format_world": "Mondo cambiato in %s.",
|
||||
"format_worldborder_too_large": "&eNotice: Your world border is currently set larger than the maximum of %s configured in server.properties. This is normally an error and can cause issues.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Gestisci i confini personalizzati del mondo",
|
||||
"help_cancel": "&2chunky cancel&r - Ferma ed elimina le attività correnti o salvate",
|
||||
"help_center": "&2chunky center <x> <z>&r - Imposta la posizione del blocco centrale",
|
||||
@@ -74,15 +77,19 @@
|
||||
"pattern_loop": "loop",
|
||||
"pattern_spiral": "spirale",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "region",
|
||||
"pattern_world": "world",
|
||||
"shape_circle": "cerchio",
|
||||
"shape_diamond": "diamante",
|
||||
"shape_ellipse": "ellisse",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "pentagono",
|
||||
"shape_rectangle": "rettangolo",
|
||||
"shape_square": "quadrato",
|
||||
"shape_star": "stella",
|
||||
"shape_triangle": "triangolo",
|
||||
"task_trim": "Eliminati %s chunk da %s in %s secondi.",
|
||||
"task_trim_update": "Task running for %s. Processed: %s regions (%s%%)",
|
||||
"task_done": "Attività terminata per %s. Elaborati: %s chunk (%s%%), Tempo totale: %s:%s:%s",
|
||||
"task_stopped": "Attività interrotta per %s.",
|
||||
"task_update": "Attività in esecuzione per %s. Elaborati: %s chunk (%s%%), ETA: %s:%s:%s, Velocità: %s cps, Attuale: %s, %s",
|
||||
|
||||
@@ -1,96 +1,103 @@
|
||||
{
|
||||
"border_dependency_update": "Chunky needs to be updated in order to use ChunkyBorder!",
|
||||
"border_load_failed": "No saved borders found.",
|
||||
"border_save_failed": "Unable to save borders.",
|
||||
"command_no_permission": "&cYou do not have permission for this command.",
|
||||
"disabled": "disabled",
|
||||
"enabled": "enabled",
|
||||
"error_version": "This plugin is not compatible with Minecraft versions below 1.13.",
|
||||
"error_version_spigot": "This plugin is not compatible with Spigot 1.13!",
|
||||
"format_border_add": "Added %s world border to %s with center %s, %s, and radius %s.",
|
||||
"format_border_bypass": "Temporary border bypass %s for %s.",
|
||||
"format_border_bypass_no_target": "Cannot find a player by the name %s.",
|
||||
"format_border_list": "World Borders",
|
||||
"format_border_list_border": "%s: %s with center %s, %s and radius %s.",
|
||||
"format_border_list_none": "There are no world borders.",
|
||||
"format_border_load": "Selection loaded from world border for %s.",
|
||||
"format_border_no_border": "No world border exists for %s.",
|
||||
"format_border_remove": "Removed world border from %s.",
|
||||
"format_border_wrap": "World border wrap changed to %s for %s.",
|
||||
"format_cancel": "Task cancelled for %s.",
|
||||
"format_cancel_all": "Cancelling all tasks.",
|
||||
"format_cancel_confirm": "Cancelled tasks cannot be continued. If you are sure you want to cancel, type '%s'.",
|
||||
"format_cancel_no_tasks": "No tasks to cancel.",
|
||||
"format_center": "Center changed to %s, %s.",
|
||||
"format_confirm": "Nothing to confirm!",
|
||||
"format_continue": "Task continuing for %s.",
|
||||
"format_continue_no_tasks": "No tasks to continue.",
|
||||
"format_trim_confirm": "&cWarning: Chunks in %s outside of the %s region centered at %s, %s with radius %s will be permanently deleted. Please make sure you have taken a backup of your server before continuing to avoid potential damage. You will be required to restart your server fully after the task has finished. If you understand and wish to proceed, type '%s'.",
|
||||
"format_pattern": "Pattern changed to %s.",
|
||||
"format_pause": "Task paused for %s.",
|
||||
"format_pause_no_tasks": "No tasks to pause.",
|
||||
"format_progress_no_tasks": "No tasks running.",
|
||||
"format_quiet": "Quiet interval set to %s seconds.",
|
||||
"format_radii": "Radius changed for x to %s, and for z to %s.",
|
||||
"format_radius": "Radius changed to %s.",
|
||||
"format_reload": "Successfully reloaded configuration.",
|
||||
"format_reload_tasks_running": "The configuration cannot be reloaded while tasks are running.",
|
||||
"format_selection": "Current selection",
|
||||
"format_selection_center": "Center: %s, %s",
|
||||
"format_selection_radius": "Radius: %s",
|
||||
"format_selection_radii": "Radii: %s, %s",
|
||||
"format_selection_shape": "Shape: %s",
|
||||
"format_selection_world": "World: %s",
|
||||
"format_shape": "Shape changed to %s.",
|
||||
"format_silent": "Silent mode %s.",
|
||||
"format_start": "Task started in %s for the %s region centered at %s, %s with radius %s.",
|
||||
"format_start_confirm": "A task was already started for this world. To continue running it, type '%s'. To start a new task, type '%s'.",
|
||||
"format_start_disk": "The server only has %s disk space remaining, but the estimated disk space required for the task is %s. If you wish to start anyway, type '%s'.",
|
||||
"format_start_limit": "Your host has limited the maximum pre-generation radius to %s to avoid excessive disk space usage. Reduce the radius or contact your host if you wish to have this limit removed.",
|
||||
"format_started_already": "Task already started for %s!",
|
||||
"format_world": "World changed to %s.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Manage custom world borders",
|
||||
"help_cancel": "&2chunky cancel&r - Stop and delete current or saved tasks",
|
||||
"help_center": "&2chunky center <x> <z>&r - Set the center block location",
|
||||
"help_continue": "&2chunky continue&r - Continue current or saved tasks",
|
||||
"help_corners": "&2chunky corners <x1> <z1> <x2> <z2>&r - Set by corners",
|
||||
"help_trim": "&2chunky trim&r - Delete chunks outside selection",
|
||||
"help_menu": "&aChunky Commands&r%s",
|
||||
"help_more": "Type &a%s&r to see more.",
|
||||
"help_pattern": "&2chunky pattern <pattern>&r - Set the generation pattern",
|
||||
"help_pause": "&2chunky pause&r - Pause current tasks and save progress",
|
||||
"help_progress": "&2chunky progress&r - Displays current task progress",
|
||||
"help_quiet": "&2chunky quiet <interval>&r - Set the quiet interval",
|
||||
"help_radius": "&2chunky radius <radius>&r - Set the radius",
|
||||
"help_reload": "&2chunky reload&r - Reload configuration",
|
||||
"help_selection": "&2chunky selection&r - Display the current selection",
|
||||
"help_shape": "&2chunky shape <shape>&r - Set the shape to generate",
|
||||
"help_silent": "&2chunky silent&r - Toggle displaying update messages",
|
||||
"help_spawn": "&2chunky spawn&r - Set the center to the spawn point",
|
||||
"help_start": "&2chunky start&r - Start a new chunk generation task",
|
||||
"help_world": "&2chunky world <world>&r - Set the world target",
|
||||
"help_worldborder": "&2chunky worldborder&r - Use the world border center & radius",
|
||||
"border_dependency_update": "ChunkyBorder를 사용하려면 Chunky를 업데이트해야 합니다!",
|
||||
"border_load_failed": "저장된 테두리를 찾을 수 없습니다.",
|
||||
"border_save_failed": "테두리를 저장할 수 없습니다.",
|
||||
"command_no_permission": "&c이 명령에 대한 권한이 없습니다.",
|
||||
"disabled": "비활성화",
|
||||
"enabled": "활성화",
|
||||
"error_version": "이 플러그인은 1.13 이하의 Minecraft 버전과 호환되지 않습니다.",
|
||||
"error_version_spigot": "이 플러그인은 Spigot 1.13과 호환되지 않습니다!",
|
||||
"format_border_add": "중심이 %s, %s 및 반지름이 %s인 %s 월드 보더를 %s에 추가했습니다.",
|
||||
"format_border_bypass": "%s에 대한 임시 경계 우회 %s입니다.",
|
||||
"format_border_bypass_no_target": "닉네임이 %s인 플레이어를 찾을 수 없습니다.",
|
||||
"format_border_list": "월드 경계선",
|
||||
"format_border_list_border": "%s: 중심이 %s, %s, 반지름이 %s인 %s.",
|
||||
"format_border_list_none": "월드 경계가 없습니다.",
|
||||
"format_border_load": "%s의 월드 경계에서 선택 항목이 로드되었습니다.",
|
||||
"format_border_no_border": "%s에 대한 월드 경계가 없습니다.",
|
||||
"format_border_remove": "%s에서 월드 경계를 제거했습니다.",
|
||||
"format_border_wrap": "%s에 대한 월드 경계 포장이 %s로 변경되었습니다.",
|
||||
"format_cancel": "%s에 대한 작업이 취소되었습니다.",
|
||||
"format_cancel_all": "모든 작업을 취소합니다.",
|
||||
"format_cancel_confirm": "작업을 취소할 수 없습니다. 취소하려면 '%s'를 입력하십시오.",
|
||||
"format_cancel_no_tasks": "취소할 작업이 없습니다.",
|
||||
"format_center": "중심이 %s, %s로 변경되었습니다.",
|
||||
"format_confirm": "확인할 사항이 없습니다!",
|
||||
"format_continue": "%s에 대한 작업이 계속됩니다.",
|
||||
"format_continue_no_tasks": "계속할 작업이 없습니다.",
|
||||
"format_trim_confirm": "&c경고: %s을(를) 중심으로 하는 %s 영역 외부의 %s에 있는 청크, 반경이 %s인 %s는 영구적으로 삭제됩니다. 잠재적 손상을 방지하기 위해 계속하기 전에 서버를 백업했는지 확인하십시오. 작업이 완료된 후 서버를 완전히 다시 시작해야 합니다. 이해하고 계속하려면 '%s'를 입력하십시오.",
|
||||
"format_trim_confirm_inside": "&c경고: 반경이 %s인 %s, %s을(를) 중심으로 하는 %s 영역 내 %s의 청크는 영구적으로 삭제됩니다. 잠재적 손상을 방지하기 위해 계속하기 전에 서버를 백업했는지 확인하십시오. 작업이 완료된 후 서버를 완전히 다시 시작해야 합니다. 이해하고 계속하려면 '%s'를 입력하십시오.",
|
||||
"format_trim_confirm_inhabited": "&e알림: %s 틱의 최대 거주 시간으로 청크를 필터링합니다. 트림을 완료하는 데 평소보다 오래 걸릴 수 있습니다.",
|
||||
"format_pattern": "패턴이 %s(으)로 변경되었습니다.",
|
||||
"format_pause": "작업이 %s 동안 일시 중지되었습니다.",
|
||||
"format_pause_no_tasks": "일시 중지할 작업이 없습니다.",
|
||||
"format_progress_no_tasks": "실행 중인 작업이 없습니다.",
|
||||
"format_quiet": "조용한 간격이 %s초로 설정되었습니다.",
|
||||
"format_radii": "반경이 x에서 %s로, z에서 %s로 변경되었습니다.",
|
||||
"format_radius": "반경이 %s(으)로 변경되었습니다.",
|
||||
"format_reload": "설정을 성공적으로 다시 로드했습니다.",
|
||||
"format_reload_tasks_running": "작업이 실행되는 동안에는 설정을 다시 로드할 수 없습니다.",
|
||||
"format_selection": "현재 선택",
|
||||
"format_selection_center": "중심: %s, %s",
|
||||
"format_selection_radius": "반경: %s",
|
||||
"format_selection_radii": "반지름: %s, %s",
|
||||
"format_selection_shape": "패턴: %s",
|
||||
"format_selection_world": "월드: %s",
|
||||
"format_shape": "패턴이 %s(으)로 변경되었습니다.",
|
||||
"format_silent": " 조용한 모드 %s.",
|
||||
"format_start": "반경이 %s인 %s, %s을(를) 중심으로 하는 %s 영역에 대해 %s에서 작업이 시작되었습니다.",
|
||||
"format_start_confirm": "이 월드에 대한 작업이 이미 시작되었습니다. 계속 실행하려면 '%s'를 입력하십시오. 새 작업을 시작하려면 '%s'를 입력하십시오.",
|
||||
"format_start_disk": "서버에는 %s 디스크 공간이 남아 있지만 작업에 필요한 예상 디스크 공간은 %s입니다. 그래도 시작하려면 '%s'를 입력하십시오.",
|
||||
"format_start_limit": "호스트는 과도한 디스크 공간 사용을 방지하기 위해 최대 사전 생성 반경을 %s로 제한했습니다. 이 제한을 제거하려면 반경을 줄이거나 호스트에게 문의하십시오.",
|
||||
"format_started_already": "%s에 대한 작업이 이미 시작되었습니다!",
|
||||
"format_world": "월드가 %s로 변경되었습니다.",
|
||||
"format_worldborder_too_large": "&eNotice: Your world border is currently set larger than the maximum of %s configured in server.properties. This is normally an error and can cause issues.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - 사용자 지정 월드 경계선 관리",
|
||||
"help_cancel": "&2chunky cancel&r - 현재 또는 저장된 작업 중지 및 삭제",
|
||||
"help_center": "&2chunky center <x> <z>&r - 중앙 블록 위치 설정",
|
||||
"help_continue": "&2chunky continue&r - 현재 또는 저장된 작업 계속하기",
|
||||
"help_corners": "&2chunky corners <x1> <z1> <x2> <z2>&r - 코너로 설정",
|
||||
"help_trim": "&2chunky trim&r - 선택 영역 밖의 청크 삭제",
|
||||
"help_menu": "&aChunky 명령어&r%s",
|
||||
"help_more": "더 보려면 &a%s&r을 입력하세요.",
|
||||
"help_pattern": "&2chunky pattern <pattern>&r - 생성 패턴 설정",
|
||||
"help_pause": "&2chunky pause&r - 현재 작업을 일시 중지하고 진행 상황을 저장합니다.",
|
||||
"help_progress": "&2chunky progress&r - 현재 작업 진행률 표시",
|
||||
"help_quiet": "&2chunky quiet <interval>&r - 조용한 간격 설정",
|
||||
"help_radius": "&2chunky radius <radius>&r - 반지름 설정",
|
||||
"help_reload": "&2chunky reload&r - 설정 리로드",
|
||||
"help_selection": "&2chunky selection&r - 현재 선택 항목 표시",
|
||||
"help_shape": "&2chunky shape <shape>&r - 생성할 모양 설정",
|
||||
"help_silent": "&2chunky silent&r - 업데이트 메시지 표시 토글",
|
||||
"help_spawn": "&2chunky spawn&r - 중심을 스폰 지점으로 설정",
|
||||
"help_start": "&2chunky start&r - 새 청크 생성 작업 시작",
|
||||
"help_world": "&2chunky world <world>&r - 월드 대상 설정",
|
||||
"help_worldborder": "&2chunky worldborder&r - 월드 경계 중심 및 반경 사용",
|
||||
"pattern_concentric": "concentric",
|
||||
"pattern_loop": "loop",
|
||||
"pattern_spiral": "spiral",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "region",
|
||||
"pattern_world": "world",
|
||||
"shape_circle": "circle",
|
||||
"shape_diamond": "diamond",
|
||||
"shape_ellipse": "ellipse",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "pentagon",
|
||||
"shape_rectangle": "rectangle",
|
||||
"shape_square": "square",
|
||||
"shape_star": "star",
|
||||
"shape_triangle": "triangle",
|
||||
"task_trim": "Deleted %s chunks from %s in %s seconds.",
|
||||
"task_done": "Task finished for %s. Processed: %s chunks (%s%%), Total time: %s:%s:%s",
|
||||
"task_stopped": "Task stopped for %s.",
|
||||
"task_update": "Task running for %s. Processed: %s chunks (%s%%), ETA: %s:%s:%s, Rate: %s cps, Current: %s, %s",
|
||||
"task_trim": "%s초 안에 %s에서 %s 청크를 삭제했습니다.",
|
||||
"task_trim_update": "Task running for %s. Processed: %s regions (%s%%)",
|
||||
"task_done": "%s에 대한 작업이 완료되었습니다. 처리됨: %s 청크(%s%%), 총 시간: %s:%s:%s",
|
||||
"task_stopped": "작업이 %s 동안 중지되었습니다.",
|
||||
"task_update": "%s에 대해 작업이 실행 중입니다. 처리됨: %s 청크(%s%%), ETA: %s:%s:%s, 속도: %s cps, 현재: %s, %s",
|
||||
"wrap_both": "both",
|
||||
"wrap_default": "default",
|
||||
"wrap_earth": "earth",
|
||||
"wrap_none": "none",
|
||||
"wrap_radial": "radial",
|
||||
"wrap_radial": "방사형",
|
||||
"wrap_x": "x",
|
||||
"wrap_z": "z"
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
"format_border_load": "Selectie geladen van wereldgrens voor %s.",
|
||||
"format_border_no_border": "Er bestaat geen wereldgrens voor %s.",
|
||||
"format_border_remove": "Verwijderde wereldgrens van %s.",
|
||||
"format_border_wrap": "World border wrap changed to %s for %s.",
|
||||
"format_border_wrap": "De worldborder is nu veranderd naar %s voor %s.",
|
||||
"format_cancel": "Taak geannuleerd voor %s.",
|
||||
"format_cancel_all": "Alle taken annuleren.",
|
||||
"format_cancel_confirm": "Geannuleerde taken kunnen niet worden voortgezet. Als u zeker weet dat u wilt annuleren, typ '%s'.",
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "Taak wordt voortgezet voor %s.",
|
||||
"format_continue_no_tasks": "Geen taken om mee door te gaan.",
|
||||
"format_trim_confirm": "&cWaarschuwing: Chunks in %s buiten de %s regio gecentreerd op %s, %s met radius %s zullen permanent verwijderd worden. Zorg ervoor dat je een back-up van je server hebt genomen voordat je verder gaat om mogelijke schade te voorkomen. Je zult de server volledig moeten herstarten nadat de taak is voltooid. Als je het begrijpt en verder wilt gaan, typ dan '%s'.",
|
||||
"format_trim_confirm_inside": "&cWaarschuwing: Chunks in %s buiten de %s regio gecentreerd op %s, %s met radius %s zullen permanent verwijderd worden. Zorg ervoor dat je een back-up van je server hebt genomen voordat je verder gaat om mogelijke schade te voorkomen. Je zult de server volledig moeten herstarten nadat de taak is voltooid. Als je het begrijpt en verder wilt gaan, typ dan '%s'.",
|
||||
"format_trim_confirm_inhabited": "&eNotitie: Chunks filteren met een maximale tijd van %s ticks. Bijsnijden kan langer duren dan gewoonlijk om te voltooien.",
|
||||
"format_pattern": "Patroon gewijzigd naar %s.",
|
||||
"format_pause": "taak gepauzeerd voor %s.",
|
||||
"format_pause_no_tasks": "Geen taken om te pauzeren.",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "Je host heeft de maximale pre-generatie radius beperkt tot %s om overmatig gebruik van schijfruimte te voorkomen. Verminder de radius of neem contact op met je host als je wilt dat deze limiet wordt verwijderd.",
|
||||
"format_started_already": "Taak is al gestart voor %s!",
|
||||
"format_world": "Wereld veranderd naar %s.",
|
||||
"format_worldborder_too_large": "&eNotice: Je wereldgrens is momenteel groter dan het maximum van %s geconfigureerd in server.properties. Dit is normaal gesproken een fout en kan problemen veroorzaken.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Beheer custom world borders",
|
||||
"help_cancel": "&2chunky cancel&r - Stop en verwijder huidige of opgeslagen taken",
|
||||
"help_center": "&2chunky center <x> <z>&r - Stel de locatie van het midden blok in",
|
||||
@@ -74,23 +77,27 @@
|
||||
"pattern_loop": "loop",
|
||||
"pattern_spiral": "spiraal",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "gebied",
|
||||
"pattern_world": "wereld",
|
||||
"shape_circle": "cirkel",
|
||||
"shape_diamond": "diamant",
|
||||
"shape_ellipse": "elllips",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "regelmatige vijfhoek",
|
||||
"shape_rectangle": "rechthoek",
|
||||
"shape_square": "vierkant",
|
||||
"shape_star": "ster",
|
||||
"shape_triangle": "driehoek",
|
||||
"task_trim": "%s chunks verwijderd van %s in %s seconden.",
|
||||
"task_trim_update": "Taak uitgevoerd voor %s. Verwerkt: %s regio's (%s%%)",
|
||||
"task_done": "Taak voltooid voor %s. Verwerkt: %s chunks (%s%%), Totale tijd: %s:%s:%s",
|
||||
"task_stopped": "Taak geannuleerd voor %s.",
|
||||
"task_update": "Taak wordt uitgevoerd voor %s. Verwerkt: %s chunks (%s%%), ETA: %s:%s:%s, Snelheid: %s cps, Huidig: %s, %s",
|
||||
"wrap_both": "both",
|
||||
"wrap_default": "default",
|
||||
"wrap_earth": "earth",
|
||||
"wrap_none": "none",
|
||||
"wrap_radial": "radial",
|
||||
"wrap_both": "beide",
|
||||
"wrap_default": "standaard",
|
||||
"wrap_earth": "aarde",
|
||||
"wrap_none": "geen",
|
||||
"wrap_radial": "radiaal",
|
||||
"wrap_x": "x",
|
||||
"wrap_z": "z"
|
||||
}
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "Oppgaven fortsetter for %s.",
|
||||
"format_continue_no_tasks": "Ingen oppgaver å fortsette.",
|
||||
"format_trim_confirm": "&cAdvarsel: Chunker i %s utenfor %s regionene satt på %s, %s med radius %s vil bli permanent slettet. Kontroller at du har tatt en sikkerhetskopi av serveren før du fortsetter for å unngå skade. Du må restarte serveren helt etter oppgaven er fullført. Hvis du forstår og ønsker å fortsette, skriv '%s'.",
|
||||
"format_trim_confirm_inside": "&cWarning: Chunks in %s inside of the %s region centered at %s, %s with radius %s will be permanently deleted. Please make sure you have taken a backup of your server before continuing to avoid potential damage. You will be required to restart your server fully after the task has finished. If you understand and wish to proceed, type '%s'.",
|
||||
"format_trim_confirm_inhabited": "&eNotice: Filtering chunks by a maximum inhabited time of %s ticks. Trim may take longer than usual to complete.",
|
||||
"format_pattern": "Mønsteret er endret til %s.",
|
||||
"format_pause": "Oppgaven ble pauset for %s.",
|
||||
"format_pause_no_tasks": "Ingen oppgaver å pause.",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "Verten har begrenset maksimal forhåndsgenerasjons radius til %s for å unngå for mye bruk av diskplassen. Reduser radiusen eller kontakt verten din hvis du ønsker å fjerne denne grensen.",
|
||||
"format_started_already": "Oppgaven har allerede startet for %s!",
|
||||
"format_world": "Verden endret til %s.",
|
||||
"format_worldborder_too_large": "&eNotice: Your world border is currently set larger than the maximum of %s configured in server.properties. This is normally an error and can cause issues.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Manage custom world borders",
|
||||
"help_cancel": "&2chunky cancel&r - Stopp og slett gjeldende eller lagrede oppgaver",
|
||||
"help_center": "&2chunky center <x> <z>&r - Sett blokklokasjon i midten",
|
||||
@@ -74,15 +77,19 @@
|
||||
"pattern_loop": "loop",
|
||||
"pattern_spiral": "spiral",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "region",
|
||||
"pattern_world": "world",
|
||||
"shape_circle": "sirkel",
|
||||
"shape_diamond": "diamant",
|
||||
"shape_ellipse": "ellipse",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "femkant",
|
||||
"shape_rectangle": "rektangel",
|
||||
"shape_square": "kvadrat",
|
||||
"shape_star": "stjerne",
|
||||
"shape_triangle": "triangel",
|
||||
"task_trim": "Slettet %s chunker fra %s på %s sekunder.",
|
||||
"task_trim_update": "Task running for %s. Processed: %s regions (%s%%)",
|
||||
"task_done": "Oppgave fullført for %s. Behandlet: %s chunker (%s%%), tid brukt: %s:%s:%s",
|
||||
"task_stopped": "Oppgaven ble stoppet for %s.",
|
||||
"task_update": "Oppgave kjører for %s. Behandlet: %s chunker (%s%%), ETA: %s:%s:%s, Rate: %s cps, nåværende: %s, %s",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"border_dependency_update": "Chunky wymaga aktualizacji aby korzystać z ChunkyBorder!",
|
||||
"border_dependency_update": "Chunky wymaga aktualizacji, aby korzystać z ChunkyBorder!",
|
||||
"border_load_failed": "Nie znaleziono zapisanych granic.",
|
||||
"border_save_failed": "Nie można zapisać granic.",
|
||||
"command_no_permission": "&cNie masz uprawnień, żeby użyć tej komendy.",
|
||||
@@ -16,7 +16,7 @@
|
||||
"format_border_load": "Selekcja załadowana z granicy świata dla %s.",
|
||||
"format_border_no_border": "Nie ma żadnych granic świata w %s.",
|
||||
"format_border_remove": "Usunięto granicę świata z %s.",
|
||||
"format_border_wrap": "World border wrap changed to %s for %s.",
|
||||
"format_border_wrap": "Zawijanie granicy świata zmieniono na %s dla %s.",
|
||||
"format_cancel": "Zadanie wstrzymane dla %s.",
|
||||
"format_cancel_all": "Anulowanie wszystkich zadań.",
|
||||
"format_cancel_confirm": "Anulowane zadania nie mogą być kontynuowane. Jeśli jesteś pewien, że chcesz anulować wpisz '%s'.",
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "Kontynuowanie zadania dla %s.",
|
||||
"format_continue_no_tasks": "Brak zadań do kontynuowania.",
|
||||
"format_trim_confirm": "&cOstrzeżenie: Chunki w %s poza obszarem %s wyśrodkowanym na %s, %s o promieniu %s zostaną trwale usunięte. Upewnij się, że zrobiłeś kopię zapasową serwera zanim będziesz mógł uniknąć potencjalnej utraty danych. Będziesz musiał zrestartować serwer po zakończeniu zadania. Jeśli rozumiesz i chcesz kontynuować, wpisz '%s'.",
|
||||
"format_trim_confirm_inside": "&cUwaga: Chunki w %s w obszarze %s wycentrowanego na %s, %s z promieniem %s zostaną trwale usunięte. Przed kontynuacją upewnij się, że wykonałeś kopię zapasową serwera aby uniknąć potencjalnej utraty danych. Po ukończeniu zadania konieczne będzie pełne ponowne uruchomienie serwera. Jeżeli rozumiesz i chcesz kontynuować, wpisz %s.",
|
||||
"format_trim_confirm_inhabited": "&eUwaga: Filtrowanie chunków według maksymalnego czasu przebywania wynoszącego %s ticków. Przycinanie może potrwać dłużej niż zazwyczaj.",
|
||||
"format_pattern": "Wzór zmieniony na %s.",
|
||||
"format_pause": "Zadanie wstrzymane dla %s.",
|
||||
"format_pause_no_tasks": "Brak zadań do wstrzymania.",
|
||||
@@ -35,12 +37,12 @@
|
||||
"format_radius": "Promień zmieniony na %s.",
|
||||
"format_reload": "pomyślnie odżwieżono konfigurację.",
|
||||
"format_reload_tasks_running": "konfiguracja nie może być odświeżona podczas trwania zadań.",
|
||||
"format_selection": "Current selection",
|
||||
"format_selection_center": "Center: %s, %s",
|
||||
"format_selection_radius": "Radius: %s",
|
||||
"format_selection_radii": "Radii: %s, %s",
|
||||
"format_selection_shape": "Shape: %s",
|
||||
"format_selection_world": "World: %s",
|
||||
"format_selection": "Bieżące zaznaczenie",
|
||||
"format_selection_center": "Środek: %s, %s",
|
||||
"format_selection_radius": "Promień: %s",
|
||||
"format_selection_radii": "Promienie X i Z: %s, %s",
|
||||
"format_selection_shape": "Kształt: %s",
|
||||
"format_selection_world": "Świat: %s",
|
||||
"format_shape": "Kształt zmieniony na %s.",
|
||||
"format_silent": "Tryb cichy %s.",
|
||||
"format_start": "Zadanie rozpoczęte dla %1$s na %3$s, %4$s z promieniem %5$s.",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "Twój host ograniczył maksymalny promień generowania do %s aby uniknąć dużego zużycia pamięci dyskowej. Zmniejsz promień albo skontaktuj się z twoim hostem jeżeli chcesz aby ten limit został usunięty.",
|
||||
"format_started_already": "Zadanie jest już rozpoczęte dla %s!",
|
||||
"format_world": "Świat zmieniony na %s.",
|
||||
"format_worldborder_too_large": "&eUwaga: Twoja granica świata jest obecnie ustawiona powyżej maksymalnej wartości %s skonfigurowanej w server.properties. Zazwyczaj jest to błąd i może powodować problemy.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Zarządzaj niestandardowymi granicami świata",
|
||||
"help_cancel": "&2chunky cancel&r - Anuluje i usuwa obecne lub zapisane zadania",
|
||||
"help_center": "&2chunky center <x> <z>&r - Ustawia lokalizację środka mapy",
|
||||
@@ -63,7 +66,7 @@
|
||||
"help_quiet": "&2chunky quiet <interval>&r - Ustawia cichy interwał",
|
||||
"help_radius": "&2chunky radius <radius>&r - Ustawia promień (rozmiar świata)",
|
||||
"help_reload": "&2chunky reload&r - Odśwież konfigurację",
|
||||
"help_selection": "&2chunky selection&r - Display the current selection",
|
||||
"help_selection": "&2chunky selection&r - Wyświetl bieżące zaznaczenie",
|
||||
"help_shape": "&2chunky shape <shape>&r - Ustawia kształt do wygenerowania",
|
||||
"help_silent": "&2chunky silent&r - Przełącza wyświetlanie wiadomości o generacji",
|
||||
"help_spawn": "&2chunky spawn&r - Ustawia środek mapy na punkt odrodzenia",
|
||||
@@ -74,23 +77,27 @@
|
||||
"pattern_loop": "pętla",
|
||||
"pattern_spiral": "spirala",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "region",
|
||||
"pattern_world": "world",
|
||||
"shape_circle": "koło",
|
||||
"shape_diamond": "diament",
|
||||
"shape_ellipse": "elipsa",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "pięciokąt",
|
||||
"shape_rectangle": "prostokąt",
|
||||
"shape_square": "kwadrat",
|
||||
"shape_star": "gwiazda",
|
||||
"shape_triangle": "trójkąt",
|
||||
"task_trim": "Usunięto %s chunków z %s w %s sekund.",
|
||||
"task_trim_update": "Task running for %s. Processed: %s regions (%s%%)",
|
||||
"task_done": "Zadanie zakończone dla %s. Przetworzono: %s chunków (%s%%), Łączny czas: %s:%s:%s",
|
||||
"task_stopped": "Zadanie zatrzymane dla %s.",
|
||||
"task_update": "Zadanie w trakcie dla %s. Przetworzono: %s chunków (%s%%), ETA: %s:%s:%s, Tempo: %s cps, Obecnie: %s, %s",
|
||||
"wrap_both": "both",
|
||||
"wrap_default": "default",
|
||||
"wrap_earth": "earth",
|
||||
"wrap_none": "none",
|
||||
"wrap_radial": "radial",
|
||||
"wrap_both": "obie",
|
||||
"wrap_default": "domyślne",
|
||||
"wrap_earth": "ziemia",
|
||||
"wrap_none": "brak",
|
||||
"wrap_radial": "kolisty",
|
||||
"wrap_x": "x",
|
||||
"wrap_z": "z"
|
||||
}
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "Tarefa contínua para %s.",
|
||||
"format_continue_no_tasks": "Nenhuma tarefa a ser continuada.",
|
||||
"format_trim_confirm": "&cWarning: Chunks in %s outside of the %s region centered at %s, %s with radius %s will be permanently deleted. Please make sure you have taken a backup of your server before continuing to avoid potential damage. You will be required to restart your server fully after the task has finished. If you understand and wish to proceed, type '%s'.",
|
||||
"format_trim_confirm_inside": "&cWarning: Chunks in %s inside of the %s region centered at %s, %s with radius %s will be permanently deleted. Please make sure you have taken a backup of your server before continuing to avoid potential damage. You will be required to restart your server fully after the task has finished. If you understand and wish to proceed, type '%s'.",
|
||||
"format_trim_confirm_inhabited": "&eNotice: Filtering chunks by a maximum inhabited time of %s ticks. Trim may take longer than usual to complete.",
|
||||
"format_pattern": "Padrão alterado para %s.",
|
||||
"format_pause": "Tarefa pausada para %s.",
|
||||
"format_pause_no_tasks": "Nenhuma tarefa a ser pausada.",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "Your host has limited the maximum pre-generation radius to %s to avoid excessive disk space usage. Reduce the radius or contact your host if you wish to have this limit removed.",
|
||||
"format_started_already": "Tarefa já iniciada para %s !",
|
||||
"format_world": "O mundo mudou para %s.",
|
||||
"format_worldborder_too_large": "&eNotice: Your world border is currently set larger than the maximum of %s configured in server.properties. This is normally an error and can cause issues.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Manage custom world borders",
|
||||
"help_cancel": "&2chunky cancel&r - Parar e apagar tarefas actuais ou guardadas",
|
||||
"help_center": "&2chunky center <x> <z>&r - Definir a localização do bloco central",
|
||||
@@ -74,15 +77,19 @@
|
||||
"pattern_loop": "loop",
|
||||
"pattern_spiral": "spiral",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "region",
|
||||
"pattern_world": "world",
|
||||
"shape_circle": "circle",
|
||||
"shape_diamond": "diamond",
|
||||
"shape_ellipse": "ellipse",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "pentagon",
|
||||
"shape_rectangle": "rectangle",
|
||||
"shape_square": "square",
|
||||
"shape_star": "star",
|
||||
"shape_triangle": "triangle",
|
||||
"task_trim": "Deleted %s chunks from %s in %s seconds.",
|
||||
"task_trim_update": "Task running for %s. Processed: %s regions (%s%%)",
|
||||
"task_done": "Tarefa terminada para %s. Processado: %s chunks (%s%%), Tempo total: %s:%s:%s",
|
||||
"task_stopped": "Tarefa parada para %s.",
|
||||
"task_update": "Tarefa em execução para %s. Processado: %s chunks (%s%%), ETA: %s:%s:%s, Taxa: %s cps, Actual: %s, %s",
|
||||
|
||||
@@ -1,31 +1,33 @@
|
||||
{
|
||||
"border_dependency_update": "Atualize o Chunky para continuar a usar o ChunkyBorder!",
|
||||
"border_dependency_update": "Atualize o Chunky para continuar usando o ChunkyBorder!",
|
||||
"border_load_failed": "Nenhuma barreira salva encontrada.",
|
||||
"border_save_failed": "Não foi possível salvar as barreiras.",
|
||||
"command_no_permission": "&cVocê não pode rodar esse comando.",
|
||||
"command_no_permission": "&cVocê não pode executar esse comando.",
|
||||
"disabled": "não",
|
||||
"enabled": "sim",
|
||||
"error_version": "O plugin é incompatível com as versões abaixo do Minecraft 1.13.",
|
||||
"error_version_spigot": "O plugin é incompatível com o Spigot 1.13!",
|
||||
"format_border_add": "Uma barreira de mundo com a forma %s foi adicionada no %s com o centro %s, %s, e raio %s.",
|
||||
"format_border_bypass": "Ignorar barreiras temporariamente: %s (para %s).",
|
||||
"format_border_bypass_no_target": "Nenhum jogador encontrado com o nome %s.",
|
||||
"format_border_bypass_no_target": "Nenhum jogador encontrado com o nome \"%s\".",
|
||||
"format_border_list": "Barreiras do mundo",
|
||||
"format_border_list_border": "%s: %s com o centro %s, %s e raio %s.",
|
||||
"format_border_list_none": "Nenhuma barreira do mundo encontrada.",
|
||||
"format_border_load": "Seleção carregada da barreira do mundo no %s.",
|
||||
"format_border_no_border": "Nenhuma barreira do mundo encontrada no %s.",
|
||||
"format_border_remove": "Barreira do mundo removida do %s.",
|
||||
"format_border_wrap": "World border wrap changed to %s for %s.",
|
||||
"format_border_wrap": "Entorno da barreira do mundo alterado para %s no %s.",
|
||||
"format_cancel": "Tarefa cancelada no mundo %s.",
|
||||
"format_cancel_all": "Cancelando todas as tarefas.",
|
||||
"format_cancel_confirm": "Tarefas canceladas não podem ser retomadas. Caso queira cancelar, digite \"%s\".",
|
||||
"format_cancel_no_tasks": "Nenhuma tarefa para cancelar.",
|
||||
"format_center": "Centro alterado para %s, %s.",
|
||||
"format_confirm": "Nada para confirmar!",
|
||||
"format_confirm": "Nada a confirmar!",
|
||||
"format_continue": "Tarefa retomada no mundo %s.",
|
||||
"format_continue_no_tasks": "Nenhuma tarefa para continuar.",
|
||||
"format_trim_confirm": "&Aviso: Chunks no %s fora da região em forma de %s centralizados em %s, %s com raio %s serão excluídos para sempre. Faça um backup do servidor antes de continuar para evitar possíveis problemas. Reinicie o servidor completamente após a conclusão da tarefa. Se você entendeu e deseja continuar, digite \"%s\".",
|
||||
"format_trim_confirm": "&Aviso: Chunks no %s fora da região em forma de %s centralizados em %s, %s com raio %s serão excluídos para sempre. Faça um backup do servidor antes de continuar para evitar problemas. Reinicie o servidor completamente após a conclusão da tarefa. Se você entendeu e deseja continuar, digite \"%s\".",
|
||||
"format_trim_confirm_inside": "&cAtenção: os chunks (%s) dentro da região centralizada em %s, %s com raio %s serão apagados para sempre. Veja se há um backup do servidor antes de continuar para evitar danos. O servidor deverá ser reiniciado para concluir a tarefa. Se você entendeu e deseja continuar, digite \"%s\".",
|
||||
"format_trim_confirm_inhabited": "&eAviso: filtrando chunks com um tempo máximo de %s ciclos. O corte pode demorar mais um pouco para concluir.",
|
||||
"format_pattern": "Padrão alterado para %s.",
|
||||
"format_pause": "Tarefa pausada no mundo %s.",
|
||||
"format_pause_no_tasks": "Nenhuma tarefa para pausar.",
|
||||
@@ -35,12 +37,12 @@
|
||||
"format_radius": "Raio alterado para %s.",
|
||||
"format_reload": "As definições foram recarregadas.",
|
||||
"format_reload_tasks_running": "A definição não pode ser recarregada com tarefas em execução.",
|
||||
"format_selection": "Current selection",
|
||||
"format_selection_center": "Center: %s, %s",
|
||||
"format_selection_radius": "Radius: %s",
|
||||
"format_selection_radii": "Radii: %s, %s",
|
||||
"format_selection_shape": "Shape: %s",
|
||||
"format_selection_world": "World: %s",
|
||||
"format_selection": "Seleção atual",
|
||||
"format_selection_center": "Centro: %s, %s",
|
||||
"format_selection_radius": "Raio: %s",
|
||||
"format_selection_radii": "Raios: %s, %s",
|
||||
"format_selection_shape": "Forma: %s",
|
||||
"format_selection_world": "Mundo: %s",
|
||||
"format_shape": "Forma alterada para %s.",
|
||||
"format_silent": "Modo silencioso: %s.",
|
||||
"format_start": "Tarefa iniciada no mundo %s para a região de forma %s em %s, %s com raio %s.",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "Sua hospedagem limitou o raio máximo de pré-geração para %s a fim de evitar o uso excessivo de espaço em disco. Reduza o raio ou entre em contato com o serviço para remover o limite.",
|
||||
"format_started_already": "Tarefa já iniciada no mundo %s!",
|
||||
"format_world": "Mundo alterado para %s.",
|
||||
"format_worldborder_too_large": "&eNotice: Your world border is currently set larger than the maximum of %s configured in server.properties. This is normally an error and can cause issues.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Gerenciar barreiras de mundo personalizadas",
|
||||
"help_cancel": "&2chunky cancel&r - Parar e excluir tarefas atuais ou salvas",
|
||||
"help_center": "&2chunky center <x> <z>&r - Definir o local do bloco central",
|
||||
@@ -63,7 +66,7 @@
|
||||
"help_quiet": "&2chunky quiet <interval>&r - Definir intervalo de avisos",
|
||||
"help_radius": "&2chunky radius <radius>&r - Definir raio",
|
||||
"help_reload": "&2chunky reload&r - Recarregar definições",
|
||||
"help_selection": "&2chunky selection&r - Display the current selection",
|
||||
"help_selection": "&2chunky selection&r - Exibe a seleção atual",
|
||||
"help_shape": "&2chunky shape <shape>&r - Definir forma para gerar",
|
||||
"help_silent": "&2chunky silent&r - Alternar exibição dos avisos de atualização",
|
||||
"help_spawn": "&2chunky spawn&r - Definir o centro para o ponto de nascimento (spawn)",
|
||||
@@ -74,22 +77,26 @@
|
||||
"pattern_loop": "loop",
|
||||
"pattern_spiral": "espiral",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "região",
|
||||
"pattern_world": "world",
|
||||
"shape_circle": "círculo",
|
||||
"shape_diamond": "diamante",
|
||||
"shape_ellipse": "elipse",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "pentágono",
|
||||
"shape_rectangle": "retângulo",
|
||||
"shape_square": "quadrado",
|
||||
"shape_star": "estrela",
|
||||
"shape_triangle": "triângulo",
|
||||
"task_trim": "%s chunks excluídos no mundo %s em %s segundos.",
|
||||
"task_trim_update": "Task running for %s. Processed: %s regions (%s%%)",
|
||||
"task_done": "Tarefa concluída no mundo %s. Chunks processados: %s (%s%%), tempo total: %s:%s:%s",
|
||||
"task_stopped": "Tarefa interrompida no mundo %s.",
|
||||
"task_update": "Tarefa em execução no mundo %s. Chunks processados: %s (%s%%), tempo restante: %s:%s:%s, taxa: %s CPS, atual: %s, %s",
|
||||
"wrap_both": "both",
|
||||
"wrap_default": "default",
|
||||
"wrap_earth": "earth",
|
||||
"wrap_none": "none",
|
||||
"wrap_both": "ambos",
|
||||
"wrap_default": "padrão",
|
||||
"wrap_earth": "terra",
|
||||
"wrap_none": "não",
|
||||
"wrap_radial": "radial",
|
||||
"wrap_x": "x",
|
||||
"wrap_z": "z"
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
{
|
||||
"border_dependency_update": "Для использования ChunkyBorder вы должны обновить Chunky!",
|
||||
"border_load_failed": "Сохранённые границы не найдены.",
|
||||
"border_save_failed": "Невозможно сохранить границы.",
|
||||
"border_dependency_update": "Обновите Chunky, чтобы использовать ChunkyBorder!",
|
||||
"border_load_failed": "Сохранённых границ не найдено.",
|
||||
"border_save_failed": "Не удалось сохранить границы.",
|
||||
"command_no_permission": "&cУ вас недостаточно прав для использования этой команды.",
|
||||
"disabled": "выключен",
|
||||
"enabled": "включен",
|
||||
"disabled": "отключено",
|
||||
"enabled": "включено",
|
||||
"error_version": "Этот плагин несовместим с версиями Minecraft ниже 1.13.",
|
||||
"error_version_spigot": "Этот плагин несовместим со Spigot 1.13!",
|
||||
"format_border_add": "Граница формы %s была добавлена в мире %s с центром на %s, %s, и радиусом %s.",
|
||||
"format_border_bypass": "Значение временного разрешения для обхода: %s для игрока %s.",
|
||||
"format_border_bypass_no_target": "Невозможно найти игрока с именем %s.",
|
||||
"format_border_add": "Граница формы %s была установлена в мире %s с центром на %s, %s, и радиусом %s.",
|
||||
"format_border_bypass": "Временное разрешение на обход границ: %s для игрока %s.",
|
||||
"format_border_bypass_no_target": "Не удалось найти игрока с именем %s.",
|
||||
"format_border_list": "Границы мира",
|
||||
"format_border_list_border": "Мир %s: %s с центром %s, %s и радиусом %s.",
|
||||
"format_border_list_border": "Мир %s: %s с центром в %s, %s и радиусом %s.",
|
||||
"format_border_list_none": "Ни у одного мира не установлены границы.",
|
||||
"format_border_load": "Выделенное пространство было загружено для мира %s.",
|
||||
"format_border_no_border": "Для мира %s не существует границ мира.",
|
||||
"format_border_no_border": "Для мира %s не установлено границ мира.",
|
||||
"format_border_remove": "Граница мира %s была удалена.",
|
||||
"format_border_wrap": "Тип пограничного перемещения сменен на '%s' для мира %s.",
|
||||
"format_cancel": "Задача для %s отменена.",
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "Задача для %s продолжена.",
|
||||
"format_continue_no_tasks": "Нет задач для продолжения.",
|
||||
"format_trim_confirm": "&cВнимание: Чанки в %s, находящиеся снаружи региона %s с центром в %s, %s и радиусом %s, будут полностью удалены. Во избежание возможной потери данных, пожалуйста, убедитесь в том, что у вас есть резервная копия сервера. После завершения задачи вам будет необходимо полностью перезагрузить сервер. Если вы готовы продолжить, введите '%s'.",
|
||||
"format_trim_confirm_inside": "&cВнимание: Чанки в %s, находящиеся внутри региона %s с центром в %s, %s и радиусом %s, будут полностью удалены. Во избежание возможной потери данных, пожалуйста, убедитесь в том, что у вас есть резервная копия сервера. После завершения задачи вам будет необходимо полностью перезагрузить сервер. Если вы готовы продолжить, введите '%s'.",
|
||||
"format_trim_confirm_inhabited": "&eВнимание: Началась фильтрация чанков, в которых находились менее %s тиков. Обрезка может занять больше времени, чем обычно.",
|
||||
"format_pattern": "Паттерн изменен на %s.",
|
||||
"format_pause": "Задача для %s приостановлена.",
|
||||
"format_pause_no_tasks": "Нет задач для приостановки.",
|
||||
@@ -42,47 +44,52 @@
|
||||
"format_selection_shape": "Форма: %s",
|
||||
"format_selection_world": "Мир: %s",
|
||||
"format_shape": "Форма изменена на %s.",
|
||||
"format_silent": "Тихий режим был %s.",
|
||||
"format_silent": "Тихий режим %s.",
|
||||
"format_start": "Задача в %s запущена для региона %s с центром в %s, %s и радиусом %s.",
|
||||
"format_start_confirm": "Задача для этого мира уже была запущена. Чтобы продолжить ее, напишите '%s'. Чтобы начать новую задачу, напишите '%s'.",
|
||||
"format_start_disk": "На сервере осталось %s дискового пространства, но для выполнения задачи требуется приблизительно %s. Если вы всё ещё хотите продолжить, введите '%s'.",
|
||||
"format_start_limit": "Ваш хост ограничил максимальный радиус предварительной генерации до %s во избежание переполнения дискового пространства. Уменьшите радиус, или свяжитесь с хостом для снятия ограничений.",
|
||||
"format_started_already": "Задача для %s уже запущена!",
|
||||
"format_world": "Мир изменен на %s.",
|
||||
"format_worldborder_too_large": "&eПредупреждение: Граница мира установлена дальше, чем указанное значение %s в server.properties. Как правило, это ошибка, которая может вызвать проблемы.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Управление пользовательскими границами мира",
|
||||
"help_cancel": "&2chunky cancel&r - Остановить и удалить текущие или сохраненные задачи",
|
||||
"help_center": "&2chunky center <x> <z>&r - Установить координаты центра",
|
||||
"help_continue": "&2chunky continue&r - Продолжить текущие или сохраненные задачи",
|
||||
"help_corners": "&2chunky corners <x1> <z1> <x2> <z2>&r - Установить координаты углов",
|
||||
"help_trim": "&2chunky trim&r - Удалить чанки за границами",
|
||||
"help_menu": "&aChunky Commands&r%s",
|
||||
"help_menu": "&aКоманды Chunky&r%s",
|
||||
"help_more": "Используйте &a%s&r, чтобы узнать больше.",
|
||||
"help_pattern": "&2chunky pattern <pattern>&r - Установить паттерн генерации",
|
||||
"help_pattern": "&2chunky pattern <паттерн>&r - Установить паттерн генерации",
|
||||
"help_pause": "&2chunky pause&r - Приостановить текущие задачи и сохранить прогресс",
|
||||
"help_progress": "&2chunky progress&r - Показать текущий прогресс задачи",
|
||||
"help_quiet": "&2chunky quiet <interval>&r - Установить интервал тихой работы",
|
||||
"help_radius": "&2chunky radius <radius>&r - Установить радиус",
|
||||
"help_quiet": "&2chunky quiet <интервал>&r - Установить интервал тихой работы",
|
||||
"help_radius": "&2chunky radius <радиус>&r - Установить радиус",
|
||||
"help_reload": "&2chunky reload&r - Перезагрузить конфигурацию",
|
||||
"help_selection": "&2chunky selection&r - Показать текущее выделение",
|
||||
"help_shape": "&2chunky shape <shape>&r - Установить форму генерации",
|
||||
"help_shape": "&2chunky shape <форма>&r - Установить форму генерации",
|
||||
"help_silent": "&2chunky silent&r - Переключить вывод сообщений о генерации чанков",
|
||||
"help_spawn": "&2chunky spawn&r - Установить центр на точке возрождения игроков",
|
||||
"help_start": "&2chunky start&r - Начать новую задачу генерации чанков",
|
||||
"help_world": "&2chunky world <world>&r - Выбрать мир для генерации чанков",
|
||||
"help_world": "&2chunky world <мир>&r - Выбрать мир для генерации чанков",
|
||||
"help_worldborder": "&2chunky worldborder&r - Установить центр и радиус, исходя из границы мира",
|
||||
"pattern_concentric": "концентрично",
|
||||
"pattern_loop": "цикл",
|
||||
"pattern_spiral": "спираль",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "область",
|
||||
"pattern_world": "мир",
|
||||
"shape_circle": "круг",
|
||||
"shape_diamond": "ромб",
|
||||
"shape_ellipse": "эллипс",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "пятиугольник",
|
||||
"shape_rectangle": "прямоугольник",
|
||||
"shape_square": "квадрат",
|
||||
"shape_star": "звезда",
|
||||
"shape_triangle": "треугольник",
|
||||
"task_trim": "Удалено %s чанков из %s за %s секунд.",
|
||||
"task_trim_update": "Задача для %s выполняется. Обработано %s регионов (%s%%)",
|
||||
"task_done": "Задача для %s выполнена. Обработано: %s чанков (%s%%), Заняло времени: %s:%s:%s",
|
||||
"task_stopped": "Задача для %s остановлена.",
|
||||
"task_update": "Задача для %s выполняется. Обработано: %s чанков (%s%%), ETA: %s:%s:%s, Скорость: %s Чанков в секунду, Текущий чанк: %s, %s",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"format_border_load": "Selekcija učitana iz bordera sveta %s.",
|
||||
"format_border_no_border": "Nema bordera sveta za %s.",
|
||||
"format_border_remove": "Obrisan border sveta iz %s.",
|
||||
"format_border_wrap": "World border wrap changed to %s for %s.",
|
||||
"format_border_wrap": "Wrapped border promenjen u %s za %s.",
|
||||
"format_cancel": "Proces otkazan za %s.",
|
||||
"format_cancel_all": "Otkazivanje svih procesa.",
|
||||
"format_cancel_confirm": "Otkazani procesi ne mogu biti nastavljeni. Ako sigurno želite da otkažete, kucajte '%s'.",
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "Proces nastavljen za %s.",
|
||||
"format_continue_no_tasks": "Nema procesa za nastavak.",
|
||||
"format_trim_confirm": "&cUpozorenje: Čankovi u %s izvan %s regije centrirani u %s, %s sa razdaljinom %s će biti trajno obrisani. Napravite rezervnu kopiju servera pre nego što nastavite da biste izbegli potencijalnu štetu. Morate restartovati server kada se proces završi. Ako ste razumeli i želite nastaviti, napišite '%s'.",
|
||||
"format_trim_confirm_inside": "&cWarning: Chunks in %s inside of the %s region centered at %s, %s with radius %s will be permanently deleted. Please make sure you have taken a backup of your server before continuing to avoid potential damage. You will be required to restart your server fully after the task has finished. If you understand and wish to proceed, type '%s'.",
|
||||
"format_trim_confirm_inhabited": "&eNotice: Filtering chunks by a maximum inhabited time of %s ticks. Trim may take longer than usual to complete.",
|
||||
"format_pattern": "Oblik promenjen u %s.",
|
||||
"format_pause": "Proces za %s pauziran.",
|
||||
"format_pause_no_tasks": "Nema procesa za pauziranje.",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "Vaš host je ograničio maksimalnu razdaljinu pregenerisanja na %s da bi izbegao veće korišćenje memorije. Smanjite razdaljinu ili ih kontaktirajte da biste uklonili ovo ograničenje.",
|
||||
"format_started_already": "Proces je već pokrenut za %s!",
|
||||
"format_world": "Svet promenjen u %s.",
|
||||
"format_worldborder_too_large": "&eNotice: Your world border is currently set larger than the maximum of %s configured in server.properties. This is normally an error and can cause issues.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Upravljajte borderima svetova",
|
||||
"help_cancel": "&2chunky cancel&r - Prekinite i obrišite trenutne ili sačuvane procese",
|
||||
"help_center": "&2chunky center <x> <z>&r - Postavite centralne koordinate",
|
||||
@@ -74,23 +77,27 @@
|
||||
"pattern_loop": "petlja",
|
||||
"pattern_spiral": "spirala",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "region",
|
||||
"pattern_world": "world",
|
||||
"shape_circle": "krug",
|
||||
"shape_diamond": "romb",
|
||||
"shape_ellipse": "elipsa",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "pentagon",
|
||||
"shape_rectangle": "pravougaonik",
|
||||
"shape_square": "kvadrat",
|
||||
"shape_star": "zvezda",
|
||||
"shape_triangle": "trougao",
|
||||
"task_trim": "Obrisano %s čankova iz %s u %s sekundi.",
|
||||
"task_trim_update": "Task running for %s. Processed: %s regions (%s%%)",
|
||||
"task_done": "Proces završen za %s. Obrađeno: %s čankova (%s%%), Proteklo vremena: %s:%s:%s",
|
||||
"task_stopped": "Proces zaustavljen za %s.",
|
||||
"task_update": "U toku je proces za %s. Obrađeno: %s čankova (%s%%), Preostalo: %s:%s:%s, Brzina: %s čps, Trenutno: %s, %s",
|
||||
"wrap_both": "both",
|
||||
"wrap_default": "default",
|
||||
"wrap_both": "oba",
|
||||
"wrap_default": "podrazumevano",
|
||||
"wrap_earth": "earth",
|
||||
"wrap_none": "none",
|
||||
"wrap_radial": "radial",
|
||||
"wrap_none": "ništa",
|
||||
"wrap_radial": "radijalno",
|
||||
"wrap_x": "x",
|
||||
"wrap_z": "z"
|
||||
}
|
||||
@@ -1,91 +1,98 @@
|
||||
{
|
||||
"border_dependency_update": "Chunky needs to be updated in order to use ChunkyBorder!",
|
||||
"border_load_failed": "No saved borders found.",
|
||||
"border_save_failed": "Unable to save borders.",
|
||||
"border_dependency_update": "ChunkyBorder'ın kullanılabilmesi için Chunk'nin güncellenmesi gerekiyor!",
|
||||
"border_load_failed": "Kaydedilmiş bir sınır bulunamadı.",
|
||||
"border_save_failed": "Sınırlar kaydedilemiyor.",
|
||||
"command_no_permission": "&cBu komutu kullanmak için yetkiniz yok.",
|
||||
"disabled": "de-aktif",
|
||||
"enabled": "aktif",
|
||||
"error_version": "Bu eklenti, 1.13'ün altındaki Minecraft sürümleriyle uyumlu değildir.",
|
||||
"error_version_spigot": "Bu eklenti Spigot 1.13 ile uyumlu değil!",
|
||||
"format_border_add": "Added %s world border to %s with center %s, %s, and radius %s.",
|
||||
"format_border_bypass": "Temporary border bypass %s for %s.",
|
||||
"format_border_bypass_no_target": "Cannot find a player by the name %s.",
|
||||
"format_border_list": "World Borders",
|
||||
"format_border_list_border": "%s: %s with center %s, %s and radius %s.",
|
||||
"format_border_list_none": "There are no world borders.",
|
||||
"format_border_load": "Selection loaded from world border for %s.",
|
||||
"format_border_no_border": "No world border exists for %s.",
|
||||
"format_border_remove": "Removed world border from %s.",
|
||||
"format_border_add": "%s dünya sınırı, %s dünyasına %s, %s merkezi ve %s yarıçap ile eklendi.",
|
||||
"format_border_bypass": "Geçici sınır geçiş izni %s ve %s adlı oyunucya verildi.",
|
||||
"format_border_bypass_no_target": "%s adıyla bir oyuncu bulunamadı.",
|
||||
"format_border_list": "Dünya Sınırları",
|
||||
"format_border_list_border": "%s: Şekil: %s, Merkez: %s, %s, Yarıçap: %s.",
|
||||
"format_border_list_none": "Hiçbir dünya sınırı bulunamadı.",
|
||||
"format_border_load": "Seçim %s dünyasının sınırlarından yüklendi.",
|
||||
"format_border_no_border": "%s üzerinde hiç bir dünya sınırı yok.",
|
||||
"format_border_remove": "%s adlı dünyadan sınır kaldırıldı.",
|
||||
"format_border_wrap": "World border wrap changed to %s for %s.",
|
||||
"format_cancel": "Fonksiyon %s için durduruldu.",
|
||||
"format_cancel": "Fonksiyon %s için iptal edildi.",
|
||||
"format_cancel_all": "Tüm fonksiyonlar iptal ediliyor.",
|
||||
"format_cancel_confirm": "İptal edilen fonksiyonlar devam ettirilemez. İptal etmek istediğinden eminsen '%s' yaz.",
|
||||
"format_cancel_no_tasks": "İptal edilecek bir fonksiyon bulunmuyor.",
|
||||
"format_center": "Merkez %s, %s olarak değiştirildi.",
|
||||
"format_confirm": "Onaylanacak bir fonksiyon yok!",
|
||||
"format_continue": "için devam eden fonksiyon.",
|
||||
"format_continue": "%s fonksiyonu devam ettiriliyor.",
|
||||
"format_continue_no_tasks": "Devam edilecek bir fonksiyon bulunmuyor.",
|
||||
"format_trim_confirm": "&cWarning: Chunks in %s outside of the %s region centered at %s, %s with radius %s will be permanently deleted. Please make sure you have taken a backup of your server before continuing to avoid potential damage. You will be required to restart your server fully after the task has finished. If you understand and wish to proceed, type '%s'.",
|
||||
"format_pattern": "Pattern changed to %s.",
|
||||
"format_pause": "fonksiyon %s için durduruldu.",
|
||||
"format_pause_no_tasks": "No tasks to pause.",
|
||||
"format_progress_no_tasks": "No tasks running.",
|
||||
"format_quiet": "Sessiz aralık %s saniye olarak yarlandı.",
|
||||
"format_radii": "Radius changed for x to %s, and for z to %s.",
|
||||
"format_trim_confirm": "&cUyarı: %1$s dünyasındaki %3$s, %4$s merkezli, %5$s yarıçaplı, %2$s alanın dışarısındaki herşey &4&lKALICI &r&colarak silinecektir. Potansiyel hasarı engellemek için lütfen yedek aldığınızdan emin olun. İşlem sona erdiğinde sunucunuzu tamamen yeniden başlatmanız gerekecek. Eğer riskleri anladıysanız ve devam etmek istiyorsanız, '%6$s' yazın.",
|
||||
"format_trim_confirm_inside": "&cUyarı: %1$s dünyasındaki %3$s, %4$s merkezli, %5$s yarıçaplı, %2$s alan &4&lKALICI &r&colarak silinecektir. Potansiyel hasarı engellemek için lütfen yedek aldığınızdan emin olun. İşlem sona erdiğinde sunucunuzu tamamen yeniden başlatmanız gerekecek. Eğer riskleri anladıysanız ve devam etmek istiyorsanız, '%6$s' yazın.",
|
||||
"format_trim_confirm_inhabited": "&eNotice: Filtering chunks by a maximum inhabited time of %s ticks. Trim may take longer than usual to complete.",
|
||||
"format_pattern": "Yol %s olarak değiştirildi.",
|
||||
"format_pause": "Fonksiyon %s için durduruldu.",
|
||||
"format_pause_no_tasks": "Durdurulacak bir fonksiyon bulunmuyor.",
|
||||
"format_progress_no_tasks": "Aktif bir fonksiyon yok.",
|
||||
"format_quiet": "Sessizlik aralığı %s saniye olarak ayarlandı.",
|
||||
"format_radii": "Yarıçap x için %s olarak, z için %s olarak değiştirildi.",
|
||||
"format_radius": "Yarıçap %s olarak ayarlandı.",
|
||||
"format_reload": "Successfully reloaded configuration.",
|
||||
"format_reload_tasks_running": "The configuration cannot be reloaded while tasks are running.",
|
||||
"format_selection": "Current selection",
|
||||
"format_selection_center": "Center: %s, %s",
|
||||
"format_selection_radius": "Radius: %s",
|
||||
"format_selection_radii": "Radii: %s, %s",
|
||||
"format_selection_shape": "Shape: %s",
|
||||
"format_selection_world": "World: %s",
|
||||
"format_shape": "Shape changed to %s.",
|
||||
"format_reload": "Konfigürasyon başarıyla yeniden yüklendi.",
|
||||
"format_reload_tasks_running": "Fonksiyonlar çalışmaya devam ederken konfigürasyon yeniden yüklenemez.",
|
||||
"format_selection": "Mevcut seçim",
|
||||
"format_selection_center": "Merkez: %s, %s",
|
||||
"format_selection_radius": "Yarıçap: %s",
|
||||
"format_selection_radii": "Yarıçaplar, X: %s, Z: %s",
|
||||
"format_selection_shape": "Şekil: %s",
|
||||
"format_selection_world": "Dünya: %s",
|
||||
"format_shape": "Şekil %s olarak değşitirildi.",
|
||||
"format_silent": "Sessiz mod %s.",
|
||||
"format_start": "Fonksiyon %1$s için %3$s, %4$s ve yarıçap %5$s olarak ayarlandı.",
|
||||
"format_start_confirm": "A task was already started for this world. To continue running it, type '%s'. To start a new task, type '%s'.",
|
||||
"format_start_disk": "The server only has %s disk space remaining, but the estimated disk space required for the task is %s. If you wish to start anyway, type '%s'.",
|
||||
"format_start_limit": "Your host has limited the maximum pre-generation radius to %s to avoid excessive disk space usage. Reduce the radius or contact your host if you wish to have this limit removed.",
|
||||
"format_started_already": "için fonksiyon zaten başladı!",
|
||||
"format_start": "Fonksiyon %s içerisinde %s şekliyle, %s, %s merkezli olarak, %s yarıçapında başlatıldı.",
|
||||
"format_start_confirm": "Bu dünya için zaten hali hazırda bir fonksiyon başlatıldı. Devam ettirmek için '%s' yaz. Yeni bir fonksiyon oluşturmak için '%s' yaz.",
|
||||
"format_start_disk": "Bu sunucu sadece %s kullanılabilir disk alanına sahip fakat bu fonksiyon için tahmin edilen gereken disk alanı %s. Yinede başlatmak istiyorsanız, '%s' yazın.",
|
||||
"format_start_limit": "Sunucu sağlayıcınız aşırı fazla disk kullanımını engellemek için maksimum önden oluşturulmuş dünya yarıçapını %s olarak belirledi. Seçiminizin yarıçapını küçültün veya sunucu sağlayıcınızla iletişime geçin.",
|
||||
"format_started_already": "%s için fonksiyon zaten başlatıldı!",
|
||||
"format_world": "Dünya %s olarak değiştirildi.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Manage custom world borders",
|
||||
"format_worldborder_too_large": "&eNotice: Your world border is currently set larger than the maximum of %s configured in server.properties. This is normally an error and can cause issues.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Özel dünya sınırlarını yönet",
|
||||
"help_cancel": "&2chunky cancel&r - Mevcut veya kayıtlı fonksiyonları durdurun ve silin",
|
||||
"help_center": "&2chunky center <x> <z>&r - Merkez blok konumunu ayarlayın",
|
||||
"help_continue": "&2chunky continue&r - Mevcut veya kayıtlı fonksiyonlara devam edin",
|
||||
"help_corners": "&2chunky corners <x1> <z1> <x2> <z2>&r - Set by corners",
|
||||
"help_trim": "&2chunky trim&r - Delete chunks outside selection",
|
||||
"help_menu": "&aChunky Commands&r%s",
|
||||
"help_more": "Type &a%s&r to see more.",
|
||||
"help_pattern": "&2chunky pattern <pattern>&r - Set the generation pattern",
|
||||
"help_continue": "&2chunky continue&r - Mevcut veya kayıtlı fonksiyonları devam ettirin",
|
||||
"help_corners": "&2chunky corners <x1> <z1> <x2> <z2>&r Köşelerle seçim yap",
|
||||
"help_trim": "&2chunky trim&r - Seçimin dışarısındaki chunkları sil",
|
||||
"help_menu": "&aChunky Komutları&r%s",
|
||||
"help_more": "Daha fazla görmek için &a%s&r yazın.",
|
||||
"help_pattern": "&2chunky pattern <yol>&r - Dünya oluşum yolunu belirler",
|
||||
"help_pause": "&2chunky pause&r - Mevcut fonksiyonları durdurun ve ilerlemeyi kaydedin",
|
||||
"help_progress": "&2chunky progress&r - Displays current task progress",
|
||||
"help_quiet": "&2chunky quiet <interval>&r - Sessiz aralığı ayarlayın",
|
||||
"help_progress": "&2chunky progress&r - Devam etmekte olan fonksiyonun durumunu gösterir",
|
||||
"help_quiet": "&2chunky quiet <interval>&r - Sessizlik aralığını ayarlayın",
|
||||
"help_radius": "&2chunky radius <radius>&r - Yarıçapı ayarlayın",
|
||||
"help_reload": "&2chunky reload&r - Reload configuration",
|
||||
"help_selection": "&2chunky selection&r - Display the current selection",
|
||||
"help_shape": "&2chunky shape <shape>&r - Set the shape to generate",
|
||||
"help_reload": "&2chunky reload&r - Konfigürasyonu yeniden yükle",
|
||||
"help_selection": "&2chunky selection&r - Seçimi görüntüle",
|
||||
"help_shape": "&2chunky shape <şekil>&r - Oluşum şeklini seçer",
|
||||
"help_silent": "&2chunky silent&r - Güncelleme mesajlarını göstermeyi aç / kapat",
|
||||
"help_spawn": "&2chunky spawn&r - Set the center to the spawn point",
|
||||
"help_spawn": "&2chunky spawn&r - Merkezi doğma noktası olarak belirler",
|
||||
"help_start": "&2chunky start&r - Yeni bir chunk oluşturma fonksiyonu başlatın",
|
||||
"help_world": "&2chunky world <world>&r - Dünya hedefini belirleyin",
|
||||
"help_world": "&2chunky world <world>&r - Hedef dünyayı belirleyin",
|
||||
"help_worldborder": "&2chunky worldborder&r - Merkezi ve yarıçapı dünya sınırına ayarlayın",
|
||||
"pattern_concentric": "concentric",
|
||||
"pattern_loop": "loop",
|
||||
"pattern_spiral": "spiral",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "region",
|
||||
"pattern_world": "world",
|
||||
"shape_circle": "circle",
|
||||
"shape_diamond": "diamond",
|
||||
"shape_ellipse": "ellipse",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "pentagon",
|
||||
"shape_rectangle": "rectangle",
|
||||
"shape_square": "square",
|
||||
"shape_star": "star",
|
||||
"shape_triangle": "triangle",
|
||||
"task_trim": "Deleted %s chunks from %s in %s seconds.",
|
||||
"task_done": "için fonksiyon tamamlandı: %s chunk (%s%%), Toplam zaman: %s:%s:%s",
|
||||
"task_stopped": "için fonksiyon durduruldu.",
|
||||
"task_update": "için çalışan fonksiyon: %s chunk (%s%%), Tahmini Oluş: %s:%s:%s, Oran: %s CPS, Mevcut: %s, %s",
|
||||
"task_trim_update": "Task running for %s. Processed: %s regions (%s%%)",
|
||||
"task_done": "%s için fonksiyon tamamlandı. %s chunk (%s%%) işlendi. Toplam zaman: %s:%s:%s",
|
||||
"task_stopped": "%s için fonksiyon durduruldu.",
|
||||
"task_update": "%s için fonksiyon devam ediyor: %s chunk (%s%%) işlendi, Kalan süre: %s:%s:%s, Hız: Saniyede %s chunk, Şu anda işlenilen chunk: %s, %s",
|
||||
"wrap_both": "both",
|
||||
"wrap_default": "default",
|
||||
"wrap_earth": "earth",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"format_border_load": "Виділення завантажено на основі світового бар'єра для світу %s.",
|
||||
"format_border_no_border": "Не існує бар'єра для світу %s.",
|
||||
"format_border_remove": "Бар'єр було видалено для світу %s.",
|
||||
"format_border_wrap": "World border wrap changed to %s for %s.",
|
||||
"format_border_wrap": "Обтікання межами світу змінено на %s для %s.",
|
||||
"format_cancel": "Скасовано завдання для світу %s.",
|
||||
"format_cancel_all": "Скасування всіх завдань.",
|
||||
"format_cancel_confirm": "Скасовані завдання не можуть бути продовжені. Якщо ви впевнені, що хочете скасувати, введіть '%s.",
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "Завдання продовжується для світу %s.",
|
||||
"format_continue_no_tasks": "Немає завдань для продовження.",
|
||||
"format_trim_confirm": "&cПопередження: Чанки в світі %s поза регіоном, формою якого є %s з центром %s, %s та радіусом %s, будуть невідворотно видалені. Буль ласка, переконайтесь, що ви зробили резервну копію вашого сервера, перш ніж продовжити, аби уникнути можливих проблем. Вам буде необхідно перезавантажити сервер після закінчення завдання. Якщо ви все розумієте та бажаєте продовжити, введіть '%s'.",
|
||||
"format_trim_confirm_inside": "&cПопередження: Чанки в %s всередині області %s з центром у %s, %s та радіусом %s буде видалено назавжди. Будь ласка, переконайтеся, що ви зробили резервну копію вашого сервера, перш ніж продовжувати, щоб уникнути можливих проблем. Після завершення завдання потрібно буде повністю перезапустити сервер. Якщо ви все зрозуміли і бажаєте продовжити, введіть '%s'.",
|
||||
"format_trim_confirm_inhabited": "&eПримітка: Фільтрування чанків за максимальним часом перебування в %s тіків. Процедура може зайняти більше часу, ніж зазвичай.",
|
||||
"format_pattern": "Патерн змінено на %s.",
|
||||
"format_pause": "Завдання призупинено для світу %s.",
|
||||
"format_pause_no_tasks": "Немає завдань для призупинення.",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "Ваш хост обмежив радіус передгенерації до %s аби уникнути надмірне споживання дискового простору. Зменште радіус, або зв'яжіться зі своїм хостом, щоб прибрати це обмеження.",
|
||||
"format_started_already": "Вже є активне завдання для світу %s!",
|
||||
"format_world": "Світ змінено на %s.",
|
||||
"format_worldborder_too_large": "&eПримітка: Ваша межа світу наразі встановлено більшим за максимальне значення %s, вказане у файлі server.properties. Зазвичай, це є помилкою і може спричинити проблеми.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Керування бар'єрами світів",
|
||||
"help_cancel": "&2chunky cancel&r - Зупинити та видалити поточні або збереженні завдання",
|
||||
"help_center": "&2chunky center <x> <z>&r - Встановити позицію центрального блока",
|
||||
@@ -74,23 +77,27 @@
|
||||
"pattern_loop": "пошаровий",
|
||||
"pattern_spiral": "спіральний",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "регіон",
|
||||
"pattern_world": "світ",
|
||||
"shape_circle": "коло",
|
||||
"shape_diamond": "ромб",
|
||||
"shape_ellipse": "еліпс",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "п'ятикутник",
|
||||
"shape_rectangle": "прямокутник",
|
||||
"shape_square": "квадрат",
|
||||
"shape_star": "зірка",
|
||||
"shape_triangle": "трикутник",
|
||||
"task_trim": "Видалено %s чанків зі світу %s, секунд витрачено: %s.",
|
||||
"task_trim_update": "Завдання запущено для %s. Оброблено: %s регіонів (%s%%)",
|
||||
"task_done": "Завдання для світу %s завершено. Опрацьовано: %s чанків (%s%%), Загальний час: %s:%s:%s",
|
||||
"task_stopped": "Завдання зупинено для світу %s.",
|
||||
"task_update": "Завдання активне для світу %s. Опрацьовано: %s chunks (%s%%), ETA: %s:%s:%s, Швидкість: %s cps, Поточний чанк: %s, %s",
|
||||
"wrap_both": "both",
|
||||
"wrap_default": "default",
|
||||
"wrap_earth": "earth",
|
||||
"wrap_none": "none",
|
||||
"wrap_radial": "radial",
|
||||
"wrap_both": "обидва",
|
||||
"wrap_default": "типовий",
|
||||
"wrap_earth": "земля",
|
||||
"wrap_none": "немає",
|
||||
"wrap_radial": "радіальний",
|
||||
"wrap_x": "x",
|
||||
"wrap_z": "z"
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
"format_border_load": "Đã tải lựa chọn từ đường biên thế giới cho %s.",
|
||||
"format_border_no_border": "Không tồn tại đường biên thế giới của %s.",
|
||||
"format_border_remove": "Đã bỏ đường biên giới của %s.",
|
||||
"format_border_wrap": "World border wrap changed to %s for %s.",
|
||||
"format_border_wrap": "Đường viền thế giới đã thay đổi thành %s cho %s.",
|
||||
"format_cancel": "Đã hủy tác vụ tại %s.",
|
||||
"format_cancel_all": "Đang hủy toàn bộ tác vụ hiện có.",
|
||||
"format_cancel_confirm": "Tác vụ đã hủy sẽ không thể tiếp tục. Nếu bạn chắc chắn, hãy gõ '%s'.",
|
||||
@@ -26,6 +26,8 @@
|
||||
"format_continue": "Tác vụ tiếp tục tại %s.",
|
||||
"format_continue_no_tasks": "Không có tác vụ nào để tiếp tục.",
|
||||
"format_trim_confirm": "&cCảnh báo: Chunks tại %s nằm ngoài khu vực %s có tọa độ trung tâm %s, %s với bán kính %s sẽ bị xóa vĩnh viễn. Hãy chắc chắn bạn đã backup lại server trước khi tiếp tục để tránh các nguy cơ tiềm ẩn. Bạn sẽ bị yêu cầu khởi động lại hoàn toàn server sau khi các tác vụ hoàn tất. Nếu bạn đã hiểu và muốn tiếp tục, hãy gõ '%s'.",
|
||||
"format_trim_confirm_inside": "&cCảnh báo: Chunks tại %s nằm trong khu vực %s có tọa độ trung tâm %s, %s với bán kính %s sẽ bị xóa vĩnh viễn. Hãy chắc chắn bạn đã backup lại server trước khi tiếp tục để tránh các nguy cơ tiềm ẩn. Bạn sẽ bị yêu cầu khởi động lại hoàn toàn server sau khi các tác vụ hoàn tất. Nếu bạn đã hiểu và muốn tiếp tục, hãy gõ '%s'.",
|
||||
"format_trim_confirm_inhabited": "&eLưu ý: Lọc các khối theo thời gian có người ở tối đa là %s tích tắc. Quá trình cắt có thể mất nhiều thời gian hơn bình thường để hoàn thành.",
|
||||
"format_pattern": "Pattern đã được đổi sang %s.",
|
||||
"format_pause": "Tác vụ đã dừng tại %s.",
|
||||
"format_pause_no_tasks": "Không có tác vụ hoạt động để dừng.",
|
||||
@@ -35,12 +37,12 @@
|
||||
"format_radius": "Bán kính đã đổi thành %s.",
|
||||
"format_reload": "Đã tải lại cấu hình thành công.",
|
||||
"format_reload_tasks_running": "Không thể tải lại cấu hình khi đang có tác vụ hoạt động.",
|
||||
"format_selection": "Current selection",
|
||||
"format_selection_center": "Center: %s, %s",
|
||||
"format_selection_radius": "Radius: %s",
|
||||
"format_selection": "Lựa chọn hiện tại",
|
||||
"format_selection_center": "Trung tâm: %s, %s",
|
||||
"format_selection_radius": "Bán kính: %s",
|
||||
"format_selection_radii": "Radii: %s, %s",
|
||||
"format_selection_shape": "Shape: %s",
|
||||
"format_selection_world": "World: %s",
|
||||
"format_selection_shape": "Hình dáng: %s",
|
||||
"format_selection_world": "Thế giới: %s",
|
||||
"format_shape": "Hình dạng thế giới đã đổi thành %s.",
|
||||
"format_silent": "Chế độ im lặng %s.",
|
||||
"format_start": "Tác vụ đã bắt đầu tại %s với khu vực dạng %s có tọa độ trung tâm tại %s, %s với bán kính %s.",
|
||||
@@ -49,6 +51,7 @@
|
||||
"format_start_limit": "Máy chủ của bạn đã giới hạn bán kính tạo trước tối đa là %s để tránh sử dụng quá nhiều dung lượng ổ đĩa. Giảm bán kính hoặc liên hệ với admin máy chủ nếu bạn muốn xóa giới hạn này.",
|
||||
"format_started_already": "Tác vụ đã bắt đầu tại %s!",
|
||||
"format_world": "Thế giới đã chọn thay đổi sang %s.",
|
||||
"format_worldborder_too_large": "&eThông báo: Ranh giới thế giới của bạn hiện được đặt lớn hơn mức tối đa %s được định cấu hình trong server.properties. Đây thường là một lỗi và có thể gây ra vấn đề.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - Quản lý các đường biên giới",
|
||||
"help_cancel": "&2chunky cancel&r - Dừng và xóa các tác vụ hiện tại hoặc đã lưu",
|
||||
"help_center": "&2chunky center <x> <z>&r - Đặt lại tọa độ của khối trung tâm",
|
||||
@@ -63,7 +66,7 @@
|
||||
"help_quiet": "&2chunky quiet <interval>&r - Đặt chế độ im lặng",
|
||||
"help_radius": "&2chunky radius <radius>&r - Đặt bán kính",
|
||||
"help_reload": "&2chunky reload&r - Tải lại cấu hình",
|
||||
"help_selection": "&2chunky selection&r - Display the current selection",
|
||||
"help_selection": "&lựa chọn chunky&s - Hiển thị lựa chọn hiện tại",
|
||||
"help_shape": "&2chunky shape <shape>&r - Đặt hình dạng thế giới",
|
||||
"help_silent": "&2chunky silent&r - Bật tắt chế độ hiển thị thông báo cập nhật tác vụ",
|
||||
"help_spawn": "&2chunky spawn&r - Đặt trung tâm thành điểm triệu hồi",
|
||||
@@ -74,23 +77,27 @@
|
||||
"pattern_loop": "vòng lặp",
|
||||
"pattern_spiral": "xoắn ốc",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "khu vực",
|
||||
"pattern_world": "thế giới",
|
||||
"shape_circle": "hình tròn",
|
||||
"shape_diamond": "hình thoi",
|
||||
"shape_ellipse": "hình bầu dục",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "hình lục giác",
|
||||
"shape_rectangle": "hình chữ nhật",
|
||||
"shape_square": "hình vuông",
|
||||
"shape_star": "hình ngôi sao",
|
||||
"shape_triangle": "hình tam giác",
|
||||
"task_trim": "Đã xóa %s chunks từ %s trong %s giây.",
|
||||
"task_trim_update": "Tác vụ đang chạy trong %s. Đã xử lý: %s khu vực (%s%%)",
|
||||
"task_done": "Đã hoàn tác vụ tại %s. Đã khởi tạo: %s chunks (%s%%), Tổng thời gian: %s:%s:%s",
|
||||
"task_stopped": "Đã dừng tác vụ tại %s.",
|
||||
"task_update": "Tác vụ đang hoạt động tại %s. Đã khởi tạo: %s chunks (%s%%), Thời gian dự kiến: %s:%s:%s, Tốc độ: %s cps, Tọa độ hiện tại %s, %s",
|
||||
"wrap_both": "both",
|
||||
"wrap_default": "default",
|
||||
"wrap_earth": "earth",
|
||||
"wrap_none": "none",
|
||||
"wrap_radial": "radial",
|
||||
"wrap_both": "cả hai",
|
||||
"wrap_default": "mặc định",
|
||||
"wrap_earth": "trái đất",
|
||||
"wrap_none": "không có",
|
||||
"wrap_radial": "xuyên tâm",
|
||||
"wrap_x": "x",
|
||||
"wrap_z": "z"
|
||||
}
|
||||
@@ -3,10 +3,10 @@
|
||||
"border_load_failed": "没有找到已保存的世界边界。",
|
||||
"border_save_failed": "无法保存世界边界。",
|
||||
"command_no_permission": "&c您没有足够权限来使用此指令。",
|
||||
"disabled": "关闭的",
|
||||
"enabled": "启用的",
|
||||
"error_version": "本插件无法与Minecraft版本低于 1.13 的服务器兼容。",
|
||||
"error_version_spigot": "本插件无法与 Spigot 1.13 兼容!",
|
||||
"disabled": "已关闭",
|
||||
"enabled": "已启用",
|
||||
"error_version": "Chunky无法与Minecraft版本低于 1.13 的服务器兼容。",
|
||||
"error_version_spigot": "Chunky无法加载在 Spigot 1.13 版本的服务器上",
|
||||
"format_border_add": "将 %s 的世界边界增加至 %s,目前边界中心坐标 %s, %s, 边界的半径为 %s。",
|
||||
"format_border_bypass": "已临时 %s 世界边界绕过给玩家 %s。",
|
||||
"format_border_bypass_no_target": "无法找到名为 %s 的玩家 。",
|
||||
@@ -18,37 +18,40 @@
|
||||
"format_border_remove": "移除了世界 %s 的世界边界。",
|
||||
"format_border_wrap": "World border wrap changed to %s for %s.",
|
||||
"format_cancel": "任务取消于 %s。",
|
||||
"format_cancel_all": "取消所有任务中。",
|
||||
"format_cancel_all": "正在中止所有任务.",
|
||||
"format_cancel_confirm": "被取消的任务将无法继续。如果您确定要那么做,请输入 '%s'。",
|
||||
"format_cancel_no_tasks": "没有任务能被取消。",
|
||||
"format_center": "预生成中心转移至 %s, %s。",
|
||||
"format_confirm": "没有什么需要您确认的操作!",
|
||||
"format_continue": "任务持续了 %s。",
|
||||
"format_continue_no_tasks": "没有预生成任务可以继续。",
|
||||
"format_continue_no_tasks": "没有可再次运行的加载任务。",
|
||||
"format_trim_confirm": "&c警告: 在世界 %s 中形状 %s 的区块以 %s, %s 为中心 %s 为半径的预生成行为将被永久删除。 请确保您已经备份了您的服务器再继续,以避免对世界存档潜在的影响与损害。 任务完成后您需要重新启动服务器。如果您理解并想继续,请输入 '%s'。",
|
||||
"format_trim_confirm_inside": "&c警告: 在世界 %s 中类型为 %s 的区块以 %s, %s 为中心 %s 为半径的加载任务将被永久删除。 请确保您已经备份了您的服务器存档再继续,以避免对世界存档潜在的影响与损害。 任务结束后您需要重新启动服务器。如果您很清楚后果是什么,请输入 '%s'。",
|
||||
"format_trim_confirm_inhabited": "&eNotice: Filtering chunks by a maximum inhabited time of %s ticks. Trim may take longer than usual to complete.",
|
||||
"format_pattern": "预生成方案改为 %s。",
|
||||
"format_pause": "任务暂停了 %s。",
|
||||
"format_pause_no_tasks": "没有预生成任务可以暂停",
|
||||
"format_progress_no_tasks": "没有在运行的任务。",
|
||||
"format_quiet": "静止间隔设置为%s秒。",
|
||||
"format_radii": "对 x 的半径已更改为 %s, 对 z 的半径已更改为 %s。",
|
||||
"format_radius": "生成范围半径已更改为 %s。",
|
||||
"format_reload": "成功重载配置文件。",
|
||||
"format_reload_tasks_running": "配置文件不能在有活跃预生成任务状态下重载。",
|
||||
"format_selection": "Current selection",
|
||||
"format_selection_center": "Center: %s, %s",
|
||||
"format_selection_radius": "Radius: %s",
|
||||
"format_radius": "世界加载半径已更改为 %s。",
|
||||
"format_reload": "配置文件成功重新加载。",
|
||||
"format_reload_tasks_running": "配置文件无法在有加载任务的状态下重载。",
|
||||
"format_selection": "当前所选",
|
||||
"format_selection_center": "中心: %s, %s",
|
||||
"format_selection_radius": "半径 ︰ %s",
|
||||
"format_selection_radii": "Radii: %s, %s",
|
||||
"format_selection_shape": "Shape: %s",
|
||||
"format_selection_world": "World: %s",
|
||||
"format_selection_shape": "形状: %s",
|
||||
"format_selection_world": "世界: %s",
|
||||
"format_shape": "预生成形状已更改为 %s。",
|
||||
"format_silent": "静默模式 %s。",
|
||||
"format_start": "任务开始于模式 %1$s 以间隔 %3$s, %4$s 以 %5$s 的范围进行。",
|
||||
"format_start_confirm": "该世界已经有一个已开始的预生成任务,如果您想继续该任务,请输入 '%s'。如果您想开启一项新生成任务,请输入 '%s'。",
|
||||
"format_start_confirm": "该世界已经有一个准备好的的预生成任务,如果您想继续该任务,请输入 '%s'。如果您想开启一项新生成任务,请输入 '%s'。",
|
||||
"format_start_disk": "服务器仅剩余磁盘空间 %s , 但任务所需的预估磁盘空间占用是 %s。 如果您仍想继续,请输入 '%s'。",
|
||||
"format_start_limit": "您的主机提供商已将最大预生成的半径限制在 %s 以避免磁盘空间的过度使用。 如果您想要解除此限制,减少您的半径大小或联系您的主机提供商。",
|
||||
"format_started_already": "任务已经持续了 %s!",
|
||||
"format_world": "世界被改变为 %s。",
|
||||
"format_worldborder_too_large": "&eNotice: Your world border is currently set larger than the maximum of %s configured in server.properties. This is normally an error and can cause issues.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - 管理自定义世界边界",
|
||||
"help_cancel": "&2chunky cancel&r - 取消并删除当前正在运行或已保存的任务",
|
||||
"help_center": "&2chunky center <x> <z>&r - 设置预生成中心的位置",
|
||||
@@ -63,31 +66,35 @@
|
||||
"help_quiet": "&2chunky quiet <interval>&r - 设置静止间隔",
|
||||
"help_radius": "&2chunky radius <radius>&r - 设置生成半径",
|
||||
"help_reload": "&2chunky reload&r - 重载配置文件",
|
||||
"help_selection": "&2chunky selection&r - Display the current selection",
|
||||
"help_selection": "&2chunky selection&r - 显示当前选择",
|
||||
"help_shape": "&2chunky shape <shape>&r - 设置预生成的世界形状",
|
||||
"help_silent": "&2chunky silent&r - 切换是否展示更新信息",
|
||||
"help_silent": "&2chunky silent&r - 是否展示更新信息",
|
||||
"help_spawn": "&2chunky spawn&r - 设置预生成任务的中心点",
|
||||
"help_start": "&2chunky start&r - 新建一个世界预生成任务",
|
||||
"help_world": "&2chunky world <world>&r - 设置目标世界",
|
||||
"help_world": "&2chunky world <world>&r - 选择世界",
|
||||
"help_worldborder": "&2chunky worldborder&r - 设置世界边界的中心与范围",
|
||||
"pattern_concentric": "同心圆",
|
||||
"pattern_loop": "回环",
|
||||
"pattern_spiral": "螺旋",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "region",
|
||||
"pattern_world": "world",
|
||||
"shape_circle": "环形",
|
||||
"shape_diamond": "菱形",
|
||||
"shape_ellipse": "椭圆形",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "五边形",
|
||||
"shape_rectangle": "长方形",
|
||||
"shape_square": "正方形",
|
||||
"shape_star": "星形",
|
||||
"shape_triangle": "三角形",
|
||||
"task_trim": "在 %3$s 秒内从 %2$s 删除了 %1$s 个区块。",
|
||||
"task_trim_update": "Task running for %s. Processed: %s regions (%s%%)",
|
||||
"task_done": "任务结束于 %s。 处理了 %s 个区块 (%s%%), 总运行时长: %s:%s:%s",
|
||||
"task_stopped": "任务暂停于 %s。",
|
||||
"task_update": "任务运行于世界 %s。 处理了 %s 个区块 (%s%%), 预计距完成还有: %s:%s:%s, 速率: %s 区块/秒, 当前区块进度: %s, %s",
|
||||
"wrap_both": "both",
|
||||
"wrap_default": "default",
|
||||
"wrap_default": "默认",
|
||||
"wrap_earth": "earth",
|
||||
"wrap_none": "none",
|
||||
"wrap_radial": "radial",
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
{
|
||||
"border_dependency_update": "在使用 ChunkyBorder 前您應該先更新 Chunky 的版本!",
|
||||
"border_load_failed": "沒有找到已儲存的世界邊界。",
|
||||
"border_save_failed": "無法儲存世界邊界。",
|
||||
"command_no_permission": "&c您沒有權限使用此指令。",
|
||||
"disabled": "關閉",
|
||||
"enabled": "啟用",
|
||||
"error_version": "此插件無法與 Minecraft 版本低於 1.13 的伺服器相容。",
|
||||
"error_version_spigot": "此插件無法與 Spigot 1.13 相容!",
|
||||
"format_border_add": "將 %s 的世界邊界增加至 %s,目前邊界中心座標 %s, %s, 邊界的半徑為 %s。",
|
||||
"format_border_bypass": "已臨時 %s 世界邊界繞過給玩家 %s。",
|
||||
"format_border_bypass_no_target": "無法找到叫做 %s 的玩家 。",
|
||||
"format_border_list": "世界邊界列表",
|
||||
"format_border_list_border": "%s:形狀為%s,以 %s、座標 %s、半徑為 %s 的世界邊界。",
|
||||
"format_border_list_none": "目前沒有已儲存的世界邊界。",
|
||||
"format_border_load": "已載入所選擇的世界邊界 %s。",
|
||||
"format_border_no_border": "您所選的世界邊界 %s 不存在。",
|
||||
"format_border_remove": "移除了世界邊界 %s 。",
|
||||
"format_border_wrap": "%s 的世界邊界邊框更改為 %s。",
|
||||
"format_cancel": "%s 的任務已被取消。",
|
||||
"format_cancel_all": "所有任務已被取消",
|
||||
"format_cancel_confirm": "被取消的任務將無法繼續。如果您想要這麼做,請輸入「%s」。",
|
||||
"format_cancel_no_tasks": "沒有任何可以被取消的任務。",
|
||||
"format_center": "中心點更改至 %s, %s。",
|
||||
"format_confirm": "沒有什麼需要您確認的操作!",
|
||||
"format_continue": "%s 任務繼續。",
|
||||
"format_continue_no_tasks": "沒有任何可以繼續的任務。",
|
||||
"format_trim_confirm": "&c警告: 在世界 %s 中形狀 %s 的區塊以 %s, %s 為中心 %s 為半徑的預生成行為將被永久刪除。 請確保您已經備份了您的伺服器再繼續,以避免對世界存檔潛在的影響與損害。 任務完成後您需要重新開機伺服器。如果您理解並想繼續,請輸入 '%s'。",
|
||||
"format_trim_confirm_inside": "&c警告: 在世界 %s 中 %s 形狀的區塊以 %s, %s 為中心 %s 為半徑的預生成行為將被永久刪除。 請確保您已經備份了您的伺服器再繼續以避免對世界存檔潛在的影響與損害。 任務完成後您需要重新啟動伺服器。如果您了解並想繼續,請輸入 '%s'。",
|
||||
"format_trim_confirm_inhabited": "&eNotice: 以最大滯留時間%s Ticks過濾區塊。刪減工作可能需要比平常更長的時間完成。",
|
||||
"format_pattern": "預載方案改為 %s。",
|
||||
"format_pause": "%s 任務暫停了 。",
|
||||
"format_pause_no_tasks": "沒有任務可以暫停。",
|
||||
"format_progress_no_tasks": "沒有正在執行的任務。",
|
||||
"format_quiet": "靜止間隔設定為 %s 秒。",
|
||||
"format_radii": "對 x 的半徑已變更為 %s,對 z 的半徑已變更為 %s。",
|
||||
"format_radius": "範圍半徑已更改為 %s。",
|
||||
"format_reload": "已成功重新載入設定。",
|
||||
"format_reload_tasks_running": "任務執行中,無法重新載入設定。",
|
||||
"format_selection": "目前選擇",
|
||||
"format_selection_center": "中心點:%s, %s",
|
||||
"format_selection_radius": "半徑:%s",
|
||||
"format_selection_radii": "範圍 x, z:%s, %s",
|
||||
"format_selection_shape": "形狀:%s",
|
||||
"format_selection_world": "世界:%s",
|
||||
"format_shape": "形狀切換至 %s。",
|
||||
"format_silent": "靜音模式 %s。",
|
||||
"format_start": "任務在 %s 開始,%s 區域以 %s 為中心,%s 半徑為 %s。",
|
||||
"format_start_confirm": "這個世界的任務已經開始了。 要繼續執行它,請輸入「%s」。 要開始新任務,請輸入「%s」。",
|
||||
"format_start_disk": "伺服器只剩下 %s 磁碟空間,但該任務所需的估計磁碟空間為 %s。 如果您仍想開始,請輸入「%s」。",
|
||||
"format_start_limit": "您的主機已將最大預生成範圍半徑限制為 %s,以避免過度使用磁碟空間。 如果您希望取消此限制,請減小半徑或聯繫您的管理員。",
|
||||
"format_started_already": "%s 的任務已經開始!",
|
||||
"format_world": "世界被改變為 %s。",
|
||||
"format_worldborder_too_large": "&eNotice: Your world border is currently set larger than the maximum of %s configured in server.properties. This is normally an error and can cause issues.",
|
||||
"help_border": "&2chunky border <add|remove|wrap|list|load|bypass>&r - 管理自定義世界邊界",
|
||||
"help_cancel": "&2chunky cancel&r - 停止和刪除目前或儲存的任務",
|
||||
"help_center": "&2chunky center <x> <z>&r - 設定中心點位置",
|
||||
"help_continue": "&2chunky continue&r - 繼續目前或儲存的任務",
|
||||
"help_corners": "&2chunky corners <x1> <z1> <x2> <z2>&r - 依對角設定",
|
||||
"help_trim": "&2chunky trim&r - 刪除選擇之外的所有區塊",
|
||||
"help_menu": "&aChunky 指令&r%s",
|
||||
"help_more": "輸入 &a%s&r 可獲得更多資訊。",
|
||||
"help_pattern": "&2chunky pattern <pattern>&r - 設置預載模式",
|
||||
"help_pause": "&2chunky pause&r - 暫停目前任務並儲存進度",
|
||||
"help_progress": "&2chunky progress&r - 顯示目前任務進度",
|
||||
"help_quiet": "&2chunky quiet <interval>&r - 設定安靜模式的間距",
|
||||
"help_radius": "&2chunky radius <radius>&r - 設定預載區塊半徑範圍",
|
||||
"help_reload": "&2chunky reload&r - 重新載入設定檔",
|
||||
"help_selection": "&2chunky selection&r - 顯示目前選擇",
|
||||
"help_shape": "&2chunky shape <shape>&r - 設定要預載的形狀",
|
||||
"help_silent": "&2chunky silent&r - 切換顯示更新消息",
|
||||
"help_spawn": "&2chunky spawn&r - 以中心點設定為重生點",
|
||||
"help_start": "&2chunky start&r - 開始一個新的區塊生成任務",
|
||||
"help_world": "&2chunky world <world>&r - 設定目標世界",
|
||||
"help_worldborder": "&2chunky worldborder&r - 使用世界邊界的中心和範圍",
|
||||
"pattern_concentric": "同心圓",
|
||||
"pattern_loop": "循環",
|
||||
"pattern_spiral": "螺旋",
|
||||
"pattern_csv": "csv",
|
||||
"pattern_region": "區域",
|
||||
"pattern_world": "world",
|
||||
"shape_circle": "環狀",
|
||||
"shape_diamond": "菱形",
|
||||
"shape_ellipse": "橢圓形",
|
||||
"shape_hexagon": "hexagon",
|
||||
"shape_pentagon": "五邊形",
|
||||
"shape_rectangle": "長方形",
|
||||
"shape_square": "正方形",
|
||||
"shape_star": "星行",
|
||||
"shape_triangle": "三角形",
|
||||
"task_trim": "在 %s 秒內從 %s 刪除了 %s 個區塊。",
|
||||
"task_trim_update": "Task running for %s. Processed: %s regions (%s%%)",
|
||||
"task_done": "%s 的任務已完成。 已處理:%s 個塊(%s%%),總時間:%s:%s:%s",
|
||||
"task_stopped": "%s 任務停止了 。",
|
||||
"task_update": "正在為 %s 執行的任務。 已處理:%s 區塊(%s%%),預計時間:%s:%s:%s,速度:%s cps,目前:%s, %s",
|
||||
"wrap_both": "皆",
|
||||
"wrap_default": "預設",
|
||||
"wrap_earth": "earth",
|
||||
"wrap_none": "無",
|
||||
"wrap_radial": "環狀",
|
||||
"wrap_x": "x",
|
||||
"wrap_z": "z"
|
||||
}
|
||||
@@ -22,28 +22,38 @@ public class BoundaryTest {
|
||||
final ChunkIterator concentricIterator = new ConcentricChunkIterator(SELECTION);
|
||||
final ChunkIterator loop2Iterator = new Loop2ChunkIterator(SELECTION);
|
||||
final ChunkIterator spiralIterator = new SpiralChunkIterator(SELECTION);
|
||||
final ChunkIterator regionIterator = new RegionChunkIterator(SELECTION);
|
||||
final List<ChunkCoordinate> concentricCoordinates = new ArrayList<>();
|
||||
final List<ChunkCoordinate> loop2Coordinates = new ArrayList<>();
|
||||
final List<ChunkCoordinate> spiralCoordinates = new ArrayList<>();
|
||||
final List<ChunkCoordinate> regionCoordinates = new ArrayList<>();
|
||||
concentricIterator.forEachRemaining(concentricCoordinates::add);
|
||||
loop2Iterator.forEachRemaining(loop2Coordinates::add);
|
||||
spiralIterator.forEachRemaining(spiralCoordinates::add);
|
||||
regionIterator.forEachRemaining(regionCoordinates::add);
|
||||
Collections.sort(concentricCoordinates);
|
||||
Collections.sort(loop2Coordinates);
|
||||
Collections.sort(spiralCoordinates);
|
||||
Collections.sort(regionCoordinates);
|
||||
final ChunkCoordinate concentricPoint1 = concentricCoordinates.get(0);
|
||||
final ChunkCoordinate concentricPoint2 = concentricCoordinates.get(concentricCoordinates.size() - 1);
|
||||
final ChunkCoordinate loop2Point1 = loop2Coordinates.get(0);
|
||||
final ChunkCoordinate loop2Point2 = loop2Coordinates.get(loop2Coordinates.size() - 1);
|
||||
final ChunkCoordinate spiralPoint1 = spiralCoordinates.get(0);
|
||||
final ChunkCoordinate spiralPoint2 = spiralCoordinates.get(spiralCoordinates.size() - 1);
|
||||
final ChunkCoordinate regionPoint1 = regionCoordinates.get(0);
|
||||
final ChunkCoordinate regionPoint2 = regionCoordinates.get(regionCoordinates.size() - 1);
|
||||
assertEquals(concentricPoint1.x(), loop2Point1.x());
|
||||
assertEquals(concentricPoint1.z(), loop2Point1.z());
|
||||
assertEquals(loop2Point1.x(), spiralPoint1.x());
|
||||
assertEquals(loop2Point1.z(), spiralPoint1.z());
|
||||
assertEquals(spiralPoint1.x(), regionPoint1.x());
|
||||
assertEquals(spiralPoint1.z(), regionPoint1.z());
|
||||
assertEquals(concentricPoint2.x(), loop2Point2.x());
|
||||
assertEquals(concentricPoint2.z(), loop2Point2.z());
|
||||
assertEquals(loop2Point2.x(), spiralPoint2.x());
|
||||
assertEquals(loop2Point2.z(), spiralPoint2.z());
|
||||
assertEquals(spiralPoint2.x(), regionPoint2.x());
|
||||
assertEquals(spiralPoint2.z(), regionPoint2.z());
|
||||
}
|
||||
}
|
||||
@@ -83,6 +83,28 @@ public class ConstructorTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void region() {
|
||||
final List<ChunkCoordinate> chunks = new ArrayList<>();
|
||||
final ChunkIterator chunkIterator = new RegionChunkIterator(SELECTION);
|
||||
chunkIterator.forEachRemaining(chunks::add);
|
||||
final int total = (int) chunkIterator.total();
|
||||
for (int i = 0; i < total; ++i) {
|
||||
final List<ChunkCoordinate> continueChunks = new ArrayList<>();
|
||||
final ChunkIterator continueIterator = new RegionChunkIterator(SELECTION, i);
|
||||
continueIterator.forEachRemaining(continueChunks::add);
|
||||
final int continueTotal = (int) continueIterator.total();
|
||||
assertEquals("Total", total, continueTotal);
|
||||
final int size = chunks.size(), continueSize = continueChunks.size();
|
||||
assertEquals("Continued Size", size - i, continueSize);
|
||||
for (int j = 0; j < continueSize; ++j) {
|
||||
final int chunkX = chunks.get(j + i).x(), chunkZ = chunks.get(j + i).z();
|
||||
final int continueChunkX = continueChunks.get(j).x(), continueChunkZ = continueChunks.get(j).z();
|
||||
assertTrue(chunkX == continueChunkX && chunkZ == continueChunkZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rectangle() {
|
||||
final List<ChunkCoordinate> chunks = new ArrayList<>();
|
||||
|
||||
@@ -22,8 +22,10 @@ public class TotalTest {
|
||||
final ChunkIterator concentricIterator = new ConcentricChunkIterator(s);
|
||||
final ChunkIterator loop2Iterator = new Loop2ChunkIterator(s);
|
||||
final ChunkIterator spiralIterator = new SpiralChunkIterator(s);
|
||||
final ChunkIterator regionIterator = new RegionChunkIterator(s);
|
||||
assertEquals(concentricIterator.total(), loop2Iterator.total());
|
||||
assertEquals(loop2Iterator.total(), spiralIterator.total());
|
||||
assertEquals(spiralIterator.total(), regionIterator.total());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,8 +41,10 @@ public class TotalTest {
|
||||
final ChunkIterator concentricIterator = new ConcentricChunkIterator(s);
|
||||
final ChunkIterator loop2Iterator = new Loop2ChunkIterator(s);
|
||||
final ChunkIterator spiralIterator = new SpiralChunkIterator(s);
|
||||
final ChunkIterator regionIterator = new RegionChunkIterator(s);
|
||||
assertEquals(concentricIterator.total(), loop2Iterator.total());
|
||||
assertEquals(loop2Iterator.total(), spiralIterator.total());
|
||||
assertEquals(spiralIterator.total(), regionIterator.total());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ public class TranslatorTest {
|
||||
testTranslation("hi");
|
||||
testTranslation("hr");
|
||||
testTranslation("it");
|
||||
testTranslation("ko");
|
||||
testTranslation("nl");
|
||||
testTranslation("no");
|
||||
testTranslation("pl");
|
||||
@@ -35,6 +36,7 @@ public class TranslatorTest {
|
||||
testTranslation("vi");
|
||||
testTranslation("zh_CN");
|
||||
testTranslation("zh_HK");
|
||||
testTranslation("zh_TW");
|
||||
}
|
||||
|
||||
private void testTranslation(final String language) {
|
||||
@@ -66,6 +68,8 @@ public class TranslatorTest {
|
||||
translate(TranslationKey.FORMAT_CONTINUE, "world");
|
||||
translate(TranslationKey.FORMAT_CONTINUE_NO_TASKS);
|
||||
translate(TranslationKey.FORMAT_TRIM_CONFIRM, "world", translate(TranslationKey.SHAPE_SQUARE), Formatting.number(1), Formatting.number(2), "500", "/chunky confirm");
|
||||
translate(TranslationKey.FORMAT_TRIM_CONFIRM_INSIDE, "world", translate(TranslationKey.SHAPE_SQUARE), Formatting.number(1), Formatting.number(2), "500", "/chunky confirm");
|
||||
translate(TranslationKey.FORMAT_TRIM_CONFIRM_INHABITED, Formatting.number(0));
|
||||
translate(TranslationKey.FORMAT_PATTERN, "concentric");
|
||||
translate(TranslationKey.FORMAT_PAUSE, "world");
|
||||
translate(TranslationKey.FORMAT_PAUSE_NO_TASKS);
|
||||
@@ -113,9 +117,11 @@ public class TranslatorTest {
|
||||
translate(TranslationKey.PATTERN_LOOP);
|
||||
translate(TranslationKey.PATTERN_SPIRAL);
|
||||
translate(TranslationKey.PATTERN_CSV);
|
||||
translate(TranslationKey.PATTERN_REGION);
|
||||
translate(TranslationKey.SHAPE_CIRCLE);
|
||||
translate(TranslationKey.SHAPE_DIAMOND);
|
||||
translate(TranslationKey.SHAPE_ELLIPSE);
|
||||
translate(TranslationKey.SHAPE_HEXAGON);
|
||||
translate(TranslationKey.SHAPE_PENTAGON);
|
||||
translate(TranslationKey.SHAPE_RECTANGLE);
|
||||
translate(TranslationKey.SHAPE_SQUARE);
|
||||
@@ -125,13 +131,13 @@ public class TranslatorTest {
|
||||
translate(TranslationKey.TASK_DONE, "world", 5000, String.format("%.2f", 50f), "0", "01", "15");
|
||||
translate(TranslationKey.TASK_STOPPED, "world");
|
||||
translate(TranslationKey.TASK_UPDATE, "world", 5000, String.format("%.2f", 50f), "0", "00", "01", String.format("%.1f", 40f), 70, 70);
|
||||
translate(TranslationKey.WRAP_NONE);
|
||||
translate(TranslationKey.WRAP_DEFAULT);
|
||||
translate(TranslationKey.WRAP_BOTH);
|
||||
translate(TranslationKey.WRAP_DEFAULT);
|
||||
translate(TranslationKey.WRAP_EARTH);
|
||||
translate(TranslationKey.WRAP_NONE);
|
||||
translate(TranslationKey.WRAP_RADIAL);
|
||||
translate(TranslationKey.WRAP_X);
|
||||
translate(TranslationKey.WRAP_Z);
|
||||
translate(TranslationKey.WRAP_EARTH);
|
||||
translate("prefix");
|
||||
translate("null");
|
||||
}
|
||||
|
||||
@@ -26,4 +26,5 @@ files:
|
||||
uk: uk
|
||||
vi: vi
|
||||
zh-CN: zh_CN
|
||||
zh-TW: zh_TW
|
||||
zh-HK: zh_HK
|
||||
@@ -1,39 +0,0 @@
|
||||
plugins {
|
||||
id("fabric-loom") version "0.12-SNAPSHOT"
|
||||
}
|
||||
|
||||
val shade: Configuration by configurations.creating
|
||||
|
||||
dependencies {
|
||||
minecraft(group = "com.mojang", name = "minecraft", version = "1.19")
|
||||
mappings(group = "net.fabricmc", name = "yarn", version = "1.19+build.1", classifier = "v2")
|
||||
modImplementation(group = "net.fabricmc", name = "fabric-loader", version = "0.14.6")
|
||||
modImplementation(group = "net.fabricmc.fabric-api", name = "fabric-api", version = "0.55.2+1.19")
|
||||
modCompileOnly(group = "me.lucko", name = "fabric-permissions-api", version = "0.2-SNAPSHOT")
|
||||
implementation(project(":chunky-common"))
|
||||
shade(project(":chunky-common"))
|
||||
}
|
||||
|
||||
tasks {
|
||||
processResources {
|
||||
filesMatching("fabric.mod.json") {
|
||||
expand(
|
||||
"id" to rootProject.name,
|
||||
"version" to project.version,
|
||||
"name" to rootProject.name.capitalize(),
|
||||
"description" to project.property("description"),
|
||||
"author" to project.property("author"),
|
||||
"github" to project.property("github")
|
||||
)
|
||||
}
|
||||
}
|
||||
shadowJar {
|
||||
configurations = listOf(shade)
|
||||
archiveClassifier.set("dev")
|
||||
archiveFileName.set(null as String?)
|
||||
}
|
||||
remapJar {
|
||||
inputFile.set(shadowJar.get().archiveFile)
|
||||
archiveFileName.set("${rootProject.name.capitalize()}-${project.version}.jar")
|
||||
}
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
package org.popcraft.chunky;
|
||||
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.builder.ArgumentBuilder;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import org.popcraft.chunky.command.ChunkyCommand;
|
||||
import org.popcraft.chunky.command.CommandArguments;
|
||||
import org.popcraft.chunky.command.CommandLiteral;
|
||||
import org.popcraft.chunky.command.suggestion.SuggestionProviders;
|
||||
import org.popcraft.chunky.event.task.GenerationTaskFinishEvent;
|
||||
import org.popcraft.chunky.event.task.GenerationTaskUpdateEvent;
|
||||
import org.popcraft.chunky.listeners.bossbar.BossBarTaskFinishListener;
|
||||
import org.popcraft.chunky.listeners.bossbar.BossBarTaskUpdateListener;
|
||||
import org.popcraft.chunky.platform.FabricPlayer;
|
||||
import org.popcraft.chunky.platform.FabricSender;
|
||||
import org.popcraft.chunky.platform.FabricServer;
|
||||
import org.popcraft.chunky.platform.Sender;
|
||||
import org.popcraft.chunky.platform.impl.GsonConfig;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
||||
import static com.mojang.brigadier.arguments.StringArgumentType.string;
|
||||
import static com.mojang.brigadier.arguments.StringArgumentType.word;
|
||||
import static net.minecraft.command.argument.DimensionArgumentType.dimension;
|
||||
import static net.minecraft.command.argument.EntityArgumentType.player;
|
||||
import static net.minecraft.server.command.CommandManager.argument;
|
||||
import static net.minecraft.server.command.CommandManager.literal;
|
||||
|
||||
public class ChunkyFabric implements ModInitializer {
|
||||
private Chunky chunky;
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
ServerLifecycleEvents.SERVER_STARTED.register(minecraftServer -> {
|
||||
final Path configPath = FabricLoader.getInstance().getConfigDir().resolve("chunky/config.json");
|
||||
this.chunky = new Chunky(new FabricServer(this, minecraftServer), new GsonConfig(configPath));
|
||||
if (chunky.getConfig().getContinueOnRestart()) {
|
||||
chunky.getCommands().get(CommandLiteral.CONTINUE).execute(chunky.getServer().getConsole(), CommandArguments.empty());
|
||||
}
|
||||
chunky.getEventBus().subscribe(GenerationTaskUpdateEvent.class, new BossBarTaskUpdateListener());
|
||||
chunky.getEventBus().subscribe(GenerationTaskFinishEvent.class, new BossBarTaskFinishListener());
|
||||
FabricLoader.getInstance().getEntrypointContainers("chunky", ModInitializer.class)
|
||||
.forEach(entryPoint -> entryPoint.getEntrypoint().onInitialize());
|
||||
});
|
||||
ServerLifecycleEvents.SERVER_STOPPING.register(minecraftServer -> {
|
||||
if (chunky != null) {
|
||||
chunky.disable();
|
||||
}
|
||||
});
|
||||
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
||||
final LiteralArgumentBuilder<ServerCommandSource> command = literal(CommandLiteral.CHUNKY)
|
||||
.requires(serverCommandSource -> serverCommandSource.hasPermissionLevel(2))
|
||||
.executes(context -> {
|
||||
final Sender sender;
|
||||
if (context.getSource().getEntity() instanceof final ServerPlayerEntity player) {
|
||||
sender = new FabricPlayer(player);
|
||||
} else {
|
||||
sender = new FabricSender(context.getSource());
|
||||
}
|
||||
final Map<String, ChunkyCommand> commands = chunky.getCommands();
|
||||
final String input = context.getInput().substring(context.getLastChild().getNodes().get(0).getRange().getStart());
|
||||
final String[] tokens = input.split(" ");
|
||||
final String subCommand = tokens.length > 1 && commands.containsKey(tokens[1]) ? tokens[1] : CommandLiteral.HELP;
|
||||
final CommandArguments arguments = tokens.length > 2 ? CommandArguments.of(Arrays.copyOfRange(tokens, 2, tokens.length)) : CommandArguments.empty();
|
||||
commands.get(subCommand).execute(sender, arguments);
|
||||
return Command.SINGLE_SUCCESS;
|
||||
});
|
||||
registerArguments(command, literal(CommandLiteral.CANCEL),
|
||||
argument(CommandLiteral.WORLD, dimension()));
|
||||
registerArguments(command, literal(CommandLiteral.CENTER),
|
||||
argument(CommandLiteral.X, word()),
|
||||
argument(CommandLiteral.Z, word()));
|
||||
registerArguments(command, literal(CommandLiteral.CONFIRM));
|
||||
registerArguments(command, literal(CommandLiteral.CONTINUE),
|
||||
argument(CommandLiteral.WORLD, dimension()));
|
||||
registerArguments(command, literal(CommandLiteral.CORNERS),
|
||||
argument(CommandLiteral.X1, word()),
|
||||
argument(CommandLiteral.Z1, word()),
|
||||
argument(CommandLiteral.X2, word()),
|
||||
argument(CommandLiteral.Z2, word()));
|
||||
registerArguments(command, literal(CommandLiteral.HELP),
|
||||
argument(CommandLiteral.PAGE, integer()));
|
||||
registerArguments(command, literal(CommandLiteral.PATTERN),
|
||||
argument(CommandLiteral.PATTERN, string()).suggests(SuggestionProviders.PATTERNS),
|
||||
argument(CommandLiteral.VALUE, string()));
|
||||
registerArguments(command, literal(CommandLiteral.PAUSE),
|
||||
argument(CommandLiteral.WORLD, dimension()));
|
||||
registerArguments(command, literal(CommandLiteral.PROGRESS));
|
||||
registerArguments(command, literal(CommandLiteral.QUIET),
|
||||
argument(CommandLiteral.INTERVAL, integer()));
|
||||
registerArguments(command, literal(CommandLiteral.RADIUS),
|
||||
argument(CommandLiteral.RADIUS, word()),
|
||||
argument(CommandLiteral.RADIUS, word()));
|
||||
registerArguments(command, literal(CommandLiteral.RELOAD),
|
||||
argument(CommandLiteral.TYPE, word()));
|
||||
registerArguments(command, literal(CommandLiteral.SELECTION));
|
||||
registerArguments(command, literal(CommandLiteral.SHAPE),
|
||||
argument(CommandLiteral.SHAPE, string()).suggests(SuggestionProviders.SHAPES));
|
||||
registerArguments(command, literal(CommandLiteral.SILENT));
|
||||
registerArguments(command, literal(CommandLiteral.SPAWN));
|
||||
registerArguments(command, literal(CommandLiteral.START),
|
||||
argument(CommandLiteral.WORLD, dimension()),
|
||||
argument(CommandLiteral.SHAPE, string()).suggests(SuggestionProviders.SHAPES),
|
||||
argument(CommandLiteral.CENTER_X, word()),
|
||||
argument(CommandLiteral.CENTER_Z, word()),
|
||||
argument(CommandLiteral.RADIUS_X, word()),
|
||||
argument(CommandLiteral.RADIUS_Z, word()));
|
||||
registerArguments(command, literal(CommandLiteral.TRIM),
|
||||
argument(CommandLiteral.WORLD, dimension()),
|
||||
argument(CommandLiteral.SHAPE, string()).suggests(SuggestionProviders.SHAPES),
|
||||
argument(CommandLiteral.CENTER_X, word()),
|
||||
argument(CommandLiteral.CENTER_Z, word()),
|
||||
argument(CommandLiteral.RADIUS_X, word()),
|
||||
argument(CommandLiteral.RADIUS_Z, word()));
|
||||
registerArguments(command, literal(CommandLiteral.WORLDBORDER));
|
||||
registerArguments(command, literal(CommandLiteral.WORLD),
|
||||
argument(CommandLiteral.WORLD, dimension()));
|
||||
final LiteralArgumentBuilder<ServerCommandSource> borderCommand = literal(CommandLiteral.BORDER)
|
||||
.requires(serverCommandSource -> chunky.getCommands().containsKey(CommandLiteral.BORDER))
|
||||
.executes(command.getCommand());
|
||||
registerArguments(borderCommand, literal(CommandLiteral.ADD),
|
||||
argument(CommandLiteral.WORLD, dimension()));
|
||||
registerArguments(borderCommand, literal(CommandLiteral.BYPASS),
|
||||
argument(CommandLiteral.PLAYER, player()));
|
||||
registerArguments(borderCommand, literal(CommandLiteral.HELP));
|
||||
registerArguments(borderCommand, literal(CommandLiteral.LIST));
|
||||
registerArguments(borderCommand, literal(CommandLiteral.LOAD),
|
||||
argument(CommandLiteral.WORLD, dimension()));
|
||||
registerArguments(borderCommand, literal(CommandLiteral.REMOVE),
|
||||
argument(CommandLiteral.WORLD, dimension()));
|
||||
registerArguments(borderCommand, literal(CommandLiteral.WRAP),
|
||||
argument(CommandLiteral.WRAP, word()));
|
||||
registerArguments(command, borderCommand);
|
||||
dispatcher.register(command);
|
||||
});
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private <S> void registerArguments(final LiteralArgumentBuilder<S> command, final ArgumentBuilder<S, ?>... arguments) {
|
||||
for (int i = arguments.length - 1; i > 0; --i) {
|
||||
arguments[i - 1].then(arguments[i].executes(command.getCommand()));
|
||||
}
|
||||
command.then(arguments[0].executes(command.getCommand()));
|
||||
}
|
||||
|
||||
public Chunky getChunky() {
|
||||
return chunky;
|
||||
}
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
package org.popcraft.chunky.command.suggestion;
|
||||
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.suggestion.SuggestionProvider;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import org.popcraft.chunky.command.CommandLiteral;
|
||||
import org.popcraft.chunky.iterator.PatternType;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class PatternSuggestionProvider implements SuggestionProvider<ServerCommandSource> {
|
||||
@Override
|
||||
public CompletableFuture<Suggestions> getSuggestions(final CommandContext<ServerCommandSource> context, final SuggestionsBuilder builder) {
|
||||
try {
|
||||
final String input = context.getArgument(CommandLiteral.PATTERN, String.class);
|
||||
PatternType.ALL.forEach(pattern -> {
|
||||
if (pattern.contains(input.toLowerCase())) {
|
||||
builder.suggest(pattern);
|
||||
}
|
||||
});
|
||||
} catch (IllegalArgumentException e) {
|
||||
PatternType.ALL.forEach(builder::suggest);
|
||||
}
|
||||
return builder.buildFuture();
|
||||
}
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
package org.popcraft.chunky.command.suggestion;
|
||||
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.suggestion.SuggestionProvider;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import org.popcraft.chunky.command.CommandLiteral;
|
||||
import org.popcraft.chunky.shape.ShapeType;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class ShapeSuggestionProvider implements SuggestionProvider<ServerCommandSource> {
|
||||
@Override
|
||||
public CompletableFuture<Suggestions> getSuggestions(final CommandContext<ServerCommandSource> context, final SuggestionsBuilder builder) {
|
||||
try {
|
||||
final String input = context.getArgument(CommandLiteral.SHAPE, String.class);
|
||||
ShapeType.ALL.forEach(shape -> {
|
||||
if (shape.contains(input.toLowerCase())) {
|
||||
builder.suggest(shape);
|
||||
}
|
||||
});
|
||||
} catch (IllegalArgumentException e) {
|
||||
ShapeType.ALL.forEach(builder::suggest);
|
||||
}
|
||||
return builder.buildFuture();
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package org.popcraft.chunky.command.suggestion;
|
||||
|
||||
import com.mojang.brigadier.suggestion.SuggestionProvider;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
|
||||
public final class SuggestionProviders {
|
||||
public static final SuggestionProvider<ServerCommandSource> PATTERNS;
|
||||
public static final SuggestionProvider<ServerCommandSource> SHAPES;
|
||||
|
||||
static {
|
||||
PATTERNS = new PatternSuggestionProvider();
|
||||
SHAPES = new ShapeSuggestionProvider();
|
||||
}
|
||||
|
||||
private SuggestionProviders() {
|
||||
}
|
||||
}
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
package org.popcraft.chunky.listeners.bossbar;
|
||||
|
||||
import net.minecraft.entity.boss.BossBarManager;
|
||||
import net.minecraft.entity.boss.CommandBossBar;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.popcraft.chunky.GenerationTask;
|
||||
import org.popcraft.chunky.event.task.GenerationTaskFinishEvent;
|
||||
import org.popcraft.chunky.platform.FabricWorld;
|
||||
import org.popcraft.chunky.platform.World;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class BossBarTaskFinishListener implements Consumer<GenerationTaskFinishEvent> {
|
||||
@Override
|
||||
public void accept(final GenerationTaskFinishEvent event) {
|
||||
final GenerationTask task = event.generationTask();
|
||||
final World world = task.getSelection().world();
|
||||
final Identifier worldIdentifier = Identifier.tryParse(world.getKey());
|
||||
final Identifier barIdentifier = Identifier.tryParse("chunky:progress_" + world.getKey().replace(':', '_'));
|
||||
if (worldIdentifier == null || barIdentifier == null || !(world instanceof FabricWorld)) {
|
||||
return;
|
||||
}
|
||||
final MinecraftServer server = ((FabricWorld) world).getServerWorld().getServer();
|
||||
final BossBarManager bossBarManager = server.getBossBarManager();
|
||||
final CommandBossBar existingBossBar = bossBarManager.get(barIdentifier);
|
||||
if (existingBossBar != null) {
|
||||
existingBossBar.clearPlayers();
|
||||
bossBarManager.remove(existingBossBar);
|
||||
}
|
||||
}
|
||||
}
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
package org.popcraft.chunky.listeners.bossbar;
|
||||
|
||||
import net.minecraft.entity.boss.BossBar;
|
||||
import net.minecraft.entity.boss.BossBarManager;
|
||||
import net.minecraft.entity.boss.CommandBossBar;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.popcraft.chunky.Chunky;
|
||||
import org.popcraft.chunky.GenerationTask;
|
||||
import org.popcraft.chunky.event.task.GenerationTaskUpdateEvent;
|
||||
import org.popcraft.chunky.platform.FabricWorld;
|
||||
import org.popcraft.chunky.platform.World;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class BossBarTaskUpdateListener implements Consumer<GenerationTaskUpdateEvent> {
|
||||
@Override
|
||||
public void accept(final GenerationTaskUpdateEvent event) {
|
||||
final GenerationTask task = event.generationTask();
|
||||
final Chunky chunky = task.getChunky();
|
||||
final World world = task.getSelection().world();
|
||||
final Identifier worldIdentifier = Identifier.tryParse(world.getKey());
|
||||
final Identifier barIdentifier = Identifier.tryParse("chunky:progress_" + world.getKey().replace(':', '_'));
|
||||
if (worldIdentifier == null || barIdentifier == null || !(world instanceof FabricWorld)) {
|
||||
return;
|
||||
}
|
||||
final MinecraftServer server = ((FabricWorld) world).getServerWorld().getServer();
|
||||
final BossBarManager bossBarManager = server.getBossBarManager();
|
||||
final CommandBossBar existingBossBar = bossBarManager.get(barIdentifier);
|
||||
final CommandBossBar bossBar = existingBossBar == null ? createNewBossBar(bossBarManager, barIdentifier, worldIdentifier) : existingBossBar;
|
||||
final boolean silent = chunky.getConfig().isSilent();
|
||||
if (silent == bossBar.isVisible()) {
|
||||
bossBar.setVisible(!silent);
|
||||
}
|
||||
for (final ServerPlayerEntity player : server.getPlayerManager().getPlayerList()) {
|
||||
if (player.hasPermissionLevel(2)) {
|
||||
bossBar.addPlayer(player);
|
||||
} else {
|
||||
bossBar.removePlayer(player);
|
||||
}
|
||||
}
|
||||
final GenerationTask.Progress progress = task.getProgress();
|
||||
bossBar.setName(Text.of(String.format("%s | %s%% | %s:%s:%s",
|
||||
worldIdentifier,
|
||||
String.format("%.2f", progress.getPercentComplete()),
|
||||
String.format("%01d", progress.getHours()),
|
||||
String.format("%02d", progress.getMinutes()),
|
||||
String.format("%02d", progress.getSeconds()))));
|
||||
bossBar.setPercent(progress.getPercentComplete() / 100f);
|
||||
if (progress.isComplete()) {
|
||||
bossBar.clearPlayers();
|
||||
bossBarManager.remove(bossBar);
|
||||
}
|
||||
}
|
||||
|
||||
private CommandBossBar createNewBossBar(final BossBarManager bossBarManager, final Identifier barIdentifier, final Identifier worldIdentifier) {
|
||||
final CommandBossBar bossBar = bossBarManager.add(barIdentifier, Text.of(barIdentifier.toString()));
|
||||
if (net.minecraft.world.World.OVERWORLD.getValue().equals(worldIdentifier)) {
|
||||
bossBar.setColor(BossBar.Color.GREEN);
|
||||
} else if (net.minecraft.world.World.NETHER.getValue().equals(worldIdentifier)) {
|
||||
bossBar.setColor(BossBar.Color.RED);
|
||||
} else if (net.minecraft.world.World.END.getValue().equals(worldIdentifier)) {
|
||||
bossBar.setColor(BossBar.Color.PURPLE);
|
||||
} else {
|
||||
bossBar.setColor(BossBar.Color.BLUE);
|
||||
}
|
||||
return bossBar;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package org.popcraft.chunky.mixin;
|
||||
|
||||
import net.minecraft.server.world.ServerChunkManager;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(ServerChunkManager.class)
|
||||
public interface ServerChunkManagerMixin {
|
||||
@Invoker("tick")
|
||||
@SuppressWarnings({"UnusedReturnValue", "UnnecessaryInterfaceModifier"})
|
||||
public boolean invokeTick();
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package org.popcraft.chunky.mixin;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.server.world.ChunkHolder;
|
||||
import net.minecraft.server.world.ThreadedAnvilChunkStorage;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@SuppressWarnings("UnnecessaryInterfaceModifier")
|
||||
@Mixin(ThreadedAnvilChunkStorage.class)
|
||||
public interface ThreadedAnvilChunkStorageMixin {
|
||||
@Invoker("getChunkHolder")
|
||||
public ChunkHolder invokeGetChunkHolder(long pos);
|
||||
|
||||
@Invoker("getUpdatedChunkNbt")
|
||||
public CompletableFuture<Optional<NbtCompound>> invokeGetUpdatedChunkNbt(ChunkPos pos);
|
||||
|
||||
@Accessor("chunksToUnload")
|
||||
public Long2ObjectLinkedOpenHashMap<ChunkHolder> getChunksToUnload();
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package org.popcraft.chunky.platform;
|
||||
|
||||
import net.minecraft.world.border.WorldBorder;
|
||||
import org.popcraft.chunky.platform.util.Vector2;
|
||||
import org.popcraft.chunky.shape.ShapeType;
|
||||
|
||||
public class FabricBorder implements Border {
|
||||
private final WorldBorder worldBorder;
|
||||
|
||||
public FabricBorder(final WorldBorder worldBorder) {
|
||||
this.worldBorder = worldBorder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2 getCenter() {
|
||||
return Vector2.of(worldBorder.getCenterX(), worldBorder.getCenterZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getRadiusX() {
|
||||
return worldBorder.getSize() / 2d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getRadiusZ() {
|
||||
return worldBorder.getSize() / 2d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getShape() {
|
||||
return ShapeType.SQUARE;
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package org.popcraft.chunky.platform;
|
||||
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import org.popcraft.chunky.platform.util.Location;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.popcraft.chunky.util.Translator.translateKey;
|
||||
|
||||
public class FabricPlayer extends FabricSender implements Player {
|
||||
private final ServerPlayerEntity player;
|
||||
|
||||
public FabricPlayer(final ServerPlayerEntity player) {
|
||||
super(player.getCommandSource());
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlayer() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return player.getName().getString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld() {
|
||||
return new FabricWorld(player.getWorld());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
return new Location(getWorld(), player.getX(), player.getY(), player.getZ(), player.getYaw(), player.getPitch());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(final String key, final boolean prefixed, final Object... args) {
|
||||
player.sendMessage(formatColored(translateKey(key, prefixed, args)), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUUID() {
|
||||
return player.getUuid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleport(final Location location) {
|
||||
player.teleport(((FabricWorld) location.getWorld()).getServerWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendActionBar(final String key) {
|
||||
player.sendMessage(formatColored(translateKey(key, false)), true);
|
||||
}
|
||||
|
||||
private Text formatColored(final String message) {
|
||||
return Text.of(message.replaceAll("&(?=[0-9a-fk-orA-FK-OR])", "§"));
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package org.popcraft.chunky.platform;
|
||||
|
||||
import me.lucko.fabric.api.permissions.v0.Permissions;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.math.Position;
|
||||
import net.minecraft.util.math.Vec2f;
|
||||
import org.popcraft.chunky.platform.util.Location;
|
||||
|
||||
import static org.popcraft.chunky.util.Translator.translateKey;
|
||||
|
||||
public class FabricSender implements Sender {
|
||||
private final ServerCommandSource source;
|
||||
|
||||
public FabricSender(final ServerCommandSource source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlayer() {
|
||||
return source.getEntity() instanceof ServerPlayerEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return source.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld() {
|
||||
return new FabricWorld(source.getWorld());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
final Position pos = source.getPosition();
|
||||
final Vec2f rotation = source.getRotation();
|
||||
return new Location(getWorld(), pos.getX(), pos.getY(), pos.getZ(), rotation.x, rotation.y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(final String permission) {
|
||||
try {
|
||||
Class.forName("me.lucko.fabric.api.permissions.v0.Permissions");
|
||||
return Permissions.check(source, permission, false);
|
||||
} catch (final ClassNotFoundException e) {
|
||||
return source.hasPermissionLevel(2);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(final String key, final boolean prefixed, final Object... args) {
|
||||
source.sendFeedback(Text.of(translateKey(key, prefixed, args).replaceAll("&[0-9a-fk-orA-FK-OR]", "")), false);
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package org.popcraft.chunky.platform;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import org.popcraft.chunky.ChunkyFabric;
|
||||
import org.popcraft.chunky.integration.Integration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class FabricServer implements Server {
|
||||
private final ChunkyFabric plugin;
|
||||
private final MinecraftServer server;
|
||||
|
||||
public FabricServer(final ChunkyFabric plugin, final MinecraftServer server) {
|
||||
this.plugin = plugin;
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Integration> getIntegrations() {
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<World> getWorld(final String name) {
|
||||
return Optional.ofNullable(Identifier.tryParse(name))
|
||||
.map(worldIdentifier -> server.getWorld(RegistryKey.of(Registry.WORLD_KEY, worldIdentifier)))
|
||||
.map(FabricWorld::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<World> getWorlds() {
|
||||
final List<World> worlds = new ArrayList<>();
|
||||
server.getWorlds().forEach(world -> worlds.add(new FabricWorld(world)));
|
||||
return worlds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sender getConsole() {
|
||||
return new FabricSender(server.getCommandSource());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Player> getPlayers() {
|
||||
return server.getPlayerManager().getPlayerList().stream().map(FabricPlayer::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Player> getPlayer(final String name) {
|
||||
return Optional.ofNullable(server.getPlayerManager().getPlayer(name)).map(FabricPlayer::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Config getConfig() {
|
||||
return plugin.getChunky().getConfig();
|
||||
}
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
package org.popcraft.chunky.platform;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.server.world.ChunkHolder;
|
||||
import net.minecraft.server.world.ChunkTicketType;
|
||||
import net.minecraft.server.world.ServerChunkManager;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.server.world.ThreadedAnvilChunkStorage;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.util.WorldSavePath;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.Heightmap;
|
||||
import net.minecraft.world.chunk.ChunkStatus;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import org.popcraft.chunky.mixin.ServerChunkManagerMixin;
|
||||
import org.popcraft.chunky.mixin.ThreadedAnvilChunkStorageMixin;
|
||||
import org.popcraft.chunky.platform.util.Location;
|
||||
import org.popcraft.chunky.util.Input;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class FabricWorld implements World {
|
||||
private static final ChunkTicketType<Unit> CHUNKY = ChunkTicketType.create("chunky", (unit, unit2) -> 0);
|
||||
private final ServerWorld serverWorld;
|
||||
private final Border worldBorder;
|
||||
|
||||
public FabricWorld(final ServerWorld serverWorld) {
|
||||
this.serverWorld = serverWorld;
|
||||
this.worldBorder = new FabricBorder(serverWorld.getWorldBorder());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return serverWorld.getRegistryKey().getValue().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkGenerated(final int x, final int z) {
|
||||
if (Thread.currentThread() != serverWorld.getServer().getThread()) {
|
||||
return CompletableFuture.supplyAsync(() -> isChunkGenerated(x, z), serverWorld.getServer()).join();
|
||||
} else {
|
||||
final ChunkPos chunkPos = new ChunkPos(x, z);
|
||||
final ThreadedAnvilChunkStorage chunkStorage = serverWorld.getChunkManager().threadedAnvilChunkStorage;
|
||||
final ThreadedAnvilChunkStorageMixin chunkStorageMixin = (ThreadedAnvilChunkStorageMixin) chunkStorage;
|
||||
final ChunkHolder loadedChunkHolder = chunkStorageMixin.invokeGetChunkHolder(chunkPos.toLong());
|
||||
if (loadedChunkHolder != null && loadedChunkHolder.getCurrentStatus() == ChunkStatus.FULL) {
|
||||
return true;
|
||||
}
|
||||
final ChunkHolder unloadedChunkHolder = chunkStorageMixin.getChunksToUnload().get(chunkPos.toLong());
|
||||
if (unloadedChunkHolder != null && unloadedChunkHolder.getCurrentStatus() == ChunkStatus.FULL) {
|
||||
return true;
|
||||
}
|
||||
return chunkStorageMixin.invokeGetUpdatedChunkNbt(chunkPos).join().map(chunkNbt -> chunkNbt.contains("Status", 8) && "full".equals(chunkNbt.getString("Status"))).orElse(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> getChunkAtAsync(final int x, final int z) {
|
||||
if (Thread.currentThread() != serverWorld.getServer().getThread()) {
|
||||
return CompletableFuture.supplyAsync(() -> getChunkAtAsync(x, z), serverWorld.getServer()).join();
|
||||
} else {
|
||||
final ChunkPos chunkPos = new ChunkPos(x, z);
|
||||
final ServerChunkManager serverChunkManager = serverWorld.getChunkManager();
|
||||
serverChunkManager.addTicket(CHUNKY, chunkPos, 0, Unit.INSTANCE);
|
||||
((ServerChunkManagerMixin) serverChunkManager).invokeTick();
|
||||
final ThreadedAnvilChunkStorage threadedAnvilChunkStorage = serverChunkManager.threadedAnvilChunkStorage;
|
||||
final ThreadedAnvilChunkStorageMixin threadedAnvilChunkStorageMixin = (ThreadedAnvilChunkStorageMixin) threadedAnvilChunkStorage;
|
||||
final ChunkHolder chunkHolder = threadedAnvilChunkStorageMixin.invokeGetChunkHolder(chunkPos.toLong());
|
||||
final CompletableFuture<Void> chunkFuture = chunkHolder == null ? CompletableFuture.completedFuture(null) : CompletableFuture.allOf(chunkHolder.getChunkAt(ChunkStatus.FULL, threadedAnvilChunkStorage));
|
||||
chunkFuture.whenCompleteAsync((ignored, throwable) -> serverChunkManager.removeTicket(CHUNKY, chunkPos, 0, Unit.INSTANCE), serverWorld.getServer());
|
||||
return chunkFuture;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUUID() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSeaLevel() {
|
||||
return serverWorld.getSeaLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getSpawn() {
|
||||
final BlockPos pos = serverWorld.getSpawnPos();
|
||||
final float angle = serverWorld.getSpawnAngle();
|
||||
return new Location(this, pos.getX(), pos.getY(), pos.getZ(), angle, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Border getWorldBorder() {
|
||||
return worldBorder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getElevation(final int x, final int z) {
|
||||
final int height = serverWorld.getChunk(x >> 4, z >> 4).sampleHeightmap(Heightmap.Type.MOTION_BLOCKING, x, z) + 1;
|
||||
final int logicalHeight = serverWorld.getLogicalHeight();
|
||||
if (height >= logicalHeight) {
|
||||
BlockPos.Mutable pos = new BlockPos.Mutable(x, logicalHeight, z);
|
||||
int air = 0;
|
||||
while (pos.getY() > serverWorld.getBottomY()) {
|
||||
pos = pos.move(Direction.DOWN);
|
||||
final BlockState blockState = serverWorld.getBlockState(pos);
|
||||
if (blockState.getMaterial().isSolid() && air > 1) {
|
||||
return pos.getY() + 1;
|
||||
}
|
||||
air = blockState.isAir() ? air + 1 : 0;
|
||||
}
|
||||
}
|
||||
return height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxElevation() {
|
||||
return serverWorld.getLogicalHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playEffect(final Player player, final String effect) {
|
||||
final Location location = player.getLocation();
|
||||
final BlockPos pos = new BlockPos(location.getX(), location.getY(), location.getZ());
|
||||
Input.tryInteger(effect).ifPresent(eventId -> serverWorld.syncWorldEvent(null, eventId, pos, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playSound(final Player player, final String sound) {
|
||||
final Location location = player.getLocation();
|
||||
Registry.SOUND_EVENT.getOrEmpty(Identifier.tryParse(sound)).ifPresent(soundEvent -> serverWorld.playSound(null, location.getX(), location.getY(), location.getZ(), soundEvent, SoundCategory.MASTER, 2f, 1f));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Path> getDirectory(final String name) {
|
||||
if (name == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
final Path directory = DimensionType.getSaveDirectory(serverWorld.getRegistryKey(), serverWorld.getServer().getSavePath(WorldSavePath.ROOT)).normalize().resolve(name);
|
||||
return Files.exists(directory) ? Optional.of(directory) : Optional.empty();
|
||||
}
|
||||
|
||||
public ServerWorld getServerWorld() {
|
||||
return serverWorld;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 56 KiB |
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "org.popcraft.chunky.mixin",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"mixins": [
|
||||
"ServerChunkManagerMixin",
|
||||
"ThreadedAnvilChunkStorageMixin"
|
||||
],
|
||||
"client": [
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "${id}",
|
||||
"version": "${version}",
|
||||
"name": "${name}",
|
||||
"description": "${description}",
|
||||
"authors": [
|
||||
"${author}"
|
||||
],
|
||||
"contact": {
|
||||
"website": "https://www.curseforge.com/minecraft/mc-mods/chunky-pregenerator",
|
||||
"homepage": "https://www.curseforge.com/minecraft/mc-mods/chunky-pregenerator",
|
||||
"repo": "${github}",
|
||||
"sources": "${github}",
|
||||
"issues": "${github}/issues"
|
||||
},
|
||||
"license": "GPLv3",
|
||||
"icon": "assets/chunky/icon.png",
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"org.popcraft.chunky.ChunkyFabric"
|
||||
]
|
||||
},
|
||||
"mixins": [
|
||||
"chunky.mixins.json"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.14.6",
|
||||
"fabric": "*",
|
||||
"minecraft": ">=1.19",
|
||||
"java": ">=17"
|
||||
},
|
||||
"custom": {
|
||||
"modmenu": {
|
||||
"links": {
|
||||
"modmenu.discord": "https://discord.gg/ZwVJukcNQG"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
repositories {
|
||||
maven("https://repo.papermc.io/repository/maven-public/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(group = "dev.folia", name = "folia-api", version = "1.20.2-R0.1-SNAPSHOT")
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.popcraft.chunky.platform;
|
||||
|
||||
import io.papermc.paper.threadedregions.RegionizedServerInitEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public final class Folia {
|
||||
private static final boolean CONFIG_EXISTS = classExists("io.papermc.paper.threadedregions.RegionizedServer") || classExists("io.papermc.paper.threadedregions.RegionizedServerInitEvent");
|
||||
|
||||
private Folia() {
|
||||
}
|
||||
|
||||
public static boolean isFolia() {
|
||||
return CONFIG_EXISTS;
|
||||
}
|
||||
|
||||
public static void schedule(final Plugin plugin, final Location location, final Runnable runnable) {
|
||||
Bukkit.getServer().getRegionScheduler().execute(plugin, location, runnable);
|
||||
}
|
||||
|
||||
public static void scheduleFixed(final Plugin plugin, final Location location, final Runnable runnable, final long delay, final long period) {
|
||||
Bukkit.getServer().getRegionScheduler().runAtFixedRate(plugin, location, ignored -> runnable.run(), delay, period);
|
||||
}
|
||||
|
||||
public static void scheduleFixedGlobal(final Plugin plugin, final Runnable runnable, final long delay, final long period) {
|
||||
Bukkit.getServer().getGlobalRegionScheduler().runAtFixedRate(plugin, ignored -> runnable.run(), delay, period);
|
||||
}
|
||||
|
||||
public static void cancelTasks(final Plugin plugin) {
|
||||
Bukkit.getServer().getGlobalRegionScheduler().cancelTasks(plugin);
|
||||
}
|
||||
|
||||
public static void onServerInit(final Plugin plugin, final Runnable runnable) {
|
||||
Bukkit.getPluginManager().registerEvents(new Listener() {
|
||||
@EventHandler
|
||||
public void onRegionisedServerInit(final RegionizedServerInitEvent event) {
|
||||
runnable.run();
|
||||
}
|
||||
}, plugin);
|
||||
}
|
||||
|
||||
private static boolean classExists(final String clazz) {
|
||||
try {
|
||||
Class.forName(clazz);
|
||||
return true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
plugins {
|
||||
id("dev.architectury.loom") version "0.12.0-SNAPSHOT"
|
||||
}
|
||||
|
||||
val shade: Configuration by configurations.creating
|
||||
|
||||
dependencies {
|
||||
minecraft(group = "com.mojang", name = "minecraft", version = "1.19")
|
||||
mappings(loom.officialMojangMappings())
|
||||
forge(group = "net.minecraftforge", name = "forge", version = "1.19-41.0.5")
|
||||
implementation(project(":chunky-common"))
|
||||
shade(project(":chunky-common"))
|
||||
}
|
||||
|
||||
tasks {
|
||||
processResources {
|
||||
filesMatching("META-INF/mods.toml") {
|
||||
expand(
|
||||
"github" to project.property("github"),
|
||||
"id" to rootProject.name,
|
||||
"version" to project.version,
|
||||
"name" to rootProject.name.capitalize(),
|
||||
"author" to project.property("author"),
|
||||
"description" to project.property("description")
|
||||
)
|
||||
}
|
||||
}
|
||||
jar {
|
||||
manifest {
|
||||
attributes(
|
||||
mapOf(
|
||||
"Implementation-Title" to rootProject.name,
|
||||
"Implementation-Version" to project.version,
|
||||
"Implementation-Vendor" to project.property("author")
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
shadowJar {
|
||||
configurations = listOf(shade)
|
||||
archiveClassifier.set("dev")
|
||||
archiveFileName.set(null as String?)
|
||||
}
|
||||
remapJar {
|
||||
inputFile.set(shadowJar.get().archiveFile)
|
||||
archiveFileName.set("${rootProject.name.capitalize()}-${project.version}.jar")
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
loom.platform=forge
|
||||
@@ -1,147 +0,0 @@
|
||||
package org.popcraft.chunky;
|
||||
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.builder.ArgumentBuilder;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.server.ServerStartingEvent;
|
||||
import net.minecraftforge.event.server.ServerStoppingEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.loading.FMLPaths;
|
||||
import org.popcraft.chunky.command.ChunkyCommand;
|
||||
import org.popcraft.chunky.command.CommandArguments;
|
||||
import org.popcraft.chunky.command.CommandLiteral;
|
||||
import org.popcraft.chunky.command.suggestion.SuggestionProviders;
|
||||
import org.popcraft.chunky.event.task.GenerationTaskFinishEvent;
|
||||
import org.popcraft.chunky.event.task.GenerationTaskUpdateEvent;
|
||||
import org.popcraft.chunky.listeners.bossbar.BossBarTaskFinishListener;
|
||||
import org.popcraft.chunky.listeners.bossbar.BossBarTaskUpdateListener;
|
||||
import org.popcraft.chunky.platform.ForgePlayer;
|
||||
import org.popcraft.chunky.platform.ForgeSender;
|
||||
import org.popcraft.chunky.platform.ForgeServer;
|
||||
import org.popcraft.chunky.platform.Sender;
|
||||
import org.popcraft.chunky.platform.impl.GsonConfig;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
||||
import static com.mojang.brigadier.arguments.StringArgumentType.string;
|
||||
import static com.mojang.brigadier.arguments.StringArgumentType.word;
|
||||
import static net.minecraft.commands.Commands.argument;
|
||||
import static net.minecraft.commands.Commands.literal;
|
||||
import static net.minecraft.commands.arguments.DimensionArgument.dimension;
|
||||
|
||||
@Mod(ChunkyForge.MOD_ID)
|
||||
public class ChunkyForge {
|
||||
public static final String MOD_ID = "chunky";
|
||||
private Chunky chunky;
|
||||
|
||||
public ChunkyForge() {
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onServerStarting(final ServerStartingEvent event) {
|
||||
final MinecraftServer server = event.getServer();
|
||||
final Path configPath = FMLPaths.CONFIGDIR.get().resolve("chunky/config.json");
|
||||
this.chunky = new Chunky(new ForgeServer(this, server), new GsonConfig(configPath));
|
||||
if (chunky.getConfig().getContinueOnRestart()) {
|
||||
chunky.getCommands().get(CommandLiteral.CONTINUE).execute(chunky.getServer().getConsole(), CommandArguments.empty());
|
||||
}
|
||||
chunky.getEventBus().subscribe(GenerationTaskUpdateEvent.class, new BossBarTaskUpdateListener());
|
||||
chunky.getEventBus().subscribe(GenerationTaskFinishEvent.class, new BossBarTaskFinishListener());
|
||||
final LiteralArgumentBuilder<CommandSourceStack> command = literal(CommandLiteral.CHUNKY)
|
||||
.requires(serverCommandSource -> serverCommandSource.hasPermission(2))
|
||||
.executes(context -> {
|
||||
final Sender sender;
|
||||
if (context.getSource().getEntity() instanceof final ServerPlayer player) {
|
||||
sender = new ForgePlayer(player);
|
||||
} else {
|
||||
sender = new ForgeSender(context.getSource());
|
||||
}
|
||||
final Map<String, ChunkyCommand> commands = chunky.getCommands();
|
||||
final String input = context.getInput().substring(context.getLastChild().getNodes().get(0).getRange().getStart());
|
||||
final String[] tokens = input.split(" ");
|
||||
final String subCommand = tokens.length > 1 && commands.containsKey(tokens[1]) ? tokens[1] : CommandLiteral.HELP;
|
||||
final CommandArguments arguments = tokens.length > 2 ? CommandArguments.of(Arrays.copyOfRange(tokens, 2, tokens.length)) : CommandArguments.empty();
|
||||
commands.get(subCommand).execute(sender, arguments);
|
||||
return Command.SINGLE_SUCCESS;
|
||||
});
|
||||
registerArguments(command, literal(CommandLiteral.CANCEL),
|
||||
argument(CommandLiteral.WORLD, dimension()));
|
||||
registerArguments(command, literal(CommandLiteral.CENTER),
|
||||
argument(CommandLiteral.X, word()),
|
||||
argument(CommandLiteral.Z, word()));
|
||||
registerArguments(command, literal(CommandLiteral.CONFIRM));
|
||||
registerArguments(command, literal(CommandLiteral.CONTINUE),
|
||||
argument(CommandLiteral.WORLD, dimension()));
|
||||
registerArguments(command, literal(CommandLiteral.CORNERS),
|
||||
argument(CommandLiteral.X1, word()),
|
||||
argument(CommandLiteral.Z1, word()),
|
||||
argument(CommandLiteral.X2, word()),
|
||||
argument(CommandLiteral.Z2, word()));
|
||||
registerArguments(command, literal(CommandLiteral.HELP),
|
||||
argument(CommandLiteral.PAGE, integer()));
|
||||
registerArguments(command, literal(CommandLiteral.PATTERN),
|
||||
argument(CommandLiteral.PATTERN, string()).suggests(SuggestionProviders.PATTERNS),
|
||||
argument(CommandLiteral.VALUE, string()));
|
||||
registerArguments(command, literal(CommandLiteral.PAUSE),
|
||||
argument(CommandLiteral.WORLD, dimension()));
|
||||
registerArguments(command, literal(CommandLiteral.PROGRESS));
|
||||
registerArguments(command, literal(CommandLiteral.QUIET),
|
||||
argument(CommandLiteral.INTERVAL, integer()));
|
||||
registerArguments(command, literal(CommandLiteral.RADIUS),
|
||||
argument(CommandLiteral.RADIUS, word()),
|
||||
argument(CommandLiteral.RADIUS, word()));
|
||||
registerArguments(command, literal(CommandLiteral.RELOAD),
|
||||
argument(CommandLiteral.TYPE, word()));
|
||||
registerArguments(command, literal(CommandLiteral.SELECTION));
|
||||
registerArguments(command, literal(CommandLiteral.SHAPE),
|
||||
argument(CommandLiteral.SHAPE, string()).suggests(SuggestionProviders.SHAPES));
|
||||
registerArguments(command, literal(CommandLiteral.SILENT));
|
||||
registerArguments(command, literal(CommandLiteral.SPAWN));
|
||||
registerArguments(command, literal(CommandLiteral.START),
|
||||
argument(CommandLiteral.WORLD, dimension()),
|
||||
argument(CommandLiteral.SHAPE, string()).suggests(SuggestionProviders.SHAPES),
|
||||
argument(CommandLiteral.CENTER_X, word()),
|
||||
argument(CommandLiteral.CENTER_Z, word()),
|
||||
argument(CommandLiteral.RADIUS_X, word()),
|
||||
argument(CommandLiteral.RADIUS_Z, word()));
|
||||
registerArguments(command, literal(CommandLiteral.TRIM),
|
||||
argument(CommandLiteral.WORLD, dimension()),
|
||||
argument(CommandLiteral.SHAPE, string()).suggests(SuggestionProviders.SHAPES),
|
||||
argument(CommandLiteral.CENTER_X, word()),
|
||||
argument(CommandLiteral.CENTER_Z, word()),
|
||||
argument(CommandLiteral.RADIUS_X, word()),
|
||||
argument(CommandLiteral.RADIUS_Z, word()));
|
||||
registerArguments(command, literal(CommandLiteral.WORLDBORDER));
|
||||
registerArguments(command, literal(CommandLiteral.WORLD),
|
||||
argument(CommandLiteral.WORLD, dimension()));
|
||||
server.getCommands().getDispatcher().register(command);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private <S> void registerArguments(final LiteralArgumentBuilder<S> command, final ArgumentBuilder<S, ?>... arguments) {
|
||||
for (int i = arguments.length - 1; i > 0; --i) {
|
||||
arguments[i - 1].then(arguments[i].executes(command.getCommand()));
|
||||
}
|
||||
command.then(arguments[0].executes(command.getCommand()));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onServerStopping(final ServerStoppingEvent event) {
|
||||
if (chunky != null) {
|
||||
chunky.disable();
|
||||
}
|
||||
}
|
||||
|
||||
public Chunky getChunky() {
|
||||
return chunky;
|
||||
}
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
package org.popcraft.chunky.command.suggestion;
|
||||
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.suggestion.SuggestionProvider;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import org.popcraft.chunky.command.CommandLiteral;
|
||||
import org.popcraft.chunky.iterator.PatternType;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class PatternSuggestionProvider implements SuggestionProvider<CommandSourceStack> {
|
||||
@Override
|
||||
public CompletableFuture<Suggestions> getSuggestions(final CommandContext<CommandSourceStack> context, final SuggestionsBuilder builder) {
|
||||
try {
|
||||
final String input = context.getArgument(CommandLiteral.PATTERN, String.class);
|
||||
PatternType.ALL.forEach(pattern -> {
|
||||
if (pattern.contains(input.toLowerCase())) {
|
||||
builder.suggest(pattern);
|
||||
}
|
||||
});
|
||||
} catch (IllegalArgumentException e) {
|
||||
PatternType.ALL.forEach(builder::suggest);
|
||||
}
|
||||
return builder.buildFuture();
|
||||
}
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
package org.popcraft.chunky.command.suggestion;
|
||||
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.suggestion.SuggestionProvider;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import org.popcraft.chunky.command.CommandLiteral;
|
||||
import org.popcraft.chunky.shape.ShapeType;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class ShapeSuggestionProvider implements SuggestionProvider<CommandSourceStack> {
|
||||
@Override
|
||||
public CompletableFuture<Suggestions> getSuggestions(final CommandContext<CommandSourceStack> context, final SuggestionsBuilder builder) {
|
||||
try {
|
||||
final String input = context.getArgument(CommandLiteral.SHAPE, String.class);
|
||||
ShapeType.ALL.forEach(shape -> {
|
||||
if (shape.contains(input.toLowerCase())) {
|
||||
builder.suggest(shape);
|
||||
}
|
||||
});
|
||||
} catch (IllegalArgumentException e) {
|
||||
ShapeType.ALL.forEach(builder::suggest);
|
||||
}
|
||||
return builder.buildFuture();
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package org.popcraft.chunky.command.suggestion;
|
||||
|
||||
import com.mojang.brigadier.suggestion.SuggestionProvider;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
|
||||
public final class SuggestionProviders {
|
||||
public static final SuggestionProvider<CommandSourceStack> PATTERNS;
|
||||
public static final SuggestionProvider<CommandSourceStack> SHAPES;
|
||||
|
||||
static {
|
||||
PATTERNS = new PatternSuggestionProvider();
|
||||
SHAPES = new ShapeSuggestionProvider();
|
||||
}
|
||||
|
||||
private SuggestionProviders() {
|
||||
}
|
||||
}
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
package org.popcraft.chunky.listeners.bossbar;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.bossevents.CustomBossEvent;
|
||||
import net.minecraft.server.bossevents.CustomBossEvents;
|
||||
import org.popcraft.chunky.GenerationTask;
|
||||
import org.popcraft.chunky.event.task.GenerationTaskFinishEvent;
|
||||
import org.popcraft.chunky.platform.ForgeWorld;
|
||||
import org.popcraft.chunky.platform.World;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class BossBarTaskFinishListener implements Consumer<GenerationTaskFinishEvent> {
|
||||
@Override
|
||||
public void accept(final GenerationTaskFinishEvent event) {
|
||||
final GenerationTask task = event.generationTask();
|
||||
final World world = task.getSelection().world();
|
||||
final ResourceLocation worldIdentifier = ResourceLocation.tryParse(world.getKey());
|
||||
final ResourceLocation barIdentifier = ResourceLocation.tryParse("chunky:progress_" + world.getKey().replace(':', '_'));
|
||||
if (worldIdentifier == null || barIdentifier == null || !(world instanceof ForgeWorld)) {
|
||||
return;
|
||||
}
|
||||
final MinecraftServer server = ((ForgeWorld) world).getWorld().getServer();
|
||||
final CustomBossEvents bossBarManager = server.getCustomBossEvents();
|
||||
final CustomBossEvent existingBossBar = bossBarManager.get(barIdentifier);
|
||||
if (existingBossBar != null) {
|
||||
existingBossBar.removeAllPlayers();
|
||||
bossBarManager.remove(existingBossBar);
|
||||
}
|
||||
}
|
||||
}
|
||||
-72
@@ -1,72 +0,0 @@
|
||||
package org.popcraft.chunky.listeners.bossbar;
|
||||
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.bossevents.CustomBossEvent;
|
||||
import net.minecraft.server.bossevents.CustomBossEvents;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.BossEvent;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.popcraft.chunky.Chunky;
|
||||
import org.popcraft.chunky.GenerationTask;
|
||||
import org.popcraft.chunky.event.task.GenerationTaskUpdateEvent;
|
||||
import org.popcraft.chunky.platform.ForgeWorld;
|
||||
import org.popcraft.chunky.platform.World;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class BossBarTaskUpdateListener implements Consumer<GenerationTaskUpdateEvent> {
|
||||
@Override
|
||||
public void accept(final GenerationTaskUpdateEvent event) {
|
||||
final GenerationTask task = event.generationTask();
|
||||
final Chunky chunky = task.getChunky();
|
||||
final World world = task.getSelection().world();
|
||||
final ResourceLocation worldIdentifier = ResourceLocation.tryParse(world.getKey());
|
||||
final ResourceLocation barIdentifier = ResourceLocation.tryParse("chunky:progress_" + world.getKey().replace(':', '_'));
|
||||
if (worldIdentifier == null || barIdentifier == null || !(world instanceof ForgeWorld)) {
|
||||
return;
|
||||
}
|
||||
final MinecraftServer server = ((ForgeWorld) world).getWorld().getServer();
|
||||
final CustomBossEvents bossBarManager = server.getCustomBossEvents();
|
||||
final CustomBossEvent existingBossBar = bossBarManager.get(barIdentifier);
|
||||
final CustomBossEvent bossBar = existingBossBar == null ? createNewBossBar(bossBarManager, barIdentifier, worldIdentifier) : existingBossBar;
|
||||
final boolean silent = chunky.getConfig().isSilent();
|
||||
if (silent == bossBar.isVisible()) {
|
||||
bossBar.setVisible(!silent);
|
||||
}
|
||||
for (final ServerPlayer player : server.getPlayerList().getPlayers()) {
|
||||
if (player.hasPermissions(2)) {
|
||||
bossBar.addPlayer(player);
|
||||
} else {
|
||||
bossBar.removePlayer(player);
|
||||
}
|
||||
}
|
||||
final GenerationTask.Progress progress = task.getProgress();
|
||||
bossBar.setName(Component.nullToEmpty(String.format("%s | %s%% | %s:%s:%s",
|
||||
worldIdentifier,
|
||||
String.format("%.2f", progress.getPercentComplete()),
|
||||
String.format("%01d", progress.getHours()),
|
||||
String.format("%02d", progress.getMinutes()),
|
||||
String.format("%02d", progress.getSeconds()))));
|
||||
bossBar.setProgress(task.getProgress().getPercentComplete() / 100f);
|
||||
if (progress.isComplete()) {
|
||||
bossBar.removeAllPlayers();
|
||||
bossBarManager.remove(bossBar);
|
||||
}
|
||||
}
|
||||
|
||||
private CustomBossEvent createNewBossBar(final CustomBossEvents bossBarManager, final ResourceLocation barIdentifier, final ResourceLocation worldIdentifier) {
|
||||
final CustomBossEvent bossBar = bossBarManager.create(barIdentifier, Component.nullToEmpty(barIdentifier.toString()));
|
||||
if (Level.OVERWORLD.location().equals(worldIdentifier)) {
|
||||
bossBar.setColor(BossEvent.BossBarColor.GREEN);
|
||||
} else if (Level.NETHER.location().equals(worldIdentifier)) {
|
||||
bossBar.setColor(BossEvent.BossBarColor.RED);
|
||||
} else if (Level.END.location().equals(worldIdentifier)) {
|
||||
bossBar.setColor(BossEvent.BossBarColor.PURPLE);
|
||||
} else {
|
||||
bossBar.setColor(BossEvent.BossBarColor.BLUE);
|
||||
}
|
||||
return bossBar;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package org.popcraft.chunky.platform;
|
||||
|
||||
import net.minecraft.world.level.border.WorldBorder;
|
||||
import org.popcraft.chunky.platform.util.Vector2;
|
||||
import org.popcraft.chunky.shape.ShapeType;
|
||||
|
||||
public class ForgeBorder implements Border {
|
||||
private final WorldBorder worldBorder;
|
||||
|
||||
public ForgeBorder(final WorldBorder worldBorder) {
|
||||
this.worldBorder = worldBorder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2 getCenter() {
|
||||
return Vector2.of(worldBorder.getCenterX(), worldBorder.getCenterZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getRadiusX() {
|
||||
return worldBorder.getSize() / 2d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getRadiusZ() {
|
||||
return worldBorder.getSize() / 2d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getShape() {
|
||||
return ShapeType.SQUARE;
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package org.popcraft.chunky.platform;
|
||||
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.popcraft.chunky.platform.util.Location;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.popcraft.chunky.util.Translator.translateKey;
|
||||
|
||||
public class ForgePlayer extends ForgeSender implements Player {
|
||||
private final ServerPlayer player;
|
||||
|
||||
public ForgePlayer(final ServerPlayer player) {
|
||||
super(player.createCommandSourceStack());
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlayer() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return player.getName().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld() {
|
||||
return new ForgeWorld(player.getLevel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
return new Location(getWorld(), player.getX(), player.getY(), player.getZ(), player.getXRot(), player.getYRot());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(final String key, final boolean prefixed, final Object... args) {
|
||||
player.sendSystemMessage(formatColored(translateKey(key, prefixed, args)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUUID() {
|
||||
return player.getUUID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleport(final Location location) {
|
||||
player.teleportTo(((ForgeWorld) location.getWorld()).getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendActionBar(final String key) {
|
||||
player.displayClientMessage(formatColored(translateKey(key, false)), true);
|
||||
}
|
||||
|
||||
private Component formatColored(final String message) {
|
||||
return Component.nullToEmpty(message.replaceAll("&(?=[0-9a-fk-orA-FK-OR])", "§"));
|
||||
}
|
||||
}
|
||||
Loaded 100 of 148 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user