7 Commits
Author SHA1 Message Date
emilyy-dev e63df98d43 Maybe don't be bad?? 2023-03-30 19:08:34 -03:00
emilyy-dev 5f440b7fcc Maybe Folia support?? 2023-03-30 18:53:34 -03:00
emilyy-dev a4bc2367c2 i forgor 2023-03-29 20:14:11 -03:00
emilyy-dev 8f42e6bbd2 Back to SNAPSHOT for continued development 2023-02-03 23:07:13 -03:00
emilyy-dev 300299196d changes
* Fix some issues on the Fabric build
* Add support for non-player actors: console, cmd blocks, API users, ...; they all get treated as one actor, blocks-per-second and sorted placement mode can be configured by running a command as not a player
* Minor build setup refactoring
2023-02-03 23:03:20 -03:00
emilyy-dev c98b076911 I am a silly goose 2023-01-17 19:59:43 -03:00
emilyy-dev 0a0c7723da Back to SNAPSHOT for continued development 2023-01-08 16:05:17 -03:00
36 changed files with 920 additions and 1253 deletions

No files matched your search

-1
View File
@@ -7,4 +7,3 @@
# These are Windows script files and should use crlf
*.bat text eol=crlf
.gitea/CODEOWNERS linguist-detectable=false
-3
View File
@@ -1,3 +0,0 @@
# 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
-4
View File
@@ -1,8 +1,4 @@
.gradle
.idea
.project
.settings/
build
run
.classpath
bin/
+5 -13
View File
@@ -1,17 +1,8 @@
## WETS-OG
## WorldEdit Tick Spreader
A soft fork of [WETS](https://github.com/emilyy-dev/wets) maintained for [TrueOG](https://true-og.net/).
Spread WorldEdit operations across multiple ticks.
**Changes:**
- Changed API version to 1.19.4.
- Removed Fabric support.
- Modified project structure to build with TrueOG's gradle configuration.
- Messages are colored using MiniMessage.
- Added a customizable prefix.
- Added a customizable default blocks per tick (set to 100).
Spreads WorldEdit operations across multiple ticks.
That's all. Download on [modrinth](https://modrinth.com/mod/wets).
Semi-configurable, single command `/wets` (`/worldedit-tick-spreader`), one permission (`wets`), two possible arguments:
* `/wets (sorted | not-sorted)` - whether blocks will be placed in a sorted arrangement or not. Sorted is default.
@@ -23,4 +14,5 @@ Sorted placing and block count per tick, affected by commands, are per-player.
## License
Project licensed under the MIT license (also known as Expat license).
The original project which supports Fabric API can be found [here](https://github.com/emilyy-dev/wets).
The Fabric build of this project redistributes
[lucko/fabric-permissions-api](https://github.com/lucko/fabric-permissions-api) which is licensed under the MIT license.
+25 -97
View File
@@ -1,105 +1,33 @@
/* ------------------------------ Plugins ------------------------------ */
plugins {
id("java") // Import Java plugin.
id("java-library") // Import Java Library plugin.
id("com.diffplug.spotless") version "8.1.0" // Import Spotless plugin.
id("com.gradleup.shadow") version "8.3.9" // Import Shadow plugin.
id("checkstyle") // Import Checkstyle plugin.
eclipse // Import Eclipse plugin.
kotlin("jvm") version "2.1.21" // Import Kotlin JVM plugin.
id("com.github.johnrengelman.shadow") version "7.1.2" apply false
id("fabric-loom") version "1.0-SNAPSHOT" apply false
}
/* --------------------------- JDK / Kotlin ---------------------------- */
java {
sourceCompatibility = JavaVersion.VERSION_17 // Compile with JDK 17 compatibility.
toolchain { // Select Java toolchain.
languageVersion.set(JavaLanguageVersion.of(17)) // Use JDK 17.
vendor.set(JvmVendorSpec.GRAAL_VM) // Use GraalVM CE.
subprojects {
apply(plugin = "java")
extensions.configure<JavaPluginExtension>("java") {
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
}
repositories {
mavenCentral().mavenContent { releasesOnly() }
}
tasks {
named<JavaCompile>("compileJava") {
options.release.set(17)
}
}
kotlin { jvmToolchain(17) }
/* ----------------------------- Metadata ------------------------------ */
group = "net.trueog.wets-og" // Declare bundle identifier.
version = "1.2" // Declare plugin version (will be in .jar).
val apiVersion = "1.19" // Declare minecraft server target version.
/* ----------------------------- Resources ----------------------------- */
tasks.named<ProcessResources>("processResources") {
val props = mapOf("version" to version, "apiVersion" to apiVersion)
inputs.properties(props) // Indicates to rerun if version changes.
filesMatching("plugin.yml") { expand(props) }
from("LICENSE") { into("/") } // Bundle licenses into jarfiles.
}
/* ---------------------------- Repos ---------------------------------- */
repositories {
mavenCentral() // Import the Maven Central Maven Repository.
gradlePluginPortal() // Import the Gradle Plugin Portal Maven Repository.
maven { url = uri("https://repo.purpurmc.org/snapshots") } // Import the PurpurMC Maven Repository.
maven { url = uri("https://maven.enginehub.org/repo") } // Import the EngineHub Maven Repository.
}
/* ---------------------- Java project deps ---------------------------- */
dependencies {
compileOnly("org.purpurmc.purpur:purpur-api:1.19.4-R0.1-SNAPSHOT") // Declare Purpur API version to be packaged.
compileOnly("com.sk89q.worldedit:worldedit-bukkit:7.3.0-SNAPSHOT") // Import WorldEdit API.
}
/* ---------------------- Reproducible jars ---------------------------- */
tasks.withType<AbstractArchiveTask>().configureEach { // Ensure reproducible .jars
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
}
/* ----------------------------- Shadow -------------------------------- */
tasks.shadowJar {
exclude("io.github.miniplaceholders.*") // Exclude the MiniPlaceholders package from being shadowed.
isEnableRelocation = true
relocationPrefix = "${project.group}.shadow"
archiveClassifier.set("") // Use empty string instead of null.
minimize()
}
tasks.jar { archiveClassifier.set("part") } // Applies to root jarfile only.
tasks.build { dependsOn(tasks.spotlessApply, tasks.shadowJar) } // Build depends on spotless and shadow.
/* --------------------------- Javac opts ------------------------------- */
tasks.withType<JavaCompile>().configureEach {
options.compilerArgs.add("-parameters") // Enable reflection for java code.
options.isFork = true // Run javac in its own process.
options.compilerArgs.add("-Xlint:deprecation") // Trigger deprecation warning messages.
options.encoding = "UTF-8" // Use UTF-8 file encoding.
}
/* ----------------------------- Auto Formatting ------------------------ */
spotless {
java {
eclipse().configFile("config/formatter/eclipse-java-formatter.xml") // Eclipse java formatting.
leadingTabsToSpaces() // Convert leftover leading tabs to spaces.
removeUnusedImports() // Remove imports that aren't being called.
named<ProcessResources>("processResources") {
inputs.property("version", this@subprojects.version)
filesNotMatching("**/icon.png") {
expand("version" to this@subprojects.version)
}
}
kotlinGradle {
ktfmt().kotlinlangStyle().configure { it.setMaxWidth(120) } // JetBrains Kotlin formatting.
target("build.gradle.kts", "settings.gradle.kts") // Gradle files to format.
withType<Jar> {
metaInf.from(rootProject.file("LICENSE")).into("ar.emily/wets")
}
}
checkstyle {
toolVersion = "10.18.1" // Declare checkstyle version to use.
configFile = file("config/checkstyle/checkstyle.xml") // Point checkstyle to config file.
isIgnoreFailures = true // Don't fail the build if checkstyle does not pass.
isShowViolations = true // Show the violations in any IDE with the checkstyle plugin.
}
tasks.named("compileJava") {
dependsOn("spotlessApply") // Run spotless before compiling with the JDK.
}
tasks.named("spotlessCheck") {
dependsOn("spotlessApply") // Run spotless before checking if spotless ran.
}
}
+27
View File
@@ -0,0 +1,27 @@
plugins {
id("com.github.johnrengelman.shadow")
}
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
maven("https://maven.enginehub.org/repo/")
}
dependencies {
// this is all set up the wrong way around but shadowJar is special
implementation("dev.folia:folia-api:1.19.4-R0.1-SNAPSHOT")
implementation("com.sk89q.worldedit:worldedit-bukkit:7.2.13")
shadow(project(":wets-common")) { isTransitive = false }
}
tasks {
shadowJar {
configurations = listOf(project.configurations["shadow"])
archiveBaseName.set("WETS")
archiveClassifier.set("bukkit")
}
assemble {
dependsOn(shadowJar)
}
}
@@ -0,0 +1,25 @@
package ar.emily.wets.bukkit;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.plugin.Plugin;
import java.util.function.Consumer;
final class BukkitSchedulerAdapter implements SchedulerAdapter.Instance {
@Override
public Consumer<Runnable> scheduleGlobal(final Plugin plugin, final long initialDelay, final long period) {
return task -> plugin.getServer().getScheduler().runTaskTimer(plugin, task, initialDelay, period);
}
@Override
public void runAt(final Plugin plugin, final Location pos, final Runnable task) {
final Server server = plugin.getServer();
if (server.isPrimaryThread()) {
task.run();
} else {
server.getScheduler().runTask(plugin, task);
}
}
}
@@ -0,0 +1,26 @@
package ar.emily.wets.bukkit;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.plugin.Plugin;
import java.util.function.Consumer;
final class FoliaSchedulerAdapter implements SchedulerAdapter.Instance {
@Override
public Consumer<Runnable> scheduleGlobal(final Plugin plugin, final long initialDelay, final long period) {
final Server server = plugin.getServer();
return task -> server.getGlobalRegionScheduler().runAtFixedRate(plugin, t -> task.run(), initialDelay, period);
}
@Override
public void runAt(final Plugin plugin, final Location pos, final Runnable task) {
final Server server = plugin.getServer();
if (server.isOwnedByCurrentRegion(pos)) {
task.run();
} else {
server.getRegionScheduler().execute(plugin, pos, task);
}
}
}
@@ -0,0 +1,37 @@
package ar.emily.wets.bukkit;
import org.bukkit.Location;
import org.bukkit.plugin.Plugin;
import java.util.function.Consumer;
final class SchedulerAdapter {
private static final Instance INSTANCE = get();
static Consumer<Runnable> scheduleGlobal(final Plugin plugin, final long initialDelay, final long period) {
return INSTANCE.scheduleGlobal(plugin, initialDelay, period);
}
static void runAt(final Plugin plugin, final Location pos, final Runnable task) {
INSTANCE.runAt(plugin, pos, task);
}
private static Instance get() {
try {
Class.forName("io.papermc.paper.threadedregions.scheduler.GlobalRegionScheduler");
return new FoliaSchedulerAdapter();
} catch (final ClassNotFoundException ex) {
return new BukkitSchedulerAdapter();
}
}
private SchedulerAdapter() {
}
interface Instance {
Consumer<Runnable> scheduleGlobal(Plugin plugin, long initialDelay, long period);
void runAt(Plugin plugin, Location pos, Runnable task);
}
}
@@ -0,0 +1,70 @@
package ar.emily.wets.bukkit;
import ar.emily.wets.common.AbstractScheduler;
import ar.emily.wets.common.WESpread;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public final class WESpreadPlugin extends JavaPlugin implements Listener {
private static final List<String> COMPLETIONS = List.of("sorted", "not-sorted");
private int globalTick = 0;
@SuppressWarnings("ThisEscapedInObjectConstruction")
private final AbstractScheduler scheduler =
new AbstractScheduler(
() -> this.globalTick,
SchedulerAdapter.scheduleGlobal(this, 1L, 1L),
(pos, task) -> SchedulerAdapter.runAt(this, BukkitAdapter.adapt(pos), task)
);
private final WESpread plugin = new WESpread(this.scheduler);
@EventHandler
public void on(final PlayerQuitEvent event) {
this.plugin.playerLogout(event.getPlayer().getUniqueId());
}
@Override
public void onLoad() {
this.plugin.load();
}
@Override
public void onEnable() {
this.scheduler.setup();
SchedulerAdapter.scheduleGlobal(this, 0L, 1L).accept(() -> this.globalTick += 1);
getServer().getPluginManager().registerEvents(this, this);
}
@Override
public boolean onCommand(
final @NotNull CommandSender sender,
final @NotNull Command command,
final @NotNull String label,
final String @NotNull [] args
) {
this.plugin.command(BukkitAdapter.adapt(sender), Arrays.asList(args));
return true;
}
@Override
public @NotNull List<String> onTabComplete(
final @NotNull CommandSender sender,
final @NotNull Command command,
final @NotNull String alias,
final String @NotNull [] args
) {
return args.length == 1 ? StringUtil.copyPartialMatches(args[0], COMPLETIONS, new ArrayList<>(1)) : List.of();
}
}
@@ -1,8 +1,9 @@
name: WETS-OG
name: WorldEditTickSpreader
version: ${version}
website: https://git.trueog.net/trueog/WETS-OG
website: https://github.com/emilyy-dev/wets
main: ar.emily.wets.bukkit.WESpreadPlugin
api-version: 1.19
api-version: 1.13
folia-supported: true
depend:
- WorldEdit
+13
View File
@@ -0,0 +1,13 @@
plugins {
`java-library`
}
repositories {
maven("https://maven.enginehub.org/repo/")
}
dependencies {
api("com.sk89q.worldedit:worldedit-core:7.2.13")
api("it.unimi.dsi:fastutil:8.5.9")
compileOnlyApi("org.jetbrains:annotations:23.0.0")
}
@@ -0,0 +1,98 @@
package ar.emily.wets.common;
import com.sk89q.worldedit.util.Location;
import java.util.ArrayDeque;
import java.util.Iterator;
import java.util.Queue;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.IntSupplier;
public final class AbstractScheduler implements Scheduler {
private final IntSupplier currentTickGetter;
private final Queue<AbstractTask> pendingTasks = new ArrayDeque<>();
private final Queue<AbstractTask> tasks = new ArrayDeque<>();
private final Consumer<Runnable> globalScheduler;
private final BiConsumer<? super Location, ? super Runnable> regionScheduler;
public AbstractScheduler(
final IntSupplier currentTickGetter,
final Consumer<Runnable> globalScheduler,
final BiConsumer<? super Location, ? super Runnable> regionScheduler
) {
this.currentTickGetter = currentTickGetter;
this.globalScheduler = globalScheduler;
this.regionScheduler = regionScheduler;
}
public void setup() {
this.globalScheduler.accept(() -> {
processPendingTasks();
processTasks();
});
}
@Override
public void runPeriodically(final Consumer<Task> action, final long initialDelay, final long period) {
this.pendingTasks.add(new AbstractTask(action, this.currentTickGetter.getAsInt(), initialDelay, period));
}
@Override
public void runAt(final Location pos, final Runnable action) {
this.regionScheduler.accept(pos, action);
}
public void flush() {
this.tasks.addAll(this.pendingTasks);
this.pendingTasks.clear();
final Iterator<AbstractTask> it = this.tasks.iterator();
while (it.hasNext()) {
final AbstractTask task = it.next();
task.task.accept(it::remove);
}
this.tasks.clear();
}
private void processPendingTasks() {
final int currentTick = this.currentTickGetter.getAsInt();
final Iterator<AbstractTask> it = this.pendingTasks.iterator();
while (it.hasNext()) {
final AbstractTask task = it.next();
if (task.registerTick + task.initialDelay >= currentTick) {
this.tasks.add(task);
task.registerTick = currentTick;
it.remove();
}
}
}
private void processTasks() {
final int currentTick = this.currentTickGetter.getAsInt();
final Iterator<AbstractTask> it = this.tasks.iterator();
while (it.hasNext()) {
final AbstractTask task = it.next();
if ((currentTick - task.registerTick) % task.period == 0) {
task.task.accept(it::remove);
}
}
}
private static final class AbstractTask {
final Consumer<Task> task;
final long initialDelay;
final long period;
long registerTick;
AbstractTask(final Consumer<Task> task, final long registerTick, final long initialDelay, final long period) {
this.task = task;
this.registerTick = registerTick;
this.initialDelay = Math.min(initialDelay, 1);
this.period = Math.min(period, 1);
}
}
}
@@ -0,0 +1,18 @@
package ar.emily.wets.common;
import com.sk89q.worldedit.util.Location;
import java.util.function.Consumer;
public interface Scheduler {
void flush();
void runPeriodically(Consumer<Task> action, long initialDelay, long period);
void runAt(Location pos, Runnable action);
@FunctionalInterface
interface Task {
void cancel();
}
}
@@ -0,0 +1,55 @@
package ar.emily.wets.common;
import java.lang.invoke.VarHandle;
import java.nio.ByteOrder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
import static java.lang.invoke.MethodHandles.byteArrayViewVarHandle;
// why am i overcomplicating this
final class V5UUID {
private static final VarHandle AS_LONG_ARRAY = byteArrayViewVarHandle(long[].class, ByteOrder.BIG_ENDIAN);
private static final MessageDigest MD;
static {
try {
MD = MessageDigest.getInstance("SHA-1");
} catch (final NoSuchAlgorithmException ex) {
// shouldn't throw, SHA-1 is a standard algorithm that is required by Java SE
// https://docs.oracle.com/en/java/javase/17/docs/specs/security/standard-names.html
throw new ExceptionInInitializerError(ex);
}
}
// MessageDigest isn't thread safe, that's why it's being cloned
@SuppressWarnings("AccessToNonThreadSafeStaticField")
private static MessageDigest md() {
try {
return (MessageDigest) MD.clone();
} catch (final CloneNotSupportedException ex) {
// shouldn't throw
throw new RuntimeException(ex);
}
}
// use V5 UUID as to not collide with V3 or V4 UUIDs, which are used by the game
static UUID create(final byte[] bs) {
final var md = md();
md.update(bs);
final byte[] digest = md.digest();
digest[6] &= 0x0f; // clear version
digest[6] |= 0x50; // set version 5
digest[8] &= 0x3f; // clear variant
digest[8] |= (byte) 0x80; // set variant 1
return new UUID(
(long) AS_LONG_ARRAY.get(digest, 0),
(long) AS_LONG_ARRAY.get(digest, 8)
);
}
private V5UUID() {
}
}
@@ -0,0 +1,197 @@
package ar.emily.wets.common;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.event.extent.EditSessionEvent;
import com.sk89q.worldedit.event.platform.PlatformUnreadyEvent;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.AbstractBufferingExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.RunContext;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Identifiable;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.collection.BlockMap;
import com.sk89q.worldedit.util.eventbus.EventHandler;
import com.sk89q.worldedit.util.eventbus.Subscribe;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import org.jetbrains.annotations.Nullable;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import java.util.function.LongSupplier;
import java.util.stream.Stream;
public final class WESpread {
public static final UUID NON_PLAYER_ACTOR_ID =
V5UUID.create(WESpread.class.descriptorString().getBytes(StandardCharsets.UTF_8));
private static final AtomicLongFieldUpdater<WESpread> DEFAULT_BLOCKS_PER_TICK =
AtomicLongFieldUpdater.newUpdater(WESpread.class, "defaultBlocksPerTick");
// @formatter:off
private static final Component INVALID_ARGUMENT = TextComponent.of("Blocks per tick must be a valid positive number");
private static final Component COMMAND_USAGE = TextComponent.of("Usage: /wets (<blocks per tick> | sorted | not-sorted)");
private static final Component COMMAND_SORTED = TextComponent.of("Block placement of new operations will now be sorted");
private static final Component COMMAND_NOT_SORTED = TextComponent.of("Block placement of new operations will now be unsorted");
private static final Component COMMAND_BPT_UPDATED = TextComponent.of("Blocks per tick placement updated");
// @formatter:on
private final Scheduler scheduler;
// Folia note: none of the ops on these collections are critical enough to be atomic
private final ConcurrentMap<UUID, Long> blocksPerTickMap = new ConcurrentHashMap<>();
private final Set<UUID> actorsWhosePlacementIsNotSorted = ConcurrentHashMap.newKeySet();
private volatile long defaultBlocksPerTick = 1;
public WESpread(final Scheduler scheduler) {
this.scheduler = scheduler;
}
public void playerLogout(final UUID id) {
this.blocksPerTickMap.remove(id);
this.actorsWhosePlacementIsNotSorted.remove(id);
}
public void load() {
WorldEdit.getInstance().getEventBus().register(this);
}
// we really really really want to flush the queue before worldedit itself unloads
@Subscribe(priority = EventHandler.Priority.VERY_EARLY)
public void on(final PlatformUnreadyEvent event) {
WorldEdit.getInstance().getEventBus().unregister(this);
DEFAULT_BLOCKS_PER_TICK.set(this, Long.MAX_VALUE);
this.blocksPerTickMap.clear();
this.actorsWhosePlacementIsNotSorted.clear();
this.scheduler.flush();
}
@Subscribe
public void on(final EditSessionEvent event) {
if (event.getStage() == EditSession.Stage.BEFORE_CHANGE) {
final UUID actorId =
Optional.ofNullable(event.getActor())
// use a set ID for non-player actors, such as console or potentially API users
.filter(Actor::isPlayer)
.map(Identifiable::getUniqueId)
.orElse(NON_PLAYER_ACTOR_ID);
event.setExtent(new SchedulingExtent(event.getExtent(), actorId));
}
}
public void command(final Actor source, final List<String> args) {
if (args.size() != 1) {
source.print(COMMAND_USAGE);
return;
}
final UUID id = source.isPlayer() ? source.getUniqueId() : NON_PLAYER_ACTOR_ID;
final String arg = args.iterator().next();
if ("sorted".equals(arg)) {
this.actorsWhosePlacementIsNotSorted.remove(id);
source.print(COMMAND_SORTED);
return;
} else if ("not-sorted".equals(arg)) {
this.actorsWhosePlacementIsNotSorted.add(id);
source.print(COMMAND_NOT_SORTED);
return;
}
try {
long blocksPerTick = Long.parseLong(arg);
if (blocksPerTick < 0) { blocksPerTick = Long.MAX_VALUE; }
this.blocksPerTickMap.put(id, blocksPerTick);
source.print(COMMAND_BPT_UPDATED);
} catch (final NumberFormatException exception) {
source.printError(INVALID_ARGUMENT);
source.print(COMMAND_USAGE);
}
}
private final class SchedulingExtent extends AbstractBufferingExtent {
private final BlockMap<BaseBlock> buffer = BlockMap.createForBaseBlock();
private final LongSupplier blocksPerTick;
private final boolean sorted;
private SchedulingExtent(final Extent delegate, final UUID actor) {
super(delegate);
this.sorted = !WESpread.this.actorsWhosePlacementIsNotSorted.contains(actor);
this.blocksPerTick =
() -> WESpread.this.blocksPerTickMap.getOrDefault(actor, DEFAULT_BLOCKS_PER_TICK.get(WESpread.this));
}
@Override
protected @Nullable BaseBlock getBufferedFullBlock(final BlockVector3 position) {
return this.buffer.computeIfAbsent(position, getExtent()::getFullBlock);
}
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(final BlockVector3 position, final T block) {
this.buffer.remove(position); // workaround silly WorldEdit bug, see https://github.com/emilyy-dev/wets/issues/1
this.buffer.put(position, block.toBaseBlock());
return true;
}
@Override
protected Operation commitBefore() {
final Iterator<Map.Entry<BlockVector3, BaseBlock>> it;
{
Stream<Map.Entry<BlockVector3, BaseBlock>> stream = this.buffer.entrySet().stream();
if (this.sorted) { stream = stream.sorted(Map.Entry.comparingByKey(BlockVector3.sortByCoordsYzx())); }
it = stream.iterator();
}
return new Operation() {
boolean started = false;
@Override
public Operation resume(final RunContext run) {
if (!this.started && it.hasNext()) {
this.started = true;
WESpread.this.scheduler.runPeriodically(this::putBlock, 1L, 1L);
}
return null;
}
private void putBlock(final Scheduler.Task task) {
try {
for (long i = 0; it.hasNext() && i < SchedulingExtent.this.blocksPerTick.getAsLong(); ++i) {
final var entry = it.next();
WESpread.this.scheduler.runAt(
new Location(getExtent(), entry.getKey().toVector3()),
() -> {
try {
setDelegateBlock(entry.getKey(), entry.getValue());
} catch (final WorldEditException ex) {
throw new RuntimeException(ex);
}
}
);
}
} finally {
if (!it.hasNext()) { task.cancel(); }
}
}
@Override
public void cancel() {
}
};
}
}
}
-34
View File
@@ -1,34 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
<module name="FileTabCharacter">
<property name="eachLine" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="TreeWalker">
<module name="FinalLocalVariable"/>
<module name="AvoidStarImport"/>
<module name="Indentation">
<property name="severity" value="ignore"/>
</module>
</module>
<module name="RegexpSingleline">
<property name="format" value="\borg\.junit\.jupiter\.api\.Assertions\.fail\s*\(\s*&quot;Not yet implemented&quot;\s*\)\s*;"/>
<property name="message" value="Remove placeholder fail() and implement the test."/>
<property name="ignoreCase" value="true"/>
<property name="severity" value="warning"/>
</module>
<module name="RegexpSingleline">
<property name="format" value="(?&lt;!\w)fail\s*\(\s*&quot;Not yet implemented&quot;\s*\)\s*;"/>
<property name="message" value="Remove placeholder fail() and implement the test."/>
<property name="severity" value="warning"/>
</module>
</module>
-404
View File
@@ -1,404 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="23">
<profile kind="CodeFormatterProfile" name="TrueOG Network Formatting" version="23">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_record_components" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_logical_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_shift_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_switch_case_arrow_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.text_block_indentation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_permitted_types" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_annotations" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_not_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.javadoc_do_not_separate_block_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_tag_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_constructor" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_string_concatenation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_additive_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case_after_arrow" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_switch_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_arrow" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_additive_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_relational_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.align_arrows_in_switch_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.align_selector_in_method_invocation_on_expression_first_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_switch_case_with_arrow_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_colon" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_shift_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_switch_case_with_arrow" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assertion_message" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_relational_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_logical_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_permitted_types" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_string_concatenation" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
</profile>
</profiles>
+38
View File
@@ -0,0 +1,38 @@
plugins {
id("fabric-loom")
}
repositories {
maven("https://oss.sonatype.org/content/repositories/snapshots/").mavenContent { snapshotsOnly() }
maven("https://maven.enginehub.org/repo/")
}
dependencies {
minecraft("com.mojang:minecraft:1.19.3")
mappings(loom.officialMojangMappings())
modImplementation("net.fabricmc:fabric-loader:0.14.11")
setOf(
"fabric-command-api-v2",
"fabric-lifecycle-events-v1"
)
.forEach { modImplementation(fabricApi.module(it, "0.72.0+1.19.3")) }
modImplementation("com.sk89q.worldedit:worldedit-fabric-mc1.19.3:7.2.13")
modImplementation("me.lucko:fabric-permissions-api:0.2-SNAPSHOT") { include(this) }
implementation(project(":wets-common")) { include(this) }
}
tasks {
remapJar {
archiveBaseName.set("WETS")
archiveClassifier.set("fabric")
}
assemble {
dependsOn(remapJar)
}
runClient {
javaLauncher.set(project.javaToolchains.launcherFor(project.java.toolchain))
}
}
@@ -0,0 +1,125 @@
package ar.emily.wets.fabric;
import ar.emily.wets.common.WESpread;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.platform.AbstractNonPlayerActor;
import com.sk89q.worldedit.session.SessionKey;
import com.sk89q.worldedit.util.formatting.WorldEditText;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.serializer.gson.GsonComponentSerializer;
import me.lucko.fabric.api.permissions.v0.Permissions;
import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandSourceStack;
import org.jetbrains.annotations.NotNull;
import java.util.Locale;
import java.util.UUID;
final class FabricNonPlayerActor extends AbstractNonPlayerActor {
private static final String[] EMPTY_STRINGS = new String[0];
private final CommandSourceStack source;
FabricNonPlayerActor(final CommandSourceStack source) {
this.source = source;
}
@Override
public UUID getUniqueId() {
return WESpread.NON_PLAYER_ACTOR_ID;
}
@Override
public String getName() {
return this.source.getTextName();
}
@Override
@Deprecated
public void printRaw(final String msg) {
for (final String part : msg.split("\n")) {
this.source.sendSystemMessage(net.minecraft.network.chat.Component.literal(part));
}
}
@Override
@Deprecated
public void printDebug(final String msg) {
for (final String part : msg.split("\n")) {
this.source.sendSystemMessage(net.minecraft.network.chat.Component.literal(part).withStyle(ChatFormatting.GRAY));
}
}
@Override
@Deprecated
public void print(final String msg) {
for (final String part : msg.split("\n")) {
this.source.sendSystemMessage(
net.minecraft.network.chat.Component.literal(part).withStyle(ChatFormatting.LIGHT_PURPLE)
);
}
}
@Override
@Deprecated
public void printError(final String msg) {
for (final String part : msg.split("\n")) {
this.source.sendSystemMessage(net.minecraft.network.chat.Component.literal(part).withStyle(ChatFormatting.RED));
}
}
@Override
@SuppressWarnings("DataFlowIssue")
public void print(final Component component) {
this.source.sendSystemMessage(
net.minecraft.network.chat.Component.Serializer.fromJson(
GsonComponentSerializer.INSTANCE.serialize(WorldEditText.format(component, getLocale()))
)
);
}
@Override
public Locale getLocale() {
return WorldEdit.getInstance().getConfiguration().defaultLocale;
}
@Override
public SessionKey getSessionKey() {
return new SessionKey() {
@Override
public @NotNull String getName() {
return FabricNonPlayerActor.this.getName();
}
@Override
public boolean isActive() {
return true;
}
@Override
public boolean isPersistent() {
return true;
}
@Override
public UUID getUniqueId() {
return FabricNonPlayerActor.this.getUniqueId();
}
};
}
@Override
public String[] getGroups() {
return EMPTY_STRINGS;
}
@Override
public void checkPermission(final String permission) {
}
@Override
public boolean hasPermission(final String permission) {
return Permissions.check(this.source, permission);
}
}
@@ -0,0 +1,82 @@
package ar.emily.wets.fabric;
import ar.emily.wets.common.AbstractScheduler;
import ar.emily.wets.common.WESpread;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.tree.LiteralCommandNode;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.fabric.FabricAdapter;
import me.lucko.fabric.api.permissions.v0.Permissions;
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.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.minecraft.commands.CommandSourceStack;
import java.util.List;
import java.util.function.Predicate;
import static com.mojang.brigadier.arguments.LongArgumentType.getLong;
import static com.mojang.brigadier.arguments.LongArgumentType.longArg;
import static net.minecraft.commands.Commands.LEVEL_GAMEMASTERS;
import static net.minecraft.commands.Commands.argument;
import static net.minecraft.commands.Commands.literal;
public final class WESpreadMod implements ModInitializer {
private static final List<String> SORTED = List.of("sorted");
private static final List<String> NOT_SORTED = List.of("not-sorted");
private static Actor adaptActor(final CommandSourceStack source) throws CommandSyntaxException {
return source.isPlayer() ?
FabricAdapter.adaptPlayer(source.getPlayerOrException()) :
new FabricNonPlayerActor(source);
}
private WESpread plugin;
@Override
public void onInitialize() {
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> command(dispatcher));
ServerLifecycleEvents.SERVER_STARTING.register(server -> {
final AbstractScheduler scheduler =
new AbstractScheduler(
server::getTickCount,
task -> ServerTickEvents.END_SERVER_TICK.register(s -> task.run()),
(pos, task) -> task.run() // already on server tick
);
scheduler.setup();
this.plugin = new WESpread(scheduler);
this.plugin.load();
});
ServerPlayConnectionEvents.DISCONNECT.register((packetListener, server) ->
this.plugin.playerLogout(packetListener.getPlayer().getUUID())
);
}
private int executeCommand(final CommandContext<? extends CommandSourceStack> ctx, final List<String> args)
throws CommandSyntaxException {
this.plugin.command(adaptActor(ctx.getSource()), args);
return Command.SINGLE_SUCCESS;
}
private void command(final CommandDispatcher<CommandSourceStack> dispatcher) {
final Predicate<CommandSourceStack> permissionRequirement = Permissions.require("wets", LEVEL_GAMEMASTERS);
final LiteralCommandNode<CommandSourceStack> wetsCommand =
dispatcher.register(
literal("worldedit-tick-spreader")
.requires(permissionRequirement)
.then(literal("sorted").executes(ctx -> executeCommand(ctx, SORTED)))
.then(literal("not-sorted").executes(ctx -> executeCommand(ctx, NOT_SORTED)))
.then(argument("blocks-per-tick", longArg()).executes(ctx ->
executeCommand(ctx, List.of(String.valueOf(getLong(ctx, "blocks-per-tick"))))
))
);
dispatcher.register(literal("wets").requires(permissionRequirement).redirect(wetsCommand));
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

+31
View File
@@ -0,0 +1,31 @@
{
"schemaVersion": 1,
"id": "worldedit-tick-spreader",
"version": "${version}",
"icon": "assets/worldedit-tick-spreader/icon.png",
"name": "WorldEdit Tick Spreader",
"authors": [
"emilyy-dev"
],
"contact": {
"sources": "https://github.com/emilyy-dev/wets",
"issues": "https://github.com/emilyy-dev/wets/issues"
},
"license": "MIT",
"environment": "*",
"entrypoints": {
"main": [
"ar.emily.wets.fabric.WESpreadMod"
]
},
"depends": {
"fabric-permissions-api-v0": "*",
"fabricloader": "*",
"java": ">=17",
"minecraft": "1.19.3",
"worldedit": "*"
}
}
+2 -3
View File
@@ -1,5 +1,4 @@
org.gradle.jvmargs=-Xmx1G
org.gradle.parallel=false
org.gradle.caching=false
group=net.trueog.wets-og
version=0.0.6
group=ar.emily
version=0.0.4-SNAPSHOT
Binary file not shown.
+1 -3
View File
@@ -1,7 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+15 -26
View File
@@ -15,8 +15,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@@ -57,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -82,11 +80,13 @@ do
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -114,7 +114,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH="\\\"\\\""
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
@@ -133,29 +133,22 @@ location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@@ -200,20 +193,16 @@ if "$cygwin" || "$msys" ; then
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
Vendored
+12 -15
View File
@@ -13,8 +13,6 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@@ -28,7 +26,6 @@ if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -45,11 +42,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
@@ -59,22 +56,22 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
+14 -1
View File
@@ -1 +1,14 @@
rootProject.name = "WETS-OG"
rootProject.name = "worldedit-spread-placing"
pluginManagement {
repositories {
maven("https://maven.fabricmc.net/")
mavenCentral()
gradlePluginPortal()
}
}
listOf("common", "bukkit", "fabric").forEach {
include(it)
project(":$it").name = "wets-$it"
}
@@ -1,112 +0,0 @@
package ar.emily.wets.bukkit;
import java.util.ArrayDeque;
import java.util.Iterator;
import java.util.Queue;
import java.util.function.Consumer;
import java.util.function.IntSupplier;
public final class AbstractScheduler implements Scheduler {
private final IntSupplier currentTickGetter;
private final Queue<AbstractTask> pendingTasks = new ArrayDeque<>();
private final Queue<AbstractTask> tasks = new ArrayDeque<>();
private final Consumer<Runnable> underlyingScheduler;
public AbstractScheduler(final IntSupplier currentTickGetter, final Consumer<Runnable> underlyingScheduler) {
this.currentTickGetter = currentTickGetter;
this.underlyingScheduler = underlyingScheduler;
}
public void setup() {
this.underlyingScheduler.accept(() -> {
processPendingTasks();
processTasks();
});
}
@Override
public void runPeriodically(final Consumer<Task> action, final long initialDelay, final long period) {
this.pendingTasks.add(new AbstractTask(action, this.currentTickGetter.getAsInt(), initialDelay, period));
}
public void flush() {
this.tasks.addAll(this.pendingTasks);
this.pendingTasks.clear();
final Iterator<AbstractTask> it = this.tasks.iterator();
while (it.hasNext()) {
final AbstractTask task = it.next();
task.task.accept(it::remove);
}
this.tasks.clear();
}
private void processPendingTasks() {
final int currentTick = this.currentTickGetter.getAsInt();
final Iterator<AbstractTask> it = this.pendingTasks.iterator();
while (it.hasNext()) {
final AbstractTask task = it.next();
if (task.registerTick + task.initialDelay >= currentTick) {
this.tasks.add(task);
task.registerTick = currentTick;
it.remove();
}
}
}
private void processTasks() {
final int currentTick = this.currentTickGetter.getAsInt();
final Iterator<AbstractTask> it = this.tasks.iterator();
while (it.hasNext()) {
final AbstractTask task = it.next();
if ((currentTick - task.registerTick) % task.period == 0) {
task.task.accept(it::remove);
}
}
}
private static final class AbstractTask {
final Consumer<Task> task;
final long initialDelay;
final long period;
long registerTick;
AbstractTask(final Consumer<Task> task, final long registerTick, final long initialDelay, final long period) {
this.task = task;
this.registerTick = registerTick;
this.initialDelay = Math.min(initialDelay, 1);
this.period = Math.min(period, 1);
}
}
}
@@ -1,18 +0,0 @@
package ar.emily.wets.bukkit;
import java.util.function.Consumer;
public interface Scheduler {
void flush();
void runPeriodically(Consumer<Task> action, long initialDelay, long period);
@FunctionalInterface
interface Task {
void cancel();
}
}
@@ -1,84 +0,0 @@
package ar.emily.wets.bukkit;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
public class Utils {
public static String legacySerializerAnyCase(String subject) {
int count = 0;
// Count the number of '&' characters to determine the size of the array
for (char c : subject.toCharArray()) {
if (c == '&') {
count++;
}
}
// Create an array to store the positions of '&' characters
int[] positions = new int[count];
int index = 0;
// Find the positions of '&' characters and store in the array
for (int i = 0; i < subject.length(); i++) {
if (subject.charAt(i) == '&') {
if (isUpperBukkitCode(subject.charAt(i + 1))) {
subject = replaceCharAtIndex(subject, (i + 1), Character.toLowerCase(subject.charAt(i + 1)));
}
positions[index++] = i;
}
}
String serializedText = LegacyComponentSerializer.legacySection()
.serialize(LegacyComponentSerializer.legacyAmpersand().deserialize(subject));
return serializedText;
}
private static boolean isUpperBukkitCode(char input) {
char[] bukkitColorCodes = { 'A', 'B', 'C', 'D', 'E', 'F', 'K', 'L', 'M', 'N', 'O', 'R' };
boolean match = false;
// Loop through each character in the array.
for (char c : bukkitColorCodes) {
// Check if the current character in the array is equal to the input character.
if (c == input) {
match = true;
}
}
return match;
}
private static String replaceCharAtIndex(String original, int index, char newChar) {
// Check if the index is valid
if (index >= 0 && index < original.length()) {
// Create a new string with the replaced character
return original.substring(0, index) + newChar + original.substring(index + 1);
}
// If the index is invalid, return the original string
return original;
}
}
@@ -1,67 +0,0 @@
package ar.emily.wets.bukkit;
import static java.lang.invoke.MethodHandles.byteArrayViewVarHandle;
import java.lang.invoke.VarHandle;
import java.nio.ByteOrder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
// why am I overcomplicating this?
final class V5UUID {
private static final VarHandle AS_LONG_ARRAY = byteArrayViewVarHandle(long[].class, ByteOrder.BIG_ENDIAN);
private static final MessageDigest MD;
static {
try {
MD = MessageDigest.getInstance("SHA-1");
} catch (final NoSuchAlgorithmException ex) {
// shouldn't throw, SHA-1 is a standard algorithm that is required by Java SE
// https://docs.oracle.com/en/java/javase/17/docs/specs/security/standard-names.html
throw new ExceptionInInitializerError(ex);
}
}
// MessageDigest isn't thread safe, that's why it's being cloned
private static MessageDigest md() {
try {
return (MessageDigest) MD.clone();
} catch (final CloneNotSupportedException ex) {
// shouldn't throw
throw new RuntimeException(ex);
}
}
// use V5 UUID as to not collide with V3 or V4 UUIDs, which are used by the game
static UUID create(final byte[] bs) {
final var md = md();
md.update(bs);
final byte[] digest = md.digest();
digest[6] &= 0x0f; // clear version
digest[6] |= 0x50; // set version 5
digest[8] &= 0x3f; // clear variant
digest[8] |= (byte) 0x80; // set variant 1
return new UUID((long) AS_LONG_ARRAY.get(digest, 0), (long) AS_LONG_ARRAY.get(digest, 8));
}
private V5UUID() {
}
}
@@ -1,295 +0,0 @@
package ar.emily.wets.bukkit;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.event.extent.EditSessionEvent;
import com.sk89q.worldedit.event.platform.PlatformUnreadyEvent;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.AbstractBufferingExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.RunContext;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Identifiable;
import com.sk89q.worldedit.util.collection.BlockMap;
import com.sk89q.worldedit.util.eventbus.EventHandler;
import com.sk89q.worldedit.util.eventbus.Subscribe;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import it.unimi.dsi.fastutil.objects.Object2LongMap;
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.function.LongSupplier;
import java.util.stream.Stream;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.Nullable;
public final class WESpread {
public static final UUID NON_PLAYER_ACTOR_ID = V5UUID
.create(WESpread.class.descriptorString().getBytes(StandardCharsets.UTF_8));
private AbstractScheduler scheduler;
File configFile = new File("plugins/WETS-OG/config.yml");
public static FileConfiguration convertFileToConfig(File file) {
FileConfiguration config = YamlConfiguration.loadConfiguration(file);
try {
config.load(file);
} catch (IOException | InvalidConfigurationException error) {
error.printStackTrace();
}
return config;
}
FileConfiguration configFileYAML = convertFileToConfig(configFile);
public WESpread(AbstractScheduler scheduler) {
this.scheduler = scheduler;
}
private final Component INVALID_ARGUMENT = TextComponent
.of(Utils.legacySerializerAnyCase(Utils.legacySerializerAnyCase(configFileYAML.getString("ChatPrefix")
+ "&cERROR: Blocks per tick must be a valid positive number!")));
private final Component COMMAND_USAGE = TextComponent.of(Utils.legacySerializerAnyCase(
configFileYAML.getString("ChatPrefix") + "&6Usage: &e/wets (<blocks per tick> | sorted | not-sorted)"));
private final Component COMMAND_SORTED = TextComponent.of(Utils.legacySerializerAnyCase(
configFileYAML.getString("ChatPrefix") + "&6Block placement of new operations will now be &esorted&6."));
private final Component COMMAND_NOT_SORTED = TextComponent.of(Utils.legacySerializerAnyCase(
configFileYAML.getString("ChatPrefix") + "&6Block placement of new operations will now be &eunsorted&6."));
private final Component COMMAND_BPT_UPDATED = TextComponent.of(Utils
.legacySerializerAnyCase(configFileYAML.getString("ChatPrefix") + "&aBlocks per tick placement set to: "));
private final Object2LongMap<UUID> blocksPerTickMap = new Object2LongOpenHashMap<>();
private final Set<UUID> actorsWhosePlacementIsNotSorted = new HashSet<>();
private long defaultBlocksPerTick = configFileYAML.getInt("DefaultBlocksPerTick");
public void playerLogout(final UUID id) {
this.blocksPerTickMap.removeLong(id);
this.actorsWhosePlacementIsNotSorted.remove(id);
}
public void load() {
WorldEdit.getInstance().getEventBus().register(this);
}
// We really really really want to flush the queue before WorldEdit itself
// unloads.
@Subscribe(priority = EventHandler.Priority.VERY_EARLY)
public void on(final PlatformUnreadyEvent event) {
WorldEdit.getInstance().getEventBus().unregister(this);
this.defaultBlocksPerTick = Long.MAX_VALUE;
this.blocksPerTickMap.clear();
this.actorsWhosePlacementIsNotSorted.clear();
this.scheduler.flush();
}
@Subscribe
public void on(final EditSessionEvent event) {
if (event.getStage() == EditSession.Stage.BEFORE_CHANGE) {
final UUID actorId = Optional.ofNullable(event.getActor())
// use a set ID for non-player actors, such as console or potentially API users
.filter(Actor::isPlayer).map(Identifiable::getUniqueId).orElse(NON_PLAYER_ACTOR_ID);
event.setExtent(new SchedulingExtent(event.getExtent(), actorId));
}
}
public void command(final Actor source, final List<String> args) {
if (args.size() != 1) {
source.print(COMMAND_USAGE);
return;
}
final UUID id = source.isPlayer() ? source.getUniqueId() : NON_PLAYER_ACTOR_ID;
final String arg = args.iterator().next();
if ("sorted".equals(arg)) {
this.actorsWhosePlacementIsNotSorted.remove(id);
source.print(COMMAND_SORTED);
return;
} else if ("not-sorted".equals(arg)) {
this.actorsWhosePlacementIsNotSorted.add(id);
source.print(COMMAND_NOT_SORTED);
return;
}
try {
long blocksPerTick = Long.parseLong(arg);
if (blocksPerTick < 0) {
blocksPerTick = Long.MAX_VALUE;
}
this.blocksPerTickMap.put(id, blocksPerTick);
configFileYAML.set("DefaultBlocksPerTick", blocksPerTick);
try {
configFileYAML.save(configFile);
} catch (IOException error) {
error.printStackTrace();
}
source.print(COMMAND_BPT_UPDATED
.append(TextComponent.of(Utils.legacySerializerAnyCase("&e" + String.valueOf(blocksPerTick)))));
} catch (final NumberFormatException exception) {
source.printError(INVALID_ARGUMENT);
source.print(COMMAND_USAGE);
}
}
private final class SchedulingExtent extends AbstractBufferingExtent {
private final BlockMap<BaseBlock> buffer = BlockMap.createForBaseBlock();
private final LongSupplier blocksPerTick;
private final boolean sorted;
private SchedulingExtent(final Extent delegate, final UUID actor) {
super(delegate);
this.sorted = !WESpread.this.actorsWhosePlacementIsNotSorted.contains(actor);
this.blocksPerTick = () -> WESpread.this.blocksPerTickMap.getOrDefault(actor,
WESpread.this.defaultBlocksPerTick);
}
@Override
protected @Nullable BaseBlock getBufferedFullBlock(final BlockVector3 position) {
return this.buffer.computeIfAbsent(position, getExtent()::getFullBlock);
}
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(final BlockVector3 position, final T block) {
this.buffer.remove(position); // workaround silly WorldEdit bug, see
// https://github.com/emilyy-dev/wets/issues/1
this.buffer.put(position, block.toBaseBlock());
return true;
}
@Override
protected Operation commitBefore() {
final Iterator<Map.Entry<BlockVector3, BaseBlock>> it;
{
Stream<Map.Entry<BlockVector3, BaseBlock>> stream = this.buffer.entrySet().stream();
if (this.sorted) {
stream = stream.sorted(Map.Entry.comparingByKey(BlockVector3.sortByCoordsYzx()));
}
it = stream.iterator();
}
return new Operation() {
boolean started = false;
@Override
public Operation resume(final RunContext run) {
if (!this.started && it.hasNext()) {
this.started = true;
WESpread.this.scheduler.runPeriodically(this::putBlock, 1L, 1L);
}
return null;
}
private void putBlock(final Scheduler.Task task) {
try {
for (long i = 0; it.hasNext() && i < SchedulingExtent.this.blocksPerTick.getAsLong(); ++i) {
final var entry = it.next();
setDelegateBlock(entry.getKey(), entry.getValue());
}
} catch (final WorldEditException exception) {
throw new RuntimeException(exception);
} finally {
if (!it.hasNext()) {
task.cancel();
}
}
}
@Override
public void cancel() {
}
};
}
}
}
@@ -1,66 +0,0 @@
package ar.emily.wets.bukkit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull;
public final class WESpreadPlugin extends JavaPlugin implements Listener {
private static final List<String> COMPLETIONS = List.of("sorted", "not-sorted");
private final AbstractScheduler scheduler = new AbstractScheduler(getServer()::getCurrentTick,
task -> getServer().getScheduler().runTaskTimer(this, task, 1L, 1L));
private final WESpread wetsSpread = new WESpread(this.scheduler);
@EventHandler
public void on(final PlayerQuitEvent event) {
this.wetsSpread.playerLogout(event.getPlayer().getUniqueId());
}
@Override
public void onLoad() {
this.wetsSpread.load();
}
@Override
public void onEnable() {
saveDefaultConfig();
this.scheduler.setup();
getServer().getPluginManager().registerEvents(this, this);
}
@Override
public boolean onCommand(final @NotNull CommandSender sender, final @NotNull Command command,
final @NotNull String label, final String @NotNull [] args)
{
this.wetsSpread.command(BukkitAdapter.adapt(sender), Arrays.asList(args));
return true;
}
@Override
public @NotNull List<String> onTabComplete(final @NotNull CommandSender sender, final @NotNull Command command,
final @NotNull String alias, final String @NotNull [] args)
{
return args.length == 1 ? StringUtil.copyPartialMatches(args[0], COMPLETIONS, new ArrayList<>(1)) : List.of();
}
}
-4
View File
@@ -1,4 +0,0 @@
# Set the chat prefix (using bukkit color codes).
ChatPrefix: "&7[&eWETS&f-&4OG&7] "
# Set the amount of blocks to update per tick (high values may cause lag).
DefaultBlocksPerTick: 100