116 Commits
Author SHA1 Message Date
NotAlexNoyle 9f8bf11660 Exclude CODEOWNERS from language statistics 2026-10-29 16:18:54 -04:00
NotAlexNoyle f8dcf33fcb Add CODEOWNERS (one staff approval) 2026-10-29 16:18:54 -04:00
NotAlexNoyle 116976d8e8 Merge branch 'master' of github.com:true-og/Chunky 2026-06-17 06:47:56 -04:00
NotAlexNoyle 800a4fa743 Update config 2026-06-17 06:47:36 -04:00
NotAlexNoyle 3124d52e3b Merge pull request #2 from true-og/codex/fix-runtime-error-in-gradle-jar-build
Fix Bukkit plugin main class relocation in shaded JAR
2026-03-13 13:42:30 -04:00
NotAlexNoyle b973781649 Fix Bukkit shadowJar relocation for plugin main class 2026-03-13 13:42:19 -04:00
NotAlexNoyle 107bb79474 Merge pull request #1 from true-og/codex/fix-jar-build-for-minecraft-plugin
Produce shaded Bukkit plugin jar for Purpur 1.19.4 and bundle/relocate dependencies
2026-03-13 09:42:12 -04:00
NotAlexNoyle f35cb20714 Fix Bukkit plugin packaging and Purpur target 2026-03-13 09:40:54 -04:00
NotAlexNoyle aab04df0b6 Update gradle to 8.14.3 2025-09-17 10:24:14 -04:00
NotAlexNoyle eda3874ba7 Remove unneeded subprojects 2025-06-11 15:31:36 -04:00
NotAlexNoyle 609fea09f6 Fix build 2024-12-08 14:07:26 -05:00
pop4959 d3956d688b New Crowdin updates (#330) 2024-04-13 23:49:49 -07:00
citylion e46c1c3abe Add Hexagon shape (#329) 2024-04-13 23:22:44 -07:00
pop4959 ca668d2434 New Crowdin updates (#328) 2024-04-13 21:37:03 -07:00
pop4959 af621921e9 New Crowdin updates (#326) 2024-03-19 23:34:46 -07:00
Christopher Bohn 9f165e647d Don't wait for server thread when dispatching tasks (Forge) 2024-02-24 11:58:35 -08:00
ishland 4cff7a4711 Don't wait for server thread when dispatching tasks (#322) 2024-02-24 11:00:53 -08:00
Christopher Bohn a60f083e08 Send trim updates to console 2024-02-20 13:07:17 -08:00
Christopher Bohn 74f6ab4866 Improve error handling of trim side 2024-02-20 13:01:05 -08:00
pop4959 ea68abc3cc New Crowdin updates (#318) 2024-02-16 18:14:16 -08:00
Christopher Bohn 73813786c0 Default to op when no permissions are set 2024-02-16 18:11:33 -08:00
pop4959 7b5594c196 New Crowdin updates (#312) 2024-02-12 23:55:32 -08:00
Christopher Bohn 87a13cf729 Add border command to Forge 2024-02-12 23:34:11 -08:00
Christopher Bohn 324f042f77 Update Github Actions 2024-02-07 19:45:26 -08:00
Christopher Bohn 83a9e8b8c3 Bump archloom 2024-02-05 22:02:15 -08:00
Christopher Bohn 2a58fdaf80 Implement chunk filters 2024-02-04 02:31:28 -08:00
Christopher Bohn 62c437dcc8 Support tag search 2024-02-03 22:33:55 -08:00
Christopher Bohn a2e8736c14 Handle interrupts while processing world 2024-02-03 12:10:10 -08:00
Christopher Bohn b93468e9f6 Add world iterator region progress 2024-02-03 11:45:34 -08:00
pop4959 9947f37a26 Implement new world pattern (#315) 2024-02-01 04:17:14 -08:00
Christopher Bohn ce93af7c81 Buffer decompressed chunk data 2024-01-31 02:59:04 -08:00
Christopher Bohn f132397ae6 Default to key when no translation 2024-01-31 02:56:52 -08:00
Christopher Bohn c15c600b45 Fix saving of CSV tasks 2024-01-25 23:10:46 -08:00
Christopher Bohn f59d7c4759 Revert "Adjust max working count default scaling"
This reverts commit 9e447d4a2a.
2024-01-25 23:07:56 -08:00
Christopher Bohn 76b678aec4 Add warning for world border beyond max world size 2024-01-21 18:43:16 -08:00
Christopher Bohn e51f093ce8 Adjust sample interval default values 2024-01-21 02:29:36 -08:00
Christopher Bohn 10f1478474 Make trim cancellable and add progress messages 2024-01-17 23:11:57 -08:00
Christopher Bohn 29c92a8dc8 Scan for generated chunk status 2024-01-17 21:24:54 -08:00
Christopher Bohn 9e447d4a2a Adjust max working count default scaling 2024-01-17 02:35:18 -08:00
Christopher Bohn 1726479648 Don't load region where location table is missing 2024-01-17 01:36:43 -08:00
Christopher Bohn 117c03fb46 Use server boss bars instead of command boss bars 2024-01-17 01:19:50 -08:00
Christopher Bohn 4d562aa62c Optional world argument for worldborder command 2024-01-17 00:11:12 -08:00
Christopher Bohn e398cc2d8e Add system property to await ticket removal 2024-01-16 23:19:51 -08:00
Christopher Bohn e6137925f3 Mention NeoForge in readme 2024-01-15 23:30:35 -08:00
Christopher Bohn f08fb59aa3 Add NeoForge artifact to Github Actions 2024-01-15 23:12:52 -08:00
Christopher Bohn f9429cd717 Apparently the loader version got reset 2024-01-15 23:11:09 -08:00
Christopher Bohn fc7e1b0bae NeoForge implementation 2024-01-15 22:50:51 -08:00
Christopher Bohn c833f27a92 Update platform specific gradle plugins 2024-01-15 20:36:11 -08:00
Christopher Bohn 5975a9f5f3 Find world by namespaced id path as a fallback 2024-01-15 16:37:05 -08:00
Christopher Bohn 0f65dbc19b Don't require permissions in Singleplayer mode 2024-01-14 02:26:42 -08:00
Christopher Bohn 646043cdf0 Replace magic values for tag type 2024-01-14 01:56:34 -08:00
Christopher Bohn caef3640d1 Make Bukkit world getDirectory more strict 2024-01-13 18:20:27 -08:00
Christopher Bohn fe130e8b8e Update Github Actions 2023-12-29 02:37:56 -08:00
Christopher Bohn 586a14e409 Revert Folia to latest published version 2023-12-29 01:25:17 -08:00
Christopher Bohn 213c5ce763 Update build scripts 2023-12-29 01:23:06 -08:00
Christopher Bohn cadf998c32 Add system property for sample interval 2023-11-22 18:13:53 -08:00
Christopher Bohn 886be957cd Support command permission on Fabric 2023-11-22 00:19:03 -08:00
Metriximor 580f0072e3 Improve vehicle teleporting logic (#301) 2023-11-21 23:28:53 -08:00
Emily 5079beb68e Implement isChunkGenerated on Spigot (#299) 2023-11-18 15:27:44 -08:00
Christopher Bohn f609ab4a34 Fix getting elevation on Folia 2023-11-05 20:03:42 -08:00
Christopher Bohn ee02cec5ac Remount vehicle when teleporting 2023-11-05 19:15:42 -08:00
pop4959 e2d8f7b89b New Crowdin updates (#292) 2023-11-05 16:35:26 -08:00
pop4959 f12a5a9258 New Crowdin updates (#291) 2023-09-16 15:40:25 -07:00
pop4959 709f2a5376 New Crowdin updates (#290) 2023-09-03 16:49:09 -07:00
pop4959 329937a7f7 New Crowdin updates (#277) 2023-08-13 18:04:53 -07:00
pop4959 61ca4e7bbf New Crowdin updates (#275) 2023-06-16 13:10:09 -07:00
pop4959 6edaeaa0b0 Handle POIs and entities properly when trimming with inhabited time 2023-06-16 13:06:31 -07:00
Christopher Bohn 176928cff2 Update Forge to 1.20 2023-06-09 22:35:46 -07:00
pop4959 1cdd07b2d5 New Crowdin updates (#273) 2023-06-09 18:37:49 -07:00
Christopher Bohn ebd263954a Update Fabric to 1.20 2023-06-07 18:33:04 -07:00
pop4959 b487702986 New Crowdin updates (#270) 2023-06-07 18:16:38 -07:00
Christopher Bohn 3597ec3465 Update build scripts 2023-05-29 20:51:37 -07:00
Christopher Bohn 33b6080ccd Update bStats 2023-05-29 17:27:53 -07:00
Christopher Bohn bfb30e58cc update test strings 2023-05-29 16:09:56 -07:00
Christopher Bohn 4a329e8029 add notice about inhabited time trim 2023-05-29 16:01:02 -07:00
Christopher Bohn f435293368 Register new trim arguments in Fabric/Forge 2023-05-29 14:01:46 -07:00
Christopher Bohn 3666d58e88 add another folia method 2023-05-28 16:22:54 -07:00
Christopher Bohn 38e99a8703 add some folia methods 2023-05-28 15:55:51 -07:00
Christopher Bohn 2ff6a5dddf Add missing tests 2023-05-21 17:34:44 -07:00
pop4959 b1d088bef6 New Crowdin updates (#268) 2023-05-21 17:31:16 -07:00
pop4959 c5f15db2b8 New Crowdin updates (#266) 2023-05-09 23:23:31 -07:00
Christopher Bohn 98baadfe32 Move NBT to its own module 2023-05-02 22:22:53 -07:00
pop4959 d4c0af18aa New Crowdin updates (#262) 2023-04-29 16:06:46 -07:00
Christopher Bohn 6df5aa1e1e Bump supported version ranges 2023-04-15 01:09:22 -07:00
Christopher Bohn 410ddd106f Fix usage of BlockPos on 1.19.4 2023-04-15 00:59:25 -07:00
pop4959 5d83912c3b New Crowdin updates (#259) 2023-04-14 21:29:33 -07:00
pop4959 953196facb New Crowdin updates (#257) 2023-04-06 22:23:38 -07:00
pop4959 9474b9144c New Crowdin updates (#248) 2023-03-29 19:54:08 -07:00
Christopher Bohn b347572f84 Update default iterator to regionized 2023-03-29 19:32:39 -07:00
pop4959 2a3f089861 Folia support (#256) 2023-03-29 19:18:20 -07:00
Christopher Bohn f8b7d0fba5 Fix reading chunks from non-regions 2023-03-18 01:38:01 -07:00
pop4959 96bb1ea7e2 Implement new region pattern (#253) 2023-03-14 01:26:16 -07:00
Christopher Bohn 9ee34d3983 Ensure tickets placed on main after gen 2023-03-11 21:31:42 -08:00
Christopher Bohn dbc51fbedf Improve generation pipeline 2023-03-08 23:38:52 -08:00
pop4959 0f914e461f New Crowdin updates (#247) 2023-03-04 01:15:15 -08:00
Christopher Bohn 66179d4a45 Extra trim options 2023-03-04 00:50:11 -08:00
Christopher Bohn 75640077b4 Update Paper repo URL 2023-03-02 00:45:29 -08:00
Christopher Bohn b7cbd6775b Register extended border arguments on Fabric 2023-03-01 20:52:34 -08:00
Christopher Bohn f912195a26 Add system property for ticking load duration 2023-02-01 01:15:27 -08:00
pop4959 02923bee53 New Crowdin updates (#236) 2023-02-01 01:11:58 -08:00
pop4959 bda5898a35 New Crowdin updates (#235) 2022-12-31 14:06:26 -08:00
pop4959 5eecf8b671 Use release version of PaperLib 2022-12-31 14:02:28 -08:00
pop4959 e2b76451ab Use RegisterCommandsEvent on Forge 2022-12-28 14:11:20 -08:00
pop4959 51c2dae5f9 New Crowdin updates (#233) 2022-12-28 13:23:39 -08:00
pop4959 c17ad230ca Bump required Minecraft versions 2022-12-15 17:25:53 -08:00
pop4959 b4d2748f94 New Crowdin updates (#225) 2022-12-15 01:34:23 -08:00
pop4959 6922cd49f5 Fabric/Forge updates for 1.19.3 2022-12-09 00:40:18 -08:00
pop4959 469dd57931 New Crowdin updates (#223) 2022-10-27 19:07:21 -07:00
pop4959 447c3daca0 Add Chinese Traditional to crowdin.yml 2022-10-26 22:17:45 -07:00
pop4959 cdd1d92fcb Fix error loading permissions before server start 2022-10-02 18:17:08 -07:00
Dylan Xaldin 2776307e51 Remove unused imports 2022-10-01 01:34:01 -07:00
pop4959 c25ea97301 New Crowdin updates (#217) 2022-09-25 14:08:16 -07:00
pop4959 eeaf3cccac New Crowdin updates (#216) 2022-09-22 08:16:28 -07:00
pop4959 0e0d5395b2 New Crowdin updates (#215) 2022-09-20 02:05:54 -07:00
pop4959 4e70b40e26 New translations en.json (French) (#214) 2022-09-18 18:24:29 -07:00
pop4959 0cc7d22190 Internally support custom shapes 2022-09-18 17:42:23 -07:00
148 changed files with 2519 additions and 3170 deletions

No files matched your search

+5
View File
@@ -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>
+1
View File
@@ -0,0 +1 @@
.gitea/CODEOWNERS linguist-detectable=false
+3
View File
@@ -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
View File
@@ -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"
+17
View File
@@ -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>
+1 -1
View File
@@ -2,7 +2,7 @@
![chunkylogo](https://user-images.githubusercontent.com/17698576/171119146-122497e4-7527-438b-8f8e-c1c04c2841b9.jpg)
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
View File
@@ -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
View File
@@ -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();
}
}
+4 -1
View File
@@ -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
+1
View File
@@ -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}]
+1
View File
@@ -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));
}
}
+7
View File
@@ -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",
+12 -5
View File
@@ -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"
}
+13 -6
View File
@@ -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"
}
+7
View File
@@ -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",
+7
View File
@@ -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",
+7
View File
@@ -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",
+7
View File
@@ -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",
+14 -7
View File
@@ -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"
+7
View File
@@ -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",
+15 -8
View File
@@ -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"
}
+12 -5
View File
@@ -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"
}
+7
View File
@@ -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",
+83 -76
View File
@@ -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"
}
+13 -6
View File
@@ -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"
}
+7
View File
@@ -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",
+21 -14
View File
@@ -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"
}
+7
View File
@@ -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",
+24 -17
View File
@@ -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"
+24 -17
View File
@@ -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",
+12 -5
View File
@@ -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"
}
+59 -52
View File
@@ -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",
+13 -6
View File
@@ -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"
}
+19 -12
View File
@@ -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"
}
+26 -19
View File
@@ -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",
+103
View File
@@ -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");
}
+1
View File
@@ -26,4 +26,5 @@ files:
uk: uk
vi: vi
zh-CN: zh_CN
zh-TW: zh_TW
zh-HK: zh_HK
-39
View File
@@ -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;
}
}
@@ -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();
}
}
@@ -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() {
}
}
@@ -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);
}
}
}
@@ -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
}
}
-41
View File
@@ -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"
}
}
}
}
+7
View File
@@ -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;
}
}
}
-48
View File
@@ -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
View File
@@ -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;
}
}
@@ -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();
}
}
@@ -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() {
}
}
@@ -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);
}
}
}
@@ -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