mirror of
https://github.com/Shiewk/BlockHistory3.git
synced 2026-04-28 04:24:17 +02:00
(3.1.0) Switch to Paper plugin & support Folia
This commit is contained in:
+20
-7
@@ -1,9 +1,10 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
|
id("xyz.jpenilla.run-paper") version "2.3.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = 'de.shiewk'
|
group = 'de.shiewk'
|
||||||
version = '3.0.1'
|
version = pluginVersion
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
@@ -11,14 +12,11 @@ repositories {
|
|||||||
name = "papermc-repo"
|
name = "papermc-repo"
|
||||||
url = "https://repo.papermc.io/repository/maven-public/"
|
url = "https://repo.papermc.io/repository/maven-public/"
|
||||||
}
|
}
|
||||||
maven {
|
|
||||||
name = "sonatype"
|
|
||||||
url = "https://oss.sonatype.org/content/groups/public/"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly("io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT")
|
//compileOnly("io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT")
|
||||||
|
compileOnly 'dev.folia:folia-api:1.20.6-R0.1-SNAPSHOT'
|
||||||
}
|
}
|
||||||
|
|
||||||
def targetJavaVersion = 21
|
def targetJavaVersion = 21
|
||||||
@@ -39,11 +37,26 @@ tasks.withType(JavaCompile).configureEach {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runPaper {
|
||||||
|
folia {
|
||||||
|
registerTask()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
runServer {
|
||||||
|
minecraftVersion("1.21.6")
|
||||||
|
downloadPlugins {
|
||||||
|
// for testing from other client versions
|
||||||
|
modrinth("ViaVersion", "5.4.1")
|
||||||
|
modrinth("ViaBackwards", "5.4.1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
def props = [version: version]
|
def props = [version: version]
|
||||||
inputs.properties props
|
inputs.properties props
|
||||||
filteringCharset 'UTF-8'
|
filteringCharset 'UTF-8'
|
||||||
filesMatching('plugin.yml') {
|
filesMatching('paper-plugin.yml') {
|
||||||
expand props
|
expand props
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
pluginVersion = 3.1.0
|
||||||
@@ -2,6 +2,7 @@ package de.shiewk.blockhistory.v3;
|
|||||||
|
|
||||||
import de.shiewk.blockhistory.v3.command.BlockHistoryCommand;
|
import de.shiewk.blockhistory.v3.command.BlockHistoryCommand;
|
||||||
import de.shiewk.blockhistory.v3.listener.BlockListener;
|
import de.shiewk.blockhistory.v3.listener.BlockListener;
|
||||||
|
import de.shiewk.blockhistory.v3.util.SchedulerUtil;
|
||||||
import io.papermc.paper.command.brigadier.Commands;
|
import io.papermc.paper.command.brigadier.Commands;
|
||||||
import io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent;
|
import io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent;
|
||||||
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents;
|
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents;
|
||||||
@@ -21,6 +22,19 @@ import static net.kyori.adventure.text.Component.text;
|
|||||||
|
|
||||||
public final class BlockHistoryPlugin extends JavaPlugin {
|
public final class BlockHistoryPlugin extends JavaPlugin {
|
||||||
|
|
||||||
|
public static final boolean isFolia;
|
||||||
|
|
||||||
|
static {
|
||||||
|
boolean folia;
|
||||||
|
try {
|
||||||
|
Class.forName("io.papermc.paper.threadedregions.RegionizedServer");
|
||||||
|
folia = true;
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
folia = false;
|
||||||
|
}
|
||||||
|
isFolia = folia;
|
||||||
|
}
|
||||||
|
|
||||||
private static ComponentLogger LOGGER = null;
|
private static ComponentLogger LOGGER = null;
|
||||||
private static BlockHistoryPlugin INSTANCE = null;
|
private static BlockHistoryPlugin INSTANCE = null;
|
||||||
|
|
||||||
@@ -41,6 +55,7 @@ public final class BlockHistoryPlugin extends JavaPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
|
LOGGER.info("Folia: {}", isFolia ? "yes" : "no");
|
||||||
statManager = new StatManager();
|
statManager = new StatManager();
|
||||||
Path saveDirectory = Path.of(getDataFolder().getPath(), "history");
|
Path saveDirectory = Path.of(getDataFolder().getPath(), "history");
|
||||||
try {
|
try {
|
||||||
@@ -52,7 +67,7 @@ public final class BlockHistoryPlugin extends JavaPlugin {
|
|||||||
|
|
||||||
getLifecycleManager().registerEventHandler(LifecycleEvents.COMMANDS, this::registerCommands);
|
getLifecycleManager().registerEventHandler(LifecycleEvents.COMMANDS, this::registerCommands);
|
||||||
|
|
||||||
Bukkit.getScheduler().scheduleSyncRepeatingTask(this, BlockListener::clearCache, 6000, 6000);
|
SchedulerUtil.scheduleGlobalRepeating(this, BlockListener::clearCache, 6000, 6000);
|
||||||
|
|
||||||
listen(new BlockListener());
|
listen(new BlockListener());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,9 +89,9 @@ public final class HistoryManager {
|
|||||||
logger.info("Shutdown finished ({}ms)", (System.nanoTime() - n) / 1000000);
|
logger.info("Shutdown finished ({}ms)", (System.nanoTime() - n) / 1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<Void> addHistoryElement(BlockHistoryElement element){
|
public void addHistoryElement(BlockHistoryElement element){
|
||||||
Objects.requireNonNull(element);
|
Objects.requireNonNull(element);
|
||||||
return CompletableFuture.runAsync(() -> {
|
writeExecutor.execute(() -> {
|
||||||
try {
|
try {
|
||||||
byte[] saveData = element.saveData();
|
byte[] saveData = element.saveData();
|
||||||
writeToDisk(
|
writeToDisk(
|
||||||
@@ -112,7 +112,7 @@ public final class HistoryManager {
|
|||||||
BlockHistoryPlugin.logger().warn(s);
|
BlockHistoryPlugin.logger().warn(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, writeExecutor);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeToDisk(Path path, byte[] saveData) throws LowDiskSpaceException, IOException {
|
private void writeToDisk(Path path, byte[] saveData) throws LowDiskSpaceException, IOException {
|
||||||
@@ -148,7 +148,7 @@ public final class HistoryManager {
|
|||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
int b = dataIn.readUnsignedByte();
|
int b = dataIn.readUnsignedByte();
|
||||||
BlockHistoryElement element = BlockHistoryElement.read(b, dataIn, world, location.getChunk().getX(), location.getChunk().getZ());
|
BlockHistoryElement element = BlockHistoryElement.read(b, dataIn, world, getChunkX(location), getChunkZ(location));
|
||||||
if (element.x() == x && element.y() == y && element.z() == z){
|
if (element.x() == x && element.y() == y && element.z() == z){
|
||||||
callback.onElementFound(element);
|
callback.onElementFound(element);
|
||||||
}
|
}
|
||||||
@@ -161,6 +161,28 @@ public final class HistoryManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getChunkZ(Location location) {
|
||||||
|
int pos;
|
||||||
|
if (location.getZ() < 0){
|
||||||
|
pos = ((location.getBlockZ() + 1) / 16) - 1;
|
||||||
|
} else {
|
||||||
|
pos = location.getBlockZ() / 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getChunkX(Location location) {
|
||||||
|
int pos;
|
||||||
|
if (location.getX() < 0){
|
||||||
|
pos = ((location.getBlockX() + 1) / 16) - 1;
|
||||||
|
} else {
|
||||||
|
pos = location.getBlockX() / 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
public CompletableFuture<DiskSpaceApproximationVisitor> approximateDiskSpaceBytes() {
|
public CompletableFuture<DiskSpaceApproximationVisitor> approximateDiskSpaceBytes() {
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ package de.shiewk.blockhistory.v3.listener;
|
|||||||
import de.shiewk.blockhistory.v3.BlockHistoryPlugin;
|
import de.shiewk.blockhistory.v3.BlockHistoryPlugin;
|
||||||
import de.shiewk.blockhistory.v3.history.BlockHistoryElement;
|
import de.shiewk.blockhistory.v3.history.BlockHistoryElement;
|
||||||
import de.shiewk.blockhistory.v3.history.BlockHistoryType;
|
import de.shiewk.blockhistory.v3.history.BlockHistoryType;
|
||||||
|
import de.shiewk.blockhistory.v3.util.SchedulerUtil;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
@@ -25,13 +25,15 @@ import org.bukkit.event.player.PlayerBucketFillEvent;
|
|||||||
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
|
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
|
||||||
public final class BlockListener implements Listener {
|
public final class BlockListener implements Listener {
|
||||||
|
|
||||||
private static final Object2ObjectOpenHashMap<UUID, UUID> igniters = new Object2ObjectOpenHashMap<>();
|
private static final Map<UUID, UUID> igniters = BlockHistoryPlugin.isFolia ? new ConcurrentHashMap<>() : new Object2ObjectOpenHashMap<>();
|
||||||
private static final Object2ObjectOpenHashMap<Block, UUID> blocks = new Object2ObjectOpenHashMap<>();
|
private static final Map<Block, UUID> blocks = BlockHistoryPlugin.isFolia ? new ConcurrentHashMap<>() : new Object2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
public static void clearCache() {
|
public static void clearCache() {
|
||||||
igniters.clear();
|
igniters.clear();
|
||||||
@@ -52,7 +54,7 @@ public final class BlockListener implements Listener {
|
|||||||
|
|
||||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||||
public void onBucketEmptied(PlayerBucketEmptyEvent event){
|
public void onBucketEmptied(PlayerBucketEmptyEvent event){
|
||||||
Bukkit.getScheduler().scheduleSyncDelayedTask(BlockHistoryPlugin.instance(), () -> {
|
SchedulerUtil.scheduleGlobal(BlockHistoryPlugin.instance(), () -> {
|
||||||
final Block block = event.getBlock();
|
final Block block = event.getBlock();
|
||||||
createAndAddEntry(BlockHistoryType.EMPTY_BUCKET, event.getPlayer(), block);
|
createAndAddEntry(BlockHistoryType.EMPTY_BUCKET, event.getPlayer(), block);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package de.shiewk.blockhistory.v3.util;
|
package de.shiewk.blockhistory.v3.util;
|
||||||
|
|
||||||
import org.bukkit.Chunk;
|
import de.shiewk.blockhistory.v3.HistoryManager;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
|
||||||
@@ -50,17 +50,7 @@ public final class BlockHistoryFileNames {
|
|||||||
public static Path encode(Path parentDirectory, Location location){
|
public static Path encode(Path parentDirectory, Location location){
|
||||||
// encoded string is 13 characters long
|
// encoded string is 13 characters long
|
||||||
World world = location.getWorld();
|
World world = location.getWorld();
|
||||||
Chunk chunk = location.getChunk();
|
long packed = getPackedPos(location);
|
||||||
int chunkX = chunk.getX();
|
|
||||||
int chunkZ = chunk.getZ();
|
|
||||||
// 20 bytes
|
|
||||||
long packed = 0;
|
|
||||||
|
|
||||||
packed |= chunkX & 0b1111111111111111111L;
|
|
||||||
if (chunkX < 0) packed |= 0b10000000000000000000;
|
|
||||||
|
|
||||||
packed |= (chunkZ & 0b1111111111111111111L) << 20;
|
|
||||||
if (chunkZ < 0) packed |= 0b1000000000000000000000000000000000000000L;
|
|
||||||
|
|
||||||
String encodedChunkFileName = new String(new char[]{
|
String encodedChunkFileName = new String(new char[]{
|
||||||
base32encode((short) (packed >> 35 & 0b11111)),
|
base32encode((short) (packed >> 35 & 0b11111)),
|
||||||
@@ -78,4 +68,19 @@ public final class BlockHistoryFileNames {
|
|||||||
encodedChunkFileName
|
encodedChunkFileName
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static long getPackedPos(Location location) {
|
||||||
|
int chunkX = HistoryManager.getChunkX(location);
|
||||||
|
int chunkZ = HistoryManager.getChunkZ(location);
|
||||||
|
|
||||||
|
// 20 bits
|
||||||
|
long packed = 0;
|
||||||
|
|
||||||
|
packed |= chunkX & 0b1111111111111111111L;
|
||||||
|
if (chunkX < 0) packed |= 0b10000000000000000000;
|
||||||
|
|
||||||
|
packed |= (chunkZ & 0b1111111111111111111L) << 20;
|
||||||
|
if (chunkZ < 0) packed |= 0b1000000000000000000000000000000000000000L;
|
||||||
|
return packed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package de.shiewk.blockhistory.v3.util;
|
||||||
|
|
||||||
|
import de.shiewk.blockhistory.v3.BlockHistoryPlugin;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
public final class SchedulerUtil {
|
||||||
|
private SchedulerUtil(){}
|
||||||
|
|
||||||
|
public static void scheduleGlobal(Plugin plugin, Runnable task){
|
||||||
|
if (BlockHistoryPlugin.isFolia){
|
||||||
|
Bukkit.getGlobalRegionScheduler().run(plugin, t -> task.run());
|
||||||
|
} else {
|
||||||
|
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void scheduleGlobalRepeating(Plugin plugin, Runnable task, int delay, int interval) {
|
||||||
|
if (BlockHistoryPlugin.isFolia){
|
||||||
|
Bukkit.getGlobalRegionScheduler().runAtFixedRate(plugin, t -> task.run(), delay, interval);
|
||||||
|
} else {
|
||||||
|
Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, task, delay, interval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,8 @@ prefix: BlockHistory
|
|||||||
load: STARTUP
|
load: STARTUP
|
||||||
authors: [ Shiewk ]
|
authors: [ Shiewk ]
|
||||||
description: BlockHistory is a Paper plugin that helps you to find griefers more easily.
|
description: BlockHistory is a Paper plugin that helps you to find griefers more easily.
|
||||||
|
folia-supported: true
|
||||||
|
website: https://github.com/Shiewk/BlockHistory3
|
||||||
permissions:
|
permissions:
|
||||||
blockhistory.command.root:
|
blockhistory.command.root:
|
||||||
default: op
|
default: op
|
||||||
Reference in New Issue
Block a user